Skip to content

api_routes

api_routes

Extended API routes for agents, workflows, memory, traces, etc.

Functions

list_agents async

list_agents(request: Request)

List available agent types and running agents.

Source code in src/openjarvis/server/api_routes.py
@agents_router.get("")
async def list_agents(request: Request):
    """List available agent types and running agents."""
    registered = []
    try:
        import openjarvis.agents  # noqa: F401 — side-effect registration
        from openjarvis.core.registry import AgentRegistry
        for key in sorted(AgentRegistry.keys()):
            cls = AgentRegistry.get(key)
            registered.append({
                "key": key,
                "class": cls.__name__,
                "accepts_tools": getattr(cls, "accepts_tools", False),
            })
    except Exception as exc:
        logger.warning("Failed to list registered agents: %s", exc)

    running = []
    try:
        from openjarvis.tools.agent_tools import _SPAWNED_AGENTS
        running = [
            {"id": k, **v} for k, v in _SPAWNED_AGENTS.items()
        ]
    except ImportError:
        pass

    return {"registered": registered, "running": running}

create_agent async

create_agent(req: AgentCreateRequest, request: Request)

Spawn a new agent.

Source code in src/openjarvis/server/api_routes.py
@agents_router.post("")
async def create_agent(req: AgentCreateRequest, request: Request):
    """Spawn a new agent."""
    try:
        from openjarvis.tools.agent_tools import AgentSpawnTool
        tool = AgentSpawnTool()
        params = {"agent_type": req.agent_type}
        if req.tools:
            params["tools"] = ",".join(req.tools)
        if req.agent_id:
            params["agent_id"] = req.agent_id
        result = tool.execute(**params)
        if not result.success:
            raise HTTPException(status_code=400, detail=result.content)
        return {
            "status": "created",
            "content": result.content,
            "metadata": result.metadata,
        }
    except ImportError:
        raise HTTPException(status_code=501, detail="Agent tools not available")

kill_agent async

kill_agent(agent_id: str, request: Request)

Kill a running agent.

Source code in src/openjarvis/server/api_routes.py
@agents_router.delete("/{agent_id}")
async def kill_agent(agent_id: str, request: Request):
    """Kill a running agent."""
    try:
        from openjarvis.tools.agent_tools import AgentKillTool
        tool = AgentKillTool()
        result = tool.execute(agent_id=agent_id)
        if not result.success:
            raise HTTPException(status_code=404, detail=result.content)
        return {"status": "stopped", "agent_id": agent_id}
    except ImportError:
        raise HTTPException(status_code=501, detail="Agent tools not available")

message_agent async

message_agent(agent_id: str, req: AgentMessageRequest, request: Request)

Send a message to a running agent.

Source code in src/openjarvis/server/api_routes.py
@agents_router.post("/{agent_id}/message")
async def message_agent(agent_id: str, req: AgentMessageRequest, request: Request):
    """Send a message to a running agent."""
    try:
        from openjarvis.tools.agent_tools import AgentSendTool
        tool = AgentSendTool()
        result = tool.execute(agent_id=agent_id, message=req.message)
        if not result.success:
            raise HTTPException(status_code=404, detail=result.content)
        return {"status": "sent", "content": result.content}
    except ImportError:
        raise HTTPException(status_code=501, detail="Agent tools not available")

memory_store async

memory_store(req: MemoryStoreRequest, request: Request)

Store content in memory.

Source code in src/openjarvis/server/api_routes.py
@memory_router.post("/store")
async def memory_store(req: MemoryStoreRequest, request: Request):
    """Store content in memory."""
    try:
        from openjarvis.tools.storage.sqlite import SQLiteMemory
        backend = SQLiteMemory()
        backend.store(req.content, metadata=req.metadata or {})
        return {"status": "stored"}
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))
memory_search(req: MemorySearchRequest, request: Request)

Search memory for relevant content.

Source code in src/openjarvis/server/api_routes.py
@memory_router.post("/search")
async def memory_search(req: MemorySearchRequest, request: Request):
    """Search memory for relevant content."""
    try:
        from openjarvis.tools.storage.sqlite import SQLiteMemory
        backend = SQLiteMemory()
        results = backend.search(req.query, top_k=req.top_k)
        items = [
            {"content": r.content, "score": r.score, "metadata": r.metadata}
            for r in results
        ]
        return {"results": items}
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))

memory_stats async

memory_stats(request: Request)

Get memory backend statistics.

