theorum 0.1.13 → 0.1.14

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.
@@ -0,0 +1,91 @@
1
+ # Google preset (`theorum/presets/google`)
2
+
3
+ Google / Gemini convenience pack: grounding builtins plus typed vocabularies
4
+ for image and speech-adjacent profile fields.
5
+
6
+ ## Export
7
+
8
+ | Field | Value |
9
+ | --- | --- |
10
+ | Import | `theorum/presets/google` / `jsr:@theorum/core/presets/google` |
11
+ | Module | `src/presets/google.ts` |
12
+
13
+ ## Ownership
14
+
15
+ | Path | Role |
16
+ | --- | --- |
17
+ | `src/presets/google.ts` | Google builtins + vocabularies |
18
+
19
+ ## Builtins
20
+
21
+ `registerGooglePreset()` registers:
22
+
23
+ | Id | Notes |
24
+ | --- | --- |
25
+ | `googleSearch` | Interactions `google_search`; OpenRouter plugin `web` |
26
+ | `googleMaps` | Interactions `google_maps`; conflicts with `googleSearch` and `urlContext` |
27
+ | `urlContext` | Interactions `url_context` |
28
+
29
+ All are `kind: 'builtin'` with `ui: true`. Profiles must allowlist ids they use;
30
+ `conflictsWith` drops maps when search/urlContext are also requested.
31
+
32
+ ## Vocabularies
33
+
34
+ Constants (and matching types) for host profile authoring:
35
+
36
+ | Constant | Purpose |
37
+ | --- | --- |
38
+ | `GOOGLE_IMAGE_INPUT_MIMES` | png / jpeg / webp / heic / heif |
39
+ | `GOOGLE_VOICE_INPUT_MIMES` | webm / wav / mpeg / mp4 |
40
+ | `GOOGLE_IMAGE_ASPECT_RATIOS` / `GOOGLE_IMAGE_SIZES` | Image output pins |
41
+ | `GOOGLE_SPEECH_VOICES` | TTS voice names for `outputs.speech.voice` |
42
+ | `GoogleImageAspectRatio`, `GoogleImageInputMime`, `GoogleImageSize`, `GoogleVoiceInputMime` | Typed vocabulary unions |
43
+ | `GoogleImagePins`, `GoogleSpeechPins`, `GoogleSpeechVoice` | Typed pins assignable to kernel specs |
44
+
45
+ Kernel types stay stringly; these packs make Google hosts typed when they opt in.
46
+
47
+ ## Exported API
48
+
49
+ | Export | Role |
50
+ | --- | --- |
51
+ | `registerGooglePreset` | Register builtins into catalog |
52
+ | `GOOGLE_BUILTIN_TOOLS` | Static catalog entries |
53
+ | `GOOGLE_IMAGE_ASPECT_RATIOS`, `GOOGLE_IMAGE_INPUT_MIMES`, `GOOGLE_IMAGE_SIZES`, `GOOGLE_VOICE_INPUT_MIMES`, `GOOGLE_SPEECH_VOICES` | Typed profile authoring constants |
54
+ | `GoogleImageAspectRatio`, `GoogleImageInputMime`, `GoogleImageSize`, `GoogleVoiceInputMime`, `GoogleImagePins`, `GoogleSpeechPins`, `GoogleSpeechVoice` | Typed pins and vocabularies |
55
+
56
+ ```theorum-evidence
57
+ {
58
+ "sections": {
59
+ "Export": {
60
+ "supports": [
61
+ { "kind": "source", "path": "src/presets/google.ts" },
62
+ { "kind": "config", "path": "package.json" }
63
+ ]
64
+ },
65
+ "Ownership": {
66
+ "supports": [
67
+ { "kind": "source", "path": "src/presets/google.ts" },
68
+ { "kind": "graph", "path": "docs/_map.mjs" }
69
+ ]
70
+ },
71
+ "Builtins": {
72
+ "supports": [
73
+ { "kind": "source", "path": "src/presets/google.ts" },
74
+ { "kind": "contract_test", "path": "tests/kernel/theorum.test.ts" }
75
+ ]
76
+ },
77
+ "Vocabularies": {
78
+ "supports": [
79
+ { "kind": "source", "path": "src/presets/google.ts" },
80
+ { "kind": "contract_test", "path": "tests/kernel/theorum.test.ts" }
81
+ ]
82
+ },
83
+ "Exported API": {
84
+ "supports": [
85
+ { "kind": "source", "path": "src/presets/google.ts" },
86
+ { "kind": "source", "path": "src/presets/mod.ts" }
87
+ ]
88
+ }
89
+ }
90
+ }
91
+ ```
@@ -0,0 +1,88 @@
1
+ # Presets (`theorum/presets`)
2
+
3
+ Optional convenience packs. Presets register host-convenience catalogs
4
+ (provider builtins, media vocabularies) without baking product opinions into the
5
+ kernel.
6
+
7
+ ## Export
8
+
9
+ | Field | Value |
10
+ | --- | --- |
11
+ | Import | `theorum/presets` / `jsr:@theorum/core/presets` |
12
+ | Module | `src/presets/mod.ts` |
13
+
14
+ ## Ownership
15
+
16
+ | Path | Role |
17
+ | --- | --- |
18
+ | `src/presets/mod.ts` | Barrel re-exporting the Google pack |
19
+ | `src/presets/google.ts` | Documented in [`GOOGLE.md`](./GOOGLE.md) |
20
+
21
+ ## Role in the package
22
+
23
+ | Concern | Kernel | Preset |
24
+ | --- | --- | --- |
25
+ | Tool ids | `string` allowlist | Registers `googleSearch`, `googleMaps`, `urlContext` |
26
+ | Image/speech pins | Open `string` fields | Typed constants (`GOOGLE_IMAGE_SIZES`, voices, …) |
27
+ | Registration | `registerTools` API | `registerGooglePreset()` at host startup |
28
+
29
+ Call preset registration **before** registering profiles that allowlist preset
30
+ builtins. Import `theorum/presets/google` when you only need the Google pack.
31
+
32
+ Presets are optional — the kernel runs without them when hosts register their
33
+ own tools and vocabularies directly via `registerTools`.
34
+
35
+ ## When to use
36
+
37
+ | Use preset | Skip preset |
38
+ | --- | --- |
39
+ | Google Gemini hosts wanting typed pins + search/maps/url builtins | Custom tool catalog entirely host-owned |
40
+ | Quick start matching Google Interactions wire types | Non-Google providers only |
41
+
42
+ ## Exported API
43
+
44
+ This barrel re-exports the Google pack:
45
+
46
+ | Export | Role |
47
+ | --- | --- |
48
+ | `registerGooglePreset` | Register Google builtins into `CATALOG` |
49
+ | `GOOGLE_BUILTIN_TOOLS` | Catalog entries |
50
+ | `GOOGLE_IMAGE_ASPECT_RATIOS`, `GOOGLE_IMAGE_INPUT_MIMES`, `GOOGLE_IMAGE_SIZES`, `GOOGLE_VOICE_INPUT_MIMES` | Profile authoring constants |
51
+ | `GoogleImageAspectRatio`, `GoogleImageInputMime`, `GoogleImagePins`, `GoogleImageSize`, `GoogleVoiceInputMime` | Typed pins and vocabularies |
52
+
53
+ ```theorum-evidence
54
+ {
55
+ "sections": {
56
+ "Export": {
57
+ "supports": [
58
+ { "kind": "source", "path": "src/presets/mod.ts" },
59
+ { "kind": "config", "path": "package.json" }
60
+ ]
61
+ },
62
+ "Ownership": {
63
+ "supports": [
64
+ { "kind": "source", "path": "src/presets/mod.ts" },
65
+ { "kind": "graph", "path": "docs/_map.mjs" }
66
+ ]
67
+ },
68
+ "Role in the package": {
69
+ "supports": [
70
+ { "kind": "source", "path": "src/presets/mod.ts" },
71
+ { "kind": "contract_test", "path": "tests/kernel/theorum.test.ts" }
72
+ ]
73
+ },
74
+ "When to use": {
75
+ "supports": [
76
+ { "kind": "source", "path": "src/presets/google.ts" },
77
+ { "kind": "contract_test", "path": "tests/kernel/theorum.test.ts" }
78
+ ]
79
+ },
80
+ "Exported API": {
81
+ "supports": [
82
+ { "kind": "source", "path": "src/presets/mod.ts" },
83
+ { "kind": "doc", "path": "src/presets/GOOGLE.md" }
84
+ ]
85
+ }
86
+ }
87
+ }
88
+ ```
@@ -0,0 +1,201 @@
1
+ # Providers (`theorum/providers`)
2
+
3
+ Single door for constructing a `ModelProvider` bound to a profile. Credentials
4
+ and runtime endpoints are always host-supplied arguments — THEORUM does not read
5
+ environment variables and does not ship `.env` files.
6
+
7
+ ## Export
8
+
9
+ | Field | Value |
10
+ | --- | --- |
11
+ | Import | `theorum/providers` / `jsr:@theorum/core/providers` |
12
+ | Module | `src/providers/mod.ts` |
13
+ | Also on | Root `theorum` re-exports `createProvider` |
14
+
15
+ ## Ownership
16
+
17
+ Owns every module under `src/providers/` **except** OpenRouter-specific modules
18
+ in [`OPENROUTER.md`](./OPENROUTER.md).
19
+
20
+ | Module | Role (internal) |
21
+ | --- | --- |
22
+ | `create-provider.ts` | Public factory + lazy OpenRouter chat wrapper |
23
+ | `provider.ts` | Google Interactions streaming adapter |
24
+ | `interactions.ts` | Interactions payload / step wiring |
25
+ | `speech.ts` | OpenRouter `/audio/speech` + Interactions audio paths |
26
+ | `local.ts` | OpenAI-compat SSE for Ollama / llama.cpp / vLLM / LM Studio |
27
+ | `keys.ts` | Gemini vault transport types |
28
+ | `sse.ts` | Shared SSE line parser |
29
+ | `pcm.ts` | PCM → WAV for Interactions speech output |
30
+ | `gemini-tape.ts` / `google-tap.ts` | Test / tap hooks (not public exports) |
31
+ | `expose-for-tests.ts` | `THEORUM_TEST_INTERNALS=1` gated test surface |
32
+
33
+ ## Package boundary
34
+
35
+ | Rule | Detail |
36
+ | --- | --- |
37
+ | No `.env` in repo | Hosts pass credentials explicitly |
38
+ | No ambient env reads | `OLLAMA_HOST` resolved by host → `local.baseUrl` |
39
+ | No key templates | Business apps own secret storage |
40
+ | Traces | Host-injected on `runTurn`, not here |
41
+
42
+ ## createProvider
43
+
44
+ ```ts
45
+ const provider = createProvider(profile, {
46
+ gemini: { vault: { freeA, freeB, freeC, paid }, fetch? },
47
+ openRouter: { apiKey, baseUrl?, siteUrl?, siteName?, fetch?, modelMap?, voice? },
48
+ local: { baseUrl?, fetch? },
49
+ })
50
+ ```
51
+
52
+ Routing table:
53
+
54
+ | protocol | provider | Requires | Transport |
55
+ | --- | --- | --- | --- |
56
+ | `geminiInteractions` | `google` | `options.gemini` | Interactions API (chat / image / speech) |
57
+ | `openAi` | `openrouter` | `options.openRouter` | Lazy chat adapter or `speech.ts` when `outputs.speech` |
58
+ | `openAi` | `local` | optional `options.local` | `POST /v1/chat/completions` SSE |
59
+
60
+ Errors:
61
+
62
+ - Missing credential block → `TheorumError` naming the required option.
63
+ - Unsupported pair → `TheorumError` with protocol/provider in the message.
64
+
65
+ OpenRouter Vercel AI SDK loads **only** on first `complete` for `openAi` +
66
+ `openrouter` chat. Google and local never import it.
67
+
68
+ ## Google Interactions
69
+
70
+ `createInteractionsProvider(geminiTransport)` streams normalized `TurnEvent`s.
71
+
72
+ | Concern | Behavior |
73
+ | --- | --- |
74
+ | History | `user_input` / `model_output` steps |
75
+ | Multimodal | `image` / `audio` / `video` / `document` parts |
76
+ | Structured | `responseFormat` JSON schema when enforced |
77
+ | Output modes | Image / speech / structured are mutually exclusive |
78
+ | Tools | Catalog `interactionsType` + plugins |
79
+ | Stop | `turnStopFromInteractionStatus` on terminal status |
80
+
81
+ ## Local provider
82
+
83
+ `createLocalProvider` / `DEFAULT_LOCAL_BASE_URL` (`http://127.0.0.1:11434`). Hosts
84
+ resolve `OLLAMA_HOST` (or similar) themselves and pass `baseUrl` here — THEORUM
85
+ does not read environment variables for local endpoints (see module header in
86
+ `local.ts`, not `docs/SECRETS.md`).
87
+
88
+ ```ts
89
+ local: {
90
+ baseUrl: "http://127.0.0.1:11434", // no trailing slash
91
+ fetch: customFetch,
92
+ }
93
+ ```
94
+
95
+ - Raw `fetch` + `sse.ts` — no SDK.
96
+ - Accumulates streaming tool calls; maps `finish_reason` through
97
+ `turnStopFromOpenRouter`.
98
+ - Supports multimodal user content when the server accepts OpenAI-style parts.
99
+
100
+ ## Speech roles
101
+
102
+ When `profile.outputs.speech` is defined and protocol/provider is OpenRouter
103
+ OpenAI, `createProvider` returns `createSpeechProvider`:
104
+
105
+ | Transport | Path | Notes |
106
+ | --- | --- | --- |
107
+ | OpenAI | `/audio/speech` | `mp3` allowed via `response_format` |
108
+ | Interactions | audio `responseFormat` | PCM → WAV; `mp3` rejected at resolve |
109
+
110
+ Fallback `openRouter.voice` when `outputs.speech.voice` omitted.
111
+
112
+ ## Gemini transport
113
+
114
+ ```ts
115
+ createProvider(profile, {
116
+ gemini: { vault: { freeA, freeB, freeC, paid } },
117
+ })
118
+ ```
119
+
120
+ | Piece | Role |
121
+ | --- | --- |
122
+ | `GeminiTransport` | Vault + optional `fetch` |
123
+ | Buckets | `freeA`, `freeB`, `freeC`, `paid` |
124
+ | Selection | `model.key` / `ModelSpec.key` / `keyBuiltins` |
125
+
126
+ Overflow to `paid` is host policy, not inferred here.
127
+
128
+ ## Exported API
129
+
130
+ From `src/providers/mod.ts` only:
131
+
132
+ | Export | Kind |
133
+ | --- | --- |
134
+ | `createProvider` | function |
135
+ | `CreateProviderOptions` | type |
136
+ | `GeminiTransport`, `GeminiVault` | types |
137
+ | `createLocalProvider` | function |
138
+ | `LocalProviderConfig` | type |
139
+ | `DEFAULT_LOCAL_BASE_URL` | const |
140
+
141
+ ```theorum-evidence
142
+ {
143
+ "sections": {
144
+ "Export": {
145
+ "supports": [
146
+ { "kind": "source", "path": "src/providers/mod.ts" },
147
+ { "kind": "config", "path": "package.json" }
148
+ ]
149
+ },
150
+ "Ownership": {
151
+ "supports": [
152
+ { "kind": "source", "path": "src/providers/mod.ts" },
153
+ { "kind": "graph", "path": "docs/_map.mjs" }
154
+ ]
155
+ },
156
+ "Package boundary": {
157
+ "supports": [
158
+ { "kind": "source", "path": "src/providers/create-provider.ts" },
159
+ { "kind": "contract_test", "path": "tests/providers/create-provider.test.ts" }
160
+ ]
161
+ },
162
+ "createProvider": {
163
+ "supports": [
164
+ { "kind": "source", "path": "src/providers/create-provider.ts" },
165
+ { "kind": "contract_test", "path": "tests/providers/create-provider.test.ts" }
166
+ ]
167
+ },
168
+ "Google Interactions": {
169
+ "supports": [
170
+ { "kind": "source", "path": "src/providers/provider.ts" },
171
+ { "kind": "source", "path": "src/providers/interactions.ts" },
172
+ { "kind": "contract_test", "path": "tests/providers/interactions.test.ts" }
173
+ ]
174
+ },
175
+ "Local provider": {
176
+ "supports": [
177
+ { "kind": "source", "path": "src/providers/local.ts" },
178
+ { "kind": "contract_test", "path": "tests/providers/local.test.ts" }
179
+ ]
180
+ },
181
+ "Speech roles": {
182
+ "supports": [
183
+ { "kind": "source", "path": "src/providers/speech.ts" },
184
+ { "kind": "contract_test", "path": "tests/providers/speech.test.ts" }
185
+ ]
186
+ },
187
+ "Gemini transport": {
188
+ "supports": [
189
+ { "kind": "source", "path": "src/providers/keys.ts" },
190
+ { "kind": "contract_test", "path": "tests/providers/keys.test.ts" }
191
+ ]
192
+ },
193
+ "Exported API": {
194
+ "supports": [
195
+ { "kind": "source", "path": "src/providers/mod.ts" },
196
+ { "kind": "contract_test", "path": "tests/providers/create-provider.test.ts" }
197
+ ]
198
+ }
199
+ }
200
+ }
201
+ ```
@@ -0,0 +1,96 @@
1
+ # Streaming (`theorum/streaming`)
2
+
3
+ Structured-output streaming helpers and turn-stop classification re-exports for
4
+ hosts that want a narrow import without taking the full kernel barrel.
5
+
6
+ ## Export
7
+
8
+ | Field | Value |
9
+ | --- | --- |
10
+ | Import | `theorum/streaming` / `jsr:@theorum/core/streaming` |
11
+ | Module | `src/streaming/mod.ts` |
12
+
13
+ ## Ownership
14
+
15
+ | Path | Role |
16
+ | --- | --- |
17
+ | `src/streaming/readStreamingJsonStringField.ts` | Incomplete JSON string preview |
18
+ | `src/streaming/mod.ts` | Barrel + stop re-exports |
19
+
20
+ Stop source of truth: [`../kernel/CONTRACT.md`](../kernel/CONTRACT.md)
21
+ (`src/kernel/stop.ts`).
22
+
23
+ ## Streaming JSON preview
24
+
25
+ `readStreamingJsonStringField(jsonText, key)` reads one string field from
26
+ **incomplete** JSON while structured output streams as text deltas.
27
+
28
+ ```ts
29
+ const preview = readStreamingJsonStringField(buffer, "mermaid");
30
+ // returns decoded prefix even before closing quote
31
+ ```
32
+
33
+ | Behavior | Detail |
34
+ | --- | --- |
35
+ | Locator | `"key": "` pattern |
36
+ | Escapes | `\n`, `\t`, `\uXXXX`, … |
37
+ | Incomplete buffer | Returns prefix for live UI preview |
38
+ | Missing key | `null` |
39
+
40
+ Does not validate full JSON documents.
41
+
42
+ ## Stop re-exports
43
+
44
+ | Category | Exports |
45
+ | --- | --- |
46
+ | Types | `TurnStop`, `TurnStopKind`, `TurnContinueFrom`, `ProfileResumeSpec` |
47
+ | Constants | `CONTINUE_INSTRUCTION`, `DEFAULT_AUTO_CONTINUE`, `AUTO_CONTINUE_DELAY_MS` |
48
+ | Helpers | `isResumeableStop`, `shouldAutoContinue`, `isUserCancelledStop`, mappers |
49
+ | Errors | `GenerationStopError`, `isGenerationStopError` |
50
+
51
+ Behavioral contract: kernel **Stop and resume** section.
52
+
53
+ ## Exported API
54
+
55
+ | Group | Symbols |
56
+ | --- | --- |
57
+ | Streaming JSON | `readStreamingJsonStringField` |
58
+ | Stop / resume (re-export from `kernel/stop.ts`) | `ProfileResumeSpec`, `TurnContinueFrom`, `TurnStop`, `TurnStopKind`, `AUTO_CONTINUE_DELAY_MS`, `CONTINUE_INSTRUCTION`, `DEFAULT_AUTO_CONTINUE`, `GenerationStopError`, `isGenerationStopError`, `isResumeableStop`, `isUserCancelledStop`, `shouldAutoContinue`, `turnStopFromClientStreamEnd`, `turnStopFromInteractionStatus`, `turnStopFromOpenRouter` |
59
+
60
+ ```theorum-evidence
61
+ {
62
+ "sections": {
63
+ "Export": {
64
+ "supports": [
65
+ { "kind": "source", "path": "src/streaming/mod.ts" },
66
+ { "kind": "config", "path": "package.json" }
67
+ ]
68
+ },
69
+ "Ownership": {
70
+ "supports": [
71
+ { "kind": "source", "path": "src/streaming/mod.ts" },
72
+ { "kind": "graph", "path": "docs/_map.mjs" }
73
+ ]
74
+ },
75
+ "Streaming JSON preview": {
76
+ "supports": [
77
+ { "kind": "source", "path": "src/streaming/readStreamingJsonStringField.ts" },
78
+ { "kind": "contract_test", "path": "tests/streaming/readStreamingJsonStringField.test.ts" }
79
+ ]
80
+ },
81
+ "Stop re-exports": {
82
+ "supports": [
83
+ { "kind": "source", "path": "src/streaming/mod.ts" },
84
+ { "kind": "source", "path": "src/kernel/stop.ts" },
85
+ { "kind": "contract_test", "path": "tests/streaming/turnStop.test.ts" }
86
+ ]
87
+ },
88
+ "Exported API": {
89
+ "supports": [
90
+ { "kind": "source", "path": "src/streaming/mod.ts" },
91
+ { "kind": "contract_test", "path": "tests/streaming/readStreamingJsonStringField.test.ts" }
92
+ ]
93
+ }
94
+ }
95
+ }
96
+ ```
package/esm/mod.d.ts CHANGED
@@ -44,7 +44,7 @@ export { PROJECT_ID_MAX, sanitizeProjectId, sanitizeText, sanitizeTurnRequest, }
44
44
  export type { CompactionSplit, CompactionTokens } from './src/kernel/engine/compaction.js';
