versioning: 0.0.6, ux: move buttons, feat: add cloud providers, feat: increese tool call limit
Build Release EXE / build-windows-exe (release) Successful in 51s

This commit is contained in:
2026-05-08 14:48:51 -04:00
parent a5a718b3e4
commit 6bd1e81a51
14 changed files with 1103 additions and 198 deletions
+102 -7
View File
@@ -39,6 +39,13 @@ def resource_path(*parts: str) -> Path:
class ChatRequest(BaseModel):
message: str
thread_id: str | None = DEFAULT_THREAD_ID
images: list["ChatImageRequest"] = []
class ChatImageRequest(BaseModel):
name: str = "pasted-image.png"
content_type: str = "image/png"
image_data: str
class ChatThreadRequest(BaseModel):
@@ -114,12 +121,14 @@ def create_app() -> FastAPI:
plan_runner = ContinualPlanRunner(plan_store, tools, memory)
tools.plan_runner = plan_runner
agent = OllamaAgent(
settings.ollama_base_url,
settings.ollama_model,
settings.openai_base_url if settings.model_provider == "openai" else settings.ollama_base_url,
settings.openai_model if settings.model_provider == "openai" else settings.ollama_model,
tools,
memory=memory,
user_name=settings.traderai_user_name,
num_ctx=settings.ollama_num_ctx,
provider=settings.model_provider,
api_key=settings.openai_api_key,
)
plan_runner.bind_agent(agent)
scheduler.bind_agent(agent)
@@ -171,6 +180,7 @@ def create_app() -> FastAPI:
async def health() -> dict:
return {
"ollama": await agent.health(),
"model_provider": settings.model_provider,
"user": memory.get_profile(),
"jobs": scheduler.list_jobs(),
"app_data_dir": settings_payload()["app_data_dir"],
@@ -190,7 +200,19 @@ def create_app() -> FastAPI:
@app.get("/api/ollama/status")
async def ollama_status() -> dict:
return await inspect_ollama()
return await inspect_model_provider()
@app.get("/api/openai/models")
async def openai_models() -> dict:
status = await inspect_openai()
return {
"provider": "openai",
"configured_model": status.get("configured_model"),
"models": status.get("models", []),
"message": status.get("message", ""),
"detail": status.get("detail", ""),
"online": status.get("online", False),
}
@app.post("/api/ollama/launch")
async def launch_ollama() -> dict:
@@ -201,7 +223,7 @@ def create_app() -> FastAPI:
popen_hidden(command)
except OSError as exc:
raise HTTPException(status_code=500, detail=f"Could not launch Ollama: {exc}") from exc
status = await inspect_ollama()
status = await inspect_model_provider()
status["message"] = "Ollama launch requested."
return status
@@ -218,7 +240,7 @@ def create_app() -> FastAPI:
popen_hidden([str(cli), "pull", model])
except OSError as exc:
raise HTTPException(status_code=500, detail=f"Could not start model install: {exc}") from exc
status = await inspect_ollama()
status = await inspect_model_provider()
status["message"] = f"Started installing model {model}."
return status
@@ -298,14 +320,22 @@ def create_app() -> FastAPI:
@app.post("/api/chat")
async def chat(request: ChatRequest) -> dict:
try:
return await agent.chat(request.message, thread_id=request.thread_id)
return await agent.chat(
request.message,
thread_id=request.thread_id,
images=[image.model_dump() for image in request.images],
)
except OllamaUnavailable as exc:
raise HTTPException(status_code=503, detail=str(exc)) from exc
@app.post("/api/chat/stream")
async def chat_stream(request: ChatRequest) -> StreamingResponse:
async def events():
async for event in agent.chat_events(request.message, thread_id=request.thread_id):
async for event in agent.chat_events(
request.message,
thread_id=request.thread_id,
images=[image.model_dump() for image in request.images],
):
yield f"data: {json.dumps(event)}\n\n"
return StreamingResponse(events(), media_type="text/event-stream")
@@ -475,6 +505,60 @@ def negotiation_identifier_params(identifier: str) -> dict[str, Any]:
return {"hash": value}
async def inspect_model_provider() -> dict[str, Any]:
settings = get_settings()
if settings.model_provider == "openai":
return await inspect_openai()
return await inspect_ollama()
async def inspect_openai() -> dict[str, Any]:
settings = get_settings()
models: list[str] = []
online = False
detail = ""
if not settings.openai_api_key:
return {
"installed": True,
"running": False,
"online": False,
"provider": "openai",
"model_available": False,
"configured_model": settings.openai_model,
"base_url": settings.openai_base_url,
"models": [],
"message": "OpenAI is selected, but no API key is configured.",
"detail": "",
}
try:
async with httpx.AsyncClient(timeout=10) as client:
response = await client.get(
f"{settings.openai_base_url.rstrip('/')}/models",
headers={"Authorization": f"Bearer {settings.openai_api_key}"},
)
response.raise_for_status()
body = response.json()
online = True
models = sorted(item.get("id") for item in body.get("data", []) if item.get("id"))
except (httpx.HTTPError, ValueError) as exc:
detail = str(exc)
model_available = settings.openai_model in models
return {
"installed": True,
"running": online,
"online": online,
"provider": "openai",
"model_available": model_available,
"configured_model": settings.openai_model,
"base_url": settings.openai_base_url,
"models": models,
"message": openai_status_message(online, bool(settings.openai_api_key), model_available, settings.openai_model),
"detail": detail,
}
async def inspect_ollama() -> dict[str, Any]:
settings = get_settings()
executable = find_ollama_executable()
@@ -500,6 +584,7 @@ async def inspect_ollama() -> dict[str, Any]:
"installed": installed,
"running": online,
"online": online,
"provider": "ollama",
"model_available": model_available,
"configured_model": settings.ollama_model,
"base_url": settings.ollama_base_url,
@@ -514,6 +599,16 @@ async def inspect_ollama() -> dict[str, Any]:
}
def openai_status_message(running: bool, configured: bool, model_available: bool, model: str) -> str:
if not configured:
return "OpenAI API key is not configured."
if not running:
return "OpenAI is not reachable with the configured key."
if not model_available:
return f'OpenAI is reachable, but model "{model}" was not returned by the API.'
return "OpenAI is ready."
def ollama_status_message(installed: bool, running: bool, model_available: bool, model: str) -> str:
if not installed:
return "Ollama is not installed."