Source code in src/openjarvis/server/api_routes.py
@memory_router.get("/stats")
async def memory_stats(request: Request):
    """Get memory backend statistics."""
    try:
        from openjarvis.tools.storage.sqlite import SQLiteMemory
        backend = SQLiteMemory()
        stats = backend.stats()
        return stats
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))

list_traces async

list_traces(request: Request, limit: int = 20)

List recent traces.

Source code in src/openjarvis/server/api_routes.py
@traces_router.get("")
async def list_traces(request: Request, limit: int = 20):
    """List recent traces."""
    try:
        from openjarvis.traces.store import TraceStore
        store = TraceStore()
        traces = store.recent(limit=limit)
        items = [
            t.to_dict() if hasattr(t, "to_dict") else str(t)
            for t in traces
        ]
        return {"traces": items}
    except Exception as exc:
        return {"traces": [], "error": str(exc)}

get_trace async

get_trace(trace_id: str, request: Request)

Get a specific trace by ID.

Source code in src/openjarvis/server/api_routes.py
@traces_router.get("/{trace_id}")
async def get_trace(trace_id: str, request: Request):
    """Get a specific trace by ID."""
    try:
        from openjarvis.traces.store import TraceStore
        store = TraceStore()
        trace = store.get(trace_id)
        if trace is None:
            raise HTTPException(status_code=404, detail="Trace not found")
        return trace.to_dict() if hasattr(trace, 'to_dict') else {"id": trace_id}
    except HTTPException:
        raise
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))

telemetry_stats async

telemetry_stats(request: Request)

Get aggregated telemetry statistics.

Source code in src/openjarvis/server/api_routes.py
@telemetry_router.get("/stats")
async def telemetry_stats(request: Request):
    """Get aggregated telemetry statistics."""
    try:
        from dataclasses import asdict

        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.telemetry.aggregator import TelemetryAggregator

        db_path = DEFAULT_CONFIG_DIR / "telemetry.db"
        if not db_path.exists():
            return {"total_requests": 0, "total_tokens": 0}

        session_start = getattr(request.app.state, "session_start", None)
        agg = TelemetryAggregator(db_path)
        try:
            stats = agg.summary(since=session_start)
            d = asdict(stats)
            d.pop("per_model", None)
            d.pop("per_engine", None)
            d["total_requests"] = d.pop("total_calls", 0)
            return d
        finally:
            agg.close()
    except Exception as exc:
        return {"error": str(exc)}

telemetry_energy async

telemetry_energy(request: Request)

Get energy monitoring data.

Source code in src/openjarvis/server/api_routes.py
@telemetry_router.get("/energy")
async def telemetry_energy(request: Request):
    """Get energy monitoring data."""
    try:

        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.telemetry.aggregator import TelemetryAggregator

        db_path = DEFAULT_CONFIG_DIR / "telemetry.db"
        if not db_path.exists():
            return {"total_energy_j": 0, "energy_per_token_j": 0, "avg_power_w": 0}

        session_start = getattr(request.app.state, "session_start", None)
        agg = TelemetryAggregator(db_path)
        try:
            stats = agg.summary(since=session_start)
            total_energy = stats.total_energy_joules
            total_tokens = stats.total_tokens
            total_latency = stats.total_latency
            return {
                "total_energy_j": total_energy,
                "energy_per_token_j": (
                    total_energy / total_tokens if total_tokens > 0 else 0
                ),
                "avg_power_w": (
                    total_energy / total_latency if total_latency > 0 else 0
                ),
            }
        finally:
            agg.close()
    except Exception as exc:
        return {"error": str(exc)}

list_skills async

list_skills(request: Request)

List installed skills.

Source code in src/openjarvis/server/api_routes.py
@skills_router.get("")
async def list_skills(request: Request):
    """List installed skills."""
    try:
        from openjarvis.core.registry import SkillRegistry
        skills = []
        for key in sorted(SkillRegistry.keys()):
            skills.append({"name": key})
        return {"skills": skills}
    except Exception as exc:
        logger.warning("Failed to list skills: %s", exc)
        return {"skills": []}

install_skill async

install_skill(request: Request)

Install a skill (placeholder).

Source code in src/openjarvis/server/api_routes.py
@skills_router.post("")
async def install_skill(request: Request):
    """Install a skill (placeholder)."""
    return {
        "status": "not_implemented",
        "message": "Use TOML files in ~/.openjarvis/skills/",
    }

remove_skill async

remove_skill(skill_name: str, request: Request)

