theorum 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/esm/_dnt.polyfills.d.ts +110 -0
  2. package/esm/_dnt.polyfills.js +144 -0
  3. package/esm/_dnt.shims.d.ts +5 -0
  4. package/esm/_dnt.shims.js +61 -0
  5. package/{mod.ts → esm/mod.d.ts} +17 -57
  6. package/esm/mod.js +50 -0
  7. package/esm/package.json +3 -0
  8. package/esm/src/cli/commands/profile.d.ts +2 -0
  9. package/esm/src/cli/commands/profile.js +53 -0
  10. package/esm/src/cli/commands/run.d.ts +10 -0
  11. package/esm/src/cli/commands/run.js +55 -0
  12. package/esm/src/cli/commands/test.d.ts +15 -0
  13. package/esm/src/cli/commands/test.js +140 -0
  14. package/esm/src/cli/index.d.ts +4 -0
  15. package/esm/src/cli/index.js +148 -0
  16. package/esm/src/cli/matrix/fixtures.d.ts +13 -0
  17. package/esm/src/cli/matrix/fixtures.js +77 -0
  18. package/esm/src/cli/matrix/synthesizer.d.ts +29 -0
  19. package/esm/src/cli/matrix/synthesizer.js +187 -0
  20. package/esm/src/guardrails/error.d.ts +45 -0
  21. package/esm/src/guardrails/error.js +149 -0
  22. package/esm/src/guardrails/injection.d.ts +12 -0
  23. package/esm/src/guardrails/injection.js +220 -0
  24. package/esm/src/guardrails/mod.d.ts +16 -0
  25. package/esm/src/guardrails/mod.js +15 -0
  26. package/esm/src/guardrails/quota.d.ts +10 -0
  27. package/esm/src/guardrails/quota.js +64 -0
  28. package/esm/src/guardrails/sanitize.d.ts +22 -0
  29. package/esm/src/guardrails/sanitize.js +133 -0
  30. package/esm/src/guardrails/sensitive.d.ts +12 -0
  31. package/esm/src/guardrails/sensitive.js +88 -0
  32. package/esm/src/host/mint-trace.d.ts +27 -0
  33. package/esm/src/host/mint-trace.js +33 -0
  34. package/esm/src/host/mod.d.ts +13 -0
  35. package/{src/host/mod.ts → esm/src/host/mod.js} +3 -11
  36. package/esm/src/host/reply.d.ts +14 -0
  37. package/esm/src/host/reply.js +27 -0
  38. package/esm/src/kernel/engine/boundary.d.ts +10 -0
  39. package/esm/src/kernel/engine/boundary.js +55 -0
  40. package/esm/src/kernel/engine/delta.d.ts +8 -0
  41. package/esm/src/kernel/engine/delta.js +389 -0
  42. package/esm/src/kernel/engine/hash.d.ts +1 -0
  43. package/esm/src/kernel/engine/hash.js +9 -0
  44. package/esm/src/kernel/engine/record.d.ts +2 -0
  45. package/esm/src/kernel/engine/record.js +7 -0
  46. package/esm/src/kernel/engine/repair.d.ts +7 -0
  47. package/esm/src/kernel/engine/repair.js +38 -0
  48. package/esm/src/kernel/engine/runner/gates.d.ts +4 -0
  49. package/esm/src/kernel/engine/runner/gates.js +203 -0
  50. package/esm/src/kernel/engine/runner/mod.d.ts +14 -0
  51. package/esm/src/kernel/engine/runner/mod.js +109 -0
  52. package/esm/src/kernel/engine/runner/state.d.ts +16 -0
  53. package/esm/src/kernel/engine/runner/state.js +8 -0
  54. package/esm/src/kernel/engine/runner/steps.d.ts +15 -0
  55. package/esm/src/kernel/engine/runner/steps.js +119 -0
  56. package/esm/src/kernel/engine/runner/stream.d.ts +11 -0
  57. package/esm/src/kernel/engine/runner/stream.js +70 -0
  58. package/esm/src/kernel/engine/runner/tokens.d.ts +3 -0
  59. package/esm/src/kernel/engine/runner/tokens.js +38 -0
  60. package/esm/src/kernel/engine/runner/tools.d.ts +13 -0
  61. package/esm/src/kernel/engine/runner/tools.js +192 -0
  62. package/{src/kernel/engine/runner.ts → esm/src/kernel/engine/runner.d.ts} +1 -2
  63. package/esm/src/kernel/engine/runner.js +6 -0
  64. package/esm/src/kernel/engine/tree.d.ts +2 -0
  65. package/esm/src/kernel/engine/tree.js +17 -0
  66. package/esm/src/kernel/mod.d.ts +18 -0
  67. package/esm/src/kernel/mod.js +16 -0
  68. package/esm/src/kernel/registry/attachments.d.ts +16 -0
  69. package/esm/src/kernel/registry/attachments.js +156 -0
  70. package/esm/src/kernel/registry/catalog.d.ts +31 -0
  71. package/esm/src/kernel/registry/catalog.js +135 -0
  72. package/esm/src/kernel/registry/ingress.d.ts +13 -0
  73. package/esm/src/kernel/registry/ingress.js +163 -0
  74. package/esm/src/kernel/registry/profiles.d.ts +34 -0
  75. package/esm/src/kernel/registry/profiles.js +120 -0
  76. package/esm/src/kernel/registry/provider-request.d.ts +4 -0
  77. package/esm/src/kernel/registry/provider-request.js +25 -0
  78. package/esm/src/kernel/registry/resolve.d.ts +19 -0
  79. package/esm/src/kernel/registry/resolve.js +217 -0
  80. package/esm/src/kernel/registry/schemas.d.ts +14 -0
  81. package/esm/src/kernel/registry/schemas.js +23 -0
  82. package/esm/src/kernel/registry/tools.d.ts +12 -0
  83. package/esm/src/kernel/registry/tools.js +36 -0
  84. package/{src/kernel/registry/vault.ts → esm/src/kernel/registry/vault.d.ts} +2 -17
  85. package/esm/src/kernel/registry/vault.js +18 -0
  86. package/esm/src/kernel/types.d.ts +524 -0
  87. package/esm/src/kernel/types.js +10 -0
  88. package/esm/src/observability/mod.d.ts +12 -0
  89. package/{src/observability/mod.ts → esm/src/observability/mod.js} +2 -11
  90. package/esm/src/observability/spans.d.ts +16 -0
  91. package/esm/src/observability/spans.js +56 -0
  92. package/esm/src/observability/trace-attach.d.ts +16 -0
  93. package/esm/src/observability/trace-attach.js +67 -0
  94. package/esm/src/observability/trace-record.d.ts +113 -0
  95. package/esm/src/observability/trace-record.js +143 -0
  96. package/esm/src/observability/trace-usage.d.ts +3 -0
  97. package/esm/src/observability/trace-usage.js +32 -0
  98. package/esm/src/observability/trace.d.ts +23 -0
  99. package/esm/src/observability/trace.js +121 -0
  100. package/esm/src/presets/google.d.ts +50 -0
  101. package/esm/src/presets/google.js +96 -0
  102. package/esm/src/presets/mod.d.ts +11 -0
  103. package/esm/src/presets/mod.js +10 -0
  104. package/esm/src/providers/create-provider.d.ts +29 -0
  105. package/esm/src/providers/create-provider.js +38 -0
  106. package/esm/src/providers/gemini-tape.d.ts +2 -0
  107. package/esm/src/providers/gemini-tape.js +46 -0
  108. package/esm/src/providers/google-tap.d.ts +3 -0
  109. package/esm/src/providers/google-tap.js +48 -0
  110. package/esm/src/providers/interactions.d.ts +5 -0
  111. package/esm/src/providers/interactions.js +153 -0
  112. package/esm/src/providers/keys.d.ts +19 -0
  113. package/esm/src/providers/keys.js +129 -0
  114. package/esm/src/providers/mod.d.ts +12 -0
  115. package/{src/providers/mod.ts → esm/src/providers/mod.js} +2 -4
  116. package/esm/src/providers/openrouter-mod.d.ts +13 -0
  117. package/{src/providers/openrouter-mod.ts → esm/src/providers/openrouter-mod.js} +3 -7
  118. package/esm/src/providers/openrouter-payload.d.ts +32 -0
  119. package/esm/src/providers/openrouter-payload.js +179 -0
  120. package/esm/src/providers/openrouter.d.ts +15 -0
  121. package/esm/src/providers/openrouter.js +589 -0
  122. package/esm/src/providers/pcm.d.ts +7 -0
  123. package/esm/src/providers/pcm.js +35 -0
  124. package/esm/src/providers/provider.d.ts +15 -0
  125. package/esm/src/providers/provider.js +160 -0
  126. package/esm/src/providers/speech.d.ts +23 -0
  127. package/esm/src/providers/speech.js +125 -0
  128. package/esm/src/providers/sse.d.ts +7 -0
  129. package/esm/src/providers/sse.js +53 -0
  130. package/package.json +45 -36
  131. package/deno.json +0 -57
  132. package/deno.lock +0 -469
  133. package/src/cli/commands/profile.ts +0 -57
  134. package/src/cli/commands/run.ts +0 -66
  135. package/src/cli/commands/test.ts +0 -195
  136. package/src/cli/index.ts +0 -161
  137. package/src/cli/matrix/fixtures.ts +0 -96
  138. package/src/cli/matrix/synthesizer.ts +0 -240
  139. package/src/guardrails/error.ts +0 -142
  140. package/src/guardrails/injection.ts +0 -254
  141. package/src/guardrails/mod.ts +0 -40
  142. package/src/guardrails/quota.ts +0 -87
  143. package/src/guardrails/sanitize.ts +0 -165
  144. package/src/guardrails/sensitive.ts +0 -96
  145. package/src/host/mint-trace.ts +0 -54
  146. package/src/host/reply.ts +0 -32
  147. package/src/kernel/engine/assert.ts +0 -29
  148. package/src/kernel/engine/boundary.ts +0 -75
  149. package/src/kernel/engine/delta.ts +0 -440
  150. package/src/kernel/engine/hash.ts +0 -11
  151. package/src/kernel/engine/record.ts +0 -8
  152. package/src/kernel/engine/repair.ts +0 -56
  153. package/src/kernel/engine/runner/gates.ts +0 -338
  154. package/src/kernel/engine/runner/mod.ts +0 -135
  155. package/src/kernel/engine/runner/state.ts +0 -31
  156. package/src/kernel/engine/runner/steps.ts +0 -183
  157. package/src/kernel/engine/runner/stream.ts +0 -83
  158. package/src/kernel/engine/runner/tokens.ts +0 -47
  159. package/src/kernel/engine/runner/tools.ts +0 -266
  160. package/src/kernel/engine/tree.ts +0 -18
  161. package/src/kernel/mod.ts +0 -39
  162. package/src/kernel/registry/attachments.ts +0 -195
  163. package/src/kernel/registry/catalog.ts +0 -181
  164. package/src/kernel/registry/ingress.ts +0 -223
  165. package/src/kernel/registry/profiles.ts +0 -165
  166. package/src/kernel/registry/provider-request.ts +0 -31
  167. package/src/kernel/registry/resolve.ts +0 -290
  168. package/src/kernel/registry/schemas.ts +0 -29
  169. package/src/kernel/registry/tools.ts +0 -45
  170. package/src/kernel/types.ts +0 -576
  171. package/src/observability/spans.ts +0 -70
  172. package/src/observability/trace-attach.ts +0 -96
  173. package/src/observability/trace-record.ts +0 -254
  174. package/src/observability/trace-usage.ts +0 -36
  175. package/src/observability/trace.ts +0 -143
  176. package/src/presets/google.ts +0 -147
  177. package/src/presets/mod.ts +0 -24
  178. package/src/providers/create-provider.ts +0 -64
  179. package/src/providers/gemini-tape.ts +0 -59
  180. package/src/providers/google-tap.ts +0 -57
  181. package/src/providers/interactions.ts +0 -182
  182. package/src/providers/keys.ts +0 -182
  183. package/src/providers/openrouter-payload.ts +0 -232
  184. package/src/providers/openrouter.ts +0 -758
  185. package/src/providers/pcm.ts +0 -37
  186. package/src/providers/provider.ts +0 -206
  187. package/src/providers/speech.ts +0 -180
  188. package/src/providers/sse.ts +0 -59
