@tonyclaw/agent-inspector 2.0.37 → 2.0.39

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 (88) hide show
  1. package/.output/cli.js +528 -24
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-nEHCEVP4.js → CompareDrawer-Jfe6M6DQ.js} +1 -1
  4. package/.output/public/assets/{ProxyViewerContainer-BstBIX2B.js → ProxyViewerContainer-CQKV0Bqq.js} +15 -15
  5. package/.output/public/assets/{ReplayDialog-CUnBdt1Q.js → ReplayDialog-B58TbTtY.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-BU9VT2Sw.js → RequestAnatomy-d4P6JNiP.js} +1 -1
  7. package/.output/public/assets/{ResponseView-amxuKPKY.js → ResponseView-Bum1a3tG.js} +1 -1
  8. package/.output/public/assets/{StreamingChunkSequence-DpscrQM2.js → StreamingChunkSequence-CjBDp5E9.js} +1 -1
  9. package/.output/public/assets/_sessionId-BupV2gtf.js +1 -0
  10. package/.output/public/assets/index-DHSww5em.js +1 -0
  11. package/.output/public/assets/{main-D56QvEyw.js → main-DK9PoBjx.js} +2 -2
  12. package/.output/server/{_sessionId-ChwEDyI4.mjs → _sessionId-DjarbXpT.mjs} +2 -2
  13. package/.output/server/_ssr/{CompareDrawer-Ce2590rK.mjs → CompareDrawer-C5Z6AlUk.mjs} +2 -2
  14. package/.output/server/_ssr/{ProxyViewerContainer-D6xM8A0S.mjs → ProxyViewerContainer-4pXsBywn.mjs} +37 -9
  15. package/.output/server/_ssr/{ReplayDialog-CB4KOlLe.mjs → ReplayDialog-w1vc1p5e.mjs} +3 -3
  16. package/.output/server/_ssr/{RequestAnatomy-CsWV3W03.mjs → RequestAnatomy-2HaBhsNV.mjs} +2 -2
  17. package/.output/server/_ssr/{ResponseView-BuCCV3LU.mjs → ResponseView-SO_Y_W85.mjs} +2 -2
  18. package/.output/server/_ssr/{StreamingChunkSequence-C5dE7V1d.mjs → StreamingChunkSequence-CXEa2DkO.mjs} +2 -2
  19. package/.output/server/_ssr/{index-BeIi0CPv.mjs → index-DuCGt4a2.mjs} +2 -2
  20. package/.output/server/_ssr/index.mjs +2 -2
  21. package/.output/server/_ssr/{router-Ca2MCyUX.mjs → router-D0BaSzkZ.mjs} +69 -76
  22. package/.output/server/{_tanstack-start-manifest_v-CBAJfSAX.mjs → _tanstack-start-manifest_v-6N4SODyd.mjs} +1 -1
  23. package/.output/server/index.mjs +62 -62
  24. package/README.md +8 -1
  25. package/package.json +1 -1
  26. package/src/cli/onboard.ts +629 -21
  27. package/src/components/ProxyViewer.tsx +1 -1
  28. package/src/components/ProxyViewerContainer.tsx +1 -1
  29. package/src/components/providers/ProviderForm.tsx +2 -2
  30. package/src/components/providers/SettingsDialog.tsx +30 -0
  31. package/src/components/proxy-viewer/AgentTraceSummary.tsx +1 -1
  32. package/src/components/proxy-viewer/CompareDrawer.tsx +1 -1
  33. package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
  34. package/src/components/proxy-viewer/ConversationGroupList.tsx +1 -1
  35. package/src/components/proxy-viewer/ConversationHeader.tsx +1 -1
  36. package/src/components/proxy-viewer/LogEntry.tsx +1 -1
  37. package/src/components/proxy-viewer/LogEntryHeader.tsx +1 -1
  38. package/src/components/proxy-viewer/ReplayDialog.tsx +1 -1
  39. package/src/components/proxy-viewer/ResponseView.tsx +2 -2
  40. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +1 -1
  41. package/src/components/proxy-viewer/TurnGroup.tsx +1 -1
  42. package/src/components/proxy-viewer/anatomy/sessionContextSummary.ts +1 -1
  43. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +1 -1
  44. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +2 -2
  45. package/src/components/proxy-viewer/formats/index.tsx +5 -3
  46. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +1 -1
  47. package/src/components/proxy-viewer/log-formats/anthropic.ts +1 -4
  48. package/src/components/proxy-viewer/log-formats/index.ts +6 -6
  49. package/src/components/proxy-viewer/log-formats/openai.ts +1 -1
  50. package/src/components/proxy-viewer/log-formats/types.ts +2 -2
  51. package/src/components/proxy-viewer/viewerState.ts +1 -1
  52. package/src/contracts/anthropic.ts +235 -0
  53. package/src/contracts/index.ts +27 -0
  54. package/src/contracts/json.ts +32 -0
  55. package/src/contracts/log.ts +72 -0
  56. package/src/contracts/openai.ts +176 -0
  57. package/src/knowledge/distiller.ts +1 -1
  58. package/src/lib/export-logs.ts +1 -1
  59. package/src/lib/groupContract.ts +1 -1
  60. package/src/lib/objectUtils.ts +3 -3
  61. package/src/lib/providerTestContract.ts +1 -1
  62. package/src/lib/runContract.ts +1 -1
  63. package/src/lib/stopReason.ts +1 -1
  64. package/src/mcp/previewExtractor.ts +4 -7
  65. package/src/mcp/server.ts +1 -1
  66. package/src/mcp/toolHandlers.ts +1 -1
  67. package/src/proxy/formats/anthropic/anthropicProvider.ts +2 -2
  68. package/src/proxy/formats/anthropic/schemas.ts +12 -235
  69. package/src/proxy/formats/handler.ts +2 -2
  70. package/src/proxy/formats/index.ts +1 -1
  71. package/src/proxy/formats/jsonSchema.ts +2 -36
  72. package/src/proxy/formats/openai/alibabaProvider.ts +2 -2
  73. package/src/proxy/formats/openai/provider.ts +2 -2
  74. package/src/proxy/formats/openai/schemas.ts +14 -187
  75. package/src/proxy/formats/openai/zhipuProvider.ts +2 -2
  76. package/src/proxy/formats/{protocol.ts → providerAdapter.ts} +5 -5
  77. package/src/proxy/formats/providerRegistry.ts +7 -7
  78. package/src/proxy/formats/providers/index.ts +1 -1
  79. package/src/proxy/formats/registry.ts +16 -13
  80. package/src/proxy/handler.ts +1 -1
  81. package/src/proxy/openaiOrphanToolStrip.ts +1 -1
  82. package/src/proxy/providers.ts +1 -1
  83. package/src/proxy/schemas.ts +18 -80
  84. package/src/proxy/store.ts +2 -2
  85. package/src/proxy/upstream.ts +1 -1
  86. package/src/routes/api/logs.stream.ts +1 -1
  87. package/.output/public/assets/_sessionId-7c9bsOFT.js +0 -1
  88. package/.output/public/assets/index-B7a5OmIO.js +0 -1
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ import { JsonValueSchema } from "./json";
3
+
4
+ export type ApiFormat = "anthropic" | "openai" | "unknown";
5
+ export type RequestFormat = ApiFormat;
6
+
7
+ /**
8
+ * A single SSE event from a streaming response.
9
+ */
10
+ export const StreamingChunkSchema = z.object({
11
+ index: z.number(),
12
+ timestamp: z.number(),
13
+ type: z.string(),
14
+ data: JsonValueSchema,
15
+ });
16
+
17
+ export type StreamingChunk = z.infer<typeof StreamingChunkSchema>;
18
+
19
+ const StreamingChunksArraySchema = z.object({
20
+ chunks: z.array(StreamingChunkSchema),
21
+ truncated: z.boolean().optional().default(false),
22
+ });
23
+
24
+ export const CapturedLogSchema = z.object({
25
+ id: z.number(),
26
+ timestamp: z.string(),
27
+ method: z.string(),
28
+ path: z.string(),
29
+ model: z.string().nullable(),
30
+ sessionId: z.string().nullable(),
31
+ rawRequestBody: z.string().nullable(),
32
+ responseStatus: z.number().nullable(),
33
+ responseText: z.string().nullable(),
34
+ inputTokens: z.number().nullable(),
35
+ outputTokens: z.number().nullable(),
36
+ cacheCreationInputTokens: z.number().nullable(),
37
+ cacheReadInputTokens: z.number().nullable(),
38
+ elapsedMs: z.number().nullable(),
39
+ firstChunkMs: z.number().nullable().optional(),
40
+ totalStreamMs: z.number().nullable().optional(),
41
+ tokensPerSecond: z.number().nullable().optional(),
42
+ streaming: z.boolean(),
43
+ userAgent: z.string().nullable(),
44
+ origin: z.string().nullable(),
45
+ rawHeaders: z.record(z.string(), z.string()).optional(),
46
+ /** Headers sent to the upstream LLM */
47
+ headers: z.record(z.string(), z.string()).optional(),
48
+ apiFormat: z.enum(["anthropic", "openai", "unknown"]).default("unknown"),
49
+ isTest: z.boolean().optional().default(false),
50
+ replayOfLogId: z.number().nullable().optional(),
51
+ providerName: z.string().nullable().optional(),
52
+ clientPort: z.number().nullable().optional(),
53
+ clientPid: z.number().nullable().optional(),
54
+ clientCwd: z.string().nullable().optional(),
55
+ clientProjectFolder: z.string().nullable().optional(),
56
+ streamingChunks: StreamingChunksArraySchema.optional(),
57
+ streamingChunksPath: z.string().nullable().optional(),
58
+ rawRequestBodyBytes: z.number().int().nonnegative().nullable().optional(),
59
+ responseTextBytes: z.number().int().nonnegative().nullable().optional(),
60
+ bodyContentMode: z.enum(["full", "compact", "truncated"]).optional(),
61
+ /** Error message from streaming response (e.g., SSE error event) */
62
+ error: z.string().nullable().optional(),
63
+ });
64
+
65
+ export type CapturedLog = z.infer<typeof CapturedLogSchema>;
66
+
67
+ export type TokenUsage = {
68
+ inputTokens: number | null;
69
+ outputTokens: number | null;
70
+ cacheCreationInputTokens: number | null;
71
+ cacheReadInputTokens: number | null;
72
+ };
@@ -0,0 +1,176 @@
1
+ import { z } from "zod";
2
+ import { JsonValueSchema } from "./json";
3
+
4
+ export const OpenAIMessageContent = z.union([
5
+ z.string(),
6
+ z.array(
7
+ z.discriminatedUnion("type", [
8
+ z.object({ type: z.literal("text"), text: z.string() }),
9
+ z.object({
10
+ type: z.literal("image_url"),
11
+ image_url: z.object({ url: z.string(), detail: z.string().optional() }),
12
+ }),
13
+ ]),
14
+ ),
15
+ ]);
16
+
17
+ export const OpenAIMessage = z.object({
18
+ role: z.enum(["system", "user", "assistant", "tool"]),
19
+ content: OpenAIMessageContent,
20
+ name: z.string().optional(),
21
+ reasoning_content: z.string().optional(),
22
+ thinking: z.string().optional(),
23
+ think: z.string().optional(),
24
+ });
25
+
26
+ export const OpenAIFunctionCall = z.object({
27
+ name: z.string(),
28
+ arguments: z.string(),
29
+ });
30
+
31
+ export const OpenAIToolCallSchema = z.object({
32
+ index: z.number().optional(),
33
+ id: z.string().optional(),
34
+ type: z.literal("function").optional(),
35
+ function: z.object({
36
+ name: z.string().optional(),
37
+ arguments: z.string().optional(),
38
+ }),
39
+ });
40
+
41
+ export type OpenAIToolCall = z.infer<typeof OpenAIToolCallSchema>;
42
+
43
+ const OpenAIMessageWithFunctionCall = OpenAIMessage.extend({
44
+ content: z
45
+ .union([z.string(), z.array(z.object({ type: z.literal("text"), text: z.string() }))])
46
+ .optional(),
47
+ function_call: OpenAIFunctionCall.optional(),
48
+ tool_calls: z.array(OpenAIToolCallSchema).optional(),
49
+ });
50
+
51
+ export const OpenAIToolDefinition = z.object({
52
+ type: z.literal("function"),
53
+ function: z.object({
54
+ name: z.string(),
55
+ description: z.string().optional(),
56
+ parameters: z.record(z.string(), JsonValueSchema),
57
+ }),
58
+ });
59
+
60
+ export const OpenAIRequestSchema = z.object({
61
+ model: z.string(),
62
+ messages: z.array(OpenAIMessage),
63
+ temperature: z.number().optional(),
64
+ max_tokens: z.number().optional(),
65
+ stream: z.boolean().optional(),
66
+ tools: z.array(OpenAIToolDefinition).optional(),
67
+ tool_choice: z
68
+ .union([
69
+ z.enum(["auto", "none", "required"]),
70
+ z.object({ type: z.literal("auto") }),
71
+ z.object({ type: z.literal("none") }),
72
+ z.object({ type: z.literal("function"), function: z.object({ name: z.string() }) }),
73
+ ])
74
+ .optional(),
75
+ user: z.string().optional(),
76
+ });
77
+
78
+ export const OpenAIChoiceDelta = z.object({
79
+ role: z.enum(["assistant"]).optional(),
80
+ content: z.string().nullable().optional(),
81
+ reasoning_content: z.string().nullable().optional(),
82
+ thinking: z.string().nullable().optional(),
83
+ think: z.string().nullable().optional(),
84
+ function_call: z
85
+ .object({ name: z.string().optional(), arguments: z.string().optional() })
86
+ .nullable()
87
+ .optional(),
88
+ tool_calls: z
89
+ .array(
90
+ z.object({
91
+ index: z.number(),
92
+ id: z.string().optional(),
93
+ type: z.literal("function").optional(),
94
+ function: z.object({
95
+ name: z.string().optional(),
96
+ arguments: z.string().optional(),
97
+ }),
98
+ }),
99
+ )
100
+ .nullable()
101
+ .optional(),
102
+ });
103
+
104
+ export const OpenAIChoice = z.object({
105
+ index: z.number(),
106
+ message: z
107
+ .object({
108
+ role: z.enum(["assistant"]),
109
+ content: z.string().nullable(),
110
+ reasoning_content: z.string().optional(),
111
+ thinking: z.string().optional(),
112
+ think: z.string().optional(),
113
+ function_call: z.object({ name: z.string(), arguments: z.string() }).nullable().optional(),
114
+ tool_calls: z.array(OpenAIToolCallSchema).optional(),
115
+ })
116
+ .optional(),
117
+ delta: OpenAIChoiceDelta.optional(),
118
+ finish_reason: z.string().nullable(),
119
+ });
120
+
121
+ export const OpenAIResponseSchema = z
122
+ .object({
123
+ id: z.string(),
124
+ object: z.literal("chat.completion"),
125
+ created: z.number(),
126
+ model: z.string(),
127
+ choices: z.array(OpenAIChoice),
128
+ usage: z
129
+ .object({
130
+ prompt_tokens: z.number().nullable().optional(),
131
+ completion_tokens: z.number().nullable().optional(),
132
+ total_tokens: z.number().nullable().optional(),
133
+ })
134
+ .passthrough(),
135
+ service_tier: z.string().nullable().optional(),
136
+ system_fingerprint: z.string().nullable().optional(),
137
+ })
138
+ .passthrough();
139
+
140
+ export const OpenAISSERawChunkSchema = z
141
+ .object({
142
+ id: z.string(),
143
+ object: z.literal("chat.completion.chunk"),
144
+ created: z.number(),
145
+ model: z.string(),
146
+ choices: z.array(
147
+ z.object({
148
+ index: z.number(),
149
+ delta: OpenAIChoiceDelta,
150
+ finish_reason: z.string().nullable().optional(),
151
+ }),
152
+ ),
153
+ usage: z
154
+ .object({
155
+ prompt_tokens: z.number().nullable().optional(),
156
+ completion_tokens: z.number().nullable().optional(),
157
+ total_tokens: z.number().nullable().optional(),
158
+ })
159
+ .passthrough()
160
+ .nullable()
161
+ .optional(),
162
+ })
163
+ .passthrough();
164
+
165
+ export type OpenAIResponse = z.infer<typeof OpenAIResponseSchema>;
166
+
167
+ export function parseOpenAIResponse(rawBody: string): OpenAIResponse | null {
168
+ try {
169
+ const json: unknown = JSON.parse(rawBody);
170
+ const result = OpenAIResponseSchema.safeParse(json);
171
+ if (result.success) return result.data;
172
+ return null;
173
+ } catch {
174
+ return null;
175
+ }
176
+ }
@@ -1,5 +1,5 @@
1
1
  import { extractLastUserMessagePreview, extractResponsePreview } from "../mcp/previewExtractor";
