@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,289 @@
1
+ /**
2
+ * Anthropic Messages emulator: a plain fetch handler for `POST /v1/messages` (origin
3
+ * `https://api.anthropic.com`), with scripted turns, wire faults, a request ledger, and an
4
+ * `/_emulate/*` control plane.
5
+ *
6
+ * It never imports SDK code: its wire shapes follow the synthetic Anthropic Messages conformance
7
+ * fixtures (`message_start` / `content_block_*` / `message_delta` / `message_stop` SSE with
8
+ * `text_delta`, `thinking_delta`, and `input_json_delta`, the `message` JSON body, and the
9
+ * `{ type: 'error', error: { type, message } }` envelope) and are linked to those conformance
10
+ * case ids in `anthropicEmulatorRoutes`. The Messages machinery lives in the internal
11
+ * `messages.ts` core; faults, the ledger, and the control plane are shared with the Chat
12
+ * Completions emulators.
13
+ *
14
+ * Requests authenticate with a non-empty `x-api-key` (native API keys) or `Authorization:
15
+ * Bearer` (Claude OAuth) credential. Neither value is ever checked or stored.
16
+ *
17
+ * The same fetch handler also answers the Claude subscription-usage route
18
+ * (`GET /api/oauth/usage`, `emulator.usage`) with its own manifest
19
+ * (`anthropicSubscriptionUsageEmulatorRoutes`), ledger, faults, and turns; see
20
+ * `makeAnthropicEmulator`.
21
+ *
22
+ * Runtime-portable Web APIs only (`Request`, `Response`, `ReadableStream`, `TextEncoder`, `URL`);
23
+ * no Effect runtime is required to use it.
24
+ *
25
+ * @experimental
26
+ */
27
+ import { Data } from 'effect'
28
+ import type * as Schema from 'effect/Schema'
29
+ import { withSubscriptionUsage } from './emulator-compose.ts'
30
+ import type {
31
+ EmulatorCoverage,
32
+ EmulatorFaultState,
33
+ EmulatorRouteCoverage
34
+ } from './emulator-kernel.ts'
35
+ import { EmulatorFaultMatch, EmulatorScriptedError } from './emulator-kernel.ts'
36
+ import {
37
+ MessagesErrorEventFault,
38
+ MessagesFault,
39
+ MessagesScriptedMessage,
40
+ MessagesScriptedToolUse,
41
+ MessagesScriptedTurn,
42
+ MessagesScriptedUsage,
43
+ MessagesWireError,
44
+ makeMessagesEmulator,
45
+ type MessagesEmulator,
46
+ type MessagesFaultKind,
47
+ type MessagesLedgerEntry
48
+ } from './messages.ts'
49
+ import type { EmulatorRouteEvidence } from './route-evidence.ts'
50
+ import {
51
+ makeSubscriptionUsageEmulator,
52
+ recordedUsageBody,
53
+ SubscriptionUsageFault,
54
+ type SubscriptionUsageEmulator,
55
+ type SubscriptionUsageLedgerEntry,
56
+ type SubscriptionUsageScriptedTurn
57
+ } from './subscription-usage.ts'
58
+ import { anthropicClaudeUsageRecording } from './subscription-usage-recordings.ts'
59
+
60
+ export type { EmulatorEvidence, EmulatorRouteEvidence } from './route-evidence.ts'
61
+
62
+ export { emulatorEvidenceHeader } from './route-evidence.ts'
63
+
64
+ export const anthropicMessagesPath = '/v1/messages'
65
+
66
+ /** The Claude subscription-usage path (`anthropicClaudeSubscriptionUsageUrl` in the SDK). */
67
+ export const anthropicSubscriptionUsagePath = '/api/oauth/usage'
68
+
69
+ /** The `anthropic-beta` value the Claude usage fetcher sends for OAuth credentials. */
70
+ export const anthropicOAuthBeta = 'oauth-2025-04-20'
71
+
72
+ /**
73
+ * Route evidence manifest of the Claude subscription-usage route (served by the same fetch
74
+ * handler as the Messages route, with its own ledger and coverage). Synthetic, unverified.
75
+ */
76
+ export const anthropicSubscriptionUsageEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence> = [
77
+ {
78
+ method: 'GET',
79
+ path: anthropicSubscriptionUsagePath,
80
+ kind: 'provider',
81
+ write: false,
82
+ caseIds: ['anthropic.claude.usage.snapshot'],
83
+ evidence: 'unverified',
84
+ observedAt: undefined
85
+ }
86
+ ]
87
+
88
+ /**
89
+ * The recorded Claude usage body (the synthetic `anthropic.claude.usage.snapshot` fixture, copied
90
+ * as data): `five_hour` and `seven_day` as `{ utilization, resets_at }`.
91
+ */
92
+ export const anthropicSubscriptionUsageDefault: Schema.Json = recordedUsageBody(
93
+ anthropicClaudeUsageRecording
94
+ )
95
+
96
+ /** Synthetic-safe default model ids, including the Anthropic Messages conformance defaults. */
97
+ export const anthropicEmulatorDefaultModels: ReadonlyArray<string> = [
98
+ 'claude-haiku-4-5',
99
+ 'claude-sonnet-4-5'
100
+ ]
101
+
102
+ /**
103
+ * Route evidence manifest: every emulated Anthropic route and the conformance cases whose
104
+ * (currently synthetic, unverified) wire shapes it follows.
105
+ */
106
+ export const anthropicEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence> = [
107
+ {
108
+ method: 'POST',
109
+ path: anthropicMessagesPath,
110
+ kind: 'provider',
111
+ write: false,
112
+ caseIds: [
113
+ 'anthropic.messages.stream.plain-text',
114
+ 'anthropic.messages.stream.tool-use-input-deltas',
115
+ 'anthropic.messages.stream.thinking-before-text',
116
+ 'anthropic.messages.stream.error-envelope',
117
+ 'anthropic.messages.stream.max-tokens'
118
+ ],
119
+ evidence: 'unverified',
120
+ observedAt: undefined
121
+ }
122
+ ]
123
+
124
+ /** Optional fault filter; an omitted field matches every request. `path` ending in `*` is a prefix. */
125
+ export const AnthropicFaultMatch = EmulatorFaultMatch
126
+
127
+ export type AnthropicFaultMatch = typeof EmulatorFaultMatch.Type
128
+
129
+ /** An Anthropic wire error (`{ type, message }`), as sent inside the error envelope. */
130
+ export const AnthropicWireError = MessagesWireError
131
+
132
+ export type AnthropicWireError = MessagesWireError
133
+
134
+ /** A mid-stream `error` event fault (default `overloaded_error`), streamed responses only. */
135
+ export const AnthropicErrorEventFault = MessagesErrorEventFault
136
+
137
+ export type AnthropicErrorEventFault = typeof MessagesErrorEventFault.Type
138
+
139
+ /**
140
+ * Wire faults:
141
+ *
142
+ * - `status`: answer with this status, headers, and body (for example 429 with `retry-after`,
143
+ * or 529). The body defaults to the Anthropic error envelope for the status
144
+ * (`rate_limit_error` for 429, `overloaded_error` for 529, `api_error` for other 5xx).
145
+ * - `error-after-chunks`: send N body chunks, then error the body stream (a dropped connection).
146
+ * - `truncate-after-chunks`: send N body chunks, then close cleanly (no `message_stop`).
147
+ * - `error-event-after-chunks`: send N SSE events, then one `event: error` event and close.
148
+ *
149
+ * Statuses that cannot carry a body and redirects are rejected, as are invalid headers and
150
+ * `location`. A fault that cannot take effect answers 500 and is not consumed.
151
+ */
152
+ export const AnthropicFault = MessagesFault
153
+
154
+ export type AnthropicFault = MessagesFault
155
+
156
+ export type AnthropicFaultKind = MessagesFaultKind
157
+
158
+ /** Usage for a scripted turn (sent in `message_start` and `message_delta`). */
159
+ export const AnthropicScriptedUsage = MessagesScriptedUsage
160
+
161
+ export type AnthropicScriptedUsage = MessagesScriptedUsage
162
+
163
+ /** One scripted `tool_use` block; its JSON input streams as these fragments. */
164
+ export const AnthropicScriptedToolUse = MessagesScriptedToolUse
165
+
166
+ export type AnthropicScriptedToolUse = MessagesScriptedToolUse
167
+
168
+ /**
169
+ * A scripted message. Every field is exact except: a block is sent only when its field is
170
+ * present; `usage` omitted is synthesized and `null` drops it; `stopReason` omitted is
171
+ * `tool_use` with tool uses, else `end_turn`; `order` defaults to `thinking-first`.
172
+ */
173
+ export const AnthropicScriptedMessage = MessagesScriptedMessage
174
+
175
+ export type AnthropicScriptedMessage = MessagesScriptedMessage
176
+
177
+ /** A scripted error response: status, body (a string is sent as is), and optional headers. */
178
+ export const AnthropicScriptedError = EmulatorScriptedError
179
+
180
+ export type AnthropicScriptedError = typeof EmulatorScriptedError.Type
181
+
182
+ /** A turn queued for the next Messages request. */
183
+ export const AnthropicScriptedTurn = MessagesScriptedTurn
184
+
185
+ export type AnthropicScriptedTurn = MessagesScriptedTurn
186
+
187
+ /** Thrown by the JS API (`faults.add`, `script.enqueue`) for invalid input; a programmer error. */
188
+ export class AnthropicEmulatorInputInvalid extends Data.TaggedError(
189
+ 'AnthropicEmulatorInputInvalid'
190
+ )<{
191
+ readonly input: 'fault' | 'turn'
192
+ readonly reason: string
193
+ }> {
194
+ override get message(): string {
195
+ return `Invalid Anthropic emulator ${this.input}: ${this.reason}`
196
+ }
197
+ }
198
+
199
+ export type AnthropicLedgerEntry = MessagesLedgerEntry
200
+
201
+ export type AnthropicFaultState = EmulatorFaultState<AnthropicFault>
202
+
203
+ export type AnthropicRouteCoverage = EmulatorRouteCoverage
204
+
205
+ export type AnthropicCoverage = EmulatorCoverage
206
+
207
+ /** A usage-route fault (`status`, `error-after-chunks`, `truncate-after-chunks`). */
208
+ export const AnthropicUsageFault = SubscriptionUsageFault
209
+
210
+ export type AnthropicUsageFault = SubscriptionUsageFault
211
+
212
+ /** A usage turn: `{ usage }` (a body with the recorded JSON shape) or `{ error }`. */
213
+ export type AnthropicUsageScriptedTurn = SubscriptionUsageScriptedTurn
214
+
215
+ export type AnthropicUsageLedgerEntry = SubscriptionUsageLedgerEntry
216
+
217
+ export type AnthropicUsageEmulator = SubscriptionUsageEmulator
218
+
219
+ export type AnthropicEmulatorOptions = {
220
+ /** Model ids that exist. Defaults to `anthropicEmulatorDefaultModels`. */
221
+ readonly knownModels?: ReadonlyArray<string>
222
+ /**
223
+ * Replacement usage-route body; must have the recorded JSON shape (same keys and value kinds).
224
+ * Defaults to the recorded body (`anthropicSubscriptionUsageDefault`).
225
+ */
226
+ readonly subscriptionUsage?: Schema.Json
227
+ }
228
+
229
+ /** The Messages emulator, plus `usage`: the subscription-usage route's own emulator API. */
230
+ export type AnthropicEmulator = MessagesEmulator & { readonly usage: AnthropicUsageEmulator }
231
+
232
+ /**
233
+ * Create an Anthropic Messages emulator. Each call has independent ledger, fault, and script
234
+ * state.
235
+ *
236
+ * Without a script, `POST /v1/messages` answers a known model with synthetic content: `stream:
237
+ * true` streams `message_start`, the content blocks (`content_block_start`, deltas,
238
+ * `content_block_stop`, with a `ping` after the first block starts), `message_delta` (stop reason
239
+ * and usage), and `message_stop`; `stream: false` returns one `message` JSON body. A request with
240
+ * `thinking` enabled (`enabled` or `adaptive`) gets a thinking block before the answer. A request
241
+ * with `tools` gets one `tool_use` block whose input is synthesized from the tool's `input_schema`
242
+ * and streamed as `input_json_delta` fragments, stopping with `tool_use`; `tool_choice: { type:
243
+ * 'tool', name }` picks that tool (otherwise the first) and `tool_choice: { type: 'none' }`
244
+ * answers with text. An answer that would exceed `max_tokens` is cut and stops with `max_tokens`.
245
+ * Unknown models get 404 `not_found_error`; a request with neither a non-empty `x-api-key` nor a
246
+ * bearer credential gets 401 `authentication_error`; a missing or unsupported `anthropic-version`
247
+ * (only `2023-06-01` is accepted), a missing or non-positive `max_tokens`, or `thinking` with a
248
+ * forced `tool_choice` (`tool` or `any`) gets 400 `invalid_request_error`; unknown routes get a
249
+ * 404 envelope. The OAuth `anthropic-beta` header and `budget_tokens` limits are not enforced. The
250
+ * ledger records which header carried the credential, `anthropic-version`, and `anthropic-beta`,
251
+ * never a credential value.
252
+ *
253
+ * `GET /api/oauth/usage` is fixture-only: a request with a non-empty bearer credential (never
254
+ * checked or stored), an `anthropic-beta` header listing `oauth-2025-04-20`, `accept:
255
+ * application/json`, and no query gets the recorded body (`anthropicSubscriptionUsageDefault`,
256
+ * or a same-shaped `options.subscriptionUsage` / scripted `{ usage }`); anything else answers 400
257
+ * not-emulated. Throws `AnthropicEmulatorInputInvalid` for a differently shaped
258
+ * `subscriptionUsage`. Its ledger, faults, turns, and coverage are
259
+ * `emulator.usage` (control plane `/_emulate/usage/*`); `emulator.faults` and the other top-level
260
+ * APIs stay the Messages route's. `reset()` and `POST /_emulate/reset` reset both.
261
+ */
262
+ export const makeAnthropicEmulator = (options: AnthropicEmulatorOptions = {}): AnthropicEmulator =>
263
+ withSubscriptionUsage(
264
+ makeMessagesEmulator({
265
+ path: anthropicMessagesPath,
266
+ routes: anthropicEmulatorRoutes,
267
+ knownModels: options.knownModels ?? anthropicEmulatorDefaultModels,
268
+ inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({ input, reason })
269
+ }),
270
+ makeSubscriptionUsageEmulator({
271
+ path: anthropicSubscriptionUsagePath,
272
+ routes: anthropicSubscriptionUsageEmulatorRoutes,
273
+ recording: anthropicClaudeUsageRecording,
274
+ headers: [
275
+ {
276
+ name: 'anthropic-beta',
277
+ record: true,
278
+ accepts: value =>
279
+ value
280
+ .split(',')
281
+ .map(beta => beta.trim())
282
+ .includes(anthropicOAuthBeta)
283
+ }
284
+ ],
285
+ subscriptionUsage: options.subscriptionUsage,
286
+ inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({ input, reason })
287
+ }),
288
+ anthropicSubscriptionUsagePath
289
+ )