@gaunt-sloth/agent 2.0.0-alpha.4 → 2.0.0-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +73 -23
  2. package/cli-acp.js +21 -24
  3. package/dist/builtInToolsConfig.d.ts +17 -3
  4. package/dist/builtInToolsConfig.js +43 -41
  5. package/dist/builtInToolsConfig.js.map +1 -1
  6. package/dist/core/debugCapture.d.ts +7 -49
  7. package/dist/core/debugCapture.js +1 -1
  8. package/dist/core/debugCapture.js.map +1 -1
  9. package/dist/core/resolveAgentFactory.d.ts +15 -0
  10. package/dist/core/resolveAgentFactory.js +17 -0
  11. package/dist/core/resolveAgentFactory.js.map +1 -0
  12. package/dist/index.d.ts +5 -4
  13. package/dist/index.js +8 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/mcp/OAuthClientProviderImpl.js.map +1 -1
  16. package/dist/mcp/tlsTrust.d.ts +61 -0
  17. package/dist/mcp/tlsTrust.js +109 -0
  18. package/dist/mcp/tlsTrust.js.map +1 -0
  19. package/dist/middleware/binaryContentInjectionMiddleware.d.ts +8 -1
  20. package/dist/middleware/binaryContentInjectionMiddleware.js +11 -2
  21. package/dist/middleware/binaryContentInjectionMiddleware.js.map +1 -1
  22. package/dist/middleware/frontendImageInjectionMiddleware.d.ts +107 -0
  23. package/dist/middleware/frontendImageInjectionMiddleware.js +167 -0
  24. package/dist/middleware/frontendImageInjectionMiddleware.js.map +1 -0
  25. package/dist/middleware/registry.js +49 -1
  26. package/dist/middleware/registry.js.map +1 -1
  27. package/dist/middleware/types.d.ts +16 -2
  28. package/dist/modules/a2a/A2AClientWrapper.d.ts +56 -1
  29. package/dist/modules/a2a/A2AClientWrapper.js +131 -31
  30. package/dist/modules/a2a/A2AClientWrapper.js.map +1 -1
  31. package/dist/modules/acp/acpAgentApp.d.ts +57 -0
  32. package/dist/modules/acp/acpAgentApp.js +378 -0
  33. package/dist/modules/acp/acpAgentApp.js.map +1 -0
  34. package/dist/modules/acp/acpAgentAppV1.d.ts +52 -0
  35. package/dist/modules/acp/acpAgentAppV1.js +307 -0
  36. package/dist/modules/acp/acpAgentAppV1.js.map +1 -0
  37. package/dist/modules/acp/acpCommon.d.ts +167 -0
  38. package/dist/modules/acp/acpCommon.js +282 -0
  39. package/dist/modules/acp/acpCommon.js.map +1 -0
  40. package/dist/modules/acp/acpPermissions.d.ts +65 -0
  41. package/dist/modules/acp/acpPermissions.js +162 -0
  42. package/dist/modules/acp/acpPermissions.js.map +1 -0
  43. package/dist/modules/acp/acpPermissionsV1.d.ts +45 -0
  44. package/dist/modules/acp/acpPermissionsV1.js +110 -0
  45. package/dist/modules/acp/acpPermissionsV1.js.map +1 -0
  46. package/dist/modules/acp/acpRouter.d.ts +41 -0
  47. package/dist/modules/acp/acpRouter.js +48 -0
  48. package/dist/modules/acp/acpRouter.js.map +1 -0
  49. package/dist/modules/acp/acpStdio.d.ts +47 -0
  50. package/dist/modules/acp/acpStdio.js +71 -0
  51. package/dist/modules/acp/acpStdio.js.map +1 -0
  52. package/dist/modules/acp/acpToolCalls.d.ts +93 -0
  53. package/dist/modules/acp/acpToolCalls.js +193 -0
  54. package/dist/modules/acp/acpToolCalls.js.map +1 -0
  55. package/dist/modules/acp/acpUpdates.d.ts +48 -0
  56. package/dist/modules/acp/acpUpdates.js +142 -0
  57. package/dist/modules/acp/acpUpdates.js.map +1 -0
  58. package/dist/modules/acp/acpUpdatesV1.d.ts +61 -0
  59. package/dist/modules/acp/acpUpdatesV1.js +162 -0
  60. package/dist/modules/acp/acpUpdatesV1.js.map +1 -0
  61. package/dist/modules/apiAgUiModule.d.ts +87 -0
  62. package/dist/modules/apiAgUiModule.js +225 -32
  63. package/dist/modules/apiAgUiModule.js.map +1 -1
  64. package/dist/modules/interactiveSessionModule.js +524 -50
  65. package/dist/modules/interactiveSessionModule.js.map +1 -1
  66. package/dist/modules/slashCommands.d.ts +582 -0
  67. package/dist/modules/slashCommands.js +1001 -0
  68. package/dist/modules/slashCommands.js.map +1 -0
  69. package/dist/resolvers.js +119 -9
  70. package/dist/resolvers.js.map +1 -1
  71. package/dist/tools/GthCustomToolkit.js +95 -11
  72. package/dist/tools/GthCustomToolkit.js.map +1 -1
  73. package/dist/tools/GthDevToolkit.d.ts +9 -33
  74. package/dist/tools/GthDevToolkit.js +94 -73
  75. package/dist/tools/GthDevToolkit.js.map +1 -1
  76. package/dist/tools/GthFileSystemToolkit.d.ts +63 -0
  77. package/dist/tools/GthFileSystemToolkit.js +506 -105
  78. package/dist/tools/GthFileSystemToolkit.js.map +1 -1
  79. package/dist/tools/McpResourceTool.d.ts +31 -0
  80. package/dist/tools/McpResourceTool.js +106 -0
  81. package/dist/tools/McpResourceTool.js.map +1 -0
  82. package/dist/tools/gthChecklistTool.d.ts +30 -0
  83. package/dist/tools/gthChecklistTool.js +80 -0
  84. package/dist/tools/gthChecklistTool.js.map +1 -0
  85. package/dist/tools/gthGrepTool.d.ts +54 -0
  86. package/dist/tools/gthGrepTool.js +482 -0
  87. package/dist/tools/gthGrepTool.js.map +1 -0
  88. package/dist/tools/shell/env.js +1 -1
  89. package/dist/tools/shell/env.js.map +1 -1
  90. package/dist/tools/shell/outputBuffer.js.map +1 -1
  91. package/dist/tools/shell/workDir.d.ts +2 -0
  92. package/dist/tools/shell/workDir.js +19 -0
  93. package/dist/tools/shell/workDir.js.map +1 -0
  94. package/dist/utils/mcpAuthError.d.ts +36 -0
  95. package/dist/utils/mcpAuthError.js +89 -0
  96. package/dist/utils/mcpAuthError.js.map +1 -0
  97. package/dist/utils/mcpUtils.js +16 -0
  98. package/dist/utils/mcpUtils.js.map +1 -1
  99. package/package.json +12 -12
  100. package/dist/core/GthDeepAgent.d.ts +0 -151
  101. package/dist/core/GthDeepAgent.js +0 -604
  102. package/dist/core/GthDeepAgent.js.map +0 -1
  103. package/dist/core/deepAgentPermissions.d.ts +0 -73
  104. package/dist/core/deepAgentPermissions.js +0 -161
  105. package/dist/core/deepAgentPermissions.js.map +0 -1
  106. package/dist/core/gthAcpServer.d.ts +0 -27
  107. package/dist/core/gthAcpServer.js +0 -71
  108. package/dist/core/gthAcpServer.js.map +0 -1
  109. package/dist/core/gthDeepAgentFactory.d.ts +0 -8
  110. package/dist/core/gthDeepAgentFactory.js +0 -9
  111. package/dist/core/gthDeepAgentFactory.js.map +0 -1
  112. package/dist/modules/acpModule.d.ts +0 -40
  113. package/dist/modules/acpModule.js +0 -70
  114. package/dist/modules/acpModule.js.map +0 -1
  115. package/dist/tools/shell/allowlist.d.ts +0 -11
  116. package/dist/tools/shell/allowlist.js +0 -12
  117. package/dist/tools/shell/allowlist.js.map +0 -1
  118. package/dist/tools/shell/arity.d.ts +0 -11
  119. package/dist/tools/shell/arity.js +0 -12
  120. package/dist/tools/shell/arity.js.map +0 -1
  121. package/dist/tools/shell/hardline.d.ts +0 -15
  122. package/dist/tools/shell/hardline.js +0 -88
  123. package/dist/tools/shell/hardline.js.map +0 -1
  124. package/dist/tools/shell/normalize.d.ts +0 -10
  125. package/dist/tools/shell/normalize.js +0 -11
  126. package/dist/tools/shell/normalize.js.map +0 -1
