theorum 0.1.4 → 0.1.5

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 (188) hide show
  1. package/esm/_dnt.polyfills.d.ts +110 -0
  2. package/esm/_dnt.polyfills.js +144 -0
  3. package/esm/_dnt.shims.d.ts +5 -0
  4. package/esm/_dnt.shims.js +61 -0
  5. package/{mod.ts → esm/mod.d.ts} +17 -57
  6. package/esm/mod.js +50 -0
  7. package/esm/package.json +3 -0
  8. package/esm/src/cli/commands/profile.d.ts +2 -0
  9. package/esm/src/cli/commands/profile.js +53 -0
  10. package/esm/src/cli/commands/run.d.ts +10 -0
  11. package/esm/src/cli/commands/run.js +55 -0
  12. package/esm/src/cli/commands/test.d.ts +15 -0
  13. package/esm/src/cli/commands/test.js +140 -0
  14. package/esm/src/cli/index.d.ts +4 -0
  15. package/esm/src/cli/index.js +148 -0
  16. package/esm/src/cli/matrix/fixtures.d.ts +13 -0
  17. package/esm/src/cli/matrix/fixtures.js +77 -0
  18. package/esm/src/cli/matrix/synthesizer.d.ts +29 -0
  19. package/esm/src/cli/matrix/synthesizer.js +187 -0
  20. package/esm/src/guardrails/error.d.ts +45 -0
  21. package/esm/src/guardrails/error.js +149 -0
  22. package/esm/src/guardrails/injection.d.ts +12 -0
  23. package/esm/src/guardrails/injection.js +220 -0
  24. package/esm/src/guardrails/mod.d.ts +16 -0
  25. package/esm/src/guardrails/mod.js +15 -0
  26. package/esm/src/guardrails/quota.d.ts +10 -0
  27. package/esm/src/guardrails/quota.js +64 -0
  28. package/esm/src/guardrails/sanitize.d.ts +22 -0
  29. package/esm/src/guardrails/sanitize.js +133 -0
  30. package/esm/src/guardrails/sensitive.d.ts +12 -0
  31. package/esm/src/guardrails/sensitive.js +88 -0
  32. package/esm/src/host/mint-trace.d.ts +27 -0
  33. package/esm/src/host/mint-trace.js +33 -0
  34. package/esm/src/host/mod.d.ts +13 -0
  35. package/{src/host/mod.ts → esm/src/host/mod.js} +3 -11
  36. package/esm/src/host/reply.d.ts +14 -0
  37. package/esm/src/host/reply.js +27 -0
  38. package/esm/src/kernel/engine/boundary.d.ts +10 -0
  39. package/esm/src/kernel/engine/boundary.js +55 -0
  40. package/esm/src/kernel/engine/delta.d.ts +8 -0
  41. package/esm/src/kernel/engine/delta.js +389 -0
  42. package/esm/src/kernel/engine/hash.d.ts +1 -0
  43. package/esm/src/kernel/engine/hash.js +9 -0
  44. package/esm/src/kernel/engine/record.d.ts +2 -0
  45. package/esm/src/kernel/engine/record.js +7 -0
  46. package/esm/src/kernel/engine/repair.d.ts +7 -0
  47. package/esm/src/kernel/engine/repair.js +38 -0
  48. package/esm/src/kernel/engine/runner/gates.d.ts +4 -0
  49. package/esm/src/kernel/engine/runner/gates.js +203 -0
  50. package/esm/src/kernel/engine/runner/mod.d.ts +14 -0
  51. package/esm/src/kernel/engine/runner/mod.js +109 -0
  52. package/esm/src/kernel/engine/runner/state.d.ts +16 -0
  53. package/esm/src/kernel/engine/runner/state.js +8 -0
  54. package/esm/src/kernel/engine/runner/steps.d.ts +15 -0
  55. package/esm/src/kernel/engine/runner/steps.js +119 -0
  56. package/esm/src/kernel/engine/runner/stream.d.ts +11 -0
  57. package/esm/src/kernel/engine/runner/stream.js +70 -0
  58. package/esm/src/kernel/engine/runner/tokens.d.ts +3 -0
  59. package/esm/src/kernel/engine/runner/tokens.js +38 -0
  60. package/esm/src/kernel/engine/runner/tools.d.ts +13 -0
  61. package/esm/src/kernel/engine/runner/tools.js +192 -0
  62. package/{src/kernel/engine/runner.ts → esm/src/kernel/engine/runner.d.ts} +1 -2
  63. package/esm/src/kernel/engine/runner.js +6 -0
  64. package/esm/src/kernel/engine/tree.d.ts +2 -0
  65. package/esm/src/kernel/engine/tree.js +17 -0
  66. package/esm/src/kernel/mod.d.ts +18 -0
  67. package/esm/src/kernel/mod.js +16 -0
  68. package/esm/src/kernel/registry/attachments.d.ts +16 -0
  69. package/esm/src/kernel/registry/attachments.js +156 -0
  70. package/esm/src/kernel/registry/catalog.d.ts +31 -0
  71. package/esm/src/kernel/registry/catalog.js +135 -0
  72. package/esm/src/kernel/registry/ingress.d.ts +13 -0
  73. package/esm/src/kernel/registry/ingress.js +163 -0
  74. package/esm/src/kernel/registry/profiles.d.ts +34 -0
  75. package/esm/src/kernel/registry/profiles.js +120 -0
  76. package/esm/src/kernel/registry/provider-request.d.ts +4 -0
  77. package/esm/src/kernel/registry/provider-request.js +25 -0
  78. package/esm/src/kernel/registry/resolve.d.ts +19 -0
  79. package/esm/src/kernel/registry/resolve.js +217 -0
  80. package/esm/src/kernel/registry/schemas.d.ts +14 -0
  81. package/esm/src/kernel/registry/schemas.js +23 -0
  82. package/esm/src/kernel/registry/tools.d.ts +12 -0
  83. package/esm/src/kernel/registry/tools.js +36 -0
  84. package/{src/kernel/registry/vault.ts → esm/src/kernel/registry/vault.d.ts} +2 -17
  85. package/esm/src/kernel/registry/vault.js +18 -0
  86. package/esm/src/kernel/types.d.ts +524 -0
  87. package/esm/src/kernel/types.js +10 -0
  88. package/esm/src/observability/mod.d.ts +12 -0
  89. package/{src/observability/mod.ts → esm/src/observability/mod.js} +2 -11
  90. package/esm/src/observability/spans.d.ts +16 -0
  91. package/esm/src/observability/spans.js +56 -0
  92. package/esm/src/observability/trace-attach.d.ts +16 -0
  93. package/esm/src/observability/trace-attach.js +67 -0
  94. package/esm/src/observability/trace-record.d.ts +113 -0
  95. package/esm/src/observability/trace-record.js +143 -0
  96. package/esm/src/observability/trace-usage.d.ts +3 -0
  97. package/esm/src/observability/trace-usage.js +32 -0
  98. package/esm/src/observability/trace.d.ts +23 -0
  99. package/esm/src/observability/trace.js +121 -0
  100. package/esm/src/presets/google.d.ts +50 -0
  101. package/esm/src/presets/google.js +96 -0
  102. package/esm/src/presets/mod.d.ts +11 -0
  103. package/esm/src/presets/mod.js +10 -0
  104. package/esm/src/providers/create-provider.d.ts +29 -0
  105. package/esm/src/providers/create-provider.js +38 -0
  106. package/esm/src/providers/gemini-tape.d.ts +2 -0
  107. package/esm/src/providers/gemini-tape.js +46 -0
  108. package/esm/src/providers/google-tap.d.ts +3 -0
  109. package/esm/src/providers/google-tap.js +48 -0
  110. package/esm/src/providers/interactions.d.ts +5 -0
  111. package/esm/src/providers/interactions.js +153 -0
  112. package/esm/src/providers/keys.d.ts +19 -0
  113. package/esm/src/providers/keys.js +129 -0
  114. package/esm/src/providers/mod.d.ts +12 -0
  115. package/{src/providers/mod.ts → esm/src/providers/mod.js} +2 -4
  116. package/esm/src/providers/openrouter-mod.d.ts +13 -0
  117. package/{src/providers/openrouter-mod.ts → esm/src/providers/openrouter-mod.js} +3 -7
  118. package/esm/src/providers/openrouter-payload.d.ts +32 -0
  119. package/esm/src/providers/openrouter-payload.js +179 -0
  120. package/esm/src/providers/openrouter.d.ts +15 -0
  121. package/esm/src/providers/openrouter.js +589 -0
  122. package/esm/src/providers/pcm.d.ts +7 -0
  123. package/esm/src/providers/pcm.js +35 -0
  124. package/esm/src/providers/provider.d.ts +15 -0
  125. package/esm/src/providers/provider.js +160 -0
  126. package/esm/src/providers/speech.d.ts +23 -0
  127. package/esm/src/providers/speech.js +125 -0
  128. package/esm/src/providers/sse.d.ts +7 -0
  129. package/esm/src/providers/sse.js +53 -0
  130. package/package.json +45 -36
  131. package/deno.json +0 -57
  132. package/deno.lock +0 -469
  133. package/src/cli/commands/profile.ts +0 -57
  134. package/src/cli/commands/run.ts +0 -66
  135. package/src/cli/commands/test.ts +0 -195
  136. package/src/cli/index.ts +0 -161
  137. package/src/cli/matrix/fixtures.ts +0 -96
  138. package/src/cli/matrix/synthesizer.ts +0 -240
  139. package/src/guardrails/error.ts +0 -142
  140. package/src/guardrails/injection.ts +0 -254
  141. package/src/guardrails/mod.ts +0 -40
  142. package/src/guardrails/quota.ts +0 -87
  143. package/src/guardrails/sanitize.ts +0 -165
  144. package/src/guardrails/sensitive.ts +0 -96
  145. package/src/host/mint-trace.ts +0 -54
  146. package/src/host/reply.ts +0 -32
  147. package/src/kernel/engine/assert.ts +0 -29
  148. package/src/kernel/engine/boundary.ts +0 -75
  149. package/src/kernel/engine/delta.ts +0 -440
  150. package/src/kernel/engine/hash.ts +0 -11
  151. package/src/kernel/engine/record.ts +0 -8
  152. package/src/kernel/engine/repair.ts +0 -56
  153. package/src/kernel/engine/runner/gates.ts +0 -338
  154. package/src/kernel/engine/runner/mod.ts +0 -135
  155. package/src/kernel/engine/runner/state.ts +0 -31
  156. package/src/kernel/engine/runner/steps.ts +0 -183
  157. package/src/kernel/engine/runner/stream.ts +0 -83
  158. package/src/kernel/engine/runner/tokens.ts +0 -47
  159. package/src/kernel/engine/runner/tools.ts +0 -266
  160. package/src/kernel/engine/tree.ts +0 -18
  161. package/src/kernel/mod.ts +0 -39
  162. package/src/kernel/registry/attachments.ts +0 -195
  163. package/src/kernel/registry/catalog.ts +0 -181
  164. package/src/kernel/registry/ingress.ts +0 -223
  165. package/src/kernel/registry/profiles.ts +0 -165
  166. package/src/kernel/registry/provider-request.ts +0 -31
  167. package/src/kernel/registry/resolve.ts +0 -290
  168. package/src/kernel/registry/schemas.ts +0 -29
  169. package/src/kernel/registry/tools.ts +0 -45
  170. package/src/kernel/types.ts +0 -576
  171. package/src/observability/spans.ts +0 -70
  172. package/src/observability/trace-attach.ts +0 -96
  173. package/src/observability/trace-record.ts +0 -254
  174. package/src/observability/trace-usage.ts +0 -36
  175. package/src/observability/trace.ts +0 -143
  176. package/src/presets/google.ts +0 -147
  177. package/src/presets/mod.ts +0 -24
  178. package/src/providers/create-provider.ts +0 -64
  179. package/src/providers/gemini-tape.ts +0 -59
  180. package/src/providers/google-tap.ts +0 -57
  181. package/src/providers/interactions.ts +0 -182
  182. package/src/providers/keys.ts +0 -182
  183. package/src/providers/openrouter-payload.ts +0 -232
  184. package/src/providers/openrouter.ts +0 -758
  185. package/src/providers/pcm.ts +0 -37
  186. package/src/providers/provider.ts +0 -206
  187. package/src/providers/speech.ts +0 -180
  188. package/src/providers/sse.ts +0 -59
