feat(agents): framework generic server — 5-interface standard for agents (#1101)#1403
Conversation
…nts (#1101) Agents previously had to hand-roll their own server glue to be reachable as anything other than an interactive session — every package reimplemented REST and MCP wiring, and most simply never got an API or MCP surface at all. This adds a framework-provided generic server so ANY Agent instance is exposed through the same five interface modes (the gaia-bash PR #985 pattern) without implementing server logic itself: interactive TUI, one-shot CLI (--prompt), pipe (stdin→stdout), OpenAI-compatible REST API (--api --port), and MCP stdio server (--mcp). AgentServer wraps any Agent and reuses the existing REST schemas (gaia.api.schemas) and MCP tool conventions rather than duplicating them. run_agent_cli(agent, argv) is the single entry point a package wires to its console script; it dispatches on the flags above. When a parsed gaia-agent.yaml is supplied, its `interfaces` block gates the allowed modes — requesting a disabled interface fails loudly with an actionable error instead of degrading silently.
Code Review — framework generic server (5-interface standard)Approve with suggestions. This is a clean, well-tested additive module — a single Issues🟢 Non-streaming 🟢 A manifest without an 🟢 🟢 Strengths
Notes (non-blocking)
VerdictApprove with suggestions — no blocking issues. All four findings are 🟢 minor; the event-loop one is the only one with runtime impact and it merely matches the existing server's behaviour. Safe to merge; applying the suggestions (especially the threadpool offload, given this is framework-level code) would make it the better template for everything that inherits it. |
Why this matters
Before, an agent could only be reached the way it hand-wrote support for — every package that wanted a REST or MCP surface reimplemented the server glue, and most agents simply never got one. This adds a framework-provided generic server: any
Agentinstance is now exposed through the same five interface modes (the gaia-bash PR #985 pattern) without implementing any server logic itself — interactive TUI, one-shot CLI (--prompt), pipe (stdin→stdout), OpenAI-compatible REST API (--api --port), and MCP stdio server (--mcp). An agent package wires one line —return run_agent_cli(MyAgent())— and gets all five.AgentServerreuses the existing REST schemas (gaia.api.schemas) and MCP tool conventions instead of duplicating them. When a parsedgaia-agent.yamlis supplied, itsinterfacesblock gates the allowed modes: requesting a disabled interface fails loudly with an actionable error (per the fail-loudly rule) rather than degrading silently.This is additive — a new
src/gaia/agents/base/server.pyplus tests, no existing behaviour changed. It does not depend on the #1102 agent-hub restructure; thegaia agent runCLI wiring lands with that work via entry-point discovery.Implements the generic-server scope of #1101 and Key Decision #5 of
docs/spec/agent-hub-restructure.mdx.Test plan
PYTHONPATH=src python -m pytest tests/unit/test_agent_server.py -xvs→ 27 passed/v1/chat/completionsnon-streaming + SSE,/v1/models,/v1/tools,/health), 404 on wrong model, 400 on missing user messageinitialize,tools/list,tools/call(incl.isError),prompts/listfrom manifest, unknown-method-32601, notification → no response, malformed-JSON-32700, full stdin→stdout looprun_agent_clidispatch; manifest-disabled interface → actionable error + exit 1python util/lint.py --pylint --black --isort --fix→ black & isort PASS; pylint clean on changed files (the one reported error is pre-existingos.geteuiddebt inlemonade_installer.py, untouched here)Closes part of #1101.