theorum 0.1.2

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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +338 -0
  3. package/docs/AGENT_PROFILE_CONTRACT.md +161 -0
  4. package/docs/CLI_SPEC.md +183 -0
  5. package/docs/SECRETS.md +55 -0
  6. package/esm/_dnt.polyfills.d.ts +11 -0
  7. package/esm/_dnt.polyfills.js +15 -0
  8. package/esm/_dnt.shims.d.ts +5 -0
  9. package/esm/_dnt.shims.js +61 -0
  10. package/esm/mod.d.ts +37 -0
  11. package/esm/mod.js +35 -0
  12. package/esm/package.json +3 -0
  13. package/esm/src/guardrails/error.d.ts +35 -0
  14. package/esm/src/guardrails/error.js +116 -0
  15. package/esm/src/guardrails/injection.d.ts +12 -0
  16. package/esm/src/guardrails/injection.js +220 -0
  17. package/esm/src/guardrails/keys.d.ts +12 -0
  18. package/esm/src/guardrails/keys.js +132 -0
  19. package/esm/src/guardrails/mod.d.ts +14 -0
  20. package/esm/src/guardrails/mod.js +14 -0
  21. package/esm/src/guardrails/sanitize.d.ts +22 -0
  22. package/esm/src/guardrails/sanitize.js +133 -0
  23. package/esm/src/guardrails/sensitive.d.ts +12 -0
  24. package/esm/src/guardrails/sensitive.js +88 -0
  25. package/esm/src/kernel/engine/boundary.d.ts +10 -0
  26. package/esm/src/kernel/engine/boundary.js +55 -0
  27. package/esm/src/kernel/engine/delta.d.ts +8 -0
  28. package/esm/src/kernel/engine/delta.js +362 -0
  29. package/esm/src/kernel/engine/hash.d.ts +1 -0
  30. package/esm/src/kernel/engine/hash.js +9 -0
  31. package/esm/src/kernel/engine/record.d.ts +2 -0
  32. package/esm/src/kernel/engine/record.js +7 -0
  33. package/esm/src/kernel/engine/repair.d.ts +9 -0
  34. package/esm/src/kernel/engine/repair.js +38 -0
  35. package/esm/src/kernel/engine/runner.d.ts +14 -0
  36. package/esm/src/kernel/engine/runner.js +731 -0
  37. package/esm/src/kernel/engine/tree.d.ts +2 -0
  38. package/esm/src/kernel/engine/tree.js +17 -0
  39. package/esm/src/kernel/mod.d.ts +16 -0
  40. package/esm/src/kernel/mod.js +15 -0
  41. package/esm/src/kernel/registry/catalog.d.ts +24 -0
  42. package/esm/src/kernel/registry/catalog.js +213 -0
  43. package/esm/src/kernel/registry/profiles.d.ts +36 -0
  44. package/esm/src/kernel/registry/profiles.js +111 -0
  45. package/esm/src/kernel/registry/resolve.d.ts +20 -0
  46. package/esm/src/kernel/registry/resolve.js +235 -0
  47. package/esm/src/kernel/registry/schemas.d.ts +14 -0
  48. package/esm/src/kernel/registry/schemas.js +23 -0
  49. package/esm/src/kernel/registry/tools.d.ts +12 -0
  50. package/esm/src/kernel/registry/tools.js +36 -0
  51. package/esm/src/kernel/types.d.ts +497 -0
  52. package/esm/src/kernel/types.js +10 -0
  53. package/esm/src/observability/mod.d.ts +12 -0
  54. package/esm/src/observability/mod.js +10 -0
  55. package/esm/src/observability/spans.d.ts +16 -0
  56. package/esm/src/observability/spans.js +56 -0
  57. package/esm/src/observability/trace-attach.d.ts +16 -0
  58. package/esm/src/observability/trace-attach.js +81 -0
  59. package/esm/src/observability/trace-record.d.ts +112 -0
  60. package/esm/src/observability/trace-record.js +140 -0
  61. package/esm/src/observability/trace-usage.d.ts +3 -0
  62. package/esm/src/observability/trace-usage.js +32 -0
  63. package/esm/src/observability/trace.d.ts +23 -0
  64. package/esm/src/observability/trace.js +121 -0
  65. package/esm/src/providers/attachments.d.ts +17 -0
  66. package/esm/src/providers/attachments.js +156 -0
  67. package/esm/src/providers/gemini-tape.d.ts +3 -0
  68. package/esm/src/providers/gemini-tape.js +46 -0
  69. package/esm/src/providers/google-tap.d.ts +3 -0
  70. package/esm/src/providers/google-tap.js +48 -0
  71. package/esm/src/providers/interactions.d.ts +5 -0
  72. package/esm/src/providers/interactions.js +127 -0
  73. package/esm/src/providers/media.d.ts +5 -0
  74. package/esm/src/providers/media.js +125 -0
  75. package/esm/src/providers/mod.d.ts +15 -0
  76. package/esm/src/providers/mod.js +13 -0
  77. package/esm/src/providers/openrouter-payload.d.ts +24 -0
  78. package/esm/src/providers/openrouter-payload.js +177 -0
  79. package/esm/src/providers/openrouter.d.ts +17 -0
  80. package/esm/src/providers/openrouter.js +332 -0
  81. package/esm/src/providers/provider.d.ts +13 -0
  82. package/esm/src/providers/provider.js +123 -0
  83. package/esm/src/providers/sse.d.ts +7 -0
  84. package/esm/src/providers/sse.js +53 -0
  85. package/esm/src/providers/tts.d.ts +24 -0
  86. package/esm/src/providers/tts.js +144 -0
  87. package/package.json +48 -0
