theorum 0.1.15 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/README.md +241 -98
  2. package/esm/mod.d.ts +57 -28
  3. package/esm/mod.js +43 -23
  4. package/esm/src/cli/commands/bench.js +18 -18
  5. package/esm/src/cli/commands/fuzz-canary.d.ts +13 -0
  6. package/esm/src/cli/commands/fuzz-canary.js +191 -0
  7. package/esm/src/cli/commands/fuzz-guardrails.d.ts +3 -5
  8. package/esm/src/cli/commands/fuzz-guardrails.js +4 -581
  9. package/esm/src/cli/commands/guardrails-eval.d.ts +14 -0
  10. package/esm/src/cli/commands/guardrails-eval.js +15 -0
  11. package/esm/src/cli/commands/profile.js +35 -15
  12. package/esm/src/cli/commands/run.d.ts +3 -0
  13. package/esm/src/cli/commands/run.js +23 -32
  14. package/esm/src/cli/commands/test.d.ts +10 -1
  15. package/esm/src/cli/commands/test.js +34 -34
  16. package/esm/src/cli/event-log.d.ts +19 -0
  17. package/esm/src/cli/event-log.js +147 -0
  18. package/esm/src/cli/index.js +57 -11
  19. package/esm/src/cli/matrix/synthesizer.d.ts +10 -12
  20. package/esm/src/cli/matrix/synthesizer.js +45 -118
  21. package/esm/src/guardrails/canary-gate.d.ts +21 -0
  22. package/esm/src/guardrails/canary-gate.js +32 -0
  23. package/esm/src/guardrails/canary.d.ts +34 -0
  24. package/esm/src/guardrails/canary.js +150 -0
  25. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +17 -0
  26. package/esm/src/guardrails/corpus/canary-egress-attacks.js +151 -0
  27. package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +11 -0
  28. package/esm/src/guardrails/corpus/fuzz-inbound.js +213 -0
  29. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +10 -0
  30. package/esm/src/guardrails/corpus/inbound-payloads.js +125 -0
  31. package/esm/src/guardrails/corpus/live-attacks.d.ts +20 -0
  32. package/esm/src/guardrails/corpus/live-attacks.js +231 -0
  33. package/esm/src/guardrails/corpus/mod.d.ts +14 -0
  34. package/esm/src/guardrails/corpus/mod.js +11 -0
  35. package/esm/src/guardrails/corpus/secrets.d.ts +17 -0
  36. package/esm/src/guardrails/corpus/secrets.js +17 -0
  37. package/esm/src/guardrails/corpus/strings.d.ts +28 -0
  38. package/esm/src/guardrails/corpus/strings.js +34 -0
  39. package/esm/src/guardrails/corpus/types.d.ts +38 -0
  40. package/esm/src/guardrails/corpus/types.js +6 -0
  41. package/esm/src/guardrails/egress.d.ts +32 -0
  42. package/esm/src/guardrails/egress.js +87 -0
  43. package/esm/src/guardrails/error.d.ts +14 -23
  44. package/esm/src/guardrails/error.js +87 -76
  45. package/esm/src/guardrails/eval/corpus.d.ts +108 -0
  46. package/esm/src/guardrails/eval/corpus.js +978 -0
  47. package/esm/src/guardrails/eval/mod.d.ts +51 -0
  48. package/esm/src/guardrails/eval/mod.js +133 -0
  49. package/esm/src/guardrails/eval/score.d.ts +66 -0
  50. package/esm/src/guardrails/eval/score.js +114 -0
  51. package/esm/src/guardrails/events.d.ts +25 -0
  52. package/esm/src/guardrails/events.js +56 -0
  53. package/esm/src/guardrails/hits.d.ts +24 -0
  54. package/esm/src/guardrails/hits.js +45 -0
  55. package/esm/src/guardrails/injection.js +28 -5
  56. package/esm/src/guardrails/lexicon.d.ts +39 -0
  57. package/esm/src/guardrails/lexicon.js +200 -0
  58. package/esm/src/guardrails/live-outbound-gate.d.ts +41 -0
  59. package/esm/src/guardrails/live-outbound-gate.js +222 -0
  60. package/esm/src/guardrails/mod.d.ts +30 -6
  61. package/esm/src/guardrails/mod.js +20 -5
  62. package/esm/src/guardrails/network.d.ts +19 -0
  63. package/esm/src/guardrails/network.js +234 -0
  64. package/esm/src/guardrails/policy.d.ts +35 -0
  65. package/esm/src/guardrails/policy.js +50 -0
  66. package/esm/src/guardrails/progressive-yield.d.ts +51 -0
  67. package/esm/src/guardrails/progressive-yield.js +98 -0
  68. package/esm/src/guardrails/quota.d.ts +17 -3
  69. package/esm/src/guardrails/quota.js +18 -4
  70. package/esm/src/guardrails/sanitize.d.ts +45 -19
  71. package/esm/src/guardrails/sanitize.js +177 -94
  72. package/esm/src/guardrails/sensitive.js +2 -1
  73. package/esm/src/guardrails/serialize.d.ts +35 -0
  74. package/esm/src/guardrails/serialize.js +58 -0
  75. package/esm/src/guardrails/testing.d.ts +17 -0
  76. package/esm/src/guardrails/testing.js +13 -0
  77. package/esm/src/guardrails/theorum-error.d.ts +12 -0
  78. package/esm/src/guardrails/theorum-error.js +15 -0
  79. package/esm/src/guardrails/tool-directives.d.ts +48 -0
  80. package/esm/src/guardrails/tool-directives.js +124 -0
  81. package/esm/src/guardrails/tool-result.d.ts +93 -0
  82. package/esm/src/guardrails/tool-result.js +276 -0
  83. package/esm/src/guardrails/types.d.ts +291 -0
  84. package/esm/src/guardrails/types.js +72 -0
  85. package/esm/src/host/client-turn.d.ts +19 -0
  86. package/esm/src/host/client-turn.js +36 -0
  87. package/esm/src/host/mint-trace.d.ts +1 -1
  88. package/esm/src/host/mod.d.ts +5 -3
  89. package/esm/src/host/mod.js +4 -3
  90. package/esm/src/kernel/auth/crypto.d.ts +42 -0
  91. package/esm/src/kernel/auth/crypto.js +106 -0
  92. package/esm/src/kernel/auth/mod.d.ts +11 -0
  93. package/esm/src/kernel/auth/mod.js +11 -0
  94. package/esm/src/kernel/auth/oauth.d.ts +47 -0
  95. package/esm/src/kernel/auth/oauth.js +278 -0
  96. package/esm/src/kernel/auth/types.d.ts +133 -0
  97. package/esm/src/kernel/auth/types.js +13 -0
  98. package/esm/src/kernel/engine/delta.d.ts +24 -2
  99. package/esm/src/kernel/engine/delta.js +478 -39
  100. package/esm/src/kernel/engine/live-inbound.d.ts +21 -0
  101. package/esm/src/kernel/engine/live-inbound.js +31 -0
  102. package/esm/src/kernel/engine/live-ingress.d.ts +19 -0
  103. package/esm/src/kernel/engine/live-ingress.js +47 -0
  104. package/esm/src/kernel/engine/repair.js +13 -12
  105. package/esm/src/kernel/engine/runner/gates.d.ts +1 -1
  106. package/esm/src/kernel/engine/runner/gates.js +130 -43
  107. package/esm/src/kernel/engine/runner/mod.d.ts +6 -4
  108. package/esm/src/kernel/engine/runner/mod.js +192 -53
  109. package/esm/src/kernel/engine/runner/schema-validation.js +3 -3
  110. package/esm/src/kernel/engine/runner/stages.d.ts +39 -0
  111. package/esm/src/kernel/engine/runner/stages.js +89 -0
  112. package/esm/src/kernel/engine/runner/state.d.ts +31 -0
  113. package/esm/src/kernel/engine/runner/steps.d.ts +1 -1
  114. package/esm/src/kernel/engine/runner/steps.js +244 -43
  115. package/esm/src/kernel/engine/runner/stream.d.ts +9 -3
  116. package/esm/src/kernel/engine/runner/stream.js +140 -44
  117. package/esm/src/kernel/engine/session/mod.d.ts +25 -0
  118. package/esm/src/kernel/engine/session/mod.js +557 -0
  119. package/esm/src/kernel/interaction-parts.d.ts +14 -0
  120. package/esm/src/kernel/interaction-parts.js +23 -0
  121. package/esm/src/kernel/mod.d.ts +21 -10
  122. package/esm/src/kernel/mod.js +11 -8
  123. package/esm/src/kernel/profile-graph.d.ts +159 -0
  124. package/esm/src/kernel/profile-graph.js +156 -0
  125. package/esm/src/kernel/registry/attachments.d.ts +12 -10
  126. package/esm/src/kernel/registry/attachments.js +33 -27
  127. package/esm/src/kernel/registry/catalog.d.ts +25 -24
  128. package/esm/src/kernel/registry/catalog.js +60 -101
  129. package/esm/src/kernel/registry/ingress.d.ts +9 -4
  130. package/esm/src/kernel/registry/ingress.js +97 -75
  131. package/esm/src/kernel/registry/profile-outputs.d.ts +4 -0
  132. package/esm/src/kernel/registry/profile-outputs.js +8 -0
  133. package/esm/src/kernel/registry/profiles.d.ts +55 -12
  134. package/esm/src/kernel/registry/profiles.js +413 -73
  135. package/esm/src/kernel/registry/provider-request.js +13 -7
  136. package/esm/src/kernel/registry/resolve.d.ts +8 -8
  137. package/esm/src/kernel/registry/resolve.js +169 -154
  138. package/esm/src/kernel/registry/schemas.js +1 -1
  139. package/esm/src/kernel/registry/sole-model.d.ts +8 -0
  140. package/esm/src/kernel/registry/sole-model.js +10 -0
  141. package/esm/src/kernel/registry/system-prompt.d.ts +10 -0
  142. package/esm/src/kernel/registry/system-prompt.js +40 -0
  143. package/esm/src/kernel/registry/system-role.d.ts +8 -0
  144. package/esm/src/kernel/registry/system-role.js +14 -0
  145. package/esm/src/kernel/registry/vault.d.ts +12 -7
  146. package/esm/src/kernel/registry/vault.js +32 -10
  147. package/esm/src/kernel/schema.d.ts +231 -0
  148. package/esm/src/kernel/schema.js +607 -0
  149. package/esm/src/kernel/stages.d.ts +175 -0
  150. package/esm/src/kernel/stages.js +476 -0
  151. package/esm/src/kernel/stop.d.ts +78 -19
  152. package/esm/src/kernel/stop.js +51 -16
  153. package/esm/src/kernel/tools/events.d.ts +41 -0
  154. package/esm/src/kernel/tools/events.js +71 -0
  155. package/esm/src/kernel/tools/execute.d.ts +84 -0
  156. package/esm/src/kernel/tools/execute.js +614 -0
  157. package/esm/src/kernel/tools/harness.d.ts +8 -0
  158. package/esm/src/kernel/tools/harness.js +46 -0
  159. package/esm/src/kernel/tools/invoke.d.ts +10 -0
  160. package/esm/src/kernel/tools/invoke.js +101 -0
  161. package/esm/src/kernel/tools/mod.d.ts +13 -0
  162. package/esm/src/kernel/tools/mod.js +11 -0
  163. package/esm/src/kernel/tools/permission.d.ts +15 -0
  164. package/esm/src/kernel/tools/permission.js +47 -0
  165. package/esm/src/kernel/tools/project.d.ts +12 -0
  166. package/esm/src/kernel/tools/project.js +36 -0
  167. package/esm/src/kernel/tools/registry.d.ts +23 -0
  168. package/esm/src/kernel/tools/registry.js +81 -0
  169. package/esm/src/kernel/tools/remote.d.ts +94 -0
  170. package/esm/src/kernel/tools/remote.js +577 -0
  171. package/esm/src/kernel/tools/resolve.d.ts +39 -0
  172. package/esm/src/kernel/tools/resolve.js +283 -0
  173. package/esm/src/kernel/tools/schema.d.ts +15 -0
  174. package/esm/src/kernel/tools/schema.js +176 -0
  175. package/esm/src/kernel/tools/stage-run.d.ts +105 -0
  176. package/esm/src/kernel/tools/stage-run.js +155 -0
  177. package/esm/src/kernel/tools/types.d.ts +394 -0
  178. package/esm/src/kernel/tools/types.js +9 -0
  179. package/esm/src/kernel/types.d.ts +540 -256
  180. package/esm/src/kernel/util/find-last.d.ts +2 -0
  181. package/esm/src/kernel/util/find-last.js +10 -0
  182. package/esm/src/observability/destinations.d.ts +31 -0
  183. package/esm/src/observability/destinations.js +67 -0
  184. package/esm/src/observability/mod.d.ts +10 -3
  185. package/esm/src/observability/mod.js +6 -2
  186. package/esm/src/observability/policy.d.ts +27 -0
  187. package/esm/src/observability/policy.js +80 -0
  188. package/esm/src/observability/resolve-policy.d.ts +16 -0
  189. package/esm/src/observability/resolve-policy.js +64 -0
  190. package/esm/src/observability/trace-attach.d.ts +8 -4
  191. package/esm/src/observability/trace-attach.js +50 -29
  192. package/esm/src/observability/trace-record.d.ts +23 -13
  193. package/esm/src/observability/trace-record.js +96 -39
  194. package/esm/src/observability/trace-sink.d.ts +19 -0
  195. package/esm/src/observability/trace-sink.js +10 -0
  196. package/esm/src/observability/trace-usage.d.ts +10 -3
  197. package/esm/src/observability/trace-usage.js +70 -17
  198. package/esm/src/observability/trace.d.ts +18 -7
  199. package/esm/src/observability/trace.js +34 -17
  200. package/esm/src/observability/types.d.ts +113 -0
  201. package/esm/src/observability/types.js +11 -0
  202. package/esm/src/presets/google/speech-voices.d.ts +11 -0
  203. package/esm/src/presets/google/speech-voices.js +41 -0
  204. package/esm/src/presets/google.d.ts +36 -24
  205. package/esm/src/presets/google.js +50 -63
  206. package/esm/src/presets/mod.d.ts +2 -2
  207. package/esm/src/presets/mod.js +1 -1
  208. package/esm/src/providers/create-provider.d.ts +20 -17
  209. package/esm/src/providers/create-provider.js +72 -26
  210. package/esm/src/providers/google/interactions/framing.d.ts +23 -0
  211. package/esm/src/providers/google/interactions/framing.js +269 -0
  212. package/esm/src/providers/google/interactions/mod.d.ts +7 -0
  213. package/esm/src/providers/google/interactions/mod.js +7 -0
  214. package/esm/src/providers/google/interactions/stream.d.ts +83 -0
  215. package/esm/src/providers/google/interactions/stream.js +588 -0
  216. package/esm/src/providers/google/keys.d.ts +26 -0
  217. package/esm/src/providers/{keys.js → google/keys.js} +19 -31
  218. package/esm/src/providers/google/live/framing.d.ts +49 -0
  219. package/esm/src/providers/google/live/framing.js +552 -0
  220. package/esm/src/providers/google/live/openapi-schema.d.ts +6 -0
  221. package/esm/src/providers/google/live/openapi-schema.js +46 -0
  222. package/esm/src/providers/google/live/session.d.ts +25 -0
  223. package/esm/src/providers/google/live/session.js +134 -0
  224. package/esm/src/providers/google/live/stream.d.ts +45 -0
  225. package/esm/src/providers/google/live/stream.js +214 -0
  226. package/esm/src/providers/google/urls.d.ts +6 -0
  227. package/esm/src/providers/google/urls.js +6 -0
  228. package/esm/src/providers/local/local.d.ts +30 -0
  229. package/esm/src/providers/{local.js → local/local.js} +66 -126
  230. package/esm/src/providers/local/mod.d.ts +9 -0
  231. package/esm/src/providers/local/mod.js +9 -0
  232. package/esm/src/providers/mod.d.ts +6 -3
  233. package/esm/src/providers/mod.js +3 -1
  234. package/esm/src/providers/openrouter/cache-control.d.ts +24 -0
  235. package/esm/src/providers/openrouter/cache-control.js +23 -0
  236. package/esm/src/providers/openrouter/chat.d.ts +107 -0
  237. package/esm/src/providers/{openrouter.js → openrouter/chat.js} +117 -231
  238. package/esm/src/providers/openrouter/image.d.ts +34 -0
  239. package/esm/src/providers/openrouter/image.js +275 -0
  240. package/esm/src/providers/openrouter/openai/chat-payload.d.ts +24 -0
  241. package/esm/src/providers/openrouter/openai/chat-payload.js +82 -0
  242. package/esm/src/providers/openrouter/openai/compat.d.ts +53 -0
  243. package/esm/src/providers/openrouter/openai/compat.js +213 -0
  244. package/esm/src/providers/openrouter/openai/image-payload.d.ts +18 -0
  245. package/esm/src/providers/openrouter/openai/image-payload.js +90 -0
  246. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +22 -0
  247. package/esm/src/providers/openrouter/openai/sdk-messages.js +122 -0
  248. package/esm/src/providers/openrouter/resolve-api-key.d.ts +9 -0
  249. package/esm/src/providers/openrouter/resolve-api-key.js +24 -0
  250. package/esm/src/providers/openrouter/speech.d.ts +23 -0
  251. package/esm/src/providers/{speech.js → openrouter/speech.js} +32 -55
  252. package/esm/src/providers/probe.d.ts +1 -0
  253. package/esm/src/providers/probe.js +22 -0
  254. package/esm/src/providers/shared/pcm.d.ts +12 -0
  255. package/esm/src/providers/{pcm.js → shared/pcm.js} +16 -3
  256. package/esm/src/providers/shared/sse.d.ts +18 -0
  257. package/esm/src/providers/shared/sse.js +87 -0
  258. package/esm/src/providers/shared/tool-args.d.ts +17 -0
  259. package/esm/src/providers/shared/tool-args.js +45 -0
  260. package/esm/src/providers/shared/upstream-tap.d.ts +5 -0
  261. package/esm/src/providers/{google-tap.js → shared/upstream-tap.js} +4 -7
  262. package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
  263. package/esm/src/providers/{gemini-tape.js → shared/upstream-tape.js} +12 -22
  264. package/esm/src/providers/types.d.ts +27 -0
  265. package/esm/src/providers/types.js +1 -0
  266. package/package.json +11 -7
  267. package/docs/cli.md +0 -97
  268. package/docs/guardrails.md +0 -178
  269. package/docs/host.md +0 -97
  270. package/docs/kernel.md +0 -404
  271. package/docs/observability.md +0 -105
  272. package/docs/openrouter.md +0 -125
  273. package/docs/presets-google.md +0 -91
  274. package/docs/presets.md +0 -88
  275. package/docs/providers.md +0 -202
  276. package/docs/streaming.md +0 -96
  277. package/esm/src/kernel/engine/boundary.d.ts +0 -10
  278. package/esm/src/kernel/engine/boundary.js +0 -55
  279. package/esm/src/kernel/engine/runner/tools.d.ts +0 -13
  280. package/esm/src/kernel/engine/runner/tools.js +0 -198
  281. package/esm/src/kernel/registry/tools.d.ts +0 -12
  282. package/esm/src/kernel/registry/tools.js +0 -36
  283. package/esm/src/providers/expose-for-tests.d.ts +0 -1
  284. package/esm/src/providers/expose-for-tests.js +0 -25
  285. package/esm/src/providers/gemini-tape.d.ts +0 -2
  286. package/esm/src/providers/google-tap.d.ts +0 -3
  287. package/esm/src/providers/interactions.d.ts +0 -5
  288. package/esm/src/providers/interactions.js +0 -169
  289. package/esm/src/providers/keys.d.ts +0 -19
  290. package/esm/src/providers/local.d.ts +0 -29
  291. package/esm/src/providers/openrouter-mod.d.ts +0 -13
  292. package/esm/src/providers/openrouter-mod.js +0 -12
  293. package/esm/src/providers/openrouter-payload.d.ts +0 -39
  294. package/esm/src/providers/openrouter-payload.js +0 -195
  295. package/esm/src/providers/openrouter.d.ts +0 -15
  296. package/esm/src/providers/pcm.d.ts +0 -7
  297. package/esm/src/providers/provider.d.ts +0 -15
  298. package/esm/src/providers/provider.js +0 -202
  299. package/esm/src/providers/speech.d.ts +0 -23
  300. package/esm/src/providers/sse.d.ts +0 -7
  301. package/esm/src/providers/sse.js +0 -55
  302. package/esm/src/streaming/mod.d.ts +0 -9
  303. package/esm/src/streaming/mod.js +0 -8
  304. /package/esm/src/{streaming → host}/readStreamingJsonStringField.d.ts +0 -0
  305. /package/esm/src/{streaming → host}/readStreamingJsonStringField.js +0 -0
