ai-capability-framework 1.0.3 → 1.1.0

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 (246) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +38 -30
  3. package/ROADMAP.md +14 -0
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +32 -1
  6. package/dist/discovery/bindings.d.ts +7 -0
  7. package/dist/discovery/bindings.d.ts.map +1 -0
  8. package/dist/discovery/bindings.js +24 -0
  9. package/dist/discovery/budget.d.ts +17 -0
  10. package/dist/discovery/budget.d.ts.map +1 -0
  11. package/dist/discovery/budget.js +77 -0
  12. package/dist/discovery/configuration.d.ts +10 -0
  13. package/dist/discovery/configuration.d.ts.map +1 -0
  14. package/dist/discovery/configuration.js +63 -0
  15. package/dist/discovery/corpus.d.ts +8 -0
  16. package/dist/discovery/corpus.d.ts.map +1 -0
  17. package/dist/discovery/corpus.js +64 -0
  18. package/dist/discovery/diagnostics.d.ts +15 -0
  19. package/dist/discovery/diagnostics.d.ts.map +1 -0
  20. package/dist/discovery/diagnostics.js +11 -0
  21. package/dist/discovery/discoverer.d.ts +23 -0
  22. package/dist/discovery/discoverer.d.ts.map +1 -0
  23. package/dist/discovery/discoverer.js +261 -0
  24. package/dist/discovery/embedding-configuration.d.ts +12 -0
  25. package/dist/discovery/embedding-configuration.d.ts.map +1 -0
  26. package/dist/discovery/embedding-configuration.js +81 -0
  27. package/dist/discovery/embedding-types.d.ts +75 -0
  28. package/dist/discovery/embedding-types.d.ts.map +1 -0
  29. package/dist/discovery/embedding-types.js +1 -0
  30. package/dist/discovery/embeddings.d.ts +38 -0
  31. package/dist/discovery/embeddings.d.ts.map +1 -0
  32. package/dist/discovery/embeddings.js +71 -0
  33. package/dist/discovery/evaluation-validation.d.ts +8 -0
  34. package/dist/discovery/evaluation-validation.d.ts.map +1 -0
  35. package/dist/discovery/evaluation-validation.js +19 -0
  36. package/dist/discovery/evaluation.d.ts +84 -0
  37. package/dist/discovery/evaluation.d.ts.map +1 -0
  38. package/dist/discovery/evaluation.js +310 -0
  39. package/dist/discovery/export.d.ts +14 -0
  40. package/dist/discovery/export.d.ts.map +1 -0
  41. package/dist/discovery/export.js +81 -0
  42. package/dist/discovery/facade.d.ts +82 -0
  43. package/dist/discovery/facade.d.ts.map +1 -0
  44. package/dist/discovery/facade.js +266 -0
  45. package/dist/discovery/fingerprint.d.ts +71 -0
  46. package/dist/discovery/fingerprint.d.ts.map +1 -0
  47. package/dist/discovery/fingerprint.js +67 -0
  48. package/dist/discovery/index-builder.d.ts +3 -0
  49. package/dist/discovery/index-builder.d.ts.map +1 -0
  50. package/dist/discovery/index-builder.js +129 -0
  51. package/dist/discovery/index-validation.d.ts +12 -0
  52. package/dist/discovery/index-validation.d.ts.map +1 -0
  53. package/dist/discovery/index-validation.js +117 -0
  54. package/dist/discovery/index.d.ts +32 -0
  55. package/dist/discovery/index.d.ts.map +1 -0
  56. package/dist/discovery/index.js +18 -0
  57. package/dist/discovery/json-snapshot.d.ts +3 -0
  58. package/dist/discovery/json-snapshot.d.ts.map +1 -0
  59. package/dist/discovery/json-snapshot.js +11 -0
  60. package/dist/discovery/lexical.d.ts +12 -0
  61. package/dist/discovery/lexical.d.ts.map +1 -0
  62. package/dist/discovery/lexical.js +26 -0
  63. package/dist/discovery/metadata.d.ts +4 -0
  64. package/dist/discovery/metadata.d.ts.map +1 -0
  65. package/dist/discovery/metadata.js +33 -0
  66. package/dist/discovery/ranking.d.ts +7 -0
  67. package/dist/discovery/ranking.d.ts.map +1 -0
  68. package/dist/discovery/ranking.js +68 -0
  69. package/dist/discovery/replay.d.ts +50 -0
  70. package/dist/discovery/replay.d.ts.map +1 -0
  71. package/dist/discovery/replay.js +175 -0
  72. package/dist/discovery/retrieval-policy.d.ts +5 -0
  73. package/dist/discovery/retrieval-policy.d.ts.map +1 -0
  74. package/dist/discovery/retrieval-policy.js +10 -0
  75. package/dist/discovery/router.d.ts +39 -0
  76. package/dist/discovery/router.d.ts.map +1 -0
  77. package/dist/discovery/router.js +98 -0
  78. package/dist/discovery/selection-attempt.d.ts +20 -0
  79. package/dist/discovery/selection-attempt.d.ts.map +1 -0
  80. package/dist/discovery/selection-attempt.js +39 -0
  81. package/dist/discovery/selection-cards.d.ts +12 -0
  82. package/dist/discovery/selection-cards.d.ts.map +1 -0
  83. package/dist/discovery/selection-cards.js +79 -0
  84. package/dist/discovery/selection-configuration.d.ts +18 -0
  85. package/dist/discovery/selection-configuration.d.ts.map +1 -0
  86. package/dist/discovery/selection-configuration.js +71 -0
  87. package/dist/discovery/selection-response.d.ts +13 -0
  88. package/dist/discovery/selection-response.d.ts.map +1 -0
  89. package/dist/discovery/selection-response.js +47 -0
  90. package/dist/discovery/selection-types.d.ts +18 -0
  91. package/dist/discovery/selection-types.d.ts.map +1 -0
  92. package/dist/discovery/selection-types.js +1 -0
  93. package/dist/discovery/selection.d.ts +6 -0
  94. package/dist/discovery/selection.d.ts.map +1 -0
  95. package/dist/discovery/selection.js +145 -0
  96. package/dist/discovery/types.d.ts +291 -0
  97. package/dist/discovery/types.d.ts.map +1 -0
  98. package/dist/discovery/types.js +1 -0
  99. package/dist/discovery/usage.d.ts +2 -0
  100. package/dist/discovery/usage.d.ts.map +1 -0
  101. package/dist/discovery/usage.js +1 -0
  102. package/dist/discovery/vectors.d.ts +5 -0
  103. package/dist/discovery/vectors.d.ts.map +1 -0
  104. package/dist/discovery/vectors.js +43 -0
  105. package/dist/discovery/versions.d.ts +37 -0
  106. package/dist/discovery/versions.d.ts.map +1 -0
  107. package/dist/discovery/versions.js +36 -0
  108. package/dist/evals-live/live-eval-runner.d.ts +1 -0
  109. package/dist/evals-live/live-eval-runner.d.ts.map +1 -1
  110. package/dist/evals-live/live-eval-runner.js +12 -1
  111. package/dist/evals-live/types.d.ts +3 -0
  112. package/dist/evals-live/types.d.ts.map +1 -1
  113. package/dist/generated/manifest-types.d.ts +3655 -0
  114. package/dist/generated/manifest-types.d.ts.map +1 -1
  115. package/dist/loader.d.ts.map +1 -1
  116. package/dist/loader.js +8 -0
  117. package/dist/mcp-server/server.d.ts.map +1 -1
  118. package/dist/mcp-server/server.js +11 -2
  119. package/dist/mcp-server/types.d.ts +4 -0
  120. package/dist/mcp-server/types.d.ts.map +1 -1
  121. package/dist/observability/redaction.d.ts.map +1 -1
  122. package/dist/observability/redaction.js +6 -2
  123. package/dist/observability/types.d.ts +1 -1
  124. package/dist/observability/types.d.ts.map +1 -1
  125. package/dist/openai/index.d.ts +2 -0
  126. package/dist/openai/index.d.ts.map +1 -1
  127. package/dist/openai/index.js +1 -0
  128. package/dist/openai/responses-runner.d.ts +1 -1
  129. package/dist/openai/responses-runner.d.ts.map +1 -1
  130. package/dist/openai/responses-runner.js +134 -7
  131. package/dist/openai/selection-client.d.ts +28 -0
  132. package/dist/openai/selection-client.d.ts.map +1 -0
  133. package/dist/openai/selection-client.js +95 -0
  134. package/dist/openai/tool-loop.js +1 -1
  135. package/dist/openai/types.d.ts +19 -2
  136. package/dist/openai/types.d.ts.map +1 -1
  137. package/dist/replay/discovery-snapshot.d.ts +10 -0
  138. package/dist/replay/discovery-snapshot.d.ts.map +1 -0
  139. package/dist/replay/discovery-snapshot.js +17 -0
  140. package/dist/replay/recorder.d.ts.map +1 -1
  141. package/dist/replay/recorder.js +4 -0
  142. package/dist/replay/redaction.js +5 -1
  143. package/dist/replay/replayer.d.ts.map +1 -1
  144. package/dist/replay/replayer.js +14 -1
  145. package/dist/replay/types.d.ts +3 -0
  146. package/dist/replay/types.d.ts.map +1 -1
  147. package/dist/replay/validation.d.ts.map +1 -1
  148. package/dist/replay/validation.js +6 -0
  149. package/dist/runtime/bounded-json.d.ts +4 -0
  150. package/dist/runtime/bounded-json.d.ts.map +1 -0
  151. package/dist/runtime/bounded-json.js +74 -0
  152. package/dist/runtime/eligibility.d.ts +4 -0
  153. package/dist/runtime/eligibility.d.ts.map +1 -0
  154. package/dist/runtime/eligibility.js +128 -0
  155. package/dist/runtime/index.d.ts +5 -1
  156. package/dist/runtime/index.d.ts.map +1 -1
  157. package/dist/runtime/index.js +2 -0
  158. package/dist/runtime/provider-attempt.d.ts +11 -0
  159. package/dist/runtime/provider-attempt.d.ts.map +1 -0
  160. package/dist/runtime/provider-attempt.js +221 -0
  161. package/dist/runtime/provider-run.d.ts +10 -0
  162. package/dist/runtime/provider-run.d.ts.map +1 -0
  163. package/dist/runtime/provider-run.js +123 -0
  164. package/dist/runtime/provider-stop.d.ts +9 -0
  165. package/dist/runtime/provider-stop.d.ts.map +1 -0
  166. package/dist/runtime/provider-stop.js +28 -0
  167. package/dist/runtime/provider-types.d.ts +189 -0
  168. package/dist/runtime/provider-types.d.ts.map +1 -0
  169. package/dist/runtime/provider-types.js +1 -0
  170. package/dist/runtime/provider-usage.d.ts +9 -0
  171. package/dist/runtime/provider-usage.d.ts.map +1 -0
  172. package/dist/runtime/provider-usage.js +69 -0
  173. package/dist/runtime/router.d.ts.map +1 -1
  174. package/dist/runtime/router.js +3 -118
  175. package/dist/runtime/types.d.ts +9 -0
  176. package/dist/runtime/types.d.ts.map +1 -1
  177. package/dist/types.d.ts +1 -1
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/validator.d.ts +3 -0
  180. package/dist/validator.d.ts.map +1 -1
  181. package/dist/validator.js +32 -0
  182. package/docs/api/public-api-policy.md +10 -0
  183. package/docs/api/stable-workflow.md +58 -0
  184. package/docs/api.md +7 -0
  185. package/docs/capability-manifests.md +24 -0
  186. package/docs/development.md +22 -0
  187. package/docs/discovery.md +186 -0
  188. package/docs/evals/discovery-live.md +199 -0
  189. package/docs/evals/discovery-qualification.md +158 -0
  190. package/docs/evals/overview.md +9 -0
  191. package/docs/getting-started/installation.md +11 -12
  192. package/docs/getting-started/openai-quickstart.md +16 -5
  193. package/docs/getting-started/provider-neutral-quickstart.md +247 -88
  194. package/docs/getting-started/quickstart.md +8 -30
  195. package/docs/index.md +10 -0
  196. package/docs/release.md +29 -5
  197. package/docs/runtime.md +27 -0
  198. package/docs/start-here.md +23 -134
  199. package/examples/12-capability-discovery-selection/README.md +346 -0
  200. package/examples/12-capability-discovery-selection/customer-cases.mjs +52 -0
  201. package/examples/12-capability-discovery-selection/customer-harness.mjs +91 -0
  202. package/examples/12-capability-discovery-selection/customer-request-example.mjs +320 -0
  203. package/examples/12-capability-discovery-selection/discovery-example.mjs +175 -0
  204. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.suite.json +7887 -0
  205. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v2.suite.json +8167 -0
  206. package/examples/12-capability-discovery-selection/discovery-fixtures/three-domains.v3.suite.json +8342 -0
  207. package/examples/12-capability-discovery-selection/evaluation/application.mjs +305 -0
  208. package/examples/12-capability-discovery-selection/evaluation/campaign.mjs +248 -0
  209. package/examples/12-capability-discovery-selection/evaluation/clients.mjs +433 -0
  210. package/examples/12-capability-discovery-selection/evaluation/continuation.mjs +208 -0
  211. package/examples/12-capability-discovery-selection/evaluation/durable-budget.mjs +420 -0
  212. package/examples/12-capability-discovery-selection/evaluation/freeze.mjs +9 -0
  213. package/examples/12-capability-discovery-selection/evaluation/harness.mjs +618 -0
  214. package/examples/12-capability-discovery-selection/evaluation/mock-host.mjs +260 -0
  215. package/examples/12-capability-discovery-selection/evaluation/preflight.mjs +115 -0
  216. package/examples/12-capability-discovery-selection/evaluation/qualification-workflows.mjs +87 -0
  217. package/examples/12-capability-discovery-selection/evaluation/regrade.mjs +281 -0
  218. package/examples/12-capability-discovery-selection/evaluation/report.mjs +517 -0
  219. package/examples/12-capability-discovery-selection/evaluation/runner.mjs +613 -0
  220. package/examples/12-capability-discovery-selection/evaluation/saved-campaign.mjs +385 -0
  221. package/examples/12-capability-discovery-selection/evaluation/wording.mjs +115 -0
  222. package/examples/12-capability-discovery-selection/evaluation/workflow-application.mjs +378 -0
  223. package/examples/12-capability-discovery-selection/evaluation/workflow-cases.mjs +90 -0
  224. package/examples/12-capability-discovery-selection/evaluation-example.mjs +154 -0
  225. package/examples/12-capability-discovery-selection/hybrid-example.mjs +174 -0
  226. package/examples/12-capability-discovery-selection/mock-embeddings.mjs +101 -0
  227. package/examples/12-capability-discovery-selection/mock-selection.mjs +78 -0
  228. package/examples/12-capability-discovery-selection/pipeline-example.mjs +496 -0
  229. package/examples/12-capability-discovery-selection/retrieval-cases.mjs +31 -0
  230. package/examples/12-capability-discovery-selection/run-campaign-mock.mjs +40 -0
  231. package/examples/12-capability-discovery-selection/run-customer-mock.mjs +15 -0
  232. package/examples/12-capability-discovery-selection/run-evaluation-live.mjs +10 -0
  233. package/examples/12-capability-discovery-selection/run-evaluation-mock.mjs +3 -0
  234. package/examples/12-capability-discovery-selection/run-evaluation-regrade.mjs +71 -0
  235. package/examples/12-capability-discovery-selection/run-hybrid-mock.mjs +3 -0
  236. package/examples/12-capability-discovery-selection/run-mock.mjs +3 -0
  237. package/examples/12-capability-discovery-selection/run-pipeline-mock.mjs +2 -0
  238. package/examples/12-capability-discovery-selection/run-selector-mock.mjs +3 -0
  239. package/examples/12-capability-discovery-selection/selection-example.mjs +88 -0
  240. package/package.json +17 -4
  241. package/schemas/discovery/embedding-index.schema.json +71 -0
  242. package/schemas/discovery/eval-observations.schema.json +409 -0
  243. package/schemas/discovery/eval-suite.schema.json +375 -0
  244. package/schemas/discovery/metadata.schema.json +30 -0
  245. package/schemas/discovery/selection-response.schema.json +47 -0
  246. package/schemas/replay/discovery-snapshot.schema.json +335 -0