@@ -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 };
@@ -0,0 +1,67 @@
1
+ import { providerCompleteRequest } from '../kernel/registry/provider-request.js';
2
+ import { tapeGemini } from '../providers/gemini-tape.js';
3
+ import { toInteractionsBody } from '../providers/interactions.js';
4
+ import { httpStatus } from './trace-usage.js';
5
+ function attachResolved(record, args) {
6
+ const { safe, model, bucket, generation } = args;
7
+ if (safe.projectId) {
8
+ record.projectId = safe.projectId;
9
+ }
10
+ if (safe.select) {
11
+ record.select = safe.select;
12
+ }
13
+ if (safe.thinking !== undefined) {
14
+ record.thinking = safe.thinking;
15
+ }
16
+ if (safe.tools) {
17
+ record.tools = safe.tools;
18
+ }
19
+ if (safe.metadata) {
20
+ record.metadata = safe.metadata;
21
+ }
22
+ if (model) {
23
+ record.model = {
24
+ id: model,
25
+ apiId: generation?.apiId ?? model,
26
+ };
27
+ }
28
+ if (bucket) {
29
+ record.bucket = bucket;
30
+ }
31
+ if (generation) {
32
+ record.generation = {
33
+ thinking: generation.thinking,
34
+ summaries: generation.summaries,
35
+ temperature: generation.temperature,
36
+ maxOutputTokens: generation.maxOutputTokens,
37
+ builtins: generation.builtins,
38
+ custom: generation.custom,
39
+ structured: generation.structured,
40
+ image: generation.image,
41
+ };
42
+ }
43
+ }
44
+ async function attachTape(record, args) {
45
+ const { gemini, canary, system, generation } = args;
46
+ if (gemini !== undefined) {
47
+ record.gemini = await tapeGemini(gemini, canary ?? '');
48
+ }
49
+ if (generation && system !== undefined) {
50
+ record.wire = await tapeGemini(toInteractionsBody(providerCompleteRequest(generation, system)), canary ?? '');
51
+ }
52
+ }
53
+ function attachUsage(record, gemini, done) {
54
+ if (done?.usage !== undefined) {
55
+ record.usage = done.usage;
56
+ }
57
+ const upStatus = httpStatus(gemini);
58
+ if (upStatus !== undefined || done) {
59
+ record.upstream = {
60
+ status: upStatus,
61
+ id: done?.id,
62
+ finish: done?.status,
63
+ serviceTier: done?.service_tier ?? done?.serviceTier,
64
+ };
65
+ }
66
+ }
67
+ export { attachResolved, attachTape, attachUsage };
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Trace record construction types.
3
+ *
4
+ * Trace records preserve useful execution evidence while hashing or omitting
5
+ * unsafe media bytes and canary-sensitive content.
6
+ *
7
+ * @module
8
+ */
9
+ import type { ResolvedGeneration, TurnEvent, TurnRequest } from '../kernel/types.js';
10
+ /** Hash-only image reference stored in trace records. */
11
+ export interface TraceImage {
12
+ mimeType: string;
13
+ sha256: string;
14
+ }
15
+ /** Trace-safe copy of a public turn event. */
16
+ export interface TraceEvent {
17
+ type: string;
18
+ text?: string;
19
+ tool?: {
20
+ name: string;
21
+ arguments?: Record<string, unknown>;
22
+ result?: {
23
+ status: string;
24
+ finding?: string;
25
+ data?: Record<string, unknown>;
26
+ };
27
+ };
28
+ structured?: unknown;
29
+ media?: TraceImage;
30
+ grounding?: TurnEvent['grounding'];
31
+ evidence?: TurnEvent['evidence'];
32
+ error?: string;
33
+ errorInternal?: string;
34
+ }
35
+ /** Complete trace-safe record for one attempted turn. */
36
+ interface TraceRecord {
37
+ v: number;
38
+ id: string;
39
+ ts: number;
40
+ ms: number;
41
+ streamed: boolean;
42
+ cancelled: boolean;
43
+ previousInteractionId: string | null;
44
+ store: boolean | null;
45
+ profile: string;
46
+ title?: string;
47
+ projectId?: string;
48
+ select?: string;
49
+ thinking?: boolean;
50
+ tools?: TurnRequest['tools'];
51
+ metadata?: Record<string, unknown>;
52
+ model?: {
53
+ id: string;
54
+ apiId: string;
55
+ };
56
+ bucket?: string;
57
+ generation?: {
58
+ thinking: string;
59
+ summaries: string;
60
+ temperature: number;
61
+ maxOutputTokens: number;
62
+ builtins: string[];
63
+ custom: string[];
64
+ structured: string | null;
65
+ image: unknown;
66
+ };
67
+ input: {
68
+ text?: string;
69
+ role?: string;
70
+ slots?: Record<string, string>;
71
+ attachments: TraceImage[];
72
+ voice: TraceImage[];
73
+ images?: TraceImage[];
74
+ audio?: TraceImage[];
75
+ };
76
+ wire?: unknown;
77
+ events: TraceEvent[];
78
+ gemini?: unknown;
79
+ usage?: unknown;
80
+ upstream?: {
81
+ status?: unknown;
82
+ id?: unknown;
83
+ finish?: unknown;
84
+ serviceTier?: unknown;
85
+ };
86
+ ok: boolean;
87
+ error?: string;
88
+ errorInternal?: string;
89
+ app?: Record<string, unknown>;
90
+ cutout?: {
91
+ ok: boolean;
92
+ ms: number;
93
+ url?: string;
94
+ inSha256?: string;
95
+ outSha256?: string;
96
+ http?: unknown;
97
+ error?: string;
98
+ };
99
+ }
100
+ declare function buildRecord(args: {
101
+ req: TurnRequest;
102
+ events: TurnEvent[];
103
+ started: number;
104
+ model?: string;
105
+ bucket?: string;
106
+ thrown?: unknown;
107
+ gemini?: unknown;
108
+ canary?: string;
109
+ system?: string;
110
+ generation?: ResolvedGeneration;
111
+ }): Promise<TraceRecord>;
112
+ export type { TraceRecord };
113
+ export { buildRecord };
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Trace record construction types.
3
+ *
4
+ * Trace records preserve useful execution evidence while hashing or omitting
5
+ * unsafe media bytes and canary-sensitive content.
6
+ *
7
+ * @module
8
+ */
9
+ import { publicError } from '../guardrails/error.js';
10
+ import { sanitizeText, sanitizeTurnRequest } from '../guardrails/sanitize.js';
11
+ import { OMIT_CANARY } from '../kernel/engine/boundary.js';
12
+ import { sha256 } from '../kernel/engine/hash.js';
13
+ import { attachResolved, attachTape, attachUsage } from './trace-attach.js';
14
+ import { completedInteraction } from './trace-usage.js';
15
+ const TRACE_VERSION = 2;
16
+ const TITLE_MAX = 80;
17
+ function hashBlobs(blobs) {
18
+ if (!blobs) {
19
+ return Promise.resolve([]);
20
+ }
21
+ return Promise.all(blobs.map(async (blob) => ({
22
+ mimeType: blob.mimeType,
23
+ sha256: await sha256(blob.data),
24
+ })));
25
+ }
26
+ async function snapshotEvent(event) {
27
+ const row = { type: event.type };
28
+ if (event.text) {
29
+ row.text = sanitizeText(event.text);
30
+ }
31
+ if (event.error) {
32
+ row.error = event.error;
33
+ }
34
+ if (event.errorInternal) {
35
+ row.errorInternal = sanitizeText(event.errorInternal);
36
+ }
37
+ if (event.structured !== undefined) {
38
+ row.structured = event.structured;
39
+ }
40
+ if (event.tool) {
41
+ const { name, arguments: args, result } = event.tool;
42
+ row.tool = { name, arguments: args };
43
+ if (result) {
44
+ row.tool.result = {
45
+ status: result.status,
46
+ ...(result.finding ? { finding: result.finding } : {}),
47
+ ...(result.data ? { data: result.data } : {}),
48
+ };
49
+ }
50
+ }
51
+ if (event.media) {
52
+ row.media = {
53
+ mimeType: event.media.mimeType,
54
+ sha256: await sha256(event.media.data),
55
+ };
56
+ }
57
+ if (event.grounding) {
58
+ row.grounding = event.grounding;
59
+ }
60
+ if (event.evidence) {
61
+ row.evidence = event.evidence;
62
+ }
63
+ return row;
64
+ }
65
+ function requestForTrace(req) {
66
+ try {
67
+ return sanitizeTurnRequest(req);
68
+ }
69
+ catch {
70
+ return { profile: req.profile, input: {} };
71
+ }
72
+ }
73
+ function internalError(err) {
74
+ if (typeof err === 'string') {
75
+ return sanitizeText(err);
76
+ }
77
+ if (err instanceof Error && err.message) {
78
+ return sanitizeText(err.message);
79
+ }
80
+ return undefined;
81
+ }
82
+ function titleFrom(text) {
83
+ if (!text) {
84
+ return undefined;
85
+ }
86
+ const trimmed = text.trim().replaceAll(/\s+/g, ' ');
87
+ if (!trimmed) {
88
+ return undefined;
89
+ }
90
+ return trimmed.slice(0, TITLE_MAX);
91
+ }
92
+ function attachFailure(record, thrown, lastErr, canary) {
93
+ if (!record.ok) {
94
+ record.error = publicError(thrown ?? lastErr?.error);
95
+ const inside = internalError(thrown) ?? lastErr?.errorInternal ?? lastErr?.error;
96
+ if (inside) {
97
+ record.errorInternal = inside;
98
+ }
99
+ }
100
+ if (canary && JSON.stringify(record).includes(canary)) {
101
+ record.errorInternal = OMIT_CANARY;
102
+ }
103
+ }
104
+ async function buildRecord(args) {
105
+ const { req, events, started, model, bucket, thrown, gemini, canary, system, generation } = args;
106
+ const safe = requestForTrace(req);
107
+ const input = safe.input ?? {};
108
+ const snapped = await Promise.all(events.map((event) => snapshotEvent(event)));
109
+ const lastErr = [...snapped].reverse().find((row) => row.type === 'error');
110
+ const done = completedInteraction(gemini);
111
+ const status = done?.status;
112
+ const ok = !(thrown || lastErr) && status !== 'cancelled';
113
+ const record = {
114
+ v: TRACE_VERSION,
115
+ id: crypto.randomUUID(),
116
+ ts: started,
117
+ ms: Date.now() - started,
118
+ streamed: true,
119
+ cancelled: status === 'cancelled',
120
+ previousInteractionId: safe.previousInteractionId ?? null,
121
+ store: safe.store ?? null,
122
+ profile: safe.profile,
123
+ input: {
124
+ text: input.text,
125
+ role: input.role,
126
+ slots: input.slots,
127
+ attachments: await hashBlobs(input.attachments),
128
+ voice: await hashBlobs(input.voice),
129
+ },
130
+ events: snapped,
131
+ ok,
132
+ };
133
+ const title = titleFrom(input.text);
134
+ if (title) {
135
+ record.title = title;
136
+ }
137
+ await attachTape(record, { gemini, canary, system, generation });
138
+ attachUsage(record, gemini, done);
139
+ attachResolved(record, { safe, model, bucket, generation });
140
+ attachFailure(record, thrown, lastErr, canary);
141
+ return record;
142
+ }
143
+ export { buildRecord };
@@ -0,0 +1,3 @@
1
+ declare function completedInteraction(gemini: unknown): Record<string, unknown> | undefined;
2
+ declare function httpStatus(gemini: unknown): unknown;
3
+ export { completedInteraction, httpStatus };
@@ -0,0 +1,32 @@
1
+ import { asRecord } from '../kernel/engine/record.js';
2
+ function eventName(row) {
3
+ return String(row.event_type ?? row.eventType ?? '');
4
+ }
5
+ function completedInteraction(gemini) {
6
+ if (!Array.isArray(gemini)) {
7
+ return undefined;
8
+ }
9
+ for (let i = gemini.length - 1; i >= 0; i -= 1) {
10
+ const row = asRecord(gemini[i]);
11
+ if (row) {
12
+ const name = eventName(row);
13
+ if (name === 'interaction.completed' || name === 'interaction.complete') {
14
+ return asRecord(row.interaction) ?? row;
15
+ }
16
+ }
17
+ }
18
+ return undefined;
19
+ }
20
+ function httpStatus(gemini) {
21
+ if (!Array.isArray(gemini)) {
22
+ return undefined;
23
+ }
24
+ for (const item of gemini) {
25
+ const row = asRecord(item);
26
+ if (row && eventName(row) === 'http_response') {
27
+ return row.status;
28
+ }
29
+ }
30
+ return undefined;
31
+ }
32
+ export { completedInteraction, httpStatus };
@@ -0,0 +1,23 @@
1
+ import type { TraceRecord } from './trace-record.js';
2
+ /** Minimal async destination for completed turn trace records. */
3
+ interface TraceSink {
4
+ write: (record: TraceRecord) => Promise<void>;
5
+ }
6
+ /** Write a trace record without allowing trace failures to fail the turn. */
7
+ declare function writeTrace(sink: TraceSink, record: Promise<TraceRecord>): Promise<void>;
8
+ /** Trace sink that drops records. */
9
+ declare function noopSink(): TraceSink;
10
+ /** Trace sink that appends records to a caller-owned array. */
11
+ declare function memorySink(into: TraceRecord[]): TraceSink;
12
+ /** Trace sink that writes daily rotating JSONL files under a host-selected directory. */
13
+ declare function jsonlSink(dir: string, now?: () => number): TraceSink;
14
+ /** Resolve a trace directory while refusing relative paths or paths inside the clone. */
15
+ declare function resolveTraceDir(args: {
16
+ dir?: string;
17
+ fallbackDir?: string;
18
+ cwd?: string;
19
+ }): string | undefined;
20
+ /** Build a JSONL sink from a host-supplied directory or return a noop sink. */
21
+ declare function sinkFromDir(dir?: string, fallbackDir?: string): TraceSink;
22
+ export type { TraceSink };
23
+ export { jsonlSink, memorySink, noopSink, resolveTraceDir, sinkFromDir, writeTrace };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Trace sink primitives for THEORUM.
3
+ *
4
+ * Tracing is host-injected: the kernel can write to a provided sink, a memory
5
+ * sink, a JSONL directory, or a noop sink. It does not read environment
6
+ * variables or own a database destination.
7
+ *
8
+ * @module
9
+ */
10
+ import * as dntShim from "../../_dnt.shims.js";
11
+ const RETAIN_DAYS = 14;
12
+ const HOURS_PER_DAY = 24;
13
+ const MIN_PER_HOUR = 60;
14
+ const SEC_PER_MIN = 60;
15
+ const MS_PER_SEC = 1000;
16
+ const RETAIN_MS = RETAIN_DAYS * HOURS_PER_DAY * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SEC;
17
+ const KIB = 1024;
18
+ const MIB = KIB * KIB;
19
+ const ROTATE_MIB = 32;
20
+ const ROTATE_BYTES = ROTATE_MIB * MIB;
21
+ const FILE_DAY = /^turns-(\d{4}-\d{2}-\d{2})(?:-\d+)?\.jsonl$/;
22
+ /** Write a trace record without allowing trace failures to fail the turn. */
23
+ async function writeTrace(sink, record) {
24
+ try {
25
+ await sink.write(await record);
26
+ }
27
+ catch {
28
+ // Tracing must not fail the turn.
29
+ }
30
+ }
31
+ /** Trace sink that drops records. */
32
+ function noopSink() {
33
+ return { write: () => Promise.resolve() };
34
+ }
35
+ /** Trace sink that appends records to a caller-owned array. */
36
+ function memorySink(into) {
37
+ return {
38
+ write: (record) => {
39
+ into.push(record);
40
+ return Promise.resolve();
41
+ },
42
+ };
43
+ }
44
+ function dayStamp(ms) {
45
+ return new Date(ms).toISOString().slice(0, 10);
46
+ }
47
+ function fileDay(name) {
48
+ return FILE_DAY.exec(name)?.[1];
49
+ }
50
+ async function pruneTraces(dir, now) {
51
+ const cutoff = now - RETAIN_MS;
52
+ for await (const entry of dntShim.Deno.readDir(dir)) {
53
+ const day = fileDay(entry.name);
54
+ if (day && Date.parse(`${day}T00:00:00.000Z`) < cutoff) {
55
+ await dntShim.Deno.remove(`${dir}/${entry.name}`);
56
+ }
57
+ }
58
+ }
59
+ async function pickFile(dir, now) {
60
+ const day = dayStamp(now);
61
+ const base = `${dir}/turns-${day}.jsonl`;
62
+ try {
63
+ const info = await dntShim.Deno.stat(base);
64
+ if ((info.size ?? 0) < ROTATE_BYTES) {
65
+ return base;
66
+ }
67
+ }
68
+ catch {
69
+ return base;
70
+ }
71
+ return `${dir}/turns-${day}-${now}.jsonl`;
72
+ }
73
+ /** Trace sink that writes daily rotating JSONL files under a host-selected directory. */
74
+ function jsonlSink(dir, now = Date.now) {
75
+ return {
76
+ write: async (record) => {
77
+ const at = now();
78
+ await dntShim.Deno.mkdir(dir, { recursive: true });
79
+ await pruneTraces(dir, at);
80
+ const path = await pickFile(dir, at);
81
+ await dntShim.Deno.writeTextFile(path, `${JSON.stringify(record)}\n`, { append: true });
82
+ },
83
+ };
84
+ }
85
+ function insideDir(path, root) {
86
+ let base = root;
87
+ if (root.endsWith('/')) {
88
+ base = root.slice(0, -1);
89
+ }
90
+ if (path === base) {
91
+ return true;
92
+ }
93
+ return path.startsWith(`${base}/`);
94
+ }
95
+ /** Resolve a trace directory while refusing relative paths or paths inside the clone. */
96
+ function resolveTraceDir(args) {
97
+ const cwd = args.cwd ?? dntShim.Deno.cwd();
98
+ if (args.dir === '') {
99
+ return undefined;
100
+ }
101
+ let dir = args.dir?.trim() || args.fallbackDir;
102
+ if (!dir) {
103
+ return undefined;
104
+ }
105
+ if (!dir.startsWith('/') || insideDir(dir, cwd)) {
106
+ dir = args.fallbackDir;
107
+ }
108
+ if (!dir || insideDir(dir, cwd)) {
109
+ return undefined;
110
+ }
111
+ return dir;
112
+ }
113
+ /** Build a JSONL sink from a host-supplied directory or return a noop sink. */
114
+ function sinkFromDir(dir, fallbackDir) {
115
+ const resolved = resolveTraceDir({ dir, fallbackDir });
116
+ if (!resolved) {
117
+ return noopSink();
118
+ }
119
+ return jsonlSink(resolved);
120
+ }
121
+ export { jsonlSink, memorySink, noopSink, resolveTraceDir, sinkFromDir, writeTrace };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Google / Gemini convenience preset.
3
+ *
4
+ * Kernel stays open (`string` pins). This pack owns Google vocabularies as
5
+ * real unions so host profiles stay typed when they opt into the preset.
6
+ *
7
+ * Call `registerGooglePreset()` at host startup for tools; use the exported
8
+ * types/constants when authoring image/speech-adjacent profile fields.
9
+ *
10
+ * @module
11
+ */
12
+ import "../../_dnt.polyfills.js";
13
+ import type { ProfileImageSpec, ProfileSpeechSpec, ToolCatalogEntry } from '../kernel/types.js';
14
+ /** Google Interactions / Gemini grounding builtins. */
15
+ declare const GOOGLE_BUILTIN_TOOLS: Record<string, ToolCatalogEntry>;
16
+ /** Common Gemini image input MIME allowlist. */
17
+ declare const GOOGLE_IMAGE_INPUT_MIMES: readonly ["image/png", "image/jpeg", "image/webp", "image/heic", "image/heif"];
18
+ /** Common voice/audio input MIME allowlist for Gemini multimodal. */
19
+ declare const GOOGLE_VOICE_INPUT_MIMES: readonly ["audio/webm", "audio/wav", "audio/mpeg", "audio/mp4"];
20
+ /** Common Gemini TTS voice names for `outputs.speech.voice`. */
21
+ declare const GOOGLE_SPEECH_VOICES: readonly ["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"];
22
+ type GoogleSpeechVoice = (typeof GOOGLE_SPEECH_VOICES)[number];
23
+ /**
24
+ * `outputs.speech` pins narrowed to Google TTS vocabulary.
25
+ * Assignable to kernel `ProfileSpeechSpec`.
26
+ */
27
+ type GoogleSpeechPins = Omit<ProfileSpeechSpec, 'voice'> & {
28
+ voice?: GoogleSpeechVoice;
29
+ };
30
+ /** Aspect ratios commonly accepted by Gemini image models. */
31
+ declare const GOOGLE_IMAGE_ASPECT_RATIOS: readonly ["1:1", "3:2", "2:3", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"];
32
+ /** Image sizes commonly accepted by Gemini Flash Lite image. */
33
+ declare const GOOGLE_IMAGE_SIZES: readonly ["1K"];
34
+ type GoogleImageInputMime = (typeof GOOGLE_IMAGE_INPUT_MIMES)[number];
35
+ type GoogleVoiceInputMime = (typeof GOOGLE_VOICE_INPUT_MIMES)[number];
36
+ type GoogleImageAspectRatio = (typeof GOOGLE_IMAGE_ASPECT_RATIOS)[number];
37
+ type GoogleImageSize = (typeof GOOGLE_IMAGE_SIZES)[number];
38
+ /**
39
+ * `outputs.image` pins narrowed to Google image vocabulary.
40
+ * Assignable to kernel `ProfileImageSpec`.
41
+ */
42
+ type GoogleImagePins = Omit<ProfileImageSpec, 'aspectRatio' | 'size' | 'mimeType'> & {
43
+ aspectRatio?: GoogleImageAspectRatio;
44
+ size?: GoogleImageSize;
45
+ mimeType?: GoogleImageInputMime | 'image/jpeg';
46
+ };
47
+ /** Register Google provider builtins into the process-local tool catalog. */
48
+ declare function registerGooglePreset(): void;
49
+ export type { GoogleImageAspectRatio, GoogleImageInputMime, GoogleImagePins, GoogleImageSize, GoogleSpeechPins, GoogleSpeechVoice, GoogleVoiceInputMime, };
50
+ export { GOOGLE_BUILTIN_TOOLS, GOOGLE_IMAGE_ASPECT_RATIOS, GOOGLE_IMAGE_INPUT_MIMES, GOOGLE_IMAGE_SIZES, GOOGLE_SPEECH_VOICES, GOOGLE_VOICE_INPUT_MIMES, registerGooglePreset, };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Google / Gemini convenience preset.
3
+ *
4
+ * Kernel stays open (`string` pins). This pack owns Google vocabularies as
5
+ * real unions so host profiles stay typed when they opt into the preset.
6
+ *
7
+ * Call `registerGooglePreset()` at host startup for tools; use the exported
8
+ * types/constants when authoring image/speech-adjacent profile fields.
9
+ *
10
+ * @module
11
+ */
12
+ import "../../_dnt.polyfills.js";
13
+ import { registerTools } from '../kernel/registry/catalog.js';
14
+ /** Google Interactions / Gemini grounding builtins. */
15
+ const GOOGLE_BUILTIN_TOOLS = {
16
+ googleSearch: {
17
+ kind: 'builtin',
18
+ ui: true,
19
+ interactionsType: 'google_search',
20
+ openRouterPlugin: 'web',
21
+ },
22
+ googleMaps: {
23
+ kind: 'builtin',
24
+ ui: true,
25
+ interactionsType: 'google_maps',
26
+ conflictsWith: ['googleSearch', 'urlContext'],
27
+ },
28
+ urlContext: {
29
+ kind: 'builtin',
30
+ ui: true,
31
+ interactionsType: 'url_context',
32
+ },
33
+ };
34
+ /** Common Gemini image input MIME allowlist. */
35
+ const GOOGLE_IMAGE_INPUT_MIMES = [
36
+ 'image/png',
37
+ 'image/jpeg',
38
+ 'image/webp',
39
+ 'image/heic',
40
+ 'image/heif',
41
+ ];
42
+ /** Common voice/audio input MIME allowlist for Gemini multimodal. */
43
+ const GOOGLE_VOICE_INPUT_MIMES = ['audio/webm', 'audio/wav', 'audio/mpeg', 'audio/mp4'];
44
+ /** Common Gemini TTS voice names for `outputs.speech.voice`. */
45
+ const GOOGLE_SPEECH_VOICES = [
46
+ 'Zephyr',
47
+ 'Puck',
48
+ 'Charon',
49
+ 'Kore',
50
+ 'Fenrir',
51
+ 'Leda',
52
+ 'Orus',
53
+ 'Aoede',
54
+ 'Callirrhoe',
55
+ 'Autonoe',
56
+ 'Enceladus',
57
+ 'Iapetus',
58
+ 'Umbriel',
59
+ 'Algieba',
60
+ 'Despina',
61
+ 'Erinome',
62
+ 'Algenib',
63
+ 'Rasalgethi',
64
+ 'Laomedeia',
65
+ 'Achernar',
66
+ 'Alnilam',
67
+ 'Schedar',
68
+ 'Gacrux',
69
+ 'Pulcherrima',
70
+ 'Achird',
71
+ 'Zubenelgenubi',
72
+ 'Vindemiatrix',
73
+ 'Sadachbia',
74
+ 'Sadaltager',
75
+ 'Sulafat',
76
+ ];
77
+ /** Aspect ratios commonly accepted by Gemini image models. */
78
+ const GOOGLE_IMAGE_ASPECT_RATIOS = [
79
+ '1:1',
80
+ '3:2',
81
+ '2:3',
82
+ '3:4',
83
+ '4:3',
84
+ '4:5',
85
+ '5:4',
86
+ '9:16',
87
+ '16:9',
88
+ '21:9',
89
+ ];
90
+ /** Image sizes commonly accepted by Gemini Flash Lite image. */
91
+ const GOOGLE_IMAGE_SIZES = ['1K'];
92
+ /** Register Google provider builtins into the process-local tool catalog. */
93
+ function registerGooglePreset() {
94
+ registerTools(GOOGLE_BUILTIN_TOOLS);
95
+ }
96
+ export { GOOGLE_BUILTIN_TOOLS, GOOGLE_IMAGE_ASPECT_RATIOS, GOOGLE_IMAGE_INPUT_MIMES, GOOGLE_IMAGE_SIZES, GOOGLE_SPEECH_VOICES, GOOGLE_VOICE_INPUT_MIMES, registerGooglePreset, };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Optional THEORUM presets.
3
+ *
4
+ * Presets register host-convenience catalogs (provider builtins, media
5
+ * vocabularies, later model packs) without baking product opinions into the kernel.
6
+ *
7
+ * @module
8
+ */
9
+ import "../../_dnt.polyfills.js";
10
+ export type { GoogleImageAspectRatio, GoogleImageInputMime, GoogleImagePins, GoogleImageSize, GoogleVoiceInputMime, } from './google.js';
11
+ export { GOOGLE_BUILTIN_TOOLS, GOOGLE_IMAGE_ASPECT_RATIOS, GOOGLE_IMAGE_INPUT_MIMES, GOOGLE_IMAGE_SIZES, GOOGLE_VOICE_INPUT_MIMES, registerGooglePreset, } from './google.js';