Remove a skill (placeholder).

Source code in src/openjarvis/server/api_routes.py
@skills_router.delete("/{skill_name}")
async def remove_skill(skill_name: str, request: Request):
    """Remove a skill (placeholder)."""
    return {
        "status": "not_implemented",
        "message": "Skill removal not yet supported via API",
    }

list_sessions async

list_sessions(request: Request, limit: int = 20)

List active sessions.

Source code in src/openjarvis/server/api_routes.py
@sessions_router.get("")
async def list_sessions(request: Request, limit: int = 20):
    """List active sessions."""
    try:
        from openjarvis.sessions.store import SessionStore
        store = SessionStore()
        sessions = store.recent(limit=limit)
        items = [
            s.to_dict() if hasattr(s, "to_dict") else str(s)
            for s in sessions
        ]
        return {"sessions": items}
    except Exception as exc:
        return {"sessions": [], "error": str(exc)}

get_session async

get_session(session_id: str, request: Request)

Get a specific session.

Source code in src/openjarvis/server/api_routes.py
@sessions_router.get("/{session_id}")
async def get_session(session_id: str, request: Request):
    """Get a specific session."""
    try:
        from openjarvis.sessions.store import SessionStore
        store = SessionStore()
        session = store.get(session_id)
        if session is None:
            raise HTTPException(status_code=404, detail="Session not found")
        return session.to_dict() if hasattr(session, 'to_dict') else {"id": session_id}
    except HTTPException:
        raise
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))

get_budget async

get_budget(request: Request)

Get current budget usage and limits.

Source code in src/openjarvis/server/api_routes.py
@budget_router.get("")
async def get_budget(request: Request):
    """Get current budget usage and limits."""
    return {"limits": _budget_limits, "usage": _budget_usage}

set_budget_limits async

set_budget_limits(req: BudgetLimitsRequest, request: Request)

Update budget limits.

Source code in src/openjarvis/server/api_routes.py
@budget_router.put("/limits")
async def set_budget_limits(req: BudgetLimitsRequest, request: Request):
    """Update budget limits."""
    if req.max_tokens_per_day is not None:
        _budget_limits["max_tokens_per_day"] = req.max_tokens_per_day
    if req.max_requests_per_hour is not None:
        _budget_limits["max_requests_per_hour"] = req.max_requests_per_hour
    return {"status": "updated", "limits": _budget_limits}

prometheus_metrics async

prometheus_metrics(request: Request)

Prometheus-compatible metrics endpoint.

Source code in src/openjarvis/server/api_routes.py
@metrics_router.get("/metrics")
async def prometheus_metrics(request: Request):
    """Prometheus-compatible metrics endpoint."""
    try:
        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.telemetry.aggregator import TelemetryAggregator

        db_path = DEFAULT_CONFIG_DIR / "telemetry.db"
        if not db_path.exists():
            from starlette.responses import PlainTextResponse
            return PlainTextResponse("# no telemetry data\n", media_type="text/plain")

        agg = TelemetryAggregator(db_path)
        stats = agg.summary()

        lines = [
            "# HELP openjarvis_requests_total Total requests processed",
            "# TYPE openjarvis_requests_total counter",
            f"openjarvis_requests_total {stats.get('total_requests', 0)}",
            "# HELP openjarvis_tokens_total Total tokens generated",
            "# TYPE openjarvis_tokens_total counter",
            f"openjarvis_tokens_total {stats.get('total_tokens', 0)}",
            "# HELP openjarvis_latency_avg_ms Average latency in milliseconds",
            "# TYPE openjarvis_latency_avg_ms gauge",
            f"openjarvis_latency_avg_ms {stats.get('avg_latency_ms', 0)}",
        ]
        from starlette.responses import PlainTextResponse
        return PlainTextResponse("\n".join(lines) + "\n", media_type="text/plain")
    except Exception as exc:
        logger.warning("Failed to collect Prometheus metrics: %s", exc)
        from starlette.responses import PlainTextResponse
        return PlainTextResponse(
            "# No metrics available\n", media_type="text/plain"
        )

websocket_chat_stream async

websocket_chat_stream(websocket: WebSocket)

Stream chat responses over a WebSocket connection.

Accepts JSON messages of the form::

{"message": "...", "model": "...", "agent": "..."}

Sends back JSON chunks::

