@gaunt-sloth/agent 2.0.0-alpha.23 → 2.0.0-alpha.25

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 (56) hide show
  1. package/README.md +73 -24
  2. package/dist/core/GthDeepAgent.d.ts +3 -3
  3. package/dist/core/GthDeepAgent.js +82 -35
  4. package/dist/core/GthDeepAgent.js.map +1 -1
  5. package/dist/core/debugCapture.d.ts +1 -1
  6. package/dist/core/debugCapture.js.map +1 -1
  7. package/dist/core/subagentProfiles.d.ts +50 -0
  8. package/dist/core/subagentProfiles.js +81 -0
  9. package/dist/core/subagentProfiles.js.map +1 -0
  10. package/dist/middleware/binaryContentInjectionMiddleware.d.ts +8 -1
  11. package/dist/middleware/binaryContentInjectionMiddleware.js +11 -2
  12. package/dist/middleware/binaryContentInjectionMiddleware.js.map +1 -1
  13. package/dist/middleware/frontendImageInjectionMiddleware.d.ts +80 -0
  14. package/dist/middleware/frontendImageInjectionMiddleware.js +146 -0
  15. package/dist/middleware/frontendImageInjectionMiddleware.js.map +1 -0
  16. package/dist/middleware/registry.js +36 -1
  17. package/dist/middleware/registry.js.map +1 -1
  18. package/dist/middleware/types.d.ts +16 -2
  19. package/dist/modules/a2a/A2AClientWrapper.d.ts +15 -6
  20. package/dist/modules/a2a/A2AClientWrapper.js +93 -64
  21. package/dist/modules/a2a/A2AClientWrapper.js.map +1 -1
  22. package/dist/modules/apiAgUiModule.d.ts +68 -0
  23. package/dist/modules/apiAgUiModule.js +95 -4
  24. package/dist/modules/apiAgUiModule.js.map +1 -1
  25. package/dist/modules/interactiveSessionModule.js +199 -43
  26. package/dist/modules/interactiveSessionModule.js.map +1 -1
  27. package/dist/modules/slashCommands.d.ts +467 -0
  28. package/dist/modules/slashCommands.js +888 -0
  29. package/dist/modules/slashCommands.js.map +1 -0
  30. package/dist/resolvers.js +15 -0
  31. package/dist/resolvers.js.map +1 -1
  32. package/dist/tools/GthCustomToolkit.js +72 -3
  33. package/dist/tools/GthCustomToolkit.js.map +1 -1
  34. package/dist/tools/GthDevToolkit.d.ts +6 -3
  35. package/dist/tools/GthDevToolkit.js +31 -11
  36. package/dist/tools/GthDevToolkit.js.map +1 -1
  37. package/dist/tools/GthFileSystemToolkit.d.ts +16 -0
  38. package/dist/tools/GthFileSystemToolkit.js +218 -110
  39. package/dist/tools/GthFileSystemToolkit.js.map +1 -1
  40. package/dist/tools/McpResourceTool.d.ts +31 -0
  41. package/dist/tools/McpResourceTool.js +106 -0
  42. package/dist/tools/McpResourceTool.js.map +1 -0
  43. package/dist/tools/shell/env.js +1 -1
  44. package/dist/tools/shell/hardline.d.ts +33 -2
  45. package/dist/tools/shell/hardline.js +525 -40
  46. package/dist/tools/shell/hardline.js.map +1 -1
  47. package/package.json +8 -8
  48. package/dist/tools/shell/allowlist.d.ts +0 -11
  49. package/dist/tools/shell/allowlist.js +0 -12
  50. package/dist/tools/shell/allowlist.js.map +0 -1
  51. package/dist/tools/shell/arity.d.ts +0 -11
  52. package/dist/tools/shell/arity.js +0 -12
  53. package/dist/tools/shell/arity.js.map +0 -1
  54. package/dist/tools/shell/normalize.d.ts +0 -10
  55. package/dist/tools/shell/normalize.js +0 -11
  56. package/dist/tools/shell/normalize.js.map +0 -1
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Opt-in middleware that turns a frontend "capture image" tool result into a vision message the
4
+ * model can actually see.
5
+ *
6
+ * A browser/frontend tool such as CopilotKit's `capture_image` fulfils client-side and posts its
7
+ * result back to gth's AG-UI server as a trailing `tool`-role message whose content is a JSON
8
+ * string `{"mimeType":"image/...","data":"<base64>"}`. gth hands that to the model as a plain-string
9
+ * ToolMessage — no vision block — so the model literally cannot see the photo. This middleware
10
+ * detects that ToolMessage in `beforeModel`, parses the envelope, and injects a `HumanMessage`
11
+ * carrying a provider-appropriate vision block before the next model call.
12
+ *
13
+ * Strictly opt-in: it fires ONLY when referenced by name in `config.middleware`
14
+ * (`"middleware": ["frontend-image-injection"]`), never auto-injected. Promoted from
15
+ * pukeko-robot-controller's proven middleware (RC-21), minus the robot-specific motion-tool coupling.
16
+ */
17
+ import { type AgentMiddleware } from 'langchain';
18
+ /** Default frontend capture tool name. Overridable via the `toolName` middleware setting. */
19
+ export declare const DEFAULT_CAPTURE_TOOL_NAME = "capture_image";
20
+ export interface FrontendImageInjectionOptions {
21
+ /**
22
+ * Provider selecting the vision-block shape. Derived by the registry factory from
23
+ * `gthConfig.modelProviderType` (the raw `llm.type`), falling back to `llm._llmType()`. One of
24
+ * gth's provider strings (`anthropic`, `openai`, `openrouter`, `deepseek`, `xai`, `groq`,
25
+ * `ollama`, `google-genai`, `vertexai`, `huggingface`, …); unknown values fall to the standard
26
+ * base64 block.
27
+ */
28
+ provider: string;
29
+ /**
30
+ * Tool name whose `{mimeType,data}` result is converted into a vision message. Defaults to
31
+ * {@link DEFAULT_CAPTURE_TOOL_NAME} (`capture_image`).
32
+ */
33
+ toolName?: string;
34
+ }
35
+ /**
36
+ * A vision content block the target provider's `@langchain` converter actually decodes. Verified
37
+ * against the installed converters (RC-21):
38
+ * - **ollama** → `{ type:'image_url', image_url:'<data-URL string>' }`. ChatOllama's
39
+ * `convertToOllamaMessages` only handles `image_url` blocks (extractBase64FromDataUrl); the
40
+ * LangChain standard `source_type` block throws "Unsupported content type: image".
41
+ * - **OpenAI-compatible** (`openai`, `openrouter`, `deepseek`, `xai`, `groq` — all extend
42
+ * `ChatOpenAI` / report `_llmType()==='openai'`) → `{ type:'image_url', image_url:{ url:'<data-URL>' } }`.
43
+ * This native OpenAI shape is correct on BOTH the Completions API AND the Responses API (GS2-74
44
+ * flips reasoning-capable openai models to Responses). A raw `source_type` standard block
45
+ * serialises to an *invalid* image part on the Responses path, so we emit the provider-native
46
+ * shape rather than lean on `@langchain/core`'s (deprecated, internal) auto-conversion.
47
+ * - **anthropic / google-genai / vertexai** (and any unknown/default) → the LangChain standard
48
+ * base64 data content block `{ type:'image', source_type:'base64', mime_type, data }`, which
49
+ * those native converters decode directly and which is the most broadly decodable fallback.
50
+ *
51
+ * Pure and exported so each provider branch can be unit-tested directly.
52
+ */
53
+ export declare function imageBlockFor(provider: string, mimeType: string, data: string): {
54
+ type: 'image_url';
55
+ image_url: string;
56
+ source_type?: undefined;
57
+ mime_type?: undefined;
58
+ data?: undefined;
59
+ } | {
60
+ type: 'image_url';
61
+ image_url: {
62
+ url: string;
63
+ };
64
+ source_type?: undefined;
65
+ mime_type?: undefined;
66
+ data?: undefined;
67
+ } | {
68
+ image_url?: undefined;
69
+ type: 'image';
70
+ source_type: 'base64';
71
+ mime_type: string;
72
+ data: string;
73
+ };
74
+ /**
75
+ * Create the frontend-image-injection middleware.
76
+ *
77
+ * @param opts.provider - provider string selecting the vision-block shape (see {@link imageBlockFor}).
78
+ * @param opts.toolName - capture tool name (default {@link DEFAULT_CAPTURE_TOOL_NAME}).
79
+ */
80
+ export declare function createFrontendImageInjectionMiddleware(opts: FrontendImageInjectionOptions): AgentMiddleware;
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Opt-in middleware that turns a frontend "capture image" tool result into a vision message the
4
+ * model can actually see.
5
+ *
6
+ * A browser/frontend tool such as CopilotKit's `capture_image` fulfils client-side and posts its
7
+ * result back to gth's AG-UI server as a trailing `tool`-role message whose content is a JSON
8
+ * string `{"mimeType":"image/...","data":"<base64>"}`. gth hands that to the model as a plain-string
9
+ * ToolMessage — no vision block — so the model literally cannot see the photo. This middleware
10
+ * detects that ToolMessage in `beforeModel`, parses the envelope, and injects a `HumanMessage`
11
+ * carrying a provider-appropriate vision block before the next model call.
12
+ *
13
+ * Strictly opt-in: it fires ONLY when referenced by name in `config.middleware`
14
+ * (`"middleware": ["frontend-image-injection"]`), never auto-injected. Promoted from
15
+ * pukeko-robot-controller's proven middleware (RC-21), minus the robot-specific motion-tool coupling.
16
+ */
17
+ import { createMiddleware } from 'langchain';
18
+ import { HumanMessage, isToolMessage } from '@langchain/core/messages';
19
+ /** Default frontend capture tool name. Overridable via the `toolName` middleware setting. */
20
+ export const DEFAULT_CAPTURE_TOOL_NAME = 'capture_image';
21
+ /**
22
+ * A vision content block the target provider's `@langchain` converter actually decodes. Verified
23
+ * against the installed converters (RC-21):
24
+ * - **ollama** → `{ type:'image_url', image_url:'<data-URL string>' }`. ChatOllama's
25
+ * `convertToOllamaMessages` only handles `image_url` blocks (extractBase64FromDataUrl); the
26
+ * LangChain standard `source_type` block throws "Unsupported content type: image".
27
+ * - **OpenAI-compatible** (`openai`, `openrouter`, `deepseek`, `xai`, `groq` — all extend
28
+ * `ChatOpenAI` / report `_llmType()==='openai'`) → `{ type:'image_url', image_url:{ url:'<data-URL>' } }`.
29
+ * This native OpenAI shape is correct on BOTH the Completions API AND the Responses API (GS2-74
30
+ * flips reasoning-capable openai models to Responses). A raw `source_type` standard block
31
+ * serialises to an *invalid* image part on the Responses path, so we emit the provider-native
32
+ * shape rather than lean on `@langchain/core`'s (deprecated, internal) auto-conversion.
33
+ * - **anthropic / google-genai / vertexai** (and any unknown/default) → the LangChain standard
34
+ * base64 data content block `{ type:'image', source_type:'base64', mime_type, data }`, which
35
+ * those native converters decode directly and which is the most broadly decodable fallback.
36
+ *
37
+ * Pure and exported so each provider branch can be unit-tested directly.
38
+ */
39
+ export function imageBlockFor(provider, mimeType, data) {
40
+ const dataUrl = `data:${mimeType};base64,${data}`;
41
+ switch (provider) {
42
+ case 'ollama':
43
+ return { type: 'image_url', image_url: dataUrl };
44
+ case 'openai':
45
+ case 'openrouter':
46
+ case 'deepseek':
47
+ case 'xai':
48
+ case 'groq':
49
+ return { type: 'image_url', image_url: { url: dataUrl } };
50
+ case 'anthropic':
51
+ case 'google-genai':
52
+ case 'vertexai':
53
+ default:
54
+ return {
55
+ type: 'image',
56
+ source_type: 'base64',
57
+ mime_type: mimeType,
58
+ data,
59
+ };
60
+ }
61
+ }
62
+ /**
63
+ * Create the frontend-image-injection middleware.
64
+ *
65
+ * @param opts.provider - provider string selecting the vision-block shape (see {@link imageBlockFor}).
66
+ * @param opts.toolName - capture tool name (default {@link DEFAULT_CAPTURE_TOOL_NAME}).
67
+ */
68
+ export function createFrontendImageInjectionMiddleware(opts) {
69
+ const toolName = opts.toolName ?? DEFAULT_CAPTURE_TOOL_NAME;
70
+ // thread_id → set of tool_call_ids whose image (or error note) has already been injected. Without
71
+ // this, a summarizer/replayed history that retains the capture ToolMessage would re-inject its
72
+ // frame on the next turn, appended after the newest turn's content and mispairing the assistant
73
+ // message with a stale frame (the RC-21 idempotency guard).
74
+ //
75
+ // Closure-scoped (one Map per middleware instance), NOT a module global as the robot had it. The
76
+ // AG-UI server caches one agent per client-toolset signature (getAgentForTools), so a thread's
77
+ // turns share this instance and idempotency-across-turns is preserved — while unrelated agents (and
78
+ // tests) get independent state instead of a process-lifetime Map that accumulates every thread_id.
79
+ const injectedByThread = new Map();
80
+ return createMiddleware({
81
+ name: 'frontend-image-injection',
82
+ beforeModel: async (state, runtime) => {
83
+ const messages = state.messages || [];
84
+ // The AG-UI server sets runConfig.configurable.thread_id (= the run's threadId) and threads it
85
+ // to the graph, so per-session idempotency keys correctly. '__default__' is only reached off
86
+ // that path (e.g. a bare invoke with no thread_id), which still behaves correctly per-instance.
87
+ const threadId = runtime?.configurable?.thread_id ?? '__default__';
88
+ let injectedIds = injectedByThread.get(threadId);
89
+ if (!injectedIds) {
90
+ injectedIds = new Set();
91
+ injectedByThread.set(threadId, injectedIds);
92
+ }
93
+ // Scan forward so injected frames stay in chronological order; skip any tool_call_id already
94
+ // injected on this thread (idempotent across a retained/replayed tail).
95
+ const injected = [];
96
+ for (let i = 0; i < messages.length; i++) {
97
+ const msg = messages[i];
98
+ if (
99
+ // RC-21 (golden fix): use the duck-typed `isToolMessage`, NEVER `msg instanceof
100
+ // ToolMessage`. A consumer (galvanized/robot) importing this middleware across a `file:`-dep
101
+ // boundary resolves a SECOND @langchain/core copy, and a capture ToolMessage constructed by
102
+ // the AG-UI pipeline's core copy is not an instance of the `ToolMessage` class we import —
103
+ // `instanceof` silently returns false across copies and no frame is ever injected.
104
+ isToolMessage(msg) &&
105
+ typeof msg.content === 'string' &&
106
+ msg.name === toolName) {
107
+ const id = msg.tool_call_id;
108
+ if (!id || injectedIds.has(id))
109
+ continue;
110
+ try {
111
+ injected.push({ payload: JSON.parse(msg.content), id });
112
+ }
113
+ catch {
114
+ // Non-JSON tool result — skip injection (leave the guard clean).
115
+ }
116
+ }
117
+ }
118
+ if (injected.length === 0)
119
+ return undefined;
120
+ const newMessages = [...messages];
121
+ for (const { payload, id } of injected) {
122
+ if (payload.error) {
123
+ // Mark injected so the error note isn't re-emitted on a later turn.
124
+ injectedIds.add(id);
125
+ newMessages.push(new HumanMessage({ content: `Camera unavailable: ${payload.error}` }));
126
+ continue;
127
+ }
128
+ if (payload.mimeType && payload.data) {
129
+ // RC-21: mark injected ONLY on a successful frame emission. A capture result that arrived
130
+ // WITHOUT its base64 `data` (dropped upstream) injects nothing and must NOT poison the
131
+ // guard — a later data-bearing result for the same tool_call_id can still recover.
132
+ injectedIds.add(id);
133
+ const block = imageBlockFor(opts.provider, payload.mimeType, payload.data);
134
+ newMessages.push(new HumanMessage({
135
+ content: [{ type: 'text', text: 'Camera frame captured:' }, block],
136
+ }));
137
+ }
138
+ // else: a capture result whose `data` is absent — inject nothing, leave the guard clean.
139
+ }
140
+ // If every candidate was data-less (nothing appended), return no state update rather than an
141
+ // identical copy — keeps beforeModel a true no-op and leaves the guard clean for recovery.
142
+ return newMessages.length > messages.length ? { messages: newMessages } : undefined;
143
+ },
144
+ });
145
+ }
146
+ //# sourceMappingURL=frontendImageInjectionMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontendImageInjectionMiddleware.js","sourceRoot":"","sources":["../../src/middleware/frontendImageInjectionMiddleware.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,28 @@ import { displayWarning } from '@gaunt-sloth/core/utils/consoleUtils.js';
9
9
  import { debugLog } from '@gaunt-sloth/core/utils/debugUtils.js';
