@esankhan3/anvil-agent-core 0.1.2 → 0.3.0

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 (122) hide show
  1. package/dist/__tests__/fetch-pool.integration.test.d.ts +15 -0
  2. package/dist/__tests__/fetch-pool.integration.test.d.ts.map +1 -0
  3. package/dist/__tests__/fetch-pool.integration.test.js +109 -0
  4. package/dist/__tests__/fetch-pool.integration.test.js.map +1 -0
  5. package/dist/__tests__/fetch-pool.test.d.ts +15 -0
  6. package/dist/__tests__/fetch-pool.test.d.ts.map +1 -0
  7. package/dist/__tests__/fetch-pool.test.js +115 -0
  8. package/dist/__tests__/fetch-pool.test.js.map +1 -0
  9. package/dist/__tests__/mcp-merged-executor.test.d.ts +2 -0
  10. package/dist/__tests__/mcp-merged-executor.test.d.ts.map +1 -0
  11. package/dist/__tests__/mcp-merged-executor.test.js +221 -0
  12. package/dist/__tests__/mcp-merged-executor.test.js.map +1 -0
  13. package/dist/__tests__/mcp.test.js +21 -15
  14. package/dist/__tests__/mcp.test.js.map +1 -1
  15. package/dist/__tests__/model-catalog.test.d.ts +11 -0
  16. package/dist/__tests__/model-catalog.test.d.ts.map +1 -0
  17. package/dist/__tests__/model-catalog.test.js +102 -0
  18. package/dist/__tests__/model-catalog.test.js.map +1 -0
  19. package/dist/__tests__/model-tier-resolver.test.d.ts +19 -0
  20. package/dist/__tests__/model-tier-resolver.test.d.ts.map +1 -0
  21. package/dist/__tests__/model-tier-resolver.test.js +97 -0
  22. package/dist/__tests__/model-tier-resolver.test.js.map +1 -0
  23. package/dist/adk-adapter.d.ts.map +1 -1
  24. package/dist/adk-adapter.js +11 -0
  25. package/dist/adk-adapter.js.map +1 -1
  26. package/dist/adk-anthropic-llm.d.ts.map +1 -1
  27. package/dist/adk-anthropic-llm.js +23 -10
  28. package/dist/adk-anthropic-llm.js.map +1 -1
  29. package/dist/agent/session/__tests__/spawn-telemetry.test.js +39 -4
  30. package/dist/agent/session/__tests__/spawn-telemetry.test.js.map +1 -1
  31. package/dist/agent/session/adapter.d.ts +44 -0
  32. package/dist/agent/session/adapter.d.ts.map +1 -1
  33. package/dist/agent/session/adapter.js +1 -0
  34. package/dist/agent/session/adapter.js.map +1 -1
  35. package/dist/agent/session/default-adapter-factory.d.ts.map +1 -1
  36. package/dist/agent/session/default-adapter-factory.js +66 -2
  37. package/dist/agent/session/default-adapter-factory.js.map +1 -1
  38. package/dist/agent/session/language-model-bridge.d.ts.map +1 -1
  39. package/dist/agent/session/language-model-bridge.js +59 -2
  40. package/dist/agent/session/language-model-bridge.js.map +1 -1
  41. package/dist/agent/session/session.d.ts +16 -0
  42. package/dist/agent/session/session.d.ts.map +1 -1
  43. package/dist/agent/session/session.js +86 -2
  44. package/dist/agent/session/session.js.map +1 -1
  45. package/dist/agent/session/types.d.ts +12 -0
  46. package/dist/agent/session/types.d.ts.map +1 -1
  47. package/dist/agent/session/types.js.map +1 -1
  48. package/dist/fetch-pool.d.ts +47 -0
  49. package/dist/fetch-pool.d.ts.map +1 -0
  50. package/dist/fetch-pool.js +132 -0
  51. package/dist/fetch-pool.js.map +1 -0
  52. package/dist/gemini-adapter.d.ts.map +1 -1
  53. package/dist/gemini-adapter.js +30 -6
  54. package/dist/gemini-adapter.js.map +1 -1
  55. package/dist/gemini-cli-adapter.d.ts.map +1 -1
  56. package/dist/gemini-cli-adapter.js +10 -0
  57. package/dist/gemini-cli-adapter.js.map +1 -1
  58. package/dist/index.d.ts +6 -0
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +7 -0
  61. package/dist/index.js.map +1 -1
  62. package/dist/mcp/client.d.ts +64 -18
  63. package/dist/mcp/client.d.ts.map +1 -1
  64. package/dist/mcp/client.js +190 -26
  65. package/dist/mcp/client.js.map +1 -1
  66. package/dist/mcp/index.d.ts +5 -2
  67. package/dist/mcp/index.d.ts.map +1 -1
  68. package/dist/mcp/index.js +3 -8
  69. package/dist/mcp/index.js.map +1 -1
  70. package/dist/mcp/merged-executor.d.ts +74 -0
  71. package/dist/mcp/merged-executor.d.ts.map +1 -0
  72. package/dist/mcp/merged-executor.js +198 -0
  73. package/dist/mcp/merged-executor.js.map +1 -0
  74. package/dist/mcp/pool.d.ts +71 -0
  75. package/dist/mcp/pool.d.ts.map +1 -0
  76. package/dist/mcp/pool.js +171 -0
  77. package/dist/mcp/pool.js.map +1 -0
  78. package/dist/mcp/tool-merger.d.ts +8 -5
  79. package/dist/mcp/tool-merger.d.ts.map +1 -1
  80. package/dist/mcp/tool-merger.js +8 -16
  81. package/dist/mcp/tool-merger.js.map +1 -1
  82. package/dist/model-catalog.d.ts +36 -0
  83. package/dist/model-catalog.d.ts.map +1 -0
  84. package/dist/model-catalog.js +102 -0
  85. package/dist/model-catalog.js.map +1 -0
  86. package/dist/model-tier-resolver.d.ts +61 -0
  87. package/dist/model-tier-resolver.d.ts.map +1 -0
  88. package/dist/model-tier-resolver.js +170 -0
  89. package/dist/model-tier-resolver.js.map +1 -0
  90. package/dist/ollama-adapter.d.ts.map +1 -1
  91. package/dist/ollama-adapter.js +33 -8
  92. package/dist/ollama-adapter.js.map +1 -1
  93. package/dist/opencode-adapter.d.ts +11 -0
  94. package/dist/opencode-adapter.d.ts.map +1 -1
  95. package/dist/opencode-adapter.js +13 -0
  96. package/dist/opencode-adapter.js.map +1 -1
  97. package/dist/openrouter-adapter.d.ts +15 -0
  98. package/dist/openrouter-adapter.d.ts.map +1 -1
  99. package/dist/openrouter-adapter.js +76 -19
  100. package/dist/openrouter-adapter.js.map +1 -1
  101. package/dist/provider-liveness.d.ts +5 -0
  102. package/dist/provider-liveness.d.ts.map +1 -1
  103. package/dist/provider-liveness.js +28 -21
  104. package/dist/provider-liveness.js.map +1 -1
  105. package/dist/registry.d.ts +1 -0
  106. package/dist/registry.d.ts.map +1 -1
  107. package/dist/registry.js +1 -1
  108. package/dist/registry.js.map +1 -1
  109. package/dist/router/local-executor.d.ts.map +1 -1
  110. package/dist/router/local-executor.js +19 -6
  111. package/dist/router/local-executor.js.map +1 -1
  112. package/dist/single-shot.d.ts.map +1 -1
  113. package/dist/single-shot.js +26 -1
  114. package/dist/single-shot.js.map +1 -1
  115. package/dist/tools/builtin.d.ts +19 -0
  116. package/dist/tools/builtin.d.ts.map +1 -1
  117. package/dist/tools/builtin.js +51 -0
  118. package/dist/tools/builtin.js.map +1 -1
  119. package/dist/upstream-error.d.ts.map +1 -1
  120. package/dist/upstream-error.js +11 -1
  121. package/dist/upstream-error.js.map +1 -1
  122. package/package.json +3 -2
