theorum 0.1.4 → 0.1.6

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 (191) hide show
  1. package/docs/AGENT_PROFILE_CONTRACT.md +2 -2
  2. package/esm/_dnt.polyfills.d.ts +110 -0
  3. package/esm/_dnt.polyfills.js +144 -0
  4. package/esm/_dnt.shims.d.ts +5 -0
  5. package/esm/_dnt.shims.js +61 -0
  6. package/{mod.ts → esm/mod.d.ts} +17 -57
  7. package/esm/mod.js +50 -0
  8. package/esm/package.json +3 -0
  9. package/esm/src/cli/commands/profile.d.ts +2 -0
  10. package/esm/src/cli/commands/profile.js +53 -0
  11. package/esm/src/cli/commands/run.d.ts +10 -0
  12. package/esm/src/cli/commands/run.js +55 -0
  13. package/esm/src/cli/commands/test.d.ts +15 -0
  14. package/esm/src/cli/commands/test.js +140 -0
  15. package/esm/src/cli/index.d.ts +4 -0
  16. package/esm/src/cli/index.js +148 -0
  17. package/esm/src/cli/matrix/fixtures.d.ts +13 -0
  18. package/esm/src/cli/matrix/fixtures.js +77 -0
  19. package/esm/src/cli/matrix/synthesizer.d.ts +29 -0
  20. package/esm/src/cli/matrix/synthesizer.js +187 -0
  21. package/esm/src/guardrails/error.d.ts +45 -0
  22. package/esm/src/guardrails/error.js +149 -0
  23. package/esm/src/guardrails/injection.d.ts +12 -0
  24. package/esm/src/guardrails/injection.js +220 -0
  25. package/esm/src/guardrails/mod.d.ts +16 -0
  26. package/esm/src/guardrails/mod.js +15 -0
  27. package/esm/src/guardrails/quota.d.ts +10 -0
  28. package/esm/src/guardrails/quota.js +64 -0
  29. package/esm/src/guardrails/sanitize.d.ts +22 -0
  30. package/esm/src/guardrails/sanitize.js +133 -0
  31. package/esm/src/guardrails/sensitive.d.ts +12 -0
  32. package/esm/src/guardrails/sensitive.js +88 -0
  33. package/esm/src/host/mint-trace.d.ts +27 -0
  34. package/esm/src/host/mint-trace.js +33 -0
  35. package/esm/src/host/mod.d.ts +13 -0
  36. package/{src/host/mod.ts → esm/src/host/mod.js} +3 -11
  37. package/esm/src/host/reply.d.ts +14 -0
  38. package/esm/src/host/reply.js +27 -0
  39. package/esm/src/kernel/engine/boundary.d.ts +10 -0
  40. package/esm/src/kernel/engine/boundary.js +55 -0
  41. package/esm/src/kernel/engine/delta.d.ts +8 -0
  42. package/esm/src/kernel/engine/delta.js +389 -0
  43. package/esm/src/kernel/engine/hash.d.ts +1 -0
  44. package/esm/src/kernel/engine/hash.js +9 -0
  45. package/esm/src/kernel/engine/record.d.ts +2 -0
  46. package/esm/src/kernel/engine/record.js +7 -0
  47. package/esm/src/kernel/engine/repair.d.ts +7 -0
  48. package/esm/src/kernel/engine/repair.js +38 -0
  49. package/esm/src/kernel/engine/runner/gates.d.ts +4 -0
  50. package/esm/src/kernel/engine/runner/gates.js +208 -0
  51. package/esm/src/kernel/engine/runner/mod.d.ts +14 -0
  52. package/esm/src/kernel/engine/runner/mod.js +103 -0
  53. package/esm/src/kernel/engine/runner/schema-validation.d.ts +22 -0
  54. package/esm/src/kernel/engine/runner/schema-validation.js +113 -0
  55. package/esm/src/kernel/engine/runner/state.d.ts +16 -0
  56. package/esm/src/kernel/engine/runner/state.js +8 -0
  57. package/esm/src/kernel/engine/runner/steps.d.ts +15 -0
  58. package/esm/src/kernel/engine/runner/steps.js +127 -0
  59. package/esm/src/kernel/engine/runner/stream.d.ts +11 -0
  60. package/esm/src/kernel/engine/runner/stream.js +70 -0
  61. package/esm/src/kernel/engine/runner/tokens.d.ts +3 -0
  62. package/esm/src/kernel/engine/runner/tokens.js +38 -0
  63. package/esm/src/kernel/engine/runner/tools.d.ts +13 -0
  64. package/esm/src/kernel/engine/runner/tools.js +192 -0
  65. package/{src/kernel/engine/runner.ts → esm/src/kernel/engine/runner.d.ts} +1 -2
  66. package/esm/src/kernel/engine/runner.js +6 -0
  67. package/esm/src/kernel/engine/tree.d.ts +2 -0
  68. package/esm/src/kernel/engine/tree.js +17 -0
  69. package/esm/src/kernel/mod.d.ts +18 -0
  70. package/esm/src/kernel/mod.js +16 -0
  71. package/esm/src/kernel/registry/attachments.d.ts +16 -0
  72. package/esm/src/kernel/registry/attachments.js +156 -0
  73. package/esm/src/kernel/registry/catalog.d.ts +31 -0
  74. package/esm/src/kernel/registry/catalog.js +135 -0
  75. package/esm/src/kernel/registry/ingress.d.ts +13 -0
  76. package/esm/src/kernel/registry/ingress.js +163 -0
  77. package/esm/src/kernel/registry/profiles.d.ts +34 -0
  78. package/esm/src/kernel/registry/profiles.js +120 -0
  79. package/esm/src/kernel/registry/provider-request.d.ts +4 -0
  80. package/esm/src/kernel/registry/provider-request.js +25 -0
  81. package/esm/src/kernel/registry/resolve.d.ts +19 -0
  82. package/esm/src/kernel/registry/resolve.js +217 -0
  83. package/esm/src/kernel/registry/schemas.d.ts +14 -0
  84. package/esm/src/kernel/registry/schemas.js +23 -0
  85. package/esm/src/kernel/registry/tools.d.ts +12 -0
  86. package/esm/src/kernel/registry/tools.js +36 -0
  87. package/{src/kernel/registry/vault.ts → esm/src/kernel/registry/vault.d.ts} +2 -17
  88. package/esm/src/kernel/registry/vault.js +18 -0
  89. package/esm/src/kernel/types.d.ts +528 -0
  90. package/esm/src/kernel/types.js +10 -0
  91. package/esm/src/observability/mod.d.ts +12 -0
  92. package/{src/observability/mod.ts → esm/src/observability/mod.js} +2 -11
  93. package/esm/src/observability/spans.d.ts +16 -0
  94. package/esm/src/observability/spans.js +56 -0
  95. package/esm/src/observability/trace-attach.d.ts +16 -0
  96. package/esm/src/observability/trace-attach.js +67 -0
  97. package/esm/src/observability/trace-record.d.ts +113 -0
  98. package/esm/src/observability/trace-record.js +143 -0
  99. package/esm/src/observability/trace-usage.d.ts +3 -0
  100. package/esm/src/observability/trace-usage.js +32 -0
  101. package/esm/src/observability/trace.d.ts +23 -0
  102. package/esm/src/observability/trace.js +121 -0
  103. package/esm/src/presets/google.d.ts +50 -0
  104. package/esm/src/presets/google.js +96 -0
  105. package/esm/src/presets/mod.d.ts +11 -0
  106. package/esm/src/presets/mod.js +10 -0
  107. package/esm/src/providers/create-provider.d.ts +29 -0
  108. package/esm/src/providers/create-provider.js +38 -0
  109. package/esm/src/providers/gemini-tape.d.ts +2 -0
  110. package/esm/src/providers/gemini-tape.js +46 -0
  111. package/esm/src/providers/google-tap.d.ts +3 -0
  112. package/esm/src/providers/google-tap.js +48 -0
  113. package/esm/src/providers/interactions.d.ts +5 -0
  114. package/esm/src/providers/interactions.js +153 -0
  115. package/esm/src/providers/keys.d.ts +19 -0
  116. package/esm/src/providers/keys.js +129 -0
  117. package/esm/src/providers/mod.d.ts +12 -0
  118. package/{src/providers/mod.ts → esm/src/providers/mod.js} +2 -4
  119. package/esm/src/providers/openrouter-mod.d.ts +13 -0
  120. package/{src/providers/openrouter-mod.ts → esm/src/providers/openrouter-mod.js} +3 -7
  121. package/esm/src/providers/openrouter-payload.d.ts +32 -0
  122. package/esm/src/providers/openrouter-payload.js +179 -0
  123. package/esm/src/providers/openrouter.d.ts +15 -0
  124. package/esm/src/providers/openrouter.js +589 -0
  125. package/esm/src/providers/pcm.d.ts +7 -0
  126. package/esm/src/providers/pcm.js +35 -0
  127. package/esm/src/providers/provider.d.ts +15 -0
  128. package/esm/src/providers/provider.js +160 -0
  129. package/esm/src/providers/speech.d.ts +23 -0
  130. package/esm/src/providers/speech.js +125 -0
  131. package/esm/src/providers/sse.d.ts +7 -0
  132. package/esm/src/providers/sse.js +53 -0
  133. package/package.json +45 -36
  134. package/deno.json +0 -57
  135. package/deno.lock +0 -469
  136. package/src/cli/commands/profile.ts +0 -57
  137. package/src/cli/commands/run.ts +0 -66
  138. package/src/cli/commands/test.ts +0 -195
  139. package/src/cli/index.ts +0 -161
  140. package/src/cli/matrix/fixtures.ts +0 -96
  141. package/src/cli/matrix/synthesizer.ts +0 -240
  142. package/src/guardrails/error.ts +0 -142
  143. package/src/guardrails/injection.ts +0 -254
  144. package/src/guardrails/mod.ts +0 -40
  145. package/src/guardrails/quota.ts +0 -87
  146. package/src/guardrails/sanitize.ts +0 -165
  147. package/src/guardrails/sensitive.ts +0 -96
  148. package/src/host/mint-trace.ts +0 -54
  149. package/src/host/reply.ts +0 -32
  150. package/src/kernel/engine/assert.ts +0 -29
  151. package/src/kernel/engine/boundary.ts +0 -75
  152. package/src/kernel/engine/delta.ts +0 -440
  153. package/src/kernel/engine/hash.ts +0 -11
  154. package/src/kernel/engine/record.ts +0 -8
  155. package/src/kernel/engine/repair.ts +0 -56
  156. package/src/kernel/engine/runner/gates.ts +0 -338
  157. package/src/kernel/engine/runner/mod.ts +0 -135
  158. package/src/kernel/engine/runner/state.ts +0 -31
  159. package/src/kernel/engine/runner/steps.ts +0 -183
  160. package/src/kernel/engine/runner/stream.ts +0 -83
  161. package/src/kernel/engine/runner/tokens.ts +0 -47
  162. package/src/kernel/engine/runner/tools.ts +0 -266
  163. package/src/kernel/engine/tree.ts +0 -18
  164. package/src/kernel/mod.ts +0 -39
  165. package/src/kernel/registry/attachments.ts +0 -195
  166. package/src/kernel/registry/catalog.ts +0 -181
  167. package/src/kernel/registry/ingress.ts +0 -223
  168. package/src/kernel/registry/profiles.ts +0 -165
  169. package/src/kernel/registry/provider-request.ts +0 -31
  170. package/src/kernel/registry/resolve.ts +0 -290
  171. package/src/kernel/registry/schemas.ts +0 -29
  172. package/src/kernel/registry/tools.ts +0 -45
  173. package/src/kernel/types.ts +0 -576
  174. package/src/observability/spans.ts +0 -70
  175. package/src/observability/trace-attach.ts +0 -96
  176. package/src/observability/trace-record.ts +0 -254
  177. package/src/observability/trace-usage.ts +0 -36
  178. package/src/observability/trace.ts +0 -143
  179. package/src/presets/google.ts +0 -147
  180. package/src/presets/mod.ts +0 -24
  181. package/src/providers/create-provider.ts +0 -64
  182. package/src/providers/gemini-tape.ts +0 -59
  183. package/src/providers/google-tap.ts +0 -57
  184. package/src/providers/interactions.ts +0 -182
  185. package/src/providers/keys.ts +0 -182
  186. package/src/providers/openrouter-payload.ts +0 -232
  187. package/src/providers/openrouter.ts +0 -758
  188. package/src/providers/pcm.ts +0 -37
  189. package/src/providers/provider.ts +0 -206
  190. package/src/providers/speech.ts +0 -180
  191. package/src/providers/sse.ts +0 -59