10
10
  import { anthropicPromptCachingMiddleware, summarizationMiddleware, } from 'langchain';
11
11
  import { createBinaryContentInjectionMiddleware, } from '#src/middleware/binaryContentInjectionMiddleware.js';
12
+ import { createFrontendImageInjectionMiddleware } from '#src/middleware/frontendImageInjectionMiddleware.js';
13
+ /**
14
+ * Derive the provider string the vision middleware maps to a per-provider block shape. Prefers the
15
+ * loader-stashed raw `llm.type` ({@link GthConfig.modelProviderType}) — the exact gth provider
16
+ * namespace (`anthropic`/`openrouter`/`deepseek`/`xai`/`groq`/`ollama`/`google-genai`/`vertexai`/…)
17
+ * — and falls back to the live model's `_llmType()` only when it is absent (module configs). The
18
+ * OpenAI-compatible shims (openrouter/deepseek/xai/groq) all report `_llmType() === 'openai'`, which
19
+ * maps to the same `image_url:{url}` block, so the fallback stays shape-correct.
20
+ */
21
+ function resolveVisionProvider(gthConfig) {
22
+ if (gthConfig.modelProviderType)
23
+ return gthConfig.modelProviderType;
24
+ const llm = gthConfig.llm;
25
+ try {
26
+ if (typeof llm?._llmType === 'function')
27
+ return llm._llmType();
28
+ }
29
+ catch {
30
+ // A misbehaving _llmType must not break middleware resolution.
31
+ }
32
+ return '';
33
+ }
12
34
  const predefinedMiddlewareFactories = {
13
35
  /**
14
36
  * Anthropic prompt caching middleware. see https://docs.langchain.com/oss/javascript/langchain/middleware#anthropic-prompt-caching
@@ -24,7 +46,20 @@ const predefinedMiddlewareFactories = {
24
46
  * as HumanMessage content blocks before the next model call.
25
47
  * This works around LangChain's limitation where ToolMessage doesn't support binary content.
26
48
  */
27
- 'binary-content-injection': (settings, gthConfig) => createBinaryContentInjectionMiddleware(settings, gthConfig),
49
+ 'binary-content-injection': (settings, gthConfig) => createBinaryContentInjectionMiddleware({
50
+ ...settings,
51
+ provider: resolveVisionProvider(gthConfig),
52
+ }, gthConfig),
53
+ /**
54
+ * Frontend image injection middleware (RC-22). Converts a frontend capture tool's
55
+ * `{mimeType,data}` ToolMessage (default tool name `capture_image`) into a provider-appropriate
56
+ * vision HumanMessage the model can see. Strictly opt-in — resolved ONLY when named in
57
+ * `config.middleware` (no auto-inject branch). Optional `toolName` setting overrides the tool name.
58
+ */
59
+ 'frontend-image-injection': (settings, gthConfig) => Promise.resolve(createFrontendImageInjectionMiddleware({
60
+ provider: resolveVisionProvider(gthConfig),
61
+ toolName: typeof settings.toolName === 'string' ? settings.toolName : undefined,
62
+ })),
28
63
  };