45
45
  export { compactionMeter, compactionNeeded, estimateHistoryTokens, HISTORY_MEDIA_TOKENS, HISTORY_TEXT_ENCODING, resolveCompactionTokens, resolveHistoryTokens, shouldCompact, splitForCompaction, } from './src/kernel/engine/compaction.js';
46
46
  export { runTurn } from './src/kernel/engine/runner.js';
47
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './src/kernel/registry/catalog.js';
47
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './src/kernel/registry/catalog.js';
48
48
  export type { ProfileDefinition } from './src/kernel/registry/profiles.js';
49
49
  export { clearProfiles, defineProfile, getProfile, hasProfile, listProfiles, registerProfile, registerProfiles, } from './src/kernel/registry/profiles.js';
50
50
  export { projectProfile, resolveTurn } from './src/kernel/registry/resolve.js';
package/esm/mod.js CHANGED
@@ -42,7 +42,7 @@ export { clientIp, quotaMessage, releaseSlot, resetSlots, skipQuota, takeSlot, }
42
42
  export { PROJECT_ID_MAX, sanitizeProjectId, sanitizeText, sanitizeTurnRequest, } from './src/guardrails/sanitize.js';
43
43
  export { compactionMeter, compactionNeeded, estimateHistoryTokens, HISTORY_MEDIA_TOKENS, HISTORY_TEXT_ENCODING, resolveCompactionTokens, resolveHistoryTokens, shouldCompact, splitForCompaction, } from './src/kernel/engine/compaction.js';