@@ -5,12 +5,33 @@ export interface A2AClientConfig {
5
5
  /** URL endpoint for the A2A agent */
6
6
  agentUrl: string;
7
7
  }
8
+ /**
9
+ * A single A2A turn's result with its conversation-continuity handles (BATCH-14). Unlike the
10
+ * text-only {@link A2AClientWrapper.sendMessage}, this carries the `contextId`/`taskId` the server
11
+ * returned so a caller can thread them into follow-up turns (an ADK agent keeps conversational
12
+ * context by `contextId`). Both are optional because a response may be a bare `Message` (which
13
+ * carries them only optionally) or a `Task` (which always carries `contextId`, and `id` as the
14
+ * taskId).
15
+ */
16
+ export interface A2AMessageResult {
17
+ /** The agent's answer text, extracted from the response's text parts. */
18
+ text: string;
19
+ /** The A2A context id to thread into subsequent turns for conversational continuity. */
20
+ contextId?: string;
21
+ /** The A2A task id, when the response was a Task (`Task.id`) or a task-scoped Message. */
22
+ taskId?: string;
23
+ }
24
+ /** Optional conversation-continuity handles to attach to an outgoing A2A message (BATCH-14). */
25
+ export interface A2ASendContext {
26
+ contextId?: string;
27
+ taskId?: string;
28
+ }
8
29
  /**
9
30
  * Wrapper around the A2A SDK client for communicating with external agents.
10
31
  * @experimental
11
32
  */
