@yolk-sdk/emulators 0.1.0-canary.96

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 (333) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2135 -0
  3. package/dist/anthropic.d.mts +269 -0
  4. package/dist/anthropic.d.mts.map +1 -0
  5. package/dist/anthropic.mjs +177 -0
  6. package/dist/anthropic.mjs.map +1 -0
  7. package/dist/chat-completions.d.mts +288 -0
  8. package/dist/chat-completions.d.mts.map +1 -0
  9. package/dist/chat-completions.mjs +451 -0
  10. package/dist/chat-completions.mjs.map +1 -0
  11. package/dist/codex.d.mts +265 -0
  12. package/dist/codex.d.mts.map +1 -0
  13. package/dist/codex.mjs +199 -0
  14. package/dist/codex.mjs.map +1 -0
  15. package/dist/dropbox/api.d.mts +63 -0
  16. package/dist/dropbox/api.d.mts.map +1 -0
  17. package/dist/dropbox/api.mjs +565 -0
  18. package/dist/dropbox/api.mjs.map +1 -0
  19. package/dist/dropbox/state.d.mts +136 -0
  20. package/dist/dropbox/state.d.mts.map +1 -0
  21. package/dist/dropbox/state.mjs +209 -0
  22. package/dist/dropbox/state.mjs.map +1 -0
  23. package/dist/dropbox.d.mts +79 -0
  24. package/dist/dropbox.d.mts.map +1 -0
  25. package/dist/dropbox.mjs +124 -0
  26. package/dist/dropbox.mjs.map +1 -0
  27. package/dist/email-fixtures.d.mts +36 -0
  28. package/dist/email-fixtures.d.mts.map +1 -0
  29. package/dist/email-fixtures.mjs +1080 -0
  30. package/dist/email-fixtures.mjs.map +1 -0
  31. package/dist/email.d.mts +160 -0
  32. package/dist/email.d.mts.map +1 -0
  33. package/dist/email.mjs +608 -0
  34. package/dist/email.mjs.map +1 -0
  35. package/dist/emulator-compose.d.mts +40 -0
  36. package/dist/emulator-compose.d.mts.map +1 -0
  37. package/dist/emulator-compose.mjs +91 -0
  38. package/dist/emulator-compose.mjs.map +1 -0
  39. package/dist/emulator-http.d.mts +53 -0
  40. package/dist/emulator-http.d.mts.map +1 -0
  41. package/dist/emulator-http.mjs +117 -0
  42. package/dist/emulator-http.mjs.map +1 -0
  43. package/dist/emulator-kernel.d.mts +176 -0
  44. package/dist/emulator-kernel.d.mts.map +1 -0
  45. package/dist/emulator-kernel.mjs +413 -0
  46. package/dist/emulator-kernel.mjs.map +1 -0
  47. package/dist/fixture-route.d.mts +129 -0
  48. package/dist/fixture-route.d.mts.map +1 -0
  49. package/dist/fixture-route.mjs +257 -0
  50. package/dist/fixture-route.mjs.map +1 -0
  51. package/dist/fortnox/api.d.mts +92 -0
  52. package/dist/fortnox/api.d.mts.map +1 -0
  53. package/dist/fortnox/api.mjs +750 -0
  54. package/dist/fortnox/api.mjs.map +1 -0
  55. package/dist/fortnox/state.d.mts +533 -0
  56. package/dist/fortnox/state.d.mts.map +1 -0
  57. package/dist/fortnox/state.mjs +612 -0
  58. package/dist/fortnox/state.mjs.map +1 -0
  59. package/dist/fortnox.d.mts +128 -0
  60. package/dist/fortnox.d.mts.map +1 -0
  61. package/dist/fortnox.mjs +403 -0
  62. package/dist/fortnox.mjs.map +1 -0
  63. package/dist/gateway-evaluate-recordings.d.mts +12 -0
  64. package/dist/gateway-evaluate-recordings.d.mts.map +1 -0
  65. package/dist/gateway-evaluate-recordings.mjs +128 -0
  66. package/dist/gateway-evaluate-recordings.mjs.map +1 -0
  67. package/dist/gateway.d.mts +272 -0
  68. package/dist/gateway.d.mts.map +1 -0
  69. package/dist/gateway.mjs +400 -0
  70. package/dist/gateway.mjs.map +1 -0
  71. package/dist/github/api.d.mts +63 -0
  72. package/dist/github/api.d.mts.map +1 -0
  73. package/dist/github/api.mjs +527 -0
  74. package/dist/github/api.mjs.map +1 -0
  75. package/dist/github/state.d.mts +272 -0
  76. package/dist/github/state.d.mts.map +1 -0
  77. package/dist/github/state.mjs +303 -0
  78. package/dist/github/state.mjs.map +1 -0
  79. package/dist/github.d.mts +77 -0
  80. package/dist/github.d.mts.map +1 -0
  81. package/dist/github.mjs +180 -0
  82. package/dist/github.mjs.map +1 -0
  83. package/dist/google/calendar.d.mts +10 -0
  84. package/dist/google/calendar.d.mts.map +1 -0
  85. package/dist/google/calendar.mjs +252 -0
  86. package/dist/google/calendar.mjs.map +1 -0
  87. package/dist/google/drive.d.mts +8 -0
  88. package/dist/google/drive.d.mts.map +1 -0
  89. package/dist/google/drive.mjs +252 -0
  90. package/dist/google/drive.mjs.map +1 -0
  91. package/dist/google/gmail.d.mts +10 -0
  92. package/dist/google/gmail.d.mts.map +1 -0
  93. package/dist/google/gmail.mjs +591 -0
  94. package/dist/google/gmail.mjs.map +1 -0
  95. package/dist/google/shared.d.mts +107 -0
  96. package/dist/google/shared.d.mts.map +1 -0
  97. package/dist/google/shared.mjs +146 -0
  98. package/dist/google/shared.mjs.map +1 -0
  99. package/dist/google/state.d.mts +385 -0
  100. package/dist/google/state.d.mts.map +1 -0
  101. package/dist/google/state.mjs +496 -0
  102. package/dist/google/state.mjs.map +1 -0
  103. package/dist/google.d.mts +75 -0
  104. package/dist/google.d.mts.map +1 -0
  105. package/dist/google.mjs +210 -0
  106. package/dist/google.mjs.map +1 -0
  107. package/dist/linkedin-search/api.d.mts +45 -0
  108. package/dist/linkedin-search/api.d.mts.map +1 -0
  109. package/dist/linkedin-search/api.mjs +181 -0
  110. package/dist/linkedin-search/api.mjs.map +1 -0
  111. package/dist/linkedin-search/state.d.mts +123 -0
  112. package/dist/linkedin-search/state.d.mts.map +1 -0
  113. package/dist/linkedin-search/state.mjs +261 -0
  114. package/dist/linkedin-search/state.mjs.map +1 -0
  115. package/dist/linkedin-search.d.mts +69 -0
  116. package/dist/linkedin-search.d.mts.map +1 -0
  117. package/dist/linkedin-search.mjs +158 -0
  118. package/dist/linkedin-search.mjs.map +1 -0
  119. package/dist/mcp/api.d.mts +44 -0
  120. package/dist/mcp/api.d.mts.map +1 -0
  121. package/dist/mcp/api.mjs +557 -0
  122. package/dist/mcp/api.mjs.map +1 -0
  123. package/dist/mcp/recordings.d.mts +40 -0
  124. package/dist/mcp/recordings.d.mts.map +1 -0
  125. package/dist/mcp/recordings.mjs +2390 -0
  126. package/dist/mcp/recordings.mjs.map +1 -0
  127. package/dist/mcp/state.d.mts +71 -0
  128. package/dist/mcp/state.d.mts.map +1 -0
  129. package/dist/mcp/state.mjs +83 -0
  130. package/dist/mcp/state.mjs.map +1 -0
  131. package/dist/mcp.d.mts +84 -0
  132. package/dist/mcp.d.mts.map +1 -0
  133. package/dist/mcp.mjs +241 -0
  134. package/dist/mcp.mjs.map +1 -0
  135. package/dist/messages.d.mts +183 -0
  136. package/dist/messages.d.mts.map +1 -0
  137. package/dist/messages.mjs +532 -0
  138. package/dist/messages.mjs.map +1 -0
  139. package/dist/microsoft/api.d.mts +47 -0
  140. package/dist/microsoft/api.d.mts.map +1 -0
  141. package/dist/microsoft/api.mjs +178 -0
  142. package/dist/microsoft/api.mjs.map +1 -0
  143. package/dist/microsoft/calendar.d.mts +30 -0
  144. package/dist/microsoft/calendar.d.mts.map +1 -0
  145. package/dist/microsoft/calendar.mjs +271 -0
  146. package/dist/microsoft/calendar.mjs.map +1 -0
  147. package/dist/microsoft/drive.d.mts +36 -0
  148. package/dist/microsoft/drive.d.mts.map +1 -0
  149. package/dist/microsoft/drive.mjs +298 -0
  150. package/dist/microsoft/drive.mjs.map +1 -0
  151. package/dist/microsoft/graph.d.mts +198 -0
  152. package/dist/microsoft/graph.d.mts.map +1 -0
  153. package/dist/microsoft/graph.mjs +264 -0
  154. package/dist/microsoft/graph.mjs.map +1 -0
  155. package/dist/microsoft/mail.d.mts +48 -0
  156. package/dist/microsoft/mail.d.mts.map +1 -0
  157. package/dist/microsoft/mail.mjs +488 -0
  158. package/dist/microsoft/mail.mjs.map +1 -0
  159. package/dist/microsoft/state.d.mts +480 -0
  160. package/dist/microsoft/state.d.mts.map +1 -0
  161. package/dist/microsoft/state.mjs +625 -0
  162. package/dist/microsoft/state.mjs.map +1 -0
  163. package/dist/microsoft.d.mts +168 -0
  164. package/dist/microsoft.d.mts.map +1 -0
  165. package/dist/microsoft.mjs +483 -0
  166. package/dist/microsoft.mjs.map +1 -0
  167. package/dist/node.d.mts +47 -0
  168. package/dist/node.d.mts.map +1 -0
  169. package/dist/node.mjs +178 -0
  170. package/dist/node.mjs.map +1 -0
  171. package/dist/notion/api.d.mts +51 -0
  172. package/dist/notion/api.d.mts.map +1 -0
  173. package/dist/notion/api.mjs +507 -0
  174. package/dist/notion/api.mjs.map +1 -0
  175. package/dist/notion/state.d.mts +329 -0
  176. package/dist/notion/state.d.mts.map +1 -0
  177. package/dist/notion/state.mjs +432 -0
  178. package/dist/notion/state.mjs.map +1 -0
  179. package/dist/notion.d.mts +72 -0
  180. package/dist/notion.d.mts.map +1 -0
  181. package/dist/notion.mjs +127 -0
  182. package/dist/notion.mjs.map +1 -0
  183. package/dist/openai.d.mts +165 -0
  184. package/dist/openai.d.mts.map +1 -0
  185. package/dist/openai.mjs +141 -0
  186. package/dist/openai.mjs.map +1 -0
  187. package/dist/opencode-recordings.d.mts +7 -0
  188. package/dist/opencode-recordings.d.mts.map +1 -0
  189. package/dist/opencode-recordings.mjs +222 -0
  190. package/dist/opencode-recordings.mjs.map +1 -0
  191. package/dist/opencode.d.mts +70 -0
  192. package/dist/opencode.d.mts.map +1 -0
  193. package/dist/opencode.mjs +217 -0
  194. package/dist/opencode.mjs.map +1 -0
  195. package/dist/r2-fixtures.d.mts +36 -0
  196. package/dist/r2-fixtures.d.mts.map +1 -0
  197. package/dist/r2-fixtures.mjs +245 -0
  198. package/dist/r2-fixtures.mjs.map +1 -0
  199. package/dist/r2-guard.d.mts +43 -0
  200. package/dist/r2-guard.d.mts.map +1 -0
  201. package/dist/r2-guard.mjs +215 -0
  202. package/dist/r2-guard.mjs.map +1 -0
  203. package/dist/r2.d.mts +166 -0
  204. package/dist/r2.d.mts.map +1 -0
  205. package/dist/r2.mjs +517 -0
  206. package/dist/r2.mjs.map +1 -0
  207. package/dist/responses.d.mts +231 -0
  208. package/dist/responses.d.mts.map +1 -0
  209. package/dist/responses.mjs +556 -0
  210. package/dist/responses.mjs.map +1 -0
  211. package/dist/route-evidence.d.mts +45 -0
  212. package/dist/route-evidence.d.mts.map +1 -0
  213. package/dist/route-evidence.mjs +56 -0
  214. package/dist/route-evidence.mjs.map +1 -0
  215. package/dist/router.d.mts +93 -0
  216. package/dist/router.d.mts.map +1 -0
  217. package/dist/router.mjs +259 -0
  218. package/dist/router.mjs.map +1 -0
  219. package/dist/stateful-core.d.mts +17 -0
  220. package/dist/stateful-core.d.mts.map +1 -0
  221. package/dist/stateful-core.mjs +41 -0
  222. package/dist/stateful-core.mjs.map +1 -0
  223. package/dist/stateful-emulator.d.mts +565 -0
  224. package/dist/stateful-emulator.d.mts.map +1 -0
  225. package/dist/stateful-emulator.mjs +1228 -0
  226. package/dist/stateful-emulator.mjs.map +1 -0
  227. package/dist/stateful-secrets.d.mts +84 -0
  228. package/dist/stateful-secrets.d.mts.map +1 -0
  229. package/dist/stateful-secrets.mjs +216 -0
  230. package/dist/stateful-secrets.mjs.map +1 -0
  231. package/dist/subscription-usage-recordings.d.mts +9 -0
  232. package/dist/subscription-usage-recordings.d.mts.map +1 -0
  233. package/dist/subscription-usage-recordings.mjs +53 -0
  234. package/dist/subscription-usage-recordings.mjs.map +1 -0
  235. package/dist/subscription-usage.d.mts +53 -0
  236. package/dist/subscription-usage.d.mts.map +1 -0
  237. package/dist/subscription-usage.mjs +21 -0
  238. package/dist/subscription-usage.mjs.map +1 -0
  239. package/dist/telegram/api.d.mts +34 -0
  240. package/dist/telegram/api.d.mts.map +1 -0
  241. package/dist/telegram/api.mjs +257 -0
  242. package/dist/telegram/api.mjs.map +1 -0
  243. package/dist/telegram/state.d.mts +128 -0
  244. package/dist/telegram/state.d.mts.map +1 -0
  245. package/dist/telegram/state.mjs +154 -0
  246. package/dist/telegram/state.mjs.map +1 -0
  247. package/dist/telegram.d.mts +62 -0
  248. package/dist/telegram.d.mts.map +1 -0
  249. package/dist/telegram.mjs +127 -0
  250. package/dist/telegram.mjs.map +1 -0
  251. package/dist/todoist/api.d.mts +55 -0
  252. package/dist/todoist/api.d.mts.map +1 -0
  253. package/dist/todoist/api.mjs +415 -0
  254. package/dist/todoist/api.mjs.map +1 -0
  255. package/dist/todoist/state.d.mts +275 -0
  256. package/dist/todoist/state.d.mts.map +1 -0
  257. package/dist/todoist/state.mjs +345 -0
  258. package/dist/todoist/state.mjs.map +1 -0
  259. package/dist/todoist.d.mts +68 -0
  260. package/dist/todoist.d.mts.map +1 -0
  261. package/dist/todoist.mjs +181 -0
  262. package/dist/todoist.mjs.map +1 -0
  263. package/dist/xai.d.mts +267 -0
  264. package/dist/xai.d.mts.map +1 -0
  265. package/dist/xai.mjs +252 -0
  266. package/dist/xai.mjs.map +1 -0
  267. package/package.json +157 -0
  268. package/src/anthropic.ts +289 -0
  269. package/src/chat-completions.ts +924 -0
  270. package/src/codex.ts +296 -0
  271. package/src/dropbox/api.ts +1084 -0
  272. package/src/dropbox/state.ts +364 -0
  273. package/src/dropbox.ts +203 -0
  274. package/src/email-fixtures.ts +1297 -0
  275. package/src/email.ts +1108 -0
  276. package/src/emulator-compose.ts +147 -0
  277. package/src/emulator-http.ts +184 -0
  278. package/src/emulator-kernel.ts +844 -0
  279. package/src/fixture-route.ts +561 -0
  280. package/src/fortnox/api.ts +1352 -0
  281. package/src/fortnox/state.ts +798 -0
  282. package/src/fortnox.ts +801 -0
  283. package/src/gateway-evaluate-recordings.ts +153 -0
  284. package/src/gateway.ts +530 -0
  285. package/src/github/api.ts +986 -0
  286. package/src/github/state.ts +439 -0
  287. package/src/github.ts +271 -0
  288. package/src/google/calendar.ts +486 -0
  289. package/src/google/drive.ts +471 -0
  290. package/src/google/gmail.ts +1011 -0
  291. package/src/google/shared.ts +321 -0
  292. package/src/google/state.ts +686 -0
  293. package/src/google.ts +298 -0
  294. package/src/linkedin-search/api.ts +363 -0
  295. package/src/linkedin-search/state.ts +373 -0
  296. package/src/linkedin-search.ts +241 -0
  297. package/src/mcp/api.ts +995 -0
  298. package/src/mcp/recordings.ts +2665 -0
  299. package/src/mcp/state.ts +125 -0
  300. package/src/mcp.ts +319 -0
  301. package/src/messages.ts +844 -0
  302. package/src/microsoft/api.ts +426 -0
  303. package/src/microsoft/calendar.ts +491 -0
  304. package/src/microsoft/drive.ts +541 -0
  305. package/src/microsoft/graph.ts +550 -0
  306. package/src/microsoft/mail.ts +833 -0
  307. package/src/microsoft/state.ts +822 -0
  308. package/src/microsoft.ts +982 -0
  309. package/src/node.ts +293 -0
  310. package/src/notion/api.ts +976 -0
  311. package/src/notion/state.ts +512 -0
  312. package/src/notion.ts +210 -0
  313. package/src/openai.ts +198 -0
  314. package/src/opencode-recordings.ts +257 -0
  315. package/src/opencode.ts +271 -0
  316. package/src/r2-fixtures.ts +295 -0
  317. package/src/r2-guard.ts +323 -0
  318. package/src/r2.ts +890 -0
  319. package/src/responses.ts +901 -0
  320. package/src/route-evidence.ts +90 -0
  321. package/src/router.ts +490 -0
  322. package/src/stateful-core.ts +70 -0
  323. package/src/stateful-emulator.ts +2571 -0
  324. package/src/stateful-secrets.ts +299 -0
  325. package/src/subscription-usage-recordings.ts +77 -0
  326. package/src/subscription-usage.ts +68 -0
  327. package/src/telegram/api.ts +437 -0
  328. package/src/telegram/state.ts +229 -0
  329. package/src/telegram.ts +227 -0
  330. package/src/todoist/api.ts +736 -0
  331. package/src/todoist/state.ts +456 -0
  332. package/src/todoist.ts +316 -0
  333. package/src/xai.ts +341 -0