2
- import type { CapturedLog } from "../proxy/schemas";
2
+ import type { CapturedLog } from "../contracts";
3
3
  import type { KnowledgeCandidate, KnowledgeCandidateType } from "./types";
4
4
  import { redactCandidate } from "./redactor";
5
5
 
@@ -1,5 +1,5 @@
1
1
  import JSZip from "jszip";
2
- import type { CapturedLog } from "../proxy/schemas";
2
+ import type { CapturedLog } from "../contracts";
3
3
 
4
4
  export type ExportMode = "redacted" | "raw";
5
5
  export type ExportLogsResult =
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { JsonValueSchema } from "../proxy/schemas";
2
+ import { JsonValueSchema } from "../contracts";
3
3
  import { EvidenceReportSchema, InspectorRunSchema, InspectorRunStatusSchema } from "./runContract";
4
4
  import { SessionInfoSchema, SessionTokenUsageSchema } from "./sessionInfoContract";
5
5
 
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Generic object utilities shared across protocol modules.
3
- * Only truly protocol-agnostic helpers belong here Anthropic/OpenAI-specific
4
- * checks stay in their respective format modules.
2
+ * Generic object utilities shared across API format modules.
3
+ * Only truly format-agnostic helpers belong here; Anthropic/OpenAI-specific
4
+ * checks stay in their respective API format modules.
5
5
  */
