@dexto/server 1.6.20 → 1.6.22
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/dist/a2a/jsonrpc/methods.cjs +1 -1
- package/dist/a2a/jsonrpc/methods.d.ts +14 -4
- package/dist/a2a/jsonrpc/methods.d.ts.map +1 -1
- package/dist/a2a/jsonrpc/methods.js +1 -1
- package/dist/approval/wire-approval-events.cjs +44 -0
- package/dist/approval/wire-approval-events.d.ts +4 -0
- package/dist/approval/wire-approval-events.d.ts.map +1 -0
- package/dist/approval/wire-approval-events.js +20 -0
- package/dist/events/session-sse-subscriber.cjs +167 -0
- package/dist/events/session-sse-subscriber.d.ts +13 -0
- package/dist/events/session-sse-subscriber.d.ts.map +1 -0
- package/dist/events/session-sse-subscriber.js +143 -0
- package/dist/hono/__tests__/test-fixtures.cjs +8 -0
- package/dist/hono/__tests__/test-fixtures.d.ts +1 -0
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +8 -0
- package/dist/hono/index.cjs +40 -8
- package/dist/hono/index.d.ts +45 -4531
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +43 -9
- package/dist/hono/node/index.cjs +51 -6
- package/dist/hono/node/index.d.ts.map +1 -1
- package/dist/hono/node/index.js +51 -6
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.cjs +158 -32
- package/dist/hono/routes/a2a-tasks.d.ts +1 -502
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.js +162 -32
- package/dist/hono/routes/a2a.d.ts.map +1 -1
- package/dist/hono/routes/agents.cjs +410 -329
- package/dist/hono/routes/agents.d.ts +16043 -68
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +418 -330
- package/dist/hono/routes/approvals.cjs +102 -88
- package/dist/hono/routes/approvals.d.ts +2089 -142
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +108 -89
- package/dist/hono/routes/dexto-auth.cjs +40 -33
- package/dist/hono/routes/dexto-auth.d.ts +401 -2
- package/dist/hono/routes/dexto-auth.d.ts.map +1 -1
- package/dist/hono/routes/dexto-auth.js +40 -33
- package/dist/hono/routes/discovery.cjs +16 -14
- package/dist/hono/routes/discovery.d.ts +586 -1
- package/dist/hono/routes/discovery.d.ts.map +1 -1
- package/dist/hono/routes/discovery.js +16 -14
- package/dist/hono/routes/greeting.cjs +26 -22
- package/dist/hono/routes/greeting.d.ts +787 -3
- package/dist/hono/routes/greeting.d.ts.map +1 -1
- package/dist/hono/routes/greeting.js +26 -22
- package/dist/hono/routes/health.d.ts +1 -1
- package/dist/hono/routes/key.cjs +60 -52
- package/dist/hono/routes/key.d.ts +1597 -1
- package/dist/hono/routes/key.d.ts.map +1 -1
- package/dist/hono/routes/key.js +60 -52
- package/dist/hono/routes/llm.cjs +382 -349
- package/dist/hono/routes/llm.d.ts +12148 -98
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +386 -349
- package/dist/hono/routes/mcp.cjs +257 -226
- package/dist/hono/routes/mcp.d.ts +6605 -309
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +263 -225
- package/dist/hono/routes/memory.cjs +102 -89
- package/dist/hono/routes/memory.d.ts +5368 -4
- package/dist/hono/routes/memory.d.ts.map +1 -1
- package/dist/hono/routes/memory.js +108 -90
- package/dist/hono/routes/messages.cjs +189 -191
- package/dist/hono/routes/messages.d.ts +3900 -12
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +192 -191
- package/dist/hono/routes/models.cjs +106 -64
- package/dist/hono/routes/models.d.ts +2875 -2
- package/dist/hono/routes/models.d.ts.map +1 -1
- package/dist/hono/routes/models.js +108 -64
- package/dist/hono/routes/openrouter.cjs +79 -65
- package/dist/hono/routes/openrouter.d.ts +854 -1
- package/dist/hono/routes/openrouter.d.ts.map +1 -1
- package/dist/hono/routes/openrouter.js +79 -65
- package/dist/hono/routes/prompts.cjs +136 -109
- package/dist/hono/routes/prompts.d.ts +2818 -10
- package/dist/hono/routes/prompts.d.ts.map +1 -1
- package/dist/hono/routes/prompts.js +138 -109
- package/dist/hono/routes/queue.cjs +133 -120
- package/dist/hono/routes/queue.d.ts +5240 -11
- package/dist/hono/routes/queue.d.ts.map +1 -1
- package/dist/hono/routes/queue.js +136 -120
- package/dist/hono/routes/resources.cjs +65 -46
- package/dist/hono/routes/resources.d.ts +1983 -5
- package/dist/hono/routes/resources.d.ts.map +1 -1
- package/dist/hono/routes/resources.js +72 -47
- package/dist/hono/routes/schedules.cjs +233 -226
- package/dist/hono/routes/schedules.d.ts +4198 -22
- package/dist/hono/routes/schedules.d.ts.map +1 -1
- package/dist/hono/routes/schedules.js +233 -226
- package/dist/hono/routes/search.cjs +34 -30
- package/dist/hono/routes/search.d.ts +3094 -17
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/search.js +40 -31
- package/dist/hono/routes/sessions.cjs +491 -393
- package/dist/hono/routes/sessions.d.ts +18263 -65
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +497 -395
- package/dist/hono/routes/static.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.cjs +57 -61
- package/dist/hono/routes/system-prompt.d.ts +1228 -2
- package/dist/hono/routes/system-prompt.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.js +58 -62
- package/dist/hono/routes/tools.cjs +29 -34
- package/dist/hono/routes/tools.d.ts +1755 -6
- package/dist/hono/routes/tools.d.ts.map +1 -1
- package/dist/hono/routes/tools.js +33 -33
- package/dist/hono/routes/webhooks.cjs +115 -123
- package/dist/hono/routes/webhooks.d.ts +2501 -11
- package/dist/hono/routes/webhooks.d.ts.map +1 -1
- package/dist/hono/routes/webhooks.js +120 -124
- package/dist/hono/routes/workspaces.cjs +84 -79
- package/dist/hono/routes/workspaces.d.ts +2093 -2
- package/dist/hono/routes/workspaces.d.ts.map +1 -1
- package/dist/hono/routes/workspaces.js +89 -80
- package/dist/hono/schemas/responses.cjs +463 -260
- package/dist/hono/schemas/responses.d.ts +1893 -209
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +203 -14
- package/dist/hono/start-server.cjs +9 -0
- package/dist/hono/start-server.d.ts.map +1 -1
- package/dist/hono/start-server.js +9 -0
- package/dist/hono/types.d.ts +11 -0
- package/dist/hono/types.d.ts.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +7 -7
|
@@ -32,158 +32,166 @@ const MessageBodySchema = import_zod_openapi.z.object({
|
|
|
32
32
|
const ResetBodySchema = import_zod_openapi.z.object({
|
|
33
33
|
sessionId: import_zod_openapi.z.string().min(1, "Session ID is required").describe("The ID of the session to reset")
|
|
34
34
|
}).describe("Request body for resetting a conversation");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
const MessageAcceptedResponseSchema = import_zod_openapi.z.object({
|
|
36
|
+
accepted: import_zod_openapi.z.literal(true).describe("Indicates request was accepted"),
|
|
37
|
+
sessionId: import_zod_openapi.z.string().describe("Session ID used for this message")
|
|
38
|
+
}).strict().describe("Asynchronous message acceptance response");
|
|
39
|
+
const MessageSyncResponseSchema = import_zod_openapi.z.object({
|
|
40
|
+
response: import_zod_openapi.z.string().describe("Agent response text"),
|
|
41
|
+
sessionId: import_zod_openapi.z.string().describe("Session ID used for this message"),
|
|
42
|
+
tokenUsage: import_responses.TokenUsageSchema.optional().describe("Token usage statistics"),
|
|
43
|
+
messageId: import_zod_openapi.z.string().uuid().optional().describe("Assistant message ID for this response"),
|
|
44
|
+
usageScopeId: import_zod_openapi.z.string().optional().describe("Optional usage scope identifier for runtime-scoped metering"),
|
|
45
|
+
estimatedCost: import_zod_openapi.z.number().nonnegative().optional().describe("Estimated cost in USD for this response"),
|
|
46
|
+
pricingStatus: import_responses.PricingStatusSchema.optional().describe(
|
|
47
|
+
"Whether pricing was resolved for this response"
|
|
48
|
+
),
|
|
49
|
+
reasoning: import_zod_openapi.z.string().optional().describe("Extended thinking content from reasoning models"),
|
|
50
|
+
model: import_zod_openapi.z.string().optional().describe("Model used for this response"),
|
|
51
|
+
provider: import_zod_openapi.z.enum(import_core.LLM_PROVIDERS).optional().describe("LLM provider")
|
|
52
|
+
}).strict().describe("Synchronous message response");
|
|
53
|
+
const ResetResponseSchema = import_zod_openapi.z.object({
|
|
54
|
+
status: import_zod_openapi.z.string().describe("Status message indicating reset was initiated"),
|
|
55
|
+
sessionId: import_zod_openapi.z.string().describe("Session ID that was reset")
|
|
56
|
+
}).strict().describe("Session reset response");
|
|
57
|
+
const MessageStreamBusyResponseSchema = import_zod_openapi.z.object({
|
|
58
|
+
busy: import_zod_openapi.z.literal(true).describe("Indicates session is busy"),
|
|
59
|
+
sessionId: import_zod_openapi.z.string().describe("The session ID"),
|
|
60
|
+
queueLength: import_zod_openapi.z.number().describe("Current number of messages in queue"),
|
|
61
|
+
hint: import_zod_openapi.z.string().describe("Instructions for the client")
|
|
62
|
+
}).strict().describe("Busy response for streaming requests");
|
|
63
|
+
const messageRoute = (0, import_zod_openapi.createRoute)({
|
|
64
|
+
method: "post",
|
|
65
|
+
path: "/message",
|
|
66
|
+
summary: "Send Message (async)",
|
|
67
|
+
description: "Sends a message and returns immediately. The full response will be sent over SSE",
|
|
68
|
+
tags: ["messages"],
|
|
69
|
+
request: {
|
|
70
|
+
body: {
|
|
71
|
+
content: { "application/json": { schema: MessageBodySchema } }
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
responses: {
|
|
75
|
+
202: {
|
|
76
|
+
description: "Message accepted for async processing; subscribe to SSE for results",
|
|
77
|
+
content: {
|
|
78
|
+
"application/json": {
|
|
79
|
+
schema: MessageAcceptedResponseSchema
|
|
58
80
|
}
|
|
59
|
-
},
|
|
60
|
-
400: {
|
|
61
|
-
description: "Validation error",
|
|
62
|
-
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
63
81
|
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
const messageSyncRoute = (0, import_zod_openapi.createRoute)({
|
|
67
|
-
method: "post",
|
|
68
|
-
path: "/message-sync",
|
|
69
|
-
summary: "Send Message (sync)",
|
|
70
|
-
description: "Sends a message and waits for the full response",
|
|
71
|
-
tags: ["messages"],
|
|
72
|
-
request: {
|
|
73
|
-
body: { content: { "application/json": { schema: MessageBodySchema } } }
|
|
74
82
|
},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
400: {
|
|
84
|
+
description: "Validation error",
|
|
85
|
+
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
86
|
+
},
|
|
87
|
+
500: import_responses.InternalErrorResponse
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const messageSyncRoute = (0, import_zod_openapi.createRoute)({
|
|
91
|
+
method: "post",
|
|
92
|
+
path: "/message-sync",
|
|
93
|
+
summary: "Send Message (sync)",
|
|
94
|
+
description: "Sends a message and waits for the full response",
|
|
95
|
+
tags: ["messages"],
|
|
96
|
+
request: {
|
|
97
|
+
body: { content: { "application/json": { schema: MessageBodySchema } } }
|
|
98
|
+
},
|
|
99
|
+
responses: {
|
|
100
|
+
200: {
|
|
101
|
+
description: "Synchronous response",
|
|
102
|
+
content: {
|
|
103
|
+
"application/json": {
|
|
104
|
+
schema: MessageSyncResponseSchema
|
|
97
105
|
}
|
|
98
|
-
},
|
|
99
|
-
400: {
|
|
100
|
-
description: "Validation error",
|
|
101
|
-
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
102
106
|
}
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
const resetRoute = (0, import_zod_openapi.createRoute)({
|
|
106
|
-
method: "post",
|
|
107
|
-
path: "/reset",
|
|
108
|
-
summary: "Reset Conversation",
|
|
109
|
-
description: "Resets the conversation history for a given session",
|
|
110
|
-
tags: ["messages"],
|
|
111
|
-
request: {
|
|
112
|
-
body: { content: { "application/json": { schema: ResetBodySchema } } }
|
|
113
107
|
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
108
|
+
400: {
|
|
109
|
+
description: "Validation error",
|
|
110
|
+
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
111
|
+
},
|
|
112
|
+
500: import_responses.InternalErrorResponse
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const resetRoute = (0, import_zod_openapi.createRoute)({
|
|
116
|
+
method: "post",
|
|
117
|
+
path: "/reset",
|
|
118
|
+
summary: "Reset Conversation",
|
|
119
|
+
description: "Resets the conversation history for a given session",
|
|
120
|
+
tags: ["messages"],
|
|
121
|
+
request: {
|
|
122
|
+
body: { content: { "application/json": { schema: ResetBodySchema } } }
|
|
123
|
+
},
|
|
124
|
+
responses: {
|
|
125
|
+
200: {
|
|
126
|
+
description: "Reset initiated",
|
|
127
|
+
content: {
|
|
128
|
+
"application/json": {
|
|
129
|
+
schema: ResetResponseSchema
|
|
124
130
|
}
|
|
125
131
|
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
const messageStreamRoute = (0, import_zod_openapi.createRoute)({
|
|
129
|
-
method: "post",
|
|
130
|
-
path: "/message-stream",
|
|
131
|
-
summary: "Stream message response",
|
|
132
|
-
description: "Sends a message and streams the response via Server-Sent Events (SSE). Returns SSE stream directly in response. Events include llm:thinking, llm:chunk, llm:tool-call, llm:tool-result, llm:response, and llm:error. Final llm:response events include token usage, assistant message ID, and pricing metadata when available. If the session is busy processing another message, returns 202 with queue information.",
|
|
133
|
-
tags: ["messages"],
|
|
134
|
-
request: {
|
|
135
|
-
body: {
|
|
136
|
-
content: { "application/json": { schema: MessageBodySchema } }
|
|
137
|
-
}
|
|
138
132
|
},
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
133
|
+
400: import_responses.BadRequestErrorResponse,
|
|
134
|
+
404: import_responses.NotFoundErrorResponse,
|
|
135
|
+
500: import_responses.InternalErrorResponse
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const messageStreamRoute = (0, import_zod_openapi.createRoute)({
|
|
139
|
+
method: "post",
|
|
140
|
+
path: "/message-stream",
|
|
141
|
+
summary: "Stream message response",
|
|
142
|
+
description: "Sends a message and streams the response via Server-Sent Events (SSE). Returns SSE stream directly in response. Events include llm:thinking, llm:chunk, llm:tool-call, llm:tool-result, llm:response, and llm:error. Final llm:response events include token usage, assistant message ID, and pricing metadata when available. If the session is busy processing another message, returns 202 with queue information.",
|
|
143
|
+
tags: ["messages"],
|
|
144
|
+
request: {
|
|
145
|
+
body: {
|
|
146
|
+
content: { "application/json": { schema: MessageBodySchema } }
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
responses: {
|
|
150
|
+
200: {
|
|
151
|
+
description: "SSE stream of agent events. Standard SSE format with event type and JSON data.",
|
|
152
|
+
headers: {
|
|
153
|
+
"Content-Type": {
|
|
154
|
+
description: "SSE content type",
|
|
155
|
+
schema: { type: "string", example: "text/event-stream" }
|
|
159
156
|
},
|
|
160
|
-
|
|
161
|
-
"
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
"Cache-Control": {
|
|
158
|
+
description: "Disable caching for stream",
|
|
159
|
+
schema: { type: "string", example: "no-cache" }
|
|
160
|
+
},
|
|
161
|
+
Connection: {
|
|
162
|
+
description: "Keep connection alive for streaming",
|
|
163
|
+
schema: { type: "string", example: "keep-alive" }
|
|
164
|
+
},
|
|
165
|
+
"X-Accel-Buffering": {
|
|
166
|
+
description: "Disable nginx buffering",
|
|
167
|
+
schema: { type: "string", example: "no" }
|
|
166
168
|
}
|
|
167
169
|
},
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
busy: import_zod_openapi.z.literal(true).describe("Indicates session is busy"),
|
|
174
|
-
sessionId: import_zod_openapi.z.string().describe("The session ID"),
|
|
175
|
-
queueLength: import_zod_openapi.z.number().describe("Current number of messages in queue"),
|
|
176
|
-
hint: import_zod_openapi.z.string().describe("Instructions for the client")
|
|
177
|
-
}).strict()
|
|
178
|
-
}
|
|
170
|
+
content: {
|
|
171
|
+
"text/event-stream": {
|
|
172
|
+
schema: import_zod_openapi.z.string().describe(
|
|
173
|
+
"Server-Sent Events stream. Events: llm:thinking (start), llm:chunk (text fragments), llm:tool-call (tool execution), llm:tool-result (tool output), llm:response (final), llm:error (errors). Final llm:response payloads include token usage, assistant message ID, and pricing metadata when available."
|
|
174
|
+
)
|
|
179
175
|
}
|
|
180
|
-
},
|
|
181
|
-
400: {
|
|
182
|
-
description: "Validation error",
|
|
183
|
-
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
184
176
|
}
|
|
185
|
-
}
|
|
186
|
-
|
|
177
|
+
},
|
|
178
|
+
202: {
|
|
179
|
+
description: "Session is busy processing another message. Use the queue endpoints to manage pending messages.",
|
|
180
|
+
content: {
|
|
181
|
+
"application/json": {
|
|
182
|
+
schema: MessageStreamBusyResponseSchema
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
400: {
|
|
187
|
+
description: "Validation error",
|
|
188
|
+
content: { "application/json": { schema: import_responses.ApiErrorResponseSchema } }
|
|
189
|
+
},
|
|
190
|
+
500: import_responses.InternalErrorResponse
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
function createMessagesRouter(getAgent, _approvalCoordinator) {
|
|
194
|
+
const app = new import_zod_openapi.OpenAPIHono();
|
|
187
195
|
return app.openapi(messageRoute, async (ctx) => {
|
|
188
196
|
const agent = await getAgent(ctx);
|
|
189
197
|
agent.logger.info("Received message via POST /api/message");
|
|
@@ -223,7 +231,7 @@ function createMessagesRouter(getAgent, approvalCoordinator) {
|
|
|
223
231
|
agent.logger.info("Received request via POST /api/reset");
|
|
224
232
|
const { sessionId } = ctx.req.valid("json");
|
|
225
233
|
await agent.resetConversation(sessionId);
|
|
226
|
-
return ctx.json({ status: "reset initiated", sessionId });
|
|
234
|
+
return ctx.json({ status: "reset initiated", sessionId }, 200);
|
|
227
235
|
}).openapi(messageStreamRoute, async (ctx) => {
|
|
228
236
|
const agent = await getAgent(ctx);
|
|
229
237
|
const { content: rawContent, sessionId } = ctx.req.valid("json");
|
|
@@ -243,42 +251,43 @@ function createMessagesRouter(getAgent, approvalCoordinator) {
|
|
|
243
251
|
}
|
|
244
252
|
const abortController = new AbortController();
|
|
245
253
|
const { signal } = abortController;
|
|
246
|
-
const
|
|
254
|
+
const requestDisconnectSignal = ctx.req.raw.signal;
|
|
255
|
+
const streamWithDisconnectSignal = agent.stream.bind(agent);
|
|
256
|
+
const iterator = await streamWithDisconnectSignal(content, sessionId, {
|
|
257
|
+
disconnectSignal: signal
|
|
258
|
+
});
|
|
247
259
|
return (0, import_streaming.streamSSE)(ctx, async (stream) => {
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
{ signal }
|
|
260
|
-
);
|
|
261
|
-
approvalCoordinator.onResponse(
|
|
262
|
-
(response) => {
|
|
263
|
-
if (response.sessionId === sessionId) {
|
|
264
|
-
pendingApprovalEvents.push({
|
|
265
|
-
event: "approval:response",
|
|
266
|
-
data: response
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
{ signal }
|
|
271
|
-
);
|
|
260
|
+
const abortOnDisconnect = () => {
|
|
261
|
+
abortController.abort();
|
|
262
|
+
};
|
|
263
|
+
stream.onAbort(abortOnDisconnect);
|
|
264
|
+
requestDisconnectSignal.addEventListener("abort", abortOnDisconnect, {
|
|
265
|
+
once: true
|
|
266
|
+
});
|
|
267
|
+
if (requestDisconnectSignal.aborted) {
|
|
268
|
+
abortOnDisconnect();
|
|
272
269
|
}
|
|
270
|
+
let writeChain = Promise.resolve();
|
|
271
|
+
const enqueueSSEWrite = (event, data) => {
|
|
272
|
+
writeChain = writeChain.then(async () => {
|
|
273
|
+
if (signal.aborted) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
await stream.writeSSE({
|
|
277
|
+
event,
|
|
278
|
+
data: JSON.stringify(data)
|
|
279
|
+
});
|
|
280
|
+
}).catch((error) => {
|
|
281
|
+
if (!signal.aborted) {
|
|
282
|
+
agent.logger.warn(
|
|
283
|
+
`Failed to write SSE event '${event}': ${error instanceof Error ? error.message : String(error)}`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
return writeChain;
|
|
288
|
+
};
|
|
273
289
|
try {
|
|
274
290
|
for await (const event of iterator) {
|
|
275
|
-
while (pendingApprovalEvents.length > 0) {
|
|
276
|
-
const approvalEvent = pendingApprovalEvents.shift();
|
|
277
|
-
await stream.writeSSE({
|
|
278
|
-
event: approvalEvent.event,
|
|
279
|
-
data: JSON.stringify(approvalEvent.data)
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
291
|
const eventData = event.name === "llm:error" && event.error instanceof Error ? {
|
|
283
292
|
...event,
|
|
284
293
|
error: {
|
|
@@ -287,31 +296,20 @@ function createMessagesRouter(getAgent, approvalCoordinator) {
|
|
|
287
296
|
stack: event.error.stack
|
|
288
297
|
}
|
|
289
298
|
} : event;
|
|
290
|
-
await
|
|
291
|
-
event: event.name,
|
|
292
|
-
data: JSON.stringify(eventData)
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
while (pendingApprovalEvents.length > 0) {
|
|
296
|
-
const approvalEvent = pendingApprovalEvents.shift();
|
|
297
|
-
await stream.writeSSE({
|
|
298
|
-
event: approvalEvent.event,
|
|
299
|
-
data: JSON.stringify(approvalEvent.data)
|
|
300
|
-
});
|
|
299
|
+
await enqueueSSEWrite(event.name, eventData);
|
|
301
300
|
}
|
|
302
301
|
} catch (error) {
|
|
303
|
-
await
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
recoverable: false,
|
|
310
|
-
sessionId
|
|
311
|
-
})
|
|
302
|
+
await enqueueSSEWrite("llm:error", {
|
|
303
|
+
error: {
|
|
304
|
+
message: error instanceof Error ? error.message : String(error)
|
|
305
|
+
},
|
|
306
|
+
recoverable: false,
|
|
307
|
+
sessionId
|
|
312
308
|
});
|
|
313
309
|
} finally {
|
|
310
|
+
requestDisconnectSignal.removeEventListener("abort", abortOnDisconnect);
|
|
314
311
|
abortController.abort();
|
|
312
|
+
await writeChain;
|
|
315
313
|
}
|
|
316
314
|
});
|
|
317
315
|
});
|