@@ -0,0 +1,556 @@
1
+ import { emulatorRouteKey } from "./route-evidence.mjs";
2
+ import { ChunkCount, EmulatorErrorAfterChunksFault, EmulatorScriptedError, EmulatorStatusFault, EmulatorTruncateAfterChunksFault, approximateTokens, controlError, emulatorFaultFields, isJsonObject, jsonField, jsonResponse, makeEmulatorKernel, parseJson, readText, splitFragments, stringField, synthesizeValue } from "./emulator-kernel.mjs";
3
+ import { Predicate, Result } from "effect";
4
+ import * as Schema from "effect/Schema";
5
+ //#region src/responses.ts
6
+ /**
7
+ * OpenAI Responses emulator core (internal; not a package export).
8
+ *
9
+ * One `POST .../responses` route with request parsing (`model`, `input`, `instructions`, `tools`,
10
+ * `tool_choice`, `reasoning`, `stream`, `store`, `max_output_tokens`), Responses SSE with typed
11
+ * `event:` names in the order the API sends them, the non-streamed `response` JSON body, scripted
12
+ * turns, and a JSON error envelope chosen by each subpath. Faults, the request ledger, the
13
+ * `/_emulate/*` control plane, evidence tagging, and route binding come from the shared kernel
14
+ * (`emulator-kernel.ts`).
15
+ *
16
+ * Streamed responses: `response.created` and `response.in_progress`, then per output item
17
+ * `response.output_item.added`, its parts and deltas, and `response.output_item.done`, then
18
+ * `response.completed` with the full `response` (output items and usage). Output items:
19
+ * `reasoning` (one summary part: `response.reasoning_summary_part.added`,
20
+ * `response.reasoning_summary_text.delta` / `.done`, `response.reasoning_summary_part.done`) when
21
+ * the request asks for a reasoning summary, `message` (`response.content_part.added`,
22
+ * `response.output_text.delta` / `.done`, `response.content_part.done`), and `function_call`
23
+ * (`response.function_call_arguments.delta` / `.done`). Every event carries a `sequence_number`.
24
+ *
25
+ * Each subpath supplies its path and manifest, model list, error envelope and unknown-model
26
+ * status, the 401 error for a missing bearer credential, extra header rules (required headers
27
+ * with their status and error, and which non-credential header values the ledger records),
28
+ * whether `max_output_tokens` is accepted, and its input-invalid error. Bearer values are never
29
+ * checked or stored.
30
+ *
31
+ * Runtime-portable Web APIs only (`Request`, `Response`, `ReadableStream`, `TextEncoder`, `URL`);
32
+ * no Node builtins and no SDK imports.
33
+ */
34
+ /** A mid-stream Responses error: a machine `code` and a message. */
35
+ const ResponsesStreamError = Schema.Struct({
36
+ code: Schema.NonEmptyString,
37
+ message: Schema.String
38
+ });
39
+ /**
40
+ * Send `chunks` SSE events, then one error event and close without `response.completed`:
41
+ * `event: 'error'` (the default) sends `{ type: 'error', code, message }`, and
42
+ * `event: 'response.failed'` sends a `response.failed` event whose `response.error` carries the
43
+ * code and message. The error defaults to `server_error`. Streamed responses only; it must come
44
+ * before `response.completed`.
45
+ */
46
+ const ResponsesErrorEventFault = Schema.Struct({
47
+ kind: Schema.Literal("error-event-after-chunks"),
48
+ chunks: ChunkCount,
49
+ event: Schema.optionalKey(Schema.Literals(["error", "response.failed"])),
50
+ error: Schema.optionalKey(ResponsesStreamError),
51
+ ...emulatorFaultFields
52
+ });
53
+ /**
54
+ * Wire faults: `status` (the body defaults to the subpath's error envelope for the status),
55
+ * `error-after-chunks` (a dropped connection), `truncate-after-chunks` (a clean close, for example
56
+ * before `response.completed`), and `error-event-after-chunks` (a mid-stream `error` or
57
+ * `response.failed` event).
58
+ */
59
+ const ResponsesFault = Schema.Union([
60
+ EmulatorStatusFault,
61
+ EmulatorErrorAfterChunksFault,
62
+ EmulatorTruncateAfterChunksFault,
63
+ ResponsesErrorEventFault
64
+ ]);
65
+ const TokenCount = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
66
+ /** Usage for a scripted turn (sent in `response.completed` or the JSON body). */
67
+ const ResponsesScriptedUsage = Schema.Struct({
68
+ inputTokens: TokenCount,
69
+ outputTokens: TokenCount,
70
+ reasoningTokens: Schema.optionalKey(TokenCount)
71
+ });
72
+ /** One scripted `function_call` item; its arguments stream as these fragments. */
73
+ const ResponsesScriptedFunctionCall = Schema.Struct({
74
+ name: Schema.NonEmptyString,
75
+ argumentFragments: Schema.Array(Schema.String),
76
+ callId: Schema.optionalKey(Schema.NonEmptyString)
77
+ });
78
+ /**
79
+ * A scripted response. Every field is exact (nothing is filled in) except: an item is sent only
80
+ * when its field is present (`reasoning` is one summary part, `text` one message); `usage`
81
+ * omitted is synthesized and `null` drops `usage` from the wire; `order` defaults to
82
+ * `reasoning-first` (`text-first` sends the reasoning item after the message); `format` defaults
83
+ * to the request's `stream` (`sse` streams even for `stream: false`, `json` answers one JSON body
84
+ * even for `stream: true`, as the JSON fallback some endpoints use).
85
+ */
86
+ const ResponsesScriptedResponse = Schema.Struct({
87
+ reasoning: Schema.optionalKey(Schema.Array(Schema.String)),
88
+ text: Schema.optionalKey(Schema.Array(Schema.String)),
89
+ functionCalls: Schema.optionalKey(Schema.Array(ResponsesScriptedFunctionCall)),
90
+ order: Schema.optionalKey(Schema.Literals(["reasoning-first", "text-first"])),
91
+ usage: Schema.optionalKey(Schema.NullOr(ResponsesScriptedUsage)),
92
+ format: Schema.optionalKey(Schema.Literals(["sse", "json"]))
93
+ });
94
+ /** A turn queued for the next Responses request. */
95
+ const ResponsesScriptedTurn = Schema.Union([EmulatorScriptedError, ResponsesScriptedResponse]);
96
+ const ResponsesTool = Schema.Struct({
97
+ type: Schema.optionalKey(Schema.String),
98
+ name: Schema.optionalKey(Schema.String),
99
+ description: Schema.optionalKey(Schema.NullOr(Schema.String)),
100
+ parameters: Schema.optionalKey(Schema.Json)
101
+ });
102
+ const ResponsesRequest = Schema.Struct({
103
+ model: Schema.optionalKey(Schema.String),
104
+ input: Schema.Union([Schema.String, Schema.Array(Schema.Json)]),
105
+ instructions: Schema.optionalKey(Schema.NullOr(Schema.String)),
106
+ tools: Schema.optionalKey(Schema.NullOr(Schema.Array(ResponsesTool))),
107
+ tool_choice: Schema.optionalKey(Schema.Json),
108
+ reasoning: Schema.optionalKey(Schema.Json),
109
+ stream: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
110
+ store: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),
111
+ max_output_tokens: Schema.optionalKey(Schema.Json)
112
+ });
113
+ const decodeResponsesRequest = Schema.decodeUnknownResult(ResponsesRequest);
114
+ const syntheticCreated = 179e7;
115
+ const bearerPattern = /^bearer\s+\S+/i;
116
+ const defaultReasoning = ["The user wants a short reply.", " Keep it brief."];
117
+ const defaultStreamError = {
118
+ code: "server_error",
119
+ message: "Synthetic: the server had an error while processing the request."
120
+ };
121
+ /** A reasoning summary is streamed when the request's `reasoning` asks for one. */
122
+ const summaryRequested = (request) => {
123
+ const summary = stringField(request.reasoning, "summary");
124
+ return summary !== void 0 && summary.length > 0;
125
+ };
126
+ const functionTools = (request) => (request.tools ?? []).flatMap((tool) => (tool.type === void 0 || tool.type === "function") && tool.name !== void 0 ? [{
127
+ name: tool.name,
128
+ parameters: tool.parameters
129
+ }] : []);
130
+ const chosenTool = (request) => {
131
+ const tools = functionTools(request);
132
+ if (tools.length === 0 || request.tool_choice === "none") return;
133
+ const forced = stringField(request.tool_choice, "type") === "function" ? stringField(request.tool_choice, "name") : void 0;
134
+ return tools.find((tool) => tool.name === forced) ?? tools[0];
135
+ };
136
+ const defaultPlan = (request, seq, defaultText) => {
137
+ const reasoning = summaryRequested(request) ? [{
138
+ type: "reasoning",
139
+ id: `rs_synthetic_${seq}_0`,
140
+ fragments: defaultReasoning
141
+ }] : [];
142
+ const tool = chosenTool(request);
143
+ if (tool === void 0) return {
144
+ items: [...reasoning, {
145
+ type: "message",
146
+ id: `msg_synthetic_${seq}_0`,
147
+ fragments: defaultText
148
+ }],
149
+ usage: void 0,
150
+ format: void 0
151
+ };
152
+ const argumentsText = JSON.stringify(synthesizeValue(tool.parameters ?? { type: "object" }, tool.name, 0));
153
+ return {
154
+ items: [...reasoning, {
155
+ type: "function_call",
156
+ id: `fc_synthetic_${seq}_0`,
157
+ callId: `call_synthetic_${seq}_0`,
158
+ name: tool.name,
159
+ fragments: splitFragments(argumentsText, 3)
160
+ }],
161
+ usage: void 0,
162
+ format: void 0
163
+ };
164
+ };
165
+ const scriptedPlan = (turn, seq) => {
166
+ const reasoning = turn.reasoning === void 0 ? [] : [{
167
+ type: "reasoning",
168
+ id: `rs_synthetic_${seq}_0`,
169
+ fragments: turn.reasoning
170
+ }];
171
+ const message = turn.text === void 0 ? [] : [{
172
+ type: "message",
173
+ id: `msg_synthetic_${seq}_0`,
174
+ fragments: turn.text
175
+ }];
176
+ const calls = (turn.functionCalls ?? []).map((call, index) => ({
177
+ type: "function_call",
178
+ id: `fc_synthetic_${seq}_${index}`,
179
+ callId: call.callId ?? `call_synthetic_${seq}_${index}`,
180
+ name: call.name,
181
+ fragments: call.argumentFragments
182
+ }));
183
+ return {
184
+ items: turn.order === "text-first" ? [
185
+ ...message,
186
+ ...reasoning,
187
+ ...calls
188
+ ] : [
189
+ ...reasoning,
190
+ ...message,
191
+ ...calls
192
+ ],
193
+ usage: turn.usage,
194
+ format: turn.format
195
+ };
196
+ };
197
+ const planUsage = (plan, requestText) => {
198
+ if (plan.usage === null) return;
199
+ const reasoningText = plan.items.flatMap((item) => item.type === "reasoning" ? item.fragments : []).join("");
200
+ const usage = plan.usage ?? {
201
+ inputTokens: approximateTokens(requestText),
202
+ outputTokens: approximateTokens(plan.items.flatMap((item) => item.fragments).join("")),
203
+ reasoningTokens: reasoningText.length > 0 ? approximateTokens(reasoningText) : 0
204
+ };
205
+ return {
206
+ input_tokens: usage.inputTokens,
207
+ input_tokens_details: { cached_tokens: 0 },
208
+ output_tokens: usage.outputTokens,
209
+ output_tokens_details: { reasoning_tokens: usage.reasoningTokens ?? 0 },
210
+ total_tokens: usage.inputTokens + usage.outputTokens
211
+ };
212
+ };
213
+ const responseObject = (identity, status, output) => ({
214
+ id: identity.id,
215
+ object: "response",
216
+ created_at: syntheticCreated,
217
+ status,
218
+ error: null,
219
+ incomplete_details: null,
220
+ model: identity.model,
221
+ output
222
+ });
223
+ const outputText = (text) => ({
224
+ type: "output_text",
225
+ text,
226
+ annotations: []
227
+ });
228
+ const summaryText = (text) => ({
229
+ type: "summary_text",
230
+ text
231
+ });
232
+ /** The complete wire item (as in `response.output_item.done` and the final `output`). */
233
+ const completeItem = (item) => {
234
+ const text = item.fragments.join("");
235
+ switch (item.type) {
236
+ case "reasoning": return {
237
+ id: item.id,
238
+ type: "reasoning",
239
+ summary: item.fragments.length === 0 ? [] : [summaryText(text)]
240
+ };
241
+ case "message": return {
242
+ id: item.id,
243
+ type: "message",
244
+ status: "completed",
245
+ role: "assistant",
246
+ content: [outputText(text)]
247
+ };
248
+ case "function_call": return {
249
+ id: item.id,
250
+ type: "function_call",
251
+ status: "completed",
252
+ call_id: item.callId,
253
+ name: item.name,
254
+ arguments: text
255
+ };
256
+ }
257
+ };
258
+ /** The item as first announced in `response.output_item.added`. */
259
+ const addedItem = (item) => {
260
+ switch (item.type) {
261
+ case "reasoning": return {
262
+ id: item.id,
263
+ type: "reasoning",
264
+ summary: []
265
+ };
266
+ case "message": return {
267
+ id: item.id,
268
+ type: "message",
269
+ status: "in_progress",
270
+ role: "assistant",
271
+ content: []
272
+ };
273
+ case "function_call": return {
274
+ id: item.id,
275
+ type: "function_call",
276
+ status: "in_progress",
277
+ call_id: item.callId,
278
+ name: item.name,
279
+ arguments: ""
280
+ };
281
+ }
282
+ };
283
+ const sseEvent = (type, sequence, payload) => `event: ${type}\ndata: ${JSON.stringify({
284
+ type,
285
+ sequence_number: sequence,
286
+ ...payload
287
+ })}\n\n`;
288
+ /** Builds SSE events with increasing `sequence_number`s, one network chunk each. */
289
+ const makeEventWriter = () => {
290
+ const events = [];
291
+ return {
292
+ events,
293
+ push: (type, payload) => {
294
+ events.push(sseEvent(type, events.length, payload));
295
+ }
296
+ };
297
+ };
298
+ const itemEvents = (writer, item, outputIndex) => {
299
+ const text = item.fragments.join("");
300
+ const ids = {
301
+ item_id: item.id,
302
+ output_index: outputIndex
303
+ };
304
+ writer.push("response.output_item.added", {
305
+ output_index: outputIndex,
306
+ item: addedItem(item)
307
+ });
308
+ switch (item.type) {
309
+ case "reasoning":
310
+ if (item.fragments.length > 0) {
311
+ const part = {
312
+ ...ids,
313
+ summary_index: 0
314
+ };
315
+ writer.push("response.reasoning_summary_part.added", {
316
+ ...part,
317
+ part: summaryText("")
318
+ });
319
+ for (const fragment of item.fragments) writer.push("response.reasoning_summary_text.delta", {
320
+ ...part,
321
+ delta: fragment
322
+ });
323
+ writer.push("response.reasoning_summary_text.done", {
324
+ ...part,
325
+ text
326
+ });
327
+ writer.push("response.reasoning_summary_part.done", {
328
+ ...part,
329
+ part: summaryText(text)
330
+ });
331
+ }
332
+ break;
333
+ case "message": {
334
+ const part = {
335
+ ...ids,
336
+ content_index: 0
337
+ };
338
+ writer.push("response.content_part.added", {
339
+ ...part,
340
+ part: outputText("")
341
+ });
342
+ for (const fragment of item.fragments) writer.push("response.output_text.delta", {
343
+ ...part,
344
+ delta: fragment
345
+ });
346
+ writer.push("response.output_text.done", {
347
+ ...part,
348
+ text
349
+ });
350
+ writer.push("response.content_part.done", {
351
+ ...part,
352
+ part: outputText(text)
353
+ });
354
+ break;
355
+ }
356
+ case "function_call":
357
+ for (const fragment of item.fragments) writer.push("response.function_call_arguments.delta", {
358
+ ...ids,
359
+ delta: fragment
360
+ });
361
+ writer.push("response.function_call_arguments.done", {
362
+ ...ids,
363
+ arguments: text
364
+ });
365
+ break;
366
+ }
367
+ writer.push("response.output_item.done", {
368
+ output_index: outputIndex,
369
+ item: completeItem(item)
370
+ });
371
+ };
372
+ /** The completed `response` object (for `response.completed` and the JSON body). */
373
+ const completedResponse = (plan, identity, usage) => {
374
+ const response = responseObject(identity, "completed", plan.items.map(completeItem));
375
+ if (usage !== void 0) response.usage = usage;
376
+ return response;
377
+ };
378
+ /** SSE events for a streamed response, one network chunk each, in the API's order. */
379
+ const streamEvents = (plan, identity, usage) => {
380
+ const writer = makeEventWriter();
381
+ const inProgress = {
382
+ ...responseObject(identity, "in_progress", []),
383
+ usage: null
384
+ };
385
+ writer.push("response.created", { response: inProgress });
386
+ writer.push("response.in_progress", { response: inProgress });
387
+ plan.items.forEach((item, index) => itemEvents(writer, item, index));
388
+ writer.push("response.completed", { response: completedResponse(plan, identity, usage) });
389
+ return writer.events;
390
+ };
391
+ /** The mid-stream error event of an `error-event-after-chunks` fault. */
392
+ const errorEvent = (fault, identity, sequence) => {
393
+ const error = fault.error ?? defaultStreamError;
394
+ if (fault.event === "response.failed") return sseEvent("response.failed", sequence, { response: {
395
+ ...responseObject(identity, "failed", []),
396
+ error: {
397
+ code: error.code,
398
+ message: error.message
399
+ },
400
+ usage: null
401
+ } });
402
+ return sseEvent("error", sequence, {
403
+ code: error.code,
404
+ message: error.message,
405
+ param: null
406
+ });
407
+ };
408
+ const isPositiveInteger = (value) => Predicate.isNumber(value) && Number.isSafeInteger(value) && value > 0;
409
+ /**
410
+ * Create a Responses emulator from its config. Each call has independent ledger, fault, and
411
+ * script state.
412
+ *
413
+ * Precedence per request: the bearer credential, the header rules in order, JSON and request
414
+ * validation (an `input` string or array, and the `max_output_tokens` policy), then the first
415
+ * matching fault if it is a `status` fault, then the next scripted turn, then model validation and
416
+ * defaults; a first matching body fault then shapes the body. Only the first matching fault (in
417
+ * insertion order) applies. Credential headers are never recorded, and credential values are
418
+ * never checked or stored.
419
+ */
420
+ const makeResponsesEmulator = (config) => {
421
+ const knownModels = [...config.knownModels];
422
+ const errorResponse = (status, error) => jsonResponse(status, config.errorEnvelope(error));
423
+ const invalidRequest = (message, code, param) => errorResponse(400, param === void 0 ? {
424
+ message,
425
+ type: "invalid_request_error",
426
+ code
427
+ } : {
428
+ message,
429
+ type: "invalid_request_error",
430
+ code,
431
+ param
432
+ });
433
+ const defaultFaultBody = (status) => status === 429 ? config.errorEnvelope({
434
+ message: "Synthetic rate limit: too many requests.",
435
+ type: "rate_limit_exceeded",
436
+ code: "rate_limit_exceeded"
437
+ }) : config.errorEnvelope({
438
+ message: `Synthetic upstream error (${status}).`,
439
+ type: status >= 500 ? "server_error" : "api_error",
440
+ code: status >= 500 ? "server_error" : "upstream_error"
441
+ });
442
+ const kernel = makeEmulatorKernel({
443
+ routes: config.routes,
444
+ faultSchema: ResponsesFault,
445
+ turnSchema: ResponsesScriptedTurn,
446
+ newEntry: (base) => ({
447
+ ...base,
448
+ toolNames: [],
449
+ headers: {}
450
+ }),
451
+ snapshotEntry: (entry) => ({
452
+ ...entry,
453
+ toolNames: [...entry.toolNames],
454
+ headers: { ...entry.headers }
455
+ }),
456
+ unknownRoute: () => errorResponse(404, {
457
+ message: "Synthetic: no emulated route.",
458
+ type: "invalid_request_error",
459
+ code: "not_found"
460
+ }),
461
+ stateFields: () => ({ knownModels }),
462
+ inputInvalid: config.inputInvalid
463
+ });
464
+ const responses = async (request, entry, path) => {
465
+ for (const rule of config.headers) {
466
+ const value = request.headers.get(rule.name);
467
+ if (rule.record && value !== null) entry.headers[rule.name] = value;
468
+ }
469
+ if (!bearerPattern.test(request.headers.get("authorization") ?? "")) {
470
+ entry.status = 401;
471
+ return errorResponse(401, config.unauthorized);
472
+ }
473
+ for (const rule of config.headers) if (rule.required !== void 0 && (request.headers.get(rule.name) ?? "").trim().length === 0) {
474
+ entry.status = rule.required.status;
475
+ return errorResponse(rule.required.status, rule.required.error);
476
+ }
477
+ const text = await readText(request);
478
+ const json = text === void 0 ? void 0 : parseJson(text);
479
+ if (text === void 0 || json === void 0) {
480
+ entry.status = 400;
481
+ return invalidRequest("Synthetic: the request body is not valid JSON.", "invalid_json");
482
+ }
483
+ entry.body = json;
484
+ const decoded = decodeResponsesRequest(json);
485
+ if (Result.isFailure(decoded) || !isJsonObject(json)) {
486
+ entry.status = 400;
487
+ return invalidRequest("Synthetic: the request body is not a Responses request (`input` is required).", "invalid_request");
488
+ }
489
+ const body = decoded.success;
490
+ const seq = entry.seq;
491
+ if (body.model !== void 0) entry.model = body.model;
492
+ entry.stream = body.stream === true;
493
+ if (Predicate.isBoolean(body.store)) entry.store = body.store;
494
+ if (body.reasoning !== void 0) entry.reasoning = body.reasoning;
495
+ if (body.tool_choice !== void 0) entry.toolChoice = body.tool_choice;
496
+ entry.toolNames = functionTools(body).map((tool) => tool.name);
497
+ const outputLimit = jsonField(json, "max_output_tokens");
498
+ if (Predicate.isNumber(outputLimit)) entry.maxOutputTokens = outputLimit;
499
+ if (config.outputTokenLimit === "rejected" && outputLimit !== void 0) {
500
+ entry.status = 400;
501
+ return invalidRequest("Synthetic: unsupported parameter: max_output_tokens.", "unsupported_parameter", "max_output_tokens");
502
+ }
503
+ if (outputLimit !== void 0 && outputLimit !== null && !isPositiveInteger(outputLimit)) {
504
+ entry.status = 400;
505
+ return invalidRequest("Synthetic: max_output_tokens must be a positive integer.", "invalid_value", "max_output_tokens");
506
+ }
507
+ const fault = kernel.takeFault(path, body.model);
508
+ if (fault !== void 0 && fault.fault.kind === "status") return kernel.respondWithStatusFault(entry, fault, fault.fault, defaultFaultBody);
509
+ const errorEventFault = fault !== void 0 && fault.fault.kind === "error-event-after-chunks" ? {
510
+ state: fault,
511
+ fault: fault.fault
512
+ } : void 0;
513
+ const cannotApply = (problem) => {
514
+ entry.faultError = problem;
515
+ entry.status = 500;
516
+ return controlError(500, `emulator fault cannot apply: ${problem}`);
517
+ };
518
+ const turn = kernel.nextTurn();
519
+ if (turn !== void 0 && "error" in turn) {
520
+ entry.scripted = "error";
521
+ if (errorEventFault !== void 0) return cannotApply("error-event-after-chunks cannot apply to a scripted error");
522
+ return kernel.respondWithScriptedError(entry, turn.error, fault);
523
+ }
524
+ if (turn === void 0 && (body.model === void 0 || !knownModels.includes(body.model))) {
525
+ entry.status = config.unknownModel.status;
526
+ return errorResponse(config.unknownModel.status, config.unknownModel.error);
527
+ }
528
+ if (turn !== void 0) entry.scripted = "response";
529
+ const plan = turn === void 0 ? defaultPlan(body, seq, config.defaultText) : scriptedPlan(turn, seq);
530
+ const identity = {
531
+ id: `resp_synthetic_${seq}`,
532
+ model: body.model ?? "unknown"
533
+ };
534
+ const usage = planUsage(plan, text);
535
+ if ((plan.format ?? (body.stream === true ? "sse" : "json")) === "json") {
536
+ if (errorEventFault !== void 0) return cannotApply("error-event-after-chunks cannot apply to a JSON response");
537
+ return kernel.respondWithBody(entry, 200, { "content-type": "application/json" }, [JSON.stringify(completedResponse(plan, identity, usage))], fault);
538
+ }
539
+ const events = streamEvents(plan, identity, usage);
540
+ const headers = {
541
+ "content-type": "text/event-stream",
542
+ "cache-control": "no-cache"
543
+ };
544
+ if (errorEventFault === void 0) return kernel.respondWithBody(entry, 200, headers, events, fault);
545
+ const after = errorEventFault.fault.chunks;
546
+ if (after >= events.length) return cannotApply(`error-event-after-chunks after ${after} chunk(s) cannot apply to a response with ${events.length} chunk(s)`);
547
+ const response = kernel.respondWithBody(entry, 200, headers, [...events.slice(0, after), errorEvent(errorEventFault.fault, identity, after)], void 0);
548
+ kernel.consumeFault(errorEventFault.state, entry);
549
+ return response;
550
+ };
551
+ return kernel.serve(new Map([[emulatorRouteKey("POST", config.path), responses]]));
552
+ };
553
+ //#endregion
554
+ export { ResponsesErrorEventFault, ResponsesFault, ResponsesScriptedFunctionCall, ResponsesScriptedResponse, ResponsesScriptedTurn, ResponsesScriptedUsage, ResponsesStreamError, makeResponsesEmulator };
555
+
556
+ //# sourceMappingURL=responses.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.mjs","names":[],"sources":["../src/responses.ts"],"sourcesContent":["/**\n * OpenAI Responses emulator core (internal; not a package export).\n *\n * One `POST .../responses` route with request parsing (`model`, `input`, `instructions`, `tools`,\n * `tool_choice`, `reasoning`, `stream`, `store`, `max_output_tokens`), Responses SSE with typed\n * `event:` names in the order the API sends them, the non-streamed `response` JSON body, scripted\n * turns, and a JSON error envelope chosen by each subpath. Faults, the request ledger, the\n * `/_emulate/*` control plane, evidence tagging, and route binding come from the shared kernel\n * (`emulator-kernel.ts`).\n *\n * Streamed responses: `response.created` and `response.in_progress`, then per output item\n * `response.output_item.added`, its parts and deltas, and `response.output_item.done`, then\n * `response.completed` with the full `response` (output items and usage). Output items:\n * `reasoning` (one summary part: `response.reasoning_summary_part.added`,\n * `response.reasoning_summary_text.delta` / `.done`, `response.reasoning_summary_part.done`) when\n * the request asks for a reasoning summary, `message` (`response.content_part.added`,\n * `response.output_text.delta` / `.done`, `response.content_part.done`), and `function_call`\n * (`response.function_call_arguments.delta` / `.done`). Every event carries a `sequence_number`.\n *\n * Each subpath supplies its path and manifest, model list, error envelope and unknown-model\n * status, the 401 error for a missing bearer credential, extra header rules (required headers\n * with their status and error, and which non-credential header values the ledger records),\n * whether `max_output_tokens` is accepted, and its input-invalid error. Bearer values are never\n * checked or stored.\n *\n * Runtime-portable Web APIs only (`Request`, `Response`, `ReadableStream`, `TextEncoder`, `URL`);\n * no Node builtins and no SDK imports.\n */\nimport { Predicate, Result } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport {\n approximateTokens,\n ChunkCount,\n controlError,\n EmulatorErrorAfterChunksFault,\n emulatorFaultFields,\n EmulatorScriptedError,\n EmulatorStatusFault,\n EmulatorTruncateAfterChunksFault,\n isJsonObject,\n jsonField,\n jsonResponse,\n makeEmulatorKernel,\n parseJson,\n readText,\n splitFragments,\n stringField,\n synthesizeValue,\n type EmulatorApi,\n type KernelLedgerEntry\n} from './emulator-kernel.ts'\nimport {\n emulatorRouteKey,\n type EmulatorEvidence,\n type EmulatorRouteEvidence\n} from './route-evidence.ts'\n\n/** A mid-stream Responses error: a machine `code` and a message. */\nexport const ResponsesStreamError = Schema.Struct({\n code: Schema.NonEmptyString,\n message: Schema.String\n})\n\nexport type ResponsesStreamError = typeof ResponsesStreamError.Type\n\n/**\n * Send `chunks` SSE events, then one error event and close without `response.completed`:\n * `event: 'error'` (the default) sends `{ type: 'error', code, message }`, and\n * `event: 'response.failed'` sends a `response.failed` event whose `response.error` carries the\n * code and message. The error defaults to `server_error`. Streamed responses only; it must come\n * before `response.completed`.\n */\nexport const ResponsesErrorEventFault = Schema.Struct({\n kind: Schema.Literal('error-event-after-chunks'),\n chunks: ChunkCount,\n event: Schema.optionalKey(Schema.Literals(['error', 'response.failed'])),\n error: Schema.optionalKey(ResponsesStreamError),\n ...emulatorFaultFields\n})\n\n/**\n * Wire faults: `status` (the body defaults to the subpath's error envelope for the status),\n * `error-after-chunks` (a dropped connection), `truncate-after-chunks` (a clean close, for example\n * before `response.completed`), and `error-event-after-chunks` (a mid-stream `error` or\n * `response.failed` event).\n */\nexport const ResponsesFault = Schema.Union([\n EmulatorStatusFault,\n EmulatorErrorAfterChunksFault,\n EmulatorTruncateAfterChunksFault,\n ResponsesErrorEventFault\n])\n\nexport type ResponsesFault = typeof ResponsesFault.Type\n\nexport type ResponsesFaultKind = ResponsesFault['kind']\n\nconst TokenCount = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0))\n\n/** Usage for a scripted turn (sent in `response.completed` or the JSON body). */\nexport const ResponsesScriptedUsage = Schema.Struct({\n inputTokens: TokenCount,\n outputTokens: TokenCount,\n reasoningTokens: Schema.optionalKey(TokenCount)\n})\n\nexport type ResponsesScriptedUsage = typeof ResponsesScriptedUsage.Type\n\n/** One scripted `function_call` item; its arguments stream as these fragments. */\nexport const ResponsesScriptedFunctionCall = Schema.Struct({\n name: Schema.NonEmptyString,\n argumentFragments: Schema.Array(Schema.String),\n callId: Schema.optionalKey(Schema.NonEmptyString)\n})\n\nexport type ResponsesScriptedFunctionCall = typeof ResponsesScriptedFunctionCall.Type\n\n/**\n * A scripted response. Every field is exact (nothing is filled in) except: an item is sent only\n * when its field is present (`reasoning` is one summary part, `text` one message); `usage`\n * omitted is synthesized and `null` drops `usage` from the wire; `order` defaults to\n * `reasoning-first` (`text-first` sends the reasoning item after the message); `format` defaults\n * to the request's `stream` (`sse` streams even for `stream: false`, `json` answers one JSON body\n * even for `stream: true`, as the JSON fallback some endpoints use).\n */\nexport const ResponsesScriptedResponse = Schema.Struct({\n reasoning: Schema.optionalKey(Schema.Array(Schema.String)),\n text: Schema.optionalKey(Schema.Array(Schema.String)),\n functionCalls: Schema.optionalKey(Schema.Array(ResponsesScriptedFunctionCall)),\n order: Schema.optionalKey(Schema.Literals(['reasoning-first', 'text-first'])),\n usage: Schema.optionalKey(Schema.NullOr(ResponsesScriptedUsage)),\n format: Schema.optionalKey(Schema.Literals(['sse', 'json']))\n})\n\nexport type ResponsesScriptedResponse = typeof ResponsesScriptedResponse.Type\n\n/** A turn queued for the next Responses request. */\nexport const ResponsesScriptedTurn = Schema.Union([\n EmulatorScriptedError,\n ResponsesScriptedResponse\n])\n\nexport type ResponsesScriptedTurn = typeof ResponsesScriptedTurn.Type\n\nexport type ResponsesLedgerEntry = {\n /** 1-based arrival order since the last ledger clear or reset. */\n readonly seq: number\n readonly method: string\n readonly path: string\n /** Parsed JSON request body, when it was valid JSON. */\n readonly body?: Schema.Json\n readonly model?: string\n readonly stream?: boolean\n readonly store?: boolean\n /** The request's `max_output_tokens`, when it is a number. */\n readonly maxOutputTokens?: number\n readonly reasoning?: Schema.Json\n readonly toolChoice?: Schema.Json\n /** Names of the offered `function` tools. */\n readonly toolNames: ReadonlyArray<string>\n /** Values of the non-credential headers the subpath records (lower-case names). */\n readonly headers: Readonly<Record<string, string>>\n /** Kind of the fault that shaped the response. */\n readonly fault?: ResponsesFaultKind\n /** Why a matching fault could not take effect (the response was a 500 emulator error). */\n readonly faultError?: string\n /**\n * Set when the emulator could not build the planned response; the request was answered with a\n * 500 emulator error (still evidence-tagged) and no fault was used up.\n */\n readonly responseError?: string\n /** Set when a scripted turn answered the request. */\n readonly scripted?: 'response' | 'error'\n /** Evidence of the matched route; `unknown-route` for requests that failed closed. */\n readonly evidence: EmulatorEvidence | 'unknown-route'\n readonly status: number\n /** Body chunks handed to the transport so far (each produced when pulled). */\n readonly bodyChunks: number\n}\n\nexport type ResponsesEmulator = EmulatorApi<\n ResponsesScriptedTurn,\n ResponsesFault,\n ResponsesLedgerEntry\n>\n\n/** A Responses wire error, rendered by the subpath's `errorEnvelope`. */\nexport type ResponsesWireError = {\n readonly message: string\n readonly type: string\n readonly code: string\n readonly param?: string\n}\n\n/**\n * One request header rule. `record` keeps the header value in the ledger `headers` (never set it\n * for credential headers); `required` answers a request without a non-empty value with that\n * status and error (the value itself is never checked).\n */\nexport type ResponsesHeaderRule = {\n /** Lower-case header name. */\n readonly name: string\n readonly record: boolean\n readonly required?: { readonly status: number; readonly error: ResponsesWireError }\n}\n\n/**\n * What differs between Responses emulators. The core owns everything else (framing, faults,\n * scripting, ledger, control plane, evidence).\n */\nexport type ResponsesEmulatorConfig = {\n /** The Responses path, for example `/v1/responses`. */\n readonly path: string\n /** Route evidence manifest; must list exactly the Responses route. */\n readonly routes: ReadonlyArray<EmulatorRouteEvidence>\n readonly knownModels: ReadonlyArray<string>\n /** Renders a wire error as the service's JSON error envelope. */\n readonly errorEnvelope: (error: ResponsesWireError) => Schema.Json\n /** Status and error for an unknown model id. */\n readonly unknownModel: { readonly status: number; readonly error: ResponsesWireError }\n /**\n * Requests authenticate with a non-empty `Authorization: Bearer` credential, never checked or\n * stored; anything else answers 401 with `unauthorized`.\n */\n readonly unauthorized: ResponsesWireError\n /** Extra header rules, checked in order after the bearer credential. */\n readonly headers: ReadonlyArray<ResponsesHeaderRule>\n /**\n * `optional`: `max_output_tokens` may be sent (a positive integer, or 400) and is recorded, not\n * enforced; `rejected`: any `max_output_tokens` answers 400 `unsupported_parameter`.\n */\n readonly outputTokenLimit: 'optional' | 'rejected'\n /** Default answer text deltas. */\n readonly defaultText: ReadonlyArray<string>\n /** Builds the error thrown by the JS API (`faults.add`, `script.enqueue`) for invalid input. */\n readonly inputInvalid: (input: 'fault' | 'turn', reason: string) => Error\n}\n\nconst ResponsesTool = Schema.Struct({\n type: Schema.optionalKey(Schema.String),\n name: Schema.optionalKey(Schema.String),\n description: Schema.optionalKey(Schema.NullOr(Schema.String)),\n parameters: Schema.optionalKey(Schema.Json)\n})\n\nconst ResponsesRequest = Schema.Struct({\n model: Schema.optionalKey(Schema.String),\n input: Schema.Union([Schema.String, Schema.Array(Schema.Json)]),\n instructions: Schema.optionalKey(Schema.NullOr(Schema.String)),\n tools: Schema.optionalKey(Schema.NullOr(Schema.Array(ResponsesTool))),\n tool_choice: Schema.optionalKey(Schema.Json),\n reasoning: Schema.optionalKey(Schema.Json),\n stream: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),\n store: Schema.optionalKey(Schema.NullOr(Schema.Boolean)),\n max_output_tokens: Schema.optionalKey(Schema.Json)\n})\n\ntype ResponsesRequest = typeof ResponsesRequest.Type\n\nconst decodeResponsesRequest = Schema.decodeUnknownResult(ResponsesRequest)\n\n// Synthetic creation time shared by every emulated response (deterministic output).\nconst syntheticCreated = 1790000000\n\n// A non-empty bearer credential. The value is never checked or stored.\nconst bearerPattern = /^bearer\\s+\\S+/i\n\nconst defaultReasoning = ['The user wants a short reply.', ' Keep it brief.']\n\nconst defaultStreamError: ResponsesStreamError = {\n code: 'server_error',\n message: 'Synthetic: the server had an error while processing the request.'\n}\n\ntype ItemPlan =\n | { readonly type: 'reasoning'; readonly id: string; readonly fragments: ReadonlyArray<string> }\n | { readonly type: 'message'; readonly id: string; readonly fragments: ReadonlyArray<string> }\n | {\n readonly type: 'function_call'\n readonly id: string\n readonly callId: string\n readonly name: string\n readonly fragments: ReadonlyArray<string>\n }\n\ntype ResponsePlan = {\n readonly items: ReadonlyArray<ItemPlan>\n /** `null`: never send usage; `undefined`: synthesize. */\n readonly usage: ResponsesScriptedUsage | null | undefined\n /** `undefined`: follow the request's `stream`. */\n readonly format: 'sse' | 'json' | undefined\n}\n\n/** A reasoning summary is streamed when the request's `reasoning` asks for one. */\nconst summaryRequested = (request: ResponsesRequest): boolean => {\n const summary = stringField(request.reasoning, 'summary')\n\n return summary !== undefined && summary.length > 0\n}\n\nconst functionTools = (request: ResponsesRequest) =>\n (request.tools ?? []).flatMap(tool =>\n (tool.type === undefined || tool.type === 'function') && tool.name !== undefined\n ? [{ name: tool.name, parameters: tool.parameters }]\n : []\n )\n\nconst chosenTool = (request: ResponsesRequest) => {\n const tools = functionTools(request)\n\n if (tools.length === 0 || request.tool_choice === 'none') {\n return undefined\n }\n\n const forced =\n stringField(request.tool_choice, 'type') === 'function'\n ? stringField(request.tool_choice, 'name')\n : undefined\n\n return tools.find(tool => tool.name === forced) ?? tools[0]\n}\n\nconst defaultPlan = (\n request: ResponsesRequest,\n seq: number,\n defaultText: ReadonlyArray<string>\n): ResponsePlan => {\n const reasoning: ReadonlyArray<ItemPlan> = summaryRequested(request)\n ? [{ type: 'reasoning', id: `rs_synthetic_${seq}_0`, fragments: defaultReasoning }]\n : []\n\n const tool = chosenTool(request)\n\n if (tool === undefined) {\n return {\n items: [\n ...reasoning,\n { type: 'message', id: `msg_synthetic_${seq}_0`, fragments: defaultText }\n ],\n usage: undefined,\n format: undefined\n }\n }\n\n const argumentsText = JSON.stringify(\n synthesizeValue(tool.parameters ?? { type: 'object' }, tool.name, 0)\n )\n\n return {\n items: [\n ...reasoning,\n {\n type: 'function_call',\n id: `fc_synthetic_${seq}_0`,\n callId: `call_synthetic_${seq}_0`,\n name: tool.name,\n fragments: splitFragments(argumentsText, 3)\n }\n ],\n usage: undefined,\n format: undefined\n }\n}\n\nconst scriptedPlan = (turn: ResponsesScriptedResponse, seq: number): ResponsePlan => {\n const reasoning: ReadonlyArray<ItemPlan> =\n turn.reasoning === undefined\n ? []\n : [{ type: 'reasoning', id: `rs_synthetic_${seq}_0`, fragments: turn.reasoning }]\n\n const message: ReadonlyArray<ItemPlan> =\n turn.text === undefined\n ? []\n : [{ type: 'message', id: `msg_synthetic_${seq}_0`, fragments: turn.text }]\n\n const calls = (turn.functionCalls ?? []).map((call, index): ItemPlan => ({\n type: 'function_call',\n id: `fc_synthetic_${seq}_${index}`,\n callId: call.callId ?? `call_synthetic_${seq}_${index}`,\n name: call.name,\n fragments: call.argumentFragments\n }))\n\n return {\n items:\n turn.order === 'text-first'\n ? [...message, ...reasoning, ...calls]\n : [...reasoning, ...message, ...calls],\n usage: turn.usage,\n format: turn.format\n }\n}\n\ntype WireUsage = {\n readonly input_tokens: number\n readonly input_tokens_details: { readonly cached_tokens: number }\n readonly output_tokens: number\n readonly output_tokens_details: { readonly reasoning_tokens: number }\n readonly total_tokens: number\n}\n\ntype WireResponse = {\n readonly id: string\n readonly object: 'response'\n readonly created_at: number\n readonly status: 'in_progress' | 'completed' | 'failed'\n readonly error: Schema.JsonObject | null\n readonly incomplete_details: null\n readonly model: string\n readonly output: ReadonlyArray<Schema.JsonObject>\n usage?: WireUsage | null\n}\n\nconst planUsage = (plan: ResponsePlan, requestText: string): WireUsage | undefined => {\n if (plan.usage === null) {\n return undefined\n }\n\n const reasoningText = plan.items\n .flatMap(item => (item.type === 'reasoning' ? item.fragments : []))\n .join('')\n\n const usage = plan.usage ?? {\n inputTokens: approximateTokens(requestText),\n outputTokens: approximateTokens(plan.items.flatMap(item => item.fragments).join('')),\n reasoningTokens: reasoningText.length > 0 ? approximateTokens(reasoningText) : 0\n }\n\n return {\n input_tokens: usage.inputTokens,\n input_tokens_details: { cached_tokens: 0 },\n output_tokens: usage.outputTokens,\n output_tokens_details: { reasoning_tokens: usage.reasoningTokens ?? 0 },\n total_tokens: usage.inputTokens + usage.outputTokens\n }\n}\n\ntype ResponseIdentity = { readonly id: string; readonly model: string }\n\nconst responseObject = (\n identity: ResponseIdentity,\n status: WireResponse['status'],\n output: ReadonlyArray<Schema.JsonObject>\n): WireResponse => ({\n id: identity.id,\n object: 'response',\n created_at: syntheticCreated,\n status,\n error: null,\n incomplete_details: null,\n model: identity.model,\n output\n})\n\nconst outputText = (text: string): Schema.JsonObject => ({\n type: 'output_text',\n text,\n annotations: []\n})\n\nconst summaryText = (text: string): Schema.JsonObject => ({ type: 'summary_text', text })\n\n/** The complete wire item (as in `response.output_item.done` and the final `output`). */\nconst completeItem = (item: ItemPlan): Schema.JsonObject => {\n const text = item.fragments.join('')\n\n switch (item.type) {\n case 'reasoning':\n return {\n id: item.id,\n type: 'reasoning',\n summary: item.fragments.length === 0 ? [] : [summaryText(text)]\n }\n case 'message':\n return {\n id: item.id,\n type: 'message',\n status: 'completed',\n role: 'assistant',\n content: [outputText(text)]\n }\n case 'function_call':\n return {\n id: item.id,\n type: 'function_call',\n status: 'completed',\n call_id: item.callId,\n name: item.name,\n arguments: text\n }\n }\n}\n\n/** The item as first announced in `response.output_item.added`. */\nconst addedItem = (item: ItemPlan): Schema.JsonObject => {\n switch (item.type) {\n case 'reasoning':\n return { id: item.id, type: 'reasoning', summary: [] }\n case 'message':\n return {\n id: item.id,\n type: 'message',\n status: 'in_progress',\n role: 'assistant',\n content: []\n }\n case 'function_call':\n return {\n id: item.id,\n type: 'function_call',\n status: 'in_progress',\n call_id: item.callId,\n name: item.name,\n arguments: ''\n }\n }\n}\n\nconst sseEvent = (type: string, sequence: number, payload: object): string =>\n `event: ${type}\\ndata: ${JSON.stringify({ type, sequence_number: sequence, ...payload })}\\n\\n`\n\ntype EventWriter = {\n readonly events: Array<string>\n readonly push: (type: string, payload: object) => void\n}\n\n/** Builds SSE events with increasing `sequence_number`s, one network chunk each. */\nconst makeEventWriter = (): EventWriter => {\n const events: Array<string> = []\n\n return {\n events,\n push: (type, payload) => {\n events.push(sseEvent(type, events.length, payload))\n }\n }\n}\n\nconst itemEvents = (writer: EventWriter, item: ItemPlan, outputIndex: number) => {\n const text = item.fragments.join('')\n const ids = { item_id: item.id, output_index: outputIndex }\n\n writer.push('response.output_item.added', { output_index: outputIndex, item: addedItem(item) })\n\n switch (item.type) {\n case 'reasoning': {\n if (item.fragments.length > 0) {\n const part = { ...ids, summary_index: 0 }\n\n writer.push('response.reasoning_summary_part.added', { ...part, part: summaryText('') })\n\n for (const fragment of item.fragments) {\n writer.push('response.reasoning_summary_text.delta', { ...part, delta: fragment })\n }\n\n writer.push('response.reasoning_summary_text.done', { ...part, text })\n writer.push('response.reasoning_summary_part.done', { ...part, part: summaryText(text) })\n }\n\n break\n }\n\n case 'message': {\n const part = { ...ids, content_index: 0 }\n\n writer.push('response.content_part.added', { ...part, part: outputText('') })\n\n for (const fragment of item.fragments) {\n writer.push('response.output_text.delta', { ...part, delta: fragment })\n }\n\n writer.push('response.output_text.done', { ...part, text })\n writer.push('response.content_part.done', { ...part, part: outputText(text) })\n break\n }\n\n case 'function_call': {\n for (const fragment of item.fragments) {\n writer.push('response.function_call_arguments.delta', { ...ids, delta: fragment })\n }\n\n writer.push('response.function_call_arguments.done', { ...ids, arguments: text })\n break\n }\n }\n\n writer.push('response.output_item.done', { output_index: outputIndex, item: completeItem(item) })\n}\n\n/** The completed `response` object (for `response.completed` and the JSON body). */\nconst completedResponse = (\n plan: ResponsePlan,\n identity: ResponseIdentity,\n usage: WireUsage | undefined\n): WireResponse => {\n const response = responseObject(identity, 'completed', plan.items.map(completeItem))\n\n if (usage !== undefined) {\n response.usage = usage\n }\n\n return response\n}\n\n/** SSE events for a streamed response, one network chunk each, in the API's order. */\nconst streamEvents = (\n plan: ResponsePlan,\n identity: ResponseIdentity,\n usage: WireUsage | undefined\n): ReadonlyArray<string> => {\n const writer = makeEventWriter()\n const inProgress: WireResponse = { ...responseObject(identity, 'in_progress', []), usage: null }\n\n writer.push('response.created', { response: inProgress })\n writer.push('response.in_progress', { response: inProgress })\n\n plan.items.forEach((item, index) => itemEvents(writer, item, index))\n\n writer.push('response.completed', { response: completedResponse(plan, identity, usage) })\n\n return writer.events\n}\n\n/** The mid-stream error event of an `error-event-after-chunks` fault. */\nconst errorEvent = (\n fault: typeof ResponsesErrorEventFault.Type,\n identity: ResponseIdentity,\n sequence: number\n): string => {\n const error = fault.error ?? defaultStreamError\n\n if (fault.event === 'response.failed') {\n return sseEvent('response.failed', sequence, {\n response: {\n ...responseObject(identity, 'failed', []),\n error: { code: error.code, message: error.message },\n usage: null\n }\n })\n }\n\n return sseEvent('error', sequence, { code: error.code, message: error.message, param: null })\n}\n\ntype MutableLedgerEntry = KernelLedgerEntry<ResponsesFaultKind> & {\n body?: Schema.Json\n model?: string\n stream?: boolean\n store?: boolean\n maxOutputTokens?: number\n reasoning?: Schema.Json\n toolChoice?: Schema.Json\n toolNames: ReadonlyArray<string>\n headers: Record<string, string>\n scripted?: 'response' | 'error'\n}\n\nconst isPositiveInteger = (value: Schema.Json | undefined): value is number =>\n Predicate.isNumber(value) && Number.isSafeInteger(value) && value > 0\n\n/**\n * Create a Responses emulator from its config. Each call has independent ledger, fault, and\n * script state.\n *\n * Precedence per request: the bearer credential, the header rules in order, JSON and request\n * validation (an `input` string or array, and the `max_output_tokens` policy), then the first\n * matching fault if it is a `status` fault, then the next scripted turn, then model validation and\n * defaults; a first matching body fault then shapes the body. Only the first matching fault (in\n * insertion order) applies. Credential headers are never recorded, and credential values are\n * never checked or stored.\n */\nexport const makeResponsesEmulator = (config: ResponsesEmulatorConfig): ResponsesEmulator => {\n const knownModels = [...config.knownModels]\n\n const errorResponse = (status: number, error: ResponsesWireError): Response =>\n jsonResponse(status, config.errorEnvelope(error))\n\n const invalidRequest = (message: string, code: string, param?: string): Response =>\n errorResponse(\n 400,\n param === undefined\n ? { message, type: 'invalid_request_error', code }\n : { message, type: 'invalid_request_error', code, param }\n )\n\n const defaultFaultBody = (status: number): Schema.Json =>\n status === 429\n ? config.errorEnvelope({\n message: 'Synthetic rate limit: too many requests.',\n type: 'rate_limit_exceeded',\n code: 'rate_limit_exceeded'\n })\n : config.errorEnvelope({\n message: `Synthetic upstream error (${status}).`,\n type: status >= 500 ? 'server_error' : 'api_error',\n code: status >= 500 ? 'server_error' : 'upstream_error'\n })\n\n const kernel = makeEmulatorKernel({\n routes: config.routes,\n faultSchema: ResponsesFault,\n turnSchema: ResponsesScriptedTurn,\n newEntry: (base): MutableLedgerEntry => ({ ...base, toolNames: [], headers: {} }),\n snapshotEntry: (entry): ResponsesLedgerEntry => ({\n ...entry,\n toolNames: [...entry.toolNames],\n headers: { ...entry.headers }\n }),\n unknownRoute: () =>\n errorResponse(404, {\n message: 'Synthetic: no emulated route.',\n type: 'invalid_request_error',\n code: 'not_found'\n }),\n stateFields: () => ({ knownModels }),\n inputInvalid: config.inputInvalid\n })\n\n const responses = async (\n request: Request,\n entry: MutableLedgerEntry,\n path: string\n ): Promise<Response> => {\n for (const rule of config.headers) {\n const value = request.headers.get(rule.name)\n\n if (rule.record && value !== null) entry.headers[rule.name] = value\n }\n\n if (!bearerPattern.test(request.headers.get('authorization') ?? '')) {\n entry.status = 401\n\n return errorResponse(401, config.unauthorized)\n }\n\n for (const rule of config.headers) {\n if (\n rule.required !== undefined &&\n (request.headers.get(rule.name) ?? '').trim().length === 0\n ) {\n entry.status = rule.required.status\n\n return errorResponse(rule.required.status, rule.required.error)\n }\n }\n\n const text = await readText(request)\n const json = text === undefined ? undefined : parseJson(text)\n\n if (text === undefined || json === undefined) {\n entry.status = 400\n\n return invalidRequest('Synthetic: the request body is not valid JSON.', 'invalid_json')\n }\n\n entry.body = json\n\n const decoded = decodeResponsesRequest(json)\n\n if (Result.isFailure(decoded) || !isJsonObject(json)) {\n entry.status = 400\n\n return invalidRequest(\n 'Synthetic: the request body is not a Responses request (`input` is required).',\n 'invalid_request'\n )\n }\n\n const body = decoded.success\n const seq = entry.seq\n\n if (body.model !== undefined) entry.model = body.model\n\n entry.stream = body.stream === true\n\n if (Predicate.isBoolean(body.store)) entry.store = body.store\n\n if (body.reasoning !== undefined) entry.reasoning = body.reasoning\n\n if (body.tool_choice !== undefined) entry.toolChoice = body.tool_choice\n\n entry.toolNames = functionTools(body).map(tool => tool.name)\n\n const outputLimit = jsonField(json, 'max_output_tokens')\n\n if (Predicate.isNumber(outputLimit)) entry.maxOutputTokens = outputLimit\n\n if (config.outputTokenLimit === 'rejected' && outputLimit !== undefined) {\n entry.status = 400\n\n return invalidRequest(\n 'Synthetic: unsupported parameter: max_output_tokens.',\n 'unsupported_parameter',\n 'max_output_tokens'\n )\n }\n\n if (outputLimit !== undefined && outputLimit !== null && !isPositiveInteger(outputLimit)) {\n entry.status = 400\n\n return invalidRequest(\n 'Synthetic: max_output_tokens must be a positive integer.',\n 'invalid_value',\n 'max_output_tokens'\n )\n }\n\n const fault = kernel.takeFault(path, body.model)\n\n if (fault !== undefined && fault.fault.kind === 'status') {\n return kernel.respondWithStatusFault(entry, fault, fault.fault, defaultFaultBody)\n }\n\n const errorEventFault =\n fault !== undefined && fault.fault.kind === 'error-event-after-chunks'\n ? { state: fault, fault: fault.fault }\n : undefined\n\n const cannotApply = (problem: string): Response => {\n entry.faultError = problem\n entry.status = 500\n\n return controlError(500, `emulator fault cannot apply: ${problem}`)\n }\n\n // A scripted turn is used up when its request arrives. Header and status validation at\n // `script.enqueue` time means its response can always be built.\n const turn = kernel.nextTurn()\n\n if (turn !== undefined && 'error' in turn) {\n entry.scripted = 'error'\n\n if (errorEventFault !== undefined) {\n return cannotApply('error-event-after-chunks cannot apply to a scripted error')\n }\n\n return kernel.respondWithScriptedError(entry, turn.error, fault)\n }\n\n if (turn === undefined && (body.model === undefined || !knownModels.includes(body.model))) {\n entry.status = config.unknownModel.status\n\n return errorResponse(config.unknownModel.status, config.unknownModel.error)\n }\n\n if (turn !== undefined) entry.scripted = 'response'\n\n const plan =\n turn === undefined ? defaultPlan(body, seq, config.defaultText) : scriptedPlan(turn, seq)\n\n const identity = { id: `resp_synthetic_${seq}`, model: body.model ?? 'unknown' }\n const usage = planUsage(plan, text)\n const format = plan.format ?? (body.stream === true ? 'sse' : 'json')\n\n if (format === 'json') {\n if (errorEventFault !== undefined) {\n return cannotApply('error-event-after-chunks cannot apply to a JSON response')\n }\n\n return kernel.respondWithBody(\n entry,\n 200,\n { 'content-type': 'application/json' },\n [JSON.stringify(completedResponse(plan, identity, usage))],\n fault\n )\n }\n\n const events = streamEvents(plan, identity, usage)\n const headers = { 'content-type': 'text/event-stream', 'cache-control': 'no-cache' }\n\n if (errorEventFault === undefined) {\n return kernel.respondWithBody(entry, 200, headers, events, fault)\n }\n\n const after = errorEventFault.fault.chunks\n\n // The error must arrive before `response.completed`, or a client rightly ignores it.\n if (after >= events.length) {\n return cannotApply(\n `error-event-after-chunks after ${after} chunk(s) cannot apply to a response with ${events.length} chunk(s)`\n )\n }\n\n const response = kernel.respondWithBody(\n entry,\n 200,\n headers,\n [...events.slice(0, after), errorEvent(errorEventFault.fault, identity, after)],\n undefined\n )\n\n kernel.consumeFault(errorEventFault.state, entry)\n\n return response\n }\n\n // Every manifest route maps to its own handler; construction throws `EmulatorRouteUnmapped`\n // when a manifest route has no handler (or a handler has no manifest route).\n return kernel.serve(new Map([[emulatorRouteKey('POST', config.path), responses]]))\n}\n"],"mappings":"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"}