{"type": "chunk", "content": "..."}   -- per-token streaming
{"type": "done",  "content": "..."}   -- final assembled response
{"type": "error", "detail": "..."}    -- on failure
Source code in src/openjarvis/server/api_routes.py
@websocket_router.websocket("/v1/chat/stream")
async def websocket_chat_stream(websocket: WebSocket):
    """Stream chat responses over a WebSocket connection.

    Accepts JSON messages of the form::

        {"message": "...", "model": "...", "agent": "..."}

    Sends back JSON chunks::

        {"type": "chunk", "content": "..."}   -- per-token streaming
        {"type": "done",  "content": "..."}   -- final assembled response
        {"type": "error", "detail": "..."}    -- on failure
    """
    await websocket.accept()
    try:
        while True:
            raw = await websocket.receive_text()
            try:
                data = json.loads(raw)
            except (json.JSONDecodeError, ValueError):
                await websocket.send_json(
                    {"type": "error", "detail": "Invalid JSON"},
                )
                continue

            message = data.get("message")
            if not message:
                await websocket.send_json(
                    {"type": "error", "detail": "Missing 'message' field"},
                )
                continue

            model = data.get("model") or getattr(
                websocket.app.state, "model", "default",
            )
            engine = getattr(websocket.app.state, "engine", None)
            if engine is None:
                await websocket.send_json(
                    {"type": "error", "detail": "No engine configured"},
                )
                continue

            messages = [{"role": "user", "content": message}]

            try:
                # Prefer streaming if the engine supports it
                stream_fn = getattr(engine, "stream", None)
                if stream_fn is not None and (
                    inspect.isasyncgenfunction(stream_fn)
                    or callable(stream_fn)
                ):
                    full_content = ""
                    try:
                        gen = stream_fn(messages, model=model)
                        # Handle both async and sync generators
                        if inspect.isasyncgen(gen):
                            async for token in gen:
                                full_content += token
                                await websocket.send_json(
                                    {"type": "chunk", "content": token},
                                )
                        else:
                            # Sync generator — iterate in a thread to avoid
                            # blocking the event loop
                            for token in gen:
                                full_content += token
                                await websocket.send_json(
                                    {"type": "chunk", "content": token},
                                )
                    except TypeError:
                        # stream() didn't return an iterable; fall back to
                        # generate()
                        result = engine.generate(messages, model=model)
                        content = result.get("content", "") if isinstance(
                            result, dict,
                        ) else str(result)
                        full_content = content
                        await websocket.send_json(
                            {"type": "chunk", "content": content},
                        )
                    await websocket.send_json(
                        {"type": "done", "content": full_content},
                    )
                else:
                    # No stream method — single-shot generate
                    result = engine.generate(messages, model=model)
                    content = result.get("content", "") if isinstance(
                        result, dict,
                    ) else str(result)
                    await websocket.send_json(
                        {"type": "chunk", "content": content},
                    )
                    await websocket.send_json(
                        {"type": "done", "content": content},
                    )
            except WebSocketDisconnect:
                raise
            except Exception as exc:
                await websocket.send_json(
                    {"type": "error", "detail": str(exc)},
                )
    except WebSocketDisconnect:
        pass  # Client disconnected — nothing to clean up

learning_stats async

learning_stats(request: Request)

Return learning system statistics across all sub-policies.

Source code in src/openjarvis/server/api_routes.py
@learning_router.get("/stats")
async def learning_stats(request: Request):
    """Return learning system statistics across all sub-policies."""
    result: Dict[str, Any] = {}

    # GRPO policy state
    try:
        from openjarvis.learning.grpo_policy import GRPORouterPolicy
        policy = GRPORouterPolicy()
        state = policy.state
        result["grpo"] = {
            "available": True,
            "total_updates": state.total_updates,
            "sample_counts": dict(state.sample_counts),
            "weight_count": sum(
                len(qc_weights) for qc_weights in state.weights.values()
            ),
        }
    except Exception as exc:
        logger.warning("Failed to load GRPO stats: %s", exc)
        result["grpo"] = {"available": False}

    # Bandit router state
    try:
        from openjarvis.learning.bandit_router import BanditRouterPolicy
        policy = BanditRouterPolicy()
        stats = policy.get_stats()
        result["bandit"] = {
            "available": True,
            "query_classes": len(stats),
            "arms": stats,
        }
    except Exception as exc:
        logger.warning("Failed to load bandit stats: %s", exc)
        result["bandit"] = {"available": False}

    # ICL updater
    try:
        from openjarvis.learning.icl_updater import ICLUpdaterPolicy
        updater = ICLUpdaterPolicy()
        result["icl"] = {
            "available": True,
            "example_count": len(updater.examples),
            "example_db_count": len(updater.example_db),
            "version": updater.version,
        }
    except Exception as exc:
        logger.warning("Failed to load ICL stats: %s", exc)
        result["icl"] = {"available": False}

    # Skill discovery
    try:
        from openjarvis.learning.skill_discovery import SkillDiscovery
        discovery = SkillDiscovery()
        result["skill_discovery"] = {
            "available": True,
            "discovered_count": len(discovery.discovered_skills),
        }
    except Exception as exc:
        logger.warning("Failed to load skill discovery stats: %s", exc)
        result["skill_discovery"] = {"available": False}

    return result

