@machinemetrics/agent-event-protocol 0.1.1 → 0.2.0

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/README.md CHANGED
@@ -84,17 +84,17 @@ When the agent needs client-side action, the stream pauses and resumes via a new
84
84
 
85
85
  The protocol defines 9 event types covering the complete lifecycle of an agent response.
86
86
 
87
- | Event | Description |
88
- |-------|-------------|
89
- | `metadata` | Stream initialization with threadId, requestId, agentId |
90
- | `text` | Streaming text output with stage lifecycle |
91
- | `thinking` | Model reasoning/thinking content (extended thinking) |
92
- | `tool_call` | Tool invocation with streaming arguments |
93
- | `tool_result` | Tool execution result (status and summary only) |
94
- | `done` | Stream complete with full content array |
95
- | `error` | Error condition with code and retry guidance |
96
- | `aborted` | Client cancellation acknowledgment |
97
- | `continuation` | Pause for client action (tools, approval, input) |
87
+ | Event | Description |
88
+ | -------------- | ------------------------------------------------------- |
89
+ | `metadata` | Stream initialization with threadId, requestId, agentId |
90
+ | `text` | Streaming text output with stage lifecycle |
91
+ | `thinking` | Model reasoning/thinking content (extended thinking) |
92
+ | `tool_call` | Tool invocation with streaming arguments |
93
+ | `tool_result` | Tool execution result (status and summary only) |
94
+ | `done` | Stream complete with full content array |
95
+ | `error` | Error condition with code and retry guidance |
96
+ | `aborted` | Client cancellation acknowledgment |
97
+ | `continuation` | Pause for client action (tools, approval, input) |
98
98
 
99
99
  ### Terminal Events
100
100
 
@@ -104,21 +104,21 @@ Each request must end with exactly one terminal event: `done`, `error`, or `abor
104
104
 
105
105
  Content events (`text`, `thinking`, `tool_call`, `tool_result`) use a consistent stage pattern:
106
106
 
107
- | Stage | Description |
108
- |-------|-------------|
109
- | `start` | Block begins, includes `blockIndex` for ordering |
107
+ | Stage | Description |
108
+ | ------- | -------------------------------------------------------------- |
109
+ | `start` | Block begins, includes `blockIndex` for ordering |
110
110
  | `delta` | Content chunk, includes `deltaIndex` for ordering within block |
111
- | `stop` | Block complete, includes final data for that block type |
111
+ | `stop` | Block complete, includes final data for that block type |
112
112
 
113
113
  ## Request Schema
114
114
 
115
115
  ```typescript
116
116
  type AgentRequest = {
117
- messages: InputMessage[]; // New user input
118
- threadId?: string; // Resume existing thread
117
+ messages: InputMessage[]; // New user input
118
+ threadId?: string; // Resume existing thread
119
119
  context?: {
120
- actionResults?: ActionResult[]; // Results from continuation events
121
- [key: string]: unknown; // Additional passthrough data
120
+ actionResults?: ActionResult[]; // Results from continuation events
121
+ [key: string]: unknown; // Additional passthrough data
122
122
  };
123
123
  };
124
124
  ```
@@ -128,9 +128,12 @@ Only `messages` is required. The server loads thread history from storage via `t
128
128
  ## Content Blocks
129
129
 
130
130
  **User Content Blocks** (in requests):
131
+
131
132
  - `text` - Plain text input
133
+ - `attachment` - A file the user uploaded ahead of the message, referenced by `attachmentId`, with its `mimeType` and optional `name`. The protocol accepts any media type; the server decides which it supports and how each reaches the model (image, document, extracted text, tool).
132
134
 
133
135
  **Assistant Content Blocks** (in responses):
136
+
134
137
  - `text` - Text output
135
138
  - `thinking` - Model reasoning
136
139
  - `tool_use` - Tool invocation with args
@@ -140,32 +143,33 @@ Only `messages` is required. The server loads thread history from storage via `t
140
143
 
141
144
  ### Error Codes
142
145
 
143
- | Code | Description |
144
- |------|-------------|
145
- | `auth_failed` | Authentication failed |
146
- | `thread_not_found` | Thread does not exist |
147
- | `thread_access_denied` | Thread ownership violation |
148
- | `invalid_message_format` | Invalid request format |
149
- | `message_too_large` | Message exceeds size limit |
150
- | `rate_limit_exceeded` | Rate limit hit |
151
- | `stream_timeout` | Stream timed out |
152
- | `agent_error` | Agent execution error |
153
- | `tool_error` | Tool execution error |
154
- | `internal_error` | Internal server error |
155
- | `invalid_action_id` | Action ID not found or already resolved |
146
+ | Code | Description |
147
+ | ------------------------ | --------------------------------------- |
148
+ | `auth_failed` | Authentication failed |
149
+ | `thread_not_found` | Thread does not exist |
150
+ | `thread_access_denied` | Thread ownership violation |
151
+ | `invalid_message_format` | Invalid request format |
152
+ | `message_too_large` | Message exceeds size limit |
153
+ | `rate_limit_exceeded` | Rate limit hit |
154
+ | `stream_timeout` | Stream timed out |
155
+ | `stream_stalled` | Model went silent mid-reply; retryable |
156
+ | `agent_error` | Agent execution error |
157
+ | `tool_error` | Tool execution error |
158
+ | `internal_error` | Internal server error |
159
+ | `invalid_action_id` | Action ID not found or already resolved |
156
160
 
157
161
  ### HTTP Status Mapping
158
162
 
159
- | Status | Error Codes |
160
- |--------|-------------|
161
- | 400 | `invalid_message_format`, `invalid_action_id` |
162
- | 401 | `auth_failed` |
163
- | 403 | `thread_access_denied` |
164
- | 404 | `thread_not_found` |
165
- | 413 | `message_too_large` |
166
- | 429 | `rate_limit_exceeded` |
167
- | 500 | `internal_error` |
168
- | 504 | `stream_timeout` |
163
+ | Status | Error Codes |
164
+ | ------ | --------------------------------------------- |
165
+ | 400 | `invalid_message_format`, `invalid_action_id` |
166
+ | 401 | `auth_failed` |
167
+ | 403 | `thread_access_denied` |
168
+ | 404 | `thread_not_found` |
169
+ | 413 | `message_too_large` |
170
+ | 429 | `rate_limit_exceeded` |
171
+ | 500 | `internal_error` |
172
+ | 504 | `stream_timeout` |
169
173
 
170
174
  ### Retry Guidance
171
175
 
@@ -215,11 +219,13 @@ const { events, remainder } = parseSSEChunk(chunk);
215
219
  ## Extensibility
216
220
 
217
221
  **Adding new events is backward compatible:**
222
+
218
223
  - Clients should ignore unknown event types
219
224
  - New optional fields can be added to existing events
220
225
  - No version bump required for additive changes
221
226
 
222
227
  **Breaking changes require new endpoint version:**
228
+
223
229
  ```
224
230
  /v1/agents/{agentName}/stream → Current
225
231
  /v2/agents/{agentName}/stream → Breaking changes
@@ -1,9 +1,24 @@
1
1
  // src/core/schemas.ts
2
2
  import { z } from "zod";