12
33
  export declare class A2AClientWrapper {
13
- private client;
34
+ private clientPromise;
14
35
  private config;
15
36
  constructor(config: A2AClientConfig);
16
37
  /**
@@ -19,4 +40,38 @@ export declare class A2AClientWrapper {
19
40
  * @returns The agent's response as a string
20
41
  */
21
42
  sendMessage(messageText: string): Promise<string>;
43
+ /**
44
+ * BATCH-14 — send one message and return its text ALONG WITH the A2A `contextId`/`taskId` needed to
45
+ * thread a multi-turn conversation. Reads the real `@a2a-js/sdk` result shapes rather than a
46
+ * loose envelope:
47
+ *
48
+ * - A **Message** result carries its text in `parts` and `contextId`/`taskId` directly (both
49
+ * optional, and empty-string when absent in the v1.0 proto model).
50
+ * - A **Task** result — what Google ADK agents commonly return — carries text in
51
+ * `status.message.parts` (falling back to the last artifact's parts), `contextId` (required), and
52
+ * the taskId as `Task.id`.
53
+ *
54
+ * `context.contextId`/`taskId` are attached to the OUTGOING message only when defined, so a
55
+ * first-turn send stays byte-identical to a contextless one.
56
+ *
57
+ * @param messageText - The message to send to the agent.
58
+ * @param context - Optional context/task ids to continue an existing conversation.
59
+ * @returns The agent's text answer plus the context/task ids from its response.
60
+ */
61
+ sendMessageWithContext(messageText: string, context?: A2ASendContext): Promise<A2AMessageResult>;
62
+ /** Build the outgoing `SendMessageRequest`. The v1.0 data model is generated from the A2A
63
+ * protobufs, so every field is required rather than optional: `role` is the numeric {@link Role}
64
+ * enum (not `'user'`), a text part is `{ content: { $case: 'text', value } }` (not
65
+ * `{ kind: 'text', text }`), and the continuity handles are empty strings rather than absent
66
+ * when there is no conversation to continue. */
67
+ private static buildSendRequest;
68
+ /** Normalize a `Message | Task` A2A result into text + continuity handles (BATCH-14). Static +
69
+ * tolerant of missing optional fields so it can be reused and unit-tested directly. */
70
+ private static extractResult;
71
+ /** v1.0 dropped the `kind` discriminator that told a Message from a Task, so discriminate
72
+ * structurally: `messageId` is required on every Message and never present on a Task. */
73
+ private static isTask;
74
+ /** Concatenate the text of every {@link https://github.com/a2aproject/A2A TextPart} in `parts`
75
+ * (ignoring file/data parts), or `''` when there is no text part. */
76
+ private static extractText;
22
77
  }
