theorum 1.0.0 → 1.1.3
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/README.md +81 -25
- package/esm/mod.d.ts +48 -29
- package/esm/mod.js +37 -24
- package/esm/src/cli/commands/bench.js +13 -16
- package/esm/src/cli/commands/fuzz-canary.js +25 -29
- package/esm/src/cli/commands/guardrails-eval.d.ts +14 -0
- package/esm/src/cli/commands/guardrails-eval.js +15 -0
- package/esm/src/cli/commands/profile.js +12 -3
- package/esm/src/cli/commands/run.js +8 -9
- package/esm/src/cli/commands/test.js +8 -8
- package/esm/src/cli/event-log.d.ts +1 -1
- package/esm/src/cli/index.js +12 -0
- package/esm/src/cli/matrix/synthesizer.d.ts +6 -6
- package/esm/src/cli/matrix/synthesizer.js +23 -22
- package/esm/src/guardrails/canary-gate.d.ts +2 -1
- package/esm/src/guardrails/canary-gate.js +2 -1
- package/esm/src/guardrails/canary.d.ts +9 -1
- package/esm/src/guardrails/canary.js +21 -10
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +1 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +12 -15
- package/esm/src/guardrails/corpus/inbound-payloads.js +1 -0
- package/esm/src/guardrails/corpus/live-attacks.js +0 -1
- package/esm/src/guardrails/corpus/mod.d.ts +1 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +1 -0
- package/esm/src/guardrails/corpus/secrets.js +1 -0
- package/esm/src/guardrails/corpus/strings.d.ts +1 -0
- package/esm/src/guardrails/corpus/strings.js +1 -0
- package/esm/src/guardrails/corpus/types.d.ts +1 -0
- package/esm/src/guardrails/egress.d.ts +26 -3
- package/esm/src/guardrails/egress.js +69 -18
- package/esm/src/guardrails/error.d.ts +14 -23
- package/esm/src/guardrails/error.js +86 -77
- package/esm/src/guardrails/eval/corpus.d.ts +108 -0
- package/esm/src/guardrails/eval/corpus.js +978 -0
- package/esm/src/guardrails/eval/mod.d.ts +51 -0
- package/esm/src/guardrails/eval/mod.js +133 -0
- package/esm/src/guardrails/eval/score.d.ts +66 -0
- package/esm/src/guardrails/eval/score.js +114 -0
- package/esm/src/guardrails/events.d.ts +25 -0
- package/esm/src/guardrails/events.js +56 -0
- package/esm/src/guardrails/hits.d.ts +24 -0
- package/esm/src/guardrails/hits.js +45 -0
- package/esm/src/guardrails/lexicon.d.ts +39 -0
- package/esm/src/guardrails/lexicon.js +200 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +15 -13
- package/esm/src/guardrails/live-outbound-gate.js +131 -89
- package/esm/src/guardrails/mod.d.ts +19 -4
- package/esm/src/guardrails/mod.js +12 -3
- package/esm/src/guardrails/network.d.ts +19 -0
- package/esm/src/guardrails/network.js +234 -0
- package/esm/src/guardrails/policy.d.ts +35 -0
- package/esm/src/guardrails/policy.js +50 -0
- package/esm/src/guardrails/progressive-yield.d.ts +51 -0
- package/esm/src/guardrails/progressive-yield.js +98 -0
- package/esm/src/guardrails/quota.d.ts +17 -3
- package/esm/src/guardrails/quota.js +18 -4
- package/esm/src/guardrails/sanitize.d.ts +36 -6
- package/esm/src/guardrails/sanitize.js +152 -60
- package/esm/src/guardrails/serialize.d.ts +35 -0
- package/esm/src/guardrails/serialize.js +58 -0
- package/esm/src/guardrails/testing.d.ts +7 -0
- package/esm/src/guardrails/testing.js +4 -0
- package/esm/src/guardrails/theorum-error.d.ts +12 -0
- package/esm/src/guardrails/theorum-error.js +15 -0
- package/esm/src/guardrails/tool-directives.d.ts +48 -0
- package/esm/src/guardrails/tool-directives.js +124 -0
- package/esm/src/guardrails/tool-result.d.ts +93 -0
- package/esm/src/guardrails/tool-result.js +276 -0
- package/esm/src/guardrails/types.d.ts +291 -0
- package/esm/src/guardrails/types.js +72 -0
- package/esm/src/host/client-turn.js +4 -0
- package/esm/src/host/mint-trace.d.ts +1 -1
- package/esm/src/kernel/auth/crypto.d.ts +42 -0
- package/esm/src/kernel/auth/crypto.js +106 -0
- package/esm/src/kernel/auth/mod.d.ts +11 -0
- package/esm/src/kernel/auth/mod.js +11 -0
- package/esm/src/kernel/auth/oauth.d.ts +47 -0
- package/esm/src/kernel/auth/oauth.js +278 -0
- package/esm/src/kernel/auth/types.d.ts +133 -0
- package/esm/src/kernel/auth/types.js +13 -0
- package/esm/src/kernel/engine/delta.js +43 -2
- package/esm/src/kernel/engine/live-inbound.d.ts +15 -3
- package/esm/src/kernel/engine/live-inbound.js +22 -8
- package/esm/src/kernel/engine/live-ingress.d.ts +19 -0
- package/esm/src/kernel/engine/live-ingress.js +47 -0
- package/esm/src/kernel/engine/repair.js +13 -12
- package/esm/src/kernel/engine/runner/gates.js +127 -40
- package/esm/src/kernel/engine/runner/mod.d.ts +6 -4
- package/esm/src/kernel/engine/runner/mod.js +182 -43
- package/esm/src/kernel/engine/runner/schema-validation.js +3 -3
- package/esm/src/kernel/engine/runner/stages.d.ts +39 -0
- package/esm/src/kernel/engine/runner/stages.js +89 -0
- package/esm/src/kernel/engine/runner/state.d.ts +24 -0
- package/esm/src/kernel/engine/runner/steps.js +128 -61
- package/esm/src/kernel/engine/runner/stream.d.ts +9 -2
- package/esm/src/kernel/engine/runner/stream.js +114 -55
- package/esm/src/kernel/engine/session/mod.d.ts +3 -1
- package/esm/src/kernel/engine/session/mod.js +386 -34
- package/esm/src/kernel/interaction-parts.d.ts +14 -0
- package/esm/src/kernel/interaction-parts.js +23 -0
- package/esm/src/kernel/mod.d.ts +19 -7
- package/esm/src/kernel/mod.js +10 -5
- package/esm/src/kernel/profile-graph.d.ts +159 -0
- package/esm/src/kernel/profile-graph.js +156 -0
- package/esm/src/kernel/registry/attachments.d.ts +10 -10
- package/esm/src/kernel/registry/attachments.js +29 -26
- package/esm/src/kernel/registry/catalog.d.ts +25 -11
- package/esm/src/kernel/registry/catalog.js +59 -24
- package/esm/src/kernel/registry/ingress.js +34 -22
- package/esm/src/kernel/registry/profile-outputs.d.ts +4 -0
- package/esm/src/kernel/registry/profile-outputs.js +8 -0
- package/esm/src/kernel/registry/profiles.d.ts +34 -14
- package/esm/src/kernel/registry/profiles.js +306 -59
- package/esm/src/kernel/registry/provider-request.js +2 -0
- package/esm/src/kernel/registry/resolve.d.ts +7 -6
- package/esm/src/kernel/registry/resolve.js +102 -117
- package/esm/src/kernel/registry/schemas.js +1 -1
- package/esm/src/kernel/registry/sole-model.d.ts +8 -0
- package/esm/src/kernel/registry/sole-model.js +10 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +10 -0
- package/esm/src/kernel/registry/system-prompt.js +40 -0
- package/esm/src/kernel/registry/system-role.d.ts +8 -0
- package/esm/src/kernel/registry/system-role.js +14 -0
- package/esm/src/kernel/registry/vault.d.ts +2 -2
- package/esm/src/kernel/registry/vault.js +4 -4
- package/esm/src/kernel/schema.d.ts +97 -11
- package/esm/src/kernel/schema.js +256 -111
- package/esm/src/kernel/stages.d.ts +175 -0
- package/esm/src/kernel/stages.js +476 -0
- package/esm/src/kernel/stop.d.ts +65 -11
- package/esm/src/kernel/stop.js +46 -11
- package/esm/src/kernel/tools/events.d.ts +41 -0
- package/esm/src/kernel/tools/events.js +71 -0
- package/esm/src/kernel/tools/execute.d.ts +63 -24
- package/esm/src/kernel/tools/execute.js +475 -224
- package/esm/src/kernel/tools/harness.js +16 -14
- package/esm/src/kernel/tools/invoke.js +26 -8
- package/esm/src/kernel/tools/mod.d.ts +3 -1
- package/esm/src/kernel/tools/mod.js +2 -1
- package/esm/src/kernel/tools/permission.d.ts +15 -0
- package/esm/src/kernel/tools/permission.js +47 -0
- package/esm/src/kernel/tools/project.js +5 -3
- package/esm/src/kernel/tools/registry.js +20 -10
- package/esm/src/kernel/tools/remote.d.ts +94 -0
- package/esm/src/kernel/tools/remote.js +577 -0
- package/esm/src/kernel/tools/resolve.d.ts +17 -7
- package/esm/src/kernel/tools/resolve.js +38 -17
- package/esm/src/kernel/tools/schema.d.ts +2 -0
- package/esm/src/kernel/tools/schema.js +23 -6
- package/esm/src/kernel/tools/stage-run.d.ts +105 -0
- package/esm/src/kernel/tools/stage-run.js +155 -0
- package/esm/src/kernel/tools/types.d.ts +198 -20
- package/esm/src/kernel/types.d.ts +253 -114
- package/esm/src/kernel/util/find-last.d.ts +2 -0
- package/esm/src/kernel/util/find-last.js +10 -0
- package/esm/src/observability/destinations.d.ts +31 -0
- package/esm/src/observability/destinations.js +67 -0
- package/esm/src/observability/mod.d.ts +10 -3
- package/esm/src/observability/mod.js +6 -2
- package/esm/src/observability/policy.d.ts +27 -0
- package/esm/src/observability/policy.js +80 -0
- package/esm/src/observability/resolve-policy.d.ts +16 -0
- package/esm/src/observability/resolve-policy.js +64 -0
- package/esm/src/observability/trace-attach.d.ts +3 -1
- package/esm/src/observability/trace-attach.js +17 -10
- package/esm/src/observability/trace-record.d.ts +12 -4
- package/esm/src/observability/trace-record.js +63 -19
- package/esm/src/observability/trace-sink.d.ts +19 -0
- package/esm/src/observability/trace-sink.js +10 -0
- package/esm/src/observability/trace.d.ts +14 -11
- package/esm/src/observability/trace.js +23 -14
- package/esm/src/observability/types.d.ts +113 -0
- package/esm/src/observability/types.js +11 -0
- package/esm/src/providers/create-provider.d.ts +7 -4
- package/esm/src/providers/create-provider.js +21 -7
- package/esm/src/providers/google/interactions/framing.d.ts +8 -0
- package/esm/src/providers/google/interactions/framing.js +74 -13
- package/esm/src/providers/google/live/framing.d.ts +5 -2
- package/esm/src/providers/google/live/framing.js +49 -12
- package/esm/src/providers/google/live/openapi-schema.js +3 -2
- package/esm/src/providers/google/live/stream.d.ts +9 -0
- package/esm/src/providers/google/live/stream.js +16 -3
- package/esm/src/providers/openrouter/cache-control.d.ts +24 -0
- package/esm/src/providers/openrouter/cache-control.js +23 -0
- package/esm/src/providers/openrouter/chat.d.ts +21 -1
- package/esm/src/providers/openrouter/chat.js +51 -6
- package/esm/src/providers/openrouter/image.js +8 -19
- package/esm/src/providers/openrouter/openai/chat-payload.js +23 -1
- package/esm/src/providers/openrouter/openai/compat.d.ts +7 -1
- package/esm/src/providers/openrouter/openai/compat.js +23 -4
- package/esm/src/providers/openrouter/openai/image-payload.js +8 -2
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +1 -1
- package/esm/src/providers/openrouter/openai/sdk-messages.js +32 -5
- package/package.json +1 -1
- package/esm/src/interface/blocks.d.ts +0 -20
- package/esm/src/interface/blocks.js +0 -180
- package/esm/src/interface/from-profile.d.ts +0 -14
- package/esm/src/interface/from-profile.js +0 -104
- package/esm/src/interface/inputs.d.ts +0 -8
- package/esm/src/interface/inputs.js +0 -127
- package/esm/src/interface/mod.d.ts +0 -10
- package/esm/src/interface/mod.js +0 -9
- package/esm/src/interface/types.d.ts +0 -153
- package/esm/src/interface/types.js +0 -13
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
+
import { AWAITING_USER_INPUT_STATUS } from '../schema.js';
|
|
7
8
|
import { registerTool } from './registry.js';
|
|
8
9
|
const AskInputSchema = z.object({
|
|
9
10
|
kind: z.enum(['confirm', 'choice', 'text']),
|
|
@@ -11,14 +12,17 @@ const AskInputSchema = z.object({
|
|
|
11
12
|
options: z.array(z.string()).optional(),
|
|
12
13
|
});
|
|
13
14
|
const AskOutputSchema = z.object({
|
|
14
|
-
|
|
15
|
+
status: z.literal(AWAITING_USER_INPUT_STATUS),
|
|
16
|
+
kind: z.enum(['confirm', 'choice', 'text']),
|
|
17
|
+
prompt: z.string().trim().min(1),
|
|
18
|
+
options: z.array(z.string()).optional(),
|
|
15
19
|
});
|
|
16
20
|
/** Register harness tools shipped with THEORUM. */
|
|
17
21
|
function registerHarnessTools() {
|
|
18
22
|
registerTool({
|
|
19
23
|
type: 'function',
|
|
20
24
|
name: 'ask_user',
|
|
21
|
-
description: 'Ask the user a question
|
|
25
|
+
description: 'Ask the user a question (completes with awaiting_user_input)', // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
22
26
|
category: 'conversation',
|
|
23
27
|
access: 'read-only',
|
|
24
28
|
paths: ['*'],
|
|
@@ -26,19 +30,17 @@ function registerHarnessTools() {
|
|
|
26
30
|
permission: 'auto',
|
|
27
31
|
input: AskInputSchema,
|
|
28
32
|
output: AskOutputSchema,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
33
|
+
handler: (input) => {
|
|
34
|
+
const out = {
|
|
35
|
+
status: AWAITING_USER_INPUT_STATUS,
|
|
36
|
+
kind: input.kind,
|
|
37
|
+
prompt: input.prompt,
|
|
38
|
+
};
|
|
39
|
+
if (input.kind === 'choice' && input.options?.length) {
|
|
40
|
+
out.options = input.options;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
38
43
|
},
|
|
39
|
-
handler: (_input, ctx) => ({
|
|
40
|
-
answer: ctx.resume?.value ?? ctx.resume?.granted,
|
|
41
|
-
}),
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
export { registerHarnessTools };
|
|
@@ -14,12 +14,14 @@ function turnRequestFromInvoke(request) {
|
|
|
14
14
|
path: request.path,
|
|
15
15
|
sessionPermissions: request.sessionPermissions,
|
|
16
16
|
input: request.turnInput,
|
|
17
|
-
|
|
17
|
+
model: request.model,
|
|
18
|
+
host: request.host,
|
|
18
19
|
};
|
|
19
20
|
}
|
|
20
21
|
async function prepareInvokeSnapshot(request, profile) {
|
|
21
22
|
const req = turnRequestFromInvoke(request);
|
|
22
|
-
|
|
23
|
+
// Host profiles bind no model — the allow list is the whole snapshot.
|
|
24
|
+
const model = profile.type === 'host' ? undefined : pickModel(profile, request.model);
|
|
23
25
|
return await prepareTurnToolSnapshot(profile, req, model);
|
|
24
26
|
}
|
|
25
27
|
/** Execute a registered tool without calling a model provider. */
|
|
@@ -41,13 +43,14 @@ async function* invokeTool(request) {
|
|
|
41
43
|
failure,
|
|
42
44
|
},
|
|
43
45
|
};
|
|
44
|
-
yield { type: 'done', stop: { kind: '
|
|
46
|
+
yield { type: 'done', stop: { kind: 'completed' } };
|
|
45
47
|
return;
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
|
-
let
|
|
50
|
+
let sawGate = false;
|
|
49
51
|
let sawError = false;
|
|
50
52
|
try {
|
|
53
|
+
const handlers = request.onStage ? [request.onStage] : [];
|
|
51
54
|
for await (const event of executeRegisteredTool({
|
|
52
55
|
profile,
|
|
53
56
|
name: request.name,
|
|
@@ -55,18 +58,29 @@ async function* invokeTool(request) {
|
|
|
55
58
|
callId,
|
|
56
59
|
ctx: {
|
|
57
60
|
sessionPermissions: request.sessionPermissions,
|
|
61
|
+
credentials: request.credentials,
|
|
58
62
|
path: request.path,
|
|
59
63
|
signal: request.signal,
|
|
60
64
|
resume: request.resume,
|
|
65
|
+
host: request.host,
|
|
61
66
|
},
|
|
62
67
|
snapshot,
|
|
68
|
+
stages: {
|
|
69
|
+
handlers,
|
|
70
|
+
profile,
|
|
71
|
+
step: 1,
|
|
72
|
+
history: () => [],
|
|
73
|
+
injectAllowed: false,
|
|
74
|
+
host: request.host,
|
|
75
|
+
signal: request.signal,
|
|
76
|
+
},
|
|
63
77
|
})) {
|
|
64
78
|
yield event;
|
|
65
79
|
if (event.type !== 'tool') {
|
|
66
80
|
continue;
|
|
67
81
|
}
|
|
68
|
-
if (event.tool?.phase === '
|
|
69
|
-
|
|
82
|
+
if (event.tool?.phase === 'gate') {
|
|
83
|
+
sawGate = true;
|
|
70
84
|
}
|
|
71
85
|
if (event.tool?.phase === 'error') {
|
|
72
86
|
sawError = true;
|
|
@@ -77,7 +91,11 @@ async function* invokeTool(request) {
|
|
|
77
91
|
yield toErrorEvent(err);
|
|
78
92
|
sawError = true;
|
|
79
93
|
}
|
|
80
|
-
const stopKind =
|
|
81
|
-
yield {
|
|
94
|
+
const stopKind = sawGate ? 'gate' : sawError ? 'completed' : 'completed';
|
|
95
|
+
yield {
|
|
96
|
+
type: 'done',
|
|
97
|
+
stop: { kind: stopKind },
|
|
98
|
+
...(sawGate ? { tools: snapshot } : {}),
|
|
99
|
+
};
|
|
82
100
|
}
|
|
83
101
|
export { invokeTool };
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
export { formatToolResult } from './execute.js';
|
|
6
|
+
export { coerceToolResultParts, executeRegisteredTool, formatToolResult, leanToolResultData, projectForModel, } from './execute.js';
|
|
7
7
|
export { registerHarnessTools } from './harness.js';
|
|
8
8
|
export { invokeTool } from './invoke.js';
|
|
9
9
|
export { getTool, hasTool, listBuiltinIds, listFunctionIds, listTools, registerTool, registerTools, requireTool, resetTools, } from './registry.js';
|
|
10
|
+
export type { McpProtocolVersion, McpRpcResponse } from './remote.js';
|
|
11
|
+
export { buildHttpToolTarget, executeHttpTool, executeMcpTool, isUnsupportedMcpProtocolError, MCP_PROTOCOL_VERSIONS, parseMcpRpcResponse, resolveToolAuth, } from './remote.js';
|
|
10
12
|
export { cloneTurnToolSnapshot, prepareTurnToolSnapshot } from './resolve.js';
|
|
11
13
|
export type * from './types.js';
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
export { formatToolResult } from './execute.js';
|
|
6
|
+
export { coerceToolResultParts, executeRegisteredTool, formatToolResult, leanToolResultData, projectForModel, } from './execute.js';
|
|
7
7
|
export { registerHarnessTools } from './harness.js';
|
|
8
8
|
export { invokeTool } from './invoke.js';
|
|
9
9
|
export { getTool, hasTool, listBuiltinIds, listFunctionIds, listTools, registerTool, registerTools, requireTool, resetTools, } from './registry.js';
|
|
10
|
+
export { buildHttpToolTarget, executeHttpTool, executeMcpTool, isUnsupportedMcpProtocolError, MCP_PROTOCOL_VERSIONS, parseMcpRpcResponse, resolveToolAuth, } from './remote.js';
|
|
10
11
|
export { cloneTurnToolSnapshot, prepareTurnToolSnapshot } from './resolve.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative catalog permission + gate-resume helpers.
|
|
3
|
+
*
|
|
4
|
+
* Shared by function and HTTP/MCP execute paths (no circular import with remote).
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { InvokeToolResume, ToolGate, ToolPermission } from './types.js';
|
|
9
|
+
export declare function isResumeContinuation(resume?: InvokeToolResume): boolean;
|
|
10
|
+
/** Gate resume — only `granted: true` skips confirm/permission/`preTool` re-ask. */
|
|
11
|
+
export declare function isGateResumeGranted(resume?: InvokeToolResume): boolean;
|
|
12
|
+
/** Host denied after a gate — settle without running the body. */
|
|
13
|
+
export declare function isGateResumeDenied(resume?: InvokeToolResume): boolean;
|
|
14
|
+
export declare function permissionGranted(toolName: string, sessionPermissions?: string[]): boolean;
|
|
15
|
+
export declare function checkPermission(toolName: string, permission: ToolPermission, sessionPermissions?: string[], resume?: InvokeToolResume): ToolGate | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declarative catalog permission + gate-resume helpers.
|
|
3
|
+
*
|
|
4
|
+
* Shared by function and HTTP/MCP execute paths (no circular import with remote).
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
export function isResumeContinuation(resume) {
|
|
9
|
+
return resume?.value !== undefined || typeof resume?.granted === 'boolean';
|
|
10
|
+
}
|
|
11
|
+
/** Gate resume — only `granted: true` skips confirm/permission/`preTool` re-ask. */
|
|
12
|
+
export function isGateResumeGranted(resume) {
|
|
13
|
+
return resume?.granted === true;
|
|
14
|
+
}
|
|
15
|
+
/** Host denied after a gate — settle without running the body. */
|
|
16
|
+
export function isGateResumeDenied(resume) {
|
|
17
|
+
return resume?.granted === false;
|
|
18
|
+
}
|
|
19
|
+
export function permissionGranted(toolName, sessionPermissions) {
|
|
20
|
+
if (!sessionPermissions) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return sessionPermissions.includes('*') || sessionPermissions.includes(toolName);
|
|
24
|
+
}
|
|
25
|
+
export function checkPermission(toolName, permission, sessionPermissions, resume) {
|
|
26
|
+
if (permission === 'auto') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (permission === 'always_confirm') {
|
|
30
|
+
if (resume?.granted === true) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
kind: 'permission',
|
|
35
|
+
tool: toolName,
|
|
36
|
+
permission,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (permissionGranted(toolName, sessionPermissions)) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
kind: 'permission',
|
|
44
|
+
tool: toolName,
|
|
45
|
+
permission,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -13,9 +13,11 @@ function projectTool(name) {
|
|
|
13
13
|
}
|
|
14
14
|
function builtInToolIds(profile) {
|
|
15
15
|
const seen = new Set();
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
if (profile.type === 'host') {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
for (const binding of Object.values(profile.models)) {
|
|
20
|
+
for (const id of binding.builtInTools ?? []) {
|
|
19
21
|
seen.add(id);
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -11,22 +11,32 @@
|
|
|
11
11
|
import { TheorumError } from '../../guardrails/error.js';
|
|
12
12
|
import { jsonSchemaFromZod, validateToolInputSchema, validateToolOutputSchema } from './schema.js';
|
|
13
13
|
const tools = new Map();
|
|
14
|
-
function
|
|
15
|
-
const inputSchema = jsonSchemaFromZod(
|
|
14
|
+
function schemasFromZod(input, output) {
|
|
15
|
+
const inputSchema = jsonSchemaFromZod(input, 'input');
|
|
16
16
|
validateToolInputSchema(inputSchema);
|
|
17
|
-
const outputSchema = jsonSchemaFromZod(
|
|
17
|
+
const outputSchema = jsonSchemaFromZod(output, 'output');
|
|
18
18
|
validateToolOutputSchema(outputSchema);
|
|
19
|
-
return {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
return { inputSchema, outputSchema };
|
|
20
|
+
}
|
|
21
|
+
function normalizeHttp(def) {
|
|
22
|
+
return { ...def, type: 'http', ...schemasFromZod(def.input, def.output) };
|
|
23
|
+
}
|
|
24
|
+
function normalizeMcp(def) {
|
|
25
|
+
return { ...def, type: 'mcp', ...schemasFromZod(def.input, def.output) };
|
|
26
|
+
}
|
|
27
|
+
function normalizeFunction(def) {
|
|
28
|
+
return { ...def, type: 'function', ...schemasFromZod(def.input, def.output) };
|
|
25
29
|
}
|
|
26
30
|
function normalizeToolDefinition(def) {
|
|
27
31
|
if (def.type === 'builtin') {
|
|
28
32
|
return def;
|
|
29
33
|
}
|
|
34
|
+
if (def.type === 'http') {
|
|
35
|
+
return normalizeHttp(def);
|
|
36
|
+
}
|
|
37
|
+
if (def.type === 'mcp') {
|
|
38
|
+
return normalizeMcp(def);
|
|
39
|
+
}
|
|
30
40
|
return normalizeFunction(def);
|
|
31
41
|
}
|
|
32
42
|
/** Register or replace a tool definition. */
|
|
@@ -45,7 +55,7 @@ function getTool(name) {
|
|
|
45
55
|
function requireTool(name) {
|
|
46
56
|
const tool = getTool(name);
|
|
47
57
|
if (!tool) {
|
|
48
|
-
throw new TheorumError(`Tool '${name}' is not registered`);
|
|
58
|
+
throw new TheorumError(`Tool '${name}' is not registered`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
49
59
|
}
|
|
50
60
|
return tool;
|
|
51
61
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution runners for Declarative HTTP and Remote MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* - URL parameter substitution and query/body mapping
|
|
6
|
+
* - Network SSRF guardrail enforcement via `assertSafeUrl`
|
|
7
|
+
* - Credential resolution (bearer, api_key, oauth2)
|
|
8
|
+
* - Proactive OAuth token refresh with progress event emission
|
|
9
|
+
* - ToolGate { kind: 'auth' } emission or model error reporting
|
|
10
|
+
* - Streamable HTTP MCP JSON-RPC protocol (`tools/call`) per 2026-07-28 spec
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import type { TurnEvent } from '../types.js';
|
|
15
|
+
import { type ToolCallBase } from './events.js';
|
|
16
|
+
import { type ToolStageSupport } from './stage-run.js';
|
|
17
|
+
import type { HttpToolAuthConfig, HttpToolDef, McpToolDef, ModelToolResult, ToolBodyOutcome, ToolContext, ToolGate } from './types.js';
|
|
18
|
+
export type AuthResolveResult = {
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
unauthenticated?: boolean;
|
|
21
|
+
modelMessage?: string;
|
|
22
|
+
gate?: ToolGate;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Resolves credentials and handles missing/expired tokens.
|
|
26
|
+
* Yields TurnEvents for auth pauses or progress (e.g. refreshed tokens).
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveToolAuth(toolName: string, authConfig: HttpToolAuthConfig | undefined, ctx: ToolContext, base: ToolCallBase): AsyncGenerator<TurnEvent, AuthResolveResult>;
|
|
29
|
+
export type HttpToolMapping = NonNullable<HttpToolDef['mapping']>;
|
|
30
|
+
export type HttpToolTarget = {
|
|
31
|
+
url: string;
|
|
32
|
+
body?: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Build the request URL (and optional JSON body) for a declarative HTTP tool
|
|
36
|
+
* from endpoint template, mapping, and validated input.
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildHttpToolTarget(endpoint: string, method: HttpToolDef['method'], input: Record<string, unknown>, mapping?: HttpToolMapping): HttpToolTarget;
|
|
39
|
+
export declare function parseToolOutput<T>(schema: {
|
|
40
|
+
safeParse: (data: unknown) => {
|
|
41
|
+
success: true;
|
|
42
|
+
data: T;
|
|
43
|
+
} | {
|
|
44
|
+
success: false;
|
|
45
|
+
error: {
|
|
46
|
+
flatten: () => unknown;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}, responseData: unknown): {
|
|
50
|
+
success: true;
|
|
51
|
+
data: T;
|
|
52
|
+
} | {
|
|
53
|
+
success: false;
|
|
54
|
+
error: {
|
|
55
|
+
flatten: () => unknown;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export declare function modelResultFromOutput(data: unknown): ModelToolResult;
|
|
59
|
+
/**
|
|
60
|
+
* Executes a Declarative HTTP tool.
|
|
61
|
+
* Order: schema → permission → auth → preTool/host stages → body.
|
|
62
|
+
*/
|
|
63
|
+
export declare function executeHttpTool(tool: HttpToolDef, rawInput: unknown, ctx: ToolContext, base: ToolCallBase, stages?: ToolStageSupport): AsyncGenerator<TurnEvent, ToolBodyOutcome>;
|
|
64
|
+
/** Preferred-first Streamable HTTP protocol revisions the kernel will negotiate. */
|
|
65
|
+
export declare const MCP_PROTOCOL_VERSIONS: readonly ["2026-07-28", "2025-11-25", "2025-06-18", "2025-03-26"];
|
|
66
|
+
export type McpProtocolVersion = (typeof MCP_PROTOCOL_VERSIONS)[number];
|
|
67
|
+
export type McpRpcResponse = {
|
|
68
|
+
jsonrpc?: string;
|
|
69
|
+
id?: unknown;
|
|
70
|
+
result?: {
|
|
71
|
+
content?: Array<{
|
|
72
|
+
type: string;
|
|
73
|
+
text?: string;
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}>;
|
|
76
|
+
isError?: boolean;
|
|
77
|
+
[key: string]: unknown;
|
|
78
|
+
};
|
|
79
|
+
error?: {
|
|
80
|
+
code: number;
|
|
81
|
+
message: string;
|
|
82
|
+
data?: unknown;
|
|
83
|
+
};
|
|
84
|
+
method?: string;
|
|
85
|
+
};
|
|
86
|
+
/** Parse MCP JSON or SSE (`event: message` / `data:`) bodies into a JSON-RPC object. */
|
|
87
|
+
export declare function parseMcpRpcResponse(text: string): McpRpcResponse;
|
|
88
|
+
/** True when a JSON-RPC error indicates the server rejected our protocol revision. */
|
|
89
|
+
export declare function isUnsupportedMcpProtocolError(error: McpRpcResponse['error']): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Executes a Remote MCP tool over Streamable HTTP (spec revision 2026-07-28).
|
|
92
|
+
* Order: schema → permission → auth → preTool/host stages → body.
|
|
93
|
+
*/
|
|
94
|
+
export declare function executeMcpTool(tool: McpToolDef, rawInput: unknown, ctx: ToolContext, base: ToolCallBase, stages?: ToolStageSupport): AsyncGenerator<TurnEvent, ToolBodyOutcome>;
|