44
44
  export { runTurn } from './src/kernel/engine/runner.js';
45
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './src/kernel/registry/catalog.js';
45
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './src/kernel/registry/catalog.js';
46
46
  export { clearProfiles, defineProfile, getProfile, hasProfile, listProfiles, registerProfile, registerProfiles, } from './src/kernel/registry/profiles.js';
47
47
  export { projectProfile, resolveTurn } from './src/kernel/registry/resolve.js';
48
48
  export { getStructured, registerStructured } from './src/kernel/registry/schemas.js';
@@ -11,7 +11,7 @@ import "../../_dnt.polyfills.js";
11
11
  export type { CompactionSplit, CompactionTokens } from './engine/compaction.js';
12
12
  export { compactionMeter, compactionNeeded, estimateHistoryTokens, HISTORY_MEDIA_TOKENS, HISTORY_TEXT_ENCODING, resolveCompactionTokens, resolveHistoryTokens, shouldCompact, splitForCompaction, } from './engine/compaction.js';
13
13
  export { runTurn } from './engine/runner.js';
14
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './registry/catalog.js';
14
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './registry/catalog.js';
15
15
  export type { ProfileDefinition } from './registry/profiles.js';
16
16
  export { clearProfiles, defineProfile, getProfile, hasProfile, listProfiles, registerProfile, registerProfiles, } from './registry/profiles.js';