@@ -3,20 +3,48 @@
3
3
  * Wrapper for A2A (Agent-to-Agent) protocol client.
4
4
  * @experimental A2A support is experimental and may change.
5
5
  */
6
- import { A2AClient } from '@a2a-js/sdk/client';
6
+ import { ClientFactory, ClientFactoryOptions, DefaultAgentCardResolver, JsonRpcTransportFactory, RestTransportFactory, } from '@a2a-js/sdk/client';
7
+ import { Role } from '@a2a-js/sdk';
7
8
  import { debugLog, debugLogError } from '@gaunt-sloth/core/utils/debugUtils.js';
8
9
  import { v4 as uuidv4 } from 'uuid';
10
+ /** The A2A spec's well-known agent-card path. The SDK's resolver needs the full CARD url, whereas
11
+ * {@link A2AClientConfig.agentUrl} is the agent's BASE url — so we append this ourselves and hand
12
+ * the resolver an empty relative path, keeping the fetched card URL byte-identical to what the
13
+ * pre-1.0 `A2AClient` string constructor produced. (Letting the resolver append its own default
14
+ * would resolve the path RELATIVE to the base url, silently dropping a base path segment: for
15
+ * `http://host/a2a` it would fetch `http://host/.well-known/agent-card.json`.) */
16
+ const AGENT_CARD_PATH = '.well-known/agent-card.json';
9
17
  /**
10
18
  * Wrapper around the A2A SDK client for communicating with external agents.
11
19
  * @experimental
12
20
  */