@@ -1,440 +0,0 @@
1
- import type { GroundingEvent, GroundingSource, TurnEvent, TurnTokens } from '../types.ts';
2
- import { asRecord } from './record.ts';
3
-
4
- function deltaText(delta: Record<string, unknown>): string {
5
- if (typeof delta.text === 'string') {
6
- return delta.text;
7
- }
8
- const { content } = delta;
9
- if (typeof content === 'string') {
10
- return content;
11
- }
12
- const nested = asRecord(content);
13
- if (nested && typeof nested.text === 'string') {
14
- return nested.text;
15
- }
16
- return '';
17
- }
18
-
19
- function deltaMedia(delta: Record<string, unknown>): TurnEvent | undefined {
20
- const mimeType = delta.mimeType ?? delta.mime_type;
21
- const { data } = delta;
22
- if (typeof mimeType === 'string' && typeof data === 'string' && data) {
23
- return { type: 'media', media: { mimeType, data } };
24
- }
25
- return undefined;
26
- }
27
-
28
- function eventIfText(type: 'thought' | 'text', delta: Record<string, unknown>): TurnEvent[] {
29
- const text = deltaText(delta);
30
- if (!text) {
31
- return [];
32
- }
33
- return [{ type, text }];
34
- }
35
-
36
- function eventsFromImage(delta: Record<string, unknown>): TurnEvent[] {
37
- const media = deltaMedia(delta);
38
- if (media) {
39
- return [media];
40
- }
41
- return [];
42
- }
43
-
44
- function eventsFromAudio(delta: Record<string, unknown>): TurnEvent[] {
45
- const media = deltaMedia(delta);
46
- if (media) {
47
- return [media];
48
- }
49
- // Google TTS deltas may ship data without a mime; treat as raw PCM.
50
- const { data } = delta;
51
- if (typeof data === 'string' && data) {
52
- return [{ type: 'media', media: { mimeType: 'audio/pcm', data } }];
53
- }
54
- return [];
55
- }
56
-
57
- function eventsFromDelta(deltaValue: unknown): TurnEvent[] {
58
- const delta = asRecord(deltaValue);
59
- if (!delta) {
60
- return [];
61
- }
62
- const deltaType = String(delta.type ?? '');
63
- if (deltaType === 'thought_summary' || deltaType === 'thought') {
64
- return eventIfText('thought', delta);
65
- }
66
- if (deltaType === 'text') {
67
- return eventIfText('text', delta);
68
- }
69
- if (deltaType === 'image') {
70
- return eventsFromImage(delta);
71
- }
72
- if (deltaType === 'audio' || deltaType === 'output_audio') {
73
- return eventsFromAudio(delta);
74
- }
75
- return [];
76
- }
77
-
78
- function mediaFromRecord(rec: Record<string, unknown>): TurnEvent | undefined {
79
- const mimeType = rec.mimeType ?? rec.mime_type;
80
- const { data } = rec;
81
- if (typeof mimeType === 'string' && typeof data === 'string' && data) {
82
- return { type: 'media', media: { mimeType, data } };
83
- }
84
- return undefined;
85
- }
86
-
87
- function mediaFromOutputItem(item: unknown): TurnEvent | undefined {
88
- const rec = asRecord(item);
89
- if (!rec) {
90
- return undefined;
91
- }
92
- if (rec.type !== 'image' && rec.type !== 'media' && rec.type !== 'audio') {
93
- return undefined;
94
- }
95
- return mediaFromRecord(rec);
96
- }
97
-
98
- function mediaFromOutputs(outputs: unknown): TurnEvent | undefined {
99
- if (!Array.isArray(outputs)) {
100
- return undefined;
101
- }
102
- for (const item of outputs) {
103
- const media = mediaFromOutputItem(item);
104
- if (media) {
105
- return media;
106
- }
107
- }
108
- return undefined;
109
- }
110
-
111
- function mediaFromComplete(event: Record<string, unknown>): TurnEvent | undefined {
112
- const interaction = asRecord(event.interaction) ?? event;
113
- const directImage = asRecord(interaction.output_image);
114
- if (directImage) {
115
- const media = mediaFromRecord(directImage);
116
- if (media) {
117
- return media;
118
- }
119
- }
120
- const directAudio = asRecord(interaction.output_audio);
121
- if (directAudio) {
122
- const media = mediaFromRecord(directAudio);
123
- if (media) {
124
- return media;
125
- }
126
- // Google TTS convenience field: base64 PCM without mime.
127
- const { data } = directAudio;
128
- if (typeof data === 'string' && data) {
129
- return { type: 'media', media: { mimeType: 'audio/pcm', data } };
130
- }
131
- }
132
- return mediaFromOutputs(interaction.outputs);
133
- }
134
-
135
- function sourceFromMaps(maps: Record<string, unknown>): GroundingSource | undefined {
136
- const uri = maps.uri ?? maps.googleMapsUri ?? maps.google_maps_uri;
137
- if (typeof uri !== 'string' || !uri) {
138
- return undefined;
139
- }
140
- const title = maps.title ?? maps.name;
141
- return {
142
- type: 'maps',
143
- uri,
144
- title: typeof title === 'string' && title ? title : uri,
145
- };
146
- }
147
-
148
- function sourceFromWeb(web: Record<string, unknown>): GroundingSource | undefined {
149
- const uri = web.uri;
150
- if (typeof uri !== 'string' || !uri) {
151
- return undefined;
152
- }
153
- const title = web.title ?? web.domain;
154
- return {
155
- type: 'web',
156
- uri,
157
- title: typeof title === 'string' && title ? title : uri,
158
- };
159
- }
160
-
161
- function pushUniqueSource(sources: GroundingSource[], source: GroundingSource | undefined): void {
162
- if (!source) {
163
- return;
164
- }
165
- if (!sources.some((item) => item.uri === source.uri && item.type === source.type)) {
166
- sources.push(source);
167
- }
168
- }
169
-
170
- function groundingChunks(metadata: Record<string, unknown>): unknown[] {
171
- const chunks = metadata.groundingChunks ?? metadata.grounding_chunks;
172
- if (Array.isArray(chunks)) {
173
- return chunks;
174
- }
175
- return [];
176
- }
177
-
178
- function searchHtml(metadata: Record<string, unknown>): string | undefined {
179
- const searchEntryPoint = asRecord(metadata.searchEntryPoint ?? metadata.search_entry_point);
180
- const renderedContent = searchEntryPoint?.renderedContent ?? searchEntryPoint?.rendered_content;
181
- if (typeof renderedContent === 'string' && renderedContent.trim()) {
182
- return renderedContent;
183
- }
184
- return undefined;
185
- }
186
-
187
- function sourcesFromChunks(chunks: unknown[]): GroundingSource[] {
188
- const sources: GroundingSource[] = [];
189
- for (const chunk of chunks) {
190
- const record = asRecord(chunk);
191
- if (!record) {
192
- continue;
193
- }
194
- const maps = asRecord(record.maps);
195
- if (maps) {
196
- pushUniqueSource(sources, sourceFromMaps(maps));
197
- }
198
- const web = asRecord(record.web);
199
- if (web) {
200
- pushUniqueSource(sources, sourceFromWeb(web));
201
- }
202
- }
203
- return sources;
204
- }
205
-
206
- function mergeGrounding(
207
- a: GroundingEvent | undefined,
208
- b: GroundingEvent | undefined,
209
- ): GroundingEvent | undefined {
210
- if (!a) {
211
- return b;
212
- }
213
- if (!b) {
214
- return a;
215
- }
216
- const chunks = [...(a.chunks ?? []), ...(b.chunks ?? [])];
217
- const sources = [...a.sources];
218
- for (const source of b.sources) {
219
- pushUniqueSource(sources, source);
220
- }
221
- return {
222
- metadata: b.metadata ?? a.metadata,
223
- ...(chunks.length > 0 ? { chunks } : {}),
224
- searchHtml: b.searchHtml ?? a.searchHtml,
225
- sources,
226
- };
227
- }
228
-
229
- function groundingFromMetadata(metadataValue: unknown): GroundingEvent | undefined {
230
- const metadata = asRecord(metadataValue);
231
- if (!metadata) {
232
- return undefined;
233
- }
234
- const chunks = groundingChunks(metadata);
235
- const sources = sourcesFromChunks(chunks);
236
- const html = searchHtml(metadata);
237
- if (chunks.length === 0 && sources.length === 0 && !html) {
238
- return { metadata, sources };
239
- }
240
- return {
241
- metadata,
242
- ...(chunks.length > 0 ? { chunks } : {}),
243
- ...(html ? { searchHtml: html } : {}),
244
- sources,
245
- };
246
- }
247
-
248
- function groundingMetadataFromRecord(record: Record<string, unknown>): unknown {
249
- return record.groundingMetadata ?? record.grounding_metadata;
250
- }
251
-
252
- function groundingFromStep(stepValue: unknown): GroundingEvent | undefined {
253
- const step = asRecord(stepValue);
254
- if (!step) {
255
- return undefined;
256
- }
257
- let grounding = groundingFromMetadata(groundingMetadataFromRecord(step));
258
- const content = step.content;
259
- if (Array.isArray(content)) {
260
- for (const block of content) {
261
- grounding = mergeGrounding(
262
- grounding,
263
- groundingFromMetadata(groundingMetadataFromRecord(asRecord(block) ?? {})),
264
- );
265
- }
266
- }
267
- return grounding;
268
- }
269
-
270
- function groundingFromEvent(event: Record<string, unknown>): TurnEvent | undefined {
271
- let grounding = groundingFromMetadata(groundingMetadataFromRecord(event));
272
- grounding = mergeGrounding(grounding, groundingFromStep(event.step));
273
- grounding = mergeGrounding(grounding, groundingFromStep(event.delta));
274
- const interaction = asRecord(event.interaction);
275
- if (interaction) {
276
- grounding = mergeGrounding(
277
- grounding,
278
- groundingFromMetadata(groundingMetadataFromRecord(interaction)),
279
- );
280
- }
281
- const steps = interaction?.steps;
282
- if (Array.isArray(steps)) {
283
- for (const step of steps) {
284
- grounding = mergeGrounding(grounding, groundingFromStep(step));
285
- }
286
- }
287
- if (!grounding) {
288
- return undefined;
289
- }
290
- return { type: 'grounding', grounding };
291
- }
292
-
293
- const INPUT_KEYS = [
294
- 'total_input_tokens',
295
- 'totalInputTokens',
296
- 'prompt_token_count',
297
- 'promptTokenCount',
298
- 'prompt_tokens',
299
- 'input_tokens',
300
- 'inputTokens',
301
- 'input',
302
- ] as const;
303
-
304
- const OUTPUT_KEYS = [
305
- 'total_output_tokens',
306
- 'totalOutputTokens',
307
- 'candidates_token_count',
308
- 'candidatesTokenCount',
309
- 'candidates_tokens',
310
- 'completion_tokens',
311
- 'output_tokens',
312
- 'outputTokens',
313
- 'output',
314
- ] as const;
315
-
316
- const THINKING_KEYS = [
317
- 'total_thought_tokens',
318
- 'totalThoughtTokens',
319
- 'thoughts_token_count',
320
- 'thoughtsTokenCount',
321
- 'thoughts_tokens',
322
- 'thinking_tokens',
323
- 'thinkingTokens',
324
- 'thinking',
325
- ] as const;
326
-
327
- const TOOL_KEYS = [
328
- 'total_tool_use_tokens',
329
- 'totalToolUseTokens',
330
- 'tool_use_token_count',
331
- 'toolUseTokenCount',
332
- 'tool_tokens',
333
- 'toolTokens',
334
- 'toolUse',
335
- ] as const;
336
-
337
- const TOTAL_KEYS = [
338
- 'total_tokens',
339
- 'totalTokens',
340
- 'total_token_count',
341
- 'totalTokenCount',
342
- 'total',
343
- ] as const;
344
-
345
- function pickNumericField(record: Record<string, unknown>, keys: readonly string[]): number {
346
- for (const key of keys) {
347
- const val = record[key];
348
- if (val !== undefined && val !== null) {
349
- const n = Number(val);
350
- if (!Number.isNaN(n)) {
351
- return n;
352
- }
353
- }
354
- }
355
- return 0;
356
- }
357
-
358
- function extractUsageTokens(raw: unknown): TurnTokens | undefined {
359
- if (!raw || typeof raw !== 'object') {
360
- return undefined;
361
- }
362
- const r = raw as Record<string, unknown>;
363
- const input = pickNumericField(r, INPUT_KEYS);
364
- const output = pickNumericField(r, OUTPUT_KEYS);
365
- const thinking = pickNumericField(r, THINKING_KEYS);
366
- const toolUse = pickNumericField(r, TOOL_KEYS);
367
- const total = pickNumericField(r, TOTAL_KEYS) || input + output + thinking + toolUse;
368
- if (input > 0 || output > 0 || thinking > 0 || toolUse > 0 || total > 0) {
369
- return { input, output, thinking, toolUse, total };
370
- }
371
- return undefined;
372
- }
373
-
374
- const USAGE_KEYS = ['usage', 'usage_metadata', 'usageMetadata'] as const;
375
-
376
- function findUsageObject(target: Record<string, unknown>, event: Record<string, unknown>): unknown {
377
- for (const key of USAGE_KEYS) {
378
- if (target[key]) return target[key];
379
- }
380
- for (const key of USAGE_KEYS) {
381
- if (event[key]) return event[key];
382
- }
383
- return undefined;
384
- }
385
-
386
- function extractTokenEvent(
387
- event: Record<string, unknown>,
388
- interaction?: Record<string, unknown>,
389
- ): TurnEvent | undefined {
390
- const target = interaction ?? asRecord(event.interaction) ?? event;
391
- const usage = extractUsageTokens(findUsageObject(target, event));
392
- const interactionId = typeof target.id === 'string' ? target.id : undefined;
393
- if (!usage) {
394
- return undefined;
395
- }
396
- return {
397
- type: 'tokens',
398
- tokens: usage,
399
- ...(interactionId ? { interactionId } : {}),
400
- };
401
- }
402
-
403
- function eventsFromComplete(event: Record<string, unknown>, alreadyText: boolean): TurnEvent[] {
404
- const interaction = asRecord(event.interaction) ?? event;
405
- const outputText = interaction.output_text;
406
- const events: TurnEvent[] = [];
407
- if (!alreadyText && typeof outputText === 'string' && outputText) {
408
- events.push({ type: 'text', text: outputText });
409
- }
410
- const media = mediaFromComplete(event);
411
- if (media) {
412
- events.push(media);
413
- }
414
- const tokenEvent = extractTokenEvent(event, interaction);
415
- if (tokenEvent) {
416
- events.push(tokenEvent);
417
- }
418
- const groundingEvent = groundingFromEvent(event);
419
- if (groundingEvent) {
420
- events.push(groundingEvent);
421
- }
422
- return events;
423
- }
424
-
425
- function tryStructured(text: string): TurnEvent | undefined {
426
- try {
427
- return { type: 'structured', structured: JSON.parse(text) };
428
- } catch {
429
- return undefined;
430
- }
431
- }
432
-
433
- export {
434
- eventsFromComplete,
435
- eventsFromDelta,
436
- extractTokenEvent,
437
- extractUsageTokens,
438
- groundingFromEvent,
439
- tryStructured,
440
- };
@@ -1,11 +0,0 @@
1
- const HEX_PAD = 2;
2
- const HEX_RADIX = 16;
3
-
4
- function hexSha256(bytes: Uint8Array): string {
5
- return [...bytes].map((b) => b.toString(HEX_RADIX).padStart(HEX_PAD, '0')).join('');
6
- }
7
-
8
- export async function sha256(text: string): Promise<string> {
9
- const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
10
- return hexSha256(new Uint8Array(buf));
11
- }
@@ -1,8 +0,0 @@
1
- function asRecord(value: unknown): Record<string, unknown> | undefined {
2
- if (value && typeof value === 'object' && !Array.isArray(value)) {
3
- return value as Record<string, unknown>;
4
- }
5
- return undefined;
6
- }
7
-
8
- export { asRecord };
@@ -1,56 +0,0 @@
1
- import type { Profile, TurnHistoryMessage, TurnRepairRequest } from '../types.ts';
2
-
3
- const MAX_REPAIR_HISTORY_EXCHANGES = 2;
4
- const MAX_REPAIR_HISTORY_MESSAGES = MAX_REPAIR_HISTORY_EXCHANGES * 2;
5
-
6
- function scopeHistory(history: TurnHistoryMessage[] | undefined): TurnHistoryMessage[] {
7
- if (!history || history.length === 0) {
8
- return [];
9
- }
10
- return history.slice(-MAX_REPAIR_HISTORY_MESSAGES);
11
- }
12
-
13
- function formatHistoryBlock(messages: TurnHistoryMessage[]): string {
14
- if (messages.length === 0) {
15
- return '';
16
- }
17
- const lines = messages.map((m) => `${m.role === 'user' ? 'User' : 'Assistant'}: ${m.content}`);
18
- return `### RECENT CONVERSATION CONTEXT (LAST ${messages.length} TURNS)\n${lines.join('\n')}\n\n`;
19
- }
20
-
21
- function synthesizeRepairPrompt(args: {
22
- profile: Profile;
23
- repair: TurnRepairRequest;
24
- history?: TurnHistoryMessage[];
25
- }): string {
26
- const { profile, repair, history } = args;
27
- const guidance =
28
- repair.guidance ||
29
- profile.outputs.validation?.repairGuidance ||
30
- 'Revise the previous output so it satisfies the validator rejection. Preserve the intended user-facing substance unless the guidance says otherwise.';
31
-
32
- const historyBlock = formatHistoryBlock(scopeHistory(history));
33
-
34
- let prompt = `## OUTPUT REPAIR REQUEST\n\n`;
35
- prompt += `The previous assistant output was rejected by a host validator and must be revised.\n\n`;
36
-
37
- prompt += `### PREVIOUS OUTPUT\n\`\`\`\n${repair.previousOutput.trim()}\n\`\`\`\n\n`;
38
- prompt += `### VALIDATOR REJECTION\n${repair.rejection.trim()}\n\n`;
39
-
40
- if (guidance.trim()) {
41
- prompt += `### REPAIR GUIDANCE\n${guidance.trim()}\n\n`;
42
- }
43
-
44
- if (historyBlock) {
45
- prompt += historyBlock;
46
- }
47
-
48
- prompt += `### INSTRUCTIONS\n`;
49
- prompt += `1. Inspect the previous output and validator rejection.\n`;
50
- prompt += `2. Apply the repair guidance without inventing unsupported facts.\n`;
51
- prompt += `3. Return only the corrected assistant output required by the active profile.`;
52
-
53
- return prompt;
54
- }
55
-
56
- export { synthesizeRepairPrompt };