17
17
  export { projectProfile, resolveTurn } from './registry/resolve.js';
@@ -10,7 +10,7 @@
10
10
  import "../../_dnt.polyfills.js";
11
11
  export { compactionMeter, compactionNeeded, estimateHistoryTokens, HISTORY_MEDIA_TOKENS, HISTORY_TEXT_ENCODING, resolveCompactionTokens, resolveHistoryTokens, shouldCompact, splitForCompaction, } from './engine/compaction.js';
12
12
  export { runTurn } from './engine/runner.js';
13
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './registry/catalog.js';
13
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, } from './registry/catalog.js';
14
14
  export { clearProfiles, defineProfile, getProfile, hasProfile, listProfiles, registerProfile, registerProfiles, } from './registry/profiles.js';
15
15
  export { projectProfile, resolveTurn } from './registry/resolve.js';
16
16
  export { getStructured, registerStructured } from './registry/schemas.js';
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @module
8
8
  */
9
- import type { BuiltinToolId, Catalog, GeminiInputKind, ModelId, ModelSpec, Profile, ThinkingLevel, ToolCatalogEntry, ToolId } from '../types.js';
9
+ import type { BuiltinToolId, Catalog, MediaInputKind, ModelId, ModelSpec, Profile, ThinkingLevel, ToolCatalogEntry, ToolId } from '../types.js';
10
10
  /** Live tool catalog. Starts with harness tools; presets/hosts register more. */