29
64
  function isPredefinedMiddlewareName(name) {
30
65
  return name in predefinedMiddlewareFactories;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/middleware/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/middleware/registry.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@ import { AgentMiddleware } from 'langchain';
10
10
  /**
11
11
  * Predefined middleware types that can be configured via JSON config.
12
12
  */
13
- export type PredefinedMiddlewareName = 'anthropic-prompt-caching' | 'summarization' | 'binary-content-injection';
13
+ export type PredefinedMiddlewareName = 'anthropic-prompt-caching' | 'summarization' | 'binary-content-injection' | 'frontend-image-injection';
14
14
  /**
15
15
  * Configuration for Anthropic prompt caching middleware.
16
16
  */
@@ -70,6 +70,18 @@ export interface ImageFormatTransformConfig {
70
70
  */
71
71
  export interface BinaryContentInjectionConfig {
72
72
  }
73
+ /**
74
+ * Configuration for frontend image injection middleware (RC-22).
75
+ * Converts a frontend capture tool's `{mimeType,data}` tool result into a vision HumanMessage the
76
+ * model can see. Opt-in — resolved only when named in `config.middleware`.
77
+ */
78
+ export interface FrontendImageInjectionConfig {
79
+ /**
80
+ * Name of the frontend capture tool whose result is converted into a vision message.
81
+ * Defaults to `capture_image`.
82
+ */
83
+ toolName?: string;
84
+ }
73
85
  /**
74
86
  * Union type of all predefined middleware configurations.
75
87
  */
@@ -79,7 +91,9 @@ export type PredefinedMiddlewareConfig = ({
79
91
  name: 'summarization';
80
92
  } & SummarizationConfig) | ({
81
93
  name: 'binary-content-injection';
82
- } & BinaryContentInjectionConfig);
94
+ } & BinaryContentInjectionConfig) | ({
95
+ name: 'frontend-image-injection';
96
+ } & FrontendImageInjectionConfig);
83
97
  /**
84
98
  * Middleware configuration that can be specified in JSON or JS config.
85
99
  * - String: Name of predefined middleware with default settings
@@ -31,7 +31,7 @@ export interface A2ASendContext {
31
31
  * @experimental
32
32
  */