6
6
 
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { StreamingChunkSchema } from "../proxy/schemas";
2
+ import { StreamingChunkSchema } from "../contracts";
3
3
 
4
4
  export const ProviderTestErrorTypeSchema = z.enum([
5
5
  "timeout",
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { JsonValueSchema } from "../proxy/schemas";
2
+ import { JsonValueSchema } from "../contracts";
3
3
  import { SessionInfoSchema } from "./sessionInfoContract";
4
4
 
5
5
  export const InspectorRunStatusSchema = z.enum([
@@ -1,4 +1,4 @@
1
- import type { CapturedLog } from "../proxy/schemas";
1
+ import type { CapturedLog } from "../contracts";
2
2
 
3
3
  export type StopReason = "end_turn" | "tool_use" | "stop" | null;
4
4
 
@@ -10,7 +10,7 @@
10
10
  * agent needs to make a "is this the log I care about?" judgment from
11
11
  * `list_logs` alone.
12
12
  *
13
- * Null returns are an expected and frequent outcome they cover:
13
+ * Null returns are an expected and frequent outcome; they cover:
14
14
  * - `apiFormat === "unknown"`
15
15
  * - `rawRequestBody` / `responseText` is null
16
16
  * - JSON.parse failure
@@ -19,12 +19,9 @@
19
19
  * - the relevant content is non-text (e.g., image-only multimodal block)
20
20
  */
21
21
 
22
- import type { CapturedLog } from "../proxy/schemas";
23
- import {
24
- AnthropicRequestSchema,
25
- AnthropicResponseSchema,
26
- } from "../proxy/formats/anthropic/schemas";
27
- import { OpenAIRequestSchema, OpenAIResponseSchema } from "../proxy/formats/openai/schemas";
22
+ import type { CapturedLog } from "../contracts";
23
+ import { AnthropicRequestSchema, AnthropicResponseSchema } from "../contracts/anthropic";
24
+ import { OpenAIRequestSchema, OpenAIResponseSchema } from "../contracts/openai";
28
25
 
29
26
  /** Preview length cap, per design D5. */
30
27
  const PREVIEW_MAX_CHARS = 500;
package/src/mcp/server.ts CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  } from "../lib/groupContract";
35
35
  import { InspectorRunStatusSchema, UpdateInspectorRunInputSchema } from "../lib/runContract";
36
36
  import { setCurrentPort } from "../lib/serverPort";
37
- import { JsonValueSchema } from "../proxy/schemas";
37
+ import { JsonValueSchema } from "../contracts";
38
38
  import {
39
39
  getInspectorGroup,
40
40
  listInspectorGroups,
@@ -28,7 +28,7 @@ import {
28
28
  } from "../lib/groupContract";
29
29
  import { type CreateInspectorRunInput, type UpdateInspectorRunInput } from "../lib/runContract";
30
30
  import { SessionInfoSchema } from "../lib/sessionInfoContract";
31
- import { CapturedLogSchema, type CapturedLog } from "../proxy/schemas";
31
+ import { CapturedLogSchema, type CapturedLog } from "../contracts";
32
32
  import {
33
33
  addInspectorGroupSession,
34
34
  createInspectorGroup,
@@ -1,5 +1,5 @@
1
1
  import type { CapturedLog } from "../../schemas";
2
- import type { ProviderProtocol } from "../protocol";
2
+ import type { ProviderAdapter } from "../providerAdapter";
3
3
  import { registry } from "../providers";
4
4
  import { extractAnthropicStream } from "./stream";
5
5
 
@@ -27,7 +27,7 @@ function getUpstreamForModel(model: string): string {
27
27
  /**
28
28
  * Anthropic Provider Implementation
29
29
  */
30
- export const anthropicProvider: ProviderProtocol = {
30
+ export const anthropicProvider: ProviderAdapter = {
31
31
  name: "anthropic",
32
32
 
33
33
  matches(model: string): boolean {
@@ -1,235 +1,12 @@
1
- import { z } from "zod";
2
- import { JsonValueSchema } from "../jsonSchema";
3
-
4
- const CacheControl = z.object({
5
- type: z.string(),
6
- ttl: z.string().optional(),
7
- scope: z.string().optional(),
8
- });
9
-
10
- const TextContentBlock = z.object({
11
- type: z.literal("text"),
12
- text: z.string(),
13
- cache_control: CacheControl.optional(),
14
- });
15
-
16
- const ThinkingContentBlock = z.object({
17
- type: z.literal("thinking"),
18
- thinking: z.string(),
19
- signature: z.string().optional(),
20
- });
21
-
22
- const ThinkContentBlock = z.object({
23
- type: z.literal("think"),
24
- thinking: z.string(),
25
- signature: z.string().optional(),
26
- });
27
-
28
- const ImageSourceBlock = z.object({
29
- type: z.literal("base64"),
30
- media_type: z.string(),
31
- data: z.string(),
32
- });
33
-
34
- const ImageContentBlock = z.object({
35
- type: z.literal("image"),
36
- source: ImageSourceBlock,
37
- });
38
-
39
- const ToolUseContentBlock = z.object({
40
- type: z.literal("tool_use"),
41
- id: z.string(),
42
- name: z.string(),
43
- input: z.record(z.string(), JsonValueSchema),
44
- });
45
-
46
- const ToolResultContentItem = z.discriminatedUnion("type", [TextContentBlock, ImageContentBlock]);
47
-
48
- const ToolResultContentBlock = z.object({
49
- type: z.literal("tool_result"),
50
- tool_use_id: z.string().optional(),
51
- content: z.union([z.string(), z.array(ToolResultContentItem)]),
52
- is_error: z.boolean().optional(),
53
- });
54
-
55
- const ContentBlock = z.discriminatedUnion("type", [
56
- TextContentBlock,
57
- ThinkingContentBlock,
58
- ImageContentBlock,
59
- ToolUseContentBlock,
60
- ToolResultContentBlock,
61
- ]);
62
-
63
- const MessageContent = z.union([z.string(), z.array(ContentBlock)]);
64
-
65
- const Message = z.object({
66
- role: z.enum(["user", "assistant"]),
67
- content: MessageContent,
68
- });
69
-
70
- const SystemBlock = z.object({
71
- type: z.literal("text"),
72
- text: z.string(),
73
- cache_control: CacheControl.optional(),
74
- });
75
-
76
- const InputSchema = z.object({
77
- type: z.string(),
78
- properties: z.record(z.string(), z.record(z.string(), JsonValueSchema)).optional(),
79
- required: z.array(z.string()).optional(),
80
- additionalProperties: z.boolean().optional(),
81
- $schema: z.string().optional(),
82
- });
83
-
84
- const ToolDefinition = z.object({
85
- name: z.string(),
86
- description: z.string().optional(),
87
- input_schema: InputSchema.optional(),
88
- cache_control: CacheControl.optional(),
89
- });
90
-
91
- const ThinkingConfig = z.discriminatedUnion("type", [
92
- z.object({ type: z.literal("enabled"), budget_tokens: z.number() }),
93
- z.object({ type: z.literal("disabled") }),
94
- z.object({ type: z.literal("adaptive") }),
95
- ]);
96
-
97
- export const AnthropicRequestSchema = z.object({
98
- model: z.string(),
99
- messages: z.array(Message),
100
- system: z.array(SystemBlock).optional(),
101
- tools: z.array(ToolDefinition).optional(),
102
- max_tokens: z.number().optional(),
103
- temperature: z.number().optional(),
104
- stream: z.boolean().optional(),
105
- thinking: ThinkingConfig.optional(),
106
- metadata: z
107
- .object({
108
- user_id: z.string().optional(),
109
- })
110
- .optional(),
111
- });
112
-
113
- const ResponseContentBlock = z.discriminatedUnion("type", [
114
- TextContentBlock,
115
- ThinkingContentBlock,
116
- ThinkContentBlock,
117
- ToolUseContentBlock,
118
- ]);
119
-
120
- const ResponseUsageSchema = z
121
- .object({
122
- input_tokens: z.number().nullable().optional(),
123
- output_tokens: z.number().nullable().optional(),
124
- cache_creation_input_tokens: z.number().nullable().optional(),
125
- cache_read_input_tokens: z.number().nullable().optional(),
126
- })
127
- .passthrough(); // Allow extra fields from different providers
128
-
129
- export const AnthropicResponseSchema = z
130
- .object({
131
- id: z.string(),
132
- type: z.literal("message"),
133
- model: z.string(),
134
- role: z.literal("assistant"),
135
- content: z.array(ResponseContentBlock),
136
- stop_reason: z.string().nullable(),
137
- stop_sequence: z.string().nullable().optional(),
138
- usage: ResponseUsageSchema,
139
- })
140
- .passthrough(); // Allow extra unknown fields
141
-
142
- const SseMessageStartEvent = z.object({
143
- type: z.literal("message_start"),
144
- message: z.object({
145
- id: z.string(),
146
- type: z.literal("message"),
147
- model: z.string(),
148
- role: z.literal("assistant"),
149
- content: z.array(ResponseContentBlock),
150
- stop_reason: z.null(),
151
- stop_sequence: z.null(),
152
- usage: z
153
- .object({
154
- input_tokens: z.number(),
155
- cache_creation_input_tokens: z.number().optional(),
156
- cache_read_input_tokens: z.number().optional(),
157
- })
158
- .passthrough(),
159
- }),
160
- });
161
-
162
- const SseContentBlockStartEvent = z.object({
163
- type: z.literal("content_block_start"),
164
- index: z.number(),
165
- content_block: ResponseContentBlock,
166
- });
167
-
168
- const SseDeltaBlock = z.discriminatedUnion("type", [
169
- z.object({ type: z.literal("text_delta"), text: z.string() }),
170
- z.object({ type: z.literal("input_json_delta"), partial_json: z.string() }),
171
- z.object({ type: z.literal("thinking_delta"), thinking: z.string() }),
172
- z.object({ type: z.literal("signature_delta"), signature: z.string() }),
173
- ]);
174
-
175
- const SseContentBlockDeltaEvent = z.object({
176
- type: z.literal("content_block_delta"),
177
- index: z.number(),
178
- delta: SseDeltaBlock,
179
- });
180
-
181
- const SseContentBlockStopEvent = z.object({
182
- type: z.literal("content_block_stop"),
183
- index: z.number(),
184
- });
185
-
186
- const SseMessageDeltaEvent = z.object({
187
- type: z.literal("message_delta"),
188
- delta: z.object({
189
- stop_reason: z.string().nullable(),
190
- stop_sequence: z.string().nullable().optional(),
191
- }),
192
- usage: z
193
- .object({
194
- output_tokens: z.number(),
195
- input_tokens: z.number().optional(),
196
- cache_creation_input_tokens: z.number().optional(),
197
- cache_read_input_tokens: z.number().optional(),
198
- })
199
- .passthrough(),
200
- });
201
-
202
- const SseMessageStopEvent = z.object({
203
- type: z.literal("message_stop"),
204
- });
205
-
206
- const SsePingEvent = z.object({
207
- type: z.literal("ping"),
208
- });
209
-
210
- const SseErrorEvent = z.object({
211
- type: z.literal("error"),
212
- error: z.object({
213
- type: z.string(),
214
- message: z.string(),
215
- }),
216
- });
217
-
218
- export const SseEventSchema = z.discriminatedUnion("type", [
219
- SseMessageStartEvent,
220
- SseContentBlockStartEvent,
221
- SseContentBlockDeltaEvent,
222
- SseContentBlockStopEvent,
223
- SseMessageDeltaEvent,
224
- SseMessageStopEvent,
225
- SsePingEvent,
226
- SseErrorEvent,
227
- ]);
228
-
229
- export type AnthropicResponse = z.infer<typeof AnthropicResponseSchema>;
230
- export type ResponseContentBlockType = z.infer<typeof ResponseContentBlock>;
231
-
232
- // Backward-compatible aliases (originally named Inspector*)
233
- export const InspectorRequestSchema = AnthropicRequestSchema;
234
- export const InspectorResponseSchema = AnthropicResponseSchema;
235
- export type InspectorResponse = AnthropicResponse;
1
+ export {
2
+ AnthropicRequestSchema,
3
+ AnthropicResponseSchema,
4
+ InspectorRequestSchema,
5
+ InspectorResponseSchema,
6
+ SseEventSchema,
7
+ } from "../../../contracts/anthropic";
8
+ export type {
9
+ AnthropicResponse,
10
+ InspectorResponse,
11
+ ResponseContentBlockType,
12
+ } from "../../../contracts/anthropic";
@@ -1,4 +1,4 @@
1
- import type { CapturedLog, RequestFormat, TokenUsage } from "../schemas";
1
+ import type { ApiFormat, CapturedLog, TokenUsage } from "../schemas";
2
2
 
3
3
  /**
4
4
  * Structured result of parsing a raw request body.
@@ -17,7 +17,7 @@ export type ParsedRequest = {
17
17
  */
18
18
  export type FormatHandler = {
19
19
  /** The format identifier */
20
- readonly format: RequestFormat;
20
+ readonly format: ApiFormat;
21
21
 
22
22
  /**
23
23
  * Parse a raw request body to extract model name and metadata.
@@ -9,5 +9,5 @@ import "./openai/zhipuProvider";
9
9
  import "./openai/alibabaProvider";
10
10
 
11
11
  export type { FormatHandler, ParsedRequest } from "./handler";
12
- export { formatRegistry, formatForPath, requestFormatForPath } from "./registry";
12
+ export { apiFormatForPath, formatRegistry, formatForPath, requestFormatForPath } from "./registry";
13
13
  export { registry } from "./providers";
@@ -1,36 +1,2 @@
1
- import { z } from "zod";
2
-
3
- /**
4
- * Shared JSON value type for streaming chunks.
5
- * Defined in a separate file to avoid circular dependencies.
6
- */
7
- export type JsonValue =
8
- | string
9
- | number
10
- | boolean
11
- | null
12
- | JsonValue[]
13
- | { [key: string]: JsonValue };
14
-
15
- export const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>
16
- z.union([
17
- z.string(),
18
- z.number(),
19
- z.boolean(),
20
- z.null(),
21
- z.array(JsonValueSchema),
22
- z.record(z.string(), JsonValueSchema),
23
- ]),
24
- );
25
-
26
- /**
27
- * Re-types a value as `JsonValue` without re-walking it. Use this ONLY when
28
- * the value has already been validated (e.g., via `SseEventSchema.safeParse`)
29
- * AND originated from `JSON.parse`. Skipping the recursive `JsonValueSchema`
30
- * walk avoids a second full-tree zod parse on every event of every streaming
31
- * response. Centralized here so the eslint-disable is one site, not two.
32
- */
33
- export function trustAsJsonValue<T>(value: T): JsonValue {
34
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
35
- return value as unknown as JsonValue;
36
- }
1
+ export { JsonValueSchema, trustAsJsonValue } from "../../contracts/json";
2
+ export type { JsonValue } from "../../contracts/json";