13
21
  export class A2AClientWrapper {
14
- client;
22
+ clientPromise;
15
23
  config;
16
24
  constructor(config) {
17
25
  this.config = config;
18
- // Initialize with agent URL. The SDK will fetch the agent card.
19
- this.client = new A2AClient(config.agentUrl);
26
+ // `@a2a-js/sdk` 1.0 removed the `A2AClient` class outright; a client is now built by a
27
+ // `ClientFactory` from the agent card. `legacyCompat` is enabled on the card resolver AND on
28
+ // every transport factory so we keep talking to agents still on protocol v0.3 — which is what
29
+ // Google ADK agents (our only real A2A peer today, see adk-eval-it/) currently speak. With it
30
+ // on, the resolver detects a v0.3-shaped card, translates it to the v1.0 model and stamps each
31
+ // synthesized interface `protocolVersion: '0.3'`, and the matching factory then instantiates
32
+ // the v0.3 wire transport. A v1.0 agent is served by the native transports unchanged, so this
33
+ // wrapper speaks to both.
34
+ const factory = new ClientFactory(ClientFactoryOptions.createFrom(ClientFactoryOptions.default, {
35
+ cardResolver: new DefaultAgentCardResolver({ legacyCompat: { enabled: true } }),
36
+ transports: [
37
+ new JsonRpcTransportFactory({ legacyCompat: { enabled: true } }),
38
+ new RestTransportFactory({ legacyCompat: { enabled: true } }),
39
+ ],
40
+ }));
41
+ // Client construction is async (it fetches the card), so we hold the promise and await it per
42
+ // send. Empty path = "the base url IS the card url" — see AGENT_CARD_PATH.
43
+ const cardUrl = `${config.agentUrl.replace(/\/+$/, '')}/${AGENT_CARD_PATH}`;
44
+ this.clientPromise = factory.createFromUrl(cardUrl, '');
45
+ // Guard against an unhandled rejection if the wrapper is constructed but never used; real
46
+ // callers still observe the rejection when they await `clientPromise` inside a send method.
47
+ void this.clientPromise.catch(() => undefined);
20
48
  }
21
49
  /**
22
50
  * Sends a message to the A2A agent and returns the response.
@@ -26,38 +54,110 @@ export class A2AClientWrapper {
26
54
  async sendMessage(messageText) {
27
55
  debugLog(`Sending message to A2A agent ${this.config.agentId} at ${this.config.agentUrl}: ${messageText}`);
28
56
  try {
29
- const messageId = uuidv4();
30
- const response = await this.client.sendMessage({
31
- message: {
32
- kind: 'message',
33
- messageId: messageId,
34
- role: 'user',
35
- parts: [{ kind: 'text', text: messageText }],
36
- },
37
- });
38
- debugLog(`Received response from A2A agent: ${JSON.stringify(response)}`);
39
- // Check for error response
40
- if ('error' in response) {
41
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
- throw new Error(`A2A Error: ${JSON.stringify(response.error)}`);
43
- }
44
- // Extract text from response
45
- // The result is likely a TaskStatus which contains a message
46
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
- const result = response.result;
48
- if (result.message && result.message.parts && result.message.parts.length > 0) {
49
- // Assuming the first part is text for now
50
- return result.message.parts[0].text || JSON.stringify(result.message.parts);
51
- }
52
- else if (result.state) {
53
- return `Task state: ${result.state}`;
54
- }
55
- return JSON.stringify(result);
57
+ const client = await this.clientPromise;
58
+ const result = await client.sendMessage(A2AClientWrapper.buildSendRequest(messageText, uuidv4()));
59
+ debugLog(`Received response from A2A agent: ${JSON.stringify(result)}`);
60
+ return A2AClientWrapper.extractResult(result).text;
56
61
  }
57
62
  catch (error) {
58
63
  debugLogError('Error sending message to A2A agent', error);
59
64
  throw error;
60
65
  }
61
66
  }
67
+ /**
68
+ * BATCH-14 — send one message and return its text ALONG WITH the A2A `contextId`/`taskId` needed to
69
+ * thread a multi-turn conversation. Reads the real `@a2a-js/sdk` result shapes rather than a
70
+ * loose envelope:
71
+ *
72
+ * - A **Message** result carries its text in `parts` and `contextId`/`taskId` directly (both
73
+ * optional, and empty-string when absent in the v1.0 proto model).
74
+ * - A **Task** result — what Google ADK agents commonly return — carries text in
75
+ * `status.message.parts` (falling back to the last artifact's parts), `contextId` (required), and
76
+ * the taskId as `Task.id`.
77
+ *
78
+ * `context.contextId`/`taskId` are attached to the OUTGOING message only when defined, so a
79
+ * first-turn send stays byte-identical to a contextless one.
80
+ *
81
+ * @param messageText - The message to send to the agent.
82
+ * @param context - Optional context/task ids to continue an existing conversation.
83
+ * @returns The agent's text answer plus the context/task ids from its response.
84
+ */
85
+ async sendMessageWithContext(messageText, context) {
86
+ debugLog(`Sending message (with context) to A2A agent ${this.config.agentId} at ` +
87
+ `${this.config.agentUrl}: ${messageText}` +
88
+ (context?.contextId ? ` [contextId=${context.contextId}]` : ''));
89
+ try {
90
+ const client = await this.clientPromise;
91
+ const result = await client.sendMessage(A2AClientWrapper.buildSendRequest(messageText, uuidv4(), context));
92
+ debugLog(`Received response from A2A agent: ${JSON.stringify(result)}`);
93
+ return A2AClientWrapper.extractResult(result);
94
+ }
95
+ catch (error) {
96
+ debugLogError('Error sending message (with context) to A2A agent', error);
97
+ throw error;
98
+ }
99
+ }
100
+ /** Build the outgoing `SendMessageRequest`. The v1.0 data model is generated from the A2A
101
+ * protobufs, so every field is required rather than optional: `role` is the numeric {@link Role}
102
+ * enum (not `'user'`), a text part is `{ content: { $case: 'text', value } }` (not
103
+ * `{ kind: 'text', text }`), and the continuity handles are empty strings rather than absent
104
+ * when there is no conversation to continue. */
105
+ static buildSendRequest(messageText, messageId, context) {
106
+ const message = {
107
+ messageId,
108
+ contextId: context?.contextId ?? '',
109
+ taskId: context?.taskId ?? '',
110
+ role: Role.ROLE_USER,
111
+ parts: [
112
+ {
113
+ content: { $case: 'text', value: messageText },
114
+ metadata: undefined,
115
+ filename: '',
116
+ mediaType: 'text/plain',
117
+ },
118
+ ],
119
+ metadata: undefined,
120
+ extensions: [],
121
+ referenceTaskIds: [],
122
+ };
123
+ return { tenant: '', message, configuration: undefined, metadata: undefined };
124
+ }
125
+ /** Normalize a `Message | Task` A2A result into text + continuity handles (BATCH-14). Static +
126
+ * tolerant of missing optional fields so it can be reused and unit-tested directly. */
127
+ static extractResult(result) {
128
+ if (A2AClientWrapper.isTask(result)) {
129
+ const statusParts = result.status?.message?.parts;
130
+ const artifactParts = result.artifacts?.[result.artifacts.length - 1]?.parts;
131
+ const text = A2AClientWrapper.extractText(statusParts ?? artifactParts) || JSON.stringify(result);
132
+ return {
133
+ text,
134
+ contextId: result.contextId || undefined,
135
+ taskId: result.id || undefined,
136
+ };
137
+ }
138
+ const text = A2AClientWrapper.extractText(result?.parts) || JSON.stringify(result);
139
+ // The proto model uses '' (not undefined) for an absent id; normalize back to undefined so a
140
+ // caller can't thread an empty handle into the next turn.
141
+ return {
142
+ text,
143
+ contextId: result?.contextId || undefined,
144
+ taskId: result?.taskId || undefined,
145
+ };
146
+ }
147
+ /** v1.0 dropped the `kind` discriminator that told a Message from a Task, so discriminate
148
+ * structurally: `messageId` is required on every Message and never present on a Task. */
149
+ static isTask(result) {
150
+ return typeof result?.messageId !== 'string';
151
+ }
152
+ /** Concatenate the text of every {@link https://github.com/a2aproject/A2A TextPart} in `parts`
153
+ * (ignoring file/data parts), or `''` when there is no text part. */
154
+ static extractText(parts) {
155
+ if (!parts || parts.length === 0)
156
+ return '';
157
+ return parts
158
+ .filter((part) => part?.content?.$case === 'text')
159
+ .map((part) => part.content?.value)
160
+ .join('\n');
161
+ }
62
162
  }