33
33
  export declare class A2AClientWrapper {
34
- private client;
34
+ private clientPromise;
35
35
  private config;
36
36
  constructor(config: A2AClientConfig);
37
37
  /**
@@ -42,12 +42,12 @@ export declare class A2AClientWrapper {
42
42
  sendMessage(messageText: string): Promise<string>;
43
43
  /**
44
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 the
46
- * loose envelope {@link sendMessage} uses:
45
+ * thread a multi-turn conversation. Reads the real `@a2a-js/sdk` result shapes rather than a
46
+ * loose envelope:
47
47
  *
48
- * - A **Message** result (`kind: 'message'`) carries its text in `parts` and `contextId`/`taskId`
49
- * directly (both optional).
50
- * - A **Task** result (`kind: 'task'`) — what Google ADK agents commonly return — carries text in
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
51
  * `status.message.parts` (falling back to the last artifact's parts), `contextId` (required), and
52
52
  * the taskId as `Task.id`.
53
53
  *
@@ -59,9 +59,18 @@ export declare class A2AClientWrapper {
59
59
  * @returns The agent's text answer plus the context/task ids from its response.
60
60
  */
61
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;
62
68
  /** Normalize a `Message | Task` A2A result into text + continuity handles (BATCH-14). Static +
63
69
  * tolerant of missing optional fields so it can be reused and unit-tested directly. */
64
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;
65
74
  /** Concatenate the text of every {@link https://github.com/a2aproject/A2A TextPart} in `parts`
66
75
  * (ignoring file/data parts), or `''` when there is no text part. */
67
76
  private static extractText;
@@ -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,33 +54,10 @@ 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);
@@ -61,12 +66,12 @@ export class A2AClientWrapper {
61
66
  }
