theorum 0.1.15 → 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 +241 -98
- package/esm/mod.d.ts +57 -28
- package/esm/mod.js +43 -23
- package/esm/src/cli/commands/bench.js +18 -18
- package/esm/src/cli/commands/fuzz-canary.d.ts +13 -0
- package/esm/src/cli/commands/fuzz-canary.js +191 -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/guardrails-eval.d.ts +14 -0
- package/esm/src/cli/commands/guardrails-eval.js +15 -0
- package/esm/src/cli/commands/profile.js +35 -15
- package/esm/src/cli/commands/run.d.ts +3 -0
- package/esm/src/cli/commands/run.js +23 -32
- package/esm/src/cli/commands/test.d.ts +10 -1
- package/esm/src/cli/commands/test.js +34 -34
- 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 +57 -11
- package/esm/src/cli/matrix/synthesizer.d.ts +10 -12
- package/esm/src/cli/matrix/synthesizer.js +45 -118
- package/esm/src/guardrails/canary-gate.d.ts +21 -0
- package/esm/src/guardrails/canary-gate.js +32 -0
- package/esm/src/guardrails/canary.d.ts +34 -0
- package/esm/src/guardrails/canary.js +150 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +17 -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 +213 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +10 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +125 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +20 -0
- package/esm/src/guardrails/corpus/live-attacks.js +231 -0
- package/esm/src/guardrails/corpus/mod.d.ts +14 -0
- package/esm/src/guardrails/corpus/mod.js +11 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +17 -0
- package/esm/src/guardrails/corpus/secrets.js +17 -0
- package/esm/src/guardrails/corpus/strings.d.ts +28 -0
- package/esm/src/guardrails/corpus/strings.js +34 -0
- package/esm/src/guardrails/corpus/types.d.ts +38 -0
- package/esm/src/guardrails/corpus/types.js +6 -0
- package/esm/src/guardrails/egress.d.ts +32 -0
- package/esm/src/guardrails/egress.js +87 -0
- package/esm/src/guardrails/error.d.ts +14 -23
- package/esm/src/guardrails/error.js +87 -76
- 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/injection.js +28 -5
- 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 +41 -0
- package/esm/src/guardrails/live-outbound-gate.js +222 -0
- package/esm/src/guardrails/mod.d.ts +30 -6
- package/esm/src/guardrails/mod.js +20 -5
- 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 +45 -19
- package/esm/src/guardrails/sanitize.js +177 -94
- package/esm/src/guardrails/sensitive.js +2 -1
- package/esm/src/guardrails/serialize.d.ts +35 -0
- package/esm/src/guardrails/serialize.js +58 -0
- package/esm/src/guardrails/testing.d.ts +17 -0
- package/esm/src/guardrails/testing.js +13 -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.d.ts +19 -0
- package/esm/src/host/client-turn.js +36 -0
- package/esm/src/host/mint-trace.d.ts +1 -1
- package/esm/src/host/mod.d.ts +5 -3
- package/esm/src/host/mod.js +4 -3
- 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.d.ts +24 -2
- package/esm/src/kernel/engine/delta.js +478 -39
- package/esm/src/kernel/engine/live-inbound.d.ts +21 -0
- package/esm/src/kernel/engine/live-inbound.js +31 -0
- 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.d.ts +1 -1
- package/esm/src/kernel/engine/runner/gates.js +130 -43
- package/esm/src/kernel/engine/runner/mod.d.ts +6 -4
- package/esm/src/kernel/engine/runner/mod.js +192 -53
- 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 +31 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +1 -1
- package/esm/src/kernel/engine/runner/steps.js +244 -43
- package/esm/src/kernel/engine/runner/stream.d.ts +9 -3
- package/esm/src/kernel/engine/runner/stream.js +140 -44
- package/esm/src/kernel/engine/session/mod.d.ts +25 -0
- package/esm/src/kernel/engine/session/mod.js +557 -0
- 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 +21 -10
- package/esm/src/kernel/mod.js +11 -8
- 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 +12 -10
- package/esm/src/kernel/registry/attachments.js +33 -27
- package/esm/src/kernel/registry/catalog.d.ts +25 -24
- package/esm/src/kernel/registry/catalog.js +60 -101
- package/esm/src/kernel/registry/ingress.d.ts +9 -4
- package/esm/src/kernel/registry/ingress.js +97 -75
- 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 +55 -12
- package/esm/src/kernel/registry/profiles.js +413 -73
- package/esm/src/kernel/registry/provider-request.js +13 -7
- package/esm/src/kernel/registry/resolve.d.ts +8 -8
- package/esm/src/kernel/registry/resolve.js +169 -154
- 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 +12 -7
- package/esm/src/kernel/registry/vault.js +32 -10
- package/esm/src/kernel/schema.d.ts +231 -0
- package/esm/src/kernel/schema.js +607 -0
- package/esm/src/kernel/stages.d.ts +175 -0
- package/esm/src/kernel/stages.js +476 -0
- package/esm/src/kernel/stop.d.ts +78 -19
- package/esm/src/kernel/stop.js +51 -16
- 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 +84 -0
- package/esm/src/kernel/tools/execute.js +614 -0
- package/esm/src/kernel/tools/harness.d.ts +8 -0
- package/esm/src/kernel/tools/harness.js +46 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +101 -0
- package/esm/src/kernel/tools/mod.d.ts +13 -0
- package/esm/src/kernel/tools/mod.js +11 -0
- 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.d.ts +12 -0
- package/esm/src/kernel/tools/project.js +36 -0
- package/esm/src/kernel/tools/registry.d.ts +23 -0
- package/esm/src/kernel/tools/registry.js +81 -0
- 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 +39 -0
- package/esm/src/kernel/tools/resolve.js +283 -0
- package/esm/src/kernel/tools/schema.d.ts +15 -0
- package/esm/src/kernel/tools/schema.js +176 -0
- 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 +394 -0
- package/esm/src/kernel/tools/types.js +9 -0
- package/esm/src/kernel/types.d.ts +540 -256
- 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 +8 -4
- package/esm/src/observability/trace-attach.js +50 -29
- package/esm/src/observability/trace-record.d.ts +23 -13
- package/esm/src/observability/trace-record.js +96 -39
- package/esm/src/observability/trace-sink.d.ts +19 -0
- package/esm/src/observability/trace-sink.js +10 -0
- 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 +18 -7
- package/esm/src/observability/trace.js +34 -17
- package/esm/src/observability/types.d.ts +113 -0
- package/esm/src/observability/types.js +11 -0
- 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 +20 -17
- package/esm/src/providers/create-provider.js +72 -26
- package/esm/src/providers/google/interactions/framing.d.ts +23 -0
- package/esm/src/providers/google/interactions/framing.js +269 -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 +49 -0
- package/esm/src/providers/google/live/framing.js +552 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +6 -0
- package/esm/src/providers/google/live/openapi-schema.js +46 -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 +45 -0
- package/esm/src/providers/google/live/stream.js +214 -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/cache-control.d.ts +24 -0
- package/esm/src/providers/openrouter/cache-control.js +23 -0
- package/esm/src/providers/openrouter/chat.d.ts +107 -0
- package/esm/src/providers/{openrouter.js → openrouter/chat.js} +117 -231
- package/esm/src/providers/openrouter/image.d.ts +34 -0
- package/esm/src/providers/openrouter/image.js +275 -0
- package/esm/src/providers/openrouter/openai/chat-payload.d.ts +24 -0
- package/esm/src/providers/openrouter/openai/chat-payload.js +82 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +53 -0
- package/esm/src/providers/openrouter/openai/compat.js +213 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +18 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +90 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +22 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +122 -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 -202
- 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 -202
- 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,126 +1,83 @@
|
|
|
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';
|
|
8
|
+
import { resolveGuardrailPolicy } from '../../guardrails/policy.js';
|
|
10
9
|
import { sanitizeTurnRequest } from '../../guardrails/sanitize.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { profileTurnResumption } from '../stop.js';
|
|
11
|
+
import { projectTools } from '../tools/project.js';
|
|
12
|
+
import { resolveTurnTools } from '../tools/resolve.js';
|
|
13
|
+
import { requireModelBinding } from './catalog.js';
|
|
14
|
+
import { assertOutputMode, assertSpeechRole, resolveImageFormat, resolveInputParts, } from './ingress.js';
|
|
14
15
|
import { getProfile } from './profiles.js';
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
let key = select;
|
|
32
|
-
if (!key) {
|
|
33
|
-
key = firstSelectKey(selectMap);
|
|
34
|
-
}
|
|
35
|
-
if (!key) {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
return selectMap[key];
|
|
39
|
-
}
|
|
40
|
-
function pickModel(profile, select) {
|
|
41
|
-
if (profile.model.select) {
|
|
42
|
-
const id = lookupSelectId(profile, select);
|
|
43
|
-
if (!(id && profile.model.allow.includes(id))) {
|
|
44
|
-
let label = '';
|
|
45
|
-
if (select) {
|
|
46
|
-
label = select;
|
|
47
|
-
}
|
|
48
|
-
throw new TheorumError(`Unknown model select '${label}' for ${profile.id}`);
|
|
16
|
+
import { soleModelId } from './sole-model.js';
|
|
17
|
+
import { resolveTurnSystemPrompt } from './system-prompt.js';
|
|
18
|
+
import { providerUsesKeySlots, resolveKeySlot } from './vault.js';
|
|
19
|
+
/** Narrow to a model-binding profile; `host` never runs a model. */
|
|
20
|
+
function requireModelProfile(profile, door) {
|
|
21
|
+
if (profile.type === 'host') {
|
|
22
|
+
throw new TheorumError(`Profile ${profile.id}: type 'host' never runs a model — ${door} is not supported; execute tools with invokeTool`);
|
|
23
|
+
}
|
|
24
|
+
return profile;
|
|
25
|
+
}
|
|
26
|
+
function pickModel(profile, requested) {
|
|
27
|
+
if (requested) {
|
|
28
|
+
if (!profile.allowModelSelect) {
|
|
29
|
+
throw new TheorumError(`Profile ${profile.id} does not allow model selection`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
49
30
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
throw new TheorumError(`Profile ${profile.id} has no models`);
|
|
31
|
+
if (!profile.models[requested]) {
|
|
32
|
+
throw new TheorumError(`Unknown model '${requested}' for ${profile.id}`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
33
|
+
}
|
|
34
|
+
return requested;
|
|
55
35
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (thinkingOn) {
|
|
60
|
-
return spec.thinking.on;
|
|
36
|
+
const defaultId = profile.defaultModel ?? soleModelId(profile.models);
|
|
37
|
+
if (!defaultId || !profile.models[defaultId]) {
|
|
38
|
+
throw new TheorumError(`Profile ${profile.id} has no default model`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
61
39
|
}
|
|
62
|
-
return
|
|
40
|
+
return defaultId;
|
|
63
41
|
}
|
|
64
|
-
function
|
|
65
|
-
|
|
42
|
+
function resolveEffort(profile, binding, modelId, requested) {
|
|
43
|
+
const efforts = binding.efforts;
|
|
44
|
+
if (!efforts || Object.keys(efforts).length === 0) {
|
|
45
|
+
if (requested) {
|
|
46
|
+
throw new TheorumError(`Profile ${profile.id} model '${modelId}' has no selectable efforts`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
47
|
+
}
|
|
66
48
|
return undefined;
|
|
67
49
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (typeof pinned === 'string') {
|
|
73
|
-
return pinned;
|
|
74
|
-
}
|
|
75
|
-
if (!pinned) {
|
|
76
|
-
throw new TheorumError(`Profile ${profile.id} must pin thinking or list it in controls`);
|
|
77
|
-
}
|
|
78
|
-
const fromSelect = pinnedLevel(pinned, select);
|
|
79
|
-
if (fromSelect) {
|
|
80
|
-
return fromSelect;
|
|
81
|
-
}
|
|
82
|
-
const fromFirst = pinnedLevel(pinned, firstSelectKey(profile.model.select ?? {}));
|
|
83
|
-
if (fromFirst) {
|
|
84
|
-
return fromFirst;
|
|
85
|
-
}
|
|
86
|
-
throw new TheorumError(`Profile ${profile.id} must pin thinking or list it in controls`);
|
|
87
|
-
}
|
|
88
|
-
function resolveThinking(profile, spec, thinkingOn, select) {
|
|
89
|
-
const raw = profile.model.controls?.includes('thinking')
|
|
90
|
-
? thinkingFromControl(spec, thinkingOn)
|
|
91
|
-
: thinkingFromPin(profile, select);
|
|
92
|
-
return clampThinkingLevel(spec, raw);
|
|
93
|
-
}
|
|
94
|
-
function resolveSummaries(profile, spec, thinkingOn) {
|
|
95
|
-
if (profile.model.controls?.includes('thinking')) {
|
|
96
|
-
if (thinkingOn) {
|
|
97
|
-
return spec.summaries.on;
|
|
50
|
+
const keys = Object.keys(efforts);
|
|
51
|
+
if (requested) {
|
|
52
|
+
if (!binding.allowEffortSelect) {
|
|
53
|
+
throw new TheorumError(`Profile ${profile.id} model '${modelId}' does not allow effort selection`);
|
|
98
54
|
}
|
|
99
|
-
|
|
55
|
+
const level = efforts[requested];
|
|
56
|
+
if (!level) {
|
|
57
|
+
throw new TheorumError(`Unknown effort '${requested}' for ${profile.id} model '${modelId}'`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
58
|
+
}
|
|
59
|
+
return level;
|
|
100
60
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!requested) {
|
|
105
|
-
return false;
|
|
61
|
+
const alias = binding.defaultEffort ?? (keys.length === 1 ? keys[0] : undefined);
|
|
62
|
+
if (!alias) {
|
|
63
|
+
throw new TheorumError(`Profile ${profile.id} model '${modelId}' must set defaultEffort when more than one effort is declared`);
|
|
106
64
|
}
|
|
107
|
-
return
|
|
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));
|
|
65
|
+
return efforts[alias];
|
|
116
66
|
}
|
|
117
|
-
function
|
|
118
|
-
if (
|
|
119
|
-
|
|
67
|
+
function resolveSummaries(binding) {
|
|
68
|
+
if (binding.summaries === true) {
|
|
69
|
+
return 'auto';
|
|
120
70
|
}
|
|
71
|
+
if (binding.summaries === false) {
|
|
72
|
+
return 'none';
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
121
75
|
}
|
|
122
76
|
function resolveStructured(profile, slots) {
|
|
123
|
-
|
|
77
|
+
if (profile.type === 'live') {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const structured = profile.outputs?.structured;
|
|
124
81
|
if (!structured) {
|
|
125
82
|
return null;
|
|
126
83
|
}
|
|
@@ -136,82 +93,140 @@ function resolveStructured(profile, slots) {
|
|
|
136
93
|
}
|
|
137
94
|
return structured.fallback;
|
|
138
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* THEORUM prefers SSE when the host omits `outputs.streaming.mode`.
|
|
98
|
+
* Explicit `'buffered'` opts out; `'sse'` (or omit) yields `stream: true`.
|
|
99
|
+
*/
|
|
100
|
+
function resolveStreamFlag(profile) {
|
|
101
|
+
if (profile.type === 'live') {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return profile.outputs?.streaming?.mode !== 'buffered';
|
|
105
|
+
}
|
|
106
|
+
function resolveStore(binding, reqStore) {
|
|
107
|
+
if (reqStore !== undefined) {
|
|
108
|
+
return reqStore;
|
|
109
|
+
}
|
|
110
|
+
return binding.store;
|
|
111
|
+
}
|
|
112
|
+
function resolveTransport(profile, binding) {
|
|
113
|
+
if (profile.type === 'live') {
|
|
114
|
+
return 'geminiLive';
|
|
115
|
+
}
|
|
116
|
+
if (binding.protocol === 'geminiInteractions' && binding.provider === 'google') {
|
|
117
|
+
return 'interactions';
|
|
118
|
+
}
|
|
119
|
+
return 'openAiCompat';
|
|
120
|
+
}
|
|
121
|
+
function assertTurnResumption(profile, req) {
|
|
122
|
+
if (!req.continueFrom) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (profile.type === 'live') {
|
|
126
|
+
throw new TheorumError(`Profile ${profile.id}: type 'live' uses live.sessionResumption, not turnBehaviour.resumption/continueFrom`);
|
|
127
|
+
}
|
|
128
|
+
const policy = profileTurnResumption(profile);
|
|
129
|
+
const max = policy?.maxContinues;
|
|
130
|
+
if (max === undefined) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const attempt = req.continuation;
|
|
134
|
+
if (attempt === undefined) {
|
|
135
|
+
throw new TheorumError(`Profile ${profile.id}: continueFrom requires TurnRequest.continuation when turnBehaviour.resumption.maxContinues is set`);
|
|
136
|
+
}
|
|
137
|
+
if (attempt < 1) {
|
|
138
|
+
throw new TheorumError(`Profile ${profile.id}: continuation must be >= 1`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
139
|
+
}
|
|
140
|
+
if (attempt > max) {
|
|
141
|
+
throw new TheorumError(`Profile ${profile.id}: continuation ${attempt} exceeds turnBehaviour.resumption.maxContinues (${max})`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
139
144
|
/** Resolve a host `TurnRequest` into provider-ready generation state. */
|
|
140
145
|
function resolveTurn(req) {
|
|
141
146
|
const safe = sanitizeTurnRequest(req);
|
|
142
147
|
const input = safe.input ?? {};
|
|
143
|
-
const profile = getProfile(safe.profile);
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
|
|
148
|
+
const profile = requireModelProfile(getProfile(safe.profile), 'resolveTurn');
|
|
149
|
+
assertTurnResumption(profile, safe);
|
|
150
|
+
const model = pickModel(profile, safe.model);
|
|
151
|
+
const binding = requireModelBinding(profile, model);
|
|
152
|
+
const toolSnapshot = resolveTurnTools(profile, safe, model);
|
|
153
|
+
const builtins = toolSnapshot.builtins;
|
|
154
|
+
const structured = resolveStructured(profile, input.slots);
|
|
155
|
+
assertOutputMode(profile, structured);
|
|
149
156
|
assertSpeechRole(profile);
|
|
150
|
-
const
|
|
151
|
-
|
|
157
|
+
const pinnedKey = profile.key ?? binding.key;
|
|
158
|
+
const keySlot = providerUsesKeySlots(binding.provider)
|
|
159
|
+
? resolveKeySlot(pinnedKey, binding, builtins, binding.provider === 'google')
|
|
152
160
|
: undefined;
|
|
161
|
+
const previousInteractionId = binding.persistViaInteractionId === false ? undefined : safe.previousInteractionId;
|
|
153
162
|
return {
|
|
154
163
|
profile,
|
|
155
164
|
generation: {
|
|
156
165
|
model,
|
|
157
|
-
apiId:
|
|
158
|
-
|
|
159
|
-
previousInteractionId
|
|
160
|
-
store: safe.store,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
apiId: binding.apiId,
|
|
167
|
+
transport: resolveTransport(profile, binding),
|
|
168
|
+
previousInteractionId,
|
|
169
|
+
store: resolveStore(binding, safe.store),
|
|
170
|
+
stream: resolveStreamFlag(profile),
|
|
171
|
+
thinking: resolveEffort(profile, binding, model, safe.effort),
|
|
172
|
+
summaries: resolveSummaries(binding),
|
|
173
|
+
maxOutputTokens: binding.maxOutputTokens,
|
|
174
|
+
temperature: binding.temperature,
|
|
165
175
|
builtins,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
googleMapsLocation: safe.googleMapsLocation,
|
|
177
|
+
cache: binding.cache,
|
|
178
|
+
sessionId: safe.sessionId,
|
|
179
|
+
tools: toolSnapshot,
|
|
169
180
|
sessionPermissions: safe.sessionPermissions,
|
|
170
181
|
history: input.history,
|
|
171
|
-
maxSteps: profile.
|
|
172
|
-
structured
|
|
173
|
-
image: resolveImageFormat(profile
|
|
174
|
-
speech: profile.
|
|
182
|
+
maxSteps: profile.maxSteps,
|
|
183
|
+
structured,
|
|
184
|
+
image: resolveImageFormat(profile),
|
|
185
|
+
speech: profile.type === 'speech' ? profile.speech : undefined,
|
|
186
|
+
live: profile.type === 'live' ? profile.live : undefined,
|
|
175
187
|
input: resolveInputParts(profile, model, safe),
|
|
176
|
-
|
|
177
|
-
canary: profile.guardrails.canary
|
|
188
|
+
keySlot,
|
|
189
|
+
canary: resolveGuardrailPolicy(profile.guardrails).canary ? mintCanary() : '',
|
|
190
|
+
sessionResumptionHandle: safe.sessionResumptionHandle ?? input.sessionResumptionHandle,
|
|
191
|
+
resolvedSystem: resolveTurnSystemPrompt(profile, safe),
|
|
192
|
+
host: safe.host,
|
|
178
193
|
},
|
|
179
194
|
};
|
|
180
195
|
}
|
|
181
196
|
function primaryImageSpec(profile) {
|
|
182
|
-
return profile.
|
|
197
|
+
return profile.type === 'image' ? profile.image : null;
|
|
183
198
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
199
|
+
function profileInputsOrNull(profile) {
|
|
200
|
+
if (profile.type === 'speech' || profile.type === 'live') {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return profile.inputs ?? null;
|
|
204
|
+
}
|
|
205
|
+
/** Project a profile object into a safe host/UI inspection object. */
|
|
206
|
+
function projectProfileObject(input) {
|
|
207
|
+
const profile = requireModelProfile(input, 'projectProfile');
|
|
208
|
+
const { identity } = profile;
|
|
209
|
+
const inputs = profileInputsOrNull(profile);
|
|
210
|
+
const outputs = profile.type === 'live' ? null : (profile.outputs ?? null);
|
|
191
211
|
return {
|
|
192
212
|
id: profile.id,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
...(CATALOG.tools[name] ?? { kind: 'custom', ui: true }),
|
|
202
|
-
})),
|
|
213
|
+
type: profile.type,
|
|
214
|
+
handle: identity.handle,
|
|
215
|
+
models: profile.models,
|
|
216
|
+
defaultModel: profile.defaultModel,
|
|
217
|
+
allowModelSelect: profile.allowModelSelect,
|
|
218
|
+
maxSteps: profile.maxSteps,
|
|
219
|
+
key: profile.key,
|
|
220
|
+
tools: projectTools(profile),
|
|
203
221
|
inputs,
|
|
204
|
-
slots: slots ?? {},
|
|
205
222
|
outputs,
|
|
206
223
|
image: primaryImageSpec(profile),
|
|
224
|
+
speech: profile.type === 'speech' ? profile.speech : null,
|
|
225
|
+
live: profile.type === 'live' ? profile.live : null,
|
|
207
226
|
};
|
|
208
227
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (requested && systemByRole && Object.hasOwn(systemByRole, requested)) {
|
|
213
|
-
return requested;
|
|
214
|
-
}
|
|
215
|
-
return handle;
|
|
228
|
+
/** Project a registered profile into a safe host/UI inspection object. */
|
|
229
|
+
function projectProfile(id) {
|
|
230
|
+
return projectProfileObject(getProfile(id));
|
|
216
231
|
}
|
|
217
|
-
export {
|
|
232
|
+
export { pickModel, projectProfile, projectProfileObject, requireModelProfile, resolveTurn };
|
|
@@ -16,7 +16,7 @@ function registerStructured(id, spec) {
|
|
|
16
16
|
function getStructured(id) {
|
|
17
17
|
const spec = schemas.get(id);
|
|
18
18
|
if (!spec) {
|
|
19
|
-
throw new TheorumError(`Unknown structured schema '${id}'`);
|
|
19
|
+
throw new TheorumError(`Unknown structured schema '${id}'`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
20
20
|
}
|
|
21
21
|
return spec;
|
|
22
22
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared model-id helpers for profile registration and resolution.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { ModelBinding, ModelId } from '../types.js';
|
|
7
|
+
/** When exactly one model is declared, that id is the implicit default. */
|
|
8
|
+
export declare function soleModelId(models: Record<ModelId, ModelBinding>): ModelId | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared model-id helpers for profile registration and resolution.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/** When exactly one model is declared, that id is the implicit default. */
|
|
7
|
+
export function soleModelId(models) {
|
|
8
|
+
const ids = Object.keys(models);
|
|
9
|
+
return ids.length === 1 ? ids[0] : undefined;
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous system-prompt resolution for a turn or session.
|
|
3
|
+
* Snapshotted in `resolveTurn` before any async work — never mutate registry per request.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { ModelProfile, TurnRequest } from '../types.js';
|
|
8
|
+
/** Merge profile + host turn system synchronously at resolve time. */
|
|
9
|
+
declare function resolveTurnSystemPrompt(profile: ModelProfile, req: TurnRequest): string;
|
|
10
|
+
export { resolveTurnSystemPrompt };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Synchronous system-prompt resolution for a turn or session.
|
|
3
|
+
* Snapshotted in `resolveTurn` before any async work — never mutate registry per request.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { lexiconText } from '../../guardrails/lexicon.js';
|
|
8
|
+
import { detectionForTrust, resolveGuardrailPolicy } from '../../guardrails/policy.js';
|
|
9
|
+
import { sanitizeText } from '../../guardrails/sanitize.js';
|
|
10
|
+
import { profileTurnResumption } from '../stop.js';
|
|
11
|
+
import { pickSystemRole } from './system-role.js';
|
|
12
|
+
/**
|
|
13
|
+
* Author-time system text for a role (handle or `systemByRole`).
|
|
14
|
+
*
|
|
15
|
+
* Routed through the guardrail policy at `trust: 'trusted'` so the exemption is
|
|
16
|
+
* declared at the point it applies rather than implied by never calling the
|
|
17
|
+
* sanitizer. Trusted resolves to no detection, so the text reaches the provider
|
|
18
|
+
* verbatim — `req.system`, which the host assembles per turn, is handled as
|
|
19
|
+
* `assembled` in `sanitizeTurnRequest` and is not exempt.
|
|
20
|
+
*/
|
|
21
|
+
function systemFromProfile(profile, role) {
|
|
22
|
+
const { identity } = profile;
|
|
23
|
+
const { systemByRole, system } = identity;
|
|
24
|
+
const text = systemByRole?.[role] || system || '';
|
|
25
|
+
if (!text) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
const policy = resolveGuardrailPolicy(profile.guardrails);
|
|
29
|
+
return sanitizeText(text, detectionForTrust(policy, 'trusted'));
|
|
30
|
+
}
|
|
31
|
+
/** Merge profile + host turn system synchronously at resolve time. */
|
|
32
|
+
function resolveTurnSystemPrompt(profile, req) {
|
|
33
|
+
const role = pickSystemRole(profile, req.input?.role);
|
|
34
|
+
// Profile override wins; otherwise the registered lexicon default.
|
|
35
|
+
const continueSys = req.continueFrom
|
|
36
|
+
? lexiconText('continue.instruction', {}, profileTurnResumption(profile)?.continueInstruction)
|
|
37
|
+
: '';
|
|
38
|
+
return [systemFromProfile(profile, role), req.system, continueSys].filter(Boolean).join('\n\n');
|
|
39
|
+
}
|
|
40
|
+
export { resolveTurnSystemPrompt };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve which `systemByRole` key (or handle) applies for a turn.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
function pickSystemRole(profile, requested) {
|
|
7
|
+
const { identity } = profile;
|
|
8
|
+
const { handle, systemByRole } = identity;
|
|
9
|
+
if (requested && systemByRole && Object.hasOwn(systemByRole, requested)) {
|
|
10
|
+
return requested;
|
|
11
|
+
}
|
|
12
|
+
return handle;
|
|
13
|
+
}
|
|
14
|
+
export { pickSystemRole };
|
|
@@ -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, ModelBinding, 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, binding: ModelBinding, 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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
12
|
}
|
|
13
|
-
|
|
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, binding, builtins, required) {
|
|
26
|
+
if (binding.key) {
|
|
27
|
+
return binding.key;
|
|
28
|
+
}
|
|
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 key or models.*.key'); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
17
39
|
}
|
|
18
|
-
export {
|
|
40
|
+
export { resolveKeySlot };
|