learning_policy async

learning_policy(request: Request)

Return current routing policy configuration.

Source code in src/openjarvis/server/api_routes.py
@learning_router.get("/policy")
async def learning_policy(request: Request):
    """Return current routing policy configuration."""
    result: Dict[str, Any] = {}

    # Load config and extract learning section
    try:
        from openjarvis.core.config import load_config
        config = load_config()
        lc = config.learning
        result["enabled"] = lc.enabled
        result["update_interval"] = lc.update_interval
        result["auto_update"] = lc.auto_update
        result["routing"] = {
            "policy": lc.routing.policy,
            "min_samples": lc.routing.min_samples,
        }
        result["intelligence"] = {
            "policy": lc.intelligence.policy,
        }
        result["agent"] = {
            "policy": lc.agent.policy,
        }
        result["metrics"] = {
            "accuracy_weight": lc.metrics.accuracy_weight,
            "latency_weight": lc.metrics.latency_weight,
            "cost_weight": lc.metrics.cost_weight,
            "efficiency_weight": lc.metrics.efficiency_weight,
        }
    except Exception as exc:
        logger.warning("Failed to load learning config: %s", exc)
        result["enabled"] = False
        result["routing"] = {"policy": "heuristic", "min_samples": 5}
        result["intelligence"] = {"policy": "none"}
        result["agent"] = {"policy": "none"}
        result["metrics"] = {}

    # Include GRPO weights if the routing policy is grpo
    if result.get("routing", {}).get("policy") == "grpo":
        try:
            from openjarvis.learning.grpo_policy import GRPORouterPolicy
            policy = GRPORouterPolicy()
            state = policy.state
            result["grpo_weights"] = {
                model: dict(qc_weights)
                for model, qc_weights in state.weights.items()
            }
        except Exception as exc:
            logger.warning("Failed to load GRPO weights: %s", exc)
            result["grpo_weights"] = {}

    return result

transcribe_speech async

transcribe_speech(request: Request)

Transcribe uploaded audio to text.

Source code in src/openjarvis/server/api_routes.py
@speech_router.post("/transcribe")
async def transcribe_speech(request: Request):
    """Transcribe uploaded audio to text."""
    backend = getattr(request.app.state, "speech_backend", None)
    if backend is None:
        raise HTTPException(status_code=501, detail="Speech backend not configured")

    form = await request.form()
    audio_file = form.get("file")
    if audio_file is None:
        raise HTTPException(status_code=400, detail="Missing 'file' field")

    audio_bytes = await audio_file.read()
    language = form.get("language")

    # Detect format from filename
    filename = getattr(audio_file, "filename", "audio.wav")
    ext = filename.rsplit(".", 1)[-1] if "." in filename else "wav"

    result = backend.transcribe(audio_bytes, format=ext, language=language or None)
    return {
        "text": result.text,
        "language": result.language,
        "confidence": result.confidence,
        "duration_seconds": result.duration_seconds,
    }

speech_health async

speech_health(request: Request)

Check if a speech backend is available.

Source code in src/openjarvis/server/api_routes.py
@speech_router.get("/health")
async def speech_health(request: Request):
    """Check if a speech backend is available."""
    backend = getattr(request.app.state, "speech_backend", None)
    if backend is None:
        return {"available": False, "reason": "No speech backend configured"}
    return {
        "available": backend.health(),
        "backend": backend.backend_id,
    }

submit_feedback async

submit_feedback(req: FeedbackScoreRequest, request: Request)

Submit feedback for a trace.

