@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.
- package/LICENSE +21 -0
- package/README.md +2135 -0
- package/dist/anthropic.d.mts +269 -0
- package/dist/anthropic.d.mts.map +1 -0
- package/dist/anthropic.mjs +177 -0
- package/dist/anthropic.mjs.map +1 -0
- package/dist/chat-completions.d.mts +288 -0
- package/dist/chat-completions.d.mts.map +1 -0
- package/dist/chat-completions.mjs +451 -0
- package/dist/chat-completions.mjs.map +1 -0
- package/dist/codex.d.mts +265 -0
- package/dist/codex.d.mts.map +1 -0
- package/dist/codex.mjs +199 -0
- package/dist/codex.mjs.map +1 -0
- package/dist/dropbox/api.d.mts +63 -0
- package/dist/dropbox/api.d.mts.map +1 -0
- package/dist/dropbox/api.mjs +565 -0
- package/dist/dropbox/api.mjs.map +1 -0
- package/dist/dropbox/state.d.mts +136 -0
- package/dist/dropbox/state.d.mts.map +1 -0
- package/dist/dropbox/state.mjs +209 -0
- package/dist/dropbox/state.mjs.map +1 -0
- package/dist/dropbox.d.mts +79 -0
- package/dist/dropbox.d.mts.map +1 -0
- package/dist/dropbox.mjs +124 -0
- package/dist/dropbox.mjs.map +1 -0
- package/dist/email-fixtures.d.mts +36 -0
- package/dist/email-fixtures.d.mts.map +1 -0
- package/dist/email-fixtures.mjs +1080 -0
- package/dist/email-fixtures.mjs.map +1 -0
- package/dist/email.d.mts +160 -0
- package/dist/email.d.mts.map +1 -0
- package/dist/email.mjs +608 -0
- package/dist/email.mjs.map +1 -0
- package/dist/emulator-compose.d.mts +40 -0
- package/dist/emulator-compose.d.mts.map +1 -0
- package/dist/emulator-compose.mjs +91 -0
- package/dist/emulator-compose.mjs.map +1 -0
- package/dist/emulator-http.d.mts +53 -0
- package/dist/emulator-http.d.mts.map +1 -0
- package/dist/emulator-http.mjs +117 -0
- package/dist/emulator-http.mjs.map +1 -0
- package/dist/emulator-kernel.d.mts +176 -0
- package/dist/emulator-kernel.d.mts.map +1 -0
- package/dist/emulator-kernel.mjs +413 -0
- package/dist/emulator-kernel.mjs.map +1 -0
- package/dist/fixture-route.d.mts +129 -0
- package/dist/fixture-route.d.mts.map +1 -0
- package/dist/fixture-route.mjs +257 -0
- package/dist/fixture-route.mjs.map +1 -0
- package/dist/fortnox/api.d.mts +92 -0
- package/dist/fortnox/api.d.mts.map +1 -0
- package/dist/fortnox/api.mjs +750 -0
- package/dist/fortnox/api.mjs.map +1 -0
- package/dist/fortnox/state.d.mts +533 -0
- package/dist/fortnox/state.d.mts.map +1 -0
- package/dist/fortnox/state.mjs +612 -0
- package/dist/fortnox/state.mjs.map +1 -0
- package/dist/fortnox.d.mts +128 -0
- package/dist/fortnox.d.mts.map +1 -0
- package/dist/fortnox.mjs +403 -0
- package/dist/fortnox.mjs.map +1 -0
- package/dist/gateway-evaluate-recordings.d.mts +12 -0
- package/dist/gateway-evaluate-recordings.d.mts.map +1 -0
- package/dist/gateway-evaluate-recordings.mjs +128 -0
- package/dist/gateway-evaluate-recordings.mjs.map +1 -0
- package/dist/gateway.d.mts +272 -0
- package/dist/gateway.d.mts.map +1 -0
- package/dist/gateway.mjs +400 -0
- package/dist/gateway.mjs.map +1 -0
- package/dist/github/api.d.mts +63 -0
- package/dist/github/api.d.mts.map +1 -0
- package/dist/github/api.mjs +527 -0
- package/dist/github/api.mjs.map +1 -0
- package/dist/github/state.d.mts +272 -0
- package/dist/github/state.d.mts.map +1 -0
- package/dist/github/state.mjs +303 -0
- package/dist/github/state.mjs.map +1 -0
- package/dist/github.d.mts +77 -0
- package/dist/github.d.mts.map +1 -0
- package/dist/github.mjs +180 -0
- package/dist/github.mjs.map +1 -0
- package/dist/google/calendar.d.mts +10 -0
- package/dist/google/calendar.d.mts.map +1 -0
- package/dist/google/calendar.mjs +252 -0
- package/dist/google/calendar.mjs.map +1 -0
- package/dist/google/drive.d.mts +8 -0
- package/dist/google/drive.d.mts.map +1 -0
- package/dist/google/drive.mjs +252 -0
- package/dist/google/drive.mjs.map +1 -0
- package/dist/google/gmail.d.mts +10 -0
- package/dist/google/gmail.d.mts.map +1 -0
- package/dist/google/gmail.mjs +591 -0
- package/dist/google/gmail.mjs.map +1 -0
- package/dist/google/shared.d.mts +107 -0
- package/dist/google/shared.d.mts.map +1 -0
- package/dist/google/shared.mjs +146 -0
- package/dist/google/shared.mjs.map +1 -0
- package/dist/google/state.d.mts +385 -0
- package/dist/google/state.d.mts.map +1 -0
- package/dist/google/state.mjs +496 -0
- package/dist/google/state.mjs.map +1 -0
- package/dist/google.d.mts +75 -0
- package/dist/google.d.mts.map +1 -0
- package/dist/google.mjs +210 -0
- package/dist/google.mjs.map +1 -0
- package/dist/linkedin-search/api.d.mts +45 -0
- package/dist/linkedin-search/api.d.mts.map +1 -0
- package/dist/linkedin-search/api.mjs +181 -0
- package/dist/linkedin-search/api.mjs.map +1 -0
- package/dist/linkedin-search/state.d.mts +123 -0
- package/dist/linkedin-search/state.d.mts.map +1 -0
- package/dist/linkedin-search/state.mjs +261 -0
- package/dist/linkedin-search/state.mjs.map +1 -0
- package/dist/linkedin-search.d.mts +69 -0
- package/dist/linkedin-search.d.mts.map +1 -0
- package/dist/linkedin-search.mjs +158 -0
- package/dist/linkedin-search.mjs.map +1 -0
- package/dist/mcp/api.d.mts +44 -0
- package/dist/mcp/api.d.mts.map +1 -0
- package/dist/mcp/api.mjs +557 -0
- package/dist/mcp/api.mjs.map +1 -0
- package/dist/mcp/recordings.d.mts +40 -0
- package/dist/mcp/recordings.d.mts.map +1 -0
- package/dist/mcp/recordings.mjs +2390 -0
- package/dist/mcp/recordings.mjs.map +1 -0
- package/dist/mcp/state.d.mts +71 -0
- package/dist/mcp/state.d.mts.map +1 -0
- package/dist/mcp/state.mjs +83 -0
- package/dist/mcp/state.mjs.map +1 -0
- package/dist/mcp.d.mts +84 -0
- package/dist/mcp.d.mts.map +1 -0
- package/dist/mcp.mjs +241 -0
- package/dist/mcp.mjs.map +1 -0
- package/dist/messages.d.mts +183 -0
- package/dist/messages.d.mts.map +1 -0
- package/dist/messages.mjs +532 -0
- package/dist/messages.mjs.map +1 -0
- package/dist/microsoft/api.d.mts +47 -0
- package/dist/microsoft/api.d.mts.map +1 -0
- package/dist/microsoft/api.mjs +178 -0
- package/dist/microsoft/api.mjs.map +1 -0
- package/dist/microsoft/calendar.d.mts +30 -0
- package/dist/microsoft/calendar.d.mts.map +1 -0
- package/dist/microsoft/calendar.mjs +271 -0
- package/dist/microsoft/calendar.mjs.map +1 -0
- package/dist/microsoft/drive.d.mts +36 -0
- package/dist/microsoft/drive.d.mts.map +1 -0
- package/dist/microsoft/drive.mjs +298 -0
- package/dist/microsoft/drive.mjs.map +1 -0
- package/dist/microsoft/graph.d.mts +198 -0
- package/dist/microsoft/graph.d.mts.map +1 -0
- package/dist/microsoft/graph.mjs +264 -0
- package/dist/microsoft/graph.mjs.map +1 -0
- package/dist/microsoft/mail.d.mts +48 -0
- package/dist/microsoft/mail.d.mts.map +1 -0
- package/dist/microsoft/mail.mjs +488 -0
- package/dist/microsoft/mail.mjs.map +1 -0
- package/dist/microsoft/state.d.mts +480 -0
- package/dist/microsoft/state.d.mts.map +1 -0
- package/dist/microsoft/state.mjs +625 -0
- package/dist/microsoft/state.mjs.map +1 -0
- package/dist/microsoft.d.mts +168 -0
- package/dist/microsoft.d.mts.map +1 -0
- package/dist/microsoft.mjs +483 -0
- package/dist/microsoft.mjs.map +1 -0
- package/dist/node.d.mts +47 -0
- package/dist/node.d.mts.map +1 -0
- package/dist/node.mjs +178 -0
- package/dist/node.mjs.map +1 -0
- package/dist/notion/api.d.mts +51 -0
- package/dist/notion/api.d.mts.map +1 -0
- package/dist/notion/api.mjs +507 -0
- package/dist/notion/api.mjs.map +1 -0
- package/dist/notion/state.d.mts +329 -0
- package/dist/notion/state.d.mts.map +1 -0
- package/dist/notion/state.mjs +432 -0
- package/dist/notion/state.mjs.map +1 -0
- package/dist/notion.d.mts +72 -0
- package/dist/notion.d.mts.map +1 -0
- package/dist/notion.mjs +127 -0
- package/dist/notion.mjs.map +1 -0
- package/dist/openai.d.mts +165 -0
- package/dist/openai.d.mts.map +1 -0
- package/dist/openai.mjs +141 -0
- package/dist/openai.mjs.map +1 -0
- package/dist/opencode-recordings.d.mts +7 -0
- package/dist/opencode-recordings.d.mts.map +1 -0
- package/dist/opencode-recordings.mjs +222 -0
- package/dist/opencode-recordings.mjs.map +1 -0
- package/dist/opencode.d.mts +70 -0
- package/dist/opencode.d.mts.map +1 -0
- package/dist/opencode.mjs +217 -0
- package/dist/opencode.mjs.map +1 -0
- package/dist/r2-fixtures.d.mts +36 -0
- package/dist/r2-fixtures.d.mts.map +1 -0
- package/dist/r2-fixtures.mjs +245 -0
- package/dist/r2-fixtures.mjs.map +1 -0
- package/dist/r2-guard.d.mts +43 -0
- package/dist/r2-guard.d.mts.map +1 -0
- package/dist/r2-guard.mjs +215 -0
- package/dist/r2-guard.mjs.map +1 -0
- package/dist/r2.d.mts +166 -0
- package/dist/r2.d.mts.map +1 -0
- package/dist/r2.mjs +517 -0
- package/dist/r2.mjs.map +1 -0
- package/dist/responses.d.mts +231 -0
- package/dist/responses.d.mts.map +1 -0
- package/dist/responses.mjs +556 -0
- package/dist/responses.mjs.map +1 -0
- package/dist/route-evidence.d.mts +45 -0
- package/dist/route-evidence.d.mts.map +1 -0
- package/dist/route-evidence.mjs +56 -0
- package/dist/route-evidence.mjs.map +1 -0
- package/dist/router.d.mts +93 -0
- package/dist/router.d.mts.map +1 -0
- package/dist/router.mjs +259 -0
- package/dist/router.mjs.map +1 -0
- package/dist/stateful-core.d.mts +17 -0
- package/dist/stateful-core.d.mts.map +1 -0
- package/dist/stateful-core.mjs +41 -0
- package/dist/stateful-core.mjs.map +1 -0
- package/dist/stateful-emulator.d.mts +565 -0
- package/dist/stateful-emulator.d.mts.map +1 -0
- package/dist/stateful-emulator.mjs +1228 -0
- package/dist/stateful-emulator.mjs.map +1 -0
- package/dist/stateful-secrets.d.mts +84 -0
- package/dist/stateful-secrets.d.mts.map +1 -0
- package/dist/stateful-secrets.mjs +216 -0
- package/dist/stateful-secrets.mjs.map +1 -0
- package/dist/subscription-usage-recordings.d.mts +9 -0
- package/dist/subscription-usage-recordings.d.mts.map +1 -0
- package/dist/subscription-usage-recordings.mjs +53 -0
- package/dist/subscription-usage-recordings.mjs.map +1 -0
- package/dist/subscription-usage.d.mts +53 -0
- package/dist/subscription-usage.d.mts.map +1 -0
- package/dist/subscription-usage.mjs +21 -0
- package/dist/subscription-usage.mjs.map +1 -0
- package/dist/telegram/api.d.mts +34 -0
- package/dist/telegram/api.d.mts.map +1 -0
- package/dist/telegram/api.mjs +257 -0
- package/dist/telegram/api.mjs.map +1 -0
- package/dist/telegram/state.d.mts +128 -0
- package/dist/telegram/state.d.mts.map +1 -0
- package/dist/telegram/state.mjs +154 -0
- package/dist/telegram/state.mjs.map +1 -0
- package/dist/telegram.d.mts +62 -0
- package/dist/telegram.d.mts.map +1 -0
- package/dist/telegram.mjs +127 -0
- package/dist/telegram.mjs.map +1 -0
- package/dist/todoist/api.d.mts +55 -0
- package/dist/todoist/api.d.mts.map +1 -0
- package/dist/todoist/api.mjs +415 -0
- package/dist/todoist/api.mjs.map +1 -0
- package/dist/todoist/state.d.mts +275 -0
- package/dist/todoist/state.d.mts.map +1 -0
- package/dist/todoist/state.mjs +345 -0
- package/dist/todoist/state.mjs.map +1 -0
- package/dist/todoist.d.mts +68 -0
- package/dist/todoist.d.mts.map +1 -0
- package/dist/todoist.mjs +181 -0
- package/dist/todoist.mjs.map +1 -0
- package/dist/xai.d.mts +267 -0
- package/dist/xai.d.mts.map +1 -0
- package/dist/xai.mjs +252 -0
- package/dist/xai.mjs.map +1 -0
- package/package.json +157 -0
- package/src/anthropic.ts +289 -0
- package/src/chat-completions.ts +924 -0
- package/src/codex.ts +296 -0
- package/src/dropbox/api.ts +1084 -0
- package/src/dropbox/state.ts +364 -0
- package/src/dropbox.ts +203 -0
- package/src/email-fixtures.ts +1297 -0
- package/src/email.ts +1108 -0
- package/src/emulator-compose.ts +147 -0
- package/src/emulator-http.ts +184 -0
- package/src/emulator-kernel.ts +844 -0
- package/src/fixture-route.ts +561 -0
- package/src/fortnox/api.ts +1352 -0
- package/src/fortnox/state.ts +798 -0
- package/src/fortnox.ts +801 -0
- package/src/gateway-evaluate-recordings.ts +153 -0
- package/src/gateway.ts +530 -0
- package/src/github/api.ts +986 -0
- package/src/github/state.ts +439 -0
- package/src/github.ts +271 -0
- package/src/google/calendar.ts +486 -0
- package/src/google/drive.ts +471 -0
- package/src/google/gmail.ts +1011 -0
- package/src/google/shared.ts +321 -0
- package/src/google/state.ts +686 -0
- package/src/google.ts +298 -0
- package/src/linkedin-search/api.ts +363 -0
- package/src/linkedin-search/state.ts +373 -0
- package/src/linkedin-search.ts +241 -0
- package/src/mcp/api.ts +995 -0
- package/src/mcp/recordings.ts +2665 -0
- package/src/mcp/state.ts +125 -0
- package/src/mcp.ts +319 -0
- package/src/messages.ts +844 -0
- package/src/microsoft/api.ts +426 -0
- package/src/microsoft/calendar.ts +491 -0
- package/src/microsoft/drive.ts +541 -0
- package/src/microsoft/graph.ts +550 -0
- package/src/microsoft/mail.ts +833 -0
- package/src/microsoft/state.ts +822 -0
- package/src/microsoft.ts +982 -0
- package/src/node.ts +293 -0
- package/src/notion/api.ts +976 -0
- package/src/notion/state.ts +512 -0
- package/src/notion.ts +210 -0
- package/src/openai.ts +198 -0
- package/src/opencode-recordings.ts +257 -0
- package/src/opencode.ts +271 -0
- package/src/r2-fixtures.ts +295 -0
- package/src/r2-guard.ts +323 -0
- package/src/r2.ts +890 -0
- package/src/responses.ts +901 -0
- package/src/route-evidence.ts +90 -0
- package/src/router.ts +490 -0
- package/src/stateful-core.ts +70 -0
- package/src/stateful-emulator.ts +2571 -0
- package/src/stateful-secrets.ts +299 -0
- package/src/subscription-usage-recordings.ts +77 -0
- package/src/subscription-usage.ts +68 -0
- package/src/telegram/api.ts +437 -0
- package/src/telegram/state.ts +229 -0
- package/src/telegram.ts +227 -0
- package/src/todoist/api.ts +736 -0
- package/src/todoist/state.ts +456 -0
- package/src/todoist.ts +316 -0
- package/src/xai.ts +341 -0
package/src/anthropic.ts
ADDED
|
@@ -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
|
+
)
|