3
- var UserContentBlockSchema = z.object({
3
+ var UserTextBlockSchema = z.object({
4
4
  type: z.literal("text"),
5
5
  text: z.string()
6
6
  });
7
+ var RESTRICTED_NAME = "[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}";
8
+ var MediaTypeSchema = z.string().regex(
9
+ new RegExp(`^${RESTRICTED_NAME}/${RESTRICTED_NAME}$`),
10
+ "expected a media type such as image/png"
11
+ );
12
+ var UserAttachmentBlockSchema = z.object({
13
+ type: z.literal("attachment"),
14
+ attachmentId: z.string().min(1),
15
+ mimeType: MediaTypeSchema,
16
+ name: z.string().min(1).optional()
17
+ });
18
+ var UserContentBlockSchema = z.discriminatedUnion("type", [
19
+ UserTextBlockSchema,
20
+ UserAttachmentBlockSchema
21
+ ]);
7
22
  var AssistantContentBlockSchema = z.discriminatedUnion("type", [
8
23
  z.object({ type: z.literal("text"), text: z.string() }),
9
24
  z.object({ type: z.literal("thinking"), text: z.string() }),
@@ -48,6 +63,7 @@ var ErrorCodeSchema = z.enum([
48
63
  "message_too_large",
49
64
  "rate_limit_exceeded",
50
65
  "stream_timeout",
66
+ "stream_stalled",
51
67
  "agent_error",
52
68
  "tool_error",
53
69
  "internal_error",
@@ -158,8 +174,97 @@ var AgentEventSchema = z.discriminatedUnion("event", [
158
174
  AbortedEventSchema,
159
175
  ContinuationEventSchema
160
176
  ]);
177
+ if (import.meta.vitest) {
178
+ const { describe, it, expect } = import.meta.vitest;
179
+ describe("UserContentBlockSchema", () => {
180
+ it("accepts a text block", () => {
181
+ expect(UserContentBlockSchema.safeParse({ type: "text", text: "hi" }).success).toBe(true);
182
+ });
183
+ it("accepts an attachment of any media type, with or without a name", () => {
184
+ for (const block of [
185
+ { type: "attachment", attachmentId: "att-1", mimeType: "image/png" },
186
+ {
187
+ type: "attachment",
188
+ attachmentId: "att-2",
189
+ mimeType: "application/pdf",
190
+ name: "spec.pdf"
191
+ },
192
+ { type: "attachment", attachmentId: "att-3", mimeType: "text/csv", name: "scrap.csv" }
193
+ ]) {
194
+ expect(UserContentBlockSchema.safeParse(block).success).toBe(true);
195
+ }
196
+ });
197
+ it("rejects an attachment without an id", () => {
198
+ expect(
199
+ UserContentBlockSchema.safeParse({ type: "attachment", mimeType: "image/png" }).success
200
+ ).toBe(false);
201
+ });
202
+ it("rejects a malformed media type", () => {
203
+ expect(
204
+ UserContentBlockSchema.safeParse({
205
+ type: "attachment",
206
+ attachmentId: "att-1",
207
+ mimeType: "png"
208
+ }).success
209
+ ).toBe(false);
210
+ });
211
+ it("follows RFC 6838 restricted names for the media type", () => {
212
+ const ok = (mimeType) => UserContentBlockSchema.safeParse({ type: "attachment", attachmentId: "a", mimeType }).success;
213
+ expect(ok("application/vnd.ms-excel")).toBe(true);
214
+ expect(ok("application/x-foo!#$&^_.+-bar")).toBe(true);
215
+ expect(ok("image/svg+xml")).toBe(true);
216
+ expect(ok(".foo/bar")).toBe(false);
217
+ expect(ok("image/-png")).toBe(false);
218
+ expect(ok("image/png; charset=x")).toBe(false);
219
+ expect(ok(`image/${"a".repeat(127)}`)).toBe(true);
220
+ expect(ok(`image/${"a".repeat(128)}`)).toBe(false);
221
+ });
222
+ it("rejects an unknown block type", () => {
223
+ expect(
224
+ UserContentBlockSchema.safeParse({
225
+ type: "image",
226
+ mimeType: "image/png",
227
+ attachmentId: "a"
228
+ }).success
229
+ ).toBe(false);
230
+ });
231
+ });
232
+ describe("ErrorEventSchema", () => {
233
+ it("accepts a stream_stalled error", () => {
234
+ expect(
235
+ AgentEventSchema.safeParse({
236
+ event: "error",
237
+ requestId: "r",
238
+ message: "The agent stopped responding",
239
+ code: "stream_stalled",
240
+ retryable: true,
241
+ timestamp: "2026-11-04T00:00:00.000Z"
242
+ }).success
243
+ ).toBe(true);
244
+ });
245
+ });
246
+ describe("AgentRequestSchema with attachment blocks", () => {
247
+ it("accepts a message mixing text and attachment blocks", () => {
248
+ const result = AgentRequestSchema.safeParse({
249
+ messages: [
250
+ {
251
+ content: [
252
+ { type: "text", text: "What is this?" },
253
+ { type: "attachment", attachmentId: "a", mimeType: "image/webp", name: "photo.webp" }
254
+ ]
255
+ }
256
+ ],
257
+ threadId: "t"
258
+ });
259
+ expect(result.success).toBe(true);
260
+ });
261
+ });
262
+ }
161
263
 
162
264
  export {
265
+ UserTextBlockSchema,
266
+ MediaTypeSchema,
267
+ UserAttachmentBlockSchema,
163
268
  UserContentBlockSchema,
164
269
  AssistantContentBlockSchema,
165
270
  InputMessageSchema,
@@ -179,4 +284,4 @@ export {
179
284
  ContinuationEventSchema,
180
285
  AgentEventSchema
181
286
  };
182
- //# sourceMappingURL=chunk-H5AXHRSE.js.map
287
+ //# sourceMappingURL=chunk-434TVYA5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/schemas.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Zod schema for a user text block.\n */\nexport const UserTextBlockSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n});\n\n/**\n * Zod schema for a media type (`type/subtype`, e.g. `image/png`,\n * `application/pdf`): RFC 6838 restricted names, each starting with a letter\n * or digit and at most 127 characters. Which media types a server accepts is the server's\n * decision, not the protocol's.\n */\nconst RESTRICTED_NAME = '[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}';\n\nexport const MediaTypeSchema = z\n .string()\n .regex(\n new RegExp(`^${RESTRICTED_NAME}/${RESTRICTED_NAME}$`),\n 'expected a media type such as image/png',\n );\n\n/**\n * Zod schema for a user attachment block: a file the user uploaded ahead of\n * the message and now refers to by id. How the file reaches the model (an\n * image, a document, extracted text, a tool) is the server's decision.\n */\nexport const UserAttachmentBlockSchema = z.object({\n type: z.literal('attachment'),\n attachmentId: z.string().min(1),\n mimeType: MediaTypeSchema,\n name: z.string().min(1).optional(),\n});\n\n/**\n * Zod schema for validating user content blocks: text or an attachment.\n */\nexport const UserContentBlockSchema = z.discriminatedUnion('type', [\n UserTextBlockSchema,\n UserAttachmentBlockSchema,\n]);\n\n/**\n * Zod schema for validating assistant content blocks.\n * Discriminated union supporting text, thinking, tool_use, and tool_result.\n */\nexport const AssistantContentBlockSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('text'), text: z.string() }),\n z.object({ type: z.literal('thinking'), text: z.string() }),\n z.object({\n type: z.literal('tool_use'),\n toolCallId: z.string(),\n tool: z.string(),\n args: z.record(z.string(), z.unknown()),\n }),\n z.object({\n type: z.literal('tool_result'),\n toolCallId: z.string(),\n tool: z.string(),\n status: z.enum(['success', 'error']),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n }),\n]);\n\n/**\n * Zod schema for validating input messages.\n */\nexport const InputMessageSchema = z.object({\n content: z.array(UserContentBlockSchema),\n});\n\n/**\n * Zod schema for validating action results from continuation events.\n */\nexport const ActionResultSchema = z.object({\n actionId: z.string(),\n kind: z.string(),\n status: z.enum(['success', 'error']),\n data: z.unknown().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Zod schema for validating agent request payloads.\n * Context object uses passthrough() to allow additional fields.\n */\nexport const AgentRequestSchema = z.object({\n messages: z.array(InputMessageSchema),\n threadId: z.string().optional(),\n context: z\n .object({\n actionResults: z.array(ActionResultSchema).optional(),\n })\n .passthrough()\n .optional(),\n});\n\n/**\n * Zod schema for event lifecycle stages.\n */\nexport const EventStageSchema = z.enum(['start', 'delta', 'stop']);\n\n/**\n * Zod schema for protocol error codes.\n */\nexport const ErrorCodeSchema = z.enum([\n 'auth_failed',\n 'thread_not_found',\n 'thread_access_denied',\n 'invalid_message_format',\n 'message_too_large',\n 'rate_limit_exceeded',\n 'stream_timeout',\n 'stream_stalled',\n 'agent_error',\n 'tool_error',\n 'internal_error',\n 'invalid_action_id',\n]);\n\n/**\n * Zod schema for stream finish reasons.\n */\nexport const FinishReasonSchema = z.enum(['stop', 'length', 'error', 'action_required']);\n\n/**\n * Zod schema for metadata events.\n * First event in every stream, provides identifiers.\n */\nexport const MetadataEventSchema = z.object({\n event: z.literal('metadata'),\n requestId: z.string(),\n threadId: z.string(),\n agentId: z.string(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for text streaming events.\n * Validates the stage lifecycle with appropriate optional fields per stage.\n */\nexport const TextEventSchema = z.object({\n event: z.literal('text'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for thinking/reasoning events.\n * Structure mirrors TextEventSchema.\n */\nexport const ThinkingEventSchema = z.object({\n event: z.literal('thinking'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool call events.\n * Args are optional (only present on stop stage).\n */\nexport const ToolCallEventSchema = z.object({\n event: z.literal('tool_call'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n args: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool result events.\n * Status and summary only present on stop stage.\n */\nexport const ToolResultEventSchema = z.object({\n event: z.literal('tool_result'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n status: z.enum(['success', 'error']).optional(),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for done events.\n * Terminal event with complete content array.\n */\nexport const DoneEventSchema = z.object({\n event: z.literal('done'),\n requestId: z.string(),\n messageId: z.string(),\n threadId: z.string(),\n content: z.array(AssistantContentBlockSchema),\n usage: z\n .object({\n promptTokens: z.number(),\n completionTokens: z.number(),\n })\n .optional(),\n finishReason: FinishReasonSchema,\n traceId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for error events.\n * Terminal event with error details and retry guidance.\n */\nexport const ErrorEventSchema = z.object({\n event: z.literal('error'),\n requestId: z.string(),\n message: z.string(),\n code: ErrorCodeSchema.optional(),\n retryable: z.boolean().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for aborted events.\n * Terminal event acknowledging client cancellation.\n */\nexport const AbortedEventSchema = z.object({\n event: z.literal('aborted'),\n requestId: z.string(),\n messageId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for continuation events.\n * Signals client action required before stream can continue.\n */\nexport const ContinuationEventSchema = z.object({\n event: z.literal('continuation'),\n requestId: z.string(),\n actionId: z.string(),\n kind: z.string(),\n payload: z.record(z.string(), z.unknown()),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for all protocol events.\n * Discriminated union on the `event` field for efficient parsing.\n */\nexport const AgentEventSchema = z.discriminatedUnion('event', [\n MetadataEventSchema,\n TextEventSchema,\n ThinkingEventSchema,\n ToolCallEventSchema,\n ToolResultEventSchema,\n DoneEventSchema,\n ErrorEventSchema,\n AbortedEventSchema,\n ContinuationEventSchema,\n]);\n\nif (import.meta.vitest) {\n const { describe, it, expect } = import.meta.vitest;\n\n describe('UserContentBlockSchema', () => {\n it('accepts a text block', () => {\n expect(UserContentBlockSchema.safeParse({ type: 'text', text: 'hi' }).success).toBe(true);\n });\n\n it('accepts an attachment of any media type, with or without a name', () => {\n for (const block of [\n { type: 'attachment', attachmentId: 'att-1', mimeType: 'image/png' },\n {\n type: 'attachment',\n attachmentId: 'att-2',\n mimeType: 'application/pdf',\n name: 'spec.pdf',\n },\n { type: 'attachment', attachmentId: 'att-3', mimeType: 'text/csv', name: 'scrap.csv' },\n ]) {\n expect(UserContentBlockSchema.safeParse(block).success).toBe(true);\n }\n });\n\n it('rejects an attachment without an id', () => {\n expect(\n UserContentBlockSchema.safeParse({ type: 'attachment', mimeType: 'image/png' }).success,\n ).toBe(false);\n });\n\n it('rejects a malformed media type', () => {\n expect(\n UserContentBlockSchema.safeParse({\n type: 'attachment',\n attachmentId: 'att-1',\n mimeType: 'png',\n }).success,\n ).toBe(false);\n });\n\n it('follows RFC 6838 restricted names for the media type', () => {\n const ok = (mimeType: string) =>\n UserContentBlockSchema.safeParse({ type: 'attachment', attachmentId: 'a', mimeType })\n .success;\n expect(ok('application/vnd.ms-excel')).toBe(true);\n expect(ok('application/x-foo!#$&^_.+-bar')).toBe(true);\n expect(ok('image/svg+xml')).toBe(true);\n expect(ok('.foo/bar')).toBe(false);\n expect(ok('image/-png')).toBe(false);\n expect(ok('image/png; charset=x')).toBe(false);\n expect(ok(`image/${'a'.repeat(127)}`)).toBe(true);\n expect(ok(`image/${'a'.repeat(128)}`)).toBe(false);\n });\n\n it('rejects an unknown block type', () => {\n expect(\n UserContentBlockSchema.safeParse({\n type: 'image',\n mimeType: 'image/png',\n attachmentId: 'a',\n }).success,\n ).toBe(false);\n });\n });\n\n describe('ErrorEventSchema', () => {\n it('accepts a stream_stalled error', () => {\n expect(\n AgentEventSchema.safeParse({\n event: 'error',\n requestId: 'r',\n message: 'The agent stopped responding',\n code: 'stream_stalled',\n retryable: true,\n timestamp: '2026-11-04T00:00:00.000Z',\n }).success,\n ).toBe(true);\n });\n });\n\n describe('AgentRequestSchema with attachment blocks', () => {\n it('accepts a message mixing text and attachment blocks', () => {\n const result = AgentRequestSchema.safeParse({\n messages: [\n {\n content: [\n { type: 'text', text: 'What is this?' },\n { type: 'attachment', attachmentId: 'a', mimeType: 'image/webp', name: 'photo.webp' },\n ],\n },\n ],\n threadId: 't',\n });\n expect(result.success).toBe(true);\n });\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AgentEventSchema
3
- } from "./chunk-H5AXHRSE.js";
3
+ } from "./chunk-434TVYA5.js";
4
4
 
5
5
  // src/sse/encode.ts
6
6
  function encodeSSE(event, data) {
@@ -217,4 +217,4 @@ export {
217
217
  encodeSSE,
218
218
  parseSSEChunk
219
219
  };
220
- //# sourceMappingURL=chunk-VDBWUNSK.js.map
220
+ //# sourceMappingURL=chunk-QIKNRCHJ.js.map
package/dist/core.cjs CHANGED
@@ -33,22 +33,41 @@ __export(core_exports, {
33
33
  EventStageSchema: () => EventStageSchema,
34
34
  FinishReasonSchema: () => FinishReasonSchema,
35
35
  InputMessageSchema: () => InputMessageSchema,
36
+ MediaTypeSchema: () => MediaTypeSchema,
36
37
  MetadataEventSchema: () => MetadataEventSchema,
37
38
  PROTOCOL_VERSION: () => PROTOCOL_VERSION,
38
39
  TextEventSchema: () => TextEventSchema,
39
40
  ThinkingEventSchema: () => ThinkingEventSchema,
40
41
  ToolCallEventSchema: () => ToolCallEventSchema,
41
42
  ToolResultEventSchema: () => ToolResultEventSchema,
42
- UserContentBlockSchema: () => UserContentBlockSchema
43
+ UserAttachmentBlockSchema: () => UserAttachmentBlockSchema,
44
+ UserContentBlockSchema: () => UserContentBlockSchema,
45
+ UserTextBlockSchema: () => UserTextBlockSchema
43
46
  });
44
47
  module.exports = __toCommonJS(core_exports);
45
48
 
46
49
  // src/core/schemas.ts
47
50
  var import_zod = require("zod");
48
- var UserContentBlockSchema = import_zod.z.object({
51
+ var import_meta = {};
52
+ var UserTextBlockSchema = import_zod.z.object({
49
53
  type: import_zod.z.literal("text"),
50
54
  text: import_zod.z.string()
51
55
  });
56
+ var RESTRICTED_NAME = "[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}";
57
+ var MediaTypeSchema = import_zod.z.string().regex(
58
+ new RegExp(`^${RESTRICTED_NAME}/${RESTRICTED_NAME}$`),
59
+ "expected a media type such as image/png"
60
+ );
61
+ var UserAttachmentBlockSchema = import_zod.z.object({
62
+ type: import_zod.z.literal("attachment"),
63
+ attachmentId: import_zod.z.string().min(1),
64
+ mimeType: MediaTypeSchema,
65
+ name: import_zod.z.string().min(1).optional()
66
+ });
67
+ var UserContentBlockSchema = import_zod.z.discriminatedUnion("type", [
68
+ UserTextBlockSchema,
69
+ UserAttachmentBlockSchema
70
+ ]);
52
71
  var AssistantContentBlockSchema = import_zod.z.discriminatedUnion("type", [
53
72
  import_zod.z.object({ type: import_zod.z.literal("text"), text: import_zod.z.string() }),
54
73
  import_zod.z.object({ type: import_zod.z.literal("thinking"), text: import_zod.z.string() }),
@@ -93,6 +112,7 @@ var ErrorCodeSchema = import_zod.z.enum([
93
112
  "message_too_large",
94
113
  "rate_limit_exceeded",
95
114
  "stream_timeout",
115
+ "stream_stalled",
96
116
  "agent_error",
97
117
  "tool_error",
98
118
  "internal_error",
@@ -203,6 +223,92 @@ var AgentEventSchema = import_zod.z.discriminatedUnion("event", [
203
223
  AbortedEventSchema,
204
224
  ContinuationEventSchema
205
225
  ]);
226
+ if (import_meta.vitest) {
227
+ const { describe, it, expect } = import_meta.vitest;
228
+ describe("UserContentBlockSchema", () => {
229
+ it("accepts a text block", () => {
230
+ expect(UserContentBlockSchema.safeParse({ type: "text", text: "hi" }).success).toBe(true);
231
+ });
232
+ it("accepts an attachment of any media type, with or without a name", () => {
233
+ for (const block of [
234
+ { type: "attachment", attachmentId: "att-1", mimeType: "image/png" },
235
+ {
236
+ type: "attachment",
237
+ attachmentId: "att-2",
238
+ mimeType: "application/pdf",
239
+ name: "spec.pdf"
240
+ },
241
+ { type: "attachment", attachmentId: "att-3", mimeType: "text/csv", name: "scrap.csv" }
242
+ ]) {
243
+ expect(UserContentBlockSchema.safeParse(block).success).toBe(true);
244
+ }
245
+ });
246
+ it("rejects an attachment without an id", () => {
247
+ expect(
248
+ UserContentBlockSchema.safeParse({ type: "attachment", mimeType: "image/png" }).success
249
+ ).toBe(false);
250
+ });
251
+ it("rejects a malformed media type", () => {
252
+ expect(
253
+ UserContentBlockSchema.safeParse({
254
+ type: "attachment",
255
+ attachmentId: "att-1",
256
+ mimeType: "png"
257
+ }).success
258
+ ).toBe(false);
259
+ });
260
+ it("follows RFC 6838 restricted names for the media type", () => {
261
+ const ok = (mimeType) => UserContentBlockSchema.safeParse({ type: "attachment", attachmentId: "a", mimeType }).success;
262
+ expect(ok("application/vnd.ms-excel")).toBe(true);
263
+ expect(ok("application/x-foo!#$&^_.+-bar")).toBe(true);
264
+ expect(ok("image/svg+xml")).toBe(true);
265
+ expect(ok(".foo/bar")).toBe(false);
266
+ expect(ok("image/-png")).toBe(false);
267
+ expect(ok("image/png; charset=x")).toBe(false);
268
+ expect(ok(`image/${"a".repeat(127)}`)).toBe(true);
269
+ expect(ok(`image/${"a".repeat(128)}`)).toBe(false);
270
+ });
271
+ it("rejects an unknown block type", () => {
272
+ expect(
273
+ UserContentBlockSchema.safeParse({
274
+ type: "image",
275
+ mimeType: "image/png",
276
+ attachmentId: "a"
277
+ }).success
278
+ ).toBe(false);
279
+ });
280
+ });
281
+ describe("ErrorEventSchema", () => {
282
+ it("accepts a stream_stalled error", () => {
283
+ expect(
284
+ AgentEventSchema.safeParse({
285
+ event: "error",
286
+ requestId: "r",
287
+ message: "The agent stopped responding",
288
+ code: "stream_stalled",
289
+ retryable: true,
290
+ timestamp: "2026-11-04T00:00:00.000Z"
291
+ }).success
292
+ ).toBe(true);
293
+ });
294
+ });
295
+ describe("AgentRequestSchema with attachment blocks", () => {
296
+ it("accepts a message mixing text and attachment blocks", () => {
297
+ const result = AgentRequestSchema.safeParse({
298
+ messages: [
299
+ {
300
+ content: [
301
+ { type: "text", text: "What is this?" },
302
+ { type: "attachment", attachmentId: "a", mimeType: "image/webp", name: "photo.webp" }
303
+ ]
304
+ }
305
+ ],
306
+ threadId: "t"
307
+ });
308
+ expect(result.success).toBe(true);
309
+ });
310
+ });
311
+ }
206
312
 
207
313
  // src/core/constants.ts
208
314
  var PROTOCOL_VERSION = "1.0.0";
@@ -232,12 +338,15 @@ var EVENT_TYPES = [
232
338
  EventStageSchema,
233
339
  FinishReasonSchema,
234
340
  InputMessageSchema,
341
+ MediaTypeSchema,
235
342
  MetadataEventSchema,
236
343
  PROTOCOL_VERSION,
237
344
  TextEventSchema,
238
345
  ThinkingEventSchema,
239
346
  ToolCallEventSchema,
240
347
  ToolResultEventSchema,
241
- UserContentBlockSchema
348
+ UserAttachmentBlockSchema,
349
+ UserContentBlockSchema,
350
+ UserTextBlockSchema
242
351
  });
243
352
  //# sourceMappingURL=core.cjs.map
package/dist/core.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/index.ts","../src/core/schemas.ts","../src/core/constants.ts"],"sourcesContent":["export * from './types.js';\nexport * from './schemas.js';\nexport * from './constants.js';\n","import { z } from 'zod';\n\n/**\n * Zod schema for validating user content blocks.\n * Currently only supports text; extensible for multimodal.\n */\nexport const UserContentBlockSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n});\n\n/**\n * Zod schema for validating assistant content blocks.\n * Discriminated union supporting text, thinking, tool_use, and tool_result.\n */\nexport const AssistantContentBlockSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('text'), text: z.string() }),\n z.object({ type: z.literal('thinking'), text: z.string() }),\n z.object({\n type: z.literal('tool_use'),\n toolCallId: z.string(),\n tool: z.string(),\n args: z.record(z.string(), z.unknown()),\n }),\n z.object({\n type: z.literal('tool_result'),\n toolCallId: z.string(),\n tool: z.string(),\n status: z.enum(['success', 'error']),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n }),\n]);\n\n/**\n * Zod schema for validating input messages.\n */\nexport const InputMessageSchema = z.object({\n content: z.array(UserContentBlockSchema),\n});\n\n/**\n * Zod schema for validating action results from continuation events.\n */\nexport const ActionResultSchema = z.object({\n actionId: z.string(),\n kind: z.string(),\n status: z.enum(['success', 'error']),\n data: z.unknown().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Zod schema for validating agent request payloads.\n * Context object uses passthrough() to allow additional fields.\n */\nexport const AgentRequestSchema = z.object({\n messages: z.array(InputMessageSchema),\n threadId: z.string().optional(),\n context: z\n .object({\n actionResults: z.array(ActionResultSchema).optional(),\n })\n .passthrough()\n .optional(),\n});\n\n/**\n * Zod schema for event lifecycle stages.\n */\nexport const EventStageSchema = z.enum(['start', 'delta', 'stop']);\n\n/**\n * Zod schema for protocol error codes.\n */\nexport const ErrorCodeSchema = z.enum([\n 'auth_failed',\n 'thread_not_found',\n 'thread_access_denied',\n 'invalid_message_format',\n 'message_too_large',\n 'rate_limit_exceeded',\n 'stream_timeout',\n 'agent_error',\n 'tool_error',\n 'internal_error',\n 'invalid_action_id',\n]);\n\n/**\n * Zod schema for stream finish reasons.\n */\nexport const FinishReasonSchema = z.enum(['stop', 'length', 'error', 'action_required']);\n\n/**\n * Zod schema for metadata events.\n * First event in every stream, provides identifiers.\n */\nexport const MetadataEventSchema = z.object({\n event: z.literal('metadata'),\n requestId: z.string(),\n threadId: z.string(),\n agentId: z.string(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for text streaming events.\n * Validates the stage lifecycle with appropriate optional fields per stage.\n */\nexport const TextEventSchema = z.object({\n event: z.literal('text'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for thinking/reasoning events.\n * Structure mirrors TextEventSchema.\n */\nexport const ThinkingEventSchema = z.object({\n event: z.literal('thinking'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool call events.\n * Args are optional (only present on stop stage).\n */\nexport const ToolCallEventSchema = z.object({\n event: z.literal('tool_call'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n args: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool result events.\n * Status and summary only present on stop stage.\n */\nexport const ToolResultEventSchema = z.object({\n event: z.literal('tool_result'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n status: z.enum(['success', 'error']).optional(),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for done events.\n * Terminal event with complete content array.\n */\nexport const DoneEventSchema = z.object({\n event: z.literal('done'),\n requestId: z.string(),\n messageId: z.string(),\n threadId: z.string(),\n content: z.array(AssistantContentBlockSchema),\n usage: z\n .object({\n promptTokens: z.number(),\n completionTokens: z.number(),\n })\n .optional(),\n finishReason: FinishReasonSchema,\n traceId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for error events.\n * Terminal event with error details and retry guidance.\n */\nexport const ErrorEventSchema = z.object({\n event: z.literal('error'),\n requestId: z.string(),\n message: z.string(),\n code: ErrorCodeSchema.optional(),\n retryable: z.boolean().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for aborted events.\n * Terminal event acknowledging client cancellation.\n */\nexport const AbortedEventSchema = z.object({\n event: z.literal('aborted'),\n requestId: z.string(),\n messageId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for continuation events.\n * Signals client action required before stream can continue.\n */\nexport const ContinuationEventSchema = z.object({\n event: z.literal('continuation'),\n requestId: z.string(),\n actionId: z.string(),\n kind: z.string(),\n payload: z.record(z.string(), z.unknown()),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for all protocol events.\n * Discriminated union on the `event` field for efficient parsing.\n */\nexport const AgentEventSchema = z.discriminatedUnion('event', [\n MetadataEventSchema,\n TextEventSchema,\n ThinkingEventSchema,\n ToolCallEventSchema,\n ToolResultEventSchema,\n DoneEventSchema,\n ErrorEventSchema,\n AbortedEventSchema,\n ContinuationEventSchema,\n]);\n","/**\n * Current protocol version.\n * Additive changes (new events, optional fields) don't require version bump.\n * Breaking changes require new endpoint version (v2, v3, etc).\n */\nexport const PROTOCOL_VERSION = '1.0.0';\n\n/**\n * All valid event type identifiers in the protocol.\n * Used for discriminated union parsing and validation.\n */\nexport const EVENT_TYPES = [\n 'metadata',\n 'text',\n 'thinking',\n 'tool_call',\n 'tool_result',\n 'done',\n 'error',\n 'aborted',\n 'continuation',\n] as const;\n\n/**\n * Event type identifier.\n * Union of all valid event type strings.\n */\nexport type EventType = (typeof EVENT_TYPES)[number];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/core/index.ts","../src/core/schemas.ts","../src/core/constants.ts"],"sourcesContent":["export * from './types.js';\nexport * from './schemas.js';\nexport * from './constants.js';\n","import { z } from 'zod';\n\n/**\n * Zod schema for a user text block.\n */\nexport const UserTextBlockSchema = z.object({\n type: z.literal('text'),\n text: z.string(),\n});\n\n/**\n * Zod schema for a media type (`type/subtype`, e.g. `image/png`,\n * `application/pdf`): RFC 6838 restricted names, each starting with a letter\n * or digit and at most 127 characters. Which media types a server accepts is the server's\n * decision, not the protocol's.\n */\nconst RESTRICTED_NAME = '[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}';\n\nexport const MediaTypeSchema = z\n .string()\n .regex(\n new RegExp(`^${RESTRICTED_NAME}/${RESTRICTED_NAME}$`),\n 'expected a media type such as image/png',\n );\n\n/**\n * Zod schema for a user attachment block: a file the user uploaded ahead of\n * the message and now refers to by id. How the file reaches the model (an\n * image, a document, extracted text, a tool) is the server's decision.\n */\nexport const UserAttachmentBlockSchema = z.object({\n type: z.literal('attachment'),\n attachmentId: z.string().min(1),\n mimeType: MediaTypeSchema,\n name: z.string().min(1).optional(),\n});\n\n/**\n * Zod schema for validating user content blocks: text or an attachment.\n */\nexport const UserContentBlockSchema = z.discriminatedUnion('type', [\n UserTextBlockSchema,\n UserAttachmentBlockSchema,\n]);\n\n/**\n * Zod schema for validating assistant content blocks.\n * Discriminated union supporting text, thinking, tool_use, and tool_result.\n */\nexport const AssistantContentBlockSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('text'), text: z.string() }),\n z.object({ type: z.literal('thinking'), text: z.string() }),\n z.object({\n type: z.literal('tool_use'),\n toolCallId: z.string(),\n tool: z.string(),\n args: z.record(z.string(), z.unknown()),\n }),\n z.object({\n type: z.literal('tool_result'),\n toolCallId: z.string(),\n tool: z.string(),\n status: z.enum(['success', 'error']),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n }),\n]);\n\n/**\n * Zod schema for validating input messages.\n */\nexport const InputMessageSchema = z.object({\n content: z.array(UserContentBlockSchema),\n});\n\n/**\n * Zod schema for validating action results from continuation events.\n */\nexport const ActionResultSchema = z.object({\n actionId: z.string(),\n kind: z.string(),\n status: z.enum(['success', 'error']),\n data: z.unknown().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Zod schema for validating agent request payloads.\n * Context object uses passthrough() to allow additional fields.\n */\nexport const AgentRequestSchema = z.object({\n messages: z.array(InputMessageSchema),\n threadId: z.string().optional(),\n context: z\n .object({\n actionResults: z.array(ActionResultSchema).optional(),\n })\n .passthrough()\n .optional(),\n});\n\n/**\n * Zod schema for event lifecycle stages.\n */\nexport const EventStageSchema = z.enum(['start', 'delta', 'stop']);\n\n/**\n * Zod schema for protocol error codes.\n */\nexport const ErrorCodeSchema = z.enum([\n 'auth_failed',\n 'thread_not_found',\n 'thread_access_denied',\n 'invalid_message_format',\n 'message_too_large',\n 'rate_limit_exceeded',\n 'stream_timeout',\n 'stream_stalled',\n 'agent_error',\n 'tool_error',\n 'internal_error',\n 'invalid_action_id',\n]);\n\n/**\n * Zod schema for stream finish reasons.\n */\nexport const FinishReasonSchema = z.enum(['stop', 'length', 'error', 'action_required']);\n\n/**\n * Zod schema for metadata events.\n * First event in every stream, provides identifiers.\n */\nexport const MetadataEventSchema = z.object({\n event: z.literal('metadata'),\n requestId: z.string(),\n threadId: z.string(),\n agentId: z.string(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for text streaming events.\n * Validates the stage lifecycle with appropriate optional fields per stage.\n */\nexport const TextEventSchema = z.object({\n event: z.literal('text'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for thinking/reasoning events.\n * Structure mirrors TextEventSchema.\n */\nexport const ThinkingEventSchema = z.object({\n event: z.literal('thinking'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool call events.\n * Args are optional (only present on stop stage).\n */\nexport const ToolCallEventSchema = z.object({\n event: z.literal('tool_call'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n delta: z.string().optional(),\n deltaIndex: z.number().optional(),\n args: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for tool result events.\n * Status and summary only present on stop stage.\n */\nexport const ToolResultEventSchema = z.object({\n event: z.literal('tool_result'),\n requestId: z.string(),\n messageId: z.string(),\n blockId: z.string(),\n blockIndex: z.number().optional(),\n stage: EventStageSchema,\n toolCallId: z.string().optional(),\n tool: z.string().optional(),\n status: z.enum(['success', 'error']).optional(),\n summary: z.string().optional(),\n output: z.record(z.string(), z.unknown()).optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for done events.\n * Terminal event with complete content array.\n */\nexport const DoneEventSchema = z.object({\n event: z.literal('done'),\n requestId: z.string(),\n messageId: z.string(),\n threadId: z.string(),\n content: z.array(AssistantContentBlockSchema),\n usage: z\n .object({\n promptTokens: z.number(),\n completionTokens: z.number(),\n })\n .optional(),\n finishReason: FinishReasonSchema,\n traceId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for error events.\n * Terminal event with error details and retry guidance.\n */\nexport const ErrorEventSchema = z.object({\n event: z.literal('error'),\n requestId: z.string(),\n message: z.string(),\n code: ErrorCodeSchema.optional(),\n retryable: z.boolean().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for aborted events.\n * Terminal event acknowledging client cancellation.\n */\nexport const AbortedEventSchema = z.object({\n event: z.literal('aborted'),\n requestId: z.string(),\n messageId: z.string().optional(),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for continuation events.\n * Signals client action required before stream can continue.\n */\nexport const ContinuationEventSchema = z.object({\n event: z.literal('continuation'),\n requestId: z.string(),\n actionId: z.string(),\n kind: z.string(),\n payload: z.record(z.string(), z.unknown()),\n timestamp: z.string(),\n});\n\n/**\n * Zod schema for all protocol events.\n * Discriminated union on the `event` field for efficient parsing.\n */\nexport const AgentEventSchema = z.discriminatedUnion('event', [\n MetadataEventSchema,\n TextEventSchema,\n ThinkingEventSchema,\n ToolCallEventSchema,\n ToolResultEventSchema,\n DoneEventSchema,\n ErrorEventSchema,\n AbortedEventSchema,\n ContinuationEventSchema,\n]);\n\nif (import.meta.vitest) {\n const { describe, it, expect } = import.meta.vitest;\n\n describe('UserContentBlockSchema', () => {\n it('accepts a text block', () => {\n expect(UserContentBlockSchema.safeParse({ type: 'text', text: 'hi' }).success).toBe(true);\n });\n\n it('accepts an attachment of any media type, with or without a name', () => {\n for (const block of [\n { type: 'attachment', attachmentId: 'att-1', mimeType: 'image/png' },\n {\n type: 'attachment',\n attachmentId: 'att-2',\n mimeType: 'application/pdf',\n name: 'spec.pdf',\n },\n { type: 'attachment', attachmentId: 'att-3', mimeType: 'text/csv', name: 'scrap.csv' },\n ]) {\n expect(UserContentBlockSchema.safeParse(block).success).toBe(true);\n }\n });\n\n it('rejects an attachment without an id', () => {\n expect(\n UserContentBlockSchema.safeParse({ type: 'attachment', mimeType: 'image/png' }).success,\n ).toBe(false);\n });\n\n it('rejects a malformed media type', () => {\n expect(\n UserContentBlockSchema.safeParse({\n type: 'attachment',\n attachmentId: 'att-1',\n mimeType: 'png',\n }).success,\n ).toBe(false);\n });\n\n it('follows RFC 6838 restricted names for the media type', () => {\n const ok = (mimeType: string) =>\n UserContentBlockSchema.safeParse({ type: 'attachment', attachmentId: 'a', mimeType })\n .success;\n expect(ok('application/vnd.ms-excel')).toBe(true);\n expect(ok('application/x-foo!#$&^_.+-bar')).toBe(true);\n expect(ok('image/svg+xml')).toBe(true);\n expect(ok('.foo/bar')).toBe(false);\n expect(ok('image/-png')).toBe(false);\n expect(ok('image/png; charset=x')).toBe(false);\n expect(ok(`image/${'a'.repeat(127)}`)).toBe(true);\n expect(ok(`image/${'a'.repeat(128)}`)).toBe(false);\n });\n\n it('rejects an unknown block type', () => {\n expect(\n UserContentBlockSchema.safeParse({\n type: 'image',\n mimeType: 'image/png',\n attachmentId: 'a',\n }).success,\n ).toBe(false);\n });\n });\n\n describe('ErrorEventSchema', () => {\n it('accepts a stream_stalled error', () => {\n expect(\n AgentEventSchema.safeParse({\n event: 'error',\n requestId: 'r',\n message: 'The agent stopped responding',\n code: 'stream_stalled',\n retryable: true,\n timestamp: '2026-11-04T00:00:00.000Z',\n }).success,\n ).toBe(true);\n });\n });\n\n describe('AgentRequestSchema with attachment blocks', () => {\n it('accepts a message mixing text and attachment blocks', () => {\n const result = AgentRequestSchema.safeParse({\n messages: [\n {\n content: [\n { type: 'text', text: 'What is this?' },\n { type: 'attachment', attachmentId: 'a', mimeType: 'image/webp', name: 'photo.webp' },\n ],\n },\n ],\n threadId: 't',\n });\n expect(result.success).toBe(true);\n });\n });\n}\n","/**\n * Current protocol version.\n * Additive changes (new events, optional fields) don't require version bump.\n * Breaking changes require new endpoint version (v2, v3, etc).\n */\nexport const PROTOCOL_VERSION = '1.0.0';\n\n/**\n * All valid event type identifiers in the protocol.\n * Used for discriminated union parsing and validation.\n */\nexport const EVENT_TYPES = [\n 'metadata',\n 'text',\n 'thinking',\n 'tool_call',\n 'tool_result',\n 'done',\n 'error',\n 'aborted',\n 'continuation',\n] as const;\n\n/**\n * Event type identifier.\n * Union of all valid event type strings.\n */\nexport type EventType = (typeof EVENT_TYPES)[number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAAkB;AAAlB;AAKO,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,MAAM,aAAE,QAAQ,MAAM;AAAA,EACtB,MAAM,aAAE,OAAO;AACjB,CAAC;AAQD,IAAM,kBAAkB;AAEjB,IAAM,kBAAkB,aAC5B,OAAO,EACP;AAAA,EACC,IAAI,OAAO,IAAI,eAAe,IAAI,eAAe,GAAG;AAAA,EACpD;AACF;AAOK,IAAM,4BAA4B,aAAE,OAAO;AAAA,EAChD,MAAM,aAAE,QAAQ,YAAY;AAAA,EAC5B,cAAc,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC9B,UAAU;AAAA,EACV,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACnC,CAAC;AAKM,IAAM,yBAAyB,aAAE,mBAAmB,QAAQ;AAAA,EACjE;AAAA,EACA;AACF,CAAC;AAMM,IAAM,8BAA8B,aAAE,mBAAmB,QAAQ;AAAA,EACtE,aAAE,OAAO,EAAE,MAAM,aAAE,QAAQ,MAAM,GAAG,MAAM,aAAE,OAAO,EAAE,CAAC;AAAA,EACtD,aAAE,OAAO,EAAE,MAAM,aAAE,QAAQ,UAAU,GAAG,MAAM,aAAE,OAAO,EAAE,CAAC;AAAA,EAC1D,aAAE,OAAO;AAAA,IACP,MAAM,aAAE,QAAQ,UAAU;AAAA,IAC1B,YAAY,aAAE,OAAO;AAAA,IACrB,MAAM,aAAE,OAAO;AAAA,IACf,MAAM,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC;AAAA,EACxC,CAAC;AAAA,EACD,aAAE,OAAO;AAAA,IACP,MAAM,aAAE,QAAQ,aAAa;AAAA,IAC7B,YAAY,aAAE,OAAO;AAAA,IACrB,MAAM,aAAE,OAAO;AAAA,IACf,QAAQ,aAAE,KAAK,CAAC,WAAW,OAAO,CAAC;AAAA,IACnC,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,QAAQ,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrD,CAAC;AACH,CAAC;AAKM,IAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,SAAS,aAAE,MAAM,sBAAsB;AACzC,CAAC;AAKM,IAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,UAAU,aAAE,OAAO;AAAA,EACnB,MAAM,aAAE,OAAO;AAAA,EACf,QAAQ,aAAE,KAAK,CAAC,WAAW,OAAO,CAAC;AAAA,EACnC,MAAM,aAAE,QAAQ,EAAE,SAAS;AAAA,EAC3B,OAAO,aAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAMM,IAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,UAAU,aAAE,MAAM,kBAAkB;AAAA,EACpC,UAAU,aAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,SAAS,aACN,OAAO;AAAA,IACN,eAAe,aAAE,MAAM,kBAAkB,EAAE,SAAS;AAAA,EACtD,CAAC,EACA,YAAY,EACZ,SAAS;AACd,CAAC;AAKM,IAAM,mBAAmB,aAAE,KAAK,CAAC,SAAS,SAAS,MAAM,CAAC;AAK1D,IAAM,kBAAkB,aAAE,KAAK;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,qBAAqB,aAAE,KAAK,CAAC,QAAQ,UAAU,SAAS,iBAAiB,CAAC;AAMhF,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,OAAO,aAAE,QAAQ,UAAU;AAAA,EAC3B,WAAW,aAAE,OAAO;AAAA,EACpB,UAAU,aAAE,OAAO;AAAA,EACnB,SAAS,aAAE,OAAO;AAAA,EAClB,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,kBAAkB,aAAE,OAAO;AAAA,EACtC,OAAO,aAAE,QAAQ,MAAM;AAAA,EACvB,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO;AAAA,EACpB,SAAS,aAAE,OAAO;AAAA,EAClB,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,OAAO;AAAA,EACP,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,OAAO,aAAE,QAAQ,UAAU;AAAA,EAC3B,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO;AAAA,EACpB,SAAS,aAAE,OAAO;AAAA,EAClB,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,OAAO;AAAA,EACP,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,sBAAsB,aAAE,OAAO;AAAA,EAC1C,OAAO,aAAE,QAAQ,WAAW;AAAA,EAC5B,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO;AAAA,EACpB,SAAS,aAAE,OAAO;AAAA,EAClB,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,OAAO;AAAA,EACP,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,MAAM,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACjD,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,wBAAwB,aAAE,OAAO;AAAA,EAC5C,OAAO,aAAE,QAAQ,aAAa;AAAA,EAC9B,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO;AAAA,EACpB,SAAS,aAAE,OAAO;AAAA,EAClB,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,OAAO;AAAA,EACP,YAAY,aAAE,OAAO,EAAE,SAAS;AAAA,EAChC,MAAM,aAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,QAAQ,aAAE,KAAK,CAAC,WAAW,OAAO,CAAC,EAAE,SAAS;AAAA,EAC9C,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,QAAQ,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACnD,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,kBAAkB,aAAE,OAAO;AAAA,EACtC,OAAO,aAAE,QAAQ,MAAM;AAAA,EACvB,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO;AAAA,EACpB,UAAU,aAAE,OAAO;AAAA,EACnB,SAAS,aAAE,MAAM,2BAA2B;AAAA,EAC5C,OAAO,aACJ,OAAO;AAAA,IACN,cAAc,aAAE,OAAO;AAAA,IACvB,kBAAkB,aAAE,OAAO;AAAA,EAC7B,CAAC,EACA,SAAS;AAAA,EACZ,cAAc;AAAA,EACd,SAAS,aAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,mBAAmB,aAAE,OAAO;AAAA,EACvC,OAAO,aAAE,QAAQ,OAAO;AAAA,EACxB,WAAW,aAAE,OAAO;AAAA,EACpB,SAAS,aAAE,OAAO;AAAA,EAClB,MAAM,gBAAgB,SAAS;AAAA,EAC/B,WAAW,aAAE,QAAQ,EAAE,SAAS;AAAA,EAChC,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,qBAAqB,aAAE,OAAO;AAAA,EACzC,OAAO,aAAE,QAAQ,SAAS;AAAA,EAC1B,WAAW,aAAE,OAAO;AAAA,EACpB,WAAW,aAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,0BAA0B,aAAE,OAAO;AAAA,EAC9C,OAAO,aAAE,QAAQ,cAAc;AAAA,EAC/B,WAAW,aAAE,OAAO;AAAA,EACpB,UAAU,aAAE,OAAO;AAAA,EACnB,MAAM,aAAE,OAAO;AAAA,EACf,SAAS,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,QAAQ,CAAC;AAAA,EACzC,WAAW,aAAE,OAAO;AACtB,CAAC;AAMM,IAAM,mBAAmB,aAAE,mBAAmB,SAAS;AAAA,EAC5D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAI,YAAY,QAAQ;AACtB,QAAM,EAAE,UAAU,IAAI,OAAO,IAAI,YAAY;AAE7C,WAAS,0BAA0B,MAAM;AACvC,OAAG,wBAAwB,MAAM;AAC/B,aAAO,uBAAuB,UAAU,EAAE,MAAM,QAAQ,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI;AAAA,IAC1F,CAAC;AAED,OAAG,mEAAmE,MAAM;AAC1E,iBAAW,SAAS;AAAA,QAClB,EAAE,MAAM,cAAc,cAAc,SAAS,UAAU,YAAY;AAAA,QACnE;AAAA,UACE,MAAM;AAAA,UACN,cAAc;AAAA,UACd,UAAU;AAAA,UACV,MAAM;AAAA,QACR;AAAA,QACA,EAAE,MAAM,cAAc,cAAc,SAAS,UAAU,YAAY,MAAM,YAAY;AAAA,MACvF,GAAG;AACD,eAAO,uBAAuB,UAAU,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI;AAAA,MACnE;AAAA,IACF,CAAC;AAED,OAAG,uCAAuC,MAAM;AAC9C;AAAA,QACE,uBAAuB,UAAU,EAAE,MAAM,cAAc,UAAU,YAAY,CAAC,EAAE;AAAA,MAClF,EAAE,KAAK,KAAK;AAAA,IACd,CAAC;AAED,OAAG,kCAAkC,MAAM;AACzC;AAAA,QACE,uBAAuB,UAAU;AAAA,UAC/B,MAAM;AAAA,UACN,cAAc;AAAA,UACd,UAAU;AAAA,QACZ,CAAC,EAAE;AAAA,MACL,EAAE,KAAK,KAAK;AAAA,IACd,CAAC;AAED,OAAG,wDAAwD,MAAM;AAC/D,YAAM,KAAK,CAAC,aACV,uBAAuB,UAAU,EAAE,MAAM,cAAc,cAAc,KAAK,SAAS,CAAC,EACjF;AACL,aAAO,GAAG,0BAA0B,CAAC,EAAE,KAAK,IAAI;AAChD,aAAO,GAAG,+BAA+B,CAAC,EAAE,KAAK,IAAI;AACrD,aAAO,GAAG,eAAe,CAAC,EAAE,KAAK,IAAI;AACrC,aAAO,GAAG,UAAU,CAAC,EAAE,KAAK,KAAK;AACjC,aAAO,GAAG,YAAY,CAAC,EAAE,KAAK,KAAK;AACnC,aAAO,GAAG,sBAAsB,CAAC,EAAE,KAAK,KAAK;AAC7C,aAAO,GAAG,SAAS,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI;AAChD,aAAO,GAAG,SAAS,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,KAAK;AAAA,IACnD,CAAC;AAED,OAAG,iCAAiC,MAAM;AACxC;AAAA,QACE,uBAAuB,UAAU;AAAA,UAC/B,MAAM;AAAA,UACN,UAAU;AAAA,UACV,cAAc;AAAA,QAChB,CAAC,EAAE;AAAA,MACL,EAAE,KAAK,KAAK;AAAA,IACd,CAAC;AAAA,EACH,CAAC;AAED,WAAS,oBAAoB,MAAM;AACjC,OAAG,kCAAkC,MAAM;AACzC;AAAA,QACE,iBAAiB,UAAU;AAAA,UACzB,OAAO;AAAA,UACP,WAAW;AAAA,UACX,SAAS;AAAA,UACT,MAAM;AAAA,UACN,WAAW;AAAA,UACX,WAAW;AAAA,QACb,CAAC,EAAE;AAAA,MACL,EAAE,KAAK,IAAI;AAAA,IACb,CAAC;AAAA,EACH,CAAC;AAED,WAAS,6CAA6C,MAAM;AAC1D,OAAG,uDAAuD,MAAM;AAC9D,YAAM,SAAS,mBAAmB,UAAU;AAAA,QAC1C,UAAU;AAAA,UACR;AAAA,YACE,SAAS;AAAA,cACP,EAAE,MAAM,QAAQ,MAAM,gBAAgB;AAAA,cACtC,EAAE,MAAM,cAAc,cAAc,KAAK,UAAU,cAAc,MAAM,aAAa;AAAA,YACtF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU;AAAA,MACZ,CAAC;AACD,aAAO,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AACH;;;ACvXO,IAAM,mBAAmB;AAMzB,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}