@@ -1,3 +1,8 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { assertProviderRunScope } from "../runtime/provider-run.js";
3
+ import { aggregateProviderUsage, freezeProviderValue } from "../runtime/provider-usage.js";
4
+ import { stopReason } from "../runtime/provider-stop.js";
5
+ import { enforceOpenAIInputTokens, normalizeOpenAIUsage } from "./selection-client.js";
1
6
  import { parseOpenAIResponsesToolCall } from "../index.js";
2
7
  import { createToolEnvelope, formatCapabilitySliceForModel } from "../runtime/index.js";
3
8
  import { controlDecisionToPolicyReasons } from "../controls/index.js";
@@ -7,8 +12,35 @@ import { buildOpenAIFunctionCallOutput, extractOpenAIResponsesFunctionCalls } fr
7
12
  import { buildRuntimeOpenAIToolset, defaultOpenAISafetyInstructions, extractOpenAIResponseText, formatOpenAIInitialInput } from "./tool-loop.js";
8
13
  const defaultMaxTurns = 6;
9
14
  const defaultMaxToolCalls = 10;
10
- export async function runOpenAIResponses(request) {
15
+ export async function runOpenAIResponses(input) {
16
+ const request = Object.freeze({ ...input });
17
+ const sourceExecution = request.providerExecution;
18
+ const providerExecution = sourceExecution ? Object.freeze({ ...sourceExecution, configuration: Object.freeze({ ...sourceExecution.configuration }) }) : undefined;
19
+ const clientCreate = request.client.responses.create;
20
+ const executionCurrent = () => !sourceExecution || !!providerExecution
21
+ && isDeepStrictEqual(sourceExecution.configuration, providerExecution.configuration)
22
+ && sourceExecution.mock === providerExecution.mock && sourceExecution.maxInputTokens === providerExecution.maxInputTokens
23
+ && sourceExecution.maxOutputTokens === providerExecution.maxOutputTokens
24
+ && sourceExecution.inputTokenPreflight === providerExecution.inputTokenPreflight
25
+ && sourceExecution.maxEstimatedCostPerCall === providerExecution.maxEstimatedCostPerCall
26
+ && sourceExecution.estimateCost === providerExecution.estimateCost;
11
27
  const runId = request.runtimeContext.runId;
28
+ const providerRun = request.providerRun ?? request.router.providerRun;
29
+ if (providerRun) {
30
+ assertProviderRunScope(providerRun, runId);
31
+ if (request.providerRun && request.router.providerRun && request.providerRun !== request.router.providerRun)
32
+ throw new Error("The router and runner provider scopes conflict.");
33
+ if (!request.providerExecution || request.providerExecution.configuration.model !== request.model
34
+ || typeof request.providerExecution.inputTokenPreflight !== "function" || typeof request.providerExecution.mock !== "boolean"
35
+ || !Number.isSafeInteger(request.providerExecution.maxInputTokens) || request.providerExecution.maxInputTokens < 1
36
+ || !Number.isSafeInteger(request.providerExecution.maxOutputTokens) || request.providerExecution.maxOutputTokens < 1
37
+ || providerRun.budget.policy.maxEstimatedCostPerRun !== undefined && request.providerExecution.maxEstimatedCostPerCall === undefined)
38
+ throw new Error("Managed model turns require explicit token limits, provenance and a token preflight.");
39
+ }
40
+ const runtimeSignals = [request.signal, providerRun?.signal].filter((item) => !!item);
41
+ const runtimeSignal = runtimeSignals.length ? AbortSignal.any(runtimeSignals) : undefined;
42
+ const managedStages = [];
43
+ const history = [];
12
44
  const requestId = request.runtimeContext.requestId;
13
45
  const traceEvents = [];
14
46
  const toolCalls = [];
@@ -41,6 +73,13 @@ export async function runOpenAIResponses(request) {
41
73
  });
42
74
  };