@@ -1,290 +0,0 @@
1
- /**
2
- * Profile resolution for THEORUM turns.
3
- *
4
- * This module validates caller overrides, selects models and tools, normalizes
5
- * input parts, and produces the provider request state consumed by `runTurn`.
6
- *
7
- * @module
8
- */
9
-
10
- import { TheorumError } from '../../guardrails/error.ts';
11
- import { sanitizeTurnRequest } from '../../guardrails/sanitize.ts';
12
- import { mintCanary } from '../engine/boundary.ts';
13
- import type {
14
- BuiltinToolId,
15
- CustomToolId,
16
- ModelId,
17
- ModelSpec,
18
- Profile,
19
- ProjectedProfile,
20
- ResolvedGeneration,
21
- StructuredSchemaId,
22
- ThinkingLevel,
23
- ToolId,
24
- TurnRequest,
25
- } from '../types.ts';
26
- import {
27
- CATALOG,
28
- clampThinkingLevel,
29
- getTool,
30
- listBuiltinIds,
31
- requireModelSpec,
32
- } from './catalog.ts';
33
- import {
34
- assertImageGrounding,
35
- assertSpeechRole,
36
- resolveImageFormat,
37
- resolveInputParts,
38
- } from './ingress.ts';
39
- import { getProfile } from './profiles.ts';
40
- import { resolveGeminiBucket } from './vault.ts';
41
-
42
- function applyBuiltinMutualExclusions(requested: BuiltinToolId[]): BuiltinToolId[] {
43
- return requested.filter((id) => {
44
- const conflicts = getTool(id)?.conflictsWith ?? [];
45
- return !conflicts.some((other) => requested.includes(other));
46
- });
47
- }
48
-
49
- function firstSelectKey(selectMap: Record<string, ModelId>): string | undefined {
50
- const [key] = Object.keys(selectMap);
51
- return key;
52
- }
53
-
54
- function lookupSelectId(profile: Profile, select?: string): ModelId | undefined {
55
- const { select: selectMap } = profile.model;
56
- if (!selectMap) {
57
- return undefined;
58
- }
59
- let key = select;
60
- if (!key) {
61
- key = firstSelectKey(selectMap);
62
- }
63
- if (!key) {
64
- return undefined;
65
- }
66
- return selectMap[key];
67
- }
68
-
69
- function pickModel(profile: Profile, select?: string): ModelId {
70
- if (profile.model.select) {
71
- const id = lookupSelectId(profile, select);
72
- if (!(id && profile.model.allow.includes(id))) {
73
- let label = '';
74
- if (select) {
75
- label = select;
76
- }
77
- throw new TheorumError(`Unknown model select '${label}' for ${profile.id}`);
78
- }
79
- return id;
80
- }
81
- const [only] = profile.model.allow;
82
- if (!only) {
83
- throw new TheorumError(`Profile ${profile.id} has no models`);
84
- }
85
- return only;
86
- }
87
-
88
- function thinkingFromControl(spec: ModelSpec, thinkingOn: boolean | undefined): ThinkingLevel {
89
- if (thinkingOn) {
90
- return spec.thinking.on;
91
- }
92
- return spec.thinking.off;
93
- }
94
-
95
- function pinnedLevel(
96
- pinned: Record<string, ThinkingLevel>,
97
- key: string | undefined,
98
- ): ThinkingLevel | undefined {
99
- if (!key) {
100
- return undefined;
101
- }
102
- return pinned[key];
103
- }
104
-
105
- function thinkingFromPin(profile: Profile, select?: string): ThinkingLevel {
106
- const pinned = profile.model.thinking;
107
- if (typeof pinned === 'string') {
108
- return pinned;
109
- }
110
- if (!pinned) {
111
- throw new TheorumError(`Profile ${profile.id} must pin thinking or list it in controls`);
112
- }
113
- const fromSelect = pinnedLevel(pinned, select);
114
- if (fromSelect) {
115
- return fromSelect;
116
- }
117
- const fromFirst = pinnedLevel(pinned, firstSelectKey(profile.model.select ?? {}));
118
- if (fromFirst) {
119
- return fromFirst;
120
- }
121
- throw new TheorumError(`Profile ${profile.id} must pin thinking or list it in controls`);
122
- }
123
-
124
- function resolveThinking(
125
- profile: Profile,
126
- spec: ModelSpec,
127
- thinkingOn: boolean | undefined,
128
- select?: string,
129
- ): ThinkingLevel {
130
- const raw = profile.model.controls?.includes('thinking')
131
- ? thinkingFromControl(spec, thinkingOn)
132
- : thinkingFromPin(profile, select);
133
- return clampThinkingLevel(spec, raw);
134
- }
135
-
136
- function resolveSummaries(
137
- profile: Profile,
138
- spec: ModelSpec,
139
- thinkingOn: boolean | undefined,
140
- ): 'auto' | 'none' {
141
- if (profile.model.controls?.includes('thinking')) {
142
- if (thinkingOn) {
143
- return spec.summaries.on;
144
- }
145
- return spec.summaries.off;
146
- }
147
- return spec.summaries.on;
148
- }
149
-
150
- function isGatedOn(requested: Partial<Record<ToolId, boolean>> | undefined, id: ToolId): boolean {
151
- if (!requested) {
152
- return false;
153
- }
154
- return requested[id] === true;
155
- }
156
-
157
- function resolveBuiltins(
158
- profile: Profile,
159
- requested?: Partial<Record<ToolId, boolean>>,
160
- ): BuiltinToolId[] {
161
- const allowed = profile.tools.allow.filter(
162
- (id): id is BuiltinToolId => CATALOG.tools[id]?.kind === 'builtin',
163
- );
164
- const picked = listBuiltinIds().filter((id) => allowed.includes(id) && isGatedOn(requested, id));
165
- return applyBuiltinMutualExclusions(picked);
166
- }
167
-
168
- function resolveCustom(
169
- profile: Profile,
170
- requested?: Partial<Record<ToolId, boolean>>,
171
- ): CustomToolId[] {
172
- return profile.tools.allow.filter(
173
- (id): id is CustomToolId => CATALOG.tools[id]?.kind === 'custom' && isGatedOn(requested, id),
174
- );
175
- }
176
-
177
- function assertToolAllowed(profile: Profile, name: ToolId): void {
178
- if (!profile.tools.allow.includes(name)) {
179
- throw new TheorumError(`Tool '${name}' is not allowed on ${profile.id}`);
180
- }
181
- }
182
-
183
- function resolveStructured(
184
- profile: Profile,
185
- slots?: Record<string, string>,
186
- ): StructuredSchemaId | null {
187
- const { structured } = profile.outputs;
188
- if (!structured) {
189
- return null;
190
- }
191
- if (typeof structured === 'string') {
192
- return structured;
193
- }
194
- const value = slots?.[structured.by];
195
- if (value) {
196
- const mapped = structured.map[value];
197
- if (mapped) {
198
- return mapped;
199
- }
200
- }
201
- return structured.fallback;
202
- }
203
-
204
- /** Resolve a host `TurnRequest` into provider-ready generation state. */
205
- function resolveTurn(req: TurnRequest): {
206
- profile: Profile;
207
- generation: ResolvedGeneration;
208
- } {
209
- const safe = sanitizeTurnRequest(req);
210
- const input = safe.input ?? {};
211
- const profile = getProfile(safe.profile);
212
- const model = pickModel(profile, safe.select);
213
- const spec = requireModelSpec(profile, model);
214
- const thinkingOn = safe.thinking === true;
215
- const builtins = resolveBuiltins(profile, safe.tools);
216
- assertImageGrounding(profile, model, builtins);
217
- assertSpeechRole(profile);
218
- const geminiBucket =
219
- profile.model.provider === 'google'
220
- ? resolveGeminiBucket(profile.model.key ?? 'freeA', spec, builtins)
221
- : undefined;
222
- return {
223
- profile,
224
- generation: {
225
- model,
226
- apiId: spec.apiId,
227
- openRouterId: spec.openRouterId,
228
- previousInteractionId: safe.previousInteractionId,
229
- store: safe.store,
230
- thinking: resolveThinking(profile, spec, thinkingOn, safe.select),
231
- summaries: resolveSummaries(profile, spec, thinkingOn),
232
- maxOutputTokens: spec.maxOutputTokens,
233
- temperature: spec.temperature,
234
- builtins,
235
- custom: resolveCustom(profile, safe.tools),
236
- dynamicTools: safe.dynamicTools,
237
- dynamicToolLoader: safe.dynamicToolLoader,
238
- sessionPermissions: safe.sessionPermissions,
239
- history: input.history,
240
- maxSteps: profile.model.maxSteps ?? 1,
241
- structured: resolveStructured(profile, input.slots),
242
- image: resolveImageFormat(profile, model, input.slots),
243
- speech: profile.outputs.speech,
244
- input: resolveInputParts(profile, model, safe),
245
- geminiBucket,
246
- canary: profile.guardrails.canary !== false ? mintCanary() : '',
247
- },
248
- };
249
- }
250
-
251
- function primaryImageSpec(profile: Profile) {
252
- return profile.outputs.image;
253
- }
254
-
255
- /** Project a registered profile into a safe host/UI inspection object. */
256
- function projectProfile(id: Profile['id']): ProjectedProfile {
257
- const profile = getProfile(id);
258
- const { model, identity, tools, inputs, outputs } = profile;
259
- const { select, allow, maxSteps, controls } = model;
260
- const { handle, chat } = identity;
261
- const { slots } = inputs;
262
- return {
263
- id: profile.id,
264
- handle,
265
- chat: chat !== false,
266
- maxSteps: maxSteps ?? 1,
267
- models: allow,
268
- select: select ?? null,
269
- controls: controls ?? [],
270
- tools: tools.allow.map((name) => ({
271
- name,
272
- ...(CATALOG.tools[name] ?? { kind: 'custom' as const, ui: true }),
273
- })),
274
- inputs,
275
- slots: slots ?? {},
276
- outputs,
277
- image: primaryImageSpec(profile),
278
- };
279
- }
280
-
281
- function pickSystemRole(profile: Profile, requested?: string): string {
282
- const { identity } = profile;
283
- const { handle, systemByRole } = identity;
284
- if (requested && systemByRole && Object.hasOwn(systemByRole, requested)) {
285
- return requested;
286
- }
287
- return handle;
288
- }
289
-
290
- export { assertToolAllowed, pickSystemRole, projectProfile, resolveTurn };
@@ -1,29 +0,0 @@
1
- /**
2
- * Runtime structured-output schema registry.
3
- *
4
- * Host apps register schemas by id, then reference those ids from profile output
5
- * declarations.
6
- *
7
- * @module
8
- */
9
-
10
- import { TheorumError } from '../../guardrails/error.ts';
11
- import type { StructuredSpec } from '../types.ts';
12
-
13
- const schemas = new Map<string, StructuredSpec>();
14
-
15
- /** Register a host-owned structured output schema. */
16
- function registerStructured(id: string, spec: StructuredSpec): void {
17
- schemas.set(id, spec);
18
- }
19
-
20
- /** Fetch a registered structured output schema or throw a `TheorumError`. */
21
- function getStructured(id: string): StructuredSpec {
22
- const spec = schemas.get(id);
23
- if (!spec) {
24
- throw new TheorumError(`Unknown structured schema '${id}'`);
25
- }
26
- return spec;
27
- }
28
-
29
- export { getStructured, registerStructured };
@@ -1,45 +0,0 @@
1
- /**
2
- * Generic built-in custom tool executor.
3
- *
4
- * Static custom tools are intentionally minimal. Application-specific tools
5
- * should be supplied as dynamic declarations with host-owned handlers.
6
- *
7
- * @module
8
- */
9
-
10
- import type { CustomToolId, Profile, ToolEnvelope } from '../types.ts';
11
- import { getTool } from './catalog.ts';
12
- import { assertToolAllowed } from './resolve.ts';
13
-
14
- function executeAskUser(args: Record<string, unknown>): ToolEnvelope {
15
- const { kind, prompt } = args;
16
- if (kind !== 'confirm' && kind !== 'choice' && kind !== 'text') {
17
- return { status: 'error', finding: 'askUser.kind must be confirm, choice, or text' };
18
- }
19
- if (typeof prompt !== 'string' || !prompt.trim()) {
20
- return { status: 'error', finding: 'askUser.prompt is required' };
21
- }
22
- return {
23
- status: 'pause',
24
- finding: prompt,
25
- data: { ...args, schema: getTool('askUser')?.schema },
26
- };
27
- }
28
-
29
- /** Execute a static tool after enforcing the profile allowlist. */
30
- function executeTool(
31
- profile: Profile,
32
- name: CustomToolId,
33
- args: Record<string, unknown>,
34
- ): ToolEnvelope {
35
- assertToolAllowed(profile, name);
36
- if (name === 'askUser') {
37
- return executeAskUser(args);
38
- }
39
- return {
40
- status: 'error',
41
- finding: `Tool '${name}' has no kernel executor; pass a dynamic tool handler instead.`,
42
- };
43
- }
44
-
45
- export { executeTool };