62
67
  /**
63
68
  * BATCH-14 — send one message and return its text ALONG WITH the A2A `contextId`/`taskId` needed to
64
- * thread a multi-turn conversation. Reads the real `@a2a-js/sdk` result shapes rather than the
65
- * loose envelope {@link sendMessage} uses:
69
+ * thread a multi-turn conversation. Reads the real `@a2a-js/sdk` result shapes rather than a
70
+ * loose envelope:
66
71
  *
67
- * - A **Message** result (`kind: 'message'`) carries its text in `parts` and `contextId`/`taskId`
68
- * directly (both optional).
69
- * - A **Task** result (`kind: 'task'`) — what Google ADK agents commonly return — carries text in
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
70
75
  * `status.message.parts` (falling back to the last artifact's parts), `contextId` (required), and
71
76
  * the taskId as `Task.id`.
72
77
  *
@@ -82,23 +87,9 @@ export class A2AClientWrapper {
82
87
  `${this.config.agentUrl}: ${messageText}` +
83
88
  (context?.contextId ? ` [contextId=${context.contextId}]` : ''));
84
89
  try {
85
- const response = await this.client.sendMessage({
86
- message: {
87
- kind: 'message',
88
- messageId: uuidv4(),
89
- role: 'user',
90
- parts: [{ kind: 'text', text: messageText }],
91
- // Attach continuity handles only when present, so a first-turn send is unchanged.
92
- ...(context?.contextId ? { contextId: context.contextId } : {}),
93
- ...(context?.taskId ? { taskId: context.taskId } : {}),
94
- },
95
- });
96
- debugLog(`Received response from A2A agent: ${JSON.stringify(response)}`);
97
- if ('error' in response) {
98
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
- throw new Error(`A2A Error: ${JSON.stringify(response.error)}`);
100
- }
101
- const result = response.result;
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)}`);
102
93
  return A2AClientWrapper.extractResult(result);
103
94
  }
104
95
  catch (error) {
@@ -106,19 +97,57 @@ export class A2AClientWrapper {
106
97
  throw error;
107
98
  }
108
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
+ }
109
125
  /** Normalize a `Message | Task` A2A result into text + continuity handles (BATCH-14). Static +
110
126
  * tolerant of missing optional fields so it can be reused and unit-tested directly. */