63
163
  //# sourceMappingURL=A2AClientWrapper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"A2AClientWrapper.js","sourceRoot":"","sources":["../../../src/modules/a2a/A2AClientWrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAUpC;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAY;IAClB,MAAM,CAAkB;IAEhC,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,gEAAgE;QAChE,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB;QACnC,QAAQ,CACN,gCAAgC,IAAI,CAAC,MAAM,CAAC,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CACjG,CAAC;QACF,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;gBAC7C,OAAO,EAAE;oBACP,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,SAAS;oBACpB,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;iBAC7C;aACF,CAAC,CAAC;YAEH,QAAQ,CAAC,qCAAqC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAE1E,2BAA2B;YAC3B,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,8DAA8D;gBAC9D,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,SAAS,CAAE,QAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3E,CAAC;YAED,6BAA6B;YAC7B,6DAA6D;YAC7D,8DAA8D;YAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAa,CAAC;YAEtC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9E,0CAA0C;gBAC1C,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9E,CAAC;iBAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACxB,OAAO,eAAe,MAAM,CAAC,KAAK,EAAE,CAAC;YACvC,CAAC;YAED,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"A2AClientWrapper.js","sourceRoot":"","sources":["../../../src/modules/a2a/A2AClientWrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,GAErB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAsC,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;kFAKkF;AAClF,MAAM,eAAe,GAAG,6BAA6B,CAAC;AAiCtD;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACnB,aAAa,CAAkB;IAC/B,MAAM,CAAkB;IAEhC,YAAY,MAAuB;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,uFAAuF;QACvF,6FAA6F;QAC7F,8FAA8F;QAC9F,8FAA8F;QAC9F,+FAA+F;QAC/F,6FAA6F;QAC7F,8FAA8F;QAC9F,0BAA0B;QAC1B,MAAM,OAAO,GAAG,IAAI,aAAa,CAC/B,oBAAoB,CAAC,UAAU,CAAC,oBAAoB,CAAC,OAAO,EAAE;YAC5D,YAAY,EAAE,IAAI,wBAAwB,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;YAC/E,UAAU,EAAE;gBACV,IAAI,uBAAuB,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;gBAChE,IAAI,oBAAoB,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;aAC9D;SACF,CAAC,CACH,CAAC;QACF,8FAA8F;QAC9F,2EAA2E;QAC3E,MAAM,OAAO,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,eAAe,EAAE,CAAC;QAC5E,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACxD,0FAA0F;QAC1F,4FAA4F;QAC5F,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB;QACnC,QAAQ,CACN,gCAAgC,IAAI,CAAC,MAAM,CAAC,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CACjG,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CACrC,gBAAgB,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CACzD,CAAC;YAEF,QAAQ,CAAC,qCAAqC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAExE,OAAO,gBAAgB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,sBAAsB,CAC1B,WAAmB,EACnB,OAAwB;QAExB,QAAQ,CACN,+CAA+C,IAAI,CAAC,MAAM,CAAC,OAAO,MAAM;YACtE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE;YACzC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAClE,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CACrC,gBAAgB,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAClE,CAAC;YAEF,QAAQ,CAAC,qCAAqC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAExE,OAAO,gBAAgB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;YAC1E,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;oDAIgD;IACxC,MAAM,CAAC,gBAAgB,CAC7B,WAAmB,EACnB,SAAiB,EACjB,OAAwB;QAExB,MAAM,OAAO,GAAY;YACvB,SAAS;YACT,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE;YACnC,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;YAC7B,IAAI,EAAE,IAAI,CAAC,SAAS;YACpB,KAAK,EAAE;gBACL;oBACE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE;oBAC9C,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,EAAE;oBACZ,SAAS,EAAE,YAAY;iBACxB;aACF;YACD,QAAQ,EAAE,SAAS;YACnB,UAAU,EAAE,EAAE;YACd,gBAAgB,EAAE,EAAE;SACrB,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAChF,CAAC;IAED;2FACuF;IAC/E,MAAM,CAAC,aAAa,CAAC,MAAsB;QACjD,IAAI,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;YAClD,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC;YAC7E,MAAM,IAAI,GACR,gBAAgB,CAAC,WAAW,CAAC,WAAW,IAAI,aAAa,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACvF,OAAO;gBACL,IAAI;gBACJ,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;gBACxC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,SAAS;aAC/B,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnF,6FAA6F;QAC7F,0DAA0D;QAC1D,OAAO;YACL,IAAI;YACJ,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,SAAS;YACzC,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,SAAS;SACpC,CAAC;IACJ,CAAC;IAED;6FACyF;IACjF,MAAM,CAAC,MAAM,CAAC,MAAsB;QAC1C,OAAO,OAAQ,MAAkB,EAAE,SAAS,KAAK,QAAQ,CAAC;IAC5D,CAAC;IAED;yEACqE;IAC7D,MAAM,CAAC,WAAW,CAAC,KAAyB;QAClD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAC5C,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,KAAK,MAAM,CAAC;aACjD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,KAAe,CAAC;aAC5C,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Gaunt Sloth's ACP (Agent Client Protocol) **v2** agent, built on the official SDK's
