Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
33 changes: 33 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Attribution (MIT License): Opentensor Foundation 2026 (https://github.com/opentensor)
# https://github.com/opentensor/bittensor/blob/bb526e6d61210ef2ee0e229f63ca5518381ff5a7/.github/workflows/ruff.yml

name: Ruff - formatter check
permissions:
contents: read

on:
pull_request:
types: [opened, synchronize, reopened, edited]

jobs:
ruff:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest

steps:
- name: Install Ruff
uses: astral-sh/ruff-action@v3.6.1
with:
version: "0.15.7"
checksum: "2253ba7f064023def4b77aaef127756d3724e92a0fc69d666d4692f5c019af6d"
args:
"--version"

- name: Ruff format check
run: |
ruff format --check --diff

- name: Ruff lint check
run: |
ruff check

62 changes: 20 additions & 42 deletions agent.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import os
import json
import requests

import os

import requests

RUN_ID = os.getenv("RUN_ID")
if not RUN_ID:
Expand All @@ -13,88 +12,67 @@
print("[AGENT] WARNING: SANDBOX_PROXY_URL is not set")



def inference(model, temperature, messages):
try:
payload = {
"run_id": RUN_ID,
"model": model,
"temperature": temperature,
"messages": messages
}

print(f"[AGENT] inference(): Sending inference request for model {model} (temperature {temperature}) with {len(messages)} messages")
payload = {"run_id": RUN_ID, "model": model, "temperature": temperature, "messages": messages}

print(
f"[AGENT] inference(): Sending inference request for model {model} (temperature {temperature}) with {len(messages)} messages"
)
response = requests.post(
f"{SANDBOX_PROXY_URL}/api/inference",
headers={"Content-Type": "application/json"},
data=json.dumps(payload)
f"{SANDBOX_PROXY_URL}/api/inference", headers={"Content-Type": "application/json"}, data=json.dumps(payload)
)

if response.status_code == 200:
result = response.text.strip('"')
print(f"[AGENT] inference(): Inference response: {len(result)} characters")
return result
else:
print(f"[AGENT] inference(): Inference failed with status {response.status_code}: {response.text}")
return None

except Exception as e:
print(f"[AGENT] inference(): Inference request failed: {e}")
return None



def embedding(input):
try:
payload = {
"run_id": RUN_ID,
"input": input
}

print(f"[AGENT] embedding(): Sending embedding request...")
payload = {"run_id": RUN_ID, "input": input}

print("[AGENT] embedding(): Sending embedding request...")
response = requests.post(
f"{SANDBOX_PROXY_URL}/api/embedding",
headers={"Content-Type": "application/json"},
data=json.dumps(payload)
f"{SANDBOX_PROXY_URL}/api/embedding", headers={"Content-Type": "application/json"}, data=json.dumps(payload)
)

if response.status_code == 200:
result = response.json()
print(f"[AGENT] embedding(): Embedding response: {len(result)} dimensions")
return result
else:
print(f"[AGENT] embedding(): Embedding failed with status {response.status_code}: {response.text}")
return None

except Exception as e:
print(f"[AGENT] embedding(): Embedding request failed: {e}")
return None



def agent_main(input):
def agent_main(input):
print("[AGENT] Entered agent_main()")



# Test inference function
message = "What is 2+2?"
print(f"[AGENT] <-- '{message}'")
messages = [
{"role": "user", "content": message}
]
messages = [{"role": "user", "content": message}]
inference_result = inference("moonshotai/Kimi-K2-Instruct", 0.5, messages)
if inference_result:
print(f"[AGENT] --> '{inference_result}'")



print("[AGENT] Reading solution from /sandbox/solution.diff")
with open("/sandbox/solution.diff", "r") as f:
diff = f.read()



print("[AGENT] Exiting agent_main()")
return diff

return diff
30 changes: 10 additions & 20 deletions api/config.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import os
import utils.logger as logger

from dotenv import load_dotenv


import utils.logger as logger

# Load everything from .env
load_dotenv()



# Load host and port
HOST = os.getenv("HOST")
if not HOST:
Expand All @@ -21,7 +19,6 @@
PORT = int(PORT)



# Load Bittensor configuration
NETUID = os.getenv("NETUID")
if not NETUID:
Expand All @@ -37,7 +34,6 @@
logger.fatal("SUBTENSOR_NETWORK is not set in .env")



OWNER_HOTKEY = os.getenv("OWNER_HOTKEY")
if not OWNER_HOTKEY:
logger.fatal("OWNER_HOTKEY is not set in .env")
Expand All @@ -62,7 +58,6 @@
logger.fatal("DISALLOW_UPLOADS_REASON is not set in .env")



# Load the environment configuration
ENV = os.getenv("ENV")
if not ENV:
Expand All @@ -72,12 +67,11 @@
logger.fatal("ENV must be either 'prod' or 'dev'")



# Load AWS configuration
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
if not AWS_ACCESS_KEY_ID:
logger.fatal("AWS_ACCESS_KEY_ID is not set in .env")

AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
if not AWS_SECRET_ACCESS_KEY:
logger.fatal("AWS_SECRET_ACCESS_KEY is not set in .env")
Expand All @@ -87,38 +81,35 @@
logger.fatal("AWS_REGION is not set in .env")



# Load S3 configuration
S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME")
if not S3_BUCKET_NAME:
logger.fatal("S3_BUCKET_NAME is not set in .env")



# Load database configuration
DATABASE_USERNAME = os.getenv("DATABASE_USERNAME")
if not DATABASE_USERNAME:
logger.fatal("DATABASE_USERNAME is not set in .env")

DATABASE_PASSWORD = os.getenv("DATABASE_PASSWORD")
if not DATABASE_PASSWORD:
logger.fatal("DATABASE_PASSWORD is not set in .env")

DATABASE_HOST = os.getenv("DATABASE_HOST")
if not DATABASE_HOST:
logger.fatal("DATABASE_HOST is not set in .env")

DATABASE_PORT = os.getenv("DATABASE_PORT")
if not DATABASE_PORT:
logger.fatal("DATABASE_PORT is not set in .env")
DATABASE_PORT = int(DATABASE_PORT)

DATABASE_NAME = os.getenv("DATABASE_NAME")
if not DATABASE_NAME:
logger.fatal("DATABASE_NAME is not set in .env")



# Load screener configuration
SCREENER_PASSWORD = os.getenv("SCREENER_PASSWORD")
if not SCREENER_PASSWORD:
Expand All @@ -140,7 +131,6 @@
PRUNE_THRESHOLD = float(PRUNE_THRESHOLD)



# Load validator configuration
VALIDATOR_HEARTBEAT_TIMEOUT_SECONDS = os.getenv("VALIDATOR_HEARTBEAT_TIMEOUT_SECONDS")
if not VALIDATOR_HEARTBEAT_TIMEOUT_SECONDS:
Expand All @@ -153,7 +143,6 @@
VALIDATOR_HEARTBEAT_TIMEOUT_INTERVAL_SECONDS = int(VALIDATOR_HEARTBEAT_TIMEOUT_INTERVAL_SECONDS)



# Load validator configuration (sent to validator upon registration)
VALIDATOR_RUNNING_AGENT_TIMEOUT_SECONDS = os.getenv("VALIDATOR_RUNNING_AGENT_TIMEOUT_SECONDS")
if not VALIDATOR_RUNNING_AGENT_TIMEOUT_SECONDS:
Expand All @@ -171,7 +160,6 @@
VALIDATOR_MAX_EVALUATION_RUN_LOG_SIZE_BYTES = int(VALIDATOR_MAX_EVALUATION_RUN_LOG_SIZE_BYTES)



MINER_AGENT_UPLOAD_RATE_LIMIT_SECONDS = os.getenv("MINER_AGENT_UPLOAD_RATE_LIMIT_SECONDS")
if not MINER_AGENT_UPLOAD_RATE_LIMIT_SECONDS:
logger.fatal("MINER_AGENT_UPLOAD_RATE_LIMIT_SECONDS is not set in .env")
Expand All @@ -190,7 +178,9 @@
FETCH_METAGRAPH_INTERVAL_SECONDS = os.getenv("FETCH_METAGRAPH_INTERVAL_SECONDS")
if not FETCH_METAGRAPH_INTERVAL_SECONDS:
default_fetch_metagraph_interval_seconds = 120
logger.warning(f"FETCH_METAGRAPH_INTERVAL_SECONDS is not set in .env, using default of {default_fetch_metagraph_interval_seconds} seconds")
logger.warning(
f"FETCH_METAGRAPH_INTERVAL_SECONDS is not set in .env, using default of {default_fetch_metagraph_interval_seconds} seconds"
)
FETCH_METAGRAPH_INTERVAL_SECONDS = default_fetch_metagraph_interval_seconds
else:
FETCH_METAGRAPH_INTERVAL_SECONDS = int(FETCH_METAGRAPH_INTERVAL_SECONDS)
Expand Down Expand Up @@ -248,4 +238,4 @@
logger.info(f"Miner Agent Upload Rate Limit: {MINER_AGENT_UPLOAD_RATE_LIMIT_SECONDS} second(s)")
logger.info(f"Number of Evaluations per Agent: {NUM_EVALS_PER_AGENT}")

logger.info("=========================")
logger.info("=========================")
10 changes: 4 additions & 6 deletions api/endpoints/agent.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from uuid import UUID
from models.agent import Agent
from fastapi import APIRouter, HTTPException
from queries.agent import get_agent_by_evaluation_run_id


from fastapi import APIRouter, HTTPException

from models.agent import Agent
from queries.agent import get_agent_by_evaluation_run_id

router = APIRouter()



# /agent/get-by-evaluation-run-id?evaluation_run_id=
@router.get("/get-by-evaluation-run-id")
async def agent_get_by_evaluation_run_id(evaluation_run_id: UUID) -> Agent:
Expand All @@ -18,4 +16,4 @@ async def agent_get_by_evaluation_run_id(evaluation_run_id: UUID) -> Agent:
if agent is None:
raise HTTPException(status_code=404, detail=f"Agent with evaluation run ID {evaluation_run_id} does not exist.")

return agent
return agent
7 changes: 2 additions & 5 deletions api/endpoints/debug.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
from fastapi import APIRouter

from utils.database import get_debug_query_info
from utils.debug_lock import get_debug_lock_info



router = APIRouter()



# /debug/lock-info
@router.get("/lock-info")
async def debug_lock_info():
return get_debug_lock_info()



# /debug/query-info
@router.get("/query-info")
async def debug_query_info():
return get_debug_query_info()
return get_debug_query_info()
19 changes: 9 additions & 10 deletions api/endpoints/evaluation_run.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
from uuid import UUID
from fastapi import APIRouter, HTTPException
from queries.evaluation_run import get_evaluation_run_by_id
from models.evaluation_run import EvaluationRun, EvaluationRunLogType
from queries.evaluation_run import get_evaluation_run_logs_by_id

from fastapi import APIRouter, HTTPException

from models.evaluation_run import EvaluationRun, EvaluationRunLogType
from queries.evaluation_run import get_evaluation_run_by_id, get_evaluation_run_logs_by_id

router = APIRouter()



# /evaluation-run/get-by-id?evaluation_run_id=
@router.get("/get-by-id")
async def evaluation_run_get_by_id(evaluation_run_id: UUID) -> EvaluationRun:
evaluation_run = await get_evaluation_run_by_id(evaluation_run_id)

if evaluation_run is None:
raise HTTPException(status_code=404, detail=f"Evaluation run with ID {evaluation_run_id} does not exist.")

return evaluation_run

return evaluation_run


# /evaluation-run/get-logs-by-id?evaluation_run_id=&type=
Expand All @@ -28,6 +25,8 @@ async def evaluation_run_get_logs_by_id(evaluation_run_id: UUID, type: Evaluatio
logs = await get_evaluation_run_logs_by_id(evaluation_run_id, type)

if logs is None:
raise HTTPException(status_code=404, detail=f"Evaluation run logs with ID {evaluation_run_id} and type {type} do not exist.")
raise HTTPException(
status_code=404, detail=f"Evaluation run logs with ID {evaluation_run_id} and type {type} do not exist."
)

return logs
return logs
Loading
Loading