Source code in src/openjarvis/server/api_routes.py
@feedback_router.post("")
async def submit_feedback(req: FeedbackScoreRequest, request: Request):
    """Submit feedback for a trace."""
    try:
        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.traces.store import TraceStore

        db_path = DEFAULT_CONFIG_DIR / "traces.db"
        if not db_path.exists():
            raise HTTPException(status_code=404, detail="No trace database")

        store = TraceStore(db_path)
        updated = store.update_feedback(req.trace_id, req.score)
        store.close()

        if not updated:
            raise HTTPException(
                status_code=404, detail=f"Trace '{req.trace_id}' not found"
            )
        return {"status": "recorded", "trace_id": req.trace_id}
    except HTTPException:
        raise
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc))

feedback_stats async

feedback_stats(request: Request)

Get feedback statistics.

Source code in src/openjarvis/server/api_routes.py
@feedback_router.get("/stats")
async def feedback_stats(request: Request):
    """Get feedback statistics."""
    return {"total": 0, "mean_score": 0.0}

list_optimize_runs async

list_optimize_runs(request: Request)

List optimization runs.

Source code in src/openjarvis/server/api_routes.py
@optimize_router.get("/runs")
async def list_optimize_runs(request: Request):
    """List optimization runs."""
    try:
        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.learning.optimize.store import OptimizationStore

        db_path = DEFAULT_CONFIG_DIR / "optimize.db"
        if not db_path.exists():
            return {"runs": []}

        store = OptimizationStore(db_path)
        runs = store.list_runs()
        store.close()
        return {"runs": runs}
    except Exception as exc:
        logger.warning("Failed to list optimization runs: %s", exc)
        return {"runs": []}

get_optimize_run async

get_optimize_run(run_id: str, request: Request)

Get optimization run details.

Source code in src/openjarvis/server/api_routes.py
@optimize_router.get("/runs/{run_id}")
async def get_optimize_run(run_id: str, request: Request):
    """Get optimization run details."""
    try:
        from openjarvis.core.config import DEFAULT_CONFIG_DIR
        from openjarvis.learning.optimize.store import OptimizationStore

        db_path = DEFAULT_CONFIG_DIR / "optimize.db"
        if not db_path.exists():
            return {"run_id": run_id, "status": "not_found"}

        store = OptimizationStore(db_path)
        run = store.get_run(run_id)
        store.close()

        if run is None:
            return {"run_id": run_id, "status": "not_found"}

        return {
            "run_id": run.run_id,
            "status": run.status,
            "benchmark": run.benchmark,
            "trials": len(run.trials),
            "best_trial_id": (
                run.best_trial.trial_id if run.best_trial else None
            ),
        }
    except Exception as exc:
        logger.warning(
            "Failed to get optimization run %s: %s", run_id, exc
        )
        return {"run_id": run_id, "status": "not_found"}

start_optimize_run async

start_optimize_run(req: OptimizeRunRequest, request: Request)

Start a new optimization run.

Source code in src/openjarvis/server/api_routes.py
@optimize_router.post("/runs")
async def start_optimize_run(req: OptimizeRunRequest, request: Request):
    """Start a new optimization run."""
    return {"status": "started", "run_id": "placeholder"}

include_all_routes

include_all_routes(app) -> None

Include all extended API routers in a FastAPI app.

Source code in src/openjarvis/server/api_routes.py
def include_all_routes(app) -> None:
    """Include all extended API routers in a FastAPI app."""
    app.include_router(agents_router)
    app.include_router(memory_router)
    app.include_router(traces_router)
    app.include_router(telemetry_router)
    app.include_router(skills_router)
    app.include_router(sessions_router)
    app.include_router(budget_router)
    app.include_router(metrics_router)
    app.include_router(websocket_router)
    app.include_router(learning_router)
    app.include_router(speech_router)
    app.include_router(feedback_router)
    app.include_router(optimize_router)

    # Agent Manager routes (if available)
    try:
        if hasattr(app.state, "agent_manager") and app.state.agent_manager:
            from openjarvis.server.agent_manager_routes import (  # noqa: PLC0415
                create_agent_manager_router,
            )
            agents_r, templates_r, global_r = create_agent_manager_router(
                app.state.agent_manager
            )
            app.include_router(agents_r)
            app.include_router(templates_r)
            app.include_router(global_r)
    except ImportError:
        pass

    # WebSocket bridge for real-time agent events
    try:
        from openjarvis.core.events import get_event_bus
        from openjarvis.server.ws_bridge import create_ws_router

        ws_router = create_ws_router(get_event_bus())
        app.include_router(ws_router)
    except Exception:
        logger.debug("WebSocket bridge not available", exc_info=True)