11
11
  declare const CATALOG: Catalog;
12
12
  /** Register or replace tool descriptors (idempotent per id). */
@@ -19,7 +19,7 @@ declare function listBuiltinIds(): BuiltinToolId[];
19
19
  declare function resetTools(): void;
20
20
  declare function mimeEssence(mime: string): string;
21
21
  declare function mimeAllowed(accept: string[], mime: string): boolean;
22
- declare function geminiKindForMime(mime: string): GeminiInputKind | undefined;
22
+ declare function mediaKindForMime(mime: string): MediaInputKind | undefined;
23
23
  /** Require a host-declared model spec for an allowed profile model id. */
24
24
  declare function requireModelSpec(profile: Profile, modelId: ModelId): ModelSpec;
25
25
  /** Clamp a requested thinking level to what the model spec accepts. */
@@ -28,4 +28,4 @@ declare function clampThinkingLevel(spec: ModelSpec, level: ThinkingLevel): Thin
28
28
  declare function modelEntryByApiId(specs: Record<string, ModelSpec>, apiId: string): ModelSpec | undefined;
29
29
  /** Clamp thinking level using a provider-native API id within a host specs map. */
30
30
  declare function clampThinkingLevelForApiId(specs: Record<string, ModelSpec>, apiId: string, level: ThinkingLevel): ThinkingLevel;
