Skip to main content
agentscope-extensions-agent-protocol exposes AgentScope’s Harness Agent as a standard Agent Protocol HTTP API, letting external systems (CI, other agent platforms, automation jobs) submit “tasks” using a uniform contract — no need to know the implementation details.

When to use

  • You want the Agent to be remotely scheduled like a cloud function.
  • An existing team uses an Agent Protocol client and you’d like to plug in directly.
  • You’re embedding a Harness Agent in a Spring Boot service and want auto-exposed /tasks REST endpoints.
  • You’re hosting a remote subagent that another Harness parent calls over HTTP.

Protocol layering

AgentScope uses different protocols for different trust / UX boundaries:

Add the dependency

Enable

The module is delivered as a Spring Boot auto-configuration. In a Spring Boot app:
  1. Provide a HarnessAgent bean (or a custom AgentFactory).
  2. Enable in application.yml:
The /tasks REST endpoints are then registered automatically.

Control-plane vs execution workspace

AgentProtocolTaskStore persists protocol task metadata (TaskRecord for submit / resume / snapshot) through a dedicated ProtocolTaskRepository. By default that repository is rooted at agentscope.agent-protocol.task-store-path (${user.dir}/.agentscope/agent-protocol), under the synthetic bucket agents/_agentscope_protocol/tasks/. This path is independent of each HarnessAgent’s own WorkspaceManager (MEMORY, sessions, skills). Multi-agent factories may give each agent a different .workspace(...); protocol task_id lookup always goes through the control-plane repository. You may supply your own ProtocolTaskRepository bean to override the default. Construct AgentProtocolTaskStore with a ProtocolTaskRepository only — do not pass an execution agent’s WorkspaceManager.

Concurrent execution

The agent is stateless between calls — a singleton handles multiple concurrent tasks. Each task carries its own (userId, sessionId) via RuntimeContext, so state is fully isolated:
Concurrent requests for the same session are automatically serialized; different sessions run in parallel.

Agent selection (AgentFactory)

Which agent runs a task is decided by an AgentFactory bean. Without one, the default factory returns the single HarnessAgent bean for every task. Define your own bean to route by agent_id, tenant, or any custom submission-context key:
AgentRequest fields: The factory is invoked once per run — on submit and again on every /resume — with the original submission context, so routing decisions stay stable across HITL pauses. Return a distinct instance per call (for example a prototype-scoped bean) when tasks run concurrently. Returning null fails the task with an error status.

Context attributes

Callers pass their own data in context.attributes, nested so it never mixes with the protocol’s own context fields. Besides being visible to the AgentFactory, attributes reach the running agent through its RuntimeContext. They arrive as one map under a single namespaced key, AgentProtocolConstants.RUNTIME_CONTEXT_ATTRIBUTES_KEY (agentprotocol.context.attributes):
Attributes are namespaced rather than written as top-level keys because the framework itself reads a few plain runtime-context keys — agentId drives async tool wakeup routing, outboundAddress carries the gateway reply address. A caller naming an attribute after one of those would otherwise change how the agent behaves. Attributes are never rendered into the system prompt, so they do not affect what the model sees.

Promoting attributes to their own keys

Register RuntimeContextCustomizer beans when a tool expects a plain key such as ctx.get("tenant"), or to turn attributes into typed values. RuntimeContextCustomizer.flatten copies an explicit allow-list, silently skipping framework-reserved names:
Every customizer bean is applied to every run, in @Order, after the namespaced injection — a later customizer overrides an earlier one. Hand-written customizers are trusted and may write any key, including reserved ones.

Sending attributes from a parent agent

A parent agent delegating to a remote subagent supplies attributes in two ways, merged with the per-call ones winning:
Values must be JSON-serializable.

Endpoints

Submit a task

POST /tasks
Optional context fields: Response on success: { "task_id", "status": "pending" }.

Poll / wait / cancel

While the remote agent waits for tool confirmation, the snapshot reports status: awaiting_confirm but the stored TaskStatus remains RUNNING so parent barriers keep waiting.

Stream events (SSE)

GET /tasks/{taskId}/events Server-Sent Events of agent progress. Requires agentscope.agent-protocol.streaming-enabled=true (default). Reconnect / resume:
  • Query param from_seq — start after this sequence number
  • Header Last-Event-ID — used when from_seq is omitted (same meaning)
Each SSE message uses the event seq as id, the remote event type as event, and a JSON body as data.

Stream detail levels

context.detail on submission decides how much of the run reaches subscribers. Each level is a superset of the previous one: Only verbose reproduces the agent’s own event stream in full. An unrecognized value is treated as status. Every event body also carries two fields beyond its type-specific ones: Both are additive: a client that ignores them keeps reading the flat fields (text, toolCallId, status, …) exactly as before, and one that predates AGENT_EVENT simply skips those messages.

Resume after HITL

POST /tasks/{taskId}/resume
tool_call_id is also accepted as an alias for toolCallId. Requires agentscope.agent-protocol.hitl-enabled=true (default). On success returns { "task_id", "status": "running" }. How remote HITL interacts with a calling parent harness is documented under Remote authorization.

Configuration

Example:
When enabled is false (the default) the dependency stays inert — no REST endpoints are exposed, safe to ship.

Workspace integration

Each task receives an isolated workspace from WorkspaceManager. Once the task finishes, files and logs in the workspace are exposed via standard Agent Protocol endpoints so external clients can fetch artifacts.