4
+ * `experimental/v2` surface.
5
+ *
6
+ * ## One of two dialects
7
+ *
8
+ * v1 is ACP's stable protocol and v2 is a draft, and the agent serves **both**: `acpRouter.ts`
9
+ * reads the `protocolVersion` on the first `initialize` and hands the connection to the matching
10
+ * app, so a host gets the dialect it asked for. This file is the v2 half; `acpAgentAppV1.ts` is
11
+ * the v1 half. Serving only v2 would cut the surface off from every shipping editor that speaks
12
+ * ACP today — measured against Zed 1.15.0 stable, which sends `protocolVersion: 1` as a literal
13
+ * with no setting to change it.
14
+ *
15
+ * ## Shape
16
+ *
17
+ * v2's agent side is a fluent app builder: `acp.agent()` returns an {@link AgentApp} on which
18
+ * typed handlers are registered by ACP method name, and `connect()` serves a client — either over
19
+ * a transport stream or, for tests, directly against a `ClientApp`. The SDK's v1 entry point offers
20
+ * the same builder, which is why the two dialects read alike even though their handlers differ.
21
+ *
22
+ * ## The prompt lifecycle is the part that looks wrong until you read the spec
23
+ *
24
+ * This is also the sharpest difference from v1, which answers the prompt request with the stop
25
+ * reason itself. In v2 `session/prompt` returns `{}` **as soon as the prompt is accepted** — not
26
+ * when the turn finishes.
27
+ * Progress, tool calls and the final stop reason all arrive as `session/update` notifications, and
28
+ * the turn is over when an idle `state_update` carrying a stop reason lands. That is what makes
29
+ * cancellation expressible at all: a cancelled turn reports `cancelled` on a `state_update`, while
30
+ * the prompt request it belongs to was answered long before. A client that waited on the prompt
31
+ * response for the result would hang through every tool call.
32
+ *
33
+ * ## Why a runner and not an agent
34
+ *
35
+ * Each session drives a {@link GthAgentRunner}, not a bare agent. The runner is where the
36
+ * tool-approval gate lives, so this is also the surface where `session/request_permission` is
37
+ * wired — see `acpPermissions.ts` for why that is not optional.
38
+ *
39
+ * ## One workspace per process
40
+ *
41
+ * Config discovery, the filesystem tools' allowed root, grep and the shell tool ALL resolve
42
+ * through `getCurrentWorkDir()`, a process-global. So the workspace is bound by the first
43
+ * `session/new` and a later `session/new` naming a different `cwd` is refused rather than served
44
+ * from the wrong root. An editor spawns one agent process per project, which is exactly the shape
45
+ * this serves; the alternative — letting the second session silently re-root the first session's
46
+ * tools — is the kind of quiet wrongness that is worse than an error a host can report.
47
+ */
48
+ import * as acp from '@agentclientprotocol/sdk/experimental/v2';
49
+ import { ACP_AGENT_NAME, ACP_AGENT_TITLE, announceAcpStart, isSameWorkspace } from '#src/modules/acp/acpCommon.js';
50
+ import type { AcpAgentAppOptions } from '#src/modules/acp/acpCommon.js';
51
+ export { ACP_AGENT_NAME, ACP_AGENT_TITLE, announceAcpStart, isSameWorkspace };
52
+ export type { AcpAgentAppOptions };
53
+ /**
54
+ * Builds the ACP v2 agent app. Register-and-return only: nothing is connected and no config is
55
+ * read until a client connects and creates a session.
56
+ */
57
+ export declare function createAcpAgentApp(options?: AcpAgentAppOptions): acp.AgentApp;