feat(public-api): expose Agent metadata and runtime status endpoints
- Dominant language
- TypeScript
- Stars
- 148
- Forks
- 26
- Avg merge
- 5h 6m
- Merged PRs (30d)
- 40
Description
## Area
API / Runtime / Developer tooling
## Problem
Mosoo already exposes a public HTTP API for creating and operating Threads, but an integrating backend cannot query the control-plane and runtime metadata of the Agent it is calling without using the Console GraphQL surface or the SDK.
This leaves business applications with four practical gaps:
1. Given an `agentId`, there is no public API to retrieve the Agent's effective configuration and metadata.
2. Given an `agentId`, there is no public API to determine the lifecycle/health of the Agent runtime instance currently serving it.
3. Given an `appId`, there is no public API to retrieve the Agent IDs belonging to that App.
4. Given a `threadId`, `GET /api/v1/threads/{threadId}` returns Thread and Run summaries, but not the backing Sandbox state or the corresponding Agent Driver/process state.
Consequently, an App integrating Mosoo must maintain its own partial logs, infer health from request timeouts, or build custom recovery logic around incomplete signals. That makes observability, incident diagnosis, failover, and retry decisions fragile, especially when a Sandbox is provisioning, a Driver is reconnecting, or a process has stopped while the Thread record remains readable.
The repository already has the relevant internal sources of truth, but they are not exposed through the public OpenAPI contract:
- `apps/api/src/adapters/http/routes/public-api-route.ts` registers the current `/api/v1` HTTP surface.
- `apps/api/src/adapters/http/routes/public-api-openapi.ts` describes the current OpenAPI document.
- `apps/api/src/modules/agents/application/agent-query.service.ts` already serves Agent detail, editor/configuration state, and App-scoped Agent lists for authenticated Console queries.
- `apps/api/src/modules/public-api/public-thread-retrieve.ts` and `public-thread-presenter.ts` currently project only Thread/Run summaries.
- Runtime persistence already links Sessions, Sandboxes, Driver Instances, and Runs in `apps/api/src/modules/runtime/infrastructure/driver-instance/session-link.repository.ts`; Driver heartbeat/ready/close state is maintained by `runtime-state-store.ts`, with lifecycle states defined in `driver-instance-lifecycle.machine.ts`.
## Proposal
Add read-only, authenticated Public API endpoints and document them in `/api/v1/openapi.json` (exact paths may be adjusted to match existing naming conventions):
### 1. Retrieve Agent configuration and metadata
`GET /api/v1/agents/{agentId}` or a clearly named `/configuration` endpoint.
The response should expose a stable, integration-safe representation of the Agent, including at least:
- `agentId`, `appId`, name, description, kind, publication status, and timestamps;
- effective provider/runtime/model settings and the active configuration/deployment version where applicable;
- Environment, Skill, MCP/tool binding, and readiness metadata needed to explain why an Agent can or cannot run;
- explicit redaction/exclusion of provider credentials, tokens, secret values, private boot payloads, environment-variable values, and other internal runtime data.
The contract must distinguish saved/effective Agent configuration from a live runtime instance and must not imply that a Thread created before a republish silently adopts the newer configuration.
### 2. Retrieve Agent runtime-instance lifecycle
`GET /api/v1/agents/{agentId}/runtime-status` (or an equivalent name).
Return a normalized, machine-readable status for the Agent's current runtime instance(s), including the lifecycle state, Sandbox reference/state, Driver connection/readiness, last heartbeat, current Run/Thread references when available, and a safe error/reason/retryability summary.
The semantics must be explicit for both runtime kinds:
- Pet Agents may have a stable Agent-level Sandbox.
- Cattle Agents use Session/Run-scoped Sandboxes and must not be represented as having a permanent Agent-level instance when none exists.
If more than one instance can be active, return a list or an explicitly documented aggregate rather than silently selecting one.
### 3. List Agents by App
`GET /api/v1/apps/{appId}/agents` (or an equivalent App-scoped endpoint).
Return the Agent IDs and the minimum metadata needed for an integrating backend to discover and select the correct published Agent. Authorization must enforce App ownership/visibility and must not allow an Access Token to enumerate another App's Agents.
### 4. Retrieve Thread + Sandbox + Agent process status
`GET /api/v1/threads/{threadId}/runtime-status` (or extend the existing Thread retrieval response with a separately documented runtime block).
Return one correlated status document containing:
- Thread and current Run lifecycle status;
- the backing Sandbox ID/kind/subject and lifecycle/provisioning status;
- the corresponding Agent Driver/process identity and status, including connected/ready state, heartbeat freshness, start/stop/close information, and a safe failure reason;
- timestamps and correlation IDs sufficient for the caller's logs and recovery decisions.
The endpoint should use the same Public API caller admission as the existing Thread endpoints and should make the difference between persisted Thread state, Sandbox state, and live Driver/Agent process state explicit. It must return a stable `unknown`/`unavailable` state when the live runtime has already been recycled, rather than fabricate health from a stale Thread record.
## Acceptance criteria
- [ ] All four read-only capabilities are available without Console GraphQL or an SDK.
- [ ] `/api/v1/openapi.json` documents paths, authentication, response schemas, status enums, redaction rules, and examples.
- [ ] Agent configuration reads use the canonical Agent/App services and never expose credentials, tokens, raw environment values, private boot payloads, or raw runtime diagnostics.
- [ ] App-to-Agent listing is App-scoped and enforces the same ownership boundary as existing Agent/App queries.
- [ ] Agent and Thread runtime responses distinguish control-plane lifecycle, Sandbox lifecycle, Driver readiness/heartbeat, and Agent-process availability.
- [ ] Pet versus Cattle Sandbox semantics are documented and covered by tests; Cattle is not reported as a permanent Agent Sandbox.
- [ ] Thread runtime reads authorize the caller against the Thread's existing Public API admission rules and do not leak cross-App or cross-Token data.
- [ ] Tests cover provisioning, ready/healthy, reconnecting/stale heartbeat, failed/stopped, recycled/unavailable, missing runtime, and a Thread whose last Run is terminal.
- [ ] The typed Public API client and integration documentation are updated if they are maintained as supported generated/manual surfaces.
- [ ] No new write or control operation is introduced by this request; restart/recreate/reset remain separate authenticated Console/runtime operations.
## Alternatives considered
- Continue requiring callers to use Console GraphQL. This does not provide the intended backend-to-backend Public API contract and does not solve the Thread-to-Sandbox/process correlation.
- Ask each integrating application to parse Thread events or maintain its own health log. This duplicates Mosoo's runtime knowledge and cannot reliably distinguish a stale persisted record from a live process.
- Expose raw D1 rows or raw Driver/Sandbox payloads. This would couple integrations to internal storage/protocol details and risks leaking credentials, environment values, or private diagnostics.
## Compatibility and migration
This should be additive and read-only. Existing Thread, Run, and event endpoints must remain backward compatible. The new responses should use stable public DTOs and machine-readable enums, with `null`/`unknown` semantics for resources that are not currently live or have already been recycled. No database migration should be required if the existing control-plane and Driver state projections are sufficient; if a new projection is needed, its ownership and retention must be documented.
The existing Access Token model is account-based and currently documented as not carrying scopes. The implementation should preserve the current authentication contract or explicitly define any additional App/Agent/Thread authorization checks before shipping; it must not weaken the existing App-owner and Public Thread admission boundaries.
## Contribution
I can provide product feedback
## Checklist
- [x] I searched existing issues before opening this request.
- [x] I described the problem before the proposed solution.
- [x] I kept this request focused on one improvement: a read-only Public API metadata/runtime-status surface for Agent integrations.
## Additional context
Service callers want to retrieve the configuration, ownership relationships, and runtime status of the Agent they invoke from their own business services, without depending on the SDK or integrating with Console GraphQL. They need this for business logging, monitoring, timeout decisions, retries, and disaster recovery. The requirement is not for callers to parse logs themselves, but for Mosoo to expose the Agent / App / Thread / Sandbox / Driver state it already knows through a stable, sanitized OpenAPI contract.
Contributor guide
Research direction
Start with apps/api/src/adapters/http/routes/public-api-route.ts and public-api-openapi.ts, then read agent-query.service.ts, public-thread-retrieve.ts, public-thread-presenter.ts, session-link.repository.ts, runtime-state-store.ts, and driver-instance-lifecycle.machine.ts. Trace existing authentication and public Thread admission before defining stable sanitized response schemas and lifecycle semantics. Done means all four read-only capabilities are documented, authorized, covered by the required runtime-state tests, and keep Pet/Cattle and unavailable-runtime distinctions explicit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend-api-design, observability
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100