31
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, };
31
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, };
@@ -45,8 +45,8 @@ function resetTools() {
45
45
  }
46
46
  Object.assign(CATALOG.tools, HARNESS_TOOLS);
47
47
  }
48
- /** Gemini Interactions inline MIME part type (adapter wire map). */
49
- const GEMINI_INPUT_KINDS = {
48
+ /** MIME essence normalized media part category (shared ingress map). */
49
+ const MEDIA_INPUT_KINDS = {
50
50
  'image/png': 'image',
51
51
  'image/jpeg': 'image',
52
52
  'image/jpg': 'image',
@@ -95,8 +95,8 @@ function mimeAllowed(accept, mime) {
95
95
  return allowed === actual;
96
96
  });
97
97
  }
98
- function geminiKindForMime(mime) {
99
- return GEMINI_INPUT_KINDS[mimeEssence(mime)];
98
+ function mediaKindForMime(mime) {
99
+ return MEDIA_INPUT_KINDS[mimeEssence(mime)];
100
100
  }
101
101
  /** Require a host-declared model spec for an allowed profile model id. */
102
102
  function requireModelSpec(profile, modelId) {
@@ -132,4 +132,4 @@ function modelEntryByApiId(specs, apiId) {
132
132
  function clampThinkingLevelForApiId(specs, apiId, level) {
133
133
  return clampLevels(modelEntryByApiId(specs, apiId), level);
134
134
  }
135
- export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, geminiKindForMime, getTool, listBuiltinIds, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, };
135
+ export { CATALOG, clampThinkingLevel, clampThinkingLevelForApiId, getTool, listBuiltinIds, mediaKindForMime, mimeAllowed, mimeEssence, modelEntryByApiId, registerTools, requireModelSpec, resetTools, };
@@ -9,7 +9,7 @@ import { TheorumError } from '../../guardrails/error.js';
9
9
  import { wrapUserData } from '../engine/boundary.js';
10
10
  import { synthesizeRepairPrompt } from '../engine/repair.js';
11
11
  import { assertAttachmentLimits, requireMediaLimits } from './attachments.js';
12
- import { geminiKindForMime, mimeAllowed, mimeEssence } from './catalog.js';
12
+ import { mediaKindForMime, mimeAllowed, mimeEssence } from './catalog.js';
13
13
  function listedValue(allowed, value) {
14
14
  if (!value) {
15
15
  return undefined;
@@ -83,10 +83,10 @@ function resolveImageFormat(profile, _model, slots) {
83
83
  size,
84
84
  };
85
85
  }
86
- function assertGeminiMime(mime) {
87
- const kind = geminiKindForMime(mime);
86
+ function assertMediaMime(mime) {
87
+ const kind = mediaKindForMime(mime);
88
88
  if (!kind) {
89
- throw new TheorumError(`MIME '${mime}' is not a Gemini input type`);
89
+ throw new TheorumError(`MIME '${mime}' is not a supported media input type`);
90
90
  }
91
91
  return kind;
92
92
  }
@@ -96,12 +96,12 @@ function mediaParts(profile, model, blobs, channel) {
96
96
  throw new TheorumError(`Profile ${profile.id} does not accept ${channel}`);
97
97
  }
98
98
  const maxInputImages = profile.outputs.image?.maxInputImages;
99
- const imageCount = blobs.filter((blob) => geminiKindForMime(blob.mimeType) === 'image').length;
99
+ const imageCount = blobs.filter((blob) => mediaKindForMime(blob.mimeType) === 'image').length;
100
100
  if (maxInputImages !== undefined && imageCount > maxInputImages) {
101
101
  throw new TheorumError(`At most ${maxInputImages} reference images on ${model}`);
102
102
  }
103
103
  return blobs.map((blob) => {
104
- const kind = assertGeminiMime(blob.mimeType);
104
+ const kind = assertMediaMime(blob.mimeType);
105
105
  if (!mimeAllowed(accept, blob.mimeType)) {
106
106
  throw new TheorumError(`MIME '${blob.mimeType}' is not accepted on ${profile.id}`);
107
107
  }
@@ -21,8 +21,8 @@ export type CustomToolId = HarnessToolId | (string & Record<never, never>);
21
21
  export type ToolId = BuiltinToolId | CustomToolId;
22
22
  /** Id of a host-registered structured output schema. */
23
23
  export type StructuredSchemaId = string;
24
- /** Interactions inline part types Gemini accepts besides text. */
25
- export type GeminiInputKind = 'image' | 'audio' | 'video' | 'document';
24
+ /** Normalized multimodal part category (image, audio, video, document). */
25
+ export type MediaInputKind = 'image' | 'audio' | 'video' | 'document';
26
26
  /** Host-owned profile identifier. */
27
27
  export type ProfileId = string;
28
28
  /** Named Gemini key bucket used by host-provided transports. */
@@ -354,7 +354,7 @@ export interface InteractionTextPart {
354
354
  }
355
355
  /** Inline media part sent to provider adapters after MIME validation. */
356
356
  export interface InteractionMediaPart {
357
- type: GeminiInputKind;
357
+ type: MediaInputKind;
358
358
  mimeType: string;
359
359
  data: string;
360
360
  }
@@ -6,7 +6,7 @@
6
6
  * normalized `TurnEvent` objects. No external SDK dependency — raw fetch + SSE.
7
7
  *
8
8
  * Hosts pass `baseUrl` explicitly. THEORUM does not read `OLLAMA_HOST` or other
9
- * environment variables (see docs/SECRETS.md).
9
+ * environment variables (see src/providers/CONTRACT.md).
10
10
  *
11
11
  * @module
12
12
  */
@@ -6,7 +6,7 @@
6
6
  * normalized `TurnEvent` objects. No external SDK dependency — raw fetch + SSE.
7
7
  *
8
8
  * Hosts pass `baseUrl` explicitly. THEORUM does not read `OLLAMA_HOST` or other
9
- * environment variables (see docs/SECRETS.md).
9
+ * environment variables (see src/providers/CONTRACT.md).
10
10
  *
11
11
  * @module
12
12
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theorum",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "A flat TypeScript agent kernel for typed profiles, deterministic turn execution, dynamic tools, provider adapters, guardrails, and host-injected traces.",
5
5
  "keywords": [
6
6
  "agent",