@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,269 @@
1
+ import { EmulatorEvidence, EmulatorRouteEvidence, emulatorEvidenceHeader } from "./route-evidence.mjs";
2
+ import { EmulatorCoverage, EmulatorFaultMatch, EmulatorFaultState, EmulatorRouteCoverage, EmulatorScriptedError } from "./emulator-kernel.mjs";
3
+ import { MessagesEmulator, MessagesErrorEventFault, MessagesFault, MessagesFaultKind, MessagesLedgerEntry, MessagesScriptedMessage, MessagesScriptedToolUse, MessagesScriptedTurn, MessagesScriptedUsage, MessagesWireError } from "./messages.mjs";
4
+ import { SubscriptionUsageEmulator, SubscriptionUsageFault, SubscriptionUsageLedgerEntry, SubscriptionUsageScriptedTurn } from "./subscription-usage.mjs";
5
+ import * as Schema from "effect/Schema";
6
+
7
+ //#region src/anthropic.d.ts
8
+ declare const anthropicMessagesPath = "/v1/messages";
9
+ /** The Claude subscription-usage path (`anthropicClaudeSubscriptionUsageUrl` in the SDK). */
10
+ declare const anthropicSubscriptionUsagePath = "/api/oauth/usage";
11
+ /** The `anthropic-beta` value the Claude usage fetcher sends for OAuth credentials. */
12
+ declare const anthropicOAuthBeta = "oauth-2025-04-20";
13
+ /**
14
+ * Route evidence manifest of the Claude subscription-usage route (served by the same fetch
15
+ * handler as the Messages route, with its own ledger and coverage). Synthetic, unverified.
16
+ */
17
+ declare const anthropicSubscriptionUsageEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence>;
18
+ /**
19
+ * The recorded Claude usage body (the synthetic `anthropic.claude.usage.snapshot` fixture, copied
20
+ * as data): `five_hour` and `seven_day` as `{ utilization, resets_at }`.
21
+ */
22
+ declare const anthropicSubscriptionUsageDefault: Schema.Json;
23
+ /** Synthetic-safe default model ids, including the Anthropic Messages conformance defaults. */
24
+ declare const anthropicEmulatorDefaultModels: ReadonlyArray<string>;
25
+ /**
26
+ * Route evidence manifest: every emulated Anthropic route and the conformance cases whose
27
+ * (currently synthetic, unverified) wire shapes it follows.
28
+ */
29
+ declare const anthropicEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence>;
30
+ /** Optional fault filter; an omitted field matches every request. `path` ending in `*` is a prefix. */
31
+ declare const AnthropicFaultMatch: Schema.Struct<{
32
+ readonly path: Schema.optionalKey<Schema.String>;
33
+ readonly model: Schema.optionalKey<Schema.String>;
34
+ }>;
35
+ type AnthropicFaultMatch = typeof EmulatorFaultMatch.Type;
36
+ /** An Anthropic wire error (`{ type, message }`), as sent inside the error envelope. */
37
+ declare const AnthropicWireError: Schema.Struct<{
38
+ readonly type: Schema.NonEmptyString;
39
+ readonly message: Schema.String;
40
+ }>;
41
+ type AnthropicWireError = MessagesWireError;
42
+ /** A mid-stream `error` event fault (default `overloaded_error`), streamed responses only. */
43
+ declare const AnthropicErrorEventFault: Schema.Struct<{
44
+ readonly match: Schema.optionalKey<Schema.Struct<{
45
+ readonly path: Schema.optionalKey<Schema.String>;
46
+ readonly model: Schema.optionalKey<Schema.String>;
47
+ }>>;
48
+ readonly count: Schema.optionalKey<Schema.Int>;
49
+ readonly kind: Schema.Literal<"error-event-after-chunks">;
50
+ readonly chunks: Schema.Int;
51
+ readonly error: Schema.optionalKey<Schema.Struct<{
52
+ readonly type: Schema.NonEmptyString;
53
+ readonly message: Schema.String;
54
+ }>>;
55
+ }>;
56
+ type AnthropicErrorEventFault = typeof MessagesErrorEventFault.Type;
57
+ /**
58
+ * Wire faults:
59
+ *
60
+ * - `status`: answer with this status, headers, and body (for example 429 with `retry-after`,
61
+ * or 529). The body defaults to the Anthropic error envelope for the status
62
+ * (`rate_limit_error` for 429, `overloaded_error` for 529, `api_error` for other 5xx).
63
+ * - `error-after-chunks`: send N body chunks, then error the body stream (a dropped connection).
64
+ * - `truncate-after-chunks`: send N body chunks, then close cleanly (no `message_stop`).
65
+ * - `error-event-after-chunks`: send N SSE events, then one `event: error` event and close.
66
+ *
67
+ * Statuses that cannot carry a body and redirects are rejected, as are invalid headers and
68
+ * `location`. A fault that cannot take effect answers 500 and is not consumed.
69
+ */
70
+ declare const AnthropicFault: Schema.Union<readonly [Schema.Struct<{
71
+ readonly match: Schema.optionalKey<Schema.Struct<{
72
+ readonly path: Schema.optionalKey<Schema.String>;
73
+ readonly model: Schema.optionalKey<Schema.String>;
74
+ }>>;
75
+ readonly count: Schema.optionalKey<Schema.Int>;
76
+ readonly kind: Schema.Literal<"status">;
77
+ readonly status: Schema.Int;
78
+ readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
79
+ readonly body: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
80
+ }>, Schema.Struct<{
81
+ readonly match: Schema.optionalKey<Schema.Struct<{
82
+ readonly path: Schema.optionalKey<Schema.String>;
83
+ readonly model: Schema.optionalKey<Schema.String>;
84
+ }>>;
85
+ readonly count: Schema.optionalKey<Schema.Int>;
86
+ readonly kind: Schema.Literal<"error-after-chunks">;
87
+ readonly chunks: Schema.Int;
88
+ }>, Schema.Struct<{
89
+ readonly match: Schema.optionalKey<Schema.Struct<{
90
+ readonly path: Schema.optionalKey<Schema.String>;
91
+ readonly model: Schema.optionalKey<Schema.String>;
92
+ }>>;
93
+ readonly count: Schema.optionalKey<Schema.Int>;
94
+ readonly kind: Schema.Literal<"truncate-after-chunks">;
95
+ readonly chunks: Schema.Int;
96
+ }>, Schema.Struct<{
97
+ readonly match: Schema.optionalKey<Schema.Struct<{
98
+ readonly path: Schema.optionalKey<Schema.String>;
99
+ readonly model: Schema.optionalKey<Schema.String>;
100
+ }>>;
101
+ readonly count: Schema.optionalKey<Schema.Int>;
102
+ readonly kind: Schema.Literal<"error-event-after-chunks">;
103
+ readonly chunks: Schema.Int;
104
+ readonly error: Schema.optionalKey<Schema.Struct<{
105
+ readonly type: Schema.NonEmptyString;
106
+ readonly message: Schema.String;
107
+ }>>;
108
+ }>]>;
109
+ type AnthropicFault = MessagesFault;
110
+ type AnthropicFaultKind = MessagesFaultKind;
111
+ /** Usage for a scripted turn (sent in `message_start` and `message_delta`). */
112
+ declare const AnthropicScriptedUsage: Schema.Struct<{
113
+ readonly inputTokens: Schema.Int;
114
+ readonly outputTokens: Schema.Int;
115
+ }>;
116
+ type AnthropicScriptedUsage = MessagesScriptedUsage;
117
+ /** One scripted `tool_use` block; its JSON input streams as these fragments. */
118
+ declare const AnthropicScriptedToolUse: Schema.Struct<{
119
+ readonly name: Schema.NonEmptyString;
120
+ readonly inputFragments: Schema.$Array<Schema.String>;
121
+ readonly id: Schema.optionalKey<Schema.NonEmptyString>;
122
+ }>;
123
+ type AnthropicScriptedToolUse = MessagesScriptedToolUse;
124
+ /**
125
+ * A scripted message. Every field is exact except: a block is sent only when its field is
126
+ * present; `usage` omitted is synthesized and `null` drops it; `stopReason` omitted is
127
+ * `tool_use` with tool uses, else `end_turn`; `order` defaults to `thinking-first`.
128
+ */
129
+ declare const AnthropicScriptedMessage: Schema.Struct<{
130
+ readonly thinking: Schema.optionalKey<Schema.$Array<Schema.String>>;
131
+ readonly text: Schema.optionalKey<Schema.$Array<Schema.String>>;
132
+ readonly toolUses: Schema.optionalKey<Schema.$Array<Schema.Struct<{
133
+ readonly name: Schema.NonEmptyString;
134
+ readonly inputFragments: Schema.$Array<Schema.String>;
135
+ readonly id: Schema.optionalKey<Schema.NonEmptyString>;
136
+ }>>>;
137
+ readonly order: Schema.optionalKey<Schema.Literals<readonly ["thinking-first", "text-first"]>>;
138
+ readonly usage: Schema.optionalKey<Schema.NullOr<Schema.Struct<{
139
+ readonly inputTokens: Schema.Int;
140
+ readonly outputTokens: Schema.Int;
141
+ }>>>;
142
+ readonly stopReason: Schema.optionalKey<Schema.NonEmptyString>;
143
+ }>;
144
+ type AnthropicScriptedMessage = MessagesScriptedMessage;
145
+ /** A scripted error response: status, body (a string is sent as is), and optional headers. */
146
+ declare const AnthropicScriptedError: Schema.Struct<{
147
+ readonly error: Schema.Struct<{
148
+ readonly status: Schema.Int;
149
+ readonly body: Schema.Codec<Schema.Json, Schema.Json, never, never>;
150
+ readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
151
+ }>;
152
+ }>;
153
+ type AnthropicScriptedError = typeof EmulatorScriptedError.Type;
154
+ /** A turn queued for the next Messages request. */
155
+ declare const AnthropicScriptedTurn: Schema.Union<readonly [Schema.Struct<{
156
+ readonly error: Schema.Struct<{
157
+ readonly status: Schema.Int;
158
+ readonly body: Schema.Codec<Schema.Json, Schema.Json, never, never>;
159
+ readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
160
+ }>;
161
+ }>, Schema.Struct<{
162
+ readonly thinking: Schema.optionalKey<Schema.$Array<Schema.String>>;
163
+ readonly text: Schema.optionalKey<Schema.$Array<Schema.String>>;
164
+ readonly toolUses: Schema.optionalKey<Schema.$Array<Schema.Struct<{
165
+ readonly name: Schema.NonEmptyString;
166
+ readonly inputFragments: Schema.$Array<Schema.String>;
167
+ readonly id: Schema.optionalKey<Schema.NonEmptyString>;
168
+ }>>>;
169
+ readonly order: Schema.optionalKey<Schema.Literals<readonly ["thinking-first", "text-first"]>>;
170
+ readonly usage: Schema.optionalKey<Schema.NullOr<Schema.Struct<{
171
+ readonly inputTokens: Schema.Int;
172
+ readonly outputTokens: Schema.Int;
173
+ }>>>;
174
+ readonly stopReason: Schema.optionalKey<Schema.NonEmptyString>;
175
+ }>]>;
176
+ type AnthropicScriptedTurn = MessagesScriptedTurn;
177
+ declare const AnthropicEmulatorInputInvalid_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => import("effect/Cause").YieldableError & {
178
+ readonly _tag: "AnthropicEmulatorInputInvalid";
179
+ } & Readonly<A>;
180
+ /** Thrown by the JS API (`faults.add`, `script.enqueue`) for invalid input; a programmer error. */
181
+ declare class AnthropicEmulatorInputInvalid extends AnthropicEmulatorInputInvalid_base<{
182
+ readonly input: 'fault' | 'turn';
183
+ readonly reason: string;
184
+ }> {
185
+ get message(): string;
186
+ }
187
+ type AnthropicLedgerEntry = MessagesLedgerEntry;
188
+ type AnthropicFaultState = EmulatorFaultState<AnthropicFault>;
189
+ type AnthropicRouteCoverage = EmulatorRouteCoverage;
190
+ type AnthropicCoverage = EmulatorCoverage;
191
+ /** A usage-route fault (`status`, `error-after-chunks`, `truncate-after-chunks`). */
192
+ declare const AnthropicUsageFault: Schema.Union<readonly [Schema.Struct<{
193
+ readonly status: Schema.Int;
194
+ readonly match: Schema.optionalKey<Schema.Struct<{
195
+ readonly path: Schema.optionalKey<Schema.String>;
196
+ readonly model: Schema.optionalKey<Schema.String>;
197
+ }>>;
198
+ readonly count: Schema.optionalKey<Schema.Int>;
199
+ readonly kind: Schema.Literal<"status">;
200
+ readonly headers: Schema.optionalKey<Schema.$Record<Schema.String, Schema.String>>;
201
+ readonly body: Schema.optionalKey<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
202
+ }>, Schema.Struct<{
203
+ readonly match: Schema.optionalKey<Schema.Struct<{
204
+ readonly path: Schema.optionalKey<Schema.String>;
205
+ readonly model: Schema.optionalKey<Schema.String>;
206
+ }>>;
207
+ readonly count: Schema.optionalKey<Schema.Int>;
208
+ readonly kind: Schema.Literal<"error-after-chunks">;
209
+ readonly chunks: Schema.Int;
210
+ }>, Schema.Struct<{
211
+ readonly match: Schema.optionalKey<Schema.Struct<{
212
+ readonly path: Schema.optionalKey<Schema.String>;
213
+ readonly model: Schema.optionalKey<Schema.String>;
214
+ }>>;
215
+ readonly count: Schema.optionalKey<Schema.Int>;
216
+ readonly kind: Schema.Literal<"truncate-after-chunks">;
217
+ readonly chunks: Schema.Int;
218
+ }>]>;
219
+ type AnthropicUsageFault = SubscriptionUsageFault;
220
+ /** A usage turn: `{ usage }` (a body with the recorded JSON shape) or `{ error }`. */
221
+ type AnthropicUsageScriptedTurn = SubscriptionUsageScriptedTurn;
222
+ type AnthropicUsageLedgerEntry = SubscriptionUsageLedgerEntry;
223
+ type AnthropicUsageEmulator = SubscriptionUsageEmulator;
224
+ type AnthropicEmulatorOptions = {
225
+ /** Model ids that exist. Defaults to `anthropicEmulatorDefaultModels`. */readonly knownModels?: ReadonlyArray<string>;
226
+ /**
227
+ * Replacement usage-route body; must have the recorded JSON shape (same keys and value kinds).
228
+ * Defaults to the recorded body (`anthropicSubscriptionUsageDefault`).
229
+ */
230
+ readonly subscriptionUsage?: Schema.Json;
231
+ };
232
+ /** The Messages emulator, plus `usage`: the subscription-usage route's own emulator API. */
233
+ type AnthropicEmulator = MessagesEmulator & {
234
+ readonly usage: AnthropicUsageEmulator;
235
+ };
236
+ /**
237
+ * Create an Anthropic Messages emulator. Each call has independent ledger, fault, and script
238
+ * state.
239
+ *
240
+ * Without a script, `POST /v1/messages` answers a known model with synthetic content: `stream:
241
+ * true` streams `message_start`, the content blocks (`content_block_start`, deltas,
242
+ * `content_block_stop`, with a `ping` after the first block starts), `message_delta` (stop reason
243
+ * and usage), and `message_stop`; `stream: false` returns one `message` JSON body. A request with
244
+ * `thinking` enabled (`enabled` or `adaptive`) gets a thinking block before the answer. A request
245
+ * with `tools` gets one `tool_use` block whose input is synthesized from the tool's `input_schema`
246
+ * and streamed as `input_json_delta` fragments, stopping with `tool_use`; `tool_choice: { type:
247
+ * 'tool', name }` picks that tool (otherwise the first) and `tool_choice: { type: 'none' }`
248
+ * answers with text. An answer that would exceed `max_tokens` is cut and stops with `max_tokens`.
249
+ * Unknown models get 404 `not_found_error`; a request with neither a non-empty `x-api-key` nor a
250
+ * bearer credential gets 401 `authentication_error`; a missing or unsupported `anthropic-version`
251
+ * (only `2023-06-01` is accepted), a missing or non-positive `max_tokens`, or `thinking` with a
252
+ * forced `tool_choice` (`tool` or `any`) gets 400 `invalid_request_error`; unknown routes get a
253
+ * 404 envelope. The OAuth `anthropic-beta` header and `budget_tokens` limits are not enforced. The
254
+ * ledger records which header carried the credential, `anthropic-version`, and `anthropic-beta`,
255
+ * never a credential value.
256
+ *
257
+ * `GET /api/oauth/usage` is fixture-only: a request with a non-empty bearer credential (never
258
+ * checked or stored), an `anthropic-beta` header listing `oauth-2025-04-20`, `accept:
259
+ * application/json`, and no query gets the recorded body (`anthropicSubscriptionUsageDefault`,
260
+ * or a same-shaped `options.subscriptionUsage` / scripted `{ usage }`); anything else answers 400
261
+ * not-emulated. Throws `AnthropicEmulatorInputInvalid` for a differently shaped
262
+ * `subscriptionUsage`. Its ledger, faults, turns, and coverage are
263
+ * `emulator.usage` (control plane `/_emulate/usage/*`); `emulator.faults` and the other top-level
264
+ * APIs stay the Messages route's. `reset()` and `POST /_emulate/reset` reset both.
265
+ */
266
+ declare const makeAnthropicEmulator: (options?: AnthropicEmulatorOptions) => AnthropicEmulator;
267
+ //#endregion
268
+ export { AnthropicCoverage, AnthropicEmulator, AnthropicEmulatorInputInvalid, AnthropicEmulatorOptions, AnthropicErrorEventFault, AnthropicFault, AnthropicFaultKind, AnthropicFaultMatch, AnthropicFaultState, AnthropicLedgerEntry, AnthropicRouteCoverage, AnthropicScriptedError, AnthropicScriptedMessage, AnthropicScriptedToolUse, AnthropicScriptedTurn, AnthropicScriptedUsage, AnthropicUsageEmulator, AnthropicUsageFault, AnthropicUsageLedgerEntry, AnthropicUsageScriptedTurn, AnthropicWireError, type EmulatorEvidence, type EmulatorRouteEvidence, anthropicEmulatorDefaultModels, anthropicEmulatorRoutes, anthropicMessagesPath, anthropicOAuthBeta, anthropicSubscriptionUsageDefault, anthropicSubscriptionUsageEmulatorRoutes, anthropicSubscriptionUsagePath, emulatorEvidenceHeader, makeAnthropicEmulator };
269
+ //# sourceMappingURL=anthropic.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.mts","names":[],"sources":["../src/anthropic.ts"],"mappings":";;;;;;;cA+Da,qBAAA;;cAGA,8BAAA;AAHqB;AAAA,cAMrB,kBAAA;;;;AAH8B;cAS9B,wCAAA,EAA0C,aAAa,CAAC,qBAAA;;;;AANtC;cAsBlB,iCAAA,EAAmC,MAAA,CAAO,IAEtD;;cAGY,8BAAA,EAAgC,aAAa;;AArBgC;AAgB1F;;cAca,uBAAA,EAAyB,aAAa,CAAC,qBAAA;;cAmBvC,mBAAA,EAAmB,MAAA,CAAA,MAAA;EAAA;;;KAEpB,mBAAA,UAA6B,kBAAA,CAAmB,IAAI;AA9BN;AAAA,cAiC7C,kBAAA,EAAkB,MAAA,CAAA,MAAA;EAAA;;;KAEnB,kBAAA,GAAqB,iBAAiB;AAPlD;AAAA,cAUa,wBAAA,EAAwB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;KAEzB,wBAAA,UAAkC,uBAAA,CAAwB,IAAI;;;;;;;;;;AAV1E;;;;cAyBa,cAAA,EAAc,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEf,cAAA,GAAiB,aAAa;AAAA,KAE9B,kBAAA,GAAqB,iBAAiB;;cAGrC,sBAAA,EAAsB,MAAA,CAAA,MAAA;EAAA;;;KAEvB,sBAAA,GAAyB,qBAAqB;;cAG7C,wBAAA,EAAwB,MAAA,CAAA,MAAA;EAAA;;;;KAEzB,wBAAA,GAA2B,uBAAuB;;;;;;cAOjD,wBAAA,EAAwB,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;KAEzB,wBAAA,GAA2B,uBAAuB;;cAGjD,sBAAA,EAAsB,MAAA,CAAA,MAAA;EAAA;;;;;;KAEvB,sBAAA,UAAgC,qBAAA,CAAsB,IAAI;;cAGzD,qBAAA,EAAqB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;KAEtB,qBAAA,GAAwB,oBAAoB;AAAA,cAAA,kCAAA;;;;cAG3C,6BAAA,SAAsC,kCAAA;EAAA,SAGxC,KAAA;EAAA,SACA,MAAA;AAAA;EAAA,IAEI,OAAA,CAAA;AAAA;AAAA,KAKH,oBAAA,GAAuB,mBAAmB;AAAA,KAE1C,mBAAA,GAAsB,kBAAkB,CAAC,cAAA;AAAA,KAEzC,sBAAA,GAAyB,qBAAqB;AAAA,KAE9C,iBAAA,GAAoB,gBAAgB;;cAGnC,mBAAA,EAAmB,MAAA,CAAA,KAAA,WAAA,MAAA,CAAA,MAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KAEpB,mBAAA,GAAsB,sBAAsB;;KAG5C,0BAAA,GAA6B,6BAA6B;AAAA,KAE1D,yBAAA,GAA4B,4BAA4B;AAAA,KAExD,sBAAA,GAAyB,yBAAyB;AAAA,KAElD,wBAAA;EAnEe,mFAqEhB,WAAA,GAAc,aAAA;;;;;WAKd,iBAAA,GAAoB,MAAA,CAAO,IAAI;AAAA;;KAI9B,iBAAA,GAAoB,gBAAA;EAAA,SAA8B,KAAA,EAAO,sBAAsB;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgC9E,qBAAA,GAAyB,OAAA,GAAS,wBAAA,KAAgC,iBA2B5E"}
@@ -0,0 +1,177 @@
1
+ import { emulatorEvidenceHeader } from "./route-evidence.mjs";
2
+ import { EmulatorFaultMatch, EmulatorScriptedError } from "./emulator-kernel.mjs";
3
+ import { withSubscriptionUsage } from "./emulator-compose.mjs";
4
+ import { MessagesErrorEventFault, MessagesFault, MessagesScriptedMessage, MessagesScriptedToolUse, MessagesScriptedTurn, MessagesScriptedUsage, MessagesWireError, makeMessagesEmulator } from "./messages.mjs";
5
+ import { SubscriptionUsageFault, makeSubscriptionUsageEmulator, recordedUsageBody } from "./subscription-usage.mjs";
6
+ import { anthropicClaudeUsageRecording } from "./subscription-usage-recordings.mjs";
7
+ import { Data } from "effect";
8
+ //#region src/anthropic.ts
9
+ /**
10
+ * Anthropic Messages emulator: a plain fetch handler for `POST /v1/messages` (origin
11
+ * `https://api.anthropic.com`), with scripted turns, wire faults, a request ledger, and an
12
+ * `/_emulate/*` control plane.
13
+ *
14
+ * It never imports SDK code: its wire shapes follow the synthetic Anthropic Messages conformance
15
+ * fixtures (`message_start` / `content_block_*` / `message_delta` / `message_stop` SSE with
16
+ * `text_delta`, `thinking_delta`, and `input_json_delta`, the `message` JSON body, and the
17
+ * `{ type: 'error', error: { type, message } }` envelope) and are linked to those conformance
18
+ * case ids in `anthropicEmulatorRoutes`. The Messages machinery lives in the internal
19
+ * `messages.ts` core; faults, the ledger, and the control plane are shared with the Chat
20
+ * Completions emulators.
21
+ *
22
+ * Requests authenticate with a non-empty `x-api-key` (native API keys) or `Authorization:
23
+ * Bearer` (Claude OAuth) credential. Neither value is ever checked or stored.
24
+ *
25
+ * The same fetch handler also answers the Claude subscription-usage route
26
+ * (`GET /api/oauth/usage`, `emulator.usage`) with its own manifest
27
+ * (`anthropicSubscriptionUsageEmulatorRoutes`), ledger, faults, and turns; see
28
+ * `makeAnthropicEmulator`.
29
+ *
30
+ * Runtime-portable Web APIs only (`Request`, `Response`, `ReadableStream`, `TextEncoder`, `URL`);
31
+ * no Effect runtime is required to use it.
32
+ *
33
+ * @experimental
34
+ */
35
+ const anthropicMessagesPath = "/v1/messages";
36
+ /** The Claude subscription-usage path (`anthropicClaudeSubscriptionUsageUrl` in the SDK). */
37
+ const anthropicSubscriptionUsagePath = "/api/oauth/usage";
38
+ /** The `anthropic-beta` value the Claude usage fetcher sends for OAuth credentials. */
39
+ const anthropicOAuthBeta = "oauth-2025-04-20";
40
+ /**
41
+ * Route evidence manifest of the Claude subscription-usage route (served by the same fetch
42
+ * handler as the Messages route, with its own ledger and coverage). Synthetic, unverified.
43
+ */
44
+ const anthropicSubscriptionUsageEmulatorRoutes = [{
45
+ method: "GET",
46
+ path: anthropicSubscriptionUsagePath,
47
+ kind: "provider",
48
+ write: false,
49
+ caseIds: ["anthropic.claude.usage.snapshot"],
50
+ evidence: "unverified",
51
+ observedAt: void 0
52
+ }];
53
+ /**
54
+ * The recorded Claude usage body (the synthetic `anthropic.claude.usage.snapshot` fixture, copied
55
+ * as data): `five_hour` and `seven_day` as `{ utilization, resets_at }`.
56
+ */
57
+ const anthropicSubscriptionUsageDefault = recordedUsageBody(anthropicClaudeUsageRecording);
58
+ /** Synthetic-safe default model ids, including the Anthropic Messages conformance defaults. */
59
+ const anthropicEmulatorDefaultModels = ["claude-haiku-4-5", "claude-sonnet-4-5"];
60
+ /**
61
+ * Route evidence manifest: every emulated Anthropic route and the conformance cases whose
62
+ * (currently synthetic, unverified) wire shapes it follows.
63
+ */
64
+ const anthropicEmulatorRoutes = [{
65
+ method: "POST",
66
+ path: anthropicMessagesPath,
67
+ kind: "provider",
68
+ write: false,
69
+ caseIds: [
70
+ "anthropic.messages.stream.plain-text",
71
+ "anthropic.messages.stream.tool-use-input-deltas",
72
+ "anthropic.messages.stream.thinking-before-text",
73
+ "anthropic.messages.stream.error-envelope",
74
+ "anthropic.messages.stream.max-tokens"
75
+ ],
76
+ evidence: "unverified",
77
+ observedAt: void 0
78
+ }];
79
+ /** Optional fault filter; an omitted field matches every request. `path` ending in `*` is a prefix. */
80
+ const AnthropicFaultMatch = EmulatorFaultMatch;
81
+ /** An Anthropic wire error (`{ type, message }`), as sent inside the error envelope. */
82
+ const AnthropicWireError = MessagesWireError;
83
+ /** A mid-stream `error` event fault (default `overloaded_error`), streamed responses only. */
84
+ const AnthropicErrorEventFault = MessagesErrorEventFault;
85
+ /**
86
+ * Wire faults:
87
+ *
88
+ * - `status`: answer with this status, headers, and body (for example 429 with `retry-after`,
89
+ * or 529). The body defaults to the Anthropic error envelope for the status
90
+ * (`rate_limit_error` for 429, `overloaded_error` for 529, `api_error` for other 5xx).
91
+ * - `error-after-chunks`: send N body chunks, then error the body stream (a dropped connection).
92
+ * - `truncate-after-chunks`: send N body chunks, then close cleanly (no `message_stop`).
93
+ * - `error-event-after-chunks`: send N SSE events, then one `event: error` event and close.
94
+ *
95
+ * Statuses that cannot carry a body and redirects are rejected, as are invalid headers and
96
+ * `location`. A fault that cannot take effect answers 500 and is not consumed.
97
+ */
98
+ const AnthropicFault = MessagesFault;
99
+ /** Usage for a scripted turn (sent in `message_start` and `message_delta`). */
100
+ const AnthropicScriptedUsage = MessagesScriptedUsage;
101
+ /** One scripted `tool_use` block; its JSON input streams as these fragments. */
102
+ const AnthropicScriptedToolUse = MessagesScriptedToolUse;
103
+ /**
104
+ * A scripted message. Every field is exact except: a block is sent only when its field is
105
+ * present; `usage` omitted is synthesized and `null` drops it; `stopReason` omitted is
106
+ * `tool_use` with tool uses, else `end_turn`; `order` defaults to `thinking-first`.
107
+ */
108
+ const AnthropicScriptedMessage = MessagesScriptedMessage;
109
+ /** A scripted error response: status, body (a string is sent as is), and optional headers. */
110
+ const AnthropicScriptedError = EmulatorScriptedError;
111
+ /** A turn queued for the next Messages request. */
112
+ const AnthropicScriptedTurn = MessagesScriptedTurn;
113
+ /** Thrown by the JS API (`faults.add`, `script.enqueue`) for invalid input; a programmer error. */
114
+ var AnthropicEmulatorInputInvalid = class extends Data.TaggedError("AnthropicEmulatorInputInvalid") {
115
+ get message() {
116
+ return `Invalid Anthropic emulator ${this.input}: ${this.reason}`;
117
+ }
118
+ };
119
+ /** A usage-route fault (`status`, `error-after-chunks`, `truncate-after-chunks`). */
120
+ const AnthropicUsageFault = SubscriptionUsageFault;
121
+ /**
122
+ * Create an Anthropic Messages emulator. Each call has independent ledger, fault, and script
123
+ * state.
124
+ *
125
+ * Without a script, `POST /v1/messages` answers a known model with synthetic content: `stream:
126
+ * true` streams `message_start`, the content blocks (`content_block_start`, deltas,
127
+ * `content_block_stop`, with a `ping` after the first block starts), `message_delta` (stop reason
128
+ * and usage), and `message_stop`; `stream: false` returns one `message` JSON body. A request with
129
+ * `thinking` enabled (`enabled` or `adaptive`) gets a thinking block before the answer. A request
130
+ * with `tools` gets one `tool_use` block whose input is synthesized from the tool's `input_schema`
131
+ * and streamed as `input_json_delta` fragments, stopping with `tool_use`; `tool_choice: { type:
132
+ * 'tool', name }` picks that tool (otherwise the first) and `tool_choice: { type: 'none' }`
133
+ * answers with text. An answer that would exceed `max_tokens` is cut and stops with `max_tokens`.
134
+ * Unknown models get 404 `not_found_error`; a request with neither a non-empty `x-api-key` nor a
135
+ * bearer credential gets 401 `authentication_error`; a missing or unsupported `anthropic-version`
136
+ * (only `2023-06-01` is accepted), a missing or non-positive `max_tokens`, or `thinking` with a
137
+ * forced `tool_choice` (`tool` or `any`) gets 400 `invalid_request_error`; unknown routes get a
138
+ * 404 envelope. The OAuth `anthropic-beta` header and `budget_tokens` limits are not enforced. The
139
+ * ledger records which header carried the credential, `anthropic-version`, and `anthropic-beta`,
140
+ * never a credential value.
141
+ *
142
+ * `GET /api/oauth/usage` is fixture-only: a request with a non-empty bearer credential (never
143
+ * checked or stored), an `anthropic-beta` header listing `oauth-2025-04-20`, `accept:
144
+ * application/json`, and no query gets the recorded body (`anthropicSubscriptionUsageDefault`,
145
+ * or a same-shaped `options.subscriptionUsage` / scripted `{ usage }`); anything else answers 400
146
+ * not-emulated. Throws `AnthropicEmulatorInputInvalid` for a differently shaped
147
+ * `subscriptionUsage`. Its ledger, faults, turns, and coverage are
148
+ * `emulator.usage` (control plane `/_emulate/usage/*`); `emulator.faults` and the other top-level
149
+ * APIs stay the Messages route's. `reset()` and `POST /_emulate/reset` reset both.
150
+ */
151
+ const makeAnthropicEmulator = (options = {}) => withSubscriptionUsage(makeMessagesEmulator({
152
+ path: anthropicMessagesPath,
153
+ routes: anthropicEmulatorRoutes,
154
+ knownModels: options.knownModels ?? anthropicEmulatorDefaultModels,
155
+ inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({
156
+ input,
157
+ reason
158
+ })
159
+ }), makeSubscriptionUsageEmulator({
160
+ path: anthropicSubscriptionUsagePath,
161
+ routes: anthropicSubscriptionUsageEmulatorRoutes,
162
+ recording: anthropicClaudeUsageRecording,
163
+ headers: [{
164
+ name: "anthropic-beta",
165
+ record: true,
166
+ accepts: (value) => value.split(",").map((beta) => beta.trim()).includes(anthropicOAuthBeta)
167
+ }],
168
+ subscriptionUsage: options.subscriptionUsage,
169
+ inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({
170
+ input,
171
+ reason
172
+ })
173
+ }), anthropicSubscriptionUsagePath);
174
+ //#endregion
175
+ export { AnthropicEmulatorInputInvalid, AnthropicErrorEventFault, AnthropicFault, AnthropicFaultMatch, AnthropicScriptedError, AnthropicScriptedMessage, AnthropicScriptedToolUse, AnthropicScriptedTurn, AnthropicScriptedUsage, AnthropicUsageFault, AnthropicWireError, anthropicEmulatorDefaultModels, anthropicEmulatorRoutes, anthropicMessagesPath, anthropicOAuthBeta, anthropicSubscriptionUsageDefault, anthropicSubscriptionUsageEmulatorRoutes, anthropicSubscriptionUsagePath, emulatorEvidenceHeader, makeAnthropicEmulator };
176
+
177
+ //# sourceMappingURL=anthropic.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.mjs","names":[],"sources":["../src/anthropic.ts"],"sourcesContent":["/**\n * Anthropic Messages emulator: a plain fetch handler for `POST /v1/messages` (origin\n * `https://api.anthropic.com`), with scripted turns, wire faults, a request ledger, and an\n * `/_emulate/*` control plane.\n *\n * It never imports SDK code: its wire shapes follow the synthetic Anthropic Messages conformance\n * fixtures (`message_start` / `content_block_*` / `message_delta` / `message_stop` SSE with\n * `text_delta`, `thinking_delta`, and `input_json_delta`, the `message` JSON body, and the\n * `{ type: 'error', error: { type, message } }` envelope) and are linked to those conformance\n * case ids in `anthropicEmulatorRoutes`. The Messages machinery lives in the internal\n * `messages.ts` core; faults, the ledger, and the control plane are shared with the Chat\n * Completions emulators.\n *\n * Requests authenticate with a non-empty `x-api-key` (native API keys) or `Authorization:\n * Bearer` (Claude OAuth) credential. Neither value is ever checked or stored.\n *\n * The same fetch handler also answers the Claude subscription-usage route\n * (`GET /api/oauth/usage`, `emulator.usage`) with its own manifest\n * (`anthropicSubscriptionUsageEmulatorRoutes`), ledger, faults, and turns; see\n * `makeAnthropicEmulator`.\n *\n * Runtime-portable Web APIs only (`Request`, `Response`, `ReadableStream`, `TextEncoder`, `URL`);\n * no Effect runtime is required to use it.\n *\n * @experimental\n */\nimport { Data } from 'effect'\nimport type * as Schema from 'effect/Schema'\nimport { withSubscriptionUsage } from './emulator-compose.ts'\nimport type {\n EmulatorCoverage,\n EmulatorFaultState,\n EmulatorRouteCoverage\n} from './emulator-kernel.ts'\nimport { EmulatorFaultMatch, EmulatorScriptedError } from './emulator-kernel.ts'\nimport {\n MessagesErrorEventFault,\n MessagesFault,\n MessagesScriptedMessage,\n MessagesScriptedToolUse,\n MessagesScriptedTurn,\n MessagesScriptedUsage,\n MessagesWireError,\n makeMessagesEmulator,\n type MessagesEmulator,\n type MessagesFaultKind,\n type MessagesLedgerEntry\n} from './messages.ts'\nimport type { EmulatorRouteEvidence } from './route-evidence.ts'\nimport {\n makeSubscriptionUsageEmulator,\n recordedUsageBody,\n SubscriptionUsageFault,\n type SubscriptionUsageEmulator,\n type SubscriptionUsageLedgerEntry,\n type SubscriptionUsageScriptedTurn\n} from './subscription-usage.ts'\nimport { anthropicClaudeUsageRecording } from './subscription-usage-recordings.ts'\n\nexport type { EmulatorEvidence, EmulatorRouteEvidence } from './route-evidence.ts'\n\nexport { emulatorEvidenceHeader } from './route-evidence.ts'\n\nexport const anthropicMessagesPath = '/v1/messages'\n\n/** The Claude subscription-usage path (`anthropicClaudeSubscriptionUsageUrl` in the SDK). */\nexport const anthropicSubscriptionUsagePath = '/api/oauth/usage'\n\n/** The `anthropic-beta` value the Claude usage fetcher sends for OAuth credentials. */\nexport const anthropicOAuthBeta = 'oauth-2025-04-20'\n\n/**\n * Route evidence manifest of the Claude subscription-usage route (served by the same fetch\n * handler as the Messages route, with its own ledger and coverage). Synthetic, unverified.\n */\nexport const anthropicSubscriptionUsageEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence> = [\n {\n method: 'GET',\n path: anthropicSubscriptionUsagePath,\n kind: 'provider',\n write: false,\n caseIds: ['anthropic.claude.usage.snapshot'],\n evidence: 'unverified',\n observedAt: undefined\n }\n]\n\n/**\n * The recorded Claude usage body (the synthetic `anthropic.claude.usage.snapshot` fixture, copied\n * as data): `five_hour` and `seven_day` as `{ utilization, resets_at }`.\n */\nexport const anthropicSubscriptionUsageDefault: Schema.Json = recordedUsageBody(\n anthropicClaudeUsageRecording\n)\n\n/** Synthetic-safe default model ids, including the Anthropic Messages conformance defaults. */\nexport const anthropicEmulatorDefaultModels: ReadonlyArray<string> = [\n 'claude-haiku-4-5',\n 'claude-sonnet-4-5'\n]\n\n/**\n * Route evidence manifest: every emulated Anthropic route and the conformance cases whose\n * (currently synthetic, unverified) wire shapes it follows.\n */\nexport const anthropicEmulatorRoutes: ReadonlyArray<EmulatorRouteEvidence> = [\n {\n method: 'POST',\n path: anthropicMessagesPath,\n kind: 'provider',\n write: false,\n caseIds: [\n 'anthropic.messages.stream.plain-text',\n 'anthropic.messages.stream.tool-use-input-deltas',\n 'anthropic.messages.stream.thinking-before-text',\n 'anthropic.messages.stream.error-envelope',\n 'anthropic.messages.stream.max-tokens'\n ],\n evidence: 'unverified',\n observedAt: undefined\n }\n]\n\n/** Optional fault filter; an omitted field matches every request. `path` ending in `*` is a prefix. */\nexport const AnthropicFaultMatch = EmulatorFaultMatch\n\nexport type AnthropicFaultMatch = typeof EmulatorFaultMatch.Type\n\n/** An Anthropic wire error (`{ type, message }`), as sent inside the error envelope. */\nexport const AnthropicWireError = MessagesWireError\n\nexport type AnthropicWireError = MessagesWireError\n\n/** A mid-stream `error` event fault (default `overloaded_error`), streamed responses only. */\nexport const AnthropicErrorEventFault = MessagesErrorEventFault\n\nexport type AnthropicErrorEventFault = typeof MessagesErrorEventFault.Type\n\n/**\n * Wire faults:\n *\n * - `status`: answer with this status, headers, and body (for example 429 with `retry-after`,\n * or 529). The body defaults to the Anthropic error envelope for the status\n * (`rate_limit_error` for 429, `overloaded_error` for 529, `api_error` for other 5xx).\n * - `error-after-chunks`: send N body chunks, then error the body stream (a dropped connection).\n * - `truncate-after-chunks`: send N body chunks, then close cleanly (no `message_stop`).\n * - `error-event-after-chunks`: send N SSE events, then one `event: error` event and close.\n *\n * Statuses that cannot carry a body and redirects are rejected, as are invalid headers and\n * `location`. A fault that cannot take effect answers 500 and is not consumed.\n */\nexport const AnthropicFault = MessagesFault\n\nexport type AnthropicFault = MessagesFault\n\nexport type AnthropicFaultKind = MessagesFaultKind\n\n/** Usage for a scripted turn (sent in `message_start` and `message_delta`). */\nexport const AnthropicScriptedUsage = MessagesScriptedUsage\n\nexport type AnthropicScriptedUsage = MessagesScriptedUsage\n\n/** One scripted `tool_use` block; its JSON input streams as these fragments. */\nexport const AnthropicScriptedToolUse = MessagesScriptedToolUse\n\nexport type AnthropicScriptedToolUse = MessagesScriptedToolUse\n\n/**\n * A scripted message. Every field is exact except: a block is sent only when its field is\n * present; `usage` omitted is synthesized and `null` drops it; `stopReason` omitted is\n * `tool_use` with tool uses, else `end_turn`; `order` defaults to `thinking-first`.\n */\nexport const AnthropicScriptedMessage = MessagesScriptedMessage\n\nexport type AnthropicScriptedMessage = MessagesScriptedMessage\n\n/** A scripted error response: status, body (a string is sent as is), and optional headers. */\nexport const AnthropicScriptedError = EmulatorScriptedError\n\nexport type AnthropicScriptedError = typeof EmulatorScriptedError.Type\n\n/** A turn queued for the next Messages request. */\nexport const AnthropicScriptedTurn = MessagesScriptedTurn\n\nexport type AnthropicScriptedTurn = MessagesScriptedTurn\n\n/** Thrown by the JS API (`faults.add`, `script.enqueue`) for invalid input; a programmer error. */\nexport class AnthropicEmulatorInputInvalid extends Data.TaggedError(\n 'AnthropicEmulatorInputInvalid'\n)<{\n readonly input: 'fault' | 'turn'\n readonly reason: string\n}> {\n override get message(): string {\n return `Invalid Anthropic emulator ${this.input}: ${this.reason}`\n }\n}\n\nexport type AnthropicLedgerEntry = MessagesLedgerEntry\n\nexport type AnthropicFaultState = EmulatorFaultState<AnthropicFault>\n\nexport type AnthropicRouteCoverage = EmulatorRouteCoverage\n\nexport type AnthropicCoverage = EmulatorCoverage\n\n/** A usage-route fault (`status`, `error-after-chunks`, `truncate-after-chunks`). */\nexport const AnthropicUsageFault = SubscriptionUsageFault\n\nexport type AnthropicUsageFault = SubscriptionUsageFault\n\n/** A usage turn: `{ usage }` (a body with the recorded JSON shape) or `{ error }`. */\nexport type AnthropicUsageScriptedTurn = SubscriptionUsageScriptedTurn\n\nexport type AnthropicUsageLedgerEntry = SubscriptionUsageLedgerEntry\n\nexport type AnthropicUsageEmulator = SubscriptionUsageEmulator\n\nexport type AnthropicEmulatorOptions = {\n /** Model ids that exist. Defaults to `anthropicEmulatorDefaultModels`. */\n readonly knownModels?: ReadonlyArray<string>\n /**\n * Replacement usage-route body; must have the recorded JSON shape (same keys and value kinds).\n * Defaults to the recorded body (`anthropicSubscriptionUsageDefault`).\n */\n readonly subscriptionUsage?: Schema.Json\n}\n\n/** The Messages emulator, plus `usage`: the subscription-usage route's own emulator API. */\nexport type AnthropicEmulator = MessagesEmulator & { readonly usage: AnthropicUsageEmulator }\n\n/**\n * Create an Anthropic Messages emulator. Each call has independent ledger, fault, and script\n * state.\n *\n * Without a script, `POST /v1/messages` answers a known model with synthetic content: `stream:\n * true` streams `message_start`, the content blocks (`content_block_start`, deltas,\n * `content_block_stop`, with a `ping` after the first block starts), `message_delta` (stop reason\n * and usage), and `message_stop`; `stream: false` returns one `message` JSON body. A request with\n * `thinking` enabled (`enabled` or `adaptive`) gets a thinking block before the answer. A request\n * with `tools` gets one `tool_use` block whose input is synthesized from the tool's `input_schema`\n * and streamed as `input_json_delta` fragments, stopping with `tool_use`; `tool_choice: { type:\n * 'tool', name }` picks that tool (otherwise the first) and `tool_choice: { type: 'none' }`\n * answers with text. An answer that would exceed `max_tokens` is cut and stops with `max_tokens`.\n * Unknown models get 404 `not_found_error`; a request with neither a non-empty `x-api-key` nor a\n * bearer credential gets 401 `authentication_error`; a missing or unsupported `anthropic-version`\n * (only `2023-06-01` is accepted), a missing or non-positive `max_tokens`, or `thinking` with a\n * forced `tool_choice` (`tool` or `any`) gets 400 `invalid_request_error`; unknown routes get a\n * 404 envelope. The OAuth `anthropic-beta` header and `budget_tokens` limits are not enforced. The\n * ledger records which header carried the credential, `anthropic-version`, and `anthropic-beta`,\n * never a credential value.\n *\n * `GET /api/oauth/usage` is fixture-only: a request with a non-empty bearer credential (never\n * checked or stored), an `anthropic-beta` header listing `oauth-2025-04-20`, `accept:\n * application/json`, and no query gets the recorded body (`anthropicSubscriptionUsageDefault`,\n * or a same-shaped `options.subscriptionUsage` / scripted `{ usage }`); anything else answers 400\n * not-emulated. Throws `AnthropicEmulatorInputInvalid` for a differently shaped\n * `subscriptionUsage`. Its ledger, faults, turns, and coverage are\n * `emulator.usage` (control plane `/_emulate/usage/*`); `emulator.faults` and the other top-level\n * APIs stay the Messages route's. `reset()` and `POST /_emulate/reset` reset both.\n */\nexport const makeAnthropicEmulator = (options: AnthropicEmulatorOptions = {}): AnthropicEmulator =>\n withSubscriptionUsage(\n makeMessagesEmulator({\n path: anthropicMessagesPath,\n routes: anthropicEmulatorRoutes,\n knownModels: options.knownModels ?? anthropicEmulatorDefaultModels,\n inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({ input, reason })\n }),\n makeSubscriptionUsageEmulator({\n path: anthropicSubscriptionUsagePath,\n routes: anthropicSubscriptionUsageEmulatorRoutes,\n recording: anthropicClaudeUsageRecording,\n headers: [\n {\n name: 'anthropic-beta',\n record: true,\n accepts: value =>\n value\n .split(',')\n .map(beta => beta.trim())\n .includes(anthropicOAuthBeta)\n }\n ],\n subscriptionUsage: options.subscriptionUsage,\n inputInvalid: (input, reason) => new AnthropicEmulatorInputInvalid({ input, reason })\n }),\n anthropicSubscriptionUsagePath\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,MAAa,wBAAwB;;AAGrC,MAAa,iCAAiC;;AAG9C,MAAa,qBAAqB;;;;;AAMlC,MAAa,2CAAiF,CAC5F;CACE,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,SAAS,CAAC,iCAAiC;CAC3C,UAAU;CACV,YAAY,KAAA;AACd,CACF;;;;;AAMA,MAAa,oCAAiD,kBAC5D,6BACF;;AAGA,MAAa,iCAAwD,CACnE,oBACA,mBACF;;;;;AAMA,MAAa,0BAAgE,CAC3E;CACE,QAAQ;CACR,MAAM;CACN,MAAM;CACN,OAAO;CACP,SAAS;EACP;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;CACV,YAAY,KAAA;AACd,CACF;;AAGA,MAAa,sBAAsB;;AAKnC,MAAa,qBAAqB;;AAKlC,MAAa,2BAA2B;;;;;;;;;;;;;;AAiBxC,MAAa,iBAAiB;;AAO9B,MAAa,yBAAyB;;AAKtC,MAAa,2BAA2B;;;;;;AASxC,MAAa,2BAA2B;;AAKxC,MAAa,yBAAyB;;AAKtC,MAAa,wBAAwB;;AAKrC,IAAa,gCAAb,cAAmD,KAAK,YACtD,+BACF,EAGG;CACD,IAAa,UAAkB;EAC7B,OAAO,8BAA8B,KAAK,MAAM,IAAI,KAAK;CAC3D;AACF;;AAWA,MAAa,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDnC,MAAa,yBAAyB,UAAoC,CAAC,MACzE,sBACE,qBAAqB;CACnB,MAAM;CACN,QAAQ;CACR,aAAa,QAAQ,eAAe;CACpC,eAAe,OAAO,WAAW,IAAI,8BAA8B;EAAE;EAAO;CAAO,CAAC;AACtF,CAAC,GACD,8BAA8B;CAC5B,MAAM;CACN,QAAQ;CACR,WAAW;CACX,SAAS,CACP;EACE,MAAM;EACN,QAAQ;EACR,UAAS,UACP,MACG,MAAM,GAAG,EACT,KAAI,SAAQ,KAAK,KAAK,CAAC,EACvB,SAAS,kBAAkB;CAClC,CACF;CACA,mBAAmB,QAAQ;CAC3B,eAAe,OAAO,WAAW,IAAI,8BAA8B;EAAE;EAAO;CAAO,CAAC;AACtF,CAAC,GACD,8BACF"}