@@ -7,96 +7,111 @@
7
7
  *
8
8
  * @module
9
9
  */
10
- /** Model reasoning effort level normalized across provider adapters. */
11
- export type ThinkingLevel = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
10
+ import type { CacheMode, CacheTtl, CompactionMeter, CompactionTiming, ContinueStopKind, FieldMeta, KeySlot, KeyVault, LiveActivityHandling, LiveContextCompression, LiveSpeechSensitivity, MediaInputKind, OverflowKeySlot, ProfileType, ProfileTypeProtocol, Protocol, Provider, SchemaEnforcement, SpeechAudioFormat, StreamMode, SummaryMode, ThinkingLevel, ToolLoadTier, TurnStage, TurnStopKind } from './schema.js';
11
+ import type { StageApplyWarning, StageHandler } from './stages.js';
12
+ import type { HostProfileToolsSpec, InvokeToolRequest, InvokeToolResume, LiveProfileToolsSpec, ModelToolResult, ProfileToolsSpec, RegisteredTool, ToolCallEvent, ToolFailure, ToolGate, ToolLoadContext, ToolPolicy, TurnToolSnapshot, WireFunctionTool } from './tools/types.js';
13
+ export type { CacheMode, CacheTtl, CompactionMeter, CompactionTiming, ContinueStopKind, FieldMeta, HostProfileToolsSpec, InvokeToolRequest, KeySlot, KeyVault, LiveActivityHandling, LiveContextCompression, LiveProfileToolsSpec, LiveSpeechSensitivity, MediaInputKind, OverflowKeySlot, ProfileToolsSpec, ProfileType, ProfileTypeProtocol, Protocol, Provider, RegisteredTool, SchemaEnforcement, SpeechAudioFormat, StreamMode, SummaryMode, ThinkingLevel, ToolCallEvent, ToolGate, ToolLoadContext, ToolLoadTier, ToolPolicy, TurnStage, TurnStopKind, TurnToolSnapshot, WireFunctionTool, };
12
14
  /** Any host-declared model id. */