111
127
  static extractResult(result) {
112
- if (result && result.kind === 'task') {
113
- const task = result;
114
- const statusParts = task.status?.message?.parts;
115
- const artifactParts = task.artifacts?.[task.artifacts.length - 1]?.parts;
116
- const text = A2AClientWrapper.extractText(statusParts ?? artifactParts) || JSON.stringify(task);
117
- return { text, contextId: task.contextId, taskId: task.id };
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
+ };
118
137
  }
119
- const message = result;
120
- const text = A2AClientWrapper.extractText(message?.parts) || JSON.stringify(result);
121
- return { text, contextId: message?.contextId, taskId: message?.taskId };
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';
122
151
  }
123
152
  /** Concatenate the text of every {@link https://github.com/a2aproject/A2A TextPart} in `parts`
124
153
  * (ignoring file/data parts), or `''` when there is no text part. */
@@ -126,8 +155,8 @@ export class A2AClientWrapper {
126
155
  if (!parts || parts.length === 0)
127
156
  return '';
128
157
  return parts
129
- .filter((part) => part?.kind === 'text')
130
- .map((part) => part.text)
158
+ .filter((part) => part?.content?.$case === 'text')
159
+ .map((part) => part.content?.value)
131
160
  .join('\n');
132
161
  }
133
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"A2AClientWrapper.js","sourceRoot":"","sources":["../../../src/modules/a2a/A2AClientWrapper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"A2AClientWrapper.js","sourceRoot":"","sources":["../../../src/modules/a2a/A2AClientWrapper.ts"],"names":[],"mappings":"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"}