You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3d46165
Browse filesBrowse the repository at this point in the historyBrowse files
Mark Pollack
committed
Advertise what an annotated agent's annotations declare in its initialize response
Without an @initialize method an annotated agent answered InitializeResponse.ok(),
so every handler beyond the baseline went unadvertised and @AcpAgent's name and
version were never sent. The response is now derived from the annotation model:
handler annotations map to capabilities, @AcpAgent gives agentInfo, auth methods
and MCP transports, and @prompt the prompt content accepted. An @initialize
response is laid over the derived one.
The agent answers `initialize` with what its annotations declare: a capability for each handler
192
+
(`@LoadSession` advertises `loadSession`, and so on), `agentInfo` from `@AcpAgent`, and declared
193
+
auth methods, prompt content and MCP transports. No `@Initialize` method is needed.
194
+
196
195
### 3. Hello World Agent (Sync)
197
196
198
197
The builder API with blocking handlers and plain return values ([tutorial](https://github.com/markpollack/acp-java-tutorial/tree/main/module-13-agent-handlers)):
No `@Initialize` method is needed: the agent answers `initialize` with what its annotations declare
31
+
(see [Advertising Capabilities](#advertising-capabilities)).
32
+
35
33
## Installation
36
34
37
35
Add the dependency to your `pom.xml`:
@@ -52,31 +50,32 @@ This module transitively includes `acp-annotations` and `acp-core`.
52
50
53
51
| Annotation | Description |
54
52
|------------|-------------|
55
-
|`@AcpAgent`| Marks a class as an ACP agent. Required on all agent classes. Its optional `name` and `version` attributes are descriptive only: the runtime does not read them, so report the agent's identity in the `InitializeResponse` (`agentInfo`). |
53
+
|`@AcpAgent`| Marks a class as an ACP agent. Required on all agent classes. Its attributes are advertised in the `initialize` response: `name`, `version` and `title` as `agentInfo` (the name defaults to the class's simple name, the version to the jar manifest's `Implementation-Version`, else `"unknown"`), `authMethods` (`@AuthMethod`s) as `authMethods`, and `mcpHttp`/`mcpSse` as `mcpCapabilities`. |
54
+
|`@AuthMethod`| One authentication method inside `@AcpAgent(authMethods = ...)`: `id`, `name`, `description`, and `type``AGENT` (served by `@Authenticate`) or `TERMINAL` (the client reruns the agent program with `args` and `env`). |
56
55
57
56
### Handler Methods
58
57
59
-
| Annotation | JSON-RPC Method | Description |
60
-
|------------|-----------------|-------------|
61
-
|`@Initialize`|`initialize`|Handles protocol initialization and capability negotiation. Without one, the agent answers `InitializeResponse.ok()`. |
62
-
|`@Authenticate`|`authenticate`| Authenticates with one of the methods the agent advertised in `authMethods`. |
63
-
|`@Logout`|`logout`| Clears stored credentials. |
64
-
|`@NewSession`|`session/new`| Creates a new agent session. Without one, the agent answers with a random session ID. |
65
-
|`@LoadSession`|`session/load`| Loads an existing session by ID, replaying its history. |
66
-
|`@ResumeSession`|`session/resume`| Reconnects to an existing session without replaying history. |
67
-
|`@ListSessions`|`session/list`| Lists sessions, optionally filtered by working directory. |
68
-
|`@CloseSession`|`session/close`| Closes an active session. |
69
-
|`@DeleteSession`|`session/delete`| Permanently deletes a stored session. |
70
-
|`@ForkSession`|`session/fork`| Creates a session branched from an existing one (unstable, `@UnstableAcpApi`). |
71
-
|`@Prompt`|`session/prompt`| Handles user prompts within a session. |
72
-
|`@SetSessionMode`|`session/set_mode`| Changes the operational mode of a session. |
73
-
|`@SetSessionConfigOption`|`session/set_config_option`| Changes a session configuration option. |
74
-
|`@ListProviders`|`providers/list`| Lists the providers the agent can route to (unstable). |
75
-
|`@SetProvider`|`providers/set`| Configures a provider (unstable). |
76
-
|`@DisableProvider`|`providers/disable`| Disables a provider (unstable). |
77
-
|`@Cancel`|`session/cancel`| Handles cancellation notifications (fire-and-forget). The cancel does not end the prompt turn: the cancelled `@Prompt` method still returns, with stop reason `cancelled`, and the session rejects a new prompt until it has, or until the cancel grace period (default 60 s, `cancelGracePeriod`) passes and the agent answers `cancelled` itself. |
78
-
|`@ExtRequest("_name")`| any `_`-prefixed request | Serves a custom extension request; the name must start with `_`. |
79
-
|`@ExtNotification("_name")`| any `_`-prefixed notification | Handles a custom extension notification; the name must start with `_`. |
|`@Initialize`|`initialize`|(the exchange itself) | Optional. Without one, the agent answers with the response derived from its annotations; with one, the method's response is laid over the derived one (see [Advertising Capabilities](#advertising-capabilities)). |
61
+
|`@Authenticate`|`authenticate`|`authMethods`, from `@AcpAgent(authMethods = ...)`|Authenticates with one of the agent methods the agent advertised. |
|`@NewSession`|`session/new`|nothing (baseline) |Creates a new agent session. Without one, the agent answers with a random session ID. |
64
+
|`@LoadSession`|`session/load`|`loadSession`|Loads an existing session by ID, replaying its history. |
65
+
|`@ResumeSession`|`session/resume`|`sessionCapabilities.resume`|Reconnects to an existing session without replaying history. |
66
+
|`@ListSessions`|`session/list`|`sessionCapabilities.list`|Lists sessions, optionally filtered by working directory. |
67
+
|`@CloseSession`|`session/close`|`sessionCapabilities.close`|Closes an active session. |
68
+
|`@DeleteSession`|`session/delete`|`sessionCapabilities.delete`|Permanently deletes a stored session. |
69
+
|`@ForkSession`|`session/fork`|`sessionCapabilities.fork`|Creates a session branched from an existing one (unstable, `@UnstableAcpApi`). |
70
+
|`@Prompt`|`session/prompt`|`promptCapabilities`, from its `image`, `audio` and `embeddedContext` attributes |Handles user prompts within a session. |
71
+
|`@SetSessionMode`|`session/set_mode`|nothing (modes are offered per session) |Changes the operational mode of a session. |
72
+
|`@SetSessionConfigOption`|`session/set_config_option`|nothing (options are offered per session) |Changes a session configuration option. |
73
+
|`@ListProviders`|`providers/list`|`providers`|Lists the providers the agent can route to (unstable). |
74
+
|`@SetProvider`|`providers/set`|`providers`|Configures a provider (unstable). |
75
+
|`@DisableProvider`|`providers/disable`|`providers`|Disables a provider (unstable). |
76
+
|`@Cancel`|`session/cancel`|nothing (baseline) |Handles cancellation notifications (fire-and-forget). The cancel does not end the prompt turn: the cancelled `@Prompt` method still returns, with stop reason `cancelled`, and the session rejects a new prompt until it has, or until the cancel grace period (default 60 s, `cancelGracePeriod`) passes and the agent answers `cancelled` itself. |
77
+
|`@ExtRequest("_name")`| any `_`-prefixed request |nothing (agreed outside the protocol) |Serves a custom extension request; the name must start with `_`. |
78
+
|`@ExtNotification("_name")`| any `_`-prefixed notification |nothing |Handles a custom extension notification; the name must start with `_`. |
80
79
81
80
A method without a handler for it is answered with `-32601` (Method not found); a notification
82
81
without one is ignored.
@@ -87,6 +86,68 @@ without one is ignored.
87
86
|------------|-------------|
88
87
|`@SessionId`| Injects the current session ID as a `String`, in handlers of session-scoped methods. |
89
88
89
+
## Advertising Capabilities
90
+
91
+
A client learns what an agent supports from the agent's `initialize` response, and only uses what
92
+
is advertised there: a client that is not told `loadSession` never calls `session/load`. An annotated
93
+
agent's response is derived from its class, so every handler it has is advertised:
0 commit comments