13
15
  export type ModelId = string;
14
16
  /** Provider-projected builtin tool id (registered by presets/adapters). */
15
17
  export type BuiltinToolId = string;
16
- /** Harness custom tool that ships with THEORUM. */
17
- export type HarnessToolId = 'askUser';
18
- /** Host-owned or harness custom tool id. */
19
- export type CustomToolId = HarnessToolId | (string & Record<never, never>);
20
18
  /** Any tool id accepted by profile allowlists and per-turn gates. */
21
- export type ToolId = BuiltinToolId | CustomToolId;
19
+ export type ToolId = string;
22
20
  /** Id of a host-registered structured output schema. */
23
21
  export type StructuredSchemaId = string;
24
- /** Normalized multimodal part category (image, audio, video, document). */
25
- export type MediaInputKind = 'image' | 'audio' | 'video' | 'document';
26
22
  /** Host-owned profile identifier. */
27
23
  export type ProfileId = string;
28
- /** Named Gemini key bucket used by host-provided transports. */
29
- export type GeminiBucket = 'freeA' | 'freeB' | 'freeC' | 'paid';
30
- /** Gemini bucket that may overflow to the paid bucket after quota backoff. */
31
- export type GeminiFreeBucket = Exclude<GeminiBucket, 'paid'>;
32
24
  /** Message role accepted by provider history mappers. */
33
25
  export type ChatRole = 'system' | 'user' | 'assistant';
34
- /** Profile-level control a caller may toggle at turn time. */
35
- export type ControlId = 'thinking';
36
26
  /**
37
27
  * Image-role output pins owned by the host profile.
38
- * The image model itself lives in `model.allow` / `model.config`.
28
+ * The image model itself lives in `profile.models`.
39
29
  * Aspect/size/mime values are host strings (presets/apps own the vocabularies).
40
30
  */
41
31
  export interface ProfileImageSpec {
42
- /** Default aspect ratio when the turn does not set `slots.aspectRatio`. */
32
+ /** Optional output aspect ratio pin (provider default when omitted). */
43
33
  aspectRatio?: string;
44
- /** Default size / resolution when the turn does not set `slots.size`. */
34
+ /** Optional output size / resolution pin (provider default when omitted). */
45
35
  size?: string;
46
36
  /** Output MIME for generated images. */
47
37
  mimeType?: string;
48
- /** When false, grounding builtins are rejected on this profile. */
49
- allowsGrounding?: boolean;
50
38
  /** Cap on reference images in one turn. */
51
39
  maxInputImages?: number;
40
+ /**
41
+ * When true, request interleaved assistant text alongside generated images
42
+ * (Google: `response_format` array with text + image entries).
43
+ */
44
+ includeText?: boolean;
52
45
  }
53
46
  /** Public event types emitted by `runTurn` and provider adapters. */