@@ -0,0 +1,497 @@
1
+ /**
2
+ * Shared type contracts for THEORUM profiles, turns, provider adapters, tools,
3
+ * guardrails, and stream events.
4
+ *
5
+ * Import from `jsr:@theorum/core/kernel` or `theorum/kernel` when a host app needs types without
6
+ * importing provider implementations.
7
+ *
8
+ * @module
9
+ */
10
+ /** Model reasoning effort level normalized across provider adapters. */
11
+ export type ThinkingLevel = 'minimal' | 'low' | 'medium' | 'high';
12
+ /** Built-in model aliases included in THEORUM's generic model catalog. */
13
+ export type StandardModelId = 'gemini31FlashLite' | 'gemini31ProPreview' | 'gemini35FlashLite' | 'gemini31FlashLiteImage' | 'gemini31FlashTts' | 'sonar';
14
+ /** Any model id a host profile may allow, including app-provided custom ids. */
15
+ export type ModelId = StandardModelId | (string & {});
16
+ /** Provider-native tools THEORUM can project into supported provider payloads. */
17
+ export type BuiltinToolId = 'googleSearch' | 'googleMaps' | 'urlContext';
18
+ /** Minimal built-in custom tool available to host apps for user interaction pauses. */
19
+ export type StandardCustomToolId = 'askUser';
20
+ /** Host-owned custom tool id. */
21
+ export type CustomToolId = StandardCustomToolId | (string & {});
22
+ /** Any tool id accepted by profile allowlists and per-turn gates. */
23
+ export type ToolId = BuiltinToolId | CustomToolId;
24
+ /** Id of a host-registered structured output schema. */
25
+ export type StructuredSchemaId = string;
26
+ /** Interactions inline part types Gemini accepts besides text. */
27
+ export type GeminiInputKind = 'image' | 'audio' | 'video' | 'document';
28
+ /** Host-owned profile identifier. */
29
+ export type ProfileId = string;
30
+ /** Named Gemini key bucket used by host-provided transports. */
31
+ export type GeminiBucket = 'freeA' | 'freeB' | 'freeC' | 'paid';
32
+ /** Gemini bucket that may overflow to the paid bucket after quota backoff. */
33
+ export type GeminiFreeBucket = Exclude<GeminiBucket, 'paid'>;
34
+ /** Message role accepted by provider history mappers. */
35
+ export type ChatRole = 'system' | 'user' | 'assistant';
36
+ /** Profile-level control a caller may toggle at turn time. */
37
+ export type ControlId = 'thinking';
38
+ /** Native image size supported by the generic image response spec. */
39
+ export type ImageSize = '1K';
40
+ /** Native image aspect ratio accepted by image-capable model specs. */
41
+ export type ImageAspectRatio = '1:1' | '3:2' | '2:3' | '3:4' | '4:3' | '4:5' | '5:4' | '9:16' | '16:9' | '21:9';
42
+ /** Public event types emitted by `runTurn` and provider adapters. */
43
+ export type TurnEventType = 'thought' | 'text' | 'tool' | 'structured' | 'media' | 'grounding' | 'evidence' | 'tokens' | 'done' | 'error';
44
+ /** Provider thinking levels used when a boolean thinking control is on or off. */
45
+ export interface ThinkingMap {
46
+ on: ThinkingLevel;
47
+ off: ThinkingLevel;
48
+ }
49
+ /** Provider summary behavior used when a boolean thinking control is on or off. */
50
+ export interface SummaryMap {
51
+ on: 'auto' | 'none';
52
+ off: 'auto' | 'none';
53
+ }
54
+ /** Native image generation on Interactions (`response_format.type = image`). */
55
+ export interface ImageModelSpec {
56
+ maxInputImages: number;
57
+ inputMimes: string[];
58
+ sizes: ImageSize[];
59
+ aspectRatios: ImageAspectRatio[];
60
+ outputMime: string;
61
+ allowsGrounding: boolean;
62
+ }
63
+ /** Static metadata THEORUM needs to safely call a model id. */
64
+ export interface ModelCatalogEntry {
65
+ apiId: string;
66
+ /** Provider-native id for OpenRouter-compatible gateways. Defaults to `google/${apiId}`. */
67
+ openRouterId?: string;
68
+ thinking: ThinkingMap;
69
+ /** Levels this model accepts on Interactions. Illegal values → 400. */
70
+ thinkingLevels: ThinkingLevel[];
71
+ summaries: SummaryMap;
72
+ maxOutputTokens: number;
73
+ temperature: number;
74
+ /** Builtins that may run on the profile's free key. Anything else is paid. */
75
+ freeBuiltins: BuiltinToolId[];
76
+ image?: ImageModelSpec;
77
+ }
78
+ /** Static metadata for built-in and generic custom tools. */
79
+ export interface ToolCatalogEntry {
80
+ kind: 'builtin' | 'custom';
81
+ ui: boolean;
82
+ schema?: Record<string, unknown>;
83
+ }
84
+ /** Host-registered structured output schema and enforcement mode. */
85
+ export interface StructuredSpec {
86
+ enforced: 'responseFormat' | 'prompt';
87
+ jsonSchema?: Record<string, unknown>;
88
+ }
89
+ /** In-memory model and tool catalog shape. */
90
+ export interface Catalog {
91
+ models: Record<ModelId, ModelCatalogEntry>;
92
+ tools: Record<ToolId, ToolCatalogEntry>;
93
+ }
94
+ /** Per-turn file, byte, and MIME-specific input limits. */
95
+ export interface MediaLimits {
96
+ maxFiles: number;
97
+ maxBytes: number;
98
+ maxTurnBytes: number;
99
+ limitsByMime?: Record<string, number>;
100
+ }
101
+ /** Input media declaration used by attachment and voice sanitizers. */
102
+ export interface MimeInputs extends Partial<MediaLimits> {
103
+ text?: boolean;
104
+ attachments?: {
105
+ accept: string[];
106
+ };
107
+ voice?: {
108
+ accept: string[];
109
+ };
110
+ }
111
+ /** Structured schema selector driven by an input slot. */
112
+ export interface StructuredBySlot {
113
+ by: string;
114
+ map: Record<string, string>;
115
+ fallback: string;
116
+ }
117
+ /** Legacy-compatible model selection block used by profile builders. */
118
+ export interface ProfileModels {
119
+ allow: ModelId[];
120
+ select?: Record<string, ModelId>;
121
+ /** Pinned level when `thinking` is not in `controls`. */
122
+ thinking?: ThinkingLevel | Record<string, ThinkingLevel>;
123
+ override?: Partial<Record<ModelId, Partial<Pick<ModelCatalogEntry, 'maxOutputTokens' | 'temperature'> & {
124
+ summaries?: 'auto' | 'none';
125
+ }>>>;
126
+ }
127
+ /** Result returned by a profile output validator. */
128
+ export interface ValidationResult {
129
+ isValid: boolean;
130
+ error?: string;
131
+ finding?: string;
132
+ data?: Record<string, unknown>;
133
+ }
134
+ /** Host-owned validator for structured output candidates. */
135
+ export type ProfileValidator = (candidate: unknown, slots?: Record<string, string>) => ValidationResult | Promise<ValidationResult>;
136
+ /** Profile output validation and deterministic repair configuration. */
137
+ export interface ProfileValidationSpec {
138
+ extract?: (structured: unknown) => unknown;
139
+ validate: ProfileValidator;
140
+ maxRetries?: number;
141
+ repairGuidance?: string;
142
+ }
143
+ /** Audio container emitted by the OpenRouter TTS adapter. */
144
+ export type OpenRouterAudioFormat = 'pcm' | 'mp3';
145
+ /** Voice name passed through to OpenRouter-compatible TTS models. */
146
+ export type OpenRouterTtsVoice = 'Zephyr' | 'Puck' | 'Charon' | 'Kore' | 'Fenrir' | 'Leda' | 'Orus' | 'Aoede' | 'Callirrhoe' | 'Autonoe' | 'Enceladus' | 'Iapetus' | 'Umbriel' | 'Algieba' | 'Despina' | 'Erinome' | 'Algenib' | 'Rasalgethi' | 'Laomedeia' | 'Achernar' | 'Alnilam' | 'Schedar' | 'Gacrux' | 'Pulcherrima' | 'Achird' | 'Zubenelgenubi' | 'Vindemiatrix' | 'Sadachbia' | 'Sadaltager' | 'Sulafat' | (string & {});
147
+ /** Voice output configuration owned by the host profile. */
148
+ export interface ProfileVoiceSpec {
149
+ voice?: OpenRouterTtsVoice;
150
+ responseFormat?: OpenRouterAudioFormat;
151
+ }
152
+ /** Stream delivery controls enforced by the kernel. */
153
+ export interface ProfileStreamingSpec {
154
+ mode?: 'sse' | 'buffered';
155
+ streamThoughts?: boolean;
156
+ gateMedia?: boolean;
157
+ }
158
+ /** Context passed to a host-owned outbound disclosure guard. */
159
+ export interface EgressContext {
160
+ text: string;
161
+ canary?: string;
162
+ slots?: Record<string, string>;
163
+ profile: Profile;
164
+ role?: string;
165
+ }
166
+ /** Decision returned by an egress guard. */
167
+ export interface EgressEnforcementResult {
168
+ blocked: boolean;
169
+ text: string;
170
+ hits?: string[];
171
+ rejectionMessage?: string | null;
172
+ }
173
+ /** Function that evaluates candidate user-visible output before release. */
174
+ export type EgressEnforcer = (context: EgressContext) => EgressEnforcementResult | Promise<EgressEnforcementResult>;
175
+ /** Profile egress policy for rejection, retry, or refusal behavior. */
176
+ export interface ProfileEgressSpec {
177
+ enforce: EgressEnforcer;
178
+ onBlock?: 'reject_to_agent' | 'refuse_to_user';
179
+ maxRetries?: number;
180
+ repairGuidance?: string;
181
+ }
182
+ /** Profile guardrail switches enforced by the kernel. */
183
+ export interface ProfileGuardrailsSpec {
184
+ /** Optional daily turn quota; omitted means quota enforcement is not configured. */
185
+ quota?: {
186
+ perDay: number;
187
+ };
188
+ canary?: boolean;
189
+ sanitizeInput?: boolean;
190
+ redactSensitive?: boolean;
191
+ egress?: ProfileEgressSpec;
192
+ }
193
+ /** Model, provider, thinking, and step bounds for a profile. */
194
+ export interface ProfileModelSpec {
195
+ protocol: 'geminiInteractions' | 'openAi';
196
+ provider: 'google' | 'openrouter';
197
+ allow: ModelId[];
198
+ select?: Record<string, ModelId>;
199
+ thinking?: ThinkingLevel | Record<string, ThinkingLevel>;
200
+ controls?: ControlId[];
201
+ maxSteps?: number;
202
+ key?: GeminiFreeBucket;
203
+ override?: Record<string, {
204
+ maxOutputTokens?: number;
205
+ temperature?: number;
206
+ summaries?: 'auto' | 'none';
207
+ }>;
208
+ }
209
+ /** Text, attachment, voice, slot, and size rules for a profile. */
210
+ export interface ProfileInputsSpec {
211
+ text?: boolean;
212
+ attachments?: {
213
+ accept: string[];
214
+ };
215
+ voice?: {
216
+ accept: string[];
217
+ };
218
+ maxFiles?: number;
219
+ maxBytes?: number;
220
+ maxTurnBytes?: number;
221
+ limitsByMime?: Record<string, number>;
222
+ slots?: Record<string, string[]>;
223
+ }
224
+ /** Output schema, media, voice, validation, and stream rules for a profile. */
225
+ export interface ProfileOutputsSpec {
226
+ structured?: StructuredSchemaId | StructuredBySlot | null;
227
+ media?: boolean;
228
+ voice?: ProfileVoiceSpec;
229
+ validation?: ProfileValidationSpec;
230
+ streaming?: ProfileStreamingSpec;
231
+ }
232
+ /** Complete host-owned agent contract consumed by the kernel. */
233
+ export interface Profile {
234
+ id: ProfileId;
235
+ identity: {
236
+ handle: string;
237
+ chat?: boolean;
238
+ system?: string;
239
+ systemByRole?: Record<string, string>;
240
+ };
241
+ model: ProfileModelSpec;
242
+ tools: {
243
+ allow: ToolId[];
244
+ };
245
+ inputs: ProfileInputsSpec;
246
+ outputs: ProfileOutputsSpec;
247
+ guardrails: ProfileGuardrailsSpec;
248
+ }
249
+ /** Text part sent to provider adapters after input normalization. */
250
+ export interface InteractionTextPart {
251
+ type: 'text';
252
+ text: string;
253
+ }
254
+ /** Inline media part sent to provider adapters after MIME validation. */
255
+ export interface InteractionMediaPart {
256
+ type: GeminiInputKind;
257
+ mimeType: string;
258
+ data: string;
259
+ }
260
+ /** Any provider input part accepted by THEORUM's provider contract. */
261
+ export type InteractionPart = InteractionTextPart | InteractionMediaPart;
262
+ /** Native image response request passed to image-capable providers. */
263
+ export interface ImageResponseFormat {
264
+ type: 'image';
265
+ mimeType: string;
266
+ aspectRatio: ImageAspectRatio;
267
+ imageSize: ImageSize;
268
+ }
269
+ /** Base64-encoded blob supplied by a host turn request. */
270
+ export interface TurnBlob {
271
+ mimeType: string;
272
+ data: string;
273
+ }
274
+ /** Provider-neutral history message preserving text, parts, tools, and metadata. */
275
+ export interface TurnHistoryMessage {
276
+ role: 'system' | 'user' | 'assistant' | 'tool';
277
+ content?: string;
278
+ parts?: InteractionPart[];
279
+ tool_calls?: Array<{
280
+ id: string;
281
+ type: 'function';
282
+ function: {
283
+ name: string;
284
+ arguments: string;
285
+ };
286
+ thoughtSignature?: string;
287
+ }>;
288
+ tool_call_id?: string;
289
+ name?: string;
290
+ metadata?: Record<string, unknown>;
291
+ }
292
+ /** Tool visibility tier used by host dynamic-loading strategies. */
293
+ export type ToolLoadTier = 'T0' | 'T1' | 'T2';
294
+ /** Execution authorization tier for dynamic tools. */
295
+ export type ToolPermissionTier = 'auto' | 'session_consent' | 'always_confirm';
296
+ /** Context supplied to a dynamic tool authorization hook. */
297
+ export interface DynamicToolExecutionContext {
298
+ args: Record<string, unknown>;
299
+ profile: Profile;
300
+ sessionPermissions?: string[];
301
+ }
302
+ /** Context supplied to a host dynamic tool schema loader. */
303
+ export interface DynamicToolLoadContext {
304
+ name: string;
305
+ args: Record<string, unknown>;
306
+ profile: Profile;
307
+ currentTools: DynamicToolDeclaration[];
308
+ sessionPermissions?: string[];
309
+ }
310
+ /** Host function that loads more tool declarations during a turn. */
311
+ export type DynamicToolLoader = (context: DynamicToolLoadContext) => DynamicToolDeclaration[] | Promise<DynamicToolDeclaration[]>;
312
+ /** Runtime tool schema and execution policy supplied by the host app. */
313
+ export interface DynamicToolDeclaration {
314
+ name: string;
315
+ description?: string;
316
+ parameters?: Record<string, unknown>;
317
+ loadTier?: ToolLoadTier;
318
+ permissionTier?: ToolPermissionTier;
319
+ category?: string;
320
+ /** Marks this declaration as a schema-loader tool for T2 expansion. */
321
+ loadsDynamicTools?: boolean;
322
+ handler?: (args: Record<string, unknown>) => ToolEnvelope | Promise<ToolEnvelope>;
323
+ canExecute?: (context: DynamicToolExecutionContext) => boolean | Promise<boolean> | ToolEnvelope | Promise<ToolEnvelope>;
324
+ }
325
+ /** Generic repair request used for validation and egress retry turns. */
326
+ export interface TurnRepairRequest {
327
+ previousOutput: string;
328
+ rejection: string;
329
+ guidance?: string;
330
+ }
331
+ /** User, media, history, and repair payload for a turn. */
332
+ export interface TurnInput {
333
+ text?: string;
334
+ role?: string;
335
+ slots?: Record<string, string>;
336
+ attachments?: TurnBlob[];
337
+ voice?: TurnBlob[];
338
+ history?: TurnHistoryMessage[];
339
+ repair?: TurnRepairRequest;
340
+ }
341
+ /** Host request after kernel ingress normalization. */
342
+ export type NormalizedTurnRequest = TurnRequest & {
343
+ input: TurnInput;
344
+ };
345
+ /** Host request for a single deterministic agent turn. */
346
+ export interface TurnRequest {
347
+ profile: ProfileId;
348
+ /** Caller project id when one exists. Omitted on some HTTP hosts. */
349
+ projectId?: string;
350
+ /** Google Interactions server-side conversation state. Omit for stateless/manual history. */
351
+ previousInteractionId?: string;
352
+ /** Optional Interactions storage override. Omit to let provider/project policy decide. */
353
+ store?: boolean;
354
+ select?: string;
355
+ thinking?: boolean;
356
+ /** Host-provided dynamic system prompt combined with profile persona */
357
+ system?: string;
358
+ /** Session permissions granted for this conversation turn */
359
+ sessionPermissions?: string[];
360
+ /** Opt-in gates. Profile `allow` is the ceiling; a tool is off until `tools[id]` is true. */
361
+ tools?: Partial<Record<ToolId, boolean>>;
362
+ /** Runtime tool declarations (e.g. load_when_needed strategy) */
363
+ dynamicTools?: DynamicToolDeclaration[];
364
+ /** Generic host-owned loader for T2 dynamic tool schema expansion. */
365
+ dynamicToolLoader?: DynamicToolLoader;
366
+ /** Host-owned metadata preserved for traces; the kernel does not interpret it. */
367
+ metadata?: Record<string, unknown>;
368
+ input?: TurnInput;
369
+ toolInvoke?: {
370
+ name: CustomToolId;
371
+ arguments: Record<string, unknown>;
372
+ };
373
+ }
374
+ /** Safe profile projection suitable for UI or host inspection. */
375
+ export interface ProjectedProfile {
376
+ id: string;
377
+ handle: string;
378
+ chat: boolean;
379
+ maxSteps: number;
380
+ models: ModelId[];
381
+ select: Record<string, ModelId> | null;
382
+ controls: ControlId[];
383
+ tools: Array<ToolCatalogEntry & {
384
+ name: ToolId;
385
+ }>;
386
+ inputs: Profile['inputs'];
387
+ slots: Record<string, string[]>;
388
+ outputs: Profile['outputs'];
389
+ image?: ImageModelSpec | null;
390
+ }
391
+ /** Fully-resolved provider request state created from a `TurnRequest`. */
392
+ export interface ResolvedGeneration {
393
+ model: ModelId;
394
+ previousInteractionId?: string;
395
+ store?: boolean;
396
+ thinking: ThinkingLevel;
397
+ summaries: 'auto' | 'none';
398
+ maxOutputTokens: number;
399
+ temperature: number;
400
+ builtins: BuiltinToolId[];
401
+ custom: CustomToolId[];
402
+ dynamicTools?: DynamicToolDeclaration[];
403
+ dynamicToolLoader?: DynamicToolLoader;
404
+ sessionPermissions?: string[];
405
+ history?: TurnHistoryMessage[];
406
+ maxSteps: number;
407
+ structured: StructuredSchemaId | null;
408
+ image: ImageResponseFormat | null;
409
+ voice?: ProfileVoiceSpec;
410
+ input: InteractionPart[];
411
+ geminiBucket: GeminiBucket;
412
+ canary: string;
413
+ }
414
+ /** Tool execution status returned to the model and stream. */
415
+ export type ToolStatus = 'ok' | 'error' | 'pause';
416
+ /** Structured result envelope returned by deterministic tool handlers. */
417
+ export interface ToolEnvelope {
418
+ status: ToolStatus;
419
+ finding?: string;
420
+ data?: Record<string, unknown>;
421
+ }
422
+ /** Token accounting emitted by providers or fallback estimation. */
423
+ export interface TurnTokens {
424
+ input: number;
425
+ output: number;
426
+ thinking?: number;
427
+ toolUse?: number;
428
+ total: number;
429
+ }
430
+ /** Normalized citation or place source surfaced from a provider. */
431
+ export interface GroundingSource {
432
+ title: string;
433
+ uri: string;
434
+ type: 'maps' | 'web';
435
+ }
436
+ /** Google grounding metadata normalized into a stream event. */
437
+ export interface GroundingEvent {
438
+ metadata?: Record<string, unknown>;
439
+ chunks?: unknown[];
440
+ searchHtml?: string;
441
+ sources: GroundingSource[];
442
+ }
443
+ /** Provider evidence such as OpenRouter citations or annotations. */
444
+ export interface ProviderEvidenceEvent {
445
+ provider: 'openrouter' | 'google' | string;
446
+ raw?: Record<string, unknown>;
447
+ citations?: string[];
448
+ annotations?: unknown[];
449
+ sources?: GroundingSource[];
450
+ }
451
+ /** Public event yielded by providers and by `runTurn`. */
452
+ export interface TurnEvent {
453
+ type: TurnEventType;
454
+ text?: string;
455
+ tool?: {
456
+ name: string;
457
+ arguments?: Record<string, unknown>;
458
+ result?: ToolEnvelope;
459
+ id?: string;
460
+ };
461
+ structured?: unknown;
462
+ media?: {
463
+ mimeType: string;
464
+ data: string;
465
+ };
466
+ grounding?: GroundingEvent;
467
+ evidence?: ProviderEvidenceEvent;
468
+ tokens?: TurnTokens;
469
+ interactionId?: string;
470
+ error?: string;
471
+ }
472
+ /** Provider-neutral request object sent from the kernel to a model adapter. */
473
+ export interface ProviderCompleteRequest {
474
+ model: ModelId;
475
+ previousInteractionId?: string;
476
+ store?: boolean;
477
+ thinking: ThinkingLevel;
478
+ summaries: 'auto' | 'none';
479
+ maxOutputTokens: number;
480
+ temperature: number;
481
+ builtins: BuiltinToolId[];
482
+ system: string;
483
+ input: InteractionPart[];
484
+ history?: TurnHistoryMessage[];
485
+ dynamicTools?: DynamicToolDeclaration[];
486
+ dynamicToolLoader?: DynamicToolLoader;
487
+ structured: StructuredSchemaId | null;
488
+ image: ImageResponseFormat | null;
489
+ voice?: ProfileVoiceSpec;
490
+ geminiBucket: GeminiBucket;
491
+ /** Scrubbed SSE / HTTP rows for traces. */
492
+ tapGemini?: (row: Record<string, unknown>) => void;
493
+ }
494
+ /** Minimal adapter contract every model provider must implement. */
495
+ export interface ModelProvider {
496
+ complete: (req: ProviderCompleteRequest) => AsyncIterable<TurnEvent>;
497
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared type contracts for THEORUM profiles, turns, provider adapters, tools,
3
+ * guardrails, and stream events.
4
+ *
5
+ * Import from `jsr:@theorum/core/kernel` or `theorum/kernel` when a host app needs types without
6
+ * importing provider implementations.
7
+ *
8
+ * @module
9
+ */
10
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Trace sinks and trace record helpers for THEORUM.
3
+ *
4
+ * THEORUM does not own a database or environment variable. Host applications
5
+ * choose a sink and pass it into `runTurn`, or use the noop sink for tests.
6
+ *
7
+ * @module
8
+ */
9
+ import "../../_dnt.polyfills.js";
10
+ export type { TraceSink } from './trace.js';
11
+ export { jsonlSink, memorySink, noopSink, resolveTraceDir, sinkFromDir, writeTrace, } from './trace.js';
12
+ export type { TraceRecord } from './trace-record.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Trace sinks and trace record helpers for THEORUM.
3
+ *
4
+ * THEORUM does not own a database or environment variable. Host applications
5
+ * choose a sink and pass it into `runTurn`, or use the noop sink for tests.
6
+ *
7
+ * @module
8
+ */
9
+ import "../../_dnt.polyfills.js";
10
+ export { jsonlSink, memorySink, noopSink, resolveTraceDir, sinkFromDir, writeTrace, } from './trace.js';
@@ -0,0 +1,16 @@
1
+ declare const OMIT_INJECTION = "[omitted - injection]";
2
+ declare const OMIT_SENSITIVE = "[omitted -sensitive]";
3
+ type RedactKind = 'injection' | 'sensitive';
4
+ interface RedactSpan {
5
+ start: number;
6
+ end: number;
7
+ kind: RedactKind;
8
+ }
9
+ declare function blobAt(match: RegExpMatchArray): {
10
+ blob: string;
11
+ index: number;
12
+ } | undefined;
13
+ declare function applySpans(text: string, spans: RedactSpan[]): string;
14
+ declare function spansFromPatterns(text: string, patterns: RegExp[], kind: RedactKind): RedactSpan[];
15
+ export type { RedactKind, RedactSpan };
16
+ export { applySpans, blobAt, OMIT_INJECTION, OMIT_SENSITIVE, spansFromPatterns };
@@ -0,0 +1,56 @@
1
+ const OMIT_INJECTION = '[omitted - injection]';
2
+ const OMIT_SENSITIVE = '[omitted -sensitive]';
3
+ function tokenFor(kind) {
4
+ if (kind === 'injection') {
5
+ return OMIT_INJECTION;
6
+ }
7
+ return OMIT_SENSITIVE;
8
+ }
9
+ function blobAt(match) {
10
+ const [blob] = match;
11
+ const { index } = match;
12
+ if (blob && index !== undefined) {
13
+ return { blob, index };
14
+ }
15
+ return undefined;
16
+ }
17
+ function mergeSpans(spans) {
18
+ const sorted = [...spans].sort((left, right) => left.start - right.start || right.end - left.end);
19
+ const out = [];
20
+ for (const span of sorted) {
21
+ if (span.end > span.start) {
22
+ const last = out.at(-1);
23
+ if (!last || span.start >= last.end) {
24
+ out.push(span);
25
+ }
26
+ else if (span.end > last.end) {
27
+ last.end = span.end;
28
+ }
29
+ }
30
+ }
31
+ return out;
32
+ }
33
+ function applySpans(text, spans) {
34
+ let out = text;
35
+ const merged = mergeSpans(spans);
36
+ for (let i = merged.length - 1; i >= 0; i -= 1) {
37
+ const span = merged[i];
38
+ if (span) {
39
+ out = out.slice(0, span.start) + tokenFor(span.kind) + out.slice(span.end);
40
+ }
41
+ }
42
+ return out;
43
+ }
44
+ function spansFromPatterns(text, patterns, kind) {
45
+ const spans = [];
46
+ for (const pattern of patterns) {
47
+ for (const match of text.matchAll(pattern)) {
48
+ const found = blobAt(match);
49
+ if (found) {
50
+ spans.push({ start: found.index, end: found.index + found.blob.length, kind });
51
+ }
52
+ }
53
+ }
54
+ return spans;
55
+ }
56
+ export { applySpans, blobAt, OMIT_INJECTION, OMIT_SENSITIVE, spansFromPatterns };
@@ -0,0 +1,16 @@
1
+ import type { ResolvedGeneration, TurnRequest } from '../kernel/types.js';
2
+ import type { TraceRecord } from './trace-record.js';
3
+ declare function attachResolved(record: TraceRecord, args: {
4
+ safe: TurnRequest;
5
+ model?: string;
6
+ bucket?: string;
7
+ generation?: ResolvedGeneration;
8
+ }): void;
9
+ declare function attachTape(record: TraceRecord, args: {
10
+ gemini?: unknown;
11
+ canary?: string;
12
+ system?: string;
13
+ generation?: ResolvedGeneration;
14
+ }): Promise<void>;
15
+ declare function attachUsage(record: TraceRecord, gemini: unknown, done: Record<string, unknown> | undefined): void;
16
+ export { attachResolved, attachTape, attachUsage };