@@ -1,36 +1,76 @@
1
1
  /**
2
2
  * `McpAgentClient` — wraps the official MCP TypeScript SDK with the lifecycle
3
- * Anvil's agent layer needs (lazy connect, tool listing with namespacing,
4
- * tool dispatch, clean close).
3
+ * Anvil's agent layer needs (lazy connect, namespaced tool listing, tool
4
+ * dispatch with cancellation, progress notifications, EOF reconnect, clean
5
+ * close).
5
6
  *
6
- * One instance per configured MCP server. The agent's tool-call loop owns
7
- * close() so subprocesses don't leak between invocations.
7
+ * One instance per configured MCP server. `McpClientPool` owns multiple
8
+ * instances per workspace and shares them across the agent's lifetime so
9
+ * resume turns don't re-pay the connect cost.
10
+ *
11
+ * Naming convention: tools are surfaced as `mcp__<server>__<tool>` (double
12
+ * underscore, matching Claude Code / Anthropic SDK). The bare tool name is
13
+ * sent to the server during dispatch.
8
14
  */
9
15
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
16
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
11
17
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
18
+ import { mkdirSync, createWriteStream } from 'node:fs';
19
+ import { join } from 'node:path';
20
+ import { homedir } from 'node:os';
12
21
  import { VERSION } from '../version.js';