54
- export type TurnEventType = 'thought' | 'text' | 'tool' | 'structured' | 'media' | 'grounding' | 'evidence' | 'tokens' | 'done' | 'error';
55
- /** Provider thinking levels used when a boolean thinking control is on or off. */
56
- export interface ThinkingMap {
57
- on: ThinkingLevel;
58
- off: ThinkingLevel;
59
- }
60
- /** Provider summary behavior used when a boolean thinking control is on or off. */
61
- export interface SummaryMap {
62
- on: 'auto' | 'none';
63
- off: 'auto' | 'none';
64
- }
65
- /** Host-declared metadata THEORUM needs to call a model safely. */
66
- export interface ModelSpec {
47
+ export type TurnEventType = 'thought' | 'text' | 'tool' | 'structured' | 'media' | 'grounding' | 'evidence' | 'tokens' | 'session' | 'guardrail' | 'stage' | 'done' | 'error';
48
+ /**
49
+ * Live session control signals (provider-neutral).
50
+ *
51
+ * - `turn_complete` — one spoken response ended; the server may still be working.
52
+ * - `working` — server is reasoning or awaiting async tool results; more output may follow.
53
+ * - `idle` — server finished all processing; conversational cycle boundary.
54
+ */
55
+ export type SessionEventKind = 'closing_soon' | 'waiting_for_input' | 'turn_complete' | 'working' | 'idle';
56
+ export interface SessionEvent {
57
+ kind: SessionEventKind;
58
+ /** Parsed drain window when the provider supplied a duration; omit when unknown. */
59
+ timeLeftMs?: number;
60
+ }
61
+ /** Host-named model binding — wire routing and generation knobs for one profile model. */
62
+ export interface ModelBinding {
63
+ protocol: Protocol;
64
+ provider: Provider;
65
+ /** Provider wire model id for the configured provider. */
67
66
  apiId: string;
68
- /** Provider-native id for OpenRouter-compatible gateways. Defaults to `google/${apiId}`. */
69
- openRouterId?: string;
70
- thinking: ThinkingMap;
71
- /** Levels this model accepts. Illegal values are clamped via `thinkingLevels`. */
72
- thinkingLevels: ThinkingLevel[];
73
- summaries: SummaryMap;
74
- maxOutputTokens: number;
75
- temperature: number;
76
- /**
77
- * Builtins that may use `profile.model.key`.
78
- * Any other enabled builtin selects the overflow vault slot (`paid`).
79
- * Host-owned policy — THEORUM does not infer tool pricing.
80
- */
81
- keyBuiltins: BuiltinToolId[];
82
- /**
83
- * Optional vault slot for this model. When set, overrides `profile.model.key`
84
- * (and builtin routing). Host-owned — e.g. pin image models to `paid`.
85
- */
86
- key?: GeminiBucket;
87
- /** Optional compaction policy for this model's context window. */
67
+ /** Alias → thinking level. One entry = fixed; two+ may be selectable at turn time. */
68
+ efforts?: Record<string, ThinkingLevel>;
69
+ /** Effort alias when the turn omits `effort`. Defaults to the only key when there is one. */
70
+ defaultEffort?: string;
71
+ /** Turn may pass `{ effort: "<alias>" }`. Requires two or more `efforts` keys. */
72
+ allowEffortSelect?: boolean;
73
+ /** Emit thinking summaries on the stream. Omit → provider default. */
74
+ summaries?: boolean;
75
+ /** Cap on output tokens. Omit → provider default. */
76
+ maxOutputTokens?: number;
77
+ /** Sampling temperature. Omit → provider default. */
78
+ temperature?: number;
79
+ /**
80
+ * Provider-native builtins this model supports.
81
+ * Omit or `[]` when none. Opt in per turn with `tools[id]: true`.
82
+ */
83
+ builtInTools?: BuiltinToolId[];
84
+ /**
85
+ * Optional vault slot for this model. When set, overrides `profile.key`.
86
+ * Host-owned — e.g. pin image models to `paid`.
87
+ */
88
+ key?: KeySlot;
89
+ /** Optional compaction policy for this model's context window (chat profiles). */
88
90
  compaction?: CompactionSpec;
91
+ /**
92
+ * OpenRouter prompt-cache policy. Omit → no opt-in `cache_control`.
93
+ * `defineProfile` accepts only when `provider` is `openrouter` (protocol `openAi`).
94
+ */
95
+ cache?: CacheSpec;
96
+ /** Gemini Interactions: whether the provider stores the interaction. Omit → provider default. */
97
+ store?: boolean;
98
+ /**
99
+ * Gemini Interactions: prefer server-side thread via `previous_interaction_id`
100
+ * instead of client-owned history. Omit → host/turn decides.
101
+ */
102
+ persistViaInteractionId?: boolean;
89
103
  }
90
104
  /**
91
- * What the compaction threshold meters.
105
+ * OpenRouter prompt-cache policy (`models.*.cache`).
92
106
  *
93
- * - `'history'` (default) — conversational history only (`TurnInput.historyTokens`
94
- * or a local estimate of `history`). Excludes system, tool schemas, and this
95
- * turn's attachments.
96
- * - `'input'` — full-prompt provider input tokens (`TurnInput.inputTokens` for
97
- * `timing: 'before'`, this turn's `tokens.input` for `timing: 'after'`).
107
+ * - `automatic` — top-level `cache_control`; breakpoint advances with the conversation.
108
+ * - `system` — explicit breakpoint on the system instruction only.
98
109
  */
99
- export type CompactionMeter = 'history' | 'input';
110
+ export interface CacheSpec {
111
+ mode: CacheMode;
112
+ /** Ephemeral TTL. Omit → provider default (typically 5m on Anthropic). */
113
+ ttl?: CacheTtl;
114
+ }
100
115
  /**
101
116
  * Context supplied to a custom compaction trigger.
102
117
  *
@@ -144,7 +159,7 @@ export interface CompactionSpec {
144
159
  * - `'before'`: kernel compacts synchronously before the turn; user pays latency on this turn.
145
160
  * - `'after'`: kernel signals in the `done` event; host runs compaction asynchronously.
146
161
  */
147
- timing: 'before' | 'after';
162
+ timing: CompactionTiming;
148
163
  /**
149
164
  * Threshold meter. Defaults to `'history'`.
150
165
  * Use `'input'` when the host prefers provider full-prompt usage (after
@@ -161,27 +176,11 @@ export interface CompactionSpec {
161
176
  */
162
177
  trigger?: (ctx: CompactionTriggerContext) => boolean | Promise<boolean>;
163
178
  }
164
- /** Static metadata for harness, preset, and host-registered tools. */
165
- export interface ToolCatalogEntry {
166
- kind: 'builtin' | 'custom';
167
- ui: boolean;
168
- schema?: Record<string, unknown>;
169
- /** Interactions API `tools[].type` when this builtin is projected. */
170
- interactionsType?: string;
171
- /** OpenRouter plugin id enabled when this builtin is on. */
172
- openRouterPlugin?: string;
173
- /** Drop this builtin when any listed sibling builtin is also requested. */
174
- conflictsWith?: ToolId[];
175
- }
176
179
  /** Host-registered structured output schema and enforcement mode. */
177
180
  export interface StructuredSpec {
178
- enforced: 'responseFormat' | 'prompt';
181
+ enforced: SchemaEnforcement;
179
182
  jsonSchema?: Record<string, unknown>;
180
183
  }
181
- /** In-memory tool catalog shape. */
182
- export interface Catalog {
183
- tools: Record<ToolId, ToolCatalogEntry>;
184
- }
185
184
  /** Per-turn file, byte, and MIME-specific input limits. */