43
75
  const finish = async (status, input = {}) => {
76
+ if (providerRun) {
77
+ const totals = providerRun.snapshot().usage.totals;
78
+ providerRun.record("usage.summary", requestId, { outcome: status, providerAttempts: totals.providerAttempts,
79
+ completedResponses: totals.completedResponses, inputTokens: totals.inputTokens, outputTokens: totals.outputTokens,
80
+ totalTokens: totals.totalTokens, cachedInputTokens: totals.cachedInputTokens, reasoningTokens: totals.reasoningTokens,
81
+ estimatedCost: totals.estimatedCost, elapsedMs: totals.elapsedMs });
82
+ }
44
83
  await emit("runtime.end", { status });
45
84
  return {
46
85
  errors: input.errors ?? [],
@@ -52,7 +91,7 @@ export async function runOpenAIResponses(request) {
52
91
  toolCalls,
53
92
  toolResults,
54
93
  traceEvents,
55
- usage
94
+ usage, ...(providerRun ? { providerUsage: aggregateProviderUsage(managedStages, Date.now() - startedAt) } : {})
56
95
  };
57
96
  };
58
97
  await emit("runtime.start", {
@@ -104,18 +143,23 @@ export async function runOpenAIResponses(request) {
104
143
  await emit("capability.route.start", {
105
144
  capabilityCount: request.registry.capabilities.length
106
145
  });
107
- selectedCapabilities = await request.router.route({
146
+ const routeRequest = {
108
147
  builtContext,
109
148
  controls: request.controls,
110
149
  includeRestricted: false,
111
150
  registry: request.registry,
112
- userInput: request.userInput
113
- });
151
+ userInput: request.userInput, providerRun, signal: runtimeSignal,
152
+ ...(Number.isFinite(Math.min(request.deadlineAt ?? Infinity, providerRun?.deadlineAt ?? Infinity))
153
+ ? { deadlineAt: Math.min(request.deadlineAt ?? Infinity, providerRun?.deadlineAt ?? Infinity) } : {})
154
+ };
155
+ selectedCapabilities = await request.router.route(routeRequest);
156
+ if (request.router.revalidate)
157
+ selectedCapabilities = await request.router.revalidate(routeRequest, selectedCapabilities);
114
158
  await emit("capability.route.end", {
115
159
  capabilityIds: selectedCapabilities.items.map((item) => item.capabilityId),
116
160
  excludedCount: selectedCapabilities.excluded.length
117
161
  });
118
- const toolset = buildRuntimeOpenAIToolset({
162
+ let toolset = buildRuntimeOpenAIToolset({
119
163
  builtContext,
120
164
  registry: request.registry,
121
165
  runtimeContext: request.runtimeContext,
@@ -134,7 +178,34 @@ export async function runOpenAIResponses(request) {
134
178
  capabilitySliceText,
135
179
  userInput: request.userInput
136
180
  });
181
+ const revalidate = async () => {
182
+ const stopped = stopReason({ signal: runtimeSignal,
183
+ deadlineAt: Math.min(request.deadlineAt ?? Infinity, providerRun?.deadlineAt ?? Infinity) });
184
+ if (stopped)
185
+ return stopped;
186
+ if (request.router.revalidate) {
187
+ const previous = selectedCapabilities;
188
+ selectedCapabilities = await request.router.revalidate(routeRequest, selectedCapabilities);
189
+ if (previous.items.length && !selectedCapabilities.items.length || selectedCapabilities.warnings.some(warning => ["stale_binding", "discovery_unavailable", "discovery_cancelled", "selection_unavailable", "selection_invalid_output", "selection_cancelled"].includes(warning.code)))
190
+ return "stale_binding";
191
+ toolset = buildRuntimeOpenAIToolset({ builtContext, registry: request.registry, runtimeContext: request.runtimeContext,
192
+ runtimeSlice: selectedCapabilities });
193
+ }
194
+ return undefined;
195
+ };
196
+ const initialStop = stopReason({ signal: runtimeSignal,
197
+ deadlineAt: Math.min(request.deadlineAt ?? Infinity, providerRun?.deadlineAt ?? Infinity) });
198
+ if (initialStop)
199
+ return finish("cancelled", { errors: [{ code: initialStop, message: "The invocation was cancelled or its deadline elapsed." }] });
200
+ if (!selectedCapabilities.items.length && selectedCapabilities.warnings.some(warning => ["selection_abstained", "selection_not_submitted"].includes(warning.code))
201
+ && !selectedCapabilities.warnings.some(warning => ["discovery_unavailable", "discovery_cancelled"].includes(warning.code)))
202
+ return finish("completed");
137
203
  for (let turn = 0; turn < maxTurns; turn += 1) {
204
+ const invalid = await revalidate();
205
+ if (invalid)
206
+ return finish(invalid === "cancelled" || invalid === "deadline_exceeded" ? "cancelled" : "failed", {
207
+ errors: [{ code: invalid, message: "The task binding or invocation bounds no longer permit this model turn." }]
208
+ });
138
209
  const providerControl = request.controls?.evaluate({
139
210
  model: request.model,
140
211
  operation: "provider_call",
@@ -170,7 +241,53 @@ export async function runOpenAIResponses(request) {
170
241
  });
171
242
  let response;
172
243
  try {
173
- response = await request.client.responses.create(responseRequest);
244
+ if (providerRun) {
245
+ const execution = providerExecution;
246
+ const configuration = freezeProviderValue({ ...execution.configuration });
247
+ const prepared = freezeProviderValue({ ...responseRequest, max_output_tokens: execution.maxOutputTokens, truncation: "disabled" });
248
+ const modelIdentity = JSON.stringify(execution.configuration), mock = execution.mock;
249
+ const result = await providerRun.attempt({ requestId, stage: "model_tool_loop", configuration, mock,
250
+ signal: request.signal, deadlineAt: request.deadlineAt, maxInputTokens: execution.maxInputTokens,
251
+ maxOutputTokens: execution.maxOutputTokens, maxEstimatedCostPerCall: execution.maxEstimatedCostPerCall,
252
+ estimateCost: execution.estimateCost, controls: request.controls, runtimeContext: request.runtimeContext,
253
+ guard: () => !executionCurrent() || JSON.stringify(execution.configuration) !== modelIdentity || execution.mock !== mock ? "stale_binding" : undefined,
254
+ invoke: async (context) => {
255
+ await enforceOpenAIInputTokens({ request: prepared, history: Object.freeze([...history]), configuration, maxInputTokens: execution.maxInputTokens,
256
+ signal: context.signal, deadlineAt: context.deadlineAt }, execution.inputTokenPreflight);
257
+ const changed = await revalidate();
258
+ if (changed)
259
+ throw Object.assign(new Error("The task binding changed before transport."), { providerAttempts: 0, usage: {} });
260
+ context.beforeProviderCall();
261
+ let completed = false;
262
+ try {
263
+ const value = await clientCreate.call(request.client.responses, prepared, { signal: context.signal,
264
+ timeout: Math.max(1, context.deadlineAt - Date.now()), maxRetries: 0 });
265
+ completed = true;
266
+ return { value, usage: normalizeOpenAIUsage(value?.usage), providerAttempts: 1 };
267
+ }
268
+ catch (error) {
269
+ const failed = error;
270
+ throw Object.assign(new Error("The managed Responses transport was unavailable."), { usage: normalizeOpenAIUsage(failed?.usage),
271
+ providerAttempts: Number.isSafeInteger(failed?.providerAttempts) && failed.providerAttempts >= 0 ? failed.providerAttempts : 1,
272
+ completedResponses: completed ? 1 : Number.isSafeInteger(failed?.completedResponses) && failed.completedResponses >= 0 ? failed.completedResponses : 0 });
273
+ }
274
+ },
275
+ validate: envelope => {
276
+ const value = envelope.value;
277
+ return !value || typeof value !== "object" || value.status !== undefined && value.status !== "completed"
278
+ || value.output !== undefined && !Array.isArray(value.output) || value.output_text !== undefined && typeof value.output_text !== "string"
279
+ ? { code: "provider_unavailable" } : { value };
280
+ }
281
+ });
282
+ managedStages.push(...result.usage.stages);
283
+ if (result.code)
284
+ return finish(result.code === "budget_denied" ? "budget_exceeded"
285
+ : result.code === "control_denied" ? "control_denied" : result.code === "cancelled" || result.code === "deadline_exceeded" ? "cancelled" : "provider_error", { errors: [{ code: result.code, message: "The managed model turn was unavailable or denied." }] });
286
+ response = result.value;
287
+ history.push({ request: prepared, response });
288
+ }
289
+ else
290
+ response = await request.client.responses.create(responseRequest);
174
291
  }
175
292
  catch (error) {
176
293
  const safeError = safeOpenAIError(error);
@@ -186,6 +303,11 @@ export async function runOpenAIResponses(request) {
186
303
  responseId,
187
304
  turn
188
305
  });
306
+ const changedAfterResponse = await revalidate();
307
+ if (changedAfterResponse)
308
+ return finish(changedAfterResponse === "cancelled" || changedAfterResponse === "deadline_exceeded" ? "cancelled" : "failed", {
309
+ errors: [{ code: changedAfterResponse, message: "The invocation or task binding changed before the response could be used." }]
310
+ });
189
311
  const calls = extractOpenAIResponsesFunctionCalls(response);
190
312
  if (calls.length === 0) {
191
313
  return finish("completed", {
@@ -255,6 +377,11 @@ export async function runOpenAIResponses(request) {
255
377
  callId: call.call_id,
256
378
  toolName: call.name
257
379
  });
380
+ const invalid = await revalidate();
381
+ if (invalid)
382
+ return finish(invalid === "cancelled" || invalid === "deadline_exceeded" ? "cancelled" : "failed", {
383
+ errors: [{ code: invalid, message: "The task binding changed before tool execution." }]
384
+ });
258
385
  const envelope = await executeToolCall({
259
386
  builtContext,
260
387
  call,
@@ -0,0 +1,28 @@
1
+ import type { SelectionModelClient } from "../discovery/types.js";
2
+ import type { ModelUsage, ProviderModelConfiguration } from "../runtime/provider-types.js";
3
+ import type { AicfOpenAIResponseLike, AicfOpenAIResponsesClient } from "./types.js";
4
+ export declare const OPENAI_SELECTION_TRANSPORT_VERSION = "responses-selection.v1";
5
+ export interface OpenAIInputPreflightInput {
6
+ request: Readonly<Record<string, unknown>>;
7
+ /** Prior requests/responses needed to account for continuation context, never logged. */
8
+ history: readonly {
9
+ request: Readonly<Record<string, unknown>>;
10
+ response: AicfOpenAIResponseLike;
11
+ }[];
12
+ configuration: Readonly<ProviderModelConfiguration>;
13
+ maxInputTokens: number;
14
+ signal?: AbortSignal;
15
+ deadlineAt: number;
16
+ }
17
+ export type OpenAIInputTokenPreflight = (input: OpenAIInputPreflightInput) => number | Promise<number>;
18
+ export interface CreateOpenAISelectionClientOptions {
19
+ client: AicfOpenAIResponsesClient;
20
+ configuration: ProviderModelConfiguration;
21
+ mock: boolean;
22
+ inputTokenPreflight: OpenAIInputTokenPreflight;
23
+ }
24
+ /** Credentials and model-specific token counting remain with the caller's configured client. */
25
+ export declare function createOpenAISelectionClient(options: CreateOpenAISelectionClientOptions): SelectionModelClient;
26
+ export declare function enforceOpenAIInputTokens(input: OpenAIInputPreflightInput, preflight: OpenAIInputTokenPreflight): Promise<void>;
27
+ export declare function normalizeOpenAIUsage(raw: unknown): ModelUsage;
28
+ //# sourceMappingURL=selection-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-client.d.ts","sourceRoot":"","sources":["../../src/openai/selection-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE3F,OAAO,KAAK,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAGpF,eAAO,MAAM,kCAAkC,2BAA2B,CAAC;AAC3E,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3C,yFAAyF;IACzF,OAAO,EAAE,SAAS;QAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,sBAAsB,CAAA;KAAE,EAAE,CAAC;IACrG,aAAa,EAAE,QAAQ,CAAC,0BAA0B,CAAC,CAAC;IACpD,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,yBAAyB,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AACvG,MAAM,WAAW,kCAAkC;IACjD,MAAM,EAAE,yBAAyB,CAAC;IAClC,aAAa,EAAE,0BAA0B,CAAC;IAC1C,IAAI,EAAE,OAAO,CAAC;IACd,mBAAmB,EAAE,yBAAyB,CAAC;CAChD;AAED,gGAAgG;AAChG,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,kCAAkC,GAAG,oBAAoB,CA+B7G;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,yBAAyB,EAAE,SAAS,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKpI;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAK7D"}
@@ -0,0 +1,95 @@
1
+ import { freezeProviderValue, knownUsage, ownValue } from "../runtime/provider-usage.js";
2
+ import { extractOpenAIResponseText } from "./tool-loop.js";
3
+ export const OPENAI_SELECTION_TRANSPORT_VERSION = "responses-selection.v1";
4
+ /** Credentials and model-specific token counting remain with the caller's configured client. */
5
+ export function createOpenAISelectionClient(options) {
6
+ const configuration = freezeProviderValue({ ...options.configuration });
7
+ if (!options.client?.responses || typeof options.client.responses.create !== "function" || typeof options.mock !== "boolean"
8
+ || typeof options.inputTokenPreflight !== "function" || [configuration.provider, configuration.model, configuration.configurationId]
9
+ .some(value => typeof value !== "string" || !value.trim()))
10
+ throw new Error("A selection adapter requires an explicit client, model, provenance and token preflight.");
11
+ return Object.freeze({ configuration, mock: options.mock, transportVersion: OPENAI_SELECTION_TRANSPORT_VERSION,
12
+ async generateStructured(input) {
13
+ const request = freezeProviderValue({ model: configuration.model, input: input.messages.map(message => ({ ...message })),
14
+ text: { format: { type: "json_schema", name: "aicf_capability_selection_v1", strict: true, schema: projectSelectionSchema(input.outputSchema) } },
15
+ max_output_tokens: input.maxOutputTokens, truncation: "disabled", stream: false, store: false, tools: [] });
16
+ let attempted = false, completed = false, usage = {};
17
+ try {
18
+ await enforceOpenAIInputTokens({ request, history: [], configuration, maxInputTokens: input.maxInputTokens,
19
+ signal: input.signal, deadlineAt: input.deadlineAt }, options.inputTokenPreflight);
20
+ input.beforeProviderCall?.();
21
+ attempted = true;
22
+ const response = await options.client.responses.create(request, { signal: input.signal,
23
+ timeout: Math.max(1, input.deadlineAt - Date.now()), maxRetries: 0 });
24
+ completed = true;
25
+ usage = normalizeOpenAIUsage(response.usage);
26
+ if (!boundedResponse(response))
27
+ throw new Error();
28
+ const output = extractOpenAIResponseText(response);
29
+ if (response.status !== "completed" || !output.trim() || hasRefusal(response)
30
+ || usage.outputTokens !== undefined && usage.outputTokens > input.maxOutputTokens)
31
+ throw new Error();
32
+ return { output, usage, providerAttempts: 1, ...(typeof response.id === "string" ? { responseRef: response.id } : {}) };
33
+ }
34
+ catch (error) {
35
+ if (!completed)
36
+ usage = normalizeOpenAIUsage(ownValue(error, "usage"));
37
+ throw providerFailure(attempted ? 1 : 0, completed ? 1 : 0, usage);
38
+ }
39
+ }
40
+ });
41
+ }
42
+ export async function enforceOpenAIInputTokens(input, preflight) {
43
+ if (input.signal?.aborted || Date.now() >= input.deadlineAt)
44
+ throw providerFailure(0, 0, {});
45
+ const count = await preflight(input);
46
+ if (!Number.isSafeInteger(count) || count < 0 || count > input.maxInputTokens
47
+ || input.signal?.aborted || Date.now() >= input.deadlineAt)
48
+ throw providerFailure(0, 0, {});
49
+ }
50
+ export function normalizeOpenAIUsage(raw) {
51
+ if (!raw || typeof raw !== "object")
52
+ return {};
53
+ return { ...knownUsage(raw), ...knownUsage({ inputTokens: ownValue(raw, "input_tokens"), outputTokens: ownValue(raw, "output_tokens"),
54
+ totalTokens: ownValue(raw, "total_tokens"), cachedInputTokens: ownValue(ownValue(raw, "input_tokens_details"), "cached_tokens"),
55
+ reasoningTokens: ownValue(ownValue(raw, "output_tokens_details"), "reasoning_tokens") }) };
56
+ }
57
+ function providerFailure(providerAttempts, completedResponses, usage) {
58
+ return Object.assign(new Error("The configured Responses transport could not produce an acceptable response."), {
59
+ providerAttempts, completedResponses, usage, diagnostic: { code: "provider_unavailable", message: "The configured Responses transport was unavailable." }
60
+ });
61
+ }
62
+ function hasRefusal(response) {
63
+ return (response.output ?? []).some(item => !!item && typeof item === "object" && "content" in item
64
+ && Array.isArray(item.content) && item.content.some(content => content && typeof content === "object" && content.type === "refusal"));
65
+ }
66
+ /** Transport-only conversion: mutually exclusive select/abstain branches retain their meaning. */
67
+ function projectSelectionSchema(value) {
68
+ if (Array.isArray(value))
69
+ return value.map(projectSelectionSchema);
70
+ if (!value || typeof value !== "object")
71
+ return value;
72
+ return Object.fromEntries(Object.entries(value).filter(([key]) => !["$schema", "$id", "title"].includes(key))
73
+ .map(([key, child]) => key === "oneOf" ? ["anyOf", projectSelectionSchema(child)]
74
+ : key === "const" ? ["enum", [child]] : [key, projectSelectionSchema(child)]));
75
+ }
76
+ function boundedResponse(response) {
77
+ if (response.output_text !== undefined && (typeof response.output_text !== "string" || response.output_text.length > 128_000))
78
+ return false;
79
+ if (response.output !== undefined && (!Array.isArray(response.output) || response.output.length > 64))
80
+ return false;
81
+ let characters = 0;
82
+ for (const item of response.output ?? []) {
83
+ if (!item || typeof item !== "object" || !("content" in item))
84
+ continue;
85
+ if (!Array.isArray(item.content) || item.content.length > 64)
86
+ return false;
87
+ for (const content of item.content)
88
+ if (content && typeof content === "object" && typeof content.text === "string") {
89
+ characters += content.text.length;
90
+ if (characters > 128_000)
91
+ return false;
92
+ }
93
+ }
94
+ return true;
95
+ }
@@ -25,7 +25,7 @@ export function createOpenAIResponsesClientFromSdk(client) {
25
25
  }
26
26
  return {
27
27
  responses: {
28
- create: async (input) => responses.create.call(responses, input)
28
+ create: async (input, options) => responses.create.call(responses, input, options)
29
29
  }
30
30
  };
31
31
  }
@@ -2,7 +2,11 @@ import type { AicfCapabilityRouter, AicfBuiltContext, AicfContextBuilder, AicfRu
2
2
  import type { AicfRuntimeTraceEvent, AicfTraceContentCapture, AicfTraceSink } from "../observability/index.js";
3
3
  export interface AicfOpenAIResponsesClient {
4
4
  responses: {
5
- create(input: Record<string, unknown>): Promise<AicfOpenAIResponseLike>;
5
+ create(input: Record<string, unknown>, options?: {
6
+ signal?: AbortSignal;
7
+ timeout?: number;
8
+ maxRetries?: number;
9
+ }): Promise<AicfOpenAIResponseLike>;
6
10
  };
7
11
  }
8
12
  export interface AicfOpenAIResponseLike {
@@ -12,9 +16,21 @@ export interface AicfOpenAIResponseLike {
12
16
  usage?: Record<string, unknown>;
13
17
  [key: string]: unknown;
14
18
  }
15
- export type AicfOpenAIRunStatus = "completed" | "budget_exceeded" | "control_denied" | "tool_limit_exceeded" | "turn_limit_exceeded" | "provider_error" | "failed";
19
+ export type AicfOpenAIRunStatus = "completed" | "cancelled" | "budget_exceeded" | "control_denied" | "tool_limit_exceeded" | "turn_limit_exceeded" | "provider_error" | "failed";
16
20
  export type AicfOpenAIRuntimeEvent = AicfRuntimeTraceEvent;
17
21
  export interface AicfOpenAIRunRequest {
22
+ providerRun?: import("../runtime/provider-types.js").AicfProviderRun;
23
+ providerExecution?: {
24
+ configuration: import("../runtime/provider-types.js").ProviderModelConfiguration;
25
+ mock: boolean;
26
+ maxInputTokens: number;
27
+ maxOutputTokens: number;
28
+ inputTokenPreflight: import("./selection-client.js").OpenAIInputTokenPreflight;
29
+ maxEstimatedCostPerCall?: number;
30
+ estimateCost?: import("../runtime/provider-types.js").ProviderAttemptInput<unknown>["estimateCost"];
31
+ };
32
+ signal?: AbortSignal;
33
+ deadlineAt?: number;
18
34
  client: AicfOpenAIResponsesClient;
19
35
  contentCapture?: AicfTraceContentCapture;
20
36
  controls?: AicfRuntimeControls;
@@ -33,6 +49,7 @@ export interface AicfOpenAIRunRequest {
33
49
  userInput: AicfRuntimeUserInput;
34
50
  }
35
51
  export interface AicfOpenAIRunResult {
52
+ providerUsage?: import("../runtime/provider-types.js").ProviderUsage;
36
53
  errors: Array<{
37
54
  code: string;
38
55
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/openai/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/openai/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CapabilityDiscoverySnapshot } from "../generated/manifest-types.js";
2
+ export declare const DISCOVERY_SNAPSHOT_MAX_BYTES: number;
3
+ /** Shape validation only. Discovery owns source/eligibility checks and ranking replay. */
4
+ export declare function validateDiscoverySnapshotStructure(value: unknown): {
5
+ valid: true;
6
+ snapshot: CapabilityDiscoverySnapshot;
7
+ } | {
8
+ valid: false;
9
+ };
10
+ //# sourceMappingURL=discovery-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-snapshot.d.ts","sourceRoot":"","sources":["../../src/replay/discovery-snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAElF,eAAO,MAAM,4BAA4B,QAAc,CAAC;AAKxD,0FAA0F;AAC1F,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,OAAO,GAC/D;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,2BAA2B,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAM1E"}
@@ -0,0 +1,17 @@
1
+ import { readFileSync } from "node:fs";
2
+ import Ajv2020 from "ajv/dist/2020.js";
3
+ import { boundedJsonSnapshot, deepFreeze } from "../runtime/bounded-json.js";
4
+ export const DISCOVERY_SNAPSHOT_MAX_BYTES = 1024 * 1024;
5
+ const validate = new Ajv2020({ strict: true, allErrors: true }).compile(JSON.parse(readFileSync(new URL("../../schemas/replay/discovery-snapshot.schema.json", import.meta.url), "utf8")));
6
+ /** Shape validation only. Discovery owns source/eligibility checks and ranking replay. */
7
+ export function validateDiscoverySnapshotStructure(value) {
8
+ try {
9
+ if (typeof value === "string" && Buffer.byteLength(value) > DISCOVERY_SNAPSHOT_MAX_BYTES)
10
+ return { valid: false };
11
+ const snapshot = boundedJsonSnapshot(typeof value === "string" ? JSON.parse(value) : value, DISCOVERY_SNAPSHOT_MAX_BYTES);
12
+ return validate(snapshot) ? { valid: true, snapshot: deepFreeze(snapshot) } : { valid: false };
13
+ }
14
+ catch {
15
+ return { valid: false };
16
+ }
17
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,WAAW;CA6BrD"}
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/replay/recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,WAAW;CAgCrD"}
@@ -1,8 +1,12 @@
1
+ import { validateDiscoverySnapshotStructure } from "./discovery-snapshot.js";
1
2
  import { hashReplayValue } from "./hash.js";
2
3
  import { redactReplayTrace } from "./redaction.js";
3
4
  export class DefaultReplayRecorder {
4
5
  record(input) {
6
+ if (input.extensions?.discovery !== undefined && !validateDiscoverySnapshotStructure(input.extensions.discovery).valid)
7
+ throw new Error("The discovery replay snapshot is invalid or exceeds its serialized limit.");
5
8
  const trace = {
9
+ ...(input.extensions ? { extensions: structuredClone(input.extensions) } : {}),
6
10
  actions: input.actions ?? [],
7
11
  approvals: input.approvals,
8
12
  capabilitySlice: {
@@ -28,6 +28,10 @@ function redactValue(value, key = "") {
28
28
  return undefined;
29
29
  }
30
30
  if (typeof value === "string") {
31
+ if ((key.endsWith("Fingerprint") || key.endsWith("Hash") || key === "matchedAliasHashes") && /^sha256:[0-9a-f]{64}$/.test(value))
32
+ return value;
33
+ if (key === "tokenizerVersion" && value === "nfkc-lower-unicode-letter-number.v1")
34
+ return value;
31
35
  if (sensitiveKeyPattern.test(key)) {
32
36
  return "[REDACTED]";
33
37
  }
@@ -42,7 +46,7 @@ function redactValue(value, key = "") {
42
46
  if (childKey === "private_diagnostics") {
43
47
  continue;
44
48
  }
45
- result[childKey] = sensitiveKeyPattern.test(childKey) ? "[REDACTED]" : redactValue(childValue, childKey);
49
+ result[childKey] = sensitiveKeyPattern.test(childKey) && childKey !== "tokenizerVersion" ? "[REDACTED]" : redactValue(childValue, childKey);
46
50
  }
47
51
  return result;
48
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"replayer.d.ts","sourceRoot":"","sources":["../../src/replay/replayer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAGV,YAAY,EAEZ,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CA2BpG"}
1
+ {"version":3,"file":"replayer.d.ts","sourceRoot":"","sources":["../../src/replay/replayer.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAGV,YAAY,EAEZ,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB,wBAAsB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoCpG"}
@@ -16,12 +16,21 @@ export async function runReplay(trace, options) {
16
16
  return runProviderLiveReplay(trace, options);
17
17
  }
18
18
  if (options.mode === "deterministic_mock") {
19
- return result(trace.traceId, options.mode, [], deterministicMockSteps(trace));
19
+ const steps = deterministicMockSteps(trace);
20
+ if (trace.extensions?.discovery)
21
+ steps.push({ name: "discovery_ranking", status: "skipped", message: "Recorded snapshots do not reproduce discovery ranking." }, { name: "model_semantic_correctness", status: "skipped", message: "Recorded decisions do not establish model semantic correctness." });
22
+ return result(trace.traceId, options.mode, [], steps);
20
23
  }
21
24
  if (options.mode === "policy_only") {
22
25
  return result(trace.traceId, options.mode, [], policyOnlySteps(trace, options));
23
26
  }
24
27
  if (options.mode === "router_only") {
28
+ if (trace.extensions?.discovery) {
29
+ if (options.routerRunner)
30
+ return options.routerRunner(trace, options);
31
+ return result(trace.traceId, options.mode, [], [{ name: "discovery_replay_handler", status: "skipped",
32
+ message: "Discovery routing requires a supplied discovery replay handler; Core filtering cannot reproduce it." }], "refused");
33
+ }
25
34
  return result(trace.traceId, options.mode, [], routerOnlySteps(trace, options));
26
35
  }
27
36
  return result(trace.traceId, options.mode, [], toolValidationSteps(trace, options));
@@ -180,6 +189,10 @@ function toolValidationSteps(trace, options) {
180
189
  }];
181
190
  }
182
191
  async function runProviderLiveReplay(trace, options) {
192
+ if (trace.extensions?.discovery && (!options.providerRun || options.providerRun.runId === trace.runId))
193
+ return result(trace.traceId, "provider_live", [], [{
194
+ name: "discovery_live_run", status: "skipped", message: "Discovery live replay requires a separately supplied run and budget."
195
+ }], "refused");
183
196
  const enabled = options.allowProviderLive || process.env.AICF_ENABLE_LIVE_REPLAY === "1";
184
197
  if (!enabled || !options.providerRunner) {
185
198
  return result(trace.traceId, "provider_live", [{
@@ -93,6 +93,7 @@ export interface ReplayResult {
93
93
  traceId: string;
94
94
  }
95
95
  export interface ReplayTraceRecorderInput {
96
+ extensions?: Record<string, unknown>;
96
97
  actions?: ReplayTrace["actions"];
97
98
  approvals?: ReplayTrace["approvals"];
98
99
  capabilitySlice: CapabilitySliceSnapshot;
@@ -121,6 +122,8 @@ export interface TraceToGoldenOptions {
121
122
  tags?: string[];
122
123
  }
123
124
  export interface RunReplayOptions {
125
+ routerRunner?: ReplayProviderRunner;
126
+ providerRun?: import("../runtime/provider-types.js").AicfProviderRun;
124
127
  allowProviderLive?: boolean;
125
128
  context?: DecisionRequest["context"];
126
129
  facts?: DecisionRequest["facts"];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/replay/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/replay/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/replay/validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAiBzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAiB,GAAG,yBAAyB,CAmBzG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAiB,GAAG,KAAK,IAAI,WAAW,CAElG"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/replay/validation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAiBzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAiB,GAAG,yBAAyB,CAuBzG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAiB,GAAG,KAAK,IAAI,WAAW,CAElG"}
@@ -1,3 +1,4 @@
1
+ import { validateDiscoverySnapshotStructure } from "./discovery-snapshot.js";
1
2
  import { readFileSync } from "node:fs";
2
3
  import path from "node:path";
3
4
  import { fileURLToPath } from "node:url";
@@ -18,6 +19,11 @@ const forbiddenRawKeys = new Set([
18
19
  ]);
19
20
  export function validateReplayTrace(trace, tracePath = "replay-trace") {
20
21
  const diagnostics = [];
22
+ const extension = trace && typeof trace === "object" ? trace.extensions?.discovery : undefined;
23
+ if (extension !== undefined && !validateDiscoverySnapshotStructure(extension).valid)
24
+ return {
25
+ valid: false, diagnostics: [{ code: "invalid_replay_trace", message: "The discovery snapshot is invalid or exceeds its serialized limit.", path: tracePath + "/extensions/discovery" }]
26
+ };
21
27
  const valid = replayTraceValidator(trace);
22
28
  if (!valid) {
23
29
  diagnostics.push(...(replayTraceValidator.errors ?? []).map((error) => ({
@@ -0,0 +1,4 @@
1
+ /** Bounds strict JSON while traversing, before allocating a complete serialization or clone. */
2
+ export declare function boundedJsonSnapshot(value: unknown, maxBytes: number): unknown;
3
+ export declare function deepFreeze<T>(value: T): T;
4
+ //# sourceMappingURL=bounded-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-json.d.ts","sourceRoot":"","sources":["../../src/runtime/bounded-json.ts"],"names":[],"mappings":"AACA,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAiD7E;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAMzC"}