@sammorrowdrums/mcpi-ext 0.2.1 → 1.0.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 +137 -47
- package/dist/code-mode/eligibility.d.ts +29 -4
- package/dist/code-mode/eligibility.js +56 -6
- package/dist/code-mode/executor.d.ts +19 -1
- package/dist/code-mode/executor.js +73 -8
- package/dist/code-mode/index.d.ts +54 -12
- package/dist/code-mode/index.js +157 -65
- package/dist/code-mode/isolated-vm.d.ts +65 -0
- package/dist/code-mode/isolated-vm.js +116 -0
- package/dist/code-mode/tools.d.ts +4 -1
- package/dist/code-mode/tools.js +7 -4
- package/dist/code-mode/type-hints.d.ts +2 -2
- package/dist/code-mode/type-hints.js +24 -8
- package/dist/docker-e2e.d.ts +0 -1
- package/dist/docker-e2e.js +0 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +146 -67
- package/dist/mcp/call-tool-result.d.ts +10 -0
- package/dist/mcp/call-tool-result.js +70 -0
- package/dist/mcp/client-factory.d.ts +59 -0
- package/dist/mcp/client-factory.js +76 -0
- package/dist/mcp/client-manager.d.ts +61 -19
- package/dist/mcp/client-manager.js +223 -64
- package/dist/mcp/config-loader.d.ts +0 -1
- package/dist/mcp/config-loader.js +0 -1
- package/dist/mcp/config.d.ts +11 -1
- package/dist/mcp/config.js +15 -1
- package/dist/mcp/gateway-defaults.d.ts +14 -0
- package/dist/mcp/gateway-defaults.js +21 -0
- package/dist/mcp/host-approval.d.ts +16 -0
- package/dist/mcp/host-approval.js +19 -0
- package/dist/mcp/host-elicitation.d.ts +19 -0
- package/dist/mcp/host-elicitation.js +94 -0
- package/dist/mcp/index.d.ts +4 -1
- package/dist/mcp/index.js +4 -1
- package/dist/mcp/policy.d.ts +314 -0
- package/dist/mcp/policy.js +848 -0
- package/dist/routing/facilities.d.ts +109 -0
- package/dist/routing/facilities.js +175 -0
- package/dist/routing/format.d.ts +24 -0
- package/dist/routing/format.js +64 -0
- package/dist/routing/index.d.ts +4 -0
- package/dist/routing/index.js +4 -0
- package/dist/routing/seam.d.ts +35 -0
- package/dist/routing/seam.js +28 -0
- package/dist/routing/tripwire.d.ts +42 -0
- package/dist/routing/tripwire.js +80 -0
- package/dist/skills/discover.d.ts +5 -3
- package/dist/skills/discover.js +37 -12
- package/dist/skills/format.d.ts +4 -1
- package/dist/skills/format.js +8 -4
- package/dist/skills/index.d.ts +2 -2
- package/dist/skills/index.js +1 -1
- package/dist/skills/load-skill-tool.d.ts +23 -7
- package/dist/skills/load-skill-tool.js +112 -33
- package/dist/skills/mcp-tool-proxy.d.ts +4 -8
- package/dist/skills/mcp-tool-proxy.js +22 -97
- package/dist/skills/sep2640/client.d.ts +91 -0
- package/dist/skills/sep2640/client.js +160 -0
- package/dist/skills/sep2640/discover.d.ts +33 -0
- package/dist/skills/sep2640/discover.js +82 -0
- package/dist/skills/sep2640/index.d.ts +13 -0
- package/dist/skills/sep2640/index.js +13 -0
- package/dist/skills/sep2640/integrity.d.ts +58 -0
- package/dist/skills/sep2640/integrity.js +185 -0
- package/dist/skills/sep2640/load.d.ts +61 -0
- package/dist/skills/sep2640/load.js +90 -0
- package/dist/skills/sep2640/protocol.d.ts +146 -0
- package/dist/skills/sep2640/protocol.js +214 -0
- package/dist/skills/sep2640/spec.d.ts +76 -0
- package/dist/skills/sep2640/spec.js +88 -0
- package/dist/skills/skill-registry.d.ts +48 -2
- package/dist/skills/skill-registry.js +40 -3
- package/dist/tool-cli/bridge.d.ts +14 -0
- package/dist/tool-cli/bridge.js +196 -0
- package/dist/tool-cli/format.d.ts +17 -5
- package/dist/tool-cli/format.js +36 -20
- package/dist/tool-cli/index.d.ts +5 -2
- package/dist/tool-cli/index.js +3 -1
- package/dist/tool-cli/provider.d.ts +21 -0
- package/dist/tool-cli/provider.js +114 -0
- package/dist/tool-cli/startup.d.ts +22 -0
- package/dist/tool-cli/startup.js +47 -0
- package/package.json +78 -30
- package/dist/code-mode/code-mode-integration.test.d.ts +0 -2
- package/dist/code-mode/code-mode-integration.test.d.ts.map +0 -1
- package/dist/code-mode/code-mode-integration.test.js +0 -116
- package/dist/code-mode/code-mode-integration.test.js.map +0 -1
- package/dist/code-mode/eligibility.d.ts.map +0 -1
- package/dist/code-mode/eligibility.js.map +0 -1
- package/dist/code-mode/eligibility.test.d.ts +0 -2
- package/dist/code-mode/eligibility.test.d.ts.map +0 -1
- package/dist/code-mode/eligibility.test.js +0 -53
- package/dist/code-mode/eligibility.test.js.map +0 -1
- package/dist/code-mode/executor.d.ts.map +0 -1
- package/dist/code-mode/executor.js.map +0 -1
- package/dist/code-mode/executor.test.d.ts +0 -2
- package/dist/code-mode/executor.test.d.ts.map +0 -1
- package/dist/code-mode/executor.test.js +0 -130
- package/dist/code-mode/executor.test.js.map +0 -1
- package/dist/code-mode/index.d.ts.map +0 -1
- package/dist/code-mode/index.js.map +0 -1
- package/dist/code-mode/tools.d.ts.map +0 -1
- package/dist/code-mode/tools.js.map +0 -1
- package/dist/code-mode/type-hints.d.ts.map +0 -1
- package/dist/code-mode/type-hints.js.map +0 -1
- package/dist/code-mode/type-hints.test.d.ts +0 -2
- package/dist/code-mode/type-hints.test.d.ts.map +0 -1
- package/dist/code-mode/type-hints.test.js +0 -157
- package/dist/code-mode/type-hints.test.js.map +0 -1
- package/dist/docker-e2e.d.ts.map +0 -1
- package/dist/docker-e2e.js.map +0 -1
- package/dist/docker-e2e.test.d.ts +0 -2
- package/dist/docker-e2e.test.d.ts.map +0 -1
- package/dist/docker-e2e.test.js +0 -176
- package/dist/docker-e2e.test.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -8
- package/dist/index.test.js.map +0 -1
- package/dist/mcp/client-manager.d.ts.map +0 -1
- package/dist/mcp/client-manager.js.map +0 -1
- package/dist/mcp/client-manager.test.d.ts +0 -2
- package/dist/mcp/client-manager.test.d.ts.map +0 -1
- package/dist/mcp/client-manager.test.js +0 -204
- package/dist/mcp/client-manager.test.js.map +0 -1
- package/dist/mcp/config-loader.d.ts.map +0 -1
- package/dist/mcp/config-loader.js.map +0 -1
- package/dist/mcp/config-loader.test.d.ts +0 -2
- package/dist/mcp/config-loader.test.d.ts.map +0 -1
- package/dist/mcp/config-loader.test.js +0 -93
- package/dist/mcp/config-loader.test.js.map +0 -1
- package/dist/mcp/config.d.ts.map +0 -1
- package/dist/mcp/config.js.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/skills/discover.d.ts.map +0 -1
- package/dist/skills/discover.js.map +0 -1
- package/dist/skills/format.d.ts.map +0 -1
- package/dist/skills/format.js.map +0 -1
- package/dist/skills/format.test.d.ts +0 -2
- package/dist/skills/format.test.d.ts.map +0 -1
- package/dist/skills/format.test.js +0 -63
- package/dist/skills/format.test.js.map +0 -1
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/load-skill-tool.d.ts.map +0 -1
- package/dist/skills/load-skill-tool.js.map +0 -1
- package/dist/skills/mcp-tool-proxy.d.ts.map +0 -1
- package/dist/skills/mcp-tool-proxy.js.map +0 -1
- package/dist/skills/skill-integration.test.d.ts +0 -2
- package/dist/skills/skill-integration.test.d.ts.map +0 -1
- package/dist/skills/skill-integration.test.js +0 -119
- package/dist/skills/skill-integration.test.js.map +0 -1
- package/dist/skills/skill-registry.d.ts.map +0 -1
- package/dist/skills/skill-registry.js.map +0 -1
- package/dist/skills/skill-registry.test.d.ts +0 -2
- package/dist/skills/skill-registry.test.d.ts.map +0 -1
- package/dist/skills/skill-registry.test.js +0 -67
- package/dist/skills/skill-registry.test.js.map +0 -1
- package/dist/test-servers/weather-server.d.ts +0 -12
- package/dist/test-servers/weather-server.d.ts.map +0 -1
- package/dist/test-servers/weather-server.js +0 -139
- package/dist/test-servers/weather-server.js.map +0 -1
- package/dist/test-servers/weather-stdio.d.ts +0 -2
- package/dist/test-servers/weather-stdio.d.ts.map +0 -1
- package/dist/test-servers/weather-stdio.js +0 -11
- package/dist/test-servers/weather-stdio.js.map +0 -1
- package/dist/tool-cli/cli.d.ts +0 -3
- package/dist/tool-cli/cli.d.ts.map +0 -1
- package/dist/tool-cli/cli.js +0 -179
- package/dist/tool-cli/cli.js.map +0 -1
- package/dist/tool-cli/constants.d.ts +0 -7
- package/dist/tool-cli/constants.d.ts.map +0 -1
- package/dist/tool-cli/constants.js +0 -15
- package/dist/tool-cli/constants.js.map +0 -1
- package/dist/tool-cli/format.d.ts.map +0 -1
- package/dist/tool-cli/format.js.map +0 -1
- package/dist/tool-cli/format.test.d.ts +0 -2
- package/dist/tool-cli/format.test.d.ts.map +0 -1
- package/dist/tool-cli/format.test.js +0 -30
- package/dist/tool-cli/format.test.js.map +0 -1
- package/dist/tool-cli/index.d.ts.map +0 -1
- package/dist/tool-cli/index.js.map +0 -1
- package/dist/tool-cli/rpc-client.d.ts +0 -6
- package/dist/tool-cli/rpc-client.d.ts.map +0 -1
- package/dist/tool-cli/rpc-client.js +0 -25
- package/dist/tool-cli/rpc-client.js.map +0 -1
- package/dist/tool-cli/rpc-server.d.ts +0 -48
- package/dist/tool-cli/rpc-server.d.ts.map +0 -1
- package/dist/tool-cli/rpc-server.js +0 -220
- package/dist/tool-cli/rpc-server.js.map +0 -1
- package/dist/tool-cli/rpc-server.test.d.ts +0 -2
- package/dist/tool-cli/rpc-server.test.d.ts.map +0 -1
- package/dist/tool-cli/rpc-server.test.js +0 -154
- package/dist/tool-cli/rpc-server.test.js.map +0 -1
|
@@ -1,34 +1,77 @@
|
|
|
1
1
|
import type { McpClientManager, McpTool } from "../mcp/index.js";
|
|
2
|
+
import { type McpPolicy } from "../mcp/policy.js";
|
|
3
|
+
import { type CodeModeDiagnostics, type CodeModeTool } from "./eligibility.js";
|
|
2
4
|
import type { ExecuteResult, ExecutorOptions } from "./executor.js";
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
export {
|
|
5
|
+
import { executeInSandbox } from "./executor.js";
|
|
6
|
+
export { SYNTHESIZED_OUTPUT_SCHEMA, getCodeModeDiagnostics, getCodeModeTools, getEligibleTools, isEligibleForCodeMode, toCodeModeTool, } from "./eligibility.js";
|
|
7
|
+
export type { CodeModeDiagnostics, CodeModeRefusalReason, CodeModeTool, OutputSchemaProvenance, } from "./eligibility.js";
|
|
8
|
+
export type { CodeModeErrorDetails, ExecuteResult, ExecutorOptions } from "./executor.js";
|
|
9
|
+
export { SANDBOX_UNAVAILABLE_ERROR, executeInSandbox, normalizeCode } from "./executor.js";
|
|
10
|
+
export { loadIsolatedVm, peekIsolatedVm, resetIsolatedVmCacheForTests, setIsolatedVmForTests, type IsolatedVmLoad, type IsolatedVmModule, } from "./isolated-vm.js";
|
|
6
11
|
export { createCodeExecuteTool, createCodeSearchTool } from "./tools.js";
|
|
7
12
|
export { generateTypeHints, jsonSchemaToTypeString, sanitizeToolName } from "./type-hints.js";
|
|
8
13
|
export interface CodeModeManagerOptions extends ExecutorOptions {
|
|
9
14
|
/** Log function for status messages. */
|
|
10
15
|
log?: (msg: string) => void;
|
|
16
|
+
/** Test seam for proving pre-isolate refusals. */
|
|
17
|
+
sandboxExecutor?: typeof executeInSandbox;
|
|
11
18
|
}
|
|
12
19
|
/**
|
|
13
|
-
*
|
|
20
|
+
* Whether the sandbox backend can run code.
|
|
21
|
+
*
|
|
22
|
+
* `unknown` is a real state, not a synonym for unavailable: before the optional
|
|
23
|
+
* native addon has been probed we have not established anything, and reporting
|
|
24
|
+
* that honestly is better than guessing in either direction.
|
|
25
|
+
*/
|
|
26
|
+
export interface SandboxAvailability {
|
|
27
|
+
readonly state: "available" | "unavailable" | "unknown";
|
|
28
|
+
readonly reason: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Orchestrates code mode: catalogs tools, generates type hints,
|
|
14
32
|
* and executes model-generated code in a sandbox with tool dispatch.
|
|
15
33
|
*/
|
|
16
34
|
export declare class CodeModeManager {
|
|
17
35
|
private mcpManager;
|
|
18
|
-
private
|
|
36
|
+
private policy;
|
|
37
|
+
private codeModeTools;
|
|
38
|
+
private diagnostics;
|
|
19
39
|
private typeHints;
|
|
20
|
-
private options;
|
|
40
|
+
private readonly options;
|
|
41
|
+
private readonly sandboxExecutor;
|
|
42
|
+
private log;
|
|
43
|
+
private lastDiagnosticSummary;
|
|
44
|
+
private sandbox;
|
|
45
|
+
private sandboxProbe;
|
|
21
46
|
constructor(options?: CodeModeManagerOptions);
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Whether code mode should be advertised to the model.
|
|
49
|
+
*
|
|
50
|
+
* Only a *proven* unavailable sandbox switches this off. An unprobed backend
|
|
51
|
+
* stays active because `code_execute` is registered synchronously at load and
|
|
52
|
+
* returns a structured `sandbox_unavailable` error if it turns out it cannot
|
|
53
|
+
* run — a truthful refusal at call time beats hiding a facility that works.
|
|
54
|
+
*/
|
|
55
|
+
get isActive(): boolean;
|
|
56
|
+
/** Current sandbox backend availability, without triggering a probe. */
|
|
57
|
+
getSandboxAvailability(): SandboxAvailability;
|
|
58
|
+
/**
|
|
59
|
+
* Load the optional native addon once and cache the verdict.
|
|
60
|
+
*
|
|
61
|
+
* Safe to call from any lifecycle hook; concurrent callers share one probe.
|
|
62
|
+
*/
|
|
63
|
+
probeSandbox(): Promise<SandboxAvailability>;
|
|
64
|
+
/** Initialize with MCP manager and policy, catalog tools, and generate type hints. */
|
|
65
|
+
initialize(mcpManager: McpClientManager, policy: McpPolicy, log?: (msg: string) => void): void;
|
|
66
|
+
/** Refresh the complete tool catalog and type hints (call on tools/list_changed). */
|
|
25
67
|
refresh(): void;
|
|
26
68
|
/** Get the type hints string for injection into system prompt. */
|
|
27
69
|
getTypeHints(): string;
|
|
28
70
|
/** Get eligible tools. */
|
|
29
71
|
getEligibleTools(): McpTool[];
|
|
30
|
-
/**
|
|
31
|
-
|
|
72
|
+
/** Get the complete client-internal catalog, including permission and schema provenance. */
|
|
73
|
+
getCatalogTools(): readonly CodeModeTool[];
|
|
74
|
+
getDiagnostics(): CodeModeDiagnostics;
|
|
32
75
|
/** Execute code in search mode (tool catalog queries). */
|
|
33
76
|
searchTools(code: string): Promise<ExecuteResult>;
|
|
34
77
|
/** Execute code that chains MCP tool calls. */
|
|
@@ -62,4 +105,3 @@ export declare class CodeModeManager {
|
|
|
62
105
|
formatSystemPromptSection(): string;
|
|
63
106
|
private execute;
|
|
64
107
|
}
|
|
65
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/code-mode/index.js
CHANGED
|
@@ -1,35 +1,111 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { McpPolicyError } from "../mcp/policy.js";
|
|
2
|
+
import { getCodeModeDiagnostics, getCodeModeTools, } from "./eligibility.js";
|
|
3
|
+
import { CodeModeDispatchError, executeInSandbox } from "./executor.js";
|
|
4
|
+
import { loadIsolatedVm } from "./isolated-vm.js";
|
|
3
5
|
import { createCodeExecuteTool, createCodeSearchTool } from "./tools.js";
|
|
4
6
|
import { generateTypeHints } from "./type-hints.js";
|
|
5
|
-
export { getEligibleTools, isEligibleForCodeMode } from "./eligibility.js";
|
|
6
|
-
export { executeInSandbox, normalizeCode } from "./executor.js";
|
|
7
|
+
export { SYNTHESIZED_OUTPUT_SCHEMA, getCodeModeDiagnostics, getCodeModeTools, getEligibleTools, isEligibleForCodeMode, toCodeModeTool, } from "./eligibility.js";
|
|
8
|
+
export { SANDBOX_UNAVAILABLE_ERROR, executeInSandbox, normalizeCode } from "./executor.js";
|
|
9
|
+
export { loadIsolatedVm, peekIsolatedVm, resetIsolatedVmCacheForTests, setIsolatedVmForTests, } from "./isolated-vm.js";
|
|
7
10
|
export { createCodeExecuteTool, createCodeSearchTool } from "./tools.js";
|
|
8
11
|
export { generateTypeHints, jsonSchemaToTypeString, sanitizeToolName } from "./type-hints.js";
|
|
12
|
+
const NO_ELIGIBLE_TOOLS_ERROR = {
|
|
13
|
+
error: "no_eligible_tools",
|
|
14
|
+
message: "code_search has no callable read-only MCP tools to search.",
|
|
15
|
+
alternatives: ["code_execute", "tool-cli"],
|
|
16
|
+
};
|
|
17
|
+
const SANDBOX_UNPROBED = {
|
|
18
|
+
state: "unknown",
|
|
19
|
+
reason: "the isolated-vm native addon has not been probed yet",
|
|
20
|
+
};
|
|
21
|
+
const SANDBOX_INJECTED = {
|
|
22
|
+
state: "available",
|
|
23
|
+
reason: "a sandbox executor was supplied directly, bypassing the isolated-vm addon",
|
|
24
|
+
};
|
|
25
|
+
const SANDBOX_NATIVE = {
|
|
26
|
+
state: "available",
|
|
27
|
+
reason: "the isolated-vm native addon loaded",
|
|
28
|
+
};
|
|
9
29
|
/**
|
|
10
|
-
* Orchestrates code mode:
|
|
30
|
+
* Orchestrates code mode: catalogs tools, generates type hints,
|
|
11
31
|
* and executes model-generated code in a sandbox with tool dispatch.
|
|
12
32
|
*/
|
|
13
33
|
export class CodeModeManager {
|
|
14
34
|
mcpManager = null;
|
|
15
|
-
|
|
16
|
-
|
|
35
|
+
policy = null;
|
|
36
|
+
codeModeTools = [];
|
|
37
|
+
diagnostics = getCodeModeDiagnostics([]);
|
|
38
|
+
typeHints = generateTypeHints([]);
|
|
17
39
|
options;
|
|
40
|
+
sandboxExecutor;
|
|
41
|
+
log;
|
|
42
|
+
lastDiagnosticSummary = "";
|
|
43
|
+
sandbox;
|
|
44
|
+
sandboxProbe;
|
|
18
45
|
constructor(options = {}) {
|
|
19
46
|
this.options = options;
|
|
47
|
+
this.sandboxExecutor = options.sandboxExecutor ?? executeInSandbox;
|
|
48
|
+
this.log = options.log;
|
|
49
|
+
// An injected executor is the sandbox. Probing the native addon in that
|
|
50
|
+
// case would report on a backend this manager will never call.
|
|
51
|
+
this.sandbox = options.sandboxExecutor ? SANDBOX_INJECTED : SANDBOX_UNPROBED;
|
|
20
52
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Whether code mode should be advertised to the model.
|
|
55
|
+
*
|
|
56
|
+
* Only a *proven* unavailable sandbox switches this off. An unprobed backend
|
|
57
|
+
* stays active because `code_execute` is registered synchronously at load and
|
|
58
|
+
* returns a structured `sandbox_unavailable` error if it turns out it cannot
|
|
59
|
+
* run — a truthful refusal at call time beats hiding a facility that works.
|
|
60
|
+
*/
|
|
61
|
+
get isActive() {
|
|
62
|
+
return this.sandbox.state !== "unavailable";
|
|
63
|
+
}
|
|
64
|
+
/** Current sandbox backend availability, without triggering a probe. */
|
|
65
|
+
getSandboxAvailability() {
|
|
66
|
+
return this.sandbox;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Load the optional native addon once and cache the verdict.
|
|
70
|
+
*
|
|
71
|
+
* Safe to call from any lifecycle hook; concurrent callers share one probe.
|
|
72
|
+
*/
|
|
73
|
+
async probeSandbox() {
|
|
74
|
+
if (this.sandbox.state !== "unknown")
|
|
75
|
+
return this.sandbox;
|
|
76
|
+
this.sandboxProbe ??= loadIsolatedVm().then((load) => {
|
|
77
|
+
this.sandbox = load.available
|
|
78
|
+
? SANDBOX_NATIVE
|
|
79
|
+
: { state: "unavailable", reason: load.reason };
|
|
80
|
+
if (!load.available) {
|
|
81
|
+
this.log?.(`[code-mode] disabled: ${load.reason}. Skills, tool-cli, and routing are unaffected.`);
|
|
82
|
+
}
|
|
83
|
+
return this.sandbox;
|
|
84
|
+
});
|
|
85
|
+
return this.sandboxProbe;
|
|
86
|
+
}
|
|
87
|
+
/** Initialize with MCP manager and policy, catalog tools, and generate type hints. */
|
|
88
|
+
initialize(mcpManager, policy, log) {
|
|
23
89
|
this.mcpManager = mcpManager;
|
|
90
|
+
this.policy = policy;
|
|
91
|
+
this.log = log ?? this.log;
|
|
24
92
|
this.refresh();
|
|
25
93
|
}
|
|
26
|
-
/** Refresh
|
|
94
|
+
/** Refresh the complete tool catalog and type hints (call on tools/list_changed). */
|
|
27
95
|
refresh() {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.
|
|
31
|
-
|
|
32
|
-
|
|
96
|
+
this.codeModeTools = this.mcpManager ? getCodeModeTools(this.mcpManager) : [];
|
|
97
|
+
this.diagnostics = getCodeModeDiagnostics(this.codeModeTools);
|
|
98
|
+
this.typeHints = generateTypeHints(this.codeModeTools);
|
|
99
|
+
const summary = `[code-mode] ${this.diagnostics.totalTools} tool(s): ` +
|
|
100
|
+
`${this.diagnostics.callableTools} callable, ${this.diagnostics.refusedTools} dispatch-refused; ` +
|
|
101
|
+
`output schemas: ${this.diagnostics.declaredOutputSchemas} declared, ` +
|
|
102
|
+
`${this.diagnostics.synthesizedOutputSchemas} synthesized, ` +
|
|
103
|
+
`${this.diagnostics.unavailableOutputSchemas} unavailable; ` +
|
|
104
|
+
`${this.typeHints.length} chars of type hints`;
|
|
105
|
+
if (summary !== this.lastDiagnosticSummary) {
|
|
106
|
+
this.log?.(summary);
|
|
107
|
+
this.lastDiagnosticSummary = summary;
|
|
108
|
+
}
|
|
33
109
|
}
|
|
34
110
|
/** Get the type hints string for injection into system prompt. */
|
|
35
111
|
getTypeHints() {
|
|
@@ -37,18 +113,34 @@ export class CodeModeManager {
|
|
|
37
113
|
}
|
|
38
114
|
/** Get eligible tools. */
|
|
39
115
|
getEligibleTools() {
|
|
40
|
-
return this.
|
|
116
|
+
return this.codeModeTools.filter((entry) => entry.callable).map((entry) => entry.tool);
|
|
41
117
|
}
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
return this.
|
|
118
|
+
/** Get the complete client-internal catalog, including permission and schema provenance. */
|
|
119
|
+
getCatalogTools() {
|
|
120
|
+
return this.codeModeTools;
|
|
121
|
+
}
|
|
122
|
+
getDiagnostics() {
|
|
123
|
+
return this.diagnostics;
|
|
45
124
|
}
|
|
46
125
|
/** Execute code in search mode (tool catalog queries). */
|
|
47
126
|
async searchTools(code) {
|
|
127
|
+
this.refresh();
|
|
128
|
+
if (this.diagnostics.callableTools === 0) {
|
|
129
|
+
return {
|
|
130
|
+
result: undefined,
|
|
131
|
+
error: NO_ELIGIBLE_TOOLS_ERROR.message,
|
|
132
|
+
errorDetails: {
|
|
133
|
+
...NO_ELIGIBLE_TOOLS_ERROR,
|
|
134
|
+
alternatives: [...(NO_ELIGIBLE_TOOLS_ERROR.alternatives ?? [])],
|
|
135
|
+
},
|
|
136
|
+
logs: [],
|
|
137
|
+
};
|
|
138
|
+
}
|
|
48
139
|
return this.execute(code);
|
|
49
140
|
}
|
|
50
141
|
/** Execute code that chains MCP tool calls. */
|
|
51
142
|
async executeCode(code) {
|
|
143
|
+
this.refresh();
|
|
52
144
|
return this.execute(code);
|
|
53
145
|
}
|
|
54
146
|
/** Create the Pi tool definitions for code_search and code_execute. */
|
|
@@ -60,14 +152,15 @@ export class CodeModeManager {
|
|
|
60
152
|
}
|
|
61
153
|
/** Format a system prompt section for code mode. */
|
|
62
154
|
formatSystemPromptSection() {
|
|
63
|
-
if (!this.isActive)
|
|
64
|
-
return "";
|
|
65
155
|
return [
|
|
66
156
|
"",
|
|
67
157
|
"<code_mode>",
|
|
68
158
|
"## Code mode",
|
|
69
159
|
"",
|
|
70
|
-
"
|
|
160
|
+
"Use when a task needs exact computation or control flow: math, aggregation, looping over",
|
|
161
|
+
"results, data transformation, or chaining several MCP tool calls with logic in between.",
|
|
162
|
+
"",
|
|
163
|
+
"`code_execute` runs vanilla JavaScript in a sandboxed V8 isolate. Concretely, that covers:",
|
|
71
164
|
"",
|
|
72
165
|
"1. **Arbitrary computation** — math, string manipulation, date arithmetic, data transformation,",
|
|
73
166
|
" or any calculation the user asks for. No MCP tools needed; plain JS works.",
|
|
@@ -75,21 +168,10 @@ export class CodeModeManager {
|
|
|
75
168
|
" many tool calls. Write a loop inside one `code_execute` instead of making many separate tool calls.",
|
|
76
169
|
"3. **Pagination** — fetch batches in a loop until exhausted, then compute over the full dataset.",
|
|
77
170
|
"",
|
|
78
|
-
"Use `code_search` first to discover
|
|
79
|
-
"",
|
|
80
|
-
"**Code mode tools are always available — you do not need to call `load_skill` first.**",
|
|
171
|
+
"Use `code_search` first to discover which MCP tools are reachable from inside the sandbox.",
|
|
81
172
|
"",
|
|
82
|
-
"
|
|
173
|
+
"`code_search` and `code_execute` are always registered and never gated.",
|
|
83
174
|
"",
|
|
84
|
-
"- **Skill** (`load_skill`) — a curated workflow exists for this domain task (e.g., a GitHub skill for PR management).",
|
|
85
|
-
"- **tool-cli** — you need to discover what tools exist, or make a quick ad-hoc tool call.",
|
|
86
|
-
"- **Code mode** (`code_execute`) — you need computation: math, aggregation, looping over results,",
|
|
87
|
-
" data transformation, or chaining multiple tool calls with logic in between.",
|
|
88
|
-
"",
|
|
89
|
-
"Pick based on what the task needs, not a fixed order. A calculation goes straight to code mode;",
|
|
90
|
-
"a single lookup goes to a skill or tool-cli; exploration starts with tool-cli or `code_search`.",
|
|
91
|
-
"",
|
|
92
|
-
"**If unsure what's available**, start with `code_search` or `tool-cli --help` to see what you have.",
|
|
93
175
|
"After producing a result, verify it makes sense — run a quick sanity check or spot-check values.",
|
|
94
176
|
"",
|
|
95
177
|
"### How to write code",
|
|
@@ -131,45 +213,55 @@ export class CodeModeManager {
|
|
|
131
213
|
].join("\n");
|
|
132
214
|
}
|
|
133
215
|
async execute(code) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
// Refresh eligible tools in case MCP servers changed since initialization
|
|
138
|
-
this.refresh();
|
|
139
|
-
const toolNames = this.eligibleTools.map((t) => t.name);
|
|
216
|
+
const policy = this.policy;
|
|
217
|
+
const toolNames = this.codeModeTools.map((entry) => entry.tool.name);
|
|
140
218
|
const dispatch = async (toolName, args) => {
|
|
141
|
-
const
|
|
142
|
-
if (!
|
|
219
|
+
const codeModeTool = this.codeModeTools.find((entry) => entry.tool.name === toolName);
|
|
220
|
+
if (!codeModeTool) {
|
|
143
221
|
throw new Error(`Tool "${toolName}" not found in code mode eligible tools`);
|
|
144
222
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
throw new Error(`MCP server "${tool.serverName}" is not connected`);
|
|
223
|
+
if (!policy) {
|
|
224
|
+
throw new Error("Code mode MCP policy is not initialized");
|
|
148
225
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
226
|
+
try {
|
|
227
|
+
const terminal = await policy.callTool({
|
|
228
|
+
source: "code-mode",
|
|
229
|
+
serverName: codeModeTool.tool.serverName,
|
|
230
|
+
toolName: codeModeTool.tool.name,
|
|
231
|
+
args,
|
|
232
|
+
});
|
|
233
|
+
return terminal.result;
|
|
153
234
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const textParts = result.content
|
|
157
|
-
.filter((c) => typeof c === "object" && c !== null && "text" in c)
|
|
158
|
-
.map((c) => c.text);
|
|
159
|
-
const combined = textParts.join("\n");
|
|
160
|
-
try {
|
|
161
|
-
return JSON.parse(combined);
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
return combined;
|
|
165
|
-
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
throw toCodeModeDispatchError(error, codeModeTool);
|
|
166
237
|
}
|
|
167
|
-
return result;
|
|
168
238
|
};
|
|
169
|
-
return
|
|
239
|
+
return this.sandboxExecutor(code, toolNames, dispatch, {
|
|
170
240
|
memoryLimit: this.options.memoryLimit,
|
|
171
241
|
timeoutMs: this.options.timeoutMs,
|
|
172
242
|
});
|
|
173
243
|
}
|
|
174
244
|
}
|
|
175
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Translate a policy denial into Code Mode's structured dispatch error, keeping
|
|
247
|
+
* the catalog's refusal detail so the model learns why a tool was refused.
|
|
248
|
+
*/
|
|
249
|
+
function toCodeModeDispatchError(error, codeModeTool) {
|
|
250
|
+
if (!(error instanceof McpPolicyError))
|
|
251
|
+
return error;
|
|
252
|
+
const isPermission = error.reason === "permission_denied";
|
|
253
|
+
return new CodeModeDispatchError({
|
|
254
|
+
error: isPermission ? "permission_denied" : error.reason,
|
|
255
|
+
message: error.message,
|
|
256
|
+
alternatives: [...error.alternatives],
|
|
257
|
+
toolName: codeModeTool.tool.name,
|
|
258
|
+
...(isPermission ? { reason: formatRefusalReasons(codeModeTool) } : {}),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function formatRefusalReasons(codeModeTool) {
|
|
262
|
+
return codeModeTool.refusalReasons
|
|
263
|
+
.map((reason) => reason === "destructive_hint"
|
|
264
|
+
? "annotations.destructiveHint is true"
|
|
265
|
+
: "annotations.readOnlyHint is not true")
|
|
266
|
+
.join("; ");
|
|
267
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy adapter for the optional `isolated-vm` native addon.
|
|
3
|
+
*
|
|
4
|
+
* Code Mode is the only feature that needs a real V8 isolate. `isolated-vm` is a
|
|
5
|
+
* native addon, so it can legitimately be absent: an unsupported platform, a
|
|
6
|
+
* missing prebuild with no toolchain to compile one, or a deliberate
|
|
7
|
+
* `--omit=optional` install. When that happens Code Mode must report itself
|
|
8
|
+
* unavailable and the rest of the extension — skills, tool-cli, routing — must
|
|
9
|
+
* keep working.
|
|
10
|
+
*
|
|
11
|
+
* Two rules govern this module:
|
|
12
|
+
*
|
|
13
|
+
* 1. **No top-level import.** The specifier is resolved through a dynamic
|
|
14
|
+
* `import()` behind a variable so neither Node nor TypeScript binds to the
|
|
15
|
+
* addon at module-evaluation time. Loading the extension never throws
|
|
16
|
+
* because a native addon is missing.
|
|
17
|
+
* 2. **Never fall back to Node's `vm`.** `node:vm` shares the host heap and
|
|
18
|
+
* realm; it is a code-organisation tool, not a security boundary. Silently
|
|
19
|
+
* downgrading to it would turn "sandboxed execution" into a false claim.
|
|
20
|
+
* If the addon is absent, Code Mode is unavailable — full stop.
|
|
21
|
+
*/
|
|
22
|
+
/** The subset of the `isolated-vm` surface Code Mode actually uses. */
|
|
23
|
+
export interface IsolatedVmContext {
|
|
24
|
+
readonly global: {
|
|
25
|
+
set(name: string, value: unknown): Promise<void>;
|
|
26
|
+
};
|
|
27
|
+
eval(code: string, options: {
|
|
28
|
+
promise: true;
|
|
29
|
+
copy: true;
|
|
30
|
+
timeout: number;
|
|
31
|
+
}): Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
export interface IsolatedVmIsolate {
|
|
34
|
+
createContext(): Promise<IsolatedVmContext>;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
}
|
|
37
|
+
export interface IsolatedVmModule {
|
|
38
|
+
Isolate: new (options: {
|
|
39
|
+
memoryLimit: number;
|
|
40
|
+
}) => IsolatedVmIsolate;
|
|
41
|
+
Callback: new (fn: (...args: never[]) => unknown) => unknown;
|
|
42
|
+
Reference: new (fn: (...args: never[]) => unknown) => unknown;
|
|
43
|
+
}
|
|
44
|
+
/** Outcome of attempting to load the native addon. */
|
|
45
|
+
export type IsolatedVmLoad = {
|
|
46
|
+
readonly available: true;
|
|
47
|
+
readonly module: IsolatedVmModule;
|
|
48
|
+
} | {
|
|
49
|
+
readonly available: false;
|
|
50
|
+
readonly reason: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Load the native addon at most once per process.
|
|
54
|
+
*
|
|
55
|
+
* The result — success *or* failure — is cached. A failed load is not retried:
|
|
56
|
+
* a missing or broken native addon does not become present later in the same
|
|
57
|
+
* process, and retrying would repeat the cost on every Code Mode call.
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadIsolatedVm(): Promise<IsolatedVmLoad>;
|
|
60
|
+
/** Synchronously report a previously resolved load, if one has happened. */
|
|
61
|
+
export declare function peekIsolatedVm(): IsolatedVmLoad | undefined;
|
|
62
|
+
/** Reset the memoised state. Test-only. */
|
|
63
|
+
export declare function resetIsolatedVmCacheForTests(): void;
|
|
64
|
+
/** Seed the memoised state. Test-only — lets tests simulate an absent addon. */
|
|
65
|
+
export declare function setIsolatedVmForTests(load: IsolatedVmLoad): void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy adapter for the optional `isolated-vm` native addon.
|
|
3
|
+
*
|
|
4
|
+
* Code Mode is the only feature that needs a real V8 isolate. `isolated-vm` is a
|
|
5
|
+
* native addon, so it can legitimately be absent: an unsupported platform, a
|
|
6
|
+
* missing prebuild with no toolchain to compile one, or a deliberate
|
|
7
|
+
* `--omit=optional` install. When that happens Code Mode must report itself
|
|
8
|
+
* unavailable and the rest of the extension — skills, tool-cli, routing — must
|
|
9
|
+
* keep working.
|
|
10
|
+
*
|
|
11
|
+
* Two rules govern this module:
|
|
12
|
+
*
|
|
13
|
+
* 1. **No top-level import.** The specifier is resolved through a dynamic
|
|
14
|
+
* `import()` behind a variable so neither Node nor TypeScript binds to the
|
|
15
|
+
* addon at module-evaluation time. Loading the extension never throws
|
|
16
|
+
* because a native addon is missing.
|
|
17
|
+
* 2. **Never fall back to Node's `vm`.** `node:vm` shares the host heap and
|
|
18
|
+
* realm; it is a code-organisation tool, not a security boundary. Silently
|
|
19
|
+
* downgrading to it would turn "sandboxed execution" into a false claim.
|
|
20
|
+
* If the addon is absent, Code Mode is unavailable — full stop.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Resolved through a variable rather than a string literal so that TypeScript
|
|
24
|
+
* does not require `isolated-vm` types to be present to build, and so no
|
|
25
|
+
* bundler or loader statically links the addon into the module graph.
|
|
26
|
+
*/
|
|
27
|
+
const ISOLATED_VM_SPECIFIER = "isolated-vm";
|
|
28
|
+
const MISSING_MODULE_CODES = new Set([
|
|
29
|
+
"ERR_MODULE_NOT_FOUND",
|
|
30
|
+
"MODULE_NOT_FOUND",
|
|
31
|
+
"ERR_DLOPEN_FAILED",
|
|
32
|
+
]);
|
|
33
|
+
let cached;
|
|
34
|
+
let inFlight;
|
|
35
|
+
/**
|
|
36
|
+
* Load the native addon at most once per process.
|
|
37
|
+
*
|
|
38
|
+
* The result — success *or* failure — is cached. A failed load is not retried:
|
|
39
|
+
* a missing or broken native addon does not become present later in the same
|
|
40
|
+
* process, and retrying would repeat the cost on every Code Mode call.
|
|
41
|
+
*/
|
|
42
|
+
export async function loadIsolatedVm() {
|
|
43
|
+
if (cached)
|
|
44
|
+
return cached;
|
|
45
|
+
inFlight ??= attemptLoad().then((result) => {
|
|
46
|
+
cached = result;
|
|
47
|
+
inFlight = undefined;
|
|
48
|
+
return result;
|
|
49
|
+
});
|
|
50
|
+
return inFlight;
|
|
51
|
+
}
|
|
52
|
+
/** Synchronously report a previously resolved load, if one has happened. */
|
|
53
|
+
export function peekIsolatedVm() {
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
/** Reset the memoised state. Test-only. */
|
|
57
|
+
export function resetIsolatedVmCacheForTests() {
|
|
58
|
+
cached = undefined;
|
|
59
|
+
inFlight = undefined;
|
|
60
|
+
}
|
|
61
|
+
/** Seed the memoised state. Test-only — lets tests simulate an absent addon. */
|
|
62
|
+
export function setIsolatedVmForTests(load) {
|
|
63
|
+
cached = load;
|
|
64
|
+
inFlight = undefined;
|
|
65
|
+
}
|
|
66
|
+
async function attemptLoad() {
|
|
67
|
+
try {
|
|
68
|
+
const imported = await import(ISOLATED_VM_SPECIFIER);
|
|
69
|
+
const candidate = unwrapDefault(imported);
|
|
70
|
+
if (!isIsolatedVmModule(candidate)) {
|
|
71
|
+
return {
|
|
72
|
+
available: false,
|
|
73
|
+
reason: "the optional isolated-vm addon loaded but did not expose the expected Isolate/Callback/Reference API",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { available: true, module: candidate };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
return { available: false, reason: describeLoadFailure(error) };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function unwrapDefault(imported) {
|
|
83
|
+
if (typeof imported !== "object" || imported === null)
|
|
84
|
+
return imported;
|
|
85
|
+
const namespace = imported;
|
|
86
|
+
return namespace.default ?? imported;
|
|
87
|
+
}
|
|
88
|
+
function isIsolatedVmModule(value) {
|
|
89
|
+
if (typeof value !== "object" || value === null)
|
|
90
|
+
return false;
|
|
91
|
+
const candidate = value;
|
|
92
|
+
return (typeof candidate.Isolate === "function" &&
|
|
93
|
+
typeof candidate.Callback === "function" &&
|
|
94
|
+
typeof candidate.Reference === "function");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Turn a load failure into a reason a human can act on.
|
|
98
|
+
*
|
|
99
|
+
* The two failure shapes are meaningfully different: "not installed" is fixed
|
|
100
|
+
* by installing it, while "installed but failed to load" points at an ABI or
|
|
101
|
+
* platform mismatch and needs a rebuild.
|
|
102
|
+
*/
|
|
103
|
+
function describeLoadFailure(error) {
|
|
104
|
+
const code = getErrorCode(error);
|
|
105
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
106
|
+
if (code && MISSING_MODULE_CODES.has(code)) {
|
|
107
|
+
return `the optional isolated-vm native addon is not installed or failed to load (${code}: ${detail})`;
|
|
108
|
+
}
|
|
109
|
+
return `the optional isolated-vm native addon could not be loaded (${detail})`;
|
|
110
|
+
}
|
|
111
|
+
function getErrorCode(error) {
|
|
112
|
+
if (typeof error !== "object" || error === null)
|
|
113
|
+
return undefined;
|
|
114
|
+
const code = error.code;
|
|
115
|
+
return typeof code === "string" ? code : undefined;
|
|
116
|
+
}
|
|
@@ -9,6 +9,10 @@ export interface CodeModeToolDetails {
|
|
|
9
9
|
executionMs: number;
|
|
10
10
|
logs: string[];
|
|
11
11
|
error?: string;
|
|
12
|
+
message?: string;
|
|
13
|
+
alternatives?: string[];
|
|
14
|
+
toolName?: string;
|
|
15
|
+
reason?: string;
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
18
|
* Create the `code_search` tool for querying the tool catalog.
|
|
@@ -42,4 +46,3 @@ export declare function createCodeExecuteTool(manager: CodeModeManager): {
|
|
|
42
46
|
execute(_toolCallId: string, params: CodeInputType, _signal: AbortSignal | undefined, _onUpdate: undefined, _ctx: ExtensionContext): Promise<AgentToolResult<CodeModeToolDetails>>;
|
|
43
47
|
};
|
|
44
48
|
export {};
|
|
45
|
-
//# sourceMappingURL=tools.d.ts.map
|
package/dist/code-mode/tools.js
CHANGED
|
@@ -7,13 +7,17 @@ const CodeInput = Type.Object({
|
|
|
7
7
|
/** Format an ExecuteResult into a tool response. Falls back to logs if result is undefined. */
|
|
8
8
|
function formatResult(result, executionMs, errorPrefix) {
|
|
9
9
|
if (result.error) {
|
|
10
|
+
const errorDetails = result.errorDetails ?? {
|
|
11
|
+
error: "execution_failed",
|
|
12
|
+
message: result.error,
|
|
13
|
+
};
|
|
10
14
|
return {
|
|
11
15
|
content: [{ type: "text", text: `${errorPrefix}: ${result.error}` }],
|
|
12
|
-
details: { executionMs, logs: result.logs,
|
|
16
|
+
details: { executionMs, logs: result.logs, ...errorDetails },
|
|
13
17
|
};
|
|
14
18
|
}
|
|
15
19
|
// If code didn't return a value, fall back to captured console output
|
|
16
|
-
const output = result.result !== undefined
|
|
20
|
+
const output = result.result !== undefined
|
|
17
21
|
? typeof result.result === "string"
|
|
18
22
|
? result.result
|
|
19
23
|
: JSON.stringify(result.result, null, 2)
|
|
@@ -38,7 +42,7 @@ export function createCodeSearchTool(manager) {
|
|
|
38
42
|
return {
|
|
39
43
|
name: "code_search",
|
|
40
44
|
label: "Code Search",
|
|
41
|
-
description: "Discover available
|
|
45
|
+
description: "Discover all available MCP tools by writing JavaScript. Use `codemode.listTools()` to list tools and `codemode.describeTools(names)` for type info. Type hints identify which tools Code Mode can call; non-read-only tools remain discovery-only.",
|
|
42
46
|
parameters: CodeInput,
|
|
43
47
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
44
48
|
const start = performance.now();
|
|
@@ -67,4 +71,3 @@ export function createCodeExecuteTool(manager) {
|
|
|
67
71
|
},
|
|
68
72
|
};
|
|
69
73
|
}
|
|
70
|
-
//# sourceMappingURL=tools.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { McpTool } from "../mcp/index.js";
|
|
2
|
+
import { type CodeModeTool } from "./eligibility.js";
|
|
2
3
|
type JsonSchema = Record<string, unknown>;
|
|
3
4
|
/**
|
|
4
5
|
* Convert a JSON Schema to a TypeScript type string.
|
|
@@ -15,6 +16,5 @@ export declare function sanitizeToolName(name: string): string;
|
|
|
15
16
|
* Produces a `declare const codemode: { ... }` block with type-safe
|
|
16
17
|
* method signatures the model can use when writing code.
|
|
17
18
|
*/
|
|
18
|
-
export declare function generateTypeHints(tools: McpTool[]): string;
|
|
19
|
+
export declare function generateTypeHints(tools: readonly (McpTool | CodeModeTool)[]): string;
|
|
19
20
|
export {};
|
|
20
|
-
//# sourceMappingURL=type-hints.d.ts.map
|