@reminix/runtime 0.5.0 → 0.6.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 +201 -30
- package/dist/agent.d.ts +126 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +201 -0
- package/dist/agent.js.map +1 -0
- package/dist/index.d.ts +28 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -5
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +39 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +239 -0
- package/dist/server.js.map +1 -0
- package/dist/streaming.d.ts +27 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +58 -0
- package/dist/streaming.js.map +1 -0
- package/dist/types.d.ts +185 -79
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +82 -2
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +6 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +11 -8
- package/dist/executor.d.ts +0 -17
- package/dist/executor.d.ts.map +0 -1
- package/dist/executor.js +0 -22
- package/dist/executor.js.map +0 -1
- package/dist/loader.d.ts +0 -19
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -52
- package/dist/loader.js.map +0 -1
- package/dist/registry.d.ts +0 -24
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -208
- package/dist/registry.js.map +0 -1
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono server for hosting AI agents.
|
|
3
|
+
*/
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
import { Agent } from './agent';
|
|
6
|
+
/**
|
|
7
|
+
* Options for the serve function.
|
|
8
|
+
*/
|
|
9
|
+
export interface ServeOptions {
|
|
10
|
+
/** Host to bind to (default: '0.0.0.0') */
|
|
11
|
+
host?: string;
|
|
12
|
+
/** Port to listen on (default: 8080) */
|
|
13
|
+
port?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a Hono app with agent routes.
|
|
17
|
+
*
|
|
18
|
+
* @param agents - List of agents to serve
|
|
19
|
+
* @returns Configured Hono app
|
|
20
|
+
*/
|
|
21
|
+
export declare function createApp(agents: Agent[]): Hono;
|
|
22
|
+
/**
|
|
23
|
+
* Start a server hosting the provided agents.
|
|
24
|
+
*
|
|
25
|
+
* @param agents - A single agent or array of agents to serve
|
|
26
|
+
* @param options - Server options (host, port)
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const agent = new Agent('my-agent');
|
|
31
|
+
* agent.onInvoke(async (input) => ({ output: 'hello' }));
|
|
32
|
+
*
|
|
33
|
+
* serve(agent, { port: 8080 });
|
|
34
|
+
* // or
|
|
35
|
+
* serve([agent1, agent2], { port: 8080 });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function serve(agents: Agent | Agent[], options?: ServeOptions): void;
|
|
39
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,EAAE,KAAK,EAAmC,MAAM,SAAS,CAAC;AAcjE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAiL/C;AA+BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI,CA8B/E"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono server for hosting AI agents.
|
|
3
|
+
*/
|
|
4
|
+
import { Hono } from 'hono';
|
|
5
|
+
import { streamSSE } from 'hono/streaming';
|
|
6
|
+
import { serve as honoServe } from '@hono/node-server';
|
|
7
|
+
import { AgentError, NotImplementedError } from './agent';
|
|
8
|
+
import { streamToSse } from './streaming';
|
|
9
|
+
import { ChatRequestSchema, InvokeRequestSchema, } from './types';
|
|
10
|
+
import { VERSION } from './version';
|
|
11
|
+
/**
|
|
12
|
+
* Create a Hono app with agent routes.
|
|
13
|
+
*
|
|
14
|
+
* @param agents - List of agents to serve
|
|
15
|
+
* @returns Configured Hono app
|
|
16
|
+
*/
|
|
17
|
+
export function createApp(agents) {
|
|
18
|
+
const app = new Hono();
|
|
19
|
+
// Build agent registry
|
|
20
|
+
const registry = new Map();
|
|
21
|
+
for (const agent of agents) {
|
|
22
|
+
if (registry.has(agent.name)) {
|
|
23
|
+
throw new Error(`Duplicate agent name: ${agent.name}`);
|
|
24
|
+
}
|
|
25
|
+
registry.set(agent.name, agent);
|
|
26
|
+
}
|
|
27
|
+
// Health check endpoint
|
|
28
|
+
app.get('/health', (c) => {
|
|
29
|
+
const response = {
|
|
30
|
+
status: 'healthy',
|
|
31
|
+
agents: Array.from(registry.keys()),
|
|
32
|
+
};
|
|
33
|
+
return c.json(response);
|
|
34
|
+
});
|
|
35
|
+
// Discovery endpoint for Reminix platform
|
|
36
|
+
app.get('/_discover', (c) => {
|
|
37
|
+
const response = {
|
|
38
|
+
runtime: {
|
|
39
|
+
version: VERSION,
|
|
40
|
+
language: 'typescript',
|
|
41
|
+
framework: 'hono',
|
|
42
|
+
},
|
|
43
|
+
agents: agents.map((agent) => agent.toInfo()),
|
|
44
|
+
};
|
|
45
|
+
return c.json(response);
|
|
46
|
+
});
|
|
47
|
+
// Per-agent health endpoint
|
|
48
|
+
app.get('/agent/:name/health', (c) => {
|
|
49
|
+
const name = c.req.param('name');
|
|
50
|
+
const agent = registry.get(name);
|
|
51
|
+
if (!agent) {
|
|
52
|
+
return c.json({ error: `Agent not found: ${name}` }, 404);
|
|
53
|
+
}
|
|
54
|
+
const response = {
|
|
55
|
+
name: agent.name,
|
|
56
|
+
invoke: agent.hasInvoke,
|
|
57
|
+
chat: agent.hasChat,
|
|
58
|
+
};
|
|
59
|
+
return c.json(response);
|
|
60
|
+
});
|
|
61
|
+
// Invoke endpoint
|
|
62
|
+
app.post('/agent/:name/invoke', async (c) => {
|
|
63
|
+
const name = c.req.param('name');
|
|
64
|
+
const agent = registry.get(name);
|
|
65
|
+
if (!agent) {
|
|
66
|
+
return c.json({ error: `Agent not found: ${name}` }, 404);
|
|
67
|
+
}
|
|
68
|
+
// Parse and validate request
|
|
69
|
+
let body;
|
|
70
|
+
try {
|
|
71
|
+
body = await c.req.json();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return c.json({ error: 'Invalid JSON body' }, 400);
|
|
75
|
+
}
|
|
76
|
+
const parseResult = InvokeRequestSchema.safeParse(body);
|
|
77
|
+
if (!parseResult.success) {
|
|
78
|
+
const errors = parseResult.error.issues
|
|
79
|
+
.map((i) => `${i.path.join('.')}: ${i.message}`)
|
|
80
|
+
.join('; ');
|
|
81
|
+
return c.json({ error: `Invalid request: ${errors}` }, 400);
|
|
82
|
+
}
|
|
83
|
+
const { input, stream } = parseResult.data;
|
|
84
|
+
try {
|
|
85
|
+
const result = await agent.handleInvoke(input);
|
|
86
|
+
// Check if streaming
|
|
87
|
+
if (isAsyncGenerator(result)) {
|
|
88
|
+
if (stream) {
|
|
89
|
+
// Return SSE stream
|
|
90
|
+
return streamSSE(c, async (sseStream) => {
|
|
91
|
+
for await (const event of streamToSse(result)) {
|
|
92
|
+
await sseStream.writeSSE({ data: event.replace(/^data: /, '').replace(/\n\n$/, '') });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Collect chunks into single response
|
|
98
|
+
const chunks = [];
|
|
99
|
+
for await (const chunk of result) {
|
|
100
|
+
chunks.push(chunk.chunk);
|
|
101
|
+
}
|
|
102
|
+
return c.json({ output: chunks.join('') });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return c.json(result);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
return handleError(c, err);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// Chat endpoint
|
|
112
|
+
app.post('/agent/:name/chat', async (c) => {
|
|
113
|
+
const name = c.req.param('name');
|
|
114
|
+
const agent = registry.get(name);
|
|
115
|
+
if (!agent) {
|
|
116
|
+
return c.json({ error: `Agent not found: ${name}` }, 404);
|
|
117
|
+
}
|
|
118
|
+
// Parse and validate request
|
|
119
|
+
let body;
|
|
120
|
+
try {
|
|
121
|
+
body = await c.req.json();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return c.json({ error: 'Invalid JSON body' }, 400);
|
|
125
|
+
}
|
|
126
|
+
const parseResult = ChatRequestSchema.safeParse(body);
|
|
127
|
+
if (!parseResult.success) {
|
|
128
|
+
const errors = parseResult.error.issues
|
|
129
|
+
.map((i) => `${i.path.join('.')}: ${i.message}`)
|
|
130
|
+
.join('; ');
|
|
131
|
+
return c.json({ error: `Invalid request: ${errors}` }, 400);
|
|
132
|
+
}
|
|
133
|
+
const { messages, stream } = parseResult.data;
|
|
134
|
+
// Validate messages array is not empty
|
|
135
|
+
if (messages.length === 0) {
|
|
136
|
+
return c.json({ error: 'Messages array cannot be empty' }, 400);
|
|
137
|
+
}
|
|
138
|
+
// Validate message roles
|
|
139
|
+
const validRoles = ['system', 'user', 'assistant', 'tool'];
|
|
140
|
+
for (const msg of messages) {
|
|
141
|
+
if (!validRoles.includes(msg.role)) {
|
|
142
|
+
return c.json({ error: `Invalid role: ${msg.role}` }, 400);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const result = await agent.handleChat(messages);
|
|
147
|
+
// Check if streaming
|
|
148
|
+
if (isAsyncGenerator(result)) {
|
|
149
|
+
if (stream) {
|
|
150
|
+
// Return SSE stream
|
|
151
|
+
return streamSSE(c, async (sseStream) => {
|
|
152
|
+
for await (const event of streamToSse(result)) {
|
|
153
|
+
await sseStream.writeSSE({ data: event.replace(/^data: /, '').replace(/\n\n$/, '') });
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Collect chunks into single response
|
|
159
|
+
const chunks = [];
|
|
160
|
+
for await (const chunk of result) {
|
|
161
|
+
chunks.push(chunk.chunk);
|
|
162
|
+
}
|
|
163
|
+
return c.json({
|
|
164
|
+
message: { role: 'assistant', content: chunks.join('') },
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return c.json(result);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
return handleError(c, err);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
return app;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if a value is an async generator.
|
|
178
|
+
*/
|
|
179
|
+
function isAsyncGenerator(value) {
|
|
180
|
+
return (value !== null &&
|
|
181
|
+
typeof value === 'object' &&
|
|
182
|
+
Symbol.asyncIterator in value &&
|
|
183
|
+
typeof value.next === 'function');
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Handle errors from agent handlers.
|
|
187
|
+
*/
|
|
188
|
+
function handleError(c, err) {
|
|
189
|
+
if (err instanceof NotImplementedError) {
|
|
190
|
+
return c.json({ error: err.message }, 501);
|
|
191
|
+
}
|
|
192
|
+
if (err instanceof AgentError) {
|
|
193
|
+
return c.json({ error: err.message }, 502);
|
|
194
|
+
}
|
|
195
|
+
const message = err instanceof Error ? err.message : 'Internal server error';
|
|
196
|
+
return c.json({ error: message }, 500);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Start a server hosting the provided agents.
|
|
200
|
+
*
|
|
201
|
+
* @param agents - A single agent or array of agents to serve
|
|
202
|
+
* @param options - Server options (host, port)
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const agent = new Agent('my-agent');
|
|
207
|
+
* agent.onInvoke(async (input) => ({ output: 'hello' }));
|
|
208
|
+
*
|
|
209
|
+
* serve(agent, { port: 8080 });
|
|
210
|
+
* // or
|
|
211
|
+
* serve([agent1, agent2], { port: 8080 });
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function serve(agents, options = {}) {
|
|
215
|
+
const { host = '0.0.0.0', port = 8080 } = options;
|
|
216
|
+
// Normalize to array
|
|
217
|
+
const agentList = Array.isArray(agents) ? agents : [agents];
|
|
218
|
+
if (agentList.length === 0) {
|
|
219
|
+
throw new Error('At least one agent must be provided');
|
|
220
|
+
}
|
|
221
|
+
// Check for duplicate names
|
|
222
|
+
const names = new Set();
|
|
223
|
+
for (const agent of agentList) {
|
|
224
|
+
if (names.has(agent.name)) {
|
|
225
|
+
throw new Error(`Duplicate agent name: ${agent.name}`);
|
|
226
|
+
}
|
|
227
|
+
names.add(agent.name);
|
|
228
|
+
}
|
|
229
|
+
const app = createApp(agentList);
|
|
230
|
+
console.log(`Starting Reminix Agent Runtime...`);
|
|
231
|
+
console.log(`Agents: ${agentList.map((a) => a.name).join(', ')}`);
|
|
232
|
+
console.log(`Listening on http://${host}:${port}`);
|
|
233
|
+
honoServe({
|
|
234
|
+
fetch: app.fetch,
|
|
235
|
+
hostname: host,
|
|
236
|
+
port,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAS,UAAU,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GAOpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,MAAe;IACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,uBAAuB;IACvB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,wBAAwB;IACxB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAmB;YAC/B,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SACpC,CAAC;QACF,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,0CAA0C;IAC1C,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAqB;YACjC,OAAO,EAAE;gBACP,OAAO,EAAE,OAAO;gBAChB,QAAQ,EAAE,YAAY;gBACtB,SAAS,EAAE,MAAM;aAClB;YACD,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;SAC9C,CAAC;QACF,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,4BAA4B;IAC5B,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,QAAQ,GAAgB;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,SAAS;YACvB,IAAI,EAAE,KAAK,CAAC,OAAO;SACpB,CAAC;QACF,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,kBAAkB;IAClB,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;QAED,6BAA6B;QAC7B,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,WAAW,GAAG,mBAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM;iBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;iBAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC;QAE3C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAE/C,qBAAqB;YACrB,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7B,IAAI,MAAM,EAAE,CAAC;oBACX,oBAAoB;oBACpB,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;wBACtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC9C,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;wBACxF,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,sCAAsC;oBACtC,MAAM,MAAM,GAAa,EAAE,CAAC;oBAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;oBACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAA2B,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;YAED,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC;QAED,6BAA6B;QAC7B,IAAI,IAAa,CAAC;QAClB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM;iBACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;iBAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC;QAE9C,uCAAuC;QACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAAE,GAAG,CAAC,CAAC;QAClE,CAAC;QAED,yBAAyB;QACzB,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QAC3D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAEhD,qBAAqB;YACrB,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7B,IAAI,MAAM,EAAE,CAAC;oBACX,oBAAoB;oBACpB,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;wBACtC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC9C,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;wBACxF,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,sCAAsC;oBACtC,MAAM,MAAM,GAAa,EAAE,CAAC;oBAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;oBACD,OAAO,CAAC,CAAC,IAAI,CAAC;wBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;qBAClC,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;YAED,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,CACL,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,MAAM,CAAC,aAAa,IAAI,KAAK;QAC7B,OAAQ,KAAwB,CAAC,IAAI,KAAK,UAAU,CACrD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,CAAwD,EACxD,GAAY;IAEZ,IAAI,GAAG,YAAY,mBAAmB,EAAE,CAAC;QACvC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;QAC9B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;IAC7E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,KAAK,CAAC,MAAuB,EAAE,UAAwB,EAAE;IACvE,MAAM,EAAE,IAAI,GAAG,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAElD,qBAAqB;IACrB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE5D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,4BAA4B;IAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,WAAW,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IAEnD,SAAS,CAAC;QACR,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,QAAQ,EAAE,IAAI;QACd,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming utilities for Server-Sent Events (SSE).
|
|
3
|
+
*/
|
|
4
|
+
import type { StreamChunk } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Format data as an SSE event.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatSseEvent(data: Record<string, unknown>): string;
|
|
9
|
+
/**
|
|
10
|
+
* Format the SSE done marker.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatSseDone(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Validate a streaming chunk.
|
|
15
|
+
*
|
|
16
|
+
* @param chunk - The chunk to validate
|
|
17
|
+
* @returns An error message if invalid, null if valid
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateChunk(chunk: unknown): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Convert an async generator to an SSE stream.
|
|
22
|
+
*
|
|
23
|
+
* @param generator - The async generator yielding StreamChunk objects
|
|
24
|
+
* @returns An async generator yielding SSE-formatted strings
|
|
25
|
+
*/
|
|
26
|
+
export declare function streamToSse(generator: AsyncGenerator<StreamChunk, void, unknown>): AsyncGenerator<string, void, unknown>;
|
|
27
|
+
//# sourceMappingURL=streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAc3D;AAED;;;;;GAKG;AACH,wBAAuB,WAAW,CAChC,SAAS,EAAE,cAAc,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,GACpD,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAiBvC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming utilities for Server-Sent Events (SSE).
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format data as an SSE event.
|
|
6
|
+
*/
|
|
7
|
+
export function formatSseEvent(data) {
|
|
8
|
+
return `data: ${JSON.stringify(data)}\n\n`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Format the SSE done marker.
|
|
12
|
+
*/
|
|
13
|
+
export function formatSseDone() {
|
|
14
|
+
return 'data: [DONE]\n\n';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validate a streaming chunk.
|
|
18
|
+
*
|
|
19
|
+
* @param chunk - The chunk to validate
|
|
20
|
+
* @returns An error message if invalid, null if valid
|
|
21
|
+
*/
|
|
22
|
+
export function validateChunk(chunk) {
|
|
23
|
+
if (typeof chunk !== 'object' || chunk === null) {
|
|
24
|
+
return 'Chunk must be an object';
|
|
25
|
+
}
|
|
26
|
+
if (!('chunk' in chunk)) {
|
|
27
|
+
return 'Chunk missing required "chunk" field';
|
|
28
|
+
}
|
|
29
|
+
if (typeof chunk.chunk !== 'string') {
|
|
30
|
+
return 'Chunk "chunk" field must be a string';
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Convert an async generator to an SSE stream.
|
|
36
|
+
*
|
|
37
|
+
* @param generator - The async generator yielding StreamChunk objects
|
|
38
|
+
* @returns An async generator yielding SSE-formatted strings
|
|
39
|
+
*/
|
|
40
|
+
export async function* streamToSse(generator) {
|
|
41
|
+
try {
|
|
42
|
+
for await (const chunk of generator) {
|
|
43
|
+
const error = validateChunk(chunk);
|
|
44
|
+
if (error) {
|
|
45
|
+
yield formatSseEvent({ error });
|
|
46
|
+
yield formatSseDone();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
yield formatSseEvent(chunk);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
54
|
+
yield formatSseEvent({ error: `Stream error: ${message}` });
|
|
55
|
+
}
|
|
56
|
+
yield formatSseDone();
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAA6B;IAC1D,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,yBAAyB,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,IAAI,OAAQ,KAAqB,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrD,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,CAChC,SAAqD;IAErD,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChC,MAAM,aAAa,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,MAAM,cAAc,CAAC,EAAE,KAAK,EAAE,iBAAiB,OAAO,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,aAAa,EAAE,CAAC;AACxB,CAAC"}
|