fix: mount JSON-RPC at root — platform POSTs to /, not /api/v1/jsonrpc/

Baseline restart 2026-04-24: every workspace came up healthy (uvicorn
listening, agent-card serving) but produced zero delegations for two
maintenance cycles. Tracing revealed platform's ProxyA2A POSTs to
`http://ws-<id>:8000/` (no path suffix, see
workspace-server/internal/provisioner.InternalURL) while the runtime's
JSON-RPC routes were mounted at `/api/v1/jsonrpc/` under the a2a-sdk
1.x API migration.

Result was silent — every inbound A2A returned 404 Not Found, the
platform logged "Not Found" at INFO level, but no error bubbled up
because the SDK's jsonrpc route factory doesn't respond to root when
mounted at a subpath. Agents stayed warm, crons fired, but no work
flowed.

Fix: `create_jsonrpc_routes(handler, "/")` — matches platform
expectation and the agent-card self-advertisement (which also shows
root as the JSON-RPC URL). Agent-card route keeps its hard-coded
`/.well-known/agent-card.json` path so there's no collision.

Bumped to 0.1.12.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
rabbitblood 2026-04-24 02:06:04 -07:00
parent 64720c0fc6
commit 30ebe9baf3
2 changed files with 10 additions and 3 deletions

View File

@ -217,10 +217,17 @@ async def main(): # pragma: no cover
agent_card=agent_card,
)
# Build Starlette app from route factory functions (a2a-sdk 1.x API)
# Build Starlette app from route factory functions (a2a-sdk 1.x API).
# JSON-RPC mounts at root because the platform's ProxyA2A (the only
# caller in this deployment) POSTs to `http://ws-<id>:8000/` — no
# path suffix. See workspace-server/internal/provisioner.InternalURL
# which returns the Docker-DNS form without a path. Mounting
# anywhere else produces 404 on every inbound A2A and silent fleet-
# wide productivity loss (baseline restart 2026-04-24: 0 delegations
# for 2 cycles until this was traced to `/api/v1/jsonrpc/`).
routes = []
routes.extend(create_agent_card_routes(agent_card))
routes.extend(create_jsonrpc_routes(handler, "/api/v1/jsonrpc/"))
routes.extend(create_jsonrpc_routes(handler, "/"))
app = Starlette(routes=routes)
# 8. Register with platform

View File

@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "molecule-ai-workspace-runtime"
version = "0.1.11"
version = "0.1.12"
description = "Molecule AI workspace runtime — shared infrastructure for all agent adapters"
requires-python = ">=3.11"