186
185
  export interface MediaLimits {
187
186
  maxFiles: number;
@@ -225,17 +224,10 @@ export interface ProfileValidationSpec {
225
224
  maxRetries?: number;
226
225
  repairGuidance?: string;
227
226
  }
228
- /**
229
- * Audio container for speech generation output.
230
- * - `openAi` speech (`/audio/speech`): sent as wire `response_format`.
231
- * - `geminiInteractions`: only `pcm` (or omit). Google returns PCM; THEORUM emits WAV.
232
- * `mp3` is rejected at resolve.
233
- */
234
- export type SpeechAudioFormat = 'pcm' | 'mp3';
235
227
  /**
236
228
  * Speech-role output pins owned by the host profile.
237
- * The speech model itself lives in `model.allow` / `model.config`.
238
- * Namespaced under `outputs.speech` so `voice` here is the TTS voice id,
229
+ * The speech model itself lives in `profile.models`.
230
+ * Declared top-level under `speech` so `voice` here is the TTS voice id,
239
231
  * not ingress audio (`inputs.voice`).
240
232
  */
241
233
  export interface ProfileSpeechSpec {
@@ -246,62 +238,82 @@ export interface ProfileSpeechSpec {
246
238
  */
247
239
  format?: SpeechAudioFormat;
248
240
  }
241
+ /** Voice activity detection & barge-in configuration for live bidirectional streaming. */
242
+ export interface LiveVadSpec {
243
+ activityHandling?: LiveActivityHandling;
244
+ startSensitivity?: LiveSpeechSensitivity;
245
+ endSensitivity?: LiveSpeechSensitivity;
246
+ prefixPaddingMs?: number;
247
+ silenceDurationMs?: number;
248
+ }
249
+ /** Audio transcription toggles for live sessions. */
250
+ export interface LiveTranscriptionSpec {
251
+ input?: boolean;
252
+ output?: boolean;
253
+ }
254
+ /**
255
+ * Realtime ingress modalities for a live session.
256
+ * Distinct from turn `inputs` (file attachments, MIME limits) — these gate
257
+ * `LiveSession.sendAudio` / `sendVideo` / `sendText` channels.
258
+ */
259
+ export interface LiveIngressSpec {
260
+ /** Microphone PCM via `sendAudio`. Omit → enabled. */
261
+ audio?: boolean;
262
+ /** Webcam JPEG frames via `sendVideo`. Omit → enabled. */
263
+ video?: boolean;
264
+ /** Typed text via `sendText`. Omit → disabled (opt-in). */
265
+ text?: boolean;
266
+ }
267
+ /**
268
+ * Output pins for a live-role profile (bidirectional WebSocket audio/video session).
269
+ * The live model itself lives in `profile.models`.
270
+ */
271
+ export interface ProfileLiveSpec {
272
+ /** Realtime ingress modality toggles (mic, camera frames, typed text). */
273
+ ingress?: LiveIngressSpec;
274
+ /** Output TTS voice name (e.g. 'Puck', 'Aoede', 'Charon'). */
275
+ voice?: string;
276
+ /** Voice activity detection & barge-in configuration. */
277
+ vad?: LiveVadSpec;
278
+ /** Whether session resumption updates and reconnection handles are enabled. */
279
+ sessionResumption?: boolean;
280
+ /** Context window compression mechanism (e.g. 'slidingWindow' or 'none'). */
281
+ contextCompression?: LiveContextCompression;
282
+ /** Proactivity: allow model to stay silent or ignore irrelevant input. */
283
+ proactiveAudio?: boolean;
284
+ /** Real-time input/output audio transcriptions. */
285
+ transcription?: LiveTranscriptionSpec;
286
+ }
249
287
  /** Stream delivery controls enforced by the kernel. */
250
288
  export interface ProfileStreamingSpec {
251
- mode?: 'sse' | 'buffered';
289
+ /**
290
+ * Profile-only source of truth for upstream stream vs batch.
291
+ * `sse` → stream; `buffered` → non-SSE where the transport supports it.
292
+ * Omit → THEORUM defaults to SSE (`ResolvedGeneration.stream === true`).
293
+ */
294
+ mode?: StreamMode;
295
+ /** When false, filter `thought` events from the turn stream. */
252
296
  streamThoughts?: boolean;
253
- gateMedia?: boolean;
254
297
  }
255
- export type { ProfileResumeSpec, TurnContinueFrom, TurnStop, TurnStopKind, } from './stop.js';
256
- import type { ProfileResumeSpec, TurnContinueFrom, TurnStop } from './stop.js';
257
- /** Context passed to a host-owned outbound disclosure guard. */
258
- export interface EgressContext {
259
- text: string;
260
- canary?: string;
261
- slots?: Record<string, string>;
262
- profile: Profile;
263
- role?: string;
264
- }
265
- /** Decision returned by an egress guard. */
266
- export interface EgressEnforcementResult {
267
- blocked: boolean;
268
- text: string;
269
- hits?: string[];
270
- rejectionMessage?: string | null;
271
- }
272
- /** Function that evaluates candidate user-visible output before release. */
273
- export type EgressEnforcer = (context: EgressContext) => EgressEnforcementResult | Promise<EgressEnforcementResult>;
274
- /** Profile egress policy for rejection, retry, or refusal behavior. */
275
- export interface ProfileEgressSpec {
276
- enforce: EgressEnforcer;
277
- onBlock?: 'reject_to_agent' | 'refuse_to_user';
278
- maxRetries?: number;
279
- repairGuidance?: string;
280
- }
281
- /** Profile guardrail switches enforced by the kernel. */
282
- export interface ProfileGuardrailsSpec {
283
- /** Optional daily turn quota; omitted means quota enforcement is not configured. */
284
- quota?: {
285
- perDay: number;
286
- };
287
- canary?: boolean;
288
- sanitizeInput?: boolean;
289
- redactSensitive?: boolean;
290
- egress?: ProfileEgressSpec;
291
- }
292
- /** Model, provider, thinking, and step bounds for a profile. */
293
- export interface ProfileModelSpec {
294
- protocol: 'geminiInteractions' | 'openAi';
295
- provider: 'google' | 'openrouter' | 'local';
296
- /** Ids this profile may select. Each id must exist in `config`. */
297
- allow: ModelId[];
298
- /** Host-owned wire config keyed by the same ids used in `allow` / `select`. */
299
- config: Record<ModelId, ModelSpec>;
300
- select?: Record<string, ModelId>;
301
- thinking?: ThinkingLevel | Record<string, ThinkingLevel>;
302
- controls?: ControlId[];
298
+ export type { ProfileTurnBehaviourSpec, ProfileTurnResumptionSpec, TurnContinueFrom, TurnStop, } from './stop.js';
299
+ import type { GuardrailEvent, HostGuardrailsSpec, ProfileGuardrailsSpec } from '../guardrails/types.js';
300
+ import type { ProfileObservabilitySpec } from '../observability/types.js';
301
+ import type { ToolCredential } from './auth/types.js';
302
+ import type { ProfileTurnBehaviourSpec, TurnContinueFrom, TurnStop } from './stop.js';
303
+ /** Model routing fields shared by every profile type. */
304
+ export interface ProfileModelFields {
305
+ /** Host-named models. Each key is a selectable model id when `allowModelSelect` is set. */
306
+ models: Record<ModelId, ModelBinding>;
307
+ /** Default model id when the turn omits `model`. Defaults to the only key when there is one. */
308
+ defaultModel?: ModelId;
309
+ /** Turn may pass `{ model: "<id>" }`. Requires two or more `models` keys. */
310
+ allowModelSelect?: boolean;
311
+ /**
312
+ * Tool-loop ceiling. `<= 0` = unbounded; `1` = one-shot; `> 1` = hard cap.
313
+ * Omit → unbounded (no THEORUM invent of `1`).
314
+ */
303
315
  maxSteps?: number;
304
- key?: GeminiFreeBucket;
316
+ key?: OverflowKeySlot;
305
317
  }
306
318
  /** Text, attachment, voice, slot, and size rules for a profile. */
307
319
  export interface ProfileInputsSpec {
@@ -318,35 +330,89 @@ export interface ProfileInputsSpec {
318
330
  limitsByMime?: Record<string, number>;
319
331
  slots?: Record<string, string[]>;
320
332
  }
321
- /** Output schema, image, speech, validation, and stream rules for a profile. */
333
+ /** Chat-shaped output schema, validation, and stream filters. */
322
334
  export interface ProfileOutputsSpec {
323
335
  structured?: StructuredSchemaId | StructuredBySlot | null;
324
- /** Pins for an image-role profile. Model id is on `model`. */
325
- image?: ProfileImageSpec;
326
- /** Pins for a speech-role profile (`voice` / `format`). Model id is on `model`. */
327
- speech?: ProfileSpeechSpec;
328
336
  validation?: ProfileValidationSpec;
329
337
  streaming?: ProfileStreamingSpec;
330
- /** Resume / Continue policy for non-user stops. */
331
- resume?: ProfileResumeSpec;
332
338
  }
333
- /** Complete host-owned agent contract consumed by the kernel. */
334
- export interface Profile {
339
+ /** Shared identity block for every profile type. */
340
+ export interface ProfileIdentity {
341
+ handle: string;
342
+ system?: string;
343
+ systemByRole?: Record<string, string>;
344
+ }
345
+ /** Fields shared by every typed profile. */
346
+ export interface ProfileCommon {
335
347
  id: ProfileId;
336
- identity: {
337
- handle: string;
338
- chat?: boolean;
339
- system?: string;
340
- systemByRole?: Record<string, string>;
341
- };
342
- model: ProfileModelSpec;
343
- tools: {
344
- allow: ToolId[];
345
- };
348
+ identity: ProfileIdentity;
349
+ models: Record<ModelId, ModelBinding>;
350
+ defaultModel?: ModelId;
351
+ allowModelSelect?: boolean;
352
+ maxSteps?: number;
353
+ key?: OverflowKeySlot;
354
+ outputs?: ProfileOutputsSpec;
355
+ guardrails?: ProfileGuardrailsSpec;
356
+ observability?: ProfileObservabilitySpec;
357
+ }
358
+ /** Text / structured turn engine with optional tool execution. */
359
+ export interface TextProfile extends ProfileCommon {
360
+ type: 'text';
361
+ tools: ProfileToolsSpec;
346
362
  inputs: ProfileInputsSpec;
347
- outputs: ProfileOutputsSpec;
348
- guardrails: ProfileGuardrailsSpec;
363
+ /** Resume + mid-turn steering policy. */
364
+ turnBehaviour?: ProfileTurnBehaviourSpec;
365
+ }
366
+ /** Image-generation primary role. */
367
+ export interface ImageProfile extends ProfileCommon {
368
+ type: 'image';
369
+ image: ProfileImageSpec;
370
+ tools: ProfileToolsSpec;
371
+ inputs: ProfileInputsSpec;
372
+ /** Resume policy (`allowSteering` is rejected — text/live only). */
373
+ turnBehaviour?: ProfileTurnBehaviourSpec;
374
+ }
375
+ /** Unary TTS — text-in locked by type; no tools / inputs block. */
376
+ export interface SpeechProfile extends ProfileCommon {
377
+ type: 'speech';
378
+ speech: ProfileSpeechSpec;
379
+ /** Resume policy (`allowSteering` is rejected — text/live only). */
380
+ turnBehaviour?: ProfileTurnBehaviourSpec;
381
+ }
382
+ /** Bidirectional live session. */
383
+ export interface LiveProfile extends Omit<ProfileCommon, 'outputs'> {
384
+ type: 'live';
385
+ live: ProfileLiveSpec;
386
+ tools: LiveProfileToolsSpec;
387
+ /**
388
+ * Stage inject gate only (`allowSteering`). Resumption is `live.sessionResumption`,
389
+ * not `turnBehaviour.resumption` (`docs/contracts/stages.md`).
390
+ */
391
+ turnBehaviour?: Pick<ProfileTurnBehaviourSpec, 'allowSteering'>;
392
+ }
393
+ /**
394
+ * Host-driven tool execution ceiling — never runs a model.
395
+ *
396
+ * `invokeTool` under a `host` profile executes any tool in `tools.allow` with no
397
+ * visibility or loading tiers and no path gating. No `models`, `identity`,
398
+ * `inputs`, `outputs`, `turnBehaviour`, `key`, or `maxSteps`. `resolveTurn`,
399
+ * `runTurn`, and `runSession` refuse it.
400
+ *
401
+ * `guardrails` is narrowed to {@link HostGuardrailsSpec}: only the guards that
402
+ * fire on the `invokeTool` path. Quota, canary, and egress guard a model turn,
403
+ * so `defineProfile` refuses them here rather than accepting inert config.
404
+ */
405
+ export interface HostProfile {
406
+ type: 'host';
407
+ id: ProfileId;
408
+ tools: HostProfileToolsSpec;
409
+ guardrails?: HostGuardrailsSpec;
410
+ observability?: ProfileObservabilitySpec;
349
411
  }
412
+ /** Complete host-owned agent contract consumed by the kernel. */
413
+ export type Profile = TextProfile | ImageProfile | SpeechProfile | LiveProfile | HostProfile;
414
+ /** Profiles that bind models — every type except `host`. */
415
+ export type ModelProfile = Exclude<Profile, HostProfile>;
350
416
  /** Text part sent to provider adapters after input normalization. */
351
417
  export interface InteractionTextPart {
352
418
  type: 'text';
@@ -358,21 +424,46 @@ export interface InteractionMediaPart {
358
424
  mimeType: string;
359
425
  data: string;
360
426
  }
427
+ /**
428
+ * Media part carried by reference (e.g. a Gemini Files `files/<id>` uri).
429
+ * The host owns the upload and cleanup; THEORUM only carries the reference.
430
+ * Wired by the Google Interactions adapter; other adapters reject it.
431
+ */
432
+ export interface InteractionMediaRefPart {
433
+ type: MediaInputKind;
434
+ mimeType: string;
435
+ uri: string;
436
+ }
361
437
  /** Any provider input part accepted by THEORUM's provider contract. */
362
- export type InteractionPart = InteractionTextPart | InteractionMediaPart;
438
+ export type InteractionPart = InteractionTextPart | InteractionMediaPart | InteractionMediaRefPart;
363
439
  /** Native image response request passed to image-capable providers. */
364
440
  export interface ImageResponseFormat {
365
441
  type: 'image';
366
- mimeType: string;
367
- aspectRatio: string;
368
- /** Authoring / kernel name; adapters map to provider wire keys (e.g. Google `imageSize`). */
369
- size: string;
442
+ /** Omitted when the profile does not pin MIME; providers use their default. */
443
+ mimeType?: string;
444
+ /** Omitted when the profile does not pin aspect; providers use their default. */
445
+ aspectRatio?: string;
446
+ /**
447
+ * Authoring / kernel name; adapters map to provider wire keys (e.g. Google `imageSize`).
448
+ * Omitted when the profile does not pin size; providers use their default.
449
+ */
450
+ size?: string;
451
+ /** Request assistant text alongside generated images when the provider supports it. */
452
+ includeText: boolean;
370
453
  }
371
454
  /** Base64-encoded blob supplied by a host turn request. */
372
455
  export interface TurnBlob {
373
456
  mimeType: string;
374
457
  data: string;
375
458
  }
459
+ /**
460
+ * Media attachment supplied by reference (provider file uri) instead of bytes.
461
+ * MIME acceptance still applies; base64 and byte limits do not.
462
+ */
463
+ export interface TurnMediaRef {
464
+ mimeType: string;
465
+ uri: string;
466
+ }
376
467
  /** Provider-neutral history message preserving text, parts, tools, and metadata. */
377
468
  export interface TurnHistoryMessage {
378
469
  role: 'system' | 'user' | 'assistant' | 'tool';
@@ -391,39 +482,6 @@ export interface TurnHistoryMessage {
391
482
  name?: string;
392
483
  metadata?: Record<string, unknown>;
393
484
  }
394
- /** Tool visibility tier used by host dynamic-loading strategies. */
395
- export type ToolLoadTier = 'T0' | 'T1' | 'T2';
396
- /** Execution authorization tier for dynamic tools. */
397
- export type ToolPermissionTier = 'auto' | 'session_consent' | 'always_confirm';
398
- /** Context supplied to a dynamic tool authorization hook. */
399
- export interface DynamicToolExecutionContext {
400
- args: Record<string, unknown>;
401
- profile: Profile;
402
- sessionPermissions?: string[];
403
- }
404
- /** Context supplied to a host dynamic tool schema loader. */
405
- export interface DynamicToolLoadContext {
406
- name: string;
407
- args: Record<string, unknown>;
408
- profile: Profile;
409
- currentTools: DynamicToolDeclaration[];
410
- sessionPermissions?: string[];
411
- }
412
- /** Host function that loads more tool declarations during a turn. */
413
- export type DynamicToolLoader = (context: DynamicToolLoadContext) => DynamicToolDeclaration[] | Promise<DynamicToolDeclaration[]>;
414
- /** Runtime tool schema and execution policy supplied by the host app. */
415
- export interface DynamicToolDeclaration {
416
- name: string;
417
- description?: string;
418
- parameters?: Record<string, unknown>;
419
- loadTier?: ToolLoadTier;
420
- permissionTier?: ToolPermissionTier;
421
- category?: string;
422
- /** Marks this declaration as a schema-loader tool for T2 expansion. */
423
- loadsDynamicTools?: boolean;
424
- handler?: (args: Record<string, unknown>) => ToolEnvelope | Promise<ToolEnvelope>;
425
- canExecute?: (context: DynamicToolExecutionContext) => boolean | Promise<boolean> | ToolEnvelope | Promise<ToolEnvelope>;
426
- }
427
485
  /** Generic repair request used for validation and egress retry turns. */
428
486
  export interface TurnRepairRequest {
429
487
  previousOutput: string;
@@ -435,7 +493,7 @@ export interface TurnInput {
435
493
  text?: string;
436
494
  role?: string;
437
495
  slots?: Record<string, string>;
438
- attachments?: TurnBlob[];
496
+ attachments?: Array<TurnBlob | TurnMediaRef>;
439
497
  voice?: TurnBlob[];
440
498
  history?: TurnHistoryMessage[];
441
499
  repair?: TurnRepairRequest;
@@ -450,6 +508,8 @@ export interface TurnInput {
450
508
  * Ignored when `meter` is `'history'`.
451
509
  */
452
510
  inputTokens?: number;
511
+ /** Optional session resumption handle for continuing live WebSocket sessions. */
512
+ sessionResumptionHandle?: string;
453
513
  }
454
514
  /** Host request after kernel ingress normalization. */
455
515
  export type NormalizedTurnRequest = TurnRequest & {
@@ -460,24 +520,42 @@ export interface TurnRequest {
460
520
  profile: ProfileId;
461
521
  /** Caller project id when one exists. Omitted on some HTTP hosts. */
462
522
  projectId?: string;
523
+ /**
524
+ * Sticky routing / cache session key for OpenRouter (`session_id`).
525
+ * Not the same as `projectId` or Gemini `previousInteractionId`.
526
+ */
527
+ sessionId?: string;
463
528
  /** Google Interactions server-side conversation state. Omit for stateless/manual history. */
464
529
  previousInteractionId?: string;
465
- /** Optional Interactions storage override. Omit to let provider/project policy decide. */
530
+ /**
531
+ * Location bias for Interactions `google_maps` builtin.
532
+ * Wired as `tools: [{ type: "google_maps", latitude, longitude }]`.
533
+ * Ignored when `googleMaps` is not enabled for the selected model.
534
+ */
535
+ googleMapsLocation?: {
536
+ latitude: number;
537
+ longitude: number;
538
+ };
539
+ /** Optional Interactions storage override. Omit to let the selected model binding decide. */
466
540
  store?: boolean;
467
- select?: string;
468
- thinking?: boolean;
541
+ /** Selected model id when `profile.allowModelSelect` is true. */
542
+ model?: ModelId;
543
+ /** Selected effort alias when the binding has `allowEffortSelect`. */
544
+ effort?: string;
469
545
  /** Host-provided dynamic system prompt combined with profile persona */
470
546
  system?: string;
471
547
  /** Session permissions granted for this conversation turn */
472
548
  sessionPermissions?: string[];
473
- /** Opt-in gates. Profile `allow` is the ceiling; a tool is off until `tools[id]` is true. */
474
- tools?: Partial<Record<ToolId, boolean>>;
475
- /** Runtime tool declarations (e.g. load_when_needed strategy) */
476
- dynamicTools?: DynamicToolDeclaration[];
477
- /** Generic host-owned loader for T2 dynamic tool schema expansion. */
478
- dynamicToolLoader?: DynamicToolLoader;
549
+ /** Host channel/path for catalog `paths` filtering. */
550
+ path?: string;
479
551
  /** Host-owned metadata preserved for traces; the kernel does not interpret it. */
480
552
  metadata?: Record<string, unknown>;
553
+ /**
554
+ * Opaque application context handed to tool `handler` / `preTool` and
555
+ * `tools.t1Policy` as `ctx.host`. The kernel never reads, logs, traces, or
556
+ * serializes it.
557
+ */
558
+ host?: unknown;
481
559
  /**
482
560
  * Optional abort signal. When aborted, THEORUM stops the turn and cancels
483
561
  * in-flight provider HTTP where the adapter supports it.
@@ -488,71 +566,115 @@ export interface TurnRequest {
488
566
  * the system prompt; hosts should also pass partial artifact via input/history.
489
567
  */
490
568
  continueFrom?: TurnContinueFrom;
569
+ /**
570
+ * 1-based continue attempt when `continueFrom` is set.
571
+ * Compared to `profile.turnBehaviour.resumption.maxContinues` when that cap is set.
572
+ */
573
+ continuation?: number;
491
574
  input?: TurnInput;
492
- toolInvoke?: {
493
- name: CustomToolId;
494
- arguments: Record<string, unknown>;
495
- };
496
575
  /** Provider for the compaction profile when `timing: 'before'`. Falls back to the turn provider. */
497
576
  compactionProvider?: ModelProvider;
577
+ /** Optional session resumption handle for continuing live WebSocket sessions. */
578
+ sessionResumptionHandle?: string;
579
+ /** Host credentials for authenticated HTTP / MCP tools keyed by auth slot. */
580
+ credentials?: Record<string, ToolCredential>;
581
+ /**
582
+ * Turn-stage handler (`docs/contracts/stages.md`).
583
+ * Text `runTurn` emits stages and applies returned affordances.
584
+ */
585
+ onStage?: StageHandler;
498
586
  }
499
- /** Safe profile projection suitable for UI or host inspection. */
500
- export interface ProjectedProfile {
587
+ /** Safe profile projection suitable for UI or host inspection (model profiles only). */
588
+ export interface ProjectedProfile extends ProfileModelFields {
501
589
  id: string;
590
+ type: ModelProfile['type'];
502
591
  handle: string;
503
- chat: boolean;
504
- maxSteps: number;
505
- models: ModelId[];
506
- select: Record<string, ModelId> | null;
507
- controls: ControlId[];
508
- tools: Array<ToolCatalogEntry & {
592
+ tools: Array<RegisteredTool | {
509
593
  name: ToolId;
594
+ missing: true;
510
595
  }>;
511
- inputs: Profile['inputs'];
512
- slots: Record<string, string[]>;
513
- outputs: Profile['outputs'];
596
+ inputs: ProfileInputsSpec | null;
597
+ outputs: ProfileOutputsSpec | null;
514
598
  image?: ProfileImageSpec | null;
599
+ speech?: ProfileSpeechSpec | null;
600
+ live?: ProfileLiveSpec | null;
515
601
  }
516
602
  /** Provider selection and generation knobs shared before and after resolution. */
517
603
  export interface ProviderGenerationConfig {
518
604
  model: ModelId;
519
- /** Provider-native model id taken from the profile model spec. */
605
+ /** Provider wire model id taken from the profile model spec. */
520
606
  apiId: string;
521
- openRouterId?: string;
522
607
  previousInteractionId?: string;
523
608
  store?: boolean;
524
- thinking: ThinkingLevel;
525
- summaries: 'auto' | 'none';
526
- maxOutputTokens: number;
527
- temperature: number;
609
+ /**
610
+ * Upstream stream vs batch, derived from `outputs.streaming.mode`.
611
+ * `true` = SSE (THEORUM default when mode is omitted); `false` = buffered.
612
+ */
613
+ stream?: boolean;
614
+ thinking?: ThinkingLevel;
615
+ summaries?: SummaryMode;
616
+ maxOutputTokens?: number;
617
+ temperature?: number;
528
618
  builtins: BuiltinToolId[];
619
+ /**
620
+ * Location bias for Interactions `google_maps`.
621
+ * Copied from `TurnRequest.googleMapsLocation` when present.
622
+ */
623
+ googleMapsLocation?: {
624
+ latitude: number;
625
+ longitude: number;
626
+ };
627
+ /**
628
+ * OpenRouter prompt-cache policy from the selected model binding.
629
+ * Omitted for non-openrouter bindings.
630
+ */
631
+ cache?: CacheSpec;
632
+ /**
633
+ * OpenRouter sticky session id from `TurnRequest.sessionId`.
634
+ * Forwarded as request `session_id` when present.
635
+ */
636
+ sessionId?: string;
529
637
  }
638
+ /** Resolved provider transport derived once in `resolveTurn`. */
639
+ export type ProviderTransport = 'interactions' | 'geminiLive' | 'openAiCompat';
530
640
  /** Fully-resolved provider request state created from a `TurnRequest`. */
531
641
  export interface ResolvedGeneration extends ProviderGenerationConfig {
532
- custom: CustomToolId[];
533
- dynamicTools?: DynamicToolDeclaration[];
534
- dynamicToolLoader?: DynamicToolLoader;
642
+ /** Resolved transport — `'interactions'` for Google Gemini Interactions, `'geminiLive'` for Gemini Live WebSocket, `'openAiCompat'` otherwise. */
643
+ transport: ProviderTransport;
644
+ /** Mutable tool visibility and wire snapshot for this turn. */
645
+ tools: TurnToolSnapshot;
535
646
  sessionPermissions?: string[];
536
647
  history?: TurnHistoryMessage[];
537
- maxSteps: number;
648
+ /**
649
+ * Interactions-only: when set, sent as the request `input` array instead of
650
+ * history + user parts (e.g. a lone `function_result` continuation step).
651
+ */
652
+ interactionOnlyInput?: Record<string, unknown>[];
653
+ /**
654
+ * Tool-loop ceiling. `undefined` or `<= 0` = unbounded.
655
+ * Taken from `profile.maxSteps` with no THEORUM invent.
656
+ */
657
+ maxSteps?: number;
538
658
  structured: StructuredSchemaId | null;
539
659
  image: ImageResponseFormat | null;
540
660
  speech?: ProfileSpeechSpec;
661
+ live?: ProfileLiveSpec;
541
662
  input: InteractionPart[];
542
663
  /**
543
- * Gemini vault slot for Google Interactions transport only.
544
- * Omitted for non-Google providers; never sent on the wire.
664
+ * Vault key slot for credentialed transports (Google required; OpenRouter when
665
+ * the profile pins `key` or a builtin forces `paid`). Never sent on the wire.
545
666
  */
546
- geminiBucket?: GeminiBucket;
667
+ keySlot?: KeySlot;
547
668
  canary: string;
548
- }
549
- /** Tool execution status returned to the model and stream. */
550
- export type ToolStatus = 'ok' | 'error' | 'pause';
551
- /** Structured result envelope returned by deterministic tool handlers. */
552
- export interface ToolEnvelope {
553
- status: ToolStatus;
554
- finding?: string;
555
- data?: Record<string, unknown>;
669
+ /** Optional session resumption handle for continuing live WebSocket sessions. */
670
+ sessionResumptionHandle?: string;
671
+ /**
672
+ * Merged profile + turn system prompt, snapshotted synchronously in `resolveTurn`
673
+ * before any async work. Runner applies canary bind on top of this string.
674
+ */
675
+ resolvedSystem: string;
676
+ /** `TurnRequest.host`, carried to tool contexts only. Never sent to providers or traces. */
677
+ host?: unknown;
556
678
  }
557
679
  /** Token accounting emitted by providers or fallback estimation. */
558
680
  export interface TurnTokens {
@@ -560,6 +682,12 @@ export interface TurnTokens {
560
682
  output: number;
561
683
  thinking?: number;
562
684
  toolUse?: number;
685
+ /** Google code-execution / tool intermediate tokens when the API reports them. */
686
+ intermediate?: number;
687
+ /** Prompt tokens read from provider cache (cache hit). */
688
+ cached?: number;
689
+ /** Prompt tokens written into provider cache. */
690
+ cacheWrite?: number;
563
691
  total: number;
564
692
  }
565
693
  /** Normalized citation or place source surfaced from a provider. */
@@ -567,6 +695,8 @@ export interface GroundingSource {
567
695
  title: string;
568
696
  uri: string;
569
697
  type: 'maps' | 'web';
698
+ /** Google Place id when the source is a Maps place / place_citation. */
699
+ placeId?: string;
570
700
  }
571
701
  /** Google grounding metadata normalized into a stream event. */
572
702
  export interface GroundingEvent {
@@ -575,13 +705,36 @@ export interface GroundingEvent {
575
705
  searchHtml?: string;
576
706
  sources: GroundingSource[];
577
707
  }
578
- /** Provider evidence such as OpenRouter citations or annotations. */
708
+ /** Provider evidence such as OpenRouter citations or Google server-side tool steps. */
579
709
  export interface ProviderEvidenceEvent {
580
710
  provider: 'openrouter' | 'google' | string;
581
711
  raw?: Record<string, unknown>;
582
712
  citations?: string[];
583
713
  annotations?: unknown[];
584
714
  sources?: GroundingSource[];
715
+ /**
716
+ * Discriminant for evidence payloads.
717
+ * Live ASR uses `input_transcription` / `output_transcription`;
718
+ * resumption uses `session_resumption`; Interactions code execution uses
719
+ * `code_execution_call` / `code_execution_result`.
720
+ */
721
+ kind?: 'code_execution_call' | 'code_execution_result' | 'input_transcription' | 'output_transcription' | 'session_resumption' | string;
722
+ /** Generated Python (or other) source from `code_execution_call.arguments.code`. */
723
+ code?: string;
724
+ /** Language of `code` when the API supplies it (typically `python`). */
725
+ language?: string;
726
+ /** Stdout / sandbox output from `code_execution_result.result`. */
727
+ result?: string;
728
+ /** `true` when the sandbox reported an execution error. */
729
+ isError?: boolean;
730
+ /** Step id (`code_execution_call.id`). */
731
+ id?: string;
732
+ /** Links a result to its call (`code_execution_result.call_id`). */
733
+ callId?: string;
734
+ /** Live ASR: partial/interim chunk (vs final transcription delta). */
735
+ interim?: boolean;
736
+ /** Live session resumption: whether the handle may be used to resume. */
737
+ resumable?: boolean;
585
738
  }
586
739
  /** Compaction signal emitted in the `done` event when `timing: 'after'`. */
587
740
  export interface CompactionSignal {
@@ -601,11 +754,10 @@ export interface CompactionSignal {
601
754
  export interface TurnEvent {
602
755
  type: TurnEventType;
603
756
  text?: string;
604
- tool?: {
605
- name: string;
606
- arguments?: Record<string, unknown>;
607
- result?: ToolEnvelope;
757
+ tool?: ToolCallEvent & {
758
+ /** Provider-native tool call id when present. */
608
759
  id?: string;
760
+ arguments?: Record<string, unknown>;
609
761
  };
610
762
  structured?: unknown;
611
763
  media?: {
@@ -614,8 +766,15 @@ export interface TurnEvent {
614
766
  };
615
767
  grounding?: GroundingEvent;
616
768
  evidence?: ProviderEvidenceEvent;
769
+ session?: SessionEvent;
770
+ /** Guardrail decision for this turn — rule identity and offsets, never content. */
771
+ guardrail?: GuardrailEvent;
617
772
  tokens?: TurnTokens;
618
773
  interactionId?: string;
774
+ /** Session resumption handle updated during live sessions. */
775
+ sessionResumptionHandle?: string;
776
+ /** True when a user utterance interrupted an in-flight live model response (barge-in). */
777
+ interrupted?: boolean;
619
778
  /** Public-safe failure text for hosts to show users. */
620
779
  error?: string;
621
780
  /** Raw diagnostic detail for traces/logs; never surface to end users. */
@@ -624,24 +783,68 @@ export interface TurnEvent {
624
783
  compaction?: CompactionSignal;
625
784
  /** Why the turn ended. Present on terminal `done` events when known. */
626
785
  stop?: TurnStop;
786
+ /**
787
+ * Turn tool visibility snapshot when `stop.kind === 'tool'`.
788
+ * Hosts pass this to `invokeTool({ snapshot })` so T1/T2 resume matches the gated turn.
789
+ */
790
+ tools?: TurnToolSnapshot;
791
+ /** Turn-stage name when `type === 'stage'` (`docs/contracts/stages.md`). */
792
+ stage?: TurnStage;
793
+ /** Tool call id on `stage` / related tool-stage events. */
794
+ callId?: string;
795
+ /** Tool name on `stage` events (`pre_tool` / `post_tool`). Not `tool` (ToolCallEvent). */
796
+ toolName?: string;
797
+ /** True when a tool completed with awaiting_user_input (on stage/tool events). */
798
+ awaiting?: boolean;
799
+ /** pre_tool gate payload when `tool.phase === 'gate'` or stage carries a gate. */
800
+ gate?: ToolGate;
801
+ /** True when pre_tool settled without running the body. */
802
+ callNotStarted?: boolean;
803
+ /**
804
+ * Host-visible stage affordance warnings (`docs/contracts/stages.md`).
805
+ * Emitted after `onStage` when invalid/rejected fields were dropped.
806
+ */
807
+ stageWarnings?: StageApplyWarning[];
627
808
  }
628
- /** Provider-neutral request object sent from the kernel to a model adapter. */
629
- export interface ProviderCompleteRequest extends ProviderGenerationConfig {
809
+ /**
810
+ * Provider-neutral request object sent from the kernel to a model adapter.
811
+ *
812
+ * Several fields are **Google Interactions-only** and omitted otherwise:
813
+ * `previousInteractionId`, `store`, `stream`, `summaries`,
814
+ * `interactionOnlyInput`.
815
+ * Adapters must tolerate their absence. `keySlot` is shared by Google and
816
+ * OpenRouter vault resolution (required for Google; optional for OpenRouter).
817
+ */
818
+ export interface ProviderCompleteRequest extends Omit<ProviderGenerationConfig, 'summaries'> {
819
+ /**
820
+ * Interactions-only: thinking-summary behavior.
821
+ * Omitted (undefined) for non-Google providers.
822
+ */
823
+ summaries?: SummaryMode;
630
824
  system: string;
631
825
  input: InteractionPart[];
632
826
  history?: TurnHistoryMessage[];
633
- dynamicTools?: DynamicToolDeclaration[];
634
- dynamicToolLoader?: DynamicToolLoader;
827
+ /**
828
+ * Interactions-only: when set, sent as the request `input` array instead of
829
+ * history + user parts (e.g. a lone `function_result` continuation step).
830
+ * Omitted for non-Google providers.
831
+ */
832
+ interactionOnlyInput?: Record<string, unknown>[];
833
+ /** Function tool wire declarations derived from the turn tool snapshot. */
834
+ wireTools?: WireFunctionTool[];
635
835
  structured: StructuredSchemaId | null;
636
836
  image: ImageResponseFormat | null;
637
837
  speech?: ProfileSpeechSpec;
838
+ live?: ProfileLiveSpec;
839
+ /** Optional session resumption handle for continuing live WebSocket sessions. */
840
+ sessionResumptionHandle?: string;
638
841
  /**
639
- * Gemini vault slot for Google Interactions transport only.
640
- * Required when completing via Google Interactions.
842
+ * Vault key slot. Required for Google; set for OpenRouter when the profile
843
+ * pins `model.key` or a builtin forces `paid`. Never sent on the wire.
641
844
  */
642
- geminiBucket?: GeminiBucket;
845
+ keySlot?: KeySlot;
643
846
  /** Scrubbed SSE / HTTP rows for traces. */
644
- tapGemini?: (row: Record<string, unknown>) => void;
847
+ tapUpstream?: (row: Record<string, unknown>) => void;
645
848
  /** Host abort signal — adapters should pass this into fetch / SDK calls. */
646
849
  signal?: AbortSignal;
647
850
  }
@@ -649,3 +852,84 @@ export interface ProviderCompleteRequest extends ProviderGenerationConfig {
649
852
  export interface ModelProvider {
650
853
  complete: (req: ProviderCompleteRequest) => AsyncIterable<TurnEvent>;
651
854
  }
855
+ /**
856
+ * Host request to open a long-lived live session (`runSession`).
857
+ * Profile must be `type: 'live'`.
858
+ */
859
+ export interface SessionRequest {
860
+ profile: ProfileId;
861
+ /** Host-built system prompt merged with profile identity.system. */
862
+ system?: string;
863
+ /** Override `profile.live.voice` for this session. */
864
+ voice?: string;
865
+ path?: string;
866
+ sessionPermissions?: string[];
867
+ history?: TurnHistoryMessage[];
868
+ sessionResumptionHandle?: string;
869
+ /** Optional realtime parts sent immediately after setup. */
870
+ input?: InteractionPart[];
871
+ /**
872
+ * Registry-resolved tool snapshot from the process that owns the tool registry
873
+ * (`prepareTurnToolSnapshot`). When set, session setup declares `snapshot.wire`
874
+ * instead of resolving tools locally, so a relay process without the registry
875
+ * can open the session. Every custom id must be within the profile's
876
+ * `tools.allow`; ids outside it are refused.
877
+ */
878
+ snapshot?: TurnToolSnapshot;
879
+ signal?: AbortSignal;
880
+ metadata?: Record<string, unknown>;
881
+ /**
882
+ * Session-lifetime stage handler (`docs/contracts/stages.md`). Immutable for
883
+ * the session; no `setOnStage`.
884
+ */
885
+ onStage?: StageHandler;
886
+ /** Default credentials for `executeTool` (per-call args override). */
887
+ credentials?: Record<string, ToolCredential>;
888
+ /** Opaque host slot for stages / tool execute (per-call args override). */
889
+ host?: unknown;
890
+ }
891
+ /**
892
+ * Long-lived live session returned by `runSession`.
893
+ * `done` events mark conversational turn boundaries; the session stays open until `close()`.
894
+ */
895
+ export type LiveExecuteToolArgs = {
896
+ name: string;
897
+ callId: string;
898
+ input?: unknown;
899
+ resume?: InvokeToolResume;
900
+ credentials?: Record<string, ToolCredential>;
901
+ host?: unknown;
902
+ };
903
+ export type LiveExecuteToolResult = {
904
+ outputRaw?: unknown;
905
+ outputModel?: ModelToolResult;
906
+ failure?: ToolFailure;
907
+ awaiting?: boolean;
908
+ gated?: ToolGate;
909
+ };
910
+ export interface LiveSession {
911
+ readonly profileId: ProfileId;
912
+ readonly canary: string;
913
+ events(): AsyncGenerator<TurnEvent, void, undefined>;
914
+ sendAudio(args: {
915
+ data: string;
916
+ mimeType?: string;
917
+ }): Promise<void>;
918
+ sendVideo(args: {
919
+ data: string;
920
+ mimeType?: string;
921
+ }): Promise<void>;
922
+ sendText(text: string): Promise<void>;
923
+ /**
924
+ * Registry tool execute with stages. Pumps `stage`/`tool` into `events()`.
925
+ * Gate → returns `gated` without upstream tool response; resume with `granted`.
926
+ */
927
+ executeTool(args: LiveExecuteToolArgs): Promise<LiveExecuteToolResult>;
928
+ sendToolResponse(id: string, name: string, output: unknown): void;
929
+ sendToolResponses(responses: Array<{
930
+ id: string;
931
+ name: string;
932
+ output: unknown;
933
+ }>): void;
934
+ close(reason?: string): Promise<void>;
935
+ }