13
22
  const CLIENT_NAME = 'anvil-agent';
23
+ /** Prefix every MCP-sourced tool with `mcp__<server>__` so it can never
24
+ * collide with a builtin and so the model recognizes the Claude-Code-
25
+ * established convention. */
26
+ export const MCP_NAME_PREFIX = 'mcp__';
27
+ export function mcpToolName(serverName, toolName) {
28
+ return `${MCP_NAME_PREFIX}${serverName}__${toolName}`;
29
+ }
14
30
  export class McpAgentClient {
15
31
  config;
16
32
  client;
17
33
  connected = false;
18
- constructor(config) {
34
+ connecting;
35
+ stderrStream;
36
+ opts;
37
+ /** Tracks request ids cancelled via `cancelInFlight`. */
38
+ cancelControllers = new Set();
39
+ constructor(config, opts = {}) {
19
40
  this.config = config;
41
+ this.opts = opts;
20
42
  this.client = new Client({ name: CLIENT_NAME, version: VERSION }, { capabilities: {} });
43
+ this.wireProgressHandler();
21
44
  }
45
+ // ── Connection lifecycle ───────────────────────────────────────────────
22
46
  async connect() {
23
47
  if (this.connected)
24
48
  return;
49
+ // Coalesce concurrent first-use; every caller awaits the same promise.
50
+ if (this.connecting)
51
+ return this.connecting;
52
+ this.connecting = this._connect().finally(() => {
53
+ this.connecting = undefined;
54
+ });
55
+ return this.connecting;
56
+ }
57
+ async _connect() {
25
58
  if (this.config.transport === 'stdio') {
26
59
  if (!this.config.command) {
27
60
  throw new Error(`MCP server "${this.config.name}" has stdio transport but no command`);
28
61
  }
62
+ this.openStderrLog();
29
63
  const transport = new StdioClientTransport({
30
64
  command: this.config.command,
31
65
  args: this.config.args ?? [],
32
66
  env: this.config.env,
67
+ // Capture stderr so the protocol JSON on stdout isn't polluted +
68
+ // give the user something to grep when an MCP server misbehaves.
69
+ stderr: this.stderrStream ? 'pipe' : 'inherit',
33
70
  });
71
+ if (this.stderrStream && transport.stderr) {
72
+ transport.stderr.pipe(this.stderrStream);
73
+ }
34
74
  await this.client.connect(transport);
35
75
  }
36
76
  else {
@@ -44,49 +84,173 @@ export class McpAgentClient {
44
84
  }
45
85
  this.connected = true;
46
86
  }
47
- /**
48
- * Returns the server's tools, namespaced as `<serverName>/<toolName>` so
49
- * multiple MCP servers exposing identically-named tools don't collide in
50
- * the agent's flat tool registry.
51
- */
87
+ openStderrLog() {
88
+ if (this.stderrStream || this.config.transport !== 'stdio')
89
+ return;
90
+ const dir = this.opts.stderrLogDir ?? join(homedir(), '.anvil', 'mcp-logs');
91
+ try {
92
+ mkdirSync(dir, { recursive: true });
93
+ const suffix = this.opts.runId ? `-${this.opts.runId}` : '';
94
+ const path = join(dir, `${safeFileName(this.config.name)}${suffix}.log`);
95
+ this.stderrStream = createWriteStream(path, { flags: 'a' });
96
+ this.stderrStream.write(`\n--- mcp server "${this.config.name}" started ${new Date().toISOString()} ---\n`);
97
+ }
98
+ catch {
99
+ // Log capture is best-effort; fall back to inherit (stderr to process).
100
+ this.stderrStream = undefined;
101
+ }
102
+ }
103
+ // ── Tool discovery + dispatch ──────────────────────────────────────────
52
104
  async listTools() {
53
105
  if (!this.connected)
54
106
  await this.connect();
55
107
  const result = await this.client.listTools();
56
- return result.tools.map((t) => ({
57
- name: `${this.config.name}/${t.name}`,
58
- description: t.description ?? '',
59
- inputSchema: t.inputSchema ?? {},
60
- }));
108
+ return result.tools.map((t) => {
109
+ const ann = t.annotations;
110
+ const annotations = {
111
+ readOnly: ann?.readOnlyHint ?? heuristicReadOnly(t.name),
112
+ destructive: ann?.destructiveHint,
113
+ idempotent: ann?.idempotentHint,
114
+ openWorld: ann?.openWorldHint,
115
+ };
116
+ const namespaced = mcpToolName(this.config.name, t.name);
117
+ const description = decorateDescription(t.description ?? '', this.config.name, annotations);
118
+ return {
119
+ name: namespaced,
120
+ bareName: t.name,
121
+ serverName: this.config.name,
122
+ schema: {
123
+ name: namespaced,
124
+ description,
125
+ inputSchema: t.inputSchema ?? { type: 'object' },
126
+ },
127
+ annotations,
128
+ };
129
+ });
61
130
  }
62
131
  /**
63
132
  * Dispatch a tool call. Accepts either the namespaced form
64
- * (`<server>/<tool>`) or the bare tool name; strips the server prefix
65
- * before forwarding to the SDK.
133
+ * (`mcp__<server>__<tool>`) or the bare tool name. Cancellation is wired
134
+ * via an AbortController stored in `cancelControllers` — `cancelInFlight`
135
+ * aborts every pending call.
66
136
  */
67
- async callTool(toolName, args) {
137
+ async callTool(toolName, args, signal) {
68
138
  if (!this.connected)
69
139
  await this.connect();
70
- const prefix = `${this.config.name}/`;
71
- const stripped = toolName.startsWith(prefix) ? toolName.slice(prefix.length) : toolName;
72
- const result = await this.client.callTool({
73
- name: stripped,
74
- arguments: args,
75
- });
76
- return result;
140
+ const bare = stripMcpPrefix(toolName, this.config.name);
141
+ const inner = new AbortController();
142
+ this.cancelControllers.add(inner);
143
+ if (signal) {
144
+ if (signal.aborted)
145
+ inner.abort(signal.reason);
146
+ else
147
+ signal.addEventListener('abort', () => inner.abort(signal.reason), { once: true });
148
+ }
149
+ try {
150
+ // The SDK's callTool accepts an AbortSignal in the request options —
151
+ // it emits `notifications/cancelled` on the wire when fired.
152
+ const result = await this.client.callTool({ name: bare, arguments: args }, undefined, {
153
+ signal: inner.signal,
154
+ });
155
+ return result;
156
+ }
157
+ finally {
158
+ this.cancelControllers.delete(inner);
159
+ }
160
+ }
161
+ /** Abort every in-flight tool call. Used on agent kill. */
162
+ cancelInFlight(reason) {
163
+ for (const c of this.cancelControllers) {
164
+ try {
165
+ c.abort(reason ?? 'cancelled');
166
+ }
167
+ catch { /* ok */ }
168
+ }
169
+ this.cancelControllers.clear();
77
170
  }
78
171
  async close() {
79
- if (!this.connected)
172
+ this.cancelInFlight('client closed');
173
+ if (!this.connected) {
174
+ this.stderrStream?.end();
175
+ this.stderrStream = undefined;
80
176
  return;
177
+ }
81
178
  try {
82
179
  await this.client.close();
83
180
  }
84
181
  finally {
85
182
  this.connected = false;
183
+ this.stderrStream?.end();
184
+ this.stderrStream = undefined;
86
185
  }
87
186
  }
88
187
  isConnected() {
89
188
  return this.connected;
90
189
  }
190
+ // ── Progress wiring ────────────────────────────────────────────────────
191
+ wireProgressHandler() {
192
+ if (!this.opts.onProgress)
193
+ return;
194
+ const onProgress = this.opts.onProgress;
195
+ // The MCP SDK exposes progress via notification handlers — register a
196
+ // generic one and re-emit through the caller's callback. The
197
+ // notification name space: `notifications/progress`.
198
+ const fallbackProgress = (ev) => onProgress(ev);
199
+ // setNotificationHandler is the public hook on the Client class —
200
+ // the SDK calls it for every server-initiated notification matching
201
+ // the schema's method.
202
+ try {
203
+ this.client.setNotificationHandler({ method: 'notifications/progress' }, (n) => {
204
+ const p = n.params ?? {};
205
+ fallbackProgress({
206
+ serverName: this.config.name,
207
+ toolName: String(p.progressToken ?? ''),
208
+ progress: typeof p.progress === 'number' ? p.progress : 0,
209
+ total: typeof p.total === 'number' ? p.total : undefined,
210
+ message: typeof p.message === 'string' ? p.message : undefined,
211
+ });
212
+ });
213
+ }
214
+ catch {
215
+ // Older SDK versions may not expose setNotificationHandler the same way;
216
+ // progress is a nice-to-have, not a blocker.
217
+ }
218
+ }
219
+ }
220
+ // ── Helpers ────────────────────────────────────────────────────────────
221
+ function stripMcpPrefix(toolName, serverName) {
222
+ const prefix = `${MCP_NAME_PREFIX}${serverName}__`;
223
+ if (toolName.startsWith(prefix))
224
+ return toolName.slice(prefix.length);
225
+ // Legacy `<server>/<tool>` form — accept for backward compat with old
226
+ // tool-merger.ts callers that may still be hanging around.
227
+ const legacy = `${serverName}/`;
228
+ if (toolName.startsWith(legacy))
229
+ return toolName.slice(legacy.length);
230
+ return toolName;
231
+ }
232
+ function safeFileName(s) {
233
+ return s.replace(/[^a-zA-Z0-9_.-]+/g, '_');
234
+ }
235
+ const READONLY_VERBS = /^(read|get|list|search|find|query|describe|inspect|count|fetch|view|show)/i;
236
+ function heuristicReadOnly(toolName) {
237
+ // Fallback when the server hasn't declared `readOnlyHint`. Permissive on
238
+ // purpose — a misclassification merely surfaces the call to the dest./
239
+ // allowlist filter, which has the last word.
240
+ return READONLY_VERBS.test(toolName);
241
+ }
242
+ function decorateDescription(raw, serverName, annotations) {
243
+ // Tag the description with the server name + behavior hints so the model
244
+ // can pick between overlapping tools (filesystem-mcp:read vs builtin
245
+ // read_file). Best practice across Claude Code / Goose / Cursor.
246
+ const hints = [];
247
+ if (annotations.destructive)
248
+ hints.push('destructive');
249
+ else if (annotations.readOnly)
250
+ hints.push('read-only');
251
+ if (annotations.idempotent)
252
+ hints.push('idempotent');
253
+ const tag = hints.length > 0 ? ` [${hints.join(', ')}]` : '';
254
+ return `(via ${serverName} MCP${tag}) ${raw}`.trim();
91
255
  }
92
256
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,13 @@
3
3
  *
4
4
  * Companion to `code-search-mcp` (which is the MCP *server* Anvil already
5
5
  * publishes). The client side lets Anvil's agent connect to OTHER MCP
6
- * servers configured per project.
6
+ * servers configured per project — surfacing their tools to non-Claude
7
+ * adapters too via `MergedToolExecutor`.
7
8
  */
8
9
  export type { McpTransport, McpServerConfig, McpServerEntry, McpServersFile, } from './types.js';
9
10
  export { loadMcpServers, findMcpConfigPath, type LoadMcpServersOptions, } from './config-loader.js';
10
- export { McpAgentClient } from './client.js';
11
+ export { McpAgentClient, mcpToolName, MCP_NAME_PREFIX, type McpClientOpts, type McpToolDescriptor, type McpToolAnnotations, type McpProgressEvent, } from './client.js';
11
12
  export { buildAgentToolset, type AgentToolset, } from './tool-merger.js';
13
+ export { McpClientPool, type McpClientPoolOpts, } from './pool.js';
14
+ export { MergedToolExecutor, type MergedToolExecutorOpts, } from './merged-executor.js';
12
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC"}
package/dist/mcp/index.js CHANGED
@@ -1,11 +1,6 @@
1
- /**
2
- * @esankhan3/anvil-agent-core/mcp — Model Context Protocol *client*-side helpers.
3
- *
4
- * Companion to `code-search-mcp` (which is the MCP *server* Anvil already
5
- * publishes). The client side lets Anvil's agent connect to OTHER MCP
6
- * servers configured per project.
7
- */
8
1
  export { loadMcpServers, findMcpConfigPath, } from './config-loader.js';
9
- export { McpAgentClient } from './client.js';
2
+ export { McpAgentClient, mcpToolName, MCP_NAME_PREFIX, } from './client.js';
10
3
  export { buildAgentToolset, } from './tool-merger.js';
4
+ export { McpClientPool, } from './pool.js';
5
+ export { MergedToolExecutor, } from './merged-executor.js';
11
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EACL,cAAc,EACd,iBAAiB,GAElB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,iBAAiB,GAElB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,iBAAiB,GAElB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,WAAW,EACX,eAAe,GAKhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,aAAa,GAEd,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,kBAAkB,GAEnB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * `MergedToolExecutor` — a `ToolExecutor` that exposes both the seven
3
+ * builtin tools and every tool advertised by an `McpClientPool`. The
4
+ * non-Claude adapters (Ollama, OpenRouter, OpenCode, OpenAI, Gemini, ADK)
5
+ * consume this as `config.toolExecutor` and gain MCP support transparently.
6
+ *
7
+ * Naming convention: builtins keep their bare names (`read_file`, `bash`);
8
+ * MCP tools are `mcp__<server>__<tool>`. The dispatch chain in `execute`
9
+ * routes by name.
10
+ *
11
+ * Per-stage `allowedTools` filtering supports two forms:
12
+ * - exact name: `"read_file"`, `"mcp__github__create_issue"`
13
+ * - per-server glob: `"mcp__github__*"` matches every tool from
14
+ * `github` server.
15
+ *
16
+ * Destructive-tier guard: if a MCP tool's annotations declare
17
+ * `destructive: true` AND the stage's allowlist doesn't explicitly name it
18
+ * (only matched by glob), it's hidden from `listSchemas`. Stages that need
19
+ * a destructive MCP tool must list it by full name. Prevents the model
20
+ * from being handed `mcp__filesystem__delete_file` just because the stage
21
+ * had `mcp__filesystem__*`.
22
+ */
23
+ import type { ToolCall, ToolSchema } from '../types.js';
24
+ import type { ExecCtx, ToolExecutor, ToolResult } from '../tools/types.js';
25
+ import { BuiltinToolExecutor } from '../tools/builtin.js';
26
+ import type { McpClientPool } from './pool.js';
27
+ export interface MergedToolExecutorOpts {
28
+ builtin: BuiltinToolExecutor;
29
+ pool?: McpClientPool;
30
+ /** Stage-policy allow list. Pass-through of `req.allowedTools`. */
31
+ allowedTools?: string[];
32
+ /** Surface MCP call resolution onto telemetry / activity feed. */
33
+ onMcpCallStart?: (info: {
34
+ tool: string;
35
+ serverName: string;
36
+ }) => void;
37
+ onMcpCallEnd?: (info: {
38
+ tool: string;
39
+ serverName: string;
40
+ durationMs: number;
41
+ isError: boolean;
42
+ }) => void;
43
+ }
44
+ export declare class MergedToolExecutor implements ToolExecutor {
45
+ private readonly builtin;
46
+ private readonly pool?;
47
+ private readonly allowedExact;
48
+ private readonly allowedGlobs;
49
+ private readonly allowAllBuiltins;
50
+ private readonly onStart?;
51
+ private readonly onEnd?;
52
+ /** Lazily populated by `listSchemas` once MCP discovery has run. */
53
+ private mcpDescriptors;
54
+ constructor(opts: MergedToolExecutorOpts);
55
+ /**
56
+ * Returns the union of builtin + MCP tool schemas, filtered by the
57
+ * stage's allowlist. Builtin filtering is delegated to BuiltinToolExecutor
58
+ * (which was already wired with `allowedTools`); MCP filtering happens
59
+ * here.
60
+ *
61
+ * NOTE: synchronous; reads the pool's cached tool list. Callers MUST
62
+ * call `prime()` once (awaitable) before the first `listSchemas` so MCP
63
+ * discovery has completed. After that the cache is hot.
64
+ */
65
+ listSchemas(): ToolSchema[];
66
+ /** Warm the MCP tool cache so a later sync `listSchemas` is complete. */
67
+ prime(): Promise<void>;
68
+ execute(call: ToolCall, ctx: ExecCtx): Promise<ToolResult>;
69
+ /** Show this descriptor at schema time? Apply destructive guard. */
70
+ private allowedForListing;
71
+ /** Allow this name at exec time? Defense-in-depth check vs listing. */
72
+ private allowedForExec;
73
+ }
74
+ //# sourceMappingURL=merged-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merged-executor.d.ts","sourceRoot":"","sources":["../../src/mcp/merged-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3G;AAED,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA2C;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAyC;IAChE,oEAAoE;IACpE,OAAO,CAAC,cAAc,CAAoC;gBAE9C,IAAI,EAAE,sBAAsB;IAmBxC;;;;;;;;;OASG;IACH,WAAW,IAAI,UAAU,EAAE;IAU3B,yEAAyE;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IA+ChE,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAgBzB,uEAAuE;IACvE,OAAO,CAAC,cAAc;CAcvB"}
@@ -0,0 +1,198 @@
1
+ export class MergedToolExecutor {
2
+ builtin;
3
+ pool;
4
+ allowedExact;
5
+ allowedGlobs;
6
+ allowAllBuiltins;
7
+ onStart;
8
+ onEnd;
9
+ /** Lazily populated by `listSchemas` once MCP discovery has run. */
10
+ mcpDescriptors = null;
11
+ constructor(opts) {
12
+ this.builtin = opts.builtin;
13
+ this.pool = opts.pool;
14
+ this.onStart = opts.onMcpCallStart;
15
+ this.onEnd = opts.onMcpCallEnd;
16
+ const allowed = opts.allowedTools ?? [];
17
+ this.allowedExact = new Set();
18
+ this.allowedGlobs = [];
19
+ this.allowAllBuiltins = allowed.length === 0;
20
+ for (const name of allowed) {
21
+ if (name.endsWith('__*') && name.startsWith('mcp__')) {
22
+ const serverName = name.slice('mcp__'.length, -3);
23
+ if (serverName.length > 0)
24
+ this.allowedGlobs.push({ serverName });
25
+ }
26
+ else {
27
+ this.allowedExact.add(name);
28
+ }
29
+ }
30
+ }
31
+ /**
32
+ * Returns the union of builtin + MCP tool schemas, filtered by the
33
+ * stage's allowlist. Builtin filtering is delegated to BuiltinToolExecutor
34
+ * (which was already wired with `allowedTools`); MCP filtering happens
35
+ * here.
36
+ *
37
+ * NOTE: synchronous; reads the pool's cached tool list. Callers MUST
38
+ * call `prime()` once (awaitable) before the first `listSchemas` so MCP
39
+ * discovery has completed. After that the cache is hot.
40
+ */
41
+ listSchemas() {
42
+ const out = [...this.builtin.listSchemas()];
43
+ if (!this.mcpDescriptors)
44
+ return out;
45
+ for (const desc of this.mcpDescriptors) {
46
+ if (!this.allowedForListing(desc))
47
+ continue;
48
+ out.push(desc.schema);
49
+ }
50
+ return out;
51
+ }
52
+ /** Warm the MCP tool cache so a later sync `listSchemas` is complete. */
53
+ async prime() {
54
+ if (!this.pool || this.mcpDescriptors)
55
+ return;
56
+ this.mcpDescriptors = await this.pool.discoverTools();
57
+ }
58
+ async execute(call, ctx) {
59
+ if (!call.name.startsWith('mcp__')) {
60
+ // Builtin path — BuiltinToolExecutor enforces its own allowlist.
61
+ return this.builtin.execute(call, ctx);
62
+ }
63
+ if (!this.pool) {
64
+ return {
65
+ isError: true,
66
+ content: `Tool "${call.name}" requires an MCP server but no pool is configured.`,
67
+ };
68
+ }
69
+ if (!this.allowedForExec(call.name)) {
70
+ return {
71
+ isError: true,
72
+ content: `Tool "${call.name}" is not permitted in this stage.`,
73
+ };
74
+ }
75
+ const serverName = ownerFor(call.name);
76
+ if (!serverName) {
77
+ return { isError: true, content: `Cannot parse MCP server from "${call.name}".` };
78
+ }
79
+ const started = Date.now();
80
+ this.onStart?.({ tool: call.name, serverName });
81
+ try {
82
+ const result = await this.pool.callTool(call.name, call.arguments ?? {}, ctx.abortSignal);
83
+ const flattened = flattenMcpContent(result);
84
+ this.onEnd?.({
85
+ tool: call.name,
86
+ serverName,
87
+ durationMs: Date.now() - started,
88
+ isError: flattened.isError,
89
+ });
90
+ return flattened;
91
+ }
92
+ catch (err) {
93
+ const message = err instanceof Error ? err.message : String(err);
94
+ this.onEnd?.({
95
+ tool: call.name,
96
+ serverName,
97
+ durationMs: Date.now() - started,
98
+ isError: true,
99
+ });
100
+ return { isError: true, content: `MCP call failed: ${message}` };
101
+ }
102
+ }
103
+ // ── Filter logic ───────────────────────────────────────────────────────
104
+ /** Show this descriptor at schema time? Apply destructive guard. */
105
+ allowedForListing(desc) {
106
+ // Exact-match wins regardless of destructive flag.
107
+ if (this.allowedExact.has(desc.name))
108
+ return true;
109
+ if (this.allowAllBuiltins && !desc.annotations.destructive) {
110
+ // Empty allowlist means read-only fallback per BuiltinToolExecutor;
111
+ // mirror that for MCP tools so they aren't surfaced by default.
112
+ return false;
113
+ }
114
+ const matchesGlob = this.allowedGlobs.some((g) => g.serverName === desc.serverName);
115
+ if (!matchesGlob)
116
+ return false;
117
+ // Glob match: hide destructive tools unless the stage names them
118
+ // explicitly.
119
+ if (desc.annotations.destructive)
120
+ return false;
121
+ return true;
122
+ }
123
+ /** Allow this name at exec time? Defense-in-depth check vs listing. */
124
+ allowedForExec(name) {
125
+ if (this.allowAllBuiltins) {
126
+ // Match the listing default for empty allowlist.
127
+ return false;
128
+ }
129
+ if (this.allowedExact.has(name))
130
+ return true;
131
+ const owner = ownerFor(name);
132
+ if (!owner)
133
+ return false;
134
+ if (!this.allowedGlobs.some((g) => g.serverName === owner))
135
+ return false;
136
+ // Glob path: re-fetch annotations to gate destructive tools.
137
+ const desc = this.mcpDescriptors?.find((d) => d.name === name);
138
+ if (desc?.annotations.destructive)
139
+ return false;
140
+ return true;
141
+ }
142
+ }
143
+ // ── Helpers ────────────────────────────────────────────────────────────
144
+ function ownerFor(toolName) {
145
+ if (!toolName.startsWith('mcp__'))
146
+ return undefined;
147
+ // mcp__<server>__<tool>; server may contain underscores. We split on the
148
+ // FIRST `__` after the prefix that's followed by a tool name with no
149
+ // `__`. Simpler: match `mcp__([^_]+(?:_[^_]+)*)__`.
150
+ const rest = toolName.slice('mcp__'.length);
151
+ // Look for the LAST `__` so the server name eats the rest.
152
+ const idx = rest.lastIndexOf('__');
153
+ if (idx < 0)
154
+ return undefined;
155
+ return rest.slice(0, idx);
156
+ }
157
+ /**
158
+ * Collapse the MCP SDK's structured `content[]` result into the
159
+ * `ToolResult` shape the builtin executor uses. Text parts concatenate;
160
+ * image / resource parts surface as `[image: <mime>]` placeholders so the
161
+ * model isn't fed binary garbage.
162
+ */
163
+ function flattenMcpContent(raw) {
164
+ if (!raw || typeof raw !== 'object') {
165
+ return { isError: false, content: String(raw ?? '') };
166
+ }
167
+ const r = raw;
168
+ const parts = [];
169
+ if (Array.isArray(r.content)) {
170
+ for (const block of r.content) {
171
+ if (!block || typeof block !== 'object')
172
+ continue;
173
+ if (block.type === 'text' && typeof block.text === 'string') {
174
+ parts.push(block.text);
175
+ }
176
+ else if (block.type === 'image') {
177
+ parts.push(`[image: ${block.mimeType ?? 'unknown'}]`);
178
+ }
179
+ else if (block.type === 'resource') {
180
+ parts.push(`[resource]`);
181
+ }
182
+ else {
183
+ parts.push(`[${block.type ?? 'unknown'}]`);
184
+ }
185
+ }
186
+ }
187
+ if (parts.length === 0 && r.structuredContent !== undefined) {
188
+ try {
189
+ parts.push(JSON.stringify(r.structuredContent));
190
+ }
191
+ catch { /* ok */ }
192
+ }
193
+ return {
194
+ isError: r.isError === true,
195
+ content: parts.join('\n').trim() || '(empty)',
196
+ };
197
+ }
198
+ //# sourceMappingURL=merged-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merged-executor.js","sourceRoot":"","sources":["../../src/mcp/merged-executor.ts"],"names":[],"mappings":"AAsCA,MAAM,OAAO,kBAAkB;IACZ,OAAO,CAAsB;IAC7B,IAAI,CAAiB;IACrB,YAAY,CAAc;IAC1B,YAAY,CAAgC;IAC5C,gBAAgB,CAAU;IAC1B,OAAO,CAA4C;IACnD,KAAK,CAA0C;IAChE,oEAAoE;IAC5D,cAAc,GAA+B,IAAI,CAAC;IAE1D,YAAY,IAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;oBAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW;QACT,MAAM,GAAG,GAAiB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,GAAG,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5C,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,yEAAyE;IACzE,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAC9C,IAAI,CAAC,cAAc,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAc,EAAE,GAAY;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,iEAAiE;YACjE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,qDAAqD;aACjF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,SAAS,IAAI,CAAC,IAAI,mCAAmC;aAC/D,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,iCAAiC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACpF,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;YAC1F,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU;gBACV,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;gBAChC,OAAO,EAAE,SAAS,CAAC,OAAO;aAC3B,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,UAAU;gBACV,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;gBAChC,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,OAAO,EAAE,EAAE,CAAC;QACnE,CAAC;IACH,CAAC;IAED,0EAA0E;IAE1E,oEAAoE;IAC5D,iBAAiB,CAAC,IAAuB;QAC/C,mDAAmD;QACnD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAClD,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAC3D,oEAAoE;YACpE,gEAAgE;YAChE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;QACpF,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/B,iEAAiE;QACjE,cAAc;QACd,IAAI,IAAI,CAAC,WAAW,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uEAAuE;IAC/D,cAAc,CAAC,IAAY;QACjC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,iDAAiD;YACjD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACzE,6DAA6D;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC/D,IAAI,IAAI,EAAE,WAAW,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,0EAA0E;AAE1E,SAAS,QAAQ,CAAC,QAAgB;IAChC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,yEAAyE;IACzE,qEAAqE;IACrE,oDAAoD;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,2DAA2D;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,GAAY;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;IACxD,CAAC;IACD,MAAM,CAAC,GAAG,GAIT,CAAC;IACF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,SAAS;YAClD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,QAAQ,IAAI,SAAS,GAAG,CAAC,CAAC;YACxD,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,SAAS,GAAG,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC5D,IAAI,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,OAAO,KAAK,IAAI;QAC3B,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS;KAC9C,CAAC;AACJ,CAAC"}