theorum 0.1.14 → 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/README.md +178 -89
- package/esm/mod.d.ts +21 -11
- package/esm/mod.js +15 -8
- package/esm/src/cli/commands/bench.js +6 -3
- package/esm/src/cli/commands/fuzz-canary.d.ts +13 -0
- package/esm/src/cli/commands/fuzz-canary.js +195 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +3 -5
- package/esm/src/cli/commands/fuzz-guardrails.js +4 -581
- package/esm/src/cli/commands/profile.js +25 -14
- package/esm/src/cli/commands/run.d.ts +3 -0
- package/esm/src/cli/commands/run.js +22 -30
- package/esm/src/cli/commands/test.d.ts +10 -1
- package/esm/src/cli/commands/test.js +31 -31
- package/esm/src/cli/event-log.d.ts +19 -0
- package/esm/src/cli/event-log.js +147 -0
- package/esm/src/cli/index.js +45 -11
- package/esm/src/cli/matrix/synthesizer.d.ts +7 -9
- package/esm/src/cli/matrix/synthesizer.js +32 -106
- package/esm/src/guardrails/canary-gate.d.ts +20 -0
- package/esm/src/guardrails/canary-gate.js +31 -0
- package/esm/src/guardrails/canary.d.ts +26 -0
- package/esm/src/guardrails/canary.js +139 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +16 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +151 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +11 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +216 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +10 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +124 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +20 -0
- package/esm/src/guardrails/corpus/live-attacks.js +232 -0
- package/esm/src/guardrails/corpus/mod.d.ts +13 -0
- package/esm/src/guardrails/corpus/mod.js +11 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +16 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +27 -0
- package/esm/src/guardrails/corpus/strings.js +33 -0
- package/esm/src/guardrails/corpus/types.d.ts +37 -0
- package/esm/src/guardrails/corpus/types.js +6 -0
- package/esm/src/guardrails/egress.d.ts +9 -0
- package/esm/src/guardrails/egress.js +36 -0
- package/esm/src/guardrails/error.js +6 -4
- package/esm/src/guardrails/injection.js +28 -5
- package/esm/src/guardrails/live-outbound-gate.d.ts +39 -0
- package/esm/src/guardrails/live-outbound-gate.js +180 -0
- package/esm/src/guardrails/mod.d.ts +13 -4
- package/esm/src/guardrails/mod.js +10 -4
- package/esm/src/guardrails/quota.js +1 -1
- package/esm/src/guardrails/sanitize.d.ts +11 -15
- package/esm/src/guardrails/sanitize.js +40 -49
- package/esm/src/guardrails/sensitive.js +2 -1
- package/esm/src/guardrails/testing.d.ts +10 -0
- package/esm/src/guardrails/testing.js +9 -0
- package/esm/src/host/client-turn.d.ts +19 -0
- package/esm/src/host/client-turn.js +32 -0
- package/esm/src/host/mod.d.ts +5 -3
- package/esm/src/host/mod.js +4 -3
- package/esm/src/interface/blocks.d.ts +20 -0
- package/esm/src/interface/blocks.js +180 -0
- package/esm/src/interface/from-profile.d.ts +14 -0
- package/esm/src/interface/from-profile.js +104 -0
- package/esm/src/interface/inputs.d.ts +8 -0
- package/esm/src/interface/inputs.js +127 -0
- package/esm/src/interface/mod.d.ts +10 -0
- package/esm/src/interface/mod.js +9 -0
- package/esm/src/interface/types.d.ts +153 -0
- package/esm/src/interface/types.js +13 -0
- package/esm/src/kernel/engine/delta.d.ts +24 -2
- package/esm/src/kernel/engine/delta.js +519 -29
- package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
- package/esm/src/kernel/engine/live-inbound.js +17 -0
- package/esm/src/kernel/engine/repair.js +1 -1
- package/esm/src/kernel/engine/runner/gates.d.ts +1 -1
- package/esm/src/kernel/engine/runner/gates.js +7 -7
- package/esm/src/kernel/engine/runner/mod.js +13 -13
- package/esm/src/kernel/engine/runner/state.d.ts +7 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +1 -1
- package/esm/src/kernel/engine/runner/steps.js +171 -37
- package/esm/src/kernel/engine/runner/stream.d.ts +1 -2
- package/esm/src/kernel/engine/runner/stream.js +66 -29
- package/esm/src/kernel/engine/session/mod.d.ts +23 -0
- package/esm/src/kernel/engine/session/mod.js +205 -0
- package/esm/src/kernel/mod.d.ts +9 -10
- package/esm/src/kernel/mod.js +6 -8
- package/esm/src/kernel/registry/attachments.d.ts +4 -2
- package/esm/src/kernel/registry/attachments.js +6 -3
- package/esm/src/kernel/registry/catalog.d.ts +3 -16
- package/esm/src/kernel/registry/catalog.js +5 -81
- package/esm/src/kernel/registry/ingress.d.ts +9 -4
- package/esm/src/kernel/registry/ingress.js +73 -63
- package/esm/src/kernel/registry/profiles.d.ts +35 -12
- package/esm/src/kernel/registry/profiles.js +159 -66
- package/esm/src/kernel/registry/provider-request.js +11 -7
- package/esm/src/kernel/registry/resolve.d.ts +5 -6
- package/esm/src/kernel/registry/resolve.js +100 -70
- package/esm/src/kernel/registry/vault.d.ts +12 -7
- package/esm/src/kernel/registry/vault.js +30 -8
- package/esm/src/kernel/schema.d.ts +145 -0
- package/esm/src/kernel/schema.js +462 -0
- package/esm/src/kernel/stop.d.ts +15 -10
- package/esm/src/kernel/stop.js +5 -5
- package/esm/src/kernel/tools/execute.d.ts +45 -0
- package/esm/src/kernel/tools/execute.js +363 -0
- package/esm/src/kernel/tools/harness.d.ts +8 -0
- package/esm/src/kernel/tools/harness.js +44 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +83 -0
- package/esm/src/kernel/tools/mod.d.ts +11 -0
- package/esm/src/kernel/tools/mod.js +10 -0
- package/esm/src/kernel/tools/project.d.ts +12 -0
- package/esm/src/kernel/tools/project.js +34 -0
- package/esm/src/kernel/tools/registry.d.ts +23 -0
- package/esm/src/kernel/tools/registry.js +71 -0
- package/esm/src/kernel/tools/resolve.d.ts +29 -0
- package/esm/src/kernel/tools/resolve.js +262 -0
- package/esm/src/kernel/tools/schema.d.ts +13 -0
- package/esm/src/kernel/tools/schema.js +159 -0
- package/esm/src/kernel/tools/types.d.ts +216 -0
- package/esm/src/kernel/tools/types.js +9 -0
- package/esm/src/kernel/types.d.ts +338 -193
- package/esm/src/observability/trace-attach.d.ts +6 -4
- package/esm/src/observability/trace-attach.js +39 -25
- package/esm/src/observability/trace-record.d.ts +11 -9
- package/esm/src/observability/trace-record.js +36 -23
- package/esm/src/observability/trace-usage.d.ts +10 -3
- package/esm/src/observability/trace-usage.js +70 -17
- package/esm/src/observability/trace.d.ts +9 -1
- package/esm/src/observability/trace.js +11 -3
- package/esm/src/presets/google/speech-voices.d.ts +11 -0
- package/esm/src/presets/google/speech-voices.js +41 -0
- package/esm/src/presets/google.d.ts +36 -24
- package/esm/src/presets/google.js +50 -63
- package/esm/src/presets/mod.d.ts +2 -2
- package/esm/src/presets/mod.js +1 -1
- package/esm/src/providers/create-provider.d.ts +14 -14
- package/esm/src/providers/create-provider.js +55 -23
- package/esm/src/providers/google/interactions/framing.d.ts +15 -0
- package/esm/src/providers/google/interactions/framing.js +208 -0
- package/esm/src/providers/google/interactions/mod.d.ts +7 -0
- package/esm/src/providers/google/interactions/mod.js +7 -0
- package/esm/src/providers/google/interactions/stream.d.ts +83 -0
- package/esm/src/providers/google/interactions/stream.js +588 -0
- package/esm/src/providers/google/keys.d.ts +26 -0
- package/esm/src/providers/{keys.js → google/keys.js} +19 -31
- package/esm/src/providers/google/live/framing.d.ts +46 -0
- package/esm/src/providers/google/live/framing.js +515 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +6 -0
- package/esm/src/providers/google/live/openapi-schema.js +45 -0
- package/esm/src/providers/google/live/session.d.ts +25 -0
- package/esm/src/providers/google/live/session.js +134 -0
- package/esm/src/providers/google/live/stream.d.ts +36 -0
- package/esm/src/providers/google/live/stream.js +201 -0
- package/esm/src/providers/google/urls.d.ts +6 -0
- package/esm/src/providers/google/urls.js +6 -0
- package/esm/src/providers/local/local.d.ts +30 -0
- package/esm/src/providers/{local.js → local/local.js} +66 -126
- package/esm/src/providers/local/mod.d.ts +9 -0
- package/esm/src/providers/local/mod.js +9 -0
- package/esm/src/providers/mod.d.ts +6 -3
- package/esm/src/providers/mod.js +3 -1
- package/esm/src/providers/openrouter/chat.d.ts +87 -0
- package/esm/src/providers/{openrouter.js → openrouter/chat.js} +70 -229
- package/esm/src/providers/openrouter/image.d.ts +34 -0
- package/esm/src/providers/openrouter/image.js +286 -0
- package/esm/src/providers/openrouter/openai/chat-payload.d.ts +24 -0
- package/esm/src/providers/openrouter/openai/chat-payload.js +60 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +47 -0
- package/esm/src/providers/openrouter/openai/compat.js +194 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +18 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +84 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +22 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +95 -0
- package/esm/src/providers/openrouter/resolve-api-key.d.ts +9 -0
- package/esm/src/providers/openrouter/resolve-api-key.js +24 -0
- package/esm/src/providers/openrouter/speech.d.ts +23 -0
- package/esm/src/providers/{speech.js → openrouter/speech.js} +32 -55
- package/esm/src/providers/probe.d.ts +1 -0
- package/esm/src/providers/probe.js +22 -0
- package/esm/src/providers/shared/pcm.d.ts +12 -0
- package/esm/src/providers/{pcm.js → shared/pcm.js} +16 -3
- package/esm/src/providers/shared/sse.d.ts +18 -0
- package/esm/src/providers/shared/sse.js +87 -0
- package/esm/src/providers/shared/tool-args.d.ts +17 -0
- package/esm/src/providers/shared/tool-args.js +45 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +5 -0
- package/esm/src/providers/{google-tap.js → shared/upstream-tap.js} +4 -7
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/{gemini-tape.js → shared/upstream-tape.js} +12 -22
- package/esm/src/providers/types.d.ts +27 -0
- package/esm/src/providers/types.js +1 -0
- package/package.json +11 -7
- package/docs/cli.md +0 -97
- package/docs/guardrails.md +0 -178
- package/docs/host.md +0 -97
- package/docs/kernel.md +0 -404
- package/docs/observability.md +0 -105
- package/docs/openrouter.md +0 -125
- package/docs/presets-google.md +0 -91
- package/docs/presets.md +0 -88
- package/docs/providers.md +0 -201
- package/docs/streaming.md +0 -96
- package/esm/src/kernel/engine/boundary.d.ts +0 -10
- package/esm/src/kernel/engine/boundary.js +0 -55
- package/esm/src/kernel/engine/runner/tools.d.ts +0 -13
- package/esm/src/kernel/engine/runner/tools.js +0 -198
- package/esm/src/kernel/registry/tools.d.ts +0 -12
- package/esm/src/kernel/registry/tools.js +0 -36
- package/esm/src/providers/expose-for-tests.d.ts +0 -1
- package/esm/src/providers/expose-for-tests.js +0 -25
- package/esm/src/providers/gemini-tape.d.ts +0 -2
- package/esm/src/providers/google-tap.d.ts +0 -3
- package/esm/src/providers/interactions.d.ts +0 -5
- package/esm/src/providers/interactions.js +0 -169
- package/esm/src/providers/keys.d.ts +0 -19
- package/esm/src/providers/local.d.ts +0 -29
- package/esm/src/providers/openrouter-mod.d.ts +0 -13
- package/esm/src/providers/openrouter-mod.js +0 -12
- package/esm/src/providers/openrouter-payload.d.ts +0 -39
- package/esm/src/providers/openrouter-payload.js +0 -195
- package/esm/src/providers/openrouter.d.ts +0 -15
- package/esm/src/providers/pcm.d.ts +0 -7
- package/esm/src/providers/provider.d.ts +0 -15
- package/esm/src/providers/provider.js +0 -176
- package/esm/src/providers/speech.d.ts +0 -23
- package/esm/src/providers/sse.d.ts +0 -7
- package/esm/src/providers/sse.js +0 -55
- package/esm/src/streaming/mod.d.ts +0 -9
- package/esm/src/streaming/mod.js +0 -8
- /package/esm/src/{streaming → host}/readStreamingJsonStringField.d.ts +0 -0
- /package/esm/src/{streaming → host}/readStreamingJsonStringField.js +0 -0
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Profile resolution for THEORUM turns.
|
|
3
3
|
*
|
|
4
|
-
* This module validates caller overrides, selects models and tools, normalizes
|
|
5
|
-
* input parts, and produces the provider request state consumed by `runTurn`.
|
|
6
|
-
*
|
|
7
4
|
* @module
|
|
8
5
|
*/
|
|
6
|
+
import { mintCanary } from '../../guardrails/canary.js';
|
|
9
7
|
import { TheorumError } from '../../guardrails/error.js';
|
|
10
8
|
import { sanitizeTurnRequest } from '../../guardrails/sanitize.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
9
|
+
import { projectTools } from '../tools/project.js';
|
|
10
|
+
import { resolveTurnTools } from '../tools/resolve.js';
|
|
11
|
+
import { clampThinkingLevel, requireModelSpec } from './catalog.js';
|
|
12
|
+
import { assertOutputMode, assertSpeechRole, resolveImageFormat, resolveInputParts, } from './ingress.js';
|
|
14
13
|
import { getProfile } from './profiles.js';
|
|
15
|
-
import {
|
|
16
|
-
function applyBuiltinMutualExclusions(requested) {
|
|
17
|
-
return requested.filter((id) => {
|
|
18
|
-
const conflicts = getTool(id)?.conflictsWith ?? [];
|
|
19
|
-
return !conflicts.some((other) => requested.includes(other));
|
|
20
|
-
});
|
|
21
|
-
}
|
|
14
|
+
import { providerUsesKeySlots, resolveKeySlot } from './vault.js';
|
|
22
15
|
function firstSelectKey(selectMap) {
|
|
23
16
|
const [key] = Object.keys(selectMap);
|
|
24
17
|
return key;
|
|
@@ -56,6 +49,9 @@ function pickModel(profile, select) {
|
|
|
56
49
|
return only;
|
|
57
50
|
}
|
|
58
51
|
function thinkingFromControl(spec, thinkingOn) {
|
|
52
|
+
if (!spec.thinking) {
|
|
53
|
+
throw new TheorumError('model.config thinking map is required when controls include thinking');
|
|
54
|
+
}
|
|
59
55
|
if (thinkingOn) {
|
|
60
56
|
return spec.thinking.on;
|
|
61
57
|
}
|
|
@@ -92,6 +88,9 @@ function resolveThinking(profile, spec, thinkingOn, select) {
|
|
|
92
88
|
return clampThinkingLevel(spec, raw);
|
|
93
89
|
}
|
|
94
90
|
function resolveSummaries(profile, spec, thinkingOn) {
|
|
91
|
+
if (!spec.summaries) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
95
94
|
if (profile.model.controls?.includes('thinking')) {
|
|
96
95
|
if (thinkingOn) {
|
|
97
96
|
return spec.summaries.on;
|
|
@@ -100,27 +99,8 @@ function resolveSummaries(profile, spec, thinkingOn) {
|
|
|
100
99
|
}
|
|
101
100
|
return spec.summaries.on;
|
|
102
101
|
}
|
|
103
|
-
function isGatedOn(requested, id) {
|
|
104
|
-
if (!requested) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
return requested[id] === true;
|
|
108
|
-
}
|
|
109
|
-
function resolveBuiltins(profile, requested) {
|
|
110
|
-
const allowed = profile.tools.allow.filter((id) => CATALOG.tools[id]?.kind === 'builtin');
|
|
111
|
-
const picked = listBuiltinIds().filter((id) => allowed.includes(id) && isGatedOn(requested, id));
|
|
112
|
-
return applyBuiltinMutualExclusions(picked);
|
|
113
|
-
}
|
|
114
|
-
function resolveCustom(profile, requested) {
|
|
115
|
-
return profile.tools.allow.filter((id) => CATALOG.tools[id]?.kind === 'custom' && isGatedOn(requested, id));
|
|
116
|
-
}
|
|
117
|
-
function assertToolAllowed(profile, name) {
|
|
118
|
-
if (!profile.tools.allow.includes(name)) {
|
|
119
|
-
throw new TheorumError(`Tool '${name}' is not allowed on ${profile.id}`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
102
|
function resolveStructured(profile, slots) {
|
|
123
|
-
const
|
|
103
|
+
const structured = profile.outputs?.structured;
|
|
124
104
|
if (!structured) {
|
|
125
105
|
return null;
|
|
126
106
|
}
|
|
@@ -136,76 +116,126 @@ function resolveStructured(profile, slots) {
|
|
|
136
116
|
}
|
|
137
117
|
return structured.fallback;
|
|
138
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* THEORUM prefers SSE when the host omits `outputs.streaming.mode`.
|
|
121
|
+
* Explicit `'buffered'` opts out; `'sse'` (or omit) yields `stream: true`.
|
|
122
|
+
*/
|
|
123
|
+
function resolveStreamFlag(profile) {
|
|
124
|
+
return profile.outputs?.streaming?.mode !== 'buffered';
|
|
125
|
+
}
|
|
126
|
+
function resolveStore(spec, reqStore) {
|
|
127
|
+
if (reqStore !== undefined) {
|
|
128
|
+
return reqStore;
|
|
129
|
+
}
|
|
130
|
+
return spec.store;
|
|
131
|
+
}
|
|
132
|
+
function assertTurnResumption(profile, req) {
|
|
133
|
+
if (!req.continueFrom) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (profile.type === 'live') {
|
|
137
|
+
throw new TheorumError(`Profile ${profile.id}: type 'live' uses live.sessionResumption, not turnResumption/continueFrom`);
|
|
138
|
+
}
|
|
139
|
+
const policy = profile.turnResumption;
|
|
140
|
+
const max = policy?.maxContinues;
|
|
141
|
+
if (max === undefined) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const attempt = req.continuation;
|
|
145
|
+
if (attempt === undefined) {
|
|
146
|
+
throw new TheorumError(`Profile ${profile.id}: continueFrom requires TurnRequest.continuation when turnResumption.maxContinues is set`);
|
|
147
|
+
}
|
|
148
|
+
if (attempt < 1) {
|
|
149
|
+
throw new TheorumError(`Profile ${profile.id}: continuation must be >= 1`);
|
|
150
|
+
}
|
|
151
|
+
if (attempt > max) {
|
|
152
|
+
throw new TheorumError(`Profile ${profile.id}: continuation ${attempt} exceeds turnResumption.maxContinues (${max})`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
139
155
|
/** Resolve a host `TurnRequest` into provider-ready generation state. */
|
|
140
156
|
function resolveTurn(req) {
|
|
141
157
|
const safe = sanitizeTurnRequest(req);
|
|
142
158
|
const input = safe.input ?? {};
|
|
143
159
|
const profile = getProfile(safe.profile);
|
|
160
|
+
assertTurnResumption(profile, safe);
|
|
144
161
|
const model = pickModel(profile, safe.select);
|
|
145
162
|
const spec = requireModelSpec(profile, model);
|
|
146
163
|
const thinkingOn = safe.thinking === true;
|
|
147
|
-
const
|
|
148
|
-
|
|
164
|
+
const toolSnapshot = resolveTurnTools(profile, safe, model);
|
|
165
|
+
const builtins = toolSnapshot.builtins;
|
|
166
|
+
const structured = resolveStructured(profile, input.slots);
|
|
167
|
+
assertOutputMode(profile, structured);
|
|
149
168
|
assertSpeechRole(profile);
|
|
150
|
-
const
|
|
151
|
-
|
|
169
|
+
const pinnedKey = profile.model.key ?? spec.key;
|
|
170
|
+
const keySlot = providerUsesKeySlots(profile.model.provider)
|
|
171
|
+
? resolveKeySlot(pinnedKey, spec, builtins, profile.model.provider === 'google')
|
|
152
172
|
: undefined;
|
|
173
|
+
const transport = profile.type === 'live'
|
|
174
|
+
? 'geminiLive'
|
|
175
|
+
: profile.model.protocol === 'geminiInteractions' && profile.model.provider === 'google'
|
|
176
|
+
? 'interactions'
|
|
177
|
+
: 'openAiCompat';
|
|
178
|
+
const previousInteractionId = spec.persistViaInteractionId === false ? undefined : safe.previousInteractionId;
|
|
153
179
|
return {
|
|
154
180
|
profile,
|
|
155
181
|
generation: {
|
|
156
182
|
model,
|
|
157
183
|
apiId: spec.apiId,
|
|
158
|
-
|
|
159
|
-
previousInteractionId
|
|
160
|
-
store: safe.store,
|
|
184
|
+
transport,
|
|
185
|
+
previousInteractionId,
|
|
186
|
+
store: resolveStore(spec, safe.store),
|
|
187
|
+
stream: resolveStreamFlag(profile),
|
|
161
188
|
thinking: resolveThinking(profile, spec, thinkingOn, safe.select),
|
|
162
189
|
summaries: resolveSummaries(profile, spec, thinkingOn),
|
|
163
190
|
maxOutputTokens: spec.maxOutputTokens,
|
|
164
191
|
temperature: spec.temperature,
|
|
165
192
|
builtins,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
dynamicToolLoader: safe.dynamicToolLoader,
|
|
193
|
+
googleMapsLocation: safe.googleMapsLocation,
|
|
194
|
+
tools: toolSnapshot,
|
|
169
195
|
sessionPermissions: safe.sessionPermissions,
|
|
170
196
|
history: input.history,
|
|
171
|
-
maxSteps: profile.model.maxSteps
|
|
172
|
-
structured
|
|
173
|
-
image: resolveImageFormat(profile
|
|
174
|
-
speech: profile.
|
|
197
|
+
maxSteps: profile.model.maxSteps,
|
|
198
|
+
structured,
|
|
199
|
+
image: resolveImageFormat(profile),
|
|
200
|
+
speech: profile.type === 'speech' ? profile.speech : undefined,
|
|
201
|
+
live: profile.type === 'live' ? profile.live : undefined,
|
|
175
202
|
input: resolveInputParts(profile, model, safe),
|
|
176
|
-
|
|
177
|
-
canary: profile.guardrails
|
|
203
|
+
keySlot,
|
|
204
|
+
canary: profile.guardrails?.canary === true ? mintCanary() : '',
|
|
205
|
+
sessionResumptionHandle: safe.sessionResumptionHandle ?? input.sessionResumptionHandle,
|
|
178
206
|
},
|
|
179
207
|
};
|
|
180
208
|
}
|
|
181
209
|
function primaryImageSpec(profile) {
|
|
182
|
-
return profile.
|
|
210
|
+
return profile.type === 'image' ? profile.image : null;
|
|
183
211
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
function profileInputsOrNull(profile) {
|
|
213
|
+
if (profile.type === 'speech') {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return profile.inputs ?? null;
|
|
217
|
+
}
|
|
218
|
+
/** Project a profile object into a safe host/UI inspection object. */
|
|
219
|
+
function projectProfileObject(profile) {
|
|
220
|
+
const { model, identity, outputs } = profile;
|
|
221
|
+
const inputs = profileInputsOrNull(profile);
|
|
191
222
|
return {
|
|
192
223
|
id: profile.id,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
select: select ?? null,
|
|
198
|
-
controls: controls ?? [],
|
|
199
|
-
tools: tools.allow.map((name) => ({
|
|
200
|
-
name,
|
|
201
|
-
...(CATALOG.tools[name] ?? { kind: 'custom', ui: true }),
|
|
202
|
-
})),
|
|
224
|
+
type: profile.type,
|
|
225
|
+
handle: identity.handle,
|
|
226
|
+
model,
|
|
227
|
+
tools: projectTools(profile),
|
|
203
228
|
inputs,
|
|
204
|
-
|
|
205
|
-
outputs,
|
|
229
|
+
outputs: outputs ?? null,
|
|
206
230
|
image: primaryImageSpec(profile),
|
|
231
|
+
speech: profile.type === 'speech' ? profile.speech : null,
|
|
232
|
+
live: profile.type === 'live' ? profile.live : null,
|
|
207
233
|
};
|
|
208
234
|
}
|
|
235
|
+
/** Project a registered profile into a safe host/UI inspection object. */
|
|
236
|
+
function projectProfile(id) {
|
|
237
|
+
return projectProfileObject(getProfile(id));
|
|
238
|
+
}
|
|
209
239
|
function pickSystemRole(profile, requested) {
|
|
210
240
|
const { identity } = profile;
|
|
211
241
|
const { handle, systemByRole } = identity;
|
|
@@ -214,4 +244,4 @@ function pickSystemRole(profile, requested) {
|
|
|
214
244
|
}
|
|
215
245
|
return handle;
|
|
216
246
|
}
|
|
217
|
-
export {
|
|
247
|
+
export { pickModel, pickSystemRole, projectProfile, projectProfileObject, resolveTurn };
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Host-owned policy over `ModelSpec.key` / `keyBuiltins`. Pure; no network.
|
|
2
|
+
* Vault key-slot selection for credentialed transports (Google, OpenRouter, …).
|
|
5
3
|
*
|
|
6
4
|
* @module
|
|
7
5
|
*/
|
|
8
|
-
import type { BuiltinToolId,
|
|
9
|
-
/**
|
|
10
|
-
declare function
|
|
11
|
-
|
|
6
|
+
import type { BuiltinToolId, KeySlot, ModelSpec, Provider } from '../types.js';
|
|
7
|
+
/** Providers that resolve a vault `keySlot` on each turn. */
|
|
8
|
+
export declare function providerUsesKeySlots(provider: Provider): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Pick the key slot for a turn from profile key, model pin, and enabled builtins.
|
|
11
|
+
*
|
|
12
|
+
* When `required` is false and nothing pins a slot, returns `undefined` so hosts
|
|
13
|
+
* can use a single flat `apiKey` (OpenRouter without a vault).
|
|
14
|
+
*/
|
|
15
|
+
declare function resolveKeySlot(profileKey: KeySlot | undefined, spec: ModelSpec, builtins: BuiltinToolId[], required: boolean): KeySlot | undefined;
|
|
16
|
+
export { resolveKeySlot };
|
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Host-owned policy over `ModelSpec.key` / `keyBuiltins`. Pure; no network.
|
|
2
|
+
* Vault key-slot selection for credentialed transports (Google, OpenRouter, …).
|
|
5
3
|
*
|
|
6
4
|
* @module
|
|
7
5
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { TheorumError } from '../../guardrails/error.js';
|
|
7
|
+
import { getTool } from '../tools/registry.js';
|
|
8
|
+
function builtinForcesPaid(id) {
|
|
9
|
+
const tool = getTool(id);
|
|
10
|
+
if (tool?.type !== 'builtin') {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return tool.forcePaidKey === true;
|
|
14
|
+
}
|
|
15
|
+
/** Providers that resolve a vault `keySlot` on each turn. */
|
|
16
|
+
export function providerUsesKeySlots(provider) {
|
|
17
|
+
return provider === 'google' || provider === 'openrouter';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pick the key slot for a turn from profile key, model pin, and enabled builtins.
|
|
21
|
+
*
|
|
22
|
+
* When `required` is false and nothing pins a slot, returns `undefined` so hosts
|
|
23
|
+
* can use a single flat `apiKey` (OpenRouter without a vault).
|
|
24
|
+
*/
|
|
25
|
+
function resolveKeySlot(profileKey, spec, builtins, required) {
|
|
10
26
|
if (spec.key) {
|
|
11
27
|
return spec.key;
|
|
12
28
|
}
|
|
13
|
-
if (builtins.some((id) =>
|
|
29
|
+
if (builtins.some((id) => builtinForcesPaid(id))) {
|
|
14
30
|
return 'paid';
|
|
15
31
|
}
|
|
16
|
-
|
|
32
|
+
if (profileKey) {
|
|
33
|
+
return profileKey;
|
|
34
|
+
}
|
|
35
|
+
if (required) {
|
|
36
|
+
throw new TheorumError('Profile must set model.key or model.config.*.key');
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
17
39
|
}
|
|
18
|
-
export {
|
|
40
|
+
export { resolveKeySlot };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime vocabulary and field catalog for THEORUM profile types.
|
|
3
|
+
*
|
|
4
|
+
* Closed unions live here as `as const` arrays; TypeScript types are derived
|
|
5
|
+
* from those arrays. Host UIs and docs import this module (no Deno APIs) so
|
|
6
|
+
* dropdowns and hover tips stay in lockstep with the kernel.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
/** Primary profile archetype. Discriminated union key for `ProfileDefinition` and `Profile`. */
|
|
11
|
+
export declare const PROFILE_TYPES: readonly ["text", "image", "speech", "live"];
|
|
12
|
+
export type ProfileType = (typeof PROFILE_TYPES)[number];
|
|
13
|
+
/** Model reasoning effort level normalized across provider adapters. */
|
|
14
|
+
export declare const THINKING_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
15
|
+
export type ThinkingLevel = (typeof THINKING_LEVELS)[number];
|
|
16
|
+
/** Wire protocol for a profile. */
|
|
17
|
+
export declare const PROTOCOLS: readonly ["geminiInteractions", "geminiLive", "openAi"];
|
|
18
|
+
export type Protocol = (typeof PROTOCOLS)[number];
|
|
19
|
+
/** Transport provider for a profile. */
|
|
20
|
+
export declare const PROVIDERS: readonly ["google", "openrouter", "local"];
|
|
21
|
+
export type Provider = (typeof PROVIDERS)[number];
|
|
22
|
+
/**
|
|
23
|
+
* Legal `createProvider` pairs. Keep this table in lockstep with the factory.
|
|
24
|
+
* Keys are protocols; values are the providers that protocol may bind.
|
|
25
|
+
*/
|
|
26
|
+
export declare const PROTOCOL_PROVIDERS: {
|
|
27
|
+
readonly geminiInteractions: readonly ["google"];
|
|
28
|
+
readonly geminiLive: readonly ["google"];
|
|
29
|
+
readonly openAi: readonly ["openrouter", "local"];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Legal wire protocols for each profile archetype.
|
|
33
|
+
* 'live' profiles require 'geminiLive'; turn-based archetypes require turn protocols.
|
|
34
|
+
*/
|
|
35
|
+
export declare const PROFILE_TYPE_PROTOCOLS: {
|
|
36
|
+
readonly text: readonly ["geminiInteractions", "openAi"];
|
|
37
|
+
readonly image: readonly ["geminiInteractions", "openAi"];
|
|
38
|
+
readonly speech: readonly ["geminiInteractions", "openAi"];
|
|
39
|
+
readonly live: readonly ["geminiLive"];
|
|
40
|
+
};
|
|
41
|
+
export type ProfileTypeProtocol<T extends ProfileType> = (typeof PROFILE_TYPE_PROTOCOLS)[T][number];
|
|
42
|
+
/** Protocols allowed for a profile archetype (`type`). */
|
|
43
|
+
export declare function protocolsForProfileType(type: ProfileType): readonly Protocol[];
|
|
44
|
+
/** True when the protocol is valid for the given profile archetype. */
|
|
45
|
+
export declare function isValidProfileProtocol(type: ProfileType, protocol: Protocol): boolean;
|
|
46
|
+
/** Named vault key slots for host-supplied credentials (provider-neutral). */
|
|
47
|
+
export declare const KEY_SLOTS: readonly ["slotA", "slotB", "slotC", "paid"];
|
|
48
|
+
export type KeySlot = (typeof KEY_SLOTS)[number];
|
|
49
|
+
/** Key slots that may overflow to `paid` after quota backoff. */
|
|
50
|
+
export declare const OVERFLOW_KEY_SLOTS: readonly ["slotA", "slotB", "slotC"];
|
|
51
|
+
export type OverflowKeySlot = (typeof OVERFLOW_KEY_SLOTS)[number];
|
|
52
|
+
/** Host vault: one optional credential string per key slot. */
|
|
53
|
+
export type KeyVault = Record<KeySlot, string | undefined>;
|
|
54
|
+
/** Profile-level control a caller may toggle at turn time. */
|
|
55
|
+
export declare const CONTROL_IDS: readonly ["thinking"];
|
|
56
|
+
export type ControlId = (typeof CONTROL_IDS)[number];
|
|
57
|
+
/** Normalized multimodal part category. */
|
|
58
|
+
export declare const MEDIA_INPUT_KIND_VALUES: readonly ["image", "audio", "video", "document"];
|
|
59
|
+
export type MediaInputKind = (typeof MEDIA_INPUT_KIND_VALUES)[number];
|
|
60
|
+
/** Provider thinking-summary behavior. */
|
|
61
|
+
export declare const SUMMARY_MODES: readonly ["auto", "none"];
|
|
62
|
+
export type SummaryMode = (typeof SUMMARY_MODES)[number];
|
|
63
|
+
/** Stream delivery mode. */
|
|
64
|
+
export declare const STREAM_MODES: readonly ["sse", "buffered"];
|
|
65
|
+
export type StreamMode = (typeof STREAM_MODES)[number];
|
|
66
|
+
/** Audio container for speech generation output. */
|
|
67
|
+
export declare const SPEECH_AUDIO_FORMATS: readonly ["pcm", "mp3"];
|
|
68
|
+
export type SpeechAudioFormat = (typeof SPEECH_AUDIO_FORMATS)[number];
|
|
69
|
+
/** Live session activity handling (barge-in behavior). */
|
|
70
|
+
export declare const LIVE_ACTIVITY_HANDLINGS: readonly ["START_OF_ACTIVITY_INTERRUPTS", "NO_INTERRUPTION"];
|
|
71
|
+
export type LiveActivityHandling = (typeof LIVE_ACTIVITY_HANDLINGS)[number];
|
|
72
|
+
/** Live session voice activity detection sensitivity. */
|
|
73
|
+
export declare const LIVE_SPEECH_SENSITIVITIES: readonly ["START_SENSITIVITY_LOW", "START_SENSITIVITY_HIGH", "END_SENSITIVITY_LOW", "END_SENSITIVITY_HIGH"];
|
|
74
|
+
export type LiveSpeechSensitivity = (typeof LIVE_SPEECH_SENSITIVITIES)[number];
|
|
75
|
+
/** Live session context window compression mode. */
|
|
76
|
+
export declare const LIVE_CONTEXT_COMPRESSIONS: readonly ["slidingWindow", "none"];
|
|
77
|
+
export type LiveContextCompression = (typeof LIVE_CONTEXT_COMPRESSIONS)[number];
|
|
78
|
+
/** Structured-output enforcement mode. */
|
|
79
|
+
export declare const SCHEMA_ENFORCEMENTS: readonly ["responseFormat", "prompt"];
|
|
80
|
+
export type SchemaEnforcement = (typeof SCHEMA_ENFORCEMENTS)[number];
|
|
81
|
+
/** Compaction threshold meter. */
|
|
82
|
+
export declare const COMPACTION_METERS: readonly ["history", "input"];
|
|
83
|
+
export type CompactionMeter = (typeof COMPACTION_METERS)[number];
|
|
84
|
+
/** When compaction runs relative to the primary turn. */
|
|
85
|
+
export declare const COMPACTION_TIMINGS: readonly ["before", "after"];
|
|
86
|
+
export type CompactionTiming = (typeof COMPACTION_TIMINGS)[number];
|
|
87
|
+
/** Egress block handling. */
|
|
88
|
+
export declare const EGRESS_ON_BLOCK: readonly ["reject_to_agent", "refuse_to_user"];
|
|
89
|
+
export type EgressOnBlock = (typeof EGRESS_ON_BLOCK)[number];
|
|
90
|
+
/** Why a turn ended (provider-neutral). */
|
|
91
|
+
export declare const TURN_STOP_KINDS: readonly ["completed", "length", "tool", "filtered", "provider_error", "cancelled", "stream_incomplete", "interrupted", "generation_complete"];
|
|
92
|
+
export type TurnStopKind = (typeof TURN_STOP_KINDS)[number];
|
|
93
|
+
/** Per-tool visibility tier — enforced by the kernel at resolve time. */
|
|
94
|
+
export declare const TOOL_LOAD_TIERS: readonly ["T0", "T1", "T2"];
|
|
95
|
+
export type ToolLoadTier = (typeof TOOL_LOAD_TIERS)[number];
|
|
96
|
+
/** Registered tool discriminant (`registerTool`). */
|
|
97
|
+
export declare const TOOL_TYPES: readonly ["builtin", "function"];
|
|
98
|
+
/** Semantic access level — host policy / UI; not enforced by execute. */
|
|
99
|
+
export declare const TOOL_ACCESS: readonly ["read-only", "read-write", "destructive"];
|
|
100
|
+
export type ToolAccess = (typeof TOOL_ACCESS)[number];
|
|
101
|
+
/** Execution authorization tier for registered tools. */
|
|
102
|
+
export declare const TOOL_PERMISSION: readonly ["auto", "session_consent", "always_confirm"];
|
|
103
|
+
export type ToolPermission = (typeof TOOL_PERMISSION)[number];
|
|
104
|
+
/** MIME essence → normalized media part category (shared ingress map). */
|
|
105
|
+
export declare const MEDIA_INPUT_KINDS: Record<string, MediaInputKind>;
|
|
106
|
+
/** Type-prefix wildcards accepted by `mimeAllowed`. */
|
|
107
|
+
export declare const MEDIA_WILDCARDS: readonly ["image/*", "audio/*", "video/*"];
|
|
108
|
+
/** Attachment `accept` values the kernel can classify (wildcards + known types). */
|
|
109
|
+
export declare const ATTACHMENT_ACCEPT_MIMES: readonly string[];
|
|
110
|
+
/** Voice `accept` values the kernel can classify (wildcard + known audio types). */
|
|
111
|
+
export declare const VOICE_ACCEPT_MIMES: readonly string[];
|
|
112
|
+
/** Providers allowed for a protocol. */
|
|
113
|
+
export declare function providersFor(protocol: Protocol): readonly Provider[];
|
|
114
|
+
/** Protocols allowed for a provider. */
|
|
115
|
+
export declare function protocolsFor(provider: Provider): readonly Protocol[];
|
|
116
|
+
/** True when `createProvider` will accept this pair. */
|
|
117
|
+
export declare function isValidPair(protocol: Protocol, provider: Provider): boolean;
|
|
118
|
+
/** When protocol changes, snap provider to a valid partner. */
|
|
119
|
+
export declare function coerceProvider(protocol: Protocol, provider: Provider): Provider;
|
|
120
|
+
/** When provider changes, snap protocol to a valid partner. */
|
|
121
|
+
export declare function coerceProtocol(protocol: Protocol, provider: Provider): Protocol;
|
|
122
|
+
/** Metadata for one profile (or adjacent) field, used by docs/UI hover. */
|
|
123
|
+
export type FieldMeta = {
|
|
124
|
+
type: string;
|
|
125
|
+
doc: string;
|
|
126
|
+
options?: readonly string[];
|
|
127
|
+
optionDescriptions?: Record<string, string>;
|
|
128
|
+
optionNote?: string;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Parents whose next key is a host-owned map key (model id, slot name, …).
|
|
132
|
+
* The annotator substitutes `*` so `model.config.flash.apiId` → `model.config.*.apiId`.
|
|
133
|
+
*/
|
|
134
|
+
export declare const DYNAMIC_FIELD_PARENTS: ReadonlySet<string>;
|
|
135
|
+
/** Resolve a key stack from authored source into a catalog path. */
|
|
136
|
+
export declare function catalogPathFor(keys: readonly string[]): string;
|
|
137
|
+
/**
|
|
138
|
+
* Authoring-surface catalog for `Profile` / `defineProfile`.
|
|
139
|
+
* Hover UIs look up dotted paths. Adding a profile field? Add it here.
|
|
140
|
+
*/
|
|
141
|
+
export declare const PROFILE_FIELDS: Record<string, FieldMeta>;
|
|
142
|
+
/** Adjacent tool catalog fields that appear next to profile examples. */
|
|
143
|
+
export declare const EXTRA_FIELDS: Record<string, FieldMeta>;
|
|
144
|
+
/** Look up hover metadata for a dotted path (profile first, then extra). */
|
|
145
|
+
export declare function fieldMeta(path: string): FieldMeta | undefined;
|