@copilotkit/aimock 1.37.4 → 1.38.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +22 -0
- package/README.md +27 -9
- package/dist/agui-recorder.cjs +6 -0
- package/dist/agui-recorder.cjs.map +1 -1
- package/dist/agui-recorder.d.cts.map +1 -1
- package/dist/agui-recorder.d.ts.map +1 -1
- package/dist/agui-recorder.js +6 -0
- package/dist/agui-recorder.js.map +1 -1
- package/dist/agui-types.d.ts.map +1 -1
- package/dist/api-key-auth.cjs +166 -0
- package/dist/api-key-auth.cjs.map +1 -0
- package/dist/api-key-auth.d.cts +17 -0
- package/dist/api-key-auth.d.cts.map +1 -0
- package/dist/api-key-auth.d.ts +17 -0
- package/dist/api-key-auth.d.ts.map +1 -0
- package/dist/api-key-auth.js +158 -0
- package/dist/api-key-auth.js.map +1 -0
- package/dist/cli.cjs +4 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/config-loader.cjs +4 -2
- package/dist/config-loader.cjs.map +1 -1
- package/dist/config-loader.d.cts +2 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts +2 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +5 -3
- package/dist/config-loader.js.map +1 -1
- package/dist/fal-audio.cjs +2 -0
- package/dist/fal-audio.cjs.map +1 -1
- package/dist/fal-audio.d.cts.map +1 -1
- package/dist/fal-audio.d.ts.map +1 -1
- package/dist/fal-audio.js +2 -0
- package/dist/fal-audio.js.map +1 -1
- package/dist/fal.cjs +4 -1
- package/dist/fal.cjs.map +1 -1
- package/dist/fal.d.cts.map +1 -1
- package/dist/fal.d.ts.map +1 -1
- package/dist/fal.js +4 -1
- package/dist/fal.js.map +1 -1
- package/dist/fixture-loader.cjs +0 -0
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts +3 -1
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts +3 -1
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +0 -0
- package/dist/fixture-loader.js.map +1 -1
- package/dist/grok-video.cjs +9 -2
- package/dist/grok-video.cjs.map +1 -1
- package/dist/grok-video.js +10 -3
- package/dist/grok-video.js.map +1 -1
- package/dist/helpers.cjs +16 -22
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +16 -21
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/llmock.cjs +14 -3
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +4 -2
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +4 -2
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +15 -5
- package/dist/llmock.js.map +1 -1
- package/dist/openrouter-chat.cjs +333 -0
- package/dist/openrouter-chat.cjs.map +1 -0
- package/dist/openrouter-chat.js +325 -0
- package/dist/openrouter-chat.js.map +1 -0
- package/dist/openrouter-video.cjs +24 -7
- package/dist/openrouter-video.cjs.map +1 -1
- package/dist/openrouter-video.d.cts.map +1 -1
- package/dist/openrouter-video.d.ts.map +1 -1
- package/dist/openrouter-video.js +25 -8
- package/dist/openrouter-video.js.map +1 -1
- package/dist/provider-auth.cjs +20 -0
- package/dist/provider-auth.cjs.map +1 -1
- package/dist/provider-auth.js +20 -1
- package/dist/provider-auth.js.map +1 -1
- package/dist/recorder.cjs +50 -8
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +50 -10
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +200 -89
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts +18 -3
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts +18 -3
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +199 -90
- package/dist/responses.js.map +1 -1
- package/dist/server.cjs +156 -66
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +157 -68
- package/dist/server.js.map +1 -1
- package/dist/sse-writer.cjs +3 -0
- package/dist/sse-writer.cjs.map +1 -1
- package/dist/sse-writer.d.cts +8 -0
- package/dist/sse-writer.d.cts.map +1 -1
- package/dist/sse-writer.d.ts +8 -0
- package/dist/sse-writer.d.ts.map +1 -1
- package/dist/sse-writer.js +3 -0
- package/dist/sse-writer.js.map +1 -1
- package/dist/stream-collapse.cjs +26 -0
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +7 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +7 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +26 -0
- package/dist/stream-collapse.js.map +1 -1
- package/dist/transcription.cjs +49 -2
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.cts.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +50 -3
- package/dist/transcription.js.map +1 -1
- package/dist/types.d.cts +187 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +187 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/veo-video.cjs +9 -2
- package/dist/veo-video.cjs.map +1 -1
- package/dist/veo-video.js +10 -3
- package/dist/veo-video.js.map +1 -1
- package/dist/ws-realtime.cjs +306 -57
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts +1 -0
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts +1 -0
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +307 -58
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +11 -6
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +12 -7
- package/dist/ws-responses.js.map +1 -1
- package/package.json +1 -1
- package/skills/write-fixtures/SKILL.md +53 -19
package/dist/responses.cjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const require_model_utils = require('./model-utils.cjs');
|
|
1
2
|
const require_helpers = require('./helpers.cjs');
|
|
2
3
|
const require_router = require('./router.cjs');
|
|
3
4
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
@@ -161,8 +162,8 @@ function responseId() {
|
|
|
161
162
|
function itemId() {
|
|
162
163
|
return require_helpers.generateId("msg");
|
|
163
164
|
}
|
|
164
|
-
function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches, overrides) {
|
|
165
|
-
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
|
|
165
|
+
function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
166
|
+
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
166
167
|
const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
|
|
167
168
|
events.push(...msgEvents);
|
|
168
169
|
events.push({
|
|
@@ -179,8 +180,8 @@ function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches
|
|
|
179
180
|
});
|
|
180
181
|
return events;
|
|
181
182
|
}
|
|
182
|
-
function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearches, overrides) {
|
|
183
|
-
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
|
|
183
|
+
function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
184
|
+
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
184
185
|
const fcOutputItems = [];
|
|
185
186
|
for (let idx = 0; idx < toolCalls.length; idx++) {
|
|
186
187
|
const tc = toolCalls[idx];
|
|
@@ -244,66 +245,184 @@ function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSe
|
|
|
244
245
|
});
|
|
245
246
|
return events;
|
|
246
247
|
}
|
|
247
|
-
|
|
248
|
+
/**
|
|
249
|
+
* Whether the incoming Responses request should receive encrypted reasoning.
|
|
250
|
+
*
|
|
251
|
+
* Two observed triggers, gated on EITHER:
|
|
252
|
+
* - `include: ["reasoning.encrypted_content"]` — the explicit opt-in, and what
|
|
253
|
+
* `agent-framework-openai` >= 1.11.0 auto-appends on its stateless-replay path
|
|
254
|
+
* (it never sends `store`), so this is the branch that fires for real clients.
|
|
255
|
+
* - `store: false` — captured responses carry the blob when not server-side
|
|
256
|
+
* stored (ZDR) and omit it when stored; kept as a secondary trigger for
|
|
257
|
+
* clients that go stateless without opting in via `include`.
|
|
258
|
+
*
|
|
259
|
+
* Stored / opted-out replays stay byte-identical. Exported so the WebSocket
|
|
260
|
+
* Responses transport can share one gate.
|
|
261
|
+
*/
|
|
262
|
+
function requestWantsEncryptedReasoning(req) {
|
|
263
|
+
if (requestIncludesEncryptedReasoning(req)) return true;
|
|
264
|
+
return req.store === false;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Whether the request carries the EXPLICIT `include` opt-in — a strictly
|
|
268
|
+
* narrower gate than `requestWantsEncryptedReasoning`, which also fires on
|
|
269
|
+
* `store: false`.
|
|
270
|
+
*
|
|
271
|
+
* This is the gate for SYNTHESIZING a reasoning item that the fixture does not
|
|
272
|
+
* declare (see `shouldSynthesizeBlobOnlyReasoning`), and it is deliberately the
|
|
273
|
+
* narrow one. Attaching a field to an item aimock was already emitting is a much
|
|
274
|
+
* smaller step than conjuring a whole output item that did not previously exist,
|
|
275
|
+
* so the larger behavior change gets the gate that is directly observable in the
|
|
276
|
+
* request rather than the inferred `store: false` one. `agent-framework-openai`
|
|
277
|
+
* >= 1.11.0 auto-appends `include` on its stateless-replay path and never sends
|
|
278
|
+
* `store` at all, so the motivating client is fully served by this branch — the
|
|
279
|
+
* narrowing costs the feature nothing.
|
|
280
|
+
*
|
|
281
|
+
* Exported so the WebSocket Responses transport shares one gate.
|
|
282
|
+
*/
|
|
283
|
+
function requestIncludesEncryptedReasoning(req) {
|
|
284
|
+
const include = req.include;
|
|
285
|
+
return Array.isArray(include) && include.includes("reasoning.encrypted_content");
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Synthetic stand-in for OpenAI's opaque `reasoning.encrypted_content`. aimock
|
|
289
|
+
* has no real ciphertext; it emits a base64 placeholder derived from the
|
|
290
|
+
* reasoning id (stable for a given item, opaque like the real field). Consumers
|
|
291
|
+
* store it (e.g. as agent-framework `protected_data`) and replay it verbatim;
|
|
292
|
+
* aimock matches on content and ignores the echoed blob. Without it,
|
|
293
|
+
* agent-framework-openai >= 1.11.0 hard-fails a reasoning + multi-tool chain on
|
|
294
|
+
* the follow-up request. See microsoft/agent-framework#7233.
|
|
295
|
+
*
|
|
296
|
+
* aimock skips inbound reasoning items entirely, so it cannot reproduce
|
|
297
|
+
* OpenAI's `invalid_encrypted_content` rejection of a mismatched blob/id — a
|
|
298
|
+
* known replay-only limitation.
|
|
299
|
+
*/
|
|
300
|
+
function syntheticEncryptedReasoning(reasoningId) {
|
|
301
|
+
return Buffer.from(`aimock-encrypted-reasoning:${reasoningId}`).toString("base64");
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Build a Responses `reasoning` output item. `summaryText` controls the summary
|
|
305
|
+
* (present for the terminal `done` / non-streaming item, omitted for the
|
|
306
|
+
* in-progress `added` item); `emitEncrypted` controls the blob INDEPENDENTLY of
|
|
307
|
+
* the summary, so a blob with an empty summary is expressible. aimock emits the
|
|
308
|
+
* blob only on the terminal item and omits it on `added`: real OpenAI populates
|
|
309
|
+
* `added` opportunistically, but the field is `anyOf: [string, null]` and
|
|
310
|
+
* non-required, so consumers should read it at `done` and treat `added` as
|
|
311
|
+
* best-effort — omitting there is legal and harmless.
|
|
312
|
+
*/
|
|
313
|
+
function buildReasoningOutputItem(reasoningId, opts = {}) {
|
|
314
|
+
const item = {
|
|
315
|
+
type: "reasoning",
|
|
316
|
+
id: reasoningId,
|
|
317
|
+
summary: opts.summaryText === void 0 ? [] : [{
|
|
318
|
+
type: "summary_text",
|
|
319
|
+
text: opts.summaryText
|
|
320
|
+
}]
|
|
321
|
+
};
|
|
322
|
+
if (opts.emitEncrypted) item.encrypted_content = syntheticEncryptedReasoning(reasoningId);
|
|
323
|
+
return item;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Whether to synthesize a summary-LESS reasoning item that exists purely to
|
|
327
|
+
* carry the encrypted blob.
|
|
328
|
+
*
|
|
329
|
+
* Every reasoning item aimock emits otherwise originates in a fixture's declared
|
|
330
|
+
* `reasoning` summary text. But a fixture RECORDED from the real stateless
|
|
331
|
+
* agent-framework flow typically has NO summary — OpenAI returns `summary: []`
|
|
332
|
+
* unless summaries are explicitly requested — so keying the item on a declared
|
|
333
|
+
* summary starves the exact flow this feature exists to serve: fully opted in,
|
|
334
|
+
* yet no reasoning item and therefore no blob. Real OpenAI, for a
|
|
335
|
+
* reasoning-capable model, still returns a reasoning item (`summary: []`) with
|
|
336
|
+
* the blob populated. So synthesize one, gated on:
|
|
337
|
+
*
|
|
338
|
+
* - the EXPLICIT `include` opt-in ONLY (`requestIncludesEncryptedReasoning`),
|
|
339
|
+
* which is NARROWER than the `requestWantsEncryptedReasoning` gate that
|
|
340
|
+
* controls the blob itself. A `store: false` request whose fixture declares no
|
|
341
|
+
* summary therefore gets NO reasoning item, exactly as before this change.
|
|
342
|
+
* Two reasons: (1) creating an output item that did not previously exist is a
|
|
343
|
+
* bigger behavior change than adding a field to an item already being
|
|
344
|
+
* emitted, so it earns the gate that is directly observable in the request
|
|
345
|
+
* rather than the inferred one; (2) the `store: false` trigger's supporting
|
|
346
|
+
* capture evidence is not verifiable from this repo, and a larger change must
|
|
347
|
+
* not be stacked on an unverifiable premise. `agent-framework-openai` >=
|
|
348
|
+
* 1.11.0 sends `include` and never `store`, so nothing is lost.
|
|
349
|
+
* - the REQUESTED model's reasoning capability (aimock#254) — emitting a
|
|
350
|
+
* reasoning item for gpt-4o would be LESS faithful, not more, since that
|
|
351
|
+
* model has no reasoning channel at all. Unlike `resolveReasoningForModel`,
|
|
352
|
+
* which fails open for a declared summary (a recorded summary is evidence the
|
|
353
|
+
* model did reason), there is nothing to preserve here: a synthesized item on
|
|
354
|
+
* a non-reasoning model would be pure fabrication, so this gate is hard.
|
|
355
|
+
*
|
|
356
|
+
* Note this is INDEPENDENT of `emitEncryptedReasoning`: when a fixture DOES
|
|
357
|
+
* declare a summary, the blob still rides on it under either trigger (including
|
|
358
|
+
* `store: false`), unchanged.
|
|
359
|
+
*/
|
|
360
|
+
function shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning) {
|
|
361
|
+
if (reasoning) return false;
|
|
362
|
+
if (!synthesizeSummarylessReasoning) return false;
|
|
363
|
+
return require_model_utils.isReasoningModel(model);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* `reasoning` is `undefined` for a synthesized blob-only item (see
|
|
367
|
+
* `shouldSynthesizeBlobOnlyReasoning`). In that case the item's `summary` is
|
|
368
|
+
* `[]`, so the summary-part / summary-text events are SKIPPED entirely — they
|
|
369
|
+
* would describe a part that does not exist on the item — leaving a coherent
|
|
370
|
+
* `output_item.added` → `output_item.done` pair with nothing between.
|
|
371
|
+
*/
|
|
372
|
+
function buildReasoningStreamEvents(reasoning, chunkSize, emitEncryptedReasoning = false) {
|
|
248
373
|
const reasoningId = require_helpers.generateId("rs");
|
|
249
374
|
const events = [];
|
|
250
375
|
events.push({
|
|
251
376
|
type: "response.output_item.added",
|
|
252
377
|
output_index: 0,
|
|
253
|
-
item:
|
|
254
|
-
type: "reasoning",
|
|
255
|
-
id: reasoningId,
|
|
256
|
-
summary: []
|
|
257
|
-
}
|
|
378
|
+
item: buildReasoningOutputItem(reasoningId)
|
|
258
379
|
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
380
|
+
if (reasoning !== void 0) {
|
|
381
|
+
events.push({
|
|
382
|
+
type: "response.reasoning_summary_part.added",
|
|
383
|
+
item_id: reasoningId,
|
|
384
|
+
output_index: 0,
|
|
385
|
+
summary_index: 0,
|
|
386
|
+
part: {
|
|
387
|
+
type: "summary_text",
|
|
388
|
+
text: ""
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
for (let i = 0; i < reasoning.length; i += chunkSize) {
|
|
392
|
+
const slice = reasoning.slice(i, i + chunkSize);
|
|
393
|
+
events.push({
|
|
394
|
+
type: "response.reasoning_summary_text.delta",
|
|
395
|
+
item_id: reasoningId,
|
|
396
|
+
output_index: 0,
|
|
397
|
+
summary_index: 0,
|
|
398
|
+
delta: slice
|
|
399
|
+
});
|
|
267
400
|
}
|
|
268
|
-
});
|
|
269
|
-
for (let i = 0; i < reasoning.length; i += chunkSize) {
|
|
270
|
-
const slice = reasoning.slice(i, i + chunkSize);
|
|
271
401
|
events.push({
|
|
272
|
-
type: "response.reasoning_summary_text.
|
|
402
|
+
type: "response.reasoning_summary_text.done",
|
|
273
403
|
item_id: reasoningId,
|
|
274
404
|
output_index: 0,
|
|
275
405
|
summary_index: 0,
|
|
276
|
-
|
|
406
|
+
text: reasoning
|
|
407
|
+
});
|
|
408
|
+
events.push({
|
|
409
|
+
type: "response.reasoning_summary_part.done",
|
|
410
|
+
item_id: reasoningId,
|
|
411
|
+
output_index: 0,
|
|
412
|
+
summary_index: 0,
|
|
413
|
+
part: {
|
|
414
|
+
type: "summary_text",
|
|
415
|
+
text: reasoning
|
|
416
|
+
}
|
|
277
417
|
});
|
|
278
418
|
}
|
|
279
|
-
events.push({
|
|
280
|
-
type: "response.reasoning_summary_text.done",
|
|
281
|
-
item_id: reasoningId,
|
|
282
|
-
output_index: 0,
|
|
283
|
-
summary_index: 0,
|
|
284
|
-
text: reasoning
|
|
285
|
-
});
|
|
286
|
-
events.push({
|
|
287
|
-
type: "response.reasoning_summary_part.done",
|
|
288
|
-
item_id: reasoningId,
|
|
289
|
-
output_index: 0,
|
|
290
|
-
summary_index: 0,
|
|
291
|
-
part: {
|
|
292
|
-
type: "summary_text",
|
|
293
|
-
text: reasoning
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
419
|
events.push({
|
|
297
420
|
type: "response.output_item.done",
|
|
298
421
|
output_index: 0,
|
|
299
|
-
item: {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
type: "summary_text",
|
|
304
|
-
text: reasoning
|
|
305
|
-
}]
|
|
306
|
-
}
|
|
422
|
+
item: buildReasoningOutputItem(reasoningId, {
|
|
423
|
+
summaryText: reasoning,
|
|
424
|
+
emitEncrypted: emitEncryptedReasoning
|
|
425
|
+
})
|
|
307
426
|
});
|
|
308
427
|
return events;
|
|
309
428
|
}
|
|
@@ -341,7 +460,7 @@ function buildWebSearchStreamEvents(queries, startOutputIndex) {
|
|
|
341
460
|
}
|
|
342
461
|
return events;
|
|
343
462
|
}
|
|
344
|
-
function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides) {
|
|
463
|
+
function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
345
464
|
const respId = overrides?.id ?? responseId();
|
|
346
465
|
const created = overrides?.created ?? Math.floor(Date.now() / 1e3);
|
|
347
466
|
const effectiveModel = overrides?.model ?? model;
|
|
@@ -370,8 +489,8 @@ function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrid
|
|
|
370
489
|
output: []
|
|
371
490
|
}
|
|
372
491
|
});
|
|
373
|
-
if (reasoning) {
|
|
374
|
-
const reasoningEvents = buildReasoningStreamEvents(reasoning,
|
|
492
|
+
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) {
|
|
493
|
+
const reasoningEvents = buildReasoningStreamEvents(reasoning, chunkSize, emitEncryptedReasoning);
|
|
375
494
|
events.push(...reasoningEvents);
|
|
376
495
|
const doneEvent = reasoningEvents.find((e) => e.type === "response.output_item.done" && e.item?.type === "reasoning");
|
|
377
496
|
if (doneEvent) prefixOutputItems.push(doneEvent.item);
|
|
@@ -518,16 +637,12 @@ function buildFunctionCallOutputEvents(toolCall, chunkSize, outputIndex) {
|
|
|
518
637
|
fcItem
|
|
519
638
|
};
|
|
520
639
|
}
|
|
521
|
-
function buildOutputPrefix(content, reasoning, webSearches) {
|
|
640
|
+
function buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
522
641
|
const output = [];
|
|
523
|
-
if (reasoning) output.push({
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
type: "summary_text",
|
|
528
|
-
text: reasoning
|
|
529
|
-
}]
|
|
530
|
-
});
|
|
642
|
+
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
|
|
643
|
+
summaryText: reasoning,
|
|
644
|
+
emitEncrypted: emitEncryptedReasoning
|
|
645
|
+
}));
|
|
531
646
|
if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
|
|
532
647
|
type: "web_search_call",
|
|
533
648
|
id: require_helpers.generateId("ws"),
|
|
@@ -561,19 +676,15 @@ function buildResponseEnvelope(model, output, overrides) {
|
|
|
561
676
|
usage: responsesUsage(overrides)
|
|
562
677
|
};
|
|
563
678
|
}
|
|
564
|
-
function buildTextResponse(content, model, reasoning, webSearches, overrides) {
|
|
565
|
-
return buildResponseEnvelope(model, buildOutputPrefix(content, reasoning, webSearches), overrides);
|
|
679
|
+
function buildTextResponse(content, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
680
|
+
return buildResponseEnvelope(model, buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning), overrides);
|
|
566
681
|
}
|
|
567
|
-
function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrides) {
|
|
682
|
+
function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
568
683
|
const output = [];
|
|
569
|
-
if (reasoning) output.push({
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
type: "summary_text",
|
|
574
|
-
text: reasoning
|
|
575
|
-
}]
|
|
576
|
-
});
|
|
684
|
+
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
|
|
685
|
+
summaryText: reasoning,
|
|
686
|
+
emitEncrypted: emitEncryptedReasoning
|
|
687
|
+
}));
|
|
577
688
|
if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
|
|
578
689
|
type: "web_search_call",
|
|
579
690
|
id: require_helpers.generateId("ws"),
|
|
@@ -593,8 +704,8 @@ function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrid
|
|
|
593
704
|
});
|
|
594
705
|
return buildResponseEnvelope(model, output, overrides);
|
|
595
706
|
}
|
|
596
|
-
function buildContentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize, reasoning, webSearches, overrides, blocks) {
|
|
597
|
-
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides);
|
|
707
|
+
function buildContentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize, reasoning, webSearches, overrides, blocks, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
708
|
+
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
598
709
|
const orderedOutputItems = [];
|
|
599
710
|
if (blocks && blocks.length > 0) {
|
|
600
711
|
const ordered = require_helpers.resolveFixtureBlocks(blocks);
|
|
@@ -663,18 +774,14 @@ function buildMessageOutputItem(content) {
|
|
|
663
774
|
}]
|
|
664
775
|
};
|
|
665
776
|
}
|
|
666
|
-
function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning, webSearches, overrides, blocks) {
|
|
777
|
+
function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning, webSearches, overrides, blocks, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
667
778
|
if (blocks && blocks.length > 0) {
|
|
668
779
|
const ordered = require_helpers.resolveFixtureBlocks(blocks);
|
|
669
780
|
const output = [];
|
|
670
|
-
if (reasoning) output.push({
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
type: "summary_text",
|
|
675
|
-
text: reasoning
|
|
676
|
-
}]
|
|
677
|
-
});
|
|
781
|
+
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
|
|
782
|
+
summaryText: reasoning,
|
|
783
|
+
emitEncrypted: emitEncryptedReasoning
|
|
784
|
+
}));
|
|
678
785
|
if (webSearches && webSearches.length > 0) for (const query of webSearches) output.push({
|
|
679
786
|
type: "web_search_call",
|
|
680
787
|
id: require_helpers.generateId("ws"),
|
|
@@ -692,7 +799,7 @@ function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning,
|
|
|
692
799
|
}));
|
|
693
800
|
return buildResponseEnvelope(model, output, overrides);
|
|
694
801
|
}
|
|
695
|
-
const output = buildOutputPrefix(content, reasoning, webSearches);
|
|
802
|
+
const output = buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
696
803
|
for (const tc of toolCalls) output.push(buildFunctionCallOutputItem(tc));
|
|
697
804
|
return buildResponseEnvelope(model, output, overrides);
|
|
698
805
|
}
|
|
@@ -748,6 +855,8 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
748
855
|
const completionReq = responsesToCompletionRequest(responsesReq);
|
|
749
856
|
completionReq._endpointType = "chat";
|
|
750
857
|
completionReq._context = require_helpers.getContext(req);
|
|
858
|
+
const emitEncryptedReasoning = requestWantsEncryptedReasoning(responsesReq);
|
|
859
|
+
const synthesizeSummarylessReasoning = requestIncludesEncryptedReasoning(responsesReq);
|
|
751
860
|
const testId = require_helpers.getTestId(req);
|
|
752
861
|
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
|
|
753
862
|
if (fixture) {
|
|
@@ -854,11 +963,11 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
854
963
|
}
|
|
855
964
|
});
|
|
856
965
|
if (responsesReq.stream !== true) {
|
|
857
|
-
const body = buildContentWithToolCallsResponse(response.content ?? "", response.toolCalls ?? [], completionReq.model, effReasoning, response.webSearches, overrides, response.blocks);
|
|
966
|
+
const body = buildContentWithToolCallsResponse(response.content ?? "", response.toolCalls ?? [], completionReq.model, effReasoning, response.webSearches, overrides, response.blocks, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
858
967
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
859
968
|
res.end(JSON.stringify(body));
|
|
860
969
|
} else {
|
|
861
|
-
const events = buildContentWithToolCallsStreamEvents(response.content ?? "", response.toolCalls ?? [], completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, response.blocks);
|
|
970
|
+
const events = buildContentWithToolCallsStreamEvents(response.content ?? "", response.toolCalls ?? [], completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, response.blocks, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
862
971
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
863
972
|
if (!await writeResponsesSSEStream(res, events, {
|
|
864
973
|
latency,
|
|
@@ -891,11 +1000,11 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
891
1000
|
}
|
|
892
1001
|
});
|
|
893
1002
|
if (responsesReq.stream !== true) {
|
|
894
|
-
const body = buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides);
|
|
1003
|
+
const body = buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
895
1004
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
896
1005
|
res.end(JSON.stringify(body));
|
|
897
1006
|
} else {
|
|
898
|
-
const events = buildTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides);
|
|
1007
|
+
const events = buildTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
899
1008
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
900
1009
|
if (!await writeResponsesSSEStream(res, events, {
|
|
901
1010
|
latency,
|
|
@@ -928,11 +1037,11 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
928
1037
|
}
|
|
929
1038
|
});
|
|
930
1039
|
if (responsesReq.stream !== true) {
|
|
931
|
-
const body = buildToolCallResponse(response.toolCalls, completionReq.model, effReasoning, response.webSearches, overrides);
|
|
1040
|
+
const body = buildToolCallResponse(response.toolCalls, completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
932
1041
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
933
1042
|
res.end(JSON.stringify(body));
|
|
934
1043
|
} else {
|
|
935
|
-
const events = buildToolCallStreamEvents(response.toolCalls, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides);
|
|
1044
|
+
const events = buildToolCallStreamEvents(response.toolCalls, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
936
1045
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
937
1046
|
if (!await writeResponsesSSEStream(res, events, {
|
|
938
1047
|
latency,
|
|
@@ -971,5 +1080,7 @@ exports.buildContentWithToolCallsStreamEvents = buildContentWithToolCallsStreamE
|
|
|
971
1080
|
exports.buildTextStreamEvents = buildTextStreamEvents;
|
|
972
1081
|
exports.buildToolCallStreamEvents = buildToolCallStreamEvents;
|
|
973
1082
|
exports.handleResponses = handleResponses;
|
|
1083
|
+
exports.requestIncludesEncryptedReasoning = requestIncludesEncryptedReasoning;
|
|
1084
|
+
exports.requestWantsEncryptedReasoning = requestWantsEncryptedReasoning;
|
|
974
1085
|
exports.responsesToCompletionRequest = responsesToCompletionRequest;
|
|
975
1086
|
//# sourceMappingURL=responses.cjs.map
|