@animus-labs/cortex 0.2.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.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/budget-guard.d.ts +75 -0
- package/dist/budget-guard.d.ts.map +1 -0
- package/dist/budget-guard.js +142 -0
- package/dist/budget-guard.js.map +1 -0
- package/dist/compaction/compaction.d.ts +99 -0
- package/dist/compaction/compaction.d.ts.map +1 -0
- package/dist/compaction/compaction.js +302 -0
- package/dist/compaction/compaction.js.map +1 -0
- package/dist/compaction/failsafe.d.ts +57 -0
- package/dist/compaction/failsafe.d.ts.map +1 -0
- package/dist/compaction/failsafe.js +135 -0
- package/dist/compaction/failsafe.js.map +1 -0
- package/dist/compaction/index.d.ts +381 -0
- package/dist/compaction/index.d.ts.map +1 -0
- package/dist/compaction/index.js +979 -0
- package/dist/compaction/index.js.map +1 -0
- package/dist/compaction/microcompaction.d.ts +219 -0
- package/dist/compaction/microcompaction.d.ts.map +1 -0
- package/dist/compaction/microcompaction.js +536 -0
- package/dist/compaction/microcompaction.js.map +1 -0
- package/dist/compaction/observational/buffering.d.ts +225 -0
- package/dist/compaction/observational/buffering.d.ts.map +1 -0
- package/dist/compaction/observational/buffering.js +354 -0
- package/dist/compaction/observational/buffering.js.map +1 -0
- package/dist/compaction/observational/constants.d.ts +70 -0
- package/dist/compaction/observational/constants.d.ts.map +1 -0
- package/dist/compaction/observational/constants.js +507 -0
- package/dist/compaction/observational/constants.js.map +1 -0
- package/dist/compaction/observational/index.d.ts +219 -0
- package/dist/compaction/observational/index.d.ts.map +1 -0
- package/dist/compaction/observational/index.js +641 -0
- package/dist/compaction/observational/index.js.map +1 -0
- package/dist/compaction/observational/observer.d.ts +97 -0
- package/dist/compaction/observational/observer.d.ts.map +1 -0
- package/dist/compaction/observational/observer.js +424 -0
- package/dist/compaction/observational/observer.js.map +1 -0
- package/dist/compaction/observational/recall-tool.d.ts +27 -0
- package/dist/compaction/observational/recall-tool.d.ts.map +1 -0
- package/dist/compaction/observational/recall-tool.js +93 -0
- package/dist/compaction/observational/recall-tool.js.map +1 -0
- package/dist/compaction/observational/reflector.d.ts +94 -0
- package/dist/compaction/observational/reflector.d.ts.map +1 -0
- package/dist/compaction/observational/reflector.js +167 -0
- package/dist/compaction/observational/reflector.js.map +1 -0
- package/dist/compaction/observational/types.d.ts +271 -0
- package/dist/compaction/observational/types.d.ts.map +1 -0
- package/dist/compaction/observational/types.js +15 -0
- package/dist/compaction/observational/types.js.map +1 -0
- package/dist/context-manager.d.ts +134 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +170 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/cortex-agent.d.ts +1020 -0
- package/dist/cortex-agent.d.ts.map +1 -0
- package/dist/cortex-agent.js +3589 -0
- package/dist/cortex-agent.js.map +1 -0
- package/dist/error-classifier.d.ts +48 -0
- package/dist/error-classifier.d.ts.map +1 -0
- package/dist/error-classifier.js +152 -0
- package/dist/error-classifier.js.map +1 -0
- package/dist/event-bridge.d.ts +166 -0
- package/dist/event-bridge.d.ts.map +1 -0
- package/dist/event-bridge.js +381 -0
- package/dist/event-bridge.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +119 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +474 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/model-wrapper.d.ts +58 -0
- package/dist/model-wrapper.d.ts.map +1 -0
- package/dist/model-wrapper.js +86 -0
- package/dist/model-wrapper.js.map +1 -0
- package/dist/noop-logger.d.ts +4 -0
- package/dist/noop-logger.d.ts.map +1 -0
- package/dist/noop-logger.js +8 -0
- package/dist/noop-logger.js.map +1 -0
- package/dist/prompt-diagnostics.d.ts +47 -0
- package/dist/prompt-diagnostics.d.ts.map +1 -0
- package/dist/prompt-diagnostics.js +230 -0
- package/dist/prompt-diagnostics.js.map +1 -0
- package/dist/provider-manager.d.ts +224 -0
- package/dist/provider-manager.d.ts.map +1 -0
- package/dist/provider-manager.js +563 -0
- package/dist/provider-manager.js.map +1 -0
- package/dist/provider-registry.d.ts +115 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +305 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/schema-converter.d.ts +20 -0
- package/dist/schema-converter.d.ts.map +1 -0
- package/dist/schema-converter.js +48 -0
- package/dist/schema-converter.js.map +1 -0
- package/dist/skill-preprocessor.d.ts +46 -0
- package/dist/skill-preprocessor.d.ts.map +1 -0
- package/dist/skill-preprocessor.js +237 -0
- package/dist/skill-preprocessor.js.map +1 -0
- package/dist/skill-registry.d.ts +107 -0
- package/dist/skill-registry.d.ts.map +1 -0
- package/dist/skill-registry.js +330 -0
- package/dist/skill-registry.js.map +1 -0
- package/dist/skill-tool.d.ts +54 -0
- package/dist/skill-tool.d.ts.map +1 -0
- package/dist/skill-tool.js +88 -0
- package/dist/skill-tool.js.map +1 -0
- package/dist/sub-agent-manager.d.ts +90 -0
- package/dist/sub-agent-manager.d.ts.map +1 -0
- package/dist/sub-agent-manager.js +192 -0
- package/dist/sub-agent-manager.js.map +1 -0
- package/dist/token-estimator.d.ts +23 -0
- package/dist/token-estimator.d.ts.map +1 -0
- package/dist/token-estimator.js +27 -0
- package/dist/token-estimator.js.map +1 -0
- package/dist/tool-contract.d.ts +68 -0
- package/dist/tool-contract.d.ts.map +1 -0
- package/dist/tool-contract.js +35 -0
- package/dist/tool-contract.js.map +1 -0
- package/dist/tool-result-persistence.d.ts +89 -0
- package/dist/tool-result-persistence.d.ts.map +1 -0
- package/dist/tool-result-persistence.js +152 -0
- package/dist/tool-result-persistence.js.map +1 -0
- package/dist/tools/bash/index.d.ts +71 -0
- package/dist/tools/bash/index.d.ts.map +1 -0
- package/dist/tools/bash/index.js +485 -0
- package/dist/tools/bash/index.js.map +1 -0
- package/dist/tools/bash/interactive.d.ts +47 -0
- package/dist/tools/bash/interactive.d.ts.map +1 -0
- package/dist/tools/bash/interactive.js +262 -0
- package/dist/tools/bash/interactive.js.map +1 -0
- package/dist/tools/bash/safety.d.ts +149 -0
- package/dist/tools/bash/safety.d.ts.map +1 -0
- package/dist/tools/bash/safety.js +1116 -0
- package/dist/tools/bash/safety.js.map +1 -0
- package/dist/tools/edit.d.ts +57 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +310 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +34 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +268 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +53 -0
- package/dist/tools/grep.d.ts.map +1 -0
- package/dist/tools/grep.js +673 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/index.d.ts +62 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/read.d.ts +43 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +459 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/runtime.d.ts +62 -0
- package/dist/tools/runtime.d.ts.map +1 -0
- package/dist/tools/runtime.js +116 -0
- package/dist/tools/runtime.js.map +1 -0
- package/dist/tools/shared/cwd-tracker.d.ts +32 -0
- package/dist/tools/shared/cwd-tracker.d.ts.map +1 -0
- package/dist/tools/shared/cwd-tracker.js +44 -0
- package/dist/tools/shared/cwd-tracker.js.map +1 -0
- package/dist/tools/shared/edit-history.d.ts +55 -0
- package/dist/tools/shared/edit-history.d.ts.map +1 -0
- package/dist/tools/shared/edit-history.js +72 -0
- package/dist/tools/shared/edit-history.js.map +1 -0
- package/dist/tools/shared/edit-matcher.d.ts +83 -0
- package/dist/tools/shared/edit-matcher.d.ts.map +1 -0
- package/dist/tools/shared/edit-matcher.js +359 -0
- package/dist/tools/shared/edit-matcher.js.map +1 -0
- package/dist/tools/shared/file-mutation-lock.d.ts +22 -0
- package/dist/tools/shared/file-mutation-lock.d.ts.map +1 -0
- package/dist/tools/shared/file-mutation-lock.js +35 -0
- package/dist/tools/shared/file-mutation-lock.js.map +1 -0
- package/dist/tools/shared/gitignore.d.ts +17 -0
- package/dist/tools/shared/gitignore.d.ts.map +1 -0
- package/dist/tools/shared/gitignore.js +59 -0
- package/dist/tools/shared/gitignore.js.map +1 -0
- package/dist/tools/shared/pdf-extractor.d.ts +96 -0
- package/dist/tools/shared/pdf-extractor.d.ts.map +1 -0
- package/dist/tools/shared/pdf-extractor.js +196 -0
- package/dist/tools/shared/pdf-extractor.js.map +1 -0
- package/dist/tools/shared/read-registry.d.ts +66 -0
- package/dist/tools/shared/read-registry.d.ts.map +1 -0
- package/dist/tools/shared/read-registry.js +65 -0
- package/dist/tools/shared/read-registry.js.map +1 -0
- package/dist/tools/shared/safe-env.d.ts +18 -0
- package/dist/tools/shared/safe-env.d.ts.map +1 -0
- package/dist/tools/shared/safe-env.js +70 -0
- package/dist/tools/shared/safe-env.js.map +1 -0
- package/dist/tools/sub-agent.d.ts +91 -0
- package/dist/tools/sub-agent.d.ts.map +1 -0
- package/dist/tools/sub-agent.js +89 -0
- package/dist/tools/sub-agent.js.map +1 -0
- package/dist/tools/task-output.d.ts +38 -0
- package/dist/tools/task-output.d.ts.map +1 -0
- package/dist/tools/task-output.js +186 -0
- package/dist/tools/task-output.js.map +1 -0
- package/dist/tools/tool-search/index.d.ts +40 -0
- package/dist/tools/tool-search/index.d.ts.map +1 -0
- package/dist/tools/tool-search/index.js +110 -0
- package/dist/tools/tool-search/index.js.map +1 -0
- package/dist/tools/tool-search/registry.d.ts +82 -0
- package/dist/tools/tool-search/registry.d.ts.map +1 -0
- package/dist/tools/tool-search/registry.js +238 -0
- package/dist/tools/tool-search/registry.js.map +1 -0
- package/dist/tools/undo-edit.d.ts +51 -0
- package/dist/tools/undo-edit.d.ts.map +1 -0
- package/dist/tools/undo-edit.js +231 -0
- package/dist/tools/undo-edit.js.map +1 -0
- package/dist/tools/web-fetch/cache.d.ts +49 -0
- package/dist/tools/web-fetch/cache.d.ts.map +1 -0
- package/dist/tools/web-fetch/cache.js +89 -0
- package/dist/tools/web-fetch/cache.js.map +1 -0
- package/dist/tools/web-fetch/index.d.ts +53 -0
- package/dist/tools/web-fetch/index.d.ts.map +1 -0
- package/dist/tools/web-fetch/index.js +513 -0
- package/dist/tools/web-fetch/index.js.map +1 -0
- package/dist/tools/write.d.ts +59 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +316 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/types.d.ts +881 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/working-tags.d.ts +44 -0
- package/dist/working-tags.d.ts.map +1 -0
- package/dist/working-tags.js +103 -0
- package/dist/working-tags.js.map +1 -0
- package/package.json +87 -0
- package/src/budget-guard.ts +170 -0
- package/src/compaction/compaction.ts +386 -0
- package/src/compaction/failsafe.ts +185 -0
- package/src/compaction/index.ts +1199 -0
- package/src/compaction/microcompaction.ts +709 -0
- package/src/compaction/observational/buffering.ts +430 -0
- package/src/compaction/observational/constants.ts +532 -0
- package/src/compaction/observational/index.ts +837 -0
- package/src/compaction/observational/observer.ts +510 -0
- package/src/compaction/observational/recall-tool.ts +130 -0
- package/src/compaction/observational/reflector.ts +221 -0
- package/src/compaction/observational/types.ts +343 -0
- package/src/context-manager.ts +237 -0
- package/src/cortex-agent.ts +4297 -0
- package/src/error-classifier.ts +199 -0
- package/src/event-bridge.ts +508 -0
- package/src/index.ts +292 -0
- package/src/mcp-client.ts +582 -0
- package/src/model-wrapper.ts +128 -0
- package/src/noop-logger.ts +9 -0
- package/src/prompt-diagnostics.ts +296 -0
- package/src/provider-manager.ts +823 -0
- package/src/provider-registry.ts +386 -0
- package/src/schema-converter.ts +51 -0
- package/src/skill-preprocessor.ts +314 -0
- package/src/skill-registry.ts +378 -0
- package/src/skill-tool.ts +130 -0
- package/src/sub-agent-manager.ts +236 -0
- package/src/token-estimator.ts +26 -0
- package/src/tool-contract.ts +113 -0
- package/src/tool-result-persistence.ts +197 -0
- package/src/tools/bash/index.ts +633 -0
- package/src/tools/bash/interactive.ts +302 -0
- package/src/tools/bash/safety.ts +1297 -0
- package/src/tools/edit.ts +422 -0
- package/src/tools/glob.ts +330 -0
- package/src/tools/grep.ts +819 -0
- package/src/tools/index.ts +110 -0
- package/src/tools/read.ts +580 -0
- package/src/tools/runtime.ts +173 -0
- package/src/tools/shared/cwd-tracker.ts +50 -0
- package/src/tools/shared/edit-history.ts +96 -0
- package/src/tools/shared/edit-matcher.ts +457 -0
- package/src/tools/shared/file-mutation-lock.ts +40 -0
- package/src/tools/shared/gitignore.ts +61 -0
- package/src/tools/shared/pdf-extractor.ts +290 -0
- package/src/tools/shared/read-registry.ts +93 -0
- package/src/tools/shared/safe-env.ts +82 -0
- package/src/tools/sub-agent.ts +171 -0
- package/src/tools/task-output.ts +236 -0
- package/src/tools/tool-search/index.ts +167 -0
- package/src/tools/tool-search/registry.ts +278 -0
- package/src/tools/undo-edit.ts +314 -0
- package/src/tools/web-fetch/cache.ts +112 -0
- package/src/tools/web-fetch/index.ts +604 -0
- package/src/tools/write.ts +385 -0
- package/src/types.ts +1057 -0
- package/src/working-tags.ts +118 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* McpClientManager: connects to MCP servers and wraps discovered tools
|
|
3
|
+
* as AgentTool objects for registration with pi-agent-core.
|
|
4
|
+
*
|
|
5
|
+
* Handles two transport types:
|
|
6
|
+
* - Stdio: spawns a subprocess, communicates via stdin/stdout
|
|
7
|
+
* - HTTP: connects to an already-running Streamable HTTP server
|
|
8
|
+
*
|
|
9
|
+
* Tool discovery via tools/list, tool execution via tools/call.
|
|
10
|
+
* Connections are persistent (kept alive between ticks) with health monitoring.
|
|
11
|
+
* Reconnect on subprocess crash (3 attempts before deregistering).
|
|
12
|
+
*
|
|
13
|
+
* References:
|
|
14
|
+
* - docs/cortex/mcp-integration.md
|
|
15
|
+
* - docs/cortex/plans/phase-3-plugin-tools.md
|
|
16
|
+
*/
|
|
17
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
18
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
19
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
20
|
+
import { Type } from 'typebox';
|
|
21
|
+
import { NOOP_LOGGER } from './noop-logger.js';
|
|
22
|
+
import { buildSafeEnv } from './tools/shared/safe-env.js';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Constants
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const MAX_RECONNECT_ATTEMPTS = 3;
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// McpClientManager
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
export class McpClientManager {
|
|
31
|
+
connections = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* Callback invoked whenever the aggregate tool set changes.
|
|
34
|
+
* CortexAgent uses this to resync live tools after connect/disconnect/reconnect.
|
|
35
|
+
*/
|
|
36
|
+
onToolsChanged;
|
|
37
|
+
/**
|
|
38
|
+
* Callback invoked when a subprocess is spawned (for PID tracking).
|
|
39
|
+
* The consumer (CortexAgent) uses this to track PIDs for exit cleanup.
|
|
40
|
+
*/
|
|
41
|
+
onSubprocessSpawned;
|
|
42
|
+
/**
|
|
43
|
+
* Callback invoked when a subprocess exits (for PID tracking).
|
|
44
|
+
*/
|
|
45
|
+
onSubprocessExited;
|
|
46
|
+
/**
|
|
47
|
+
* Consumer-set environment variable overrides that bypass the security blocklist.
|
|
48
|
+
* Merged ON TOP of the sanitized environment for all stdio subprocesses.
|
|
49
|
+
* Used for macOS dock icon suppression vars (DYLD_INSERT_LIBRARIES, etc.).
|
|
50
|
+
*/
|
|
51
|
+
envOverrides;
|
|
52
|
+
/** Logger for MCP diagnostics. Set by CortexAgent after construction. */
|
|
53
|
+
logger = NOOP_LOGGER;
|
|
54
|
+
/**
|
|
55
|
+
* Connect to an MCP server and discover its tools.
|
|
56
|
+
*
|
|
57
|
+
* Spawns a subprocess (stdio) or connects to a URL (http), performs
|
|
58
|
+
* the MCP handshake, calls tools/list, and wraps each discovered
|
|
59
|
+
* tool as an AgentTool with namespaced name.
|
|
60
|
+
*
|
|
61
|
+
* @param serverName - Unique name for this server (used for tool namespacing)
|
|
62
|
+
* @param config - Transport configuration
|
|
63
|
+
* @throws Error if connection or tool discovery fails
|
|
64
|
+
*/
|
|
65
|
+
async connect(serverName, config) {
|
|
66
|
+
// Disconnect existing connection with this name first
|
|
67
|
+
if (this.connections.has(serverName)) {
|
|
68
|
+
await this.disconnect(serverName);
|
|
69
|
+
}
|
|
70
|
+
this.logger.info('[MCP] connecting', { serverName, transport: config.transport });
|
|
71
|
+
const transport = this.createTransport(config);
|
|
72
|
+
const client = new Client({ name: `cortex-${serverName}`, version: '1.0.0' }, { capabilities: {} });
|
|
73
|
+
try {
|
|
74
|
+
await client.connect(transport);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
this.logger.error('[MCP] connection failed', { serverName, error: err instanceof Error ? err.message : String(err) });
|
|
78
|
+
throw new Error(`MCP connection failed for "${serverName}": ${err instanceof Error ? err.message : String(err)}`);
|
|
79
|
+
}
|
|
80
|
+
// Track subprocess PID for stdio transports
|
|
81
|
+
let pid = null;
|
|
82
|
+
if (transport instanceof StdioClientTransport) {
|
|
83
|
+
pid = transport.pid;
|
|
84
|
+
if (pid != null) {
|
|
85
|
+
this.onSubprocessSpawned?.(pid);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Discover tools
|
|
89
|
+
let tools;
|
|
90
|
+
try {
|
|
91
|
+
tools = await this.discoverTools(serverName, client);
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
this.logger.error('[MCP] tool discovery failed', { serverName, error: err instanceof Error ? err.message : String(err) });
|
|
95
|
+
// Close the connection since tool discovery failed
|
|
96
|
+
try {
|
|
97
|
+
await client.close();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Best-effort cleanup
|
|
101
|
+
}
|
|
102
|
+
if (pid != null) {
|
|
103
|
+
this.onSubprocessExited?.(pid);
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`MCP tool discovery failed for "${serverName}": ${err instanceof Error ? err.message : String(err)}`);
|
|
106
|
+
}
|
|
107
|
+
const connection = {
|
|
108
|
+
serverName,
|
|
109
|
+
config,
|
|
110
|
+
client,
|
|
111
|
+
transport,
|
|
112
|
+
tools,
|
|
113
|
+
connected: true,
|
|
114
|
+
reconnectAttempts: 0,
|
|
115
|
+
pid,
|
|
116
|
+
};
|
|
117
|
+
// Wire close handler for reconnect on unexpected disconnect
|
|
118
|
+
transport.onclose = () => {
|
|
119
|
+
this.handleDisconnect(serverName);
|
|
120
|
+
};
|
|
121
|
+
this.connections.set(serverName, connection);
|
|
122
|
+
this.logger.info('[MCP] connected', { serverName, toolCount: tools.length, tools: tools.map(t => t.name) });
|
|
123
|
+
this.onToolsChanged?.();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Disconnect from a specific MCP server.
|
|
127
|
+
* Closes the transport and removes all tools from that server.
|
|
128
|
+
*
|
|
129
|
+
* @param serverName - The server name to disconnect
|
|
130
|
+
*/
|
|
131
|
+
async disconnect(serverName) {
|
|
132
|
+
const conn = this.connections.get(serverName);
|
|
133
|
+
if (!conn)
|
|
134
|
+
return;
|
|
135
|
+
this.logger.info('[MCP] disconnecting', { serverName });
|
|
136
|
+
conn.connected = false;
|
|
137
|
+
try {
|
|
138
|
+
await conn.client.close();
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
this.logger.warn('[MCP] error closing client', { serverName, error: err instanceof Error ? err.message : String(err) });
|
|
142
|
+
}
|
|
143
|
+
if (conn.pid != null) {
|
|
144
|
+
this.onSubprocessExited?.(conn.pid);
|
|
145
|
+
}
|
|
146
|
+
this.connections.delete(serverName);
|
|
147
|
+
this.onToolsChanged?.();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Close all MCP connections.
|
|
151
|
+
* Kills all stdio subprocesses and closes HTTP connections.
|
|
152
|
+
*/
|
|
153
|
+
async closeAll() {
|
|
154
|
+
const names = [...this.connections.keys()];
|
|
155
|
+
const results = await Promise.allSettled(names.map(name => this.disconnect(name)));
|
|
156
|
+
for (let i = 0; i < results.length; i++) {
|
|
157
|
+
const result = results[i];
|
|
158
|
+
if (result.status === 'rejected') {
|
|
159
|
+
this.logger.warn('[MCP] failed to disconnect', { serverName: names[i], error: String(result.reason) });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all AgentTool objects from all connected MCP servers.
|
|
165
|
+
* Returns tools namespaced as serverName__toolName.
|
|
166
|
+
*/
|
|
167
|
+
getTools() {
|
|
168
|
+
const allTools = [];
|
|
169
|
+
for (const conn of this.connections.values()) {
|
|
170
|
+
if (conn.connected) {
|
|
171
|
+
allTools.push(...conn.tools);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return allTools;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get tool names from a specific server.
|
|
178
|
+
*/
|
|
179
|
+
getServerToolNames(serverName) {
|
|
180
|
+
const conn = this.connections.get(serverName);
|
|
181
|
+
if (!conn || !conn.connected)
|
|
182
|
+
return [];
|
|
183
|
+
return conn.tools.map(t => t.name);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get the connection state for all servers.
|
|
187
|
+
*/
|
|
188
|
+
getConnectionStates() {
|
|
189
|
+
const states = [];
|
|
190
|
+
for (const conn of this.connections.values()) {
|
|
191
|
+
states.push({
|
|
192
|
+
serverName: conn.serverName,
|
|
193
|
+
config: conn.config,
|
|
194
|
+
connected: conn.connected,
|
|
195
|
+
reconnectAttempts: conn.reconnectAttempts,
|
|
196
|
+
toolNames: conn.tools.map(t => t.name),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return states;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check if a specific server is connected.
|
|
203
|
+
*/
|
|
204
|
+
isConnected(serverName) {
|
|
205
|
+
const conn = this.connections.get(serverName);
|
|
206
|
+
return conn?.connected ?? false;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get the number of active connections.
|
|
210
|
+
*/
|
|
211
|
+
get connectionCount() {
|
|
212
|
+
let count = 0;
|
|
213
|
+
for (const conn of this.connections.values()) {
|
|
214
|
+
if (conn.connected)
|
|
215
|
+
count++;
|
|
216
|
+
}
|
|
217
|
+
return count;
|
|
218
|
+
}
|
|
219
|
+
// -----------------------------------------------------------------------
|
|
220
|
+
// Private: Transport creation
|
|
221
|
+
// -----------------------------------------------------------------------
|
|
222
|
+
createTransport(config) {
|
|
223
|
+
if (config.transport === 'stdio') {
|
|
224
|
+
return this.createStdioTransport(config);
|
|
225
|
+
}
|
|
226
|
+
return this.createHttpTransport(config);
|
|
227
|
+
}
|
|
228
|
+
createStdioTransport(config) {
|
|
229
|
+
// Sanitize environment variables for the subprocess.
|
|
230
|
+
// Strip dangerous vars (LD_PRELOAD, NODE_OPTIONS, etc.) to prevent
|
|
231
|
+
// injection via environment. Uses the same blocklist as the Bash tool.
|
|
232
|
+
// envOverrides are merged ON TOP, bypassing the blocklist for
|
|
233
|
+
// consumer-specified variables (e.g., macOS dock icon suppression).
|
|
234
|
+
const baseEnv = config.env ?? process.env;
|
|
235
|
+
const safeEnv = buildSafeEnv(baseEnv, undefined, this.envOverrides);
|
|
236
|
+
// Build params object, only including defined optional fields to satisfy
|
|
237
|
+
// exactOptionalPropertyTypes
|
|
238
|
+
const params = {
|
|
239
|
+
command: config.command,
|
|
240
|
+
args: config.args ?? [],
|
|
241
|
+
env: safeEnv,
|
|
242
|
+
stderr: 'pipe',
|
|
243
|
+
};
|
|
244
|
+
if (config.cwd !== undefined)
|
|
245
|
+
params.cwd = config.cwd;
|
|
246
|
+
return new StdioClientTransport(params);
|
|
247
|
+
}
|
|
248
|
+
createHttpTransport(config) {
|
|
249
|
+
const url = new URL(config.url);
|
|
250
|
+
if (config.headers && Object.keys(config.headers).length > 0) {
|
|
251
|
+
return new StreamableHTTPClientTransport(url, {
|
|
252
|
+
requestInit: {
|
|
253
|
+
headers: config.headers,
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return new StreamableHTTPClientTransport(url);
|
|
258
|
+
}
|
|
259
|
+
// -----------------------------------------------------------------------
|
|
260
|
+
// Private: Tool discovery and wrapping
|
|
261
|
+
// -----------------------------------------------------------------------
|
|
262
|
+
/**
|
|
263
|
+
* Discover tools from a connected MCP server and wrap them as AgentTools.
|
|
264
|
+
*/
|
|
265
|
+
async discoverTools(serverName, client) {
|
|
266
|
+
const response = await client.listTools();
|
|
267
|
+
const tools = [];
|
|
268
|
+
for (const mcpTool of response.tools) {
|
|
269
|
+
tools.push(this.wrapMcpTool(serverName, {
|
|
270
|
+
name: mcpTool.name,
|
|
271
|
+
description: mcpTool.description,
|
|
272
|
+
inputSchema: mcpTool.inputSchema,
|
|
273
|
+
}, client));
|
|
274
|
+
}
|
|
275
|
+
return tools;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Wrap a single MCP tool definition as an AgentTool.
|
|
279
|
+
*
|
|
280
|
+
* Key details:
|
|
281
|
+
* - Name is prefixed with serverName__ for namespacing
|
|
282
|
+
* - JSON Schema from MCP is wrapped via Type.Unsafe() for TypeBox
|
|
283
|
+
* - execute() calls tools/call on the MCP connection using the original name
|
|
284
|
+
* - Errors are caught and returned as error results (not thrown)
|
|
285
|
+
*/
|
|
286
|
+
wrapMcpTool(serverName, mcpTool, client) {
|
|
287
|
+
const namespacedName = `${serverName}__${mcpTool.name}`;
|
|
288
|
+
// Wrap the MCP JSON Schema as a TypeBox type via Type.Unsafe()
|
|
289
|
+
const inputSchema = mcpTool.inputSchema ?? { type: 'object', properties: {} };
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
291
|
+
const parameters = Type.Unsafe(inputSchema);
|
|
292
|
+
return {
|
|
293
|
+
name: namespacedName,
|
|
294
|
+
description: mcpTool.description ?? '',
|
|
295
|
+
parameters,
|
|
296
|
+
// Marks this tool as MCP-sourced so CortexAgent's deferred-tool
|
|
297
|
+
// partitioning can identify it without rechecking by name prefix.
|
|
298
|
+
isMcp: true,
|
|
299
|
+
execute: async (args) => {
|
|
300
|
+
try {
|
|
301
|
+
const result = await client.callTool({
|
|
302
|
+
name: mcpTool.name, // Original name (no prefix)
|
|
303
|
+
arguments: (args ?? {}),
|
|
304
|
+
});
|
|
305
|
+
// Return text content from MCP result
|
|
306
|
+
if (result.isError) {
|
|
307
|
+
const errorText = Array.isArray(result.content)
|
|
308
|
+
? result.content
|
|
309
|
+
.filter((c) => typeof c === 'object' && c !== null && 'type' in c && c.type === 'text')
|
|
310
|
+
.map(c => c.text)
|
|
311
|
+
.join('\n')
|
|
312
|
+
: String(result.content);
|
|
313
|
+
throw new Error(errorText || 'MCP tool call failed');
|
|
314
|
+
}
|
|
315
|
+
const normalizedContent = [];
|
|
316
|
+
if (Array.isArray(result.content)) {
|
|
317
|
+
for (const item of result.content) {
|
|
318
|
+
if (!item || typeof item !== 'object') {
|
|
319
|
+
normalizedContent.push({ type: 'text', text: String(item) });
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const block = item;
|
|
323
|
+
const type = block['type'];
|
|
324
|
+
if (type === 'text' && typeof block['text'] === 'string') {
|
|
325
|
+
normalizedContent.push({ type: 'text', text: block['text'] });
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (type === 'image' &&
|
|
329
|
+
typeof block['data'] === 'string' &&
|
|
330
|
+
typeof block['mimeType'] === 'string') {
|
|
331
|
+
normalizedContent.push({
|
|
332
|
+
type: 'image',
|
|
333
|
+
data: block['data'],
|
|
334
|
+
mimeType: block['mimeType'],
|
|
335
|
+
});
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
normalizedContent.push({
|
|
339
|
+
type: 'text',
|
|
340
|
+
text: JSON.stringify(block, null, 2),
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (normalizedContent.length === 0) {
|
|
345
|
+
const structuredContent = result['structuredContent'];
|
|
346
|
+
if (structuredContent !== undefined) {
|
|
347
|
+
normalizedContent.push({
|
|
348
|
+
type: 'text',
|
|
349
|
+
text: JSON.stringify(structuredContent, null, 2),
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
normalizedContent.push({
|
|
354
|
+
type: 'text',
|
|
355
|
+
text: String(result.content ?? ''),
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
content: normalizedContent,
|
|
361
|
+
details: {
|
|
362
|
+
structuredContent: result['structuredContent'] ?? null,
|
|
363
|
+
rawContent: result.content ?? null,
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
// Re-throw as a standard error for pi-agent-core to handle
|
|
369
|
+
if (err instanceof Error)
|
|
370
|
+
throw err;
|
|
371
|
+
throw new Error(`MCP tool call "${mcpTool.name}" failed: ${String(err)}`);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
// -----------------------------------------------------------------------
|
|
377
|
+
// Private: Reconnect handling
|
|
378
|
+
// -----------------------------------------------------------------------
|
|
379
|
+
/**
|
|
380
|
+
* Handle unexpected disconnection from an MCP server.
|
|
381
|
+
* Attempts reconnection up to MAX_RECONNECT_ATTEMPTS times.
|
|
382
|
+
*/
|
|
383
|
+
handleDisconnect(serverName) {
|
|
384
|
+
const conn = this.connections.get(serverName);
|
|
385
|
+
if (!conn)
|
|
386
|
+
return;
|
|
387
|
+
// Already disconnected intentionally
|
|
388
|
+
if (!conn.connected)
|
|
389
|
+
return;
|
|
390
|
+
conn.connected = false;
|
|
391
|
+
conn.reconnectAttempts++;
|
|
392
|
+
if (conn.pid != null) {
|
|
393
|
+
this.onSubprocessExited?.(conn.pid);
|
|
394
|
+
conn.pid = null;
|
|
395
|
+
}
|
|
396
|
+
this.logger.warn('[MCP] unexpected disconnect', { serverName, attempt: conn.reconnectAttempts, maxAttempts: MAX_RECONNECT_ATTEMPTS });
|
|
397
|
+
if (conn.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
398
|
+
this.logger.error('[MCP] reconnect exhausted, deregistering', { serverName, maxAttempts: MAX_RECONNECT_ATTEMPTS });
|
|
399
|
+
this.connections.delete(serverName);
|
|
400
|
+
this.onToolsChanged?.();
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
// Attempt reconnect asynchronously
|
|
404
|
+
this.attemptReconnect(serverName, conn.config).catch((err) => {
|
|
405
|
+
this.logger.error('[MCP] reconnect attempt failed', { serverName, error: err instanceof Error ? err.message : String(err) });
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Attempt to reconnect to an MCP server.
|
|
410
|
+
*/
|
|
411
|
+
async attemptReconnect(serverName, config) {
|
|
412
|
+
// Brief delay before reconnect
|
|
413
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
414
|
+
const existing = this.connections.get(serverName);
|
|
415
|
+
if (!existing)
|
|
416
|
+
return; // Was deregistered during delay
|
|
417
|
+
let client = null;
|
|
418
|
+
let pid = null;
|
|
419
|
+
try {
|
|
420
|
+
// Attempt fresh connection
|
|
421
|
+
const transport = this.createTransport(config);
|
|
422
|
+
client = new Client({ name: `cortex-${serverName}`, version: '1.0.0' }, { capabilities: {} });
|
|
423
|
+
await client.connect(transport);
|
|
424
|
+
// Track subprocess PID
|
|
425
|
+
if (transport instanceof StdioClientTransport) {
|
|
426
|
+
pid = transport.pid;
|
|
427
|
+
if (pid != null) {
|
|
428
|
+
this.onSubprocessSpawned?.(pid);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Rediscover tools
|
|
432
|
+
const tools = await this.discoverTools(serverName, client);
|
|
433
|
+
// Wire close handler
|
|
434
|
+
transport.onclose = () => {
|
|
435
|
+
this.handleDisconnect(serverName);
|
|
436
|
+
};
|
|
437
|
+
// Update connection record
|
|
438
|
+
existing.client = client;
|
|
439
|
+
existing.transport = transport;
|
|
440
|
+
existing.tools = tools;
|
|
441
|
+
existing.connected = true;
|
|
442
|
+
existing.pid = pid;
|
|
443
|
+
// Keep reconnectAttempts as-is (reset only on fresh connect)
|
|
444
|
+
this.logger.info('[MCP] reconnected', { serverName, toolCount: tools.length });
|
|
445
|
+
this.onToolsChanged?.();
|
|
446
|
+
}
|
|
447
|
+
catch (err) {
|
|
448
|
+
// Clean up resources from partial connection
|
|
449
|
+
if (client) {
|
|
450
|
+
try {
|
|
451
|
+
await client.close();
|
|
452
|
+
}
|
|
453
|
+
catch { /* best-effort */ }
|
|
454
|
+
}
|
|
455
|
+
if (pid != null) {
|
|
456
|
+
this.onSubprocessExited?.(pid);
|
|
457
|
+
}
|
|
458
|
+
this.logger.warn('[MCP] reconnect failed', { serverName, error: err instanceof Error ? err.message : String(err) });
|
|
459
|
+
existing.reconnectAttempts++;
|
|
460
|
+
if (existing.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
461
|
+
this.logger.error('[MCP] max reconnect attempts exceeded, deregistering', { serverName });
|
|
462
|
+
this.connections.delete(serverName);
|
|
463
|
+
this.onToolsChanged?.();
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
// Schedule another attempt since transport.onclose may not fire
|
|
467
|
+
this.attemptReconnect(serverName, config).catch((retryErr) => {
|
|
468
|
+
this.logger.error('[MCP] subsequent reconnect failed', { serverName, error: retryErr instanceof Error ? retryErr.message : String(retryErr) });
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../src/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AA2B1D,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAEjC,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,OAAO,gBAAgB;IACnB,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEvD;;;OAGG;IACH,cAAc,CAAc;IAE5B;;;OAGG;IACH,mBAAmB,CAAyB;IAE5C;;OAEG;IACH,kBAAkB,CAAyB;IAE3C;;;;OAIG;IACH,YAAY,CAA0B;IAEtC,yEAAyE;IACzE,MAAM,GAAiB,WAAW,CAAC;IAEnC;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO,CAAC,UAAkB,EAAE,MAA0B;QAC1D,sDAAsD;QACtD,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAElF,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,UAAU,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAClD,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAsB,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtH,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpH,CAAC;QAED,4CAA4C;QAC5C,IAAI,GAAG,GAAkB,IAAI,CAAC;QAC9B,IAAI,SAAS,YAAY,oBAAoB,EAAE,CAAC;YAC9C,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;YACpB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,KAAkB,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1H,mDAAmD;YACnD,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;YACD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,UAAU,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxH,CAAC;QAED,MAAM,UAAU,GAAkB;YAChC,UAAU;YACV,MAAM;YACN,MAAM;YACN,SAAS;YACT,KAAK;YACL,SAAS,EAAE,IAAI;YACf,iBAAiB,EAAE,CAAC;YACpB,GAAG;SACJ,CAAC;QAEF,4DAA4D;QAC5D,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;YACvB,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5G,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU,CAAC,UAAkB;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QAEvB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1H,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CACzC,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAE,MAAgC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpI,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,QAAQ;QACN,MAAM,QAAQ,GAAgB,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,UAAkB;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,MAAM,MAAM,GAAyB,EAAE,CAAC;QACxC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC;gBACV,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;gBACzC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aACvC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,UAAkB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9C,OAAO,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,eAAe;QACjB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,SAAS;gBAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0EAA0E;IAC1E,8BAA8B;IAC9B,0EAA0E;IAElE,eAAe,CAAC,MAA0B;QAChD,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEO,oBAAoB,CAAC,MAAsB;QACjD,qDAAqD;QACrD,mEAAmE;QACnE,uEAAuE;QACvE,8DAA8D;QAC9D,oEAAoE;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAEpE,yEAAyE;QACzE,6BAA6B;QAC7B,MAAM,MAAM,GAMR;YACF,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;YACvB,GAAG,EAAE,OAAO;YACZ,MAAM,EAAE,MAAM;SACf,CAAC;QACF,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QAEtD,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEO,mBAAmB,CAAC,MAAqB;QAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,6BAA6B,CAAC,GAAG,EAAE;gBAC5C,WAAW,EAAE;oBACX,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,6BAA6B,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,0EAA0E;IAC1E,uCAAuC;IACvC,0EAA0E;IAE1E;;OAEG;IACK,KAAK,CAAC,aAAa,CAAC,UAAkB,EAAE,MAAc;QAC5D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAgB,EAAE,CAAC;QAE9B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CACzB,UAAU,EACV;gBACE,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,WAAW,EAAE,OAAO,CAAC,WAAkD;aACxE,EACD,MAAM,CACP,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACK,WAAW,CACjB,UAAkB,EAClB,OAA8G,EAC9G,MAAc;QAEd,MAAM,cAAc,GAAG,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;QAEtD,+DAA+D;QACjE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAC9E,8DAA8D;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,WAAkB,CAAC,CAAC;QAEnD,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;YACtC,UAAU;YACV,gEAAgE;YAChE,kEAAkE;YAClE,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,KAAK,EAAE,IAAa,EAAoB,EAAE;gBACjD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;wBACnC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAG,4BAA4B;wBACjD,SAAS,EAAE,CAAC,IAAI,IAAI,EAAE,CAA4B;qBACnD,CAAC,CAAC;oBAEH,sCAAsC;oBACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;4BAC7C,CAAC,CAAC,MAAM,CAAC,OAAO;iCACX,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CACjD,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iCACzE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iCAChB,IAAI,CAAC,IAAI,CAAC;4BACf,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBAC3B,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,sBAAsB,CAAC,CAAC;oBACvD,CAAC;oBAED,MAAM,iBAAiB,GAGnB,EAAE,CAAC;oBAEP,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;wBAClC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BAClC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gCACtC,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gCAC7D,SAAS;4BACX,CAAC;4BAED,MAAM,KAAK,GAAG,IAA+B,CAAC;4BAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;4BAE3B,IAAI,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;gCACzD,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gCAC9D,SAAS;4BACX,CAAC;4BAED,IAAI,IAAI,KAAK,OAAO;gCAChB,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;gCACjC,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,QAAQ,EAAE,CAAC;gCAC1C,iBAAiB,CAAC,IAAI,CAAC;oCACrB,IAAI,EAAE,OAAO;oCACb,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;oCACnB,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC;iCAC5B,CAAC,CAAC;gCACH,SAAS;4BACX,CAAC;4BAED,iBAAiB,CAAC,IAAI,CAAC;gCACrB,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;6BACrC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAED,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACnC,MAAM,iBAAiB,GAAI,MAAkC,CAAC,mBAAmB,CAAC,CAAC;wBACnF,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;4BACpC,iBAAiB,CAAC,IAAI,CAAC;gCACrB,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;6BACjD,CAAC,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACN,iBAAiB,CAAC,IAAI,CAAC;gCACrB,IAAI,EAAE,MAAM;gCACZ,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;6BACnC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAED,OAAO;wBACL,OAAO,EAAE,iBAAiB;wBAC1B,OAAO,EAAE;4BACP,iBAAiB,EAAG,MAAkC,CAAC,mBAAmB,CAAC,IAAI,IAAI;4BACnF,UAAU,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;yBACnC;qBACF,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,2DAA2D;oBAC3D,IAAI,GAAG,YAAY,KAAK;wBAAE,MAAM,GAAG,CAAC;oBACpC,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,CAAC,IAAI,aAAa,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,8BAA8B;IAC9B,0EAA0E;IAE1E;;;OAGG;IACK,gBAAgB,CAAC,UAAkB;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,qCAAqC;QACrC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE5B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC,CAAC;QAEtI,IAAI,IAAI,CAAC,iBAAiB,IAAI,sBAAsB,EAAE,CAAC;YACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC,CAAC;YACnH,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACpC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/H,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,MAA0B;QAC3E,+BAA+B;QAC/B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,gCAAgC;QAEvD,IAAI,MAAM,GAAkB,IAAI,CAAC;QACjC,IAAI,GAAG,GAAkB,IAAI,CAAC;QAE9B,IAAI,CAAC;YACH,2BAA2B;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,GAAG,IAAI,MAAM,CACjB,EAAE,IAAI,EAAE,UAAU,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAClD,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;YAEF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAsB,CAAC,CAAC;YAE7C,uBAAuB;YACvB,IAAI,SAAS,YAAY,oBAAoB,EAAE,CAAC;gBAC9C,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;gBACpB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;oBAChB,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YAED,mBAAmB;YACnB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAE3D,qBAAqB;YACrB,SAAS,CAAC,OAAO,GAAG,GAAG,EAAE;gBACvB,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YACpC,CAAC,CAAC;YAEF,2BAA2B;YAC3B,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;YACzB,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC;YAC/B,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;YACvB,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;YAC1B,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC;YACnB,6DAA6D;YAE7D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/E,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,6CAA6C;YAC7C,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC;oBAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;YAC3D,CAAC;YACD,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpH,QAAQ,CAAC,iBAAiB,EAAE,CAAC;YAC7B,IAAI,QAAQ,CAAC,iBAAiB,IAAI,sBAAsB,EAAE,CAAC;gBACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC1F,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBACpC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,gEAAgE;gBAChE,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,EAAE;oBAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACjJ,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CortexModel: branded opaque type for type-safe model passing.
|
|
3
|
+
*
|
|
4
|
+
* Wraps pi-ai's Model<any> with a branded type to prevent consumers
|
|
5
|
+
* from accidentally passing raw pi-ai models where cortex models
|
|
6
|
+
* are expected (and vice versa).
|
|
7
|
+
*
|
|
8
|
+
* The consumer can read provider, modelId, and contextWindow for
|
|
9
|
+
* display and configuration. The underlying pi-ai Model object is
|
|
10
|
+
* accessed internally by CortexAgent when constructing the
|
|
11
|
+
* pi-agent-core Agent.
|
|
12
|
+
*
|
|
13
|
+
* Reference: provider-manager.md
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Opaque model handle. The consumer receives this from ProviderManager
|
|
17
|
+
* and passes it to CortexAgent. The consumer never inspects its internals
|
|
18
|
+
* beyond the declared fields.
|
|
19
|
+
*
|
|
20
|
+
* Internally, this wraps pi-ai's Model<T> type.
|
|
21
|
+
*/
|
|
22
|
+
export interface CortexModel {
|
|
23
|
+
/** @internal Brand tag for nominal type safety. */
|
|
24
|
+
readonly __brand: 'CortexModel';
|
|
25
|
+
/** Provider identifier (e.g., 'anthropic', 'openai', 'google'). */
|
|
26
|
+
readonly provider: string;
|
|
27
|
+
/** Model identifier (e.g., 'claude-sonnet-4-20250514'). */
|
|
28
|
+
readonly modelId: string;
|
|
29
|
+
/** Context window size in tokens. */
|
|
30
|
+
readonly contextWindow: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Wrap a pi-ai Model object into a CortexModel.
|
|
34
|
+
*
|
|
35
|
+
* @param model - The pi-ai Model object to wrap
|
|
36
|
+
* @param provider - The provider identifier
|
|
37
|
+
* @param modelId - The model identifier
|
|
38
|
+
* @param contextWindow - The context window size (default: 200000)
|
|
39
|
+
* @returns An opaque CortexModel handle
|
|
40
|
+
*/
|
|
41
|
+
export declare function wrapModel(model: unknown, provider: string, modelId: string, contextWindow?: number): CortexModel;
|
|
42
|
+
/**
|
|
43
|
+
* Unwrap a CortexModel to retrieve the underlying pi-ai Model object.
|
|
44
|
+
*
|
|
45
|
+
* @param cortexModel - The CortexModel to unwrap
|
|
46
|
+
* @returns The underlying pi-ai Model object
|
|
47
|
+
* @throws Error if the object is not a valid CortexModel
|
|
48
|
+
*/
|
|
49
|
+
export declare function unwrapModel(cortexModel: CortexModel): unknown;
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a value is a valid CortexModel (has the correct brand
|
|
52
|
+
* and contains a wrapped inner model).
|
|
53
|
+
*
|
|
54
|
+
* @param value - The value to check
|
|
55
|
+
* @returns True if the value is a valid CortexModel
|
|
56
|
+
*/
|
|
57
|
+
export declare function isCortexModel(value: unknown): value is CortexModel;
|
|
58
|
+
//# sourceMappingURL=model-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-wrapper.d.ts","sourceRoot":"","sources":["../src/model-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,WAAW,CASb;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAK7D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAUlE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CortexModel: branded opaque type for type-safe model passing.
|
|
3
|
+
*
|
|
4
|
+
* Wraps pi-ai's Model<any> with a branded type to prevent consumers
|
|
5
|
+
* from accidentally passing raw pi-ai models where cortex models
|
|
6
|
+
* are expected (and vice versa).
|
|
7
|
+
*
|
|
8
|
+
* The consumer can read provider, modelId, and contextWindow for
|
|
9
|
+
* display and configuration. The underlying pi-ai Model object is
|
|
10
|
+
* accessed internally by CortexAgent when constructing the
|
|
11
|
+
* pi-agent-core Agent.
|
|
12
|
+
*
|
|
13
|
+
* Reference: provider-manager.md
|
|
14
|
+
*/
|
|
15
|
+
// The symbol key used to store the underlying pi-ai model.
|
|
16
|
+
const INNER_MODEL = Symbol.for('cortex.innerModel');
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Public API
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/**
|
|
21
|
+
* Wrap a pi-ai Model object into a CortexModel.
|
|
22
|
+
*
|
|
23
|
+
* @param model - The pi-ai Model object to wrap
|
|
24
|
+
* @param provider - The provider identifier
|
|
25
|
+
* @param modelId - The model identifier
|
|
26
|
+
* @param contextWindow - The context window size (default: 200000)
|
|
27
|
+
* @returns An opaque CortexModel handle
|
|
28
|
+
*/
|
|
29
|
+
export function wrapModel(model, provider, modelId, contextWindow) {
|
|
30
|
+
const wrapped = {
|
|
31
|
+
__brand: 'CortexModel',
|
|
32
|
+
provider,
|
|
33
|
+
modelId,
|
|
34
|
+
contextWindow: contextWindow ?? extractContextWindow(model) ?? 200_000,
|
|
35
|
+
[INNER_MODEL]: model,
|
|
36
|
+
};
|
|
37
|
+
return wrapped;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Unwrap a CortexModel to retrieve the underlying pi-ai Model object.
|
|
41
|
+
*
|
|
42
|
+
* @param cortexModel - The CortexModel to unwrap
|
|
43
|
+
* @returns The underlying pi-ai Model object
|
|
44
|
+
* @throws Error if the object is not a valid CortexModel
|
|
45
|
+
*/
|
|
46
|
+
export function unwrapModel(cortexModel) {
|
|
47
|
+
if (!isCortexModel(cortexModel)) {
|
|
48
|
+
throw new Error('Expected a CortexModel created by wrapModel()');
|
|
49
|
+
}
|
|
50
|
+
return cortexModel[INNER_MODEL];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check whether a value is a valid CortexModel (has the correct brand
|
|
54
|
+
* and contains a wrapped inner model).
|
|
55
|
+
*
|
|
56
|
+
* @param value - The value to check
|
|
57
|
+
* @returns True if the value is a valid CortexModel
|
|
58
|
+
*/
|
|
59
|
+
export function isCortexModel(value) {
|
|
60
|
+
if (!value || typeof value !== 'object')
|
|
61
|
+
return false;
|
|
62
|
+
const obj = value;
|
|
63
|
+
return (obj['__brand'] === 'CortexModel' &&
|
|
64
|
+
typeof obj['provider'] === 'string' &&
|
|
65
|
+
typeof obj['modelId'] === 'string' &&
|
|
66
|
+
typeof obj['contextWindow'] === 'number' &&
|
|
67
|
+
INNER_MODEL in obj);
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Internal helpers
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
/**
|
|
73
|
+
* Attempt to extract the context window size from a pi-ai Model object.
|
|
74
|
+
* Pi-ai models expose contextWindow as a property.
|
|
75
|
+
*/
|
|
76
|
+
function extractContextWindow(model) {
|
|
77
|
+
if (model && typeof model === 'object') {
|
|
78
|
+
const obj = model;
|
|
79
|
+
const cw = obj['contextWindow'];
|
|
80
|
+
if (typeof cw === 'number') {
|
|
81
|
+
return cw;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=model-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-wrapper.js","sourceRoot":"","sources":["../src/model-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAwBH,2DAA2D;AAC3D,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAUpD,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,KAAc,EACd,QAAgB,EAChB,OAAe,EACf,aAAsB;IAEtB,MAAM,OAAO,GAAiB;QAC5B,OAAO,EAAE,aAAsB;QAC/B,QAAQ;QACR,OAAO;QACP,aAAa,EAAE,aAAa,IAAI,oBAAoB,CAAC,KAAK,CAAC,IAAI,OAAO;QACtE,CAAC,WAAW,CAAC,EAAE,KAAK;KACrB,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,WAAwB;IAClD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAQ,WAA4B,CAAC,WAAW,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,KAAyC,CAAC;IACtD,OAAO,CACL,GAAG,CAAC,SAAS,CAAC,KAAK,aAAa;QAChC,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,QAAQ;QACnC,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ;QAClC,OAAO,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ;QACxC,WAAW,IAAI,GAAG,CACnB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;QAChC,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop-logger.d.ts","sourceRoot":"","sources":["../src/noop-logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,8DAA8D;AAC9D,eAAO,MAAM,WAAW,EAAE,YAKzB,CAAC"}
|