@cogitator-ai/koa 0.1.14 → 0.3.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 +50 -28
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +1 -4
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +8 -11
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/body-parser.d.ts +5 -1
- package/dist/middleware/body-parser.d.ts.map +1 -1
- package/dist/middleware/body-parser.js +70 -25
- package/dist/middleware/body-parser.js.map +1 -1
- package/dist/middleware/error-handler.js +1 -1
- package/dist/middleware/error-handler.js.map +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +38 -34
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/swarms.d.ts.map +1 -1
- package/dist/routes/swarms.js +49 -53
- package/dist/routes/swarms.js.map +1 -1
- package/dist/routes/threads.d.ts.map +1 -1
- package/dist/routes/threads.js +33 -37
- package/dist/routes/threads.js.map +1 -1
- package/dist/routes/tools.d.ts.map +1 -1
- package/dist/routes/tools.js +11 -17
- package/dist/routes/tools.js.map +1 -1
- package/dist/routes/workflows.d.ts.map +1 -1
- package/dist/routes/workflows.js +55 -28
- package/dist/routes/workflows.js.map +1 -1
- package/dist/types.d.ts +11 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +8 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +21 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/lookup.d.ts +2 -0
- package/dist/utils/lookup.d.ts.map +1 -0
- package/dist/utils/lookup.js +4 -0
- package/dist/utils/lookup.js.map +1 -0
- package/dist/utils/request.d.ts +4 -0
- package/dist/utils/request.d.ts.map +1 -0
- package/dist/utils/request.js +11 -0
- package/dist/utils/request.js.map +1 -0
- package/dist/utils/results.d.ts +22 -0
- package/dist/utils/results.d.ts.map +1 -0
- package/dist/utils/results.js +37 -0
- package/dist/utils/results.js.map +1 -0
- package/dist/utils/validation.d.ts +14 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +103 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/websocket/handler.d.ts +1 -1
- package/dist/websocket/handler.d.ts.map +1 -1
- package/dist/websocket/handler.js +260 -151
- package/dist/websocket/handler.js.map +1 -1
- package/package.json +23 -20
package/README.md
CHANGED
|
@@ -15,9 +15,7 @@ import Koa from 'koa';
|
|
|
15
15
|
import { Cogitator, Agent } from '@cogitator-ai/core';
|
|
16
16
|
import { cogitatorApp } from '@cogitator-ai/koa';
|
|
17
17
|
|
|
18
|
-
const cogitator = new Cogitator({
|
|
19
|
-
/* ... */
|
|
20
|
-
});
|
|
18
|
+
const cogitator = new Cogitator({/* ... */});
|
|
21
19
|
const chatAgent = new Agent({ name: 'chat', instructions: 'You are a helpful assistant.' });
|
|
22
20
|
|
|
23
21
|
const app = new Koa();
|
|
@@ -41,17 +39,28 @@ Creates a Koa Router with all Cogitator endpoints.
|
|
|
41
39
|
|
|
42
40
|
**Options:**
|
|
43
41
|
|
|
44
|
-
| Option
|
|
45
|
-
|
|
|
46
|
-
| `cogitator`
|
|
47
|
-
| `agents`
|
|
48
|
-
| `workflows`
|
|
49
|
-
| `swarms`
|
|
50
|
-
| `auth`
|
|
51
|
-
| `enableSwagger`
|
|
52
|
-
| `swagger`
|
|
53
|
-
| `
|
|
54
|
-
|
|
42
|
+
| Option | Type | Description |
|
|
43
|
+
| --------------- | ------------------------------- | ---------------------------------------------- |
|
|
44
|
+
| `cogitator` | `Cogitator` | **Required.** Cogitator runtime instance |
|
|
45
|
+
| `agents` | `Record<string, Agent>` | Named agents to expose |
|
|
46
|
+
| `workflows` | `Record<string, Workflow>` | Named workflows |
|
|
47
|
+
| `swarms` | `Record<string, SwarmConfig>` | Named swarms |
|
|
48
|
+
| `auth` | `(ctx: Context) => AuthContext` | Authentication function (receives Koa Context) |
|
|
49
|
+
| `enableSwagger` | `boolean` | Enable Swagger/OpenAPI docs |
|
|
50
|
+
| `swagger` | `SwaggerConfig` | Swagger configuration |
|
|
51
|
+
| `bodyLimit` | `number` | Max JSON body size in bytes (default 1 MiB) |
|
|
52
|
+
|
|
53
|
+
WebSocket support is attached to the HTTP server with [`setupWebSocket`](#websocket), not through router options.
|
|
54
|
+
|
|
55
|
+
## Request Handling
|
|
56
|
+
|
|
57
|
+
- Request bodies are validated before anything reaches the runtime: `input` must be a non-empty string, `context` an object, `threadId` a non-empty string, swarm `timeout` a positive number. Invalid bodies return `400 INVALID_INPUT` with the offending field in the message.
|
|
58
|
+
- Workflow runs accept an optional body. `options` is limited to `maxConcurrency`, `maxIterations` (positive integers) and `checkpoint` (boolean); any other option is dropped, and a wrongly typed one returns `400 INVALID_INPUT`.
|
|
59
|
+
- Thread messages accept `role` of `user`, `assistant` or `system`; `metadata` is stored with the entry and a token estimate is recorded.
|
|
60
|
+
- `CogitatorError`s are returned with their HTTP status and code (for example `429 LLM_RATE_LIMITED`). Any other error is logged and returned as `500 Internal server error` without internal details. A workflow that finishes with an error is reported as an error, never as a successful result.
|
|
61
|
+
- When the client disconnects, the running agent, workflow or swarm is aborted, for both JSON and SSE endpoints.
|
|
62
|
+
- `GET /agents` returns each agent's `description` and never exposes its `instructions`.
|
|
63
|
+
- `GET /tools` returns tool parameters as JSON Schema.
|
|
55
64
|
|
|
56
65
|
## Endpoints
|
|
57
66
|
|
|
@@ -127,14 +136,14 @@ app.use(main.routes());
|
|
|
127
136
|
|
|
128
137
|
## WebSocket
|
|
129
138
|
|
|
130
|
-
Requires the optional `ws`
|
|
139
|
+
Requires the optional `ws` dependency. Supports agent, workflow, and swarm runs over a persistent connection.
|
|
131
140
|
|
|
132
141
|
```typescript
|
|
133
142
|
import { createServer } from 'http';
|
|
134
143
|
import { cogitatorApp, setupWebSocket } from '@cogitator-ai/koa';
|
|
135
144
|
|
|
136
145
|
const app = new Koa();
|
|
137
|
-
const router = cogitatorApp({ cogitator, agents
|
|
146
|
+
const router = cogitatorApp({ cogitator, agents });
|
|
138
147
|
app.use(router.routes());
|
|
139
148
|
app.use(router.allowedMethods());
|
|
140
149
|
|
|
@@ -145,29 +154,39 @@ await setupWebSocket(
|
|
|
145
154
|
{
|
|
146
155
|
path: '/ws',
|
|
147
156
|
pingInterval: 30000,
|
|
157
|
+
pingTimeout: 10000,
|
|
158
|
+
maxPayloadSize: 1024 * 1024,
|
|
159
|
+
auth: (req) => {
|
|
160
|
+
if (req.headers.authorization !== `Bearer ${process.env.API_TOKEN}`) {
|
|
161
|
+
throw new Error('Unauthorized');
|
|
162
|
+
}
|
|
163
|
+
return { userId: 'api' };
|
|
164
|
+
},
|
|
148
165
|
}
|
|
149
166
|
);
|
|
150
167
|
|
|
151
168
|
server.listen(3000);
|
|
152
169
|
```
|
|
153
170
|
|
|
171
|
+
The router's `auth` option does not cover WebSocket connections, so pass `auth` to `setupWebSocket` to protect them: it receives the upgrade `IncomingMessage`, and throwing rejects the handshake with `401` (or `500` when the error carries a `status >= 500`). Upgrades on other paths are left to other `upgrade` listeners (or rejected with `404` when there are none), so the socket can share the HTTP server with other WebSocket servers. A client that does not answer a ping within `pingTimeout` (defaults to `pingInterval`) is terminated, and closing a connection aborts its active run.
|
|
172
|
+
|
|
154
173
|
**Message types:**
|
|
155
174
|
|
|
156
|
-
| Client sends |
|
|
157
|
-
| ------------ |
|
|
158
|
-
| `run` |
|
|
159
|
-
| `stop` |
|
|
160
|
-
| `ping` |
|
|
175
|
+
| Client sends | Payload |
|
|
176
|
+
| ------------ | ------------------------------------------------------------------------------ |
|
|
177
|
+
| `run` | `{ type: 'agent' \| 'workflow' \| 'swarm', name, input, context?, threadId? }` |
|
|
178
|
+
| `stop` | Cancels the current run |
|
|
179
|
+
| `ping` | Answered with `pong` (echoes `id`) |
|
|
161
180
|
|
|
162
|
-
| Server sends | Description
|
|
163
|
-
| ------------ |
|
|
164
|
-
| `event` |
|
|
165
|
-
| `error` |
|
|
166
|
-
| `pong` | Heartbeat
|
|
181
|
+
| Server sends | Description |
|
|
182
|
+
| ------------ | ----------------------------------------------------------------------------------------- |
|
|
183
|
+
| `event` | `token`, `tool-call`, `tool-result`, `complete` (with the serialized result), `cancelled` |
|
|
184
|
+
| `error` | Invalid message, unknown resource, run already in progress, or a masked run failure |
|
|
185
|
+
| `pong` | Heartbeat reply |
|
|
167
186
|
|
|
168
187
|
## SSE Streaming
|
|
169
188
|
|
|
170
|
-
The adapter includes `KoaStreamWriter` for Server-Sent Events with structured event types (text deltas, tool calls, workflow/swarm events).
|
|
189
|
+
The adapter includes `KoaStreamWriter` for Server-Sent Events with structured event types (text deltas, tool calls, workflow/swarm events). Agent streams emit `tool-call-start`, `tool-call-delta` (the JSON arguments) and `tool-call-end` with the provider's tool call id, so `tool-result.toolCallId` always matches the call it belongs to.
|
|
171
190
|
|
|
172
191
|
## Event Factories
|
|
173
192
|
|
|
@@ -205,7 +224,7 @@ import {
|
|
|
205
224
|
Built-in middleware stack (applied automatically by `cogitatorApp`):
|
|
206
225
|
|
|
207
226
|
- **Error handler** — catches errors and returns structured `ErrorResponse`
|
|
208
|
-
- **Body parser** — parses JSON for POST, PUT, PATCH requests (1
|
|
227
|
+
- **Body parser** — parses JSON for POST, PUT, PATCH requests (`bodyLimit`, 1 MiB by default, returns `413` above it). A body already parsed by upstream middleware such as `koa-bodyparser` is reused
|
|
209
228
|
- **Context** — injects `RouteContext` with `runtime`, `agents`, `workflows`, `swarms` into Koa state
|
|
210
229
|
- **Auth** — optional authentication via the `auth` callback
|
|
211
230
|
|
|
@@ -218,6 +237,9 @@ import type {
|
|
|
218
237
|
AuthContext,
|
|
219
238
|
AuthFunction,
|
|
220
239
|
WebSocketConfig,
|
|
240
|
+
WebSocketAuthFunction,
|
|
241
|
+
WebSocketRunPayload,
|
|
242
|
+
BodyParserOptions,
|
|
221
243
|
WorkflowStatusResponse,
|
|
222
244
|
AgentRunRequest,
|
|
223
245
|
AgentRunResponse,
|
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiBtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiBtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC,CA8B9E"}
|
package/dist/app.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createSwaggerRoutes } from './swagger/index.js';
|
|
|
5
5
|
export function cogitatorApp(opts) {
|
|
6
6
|
const router = new Router();
|
|
7
7
|
router.use(createErrorHandler());
|
|
8
|
-
router.use(createBodyParser());
|
|
8
|
+
router.use(createBodyParser({ limit: opts.bodyLimit }));
|
|
9
9
|
router.use(createContextMiddleware(opts));
|
|
10
10
|
if (opts.auth) {
|
|
11
11
|
router.use(createAuthMiddleware(opts.auth));
|
|
@@ -25,9 +25,6 @@ export function cogitatorApp(opts) {
|
|
|
25
25
|
router.use(sub.routes());
|
|
26
26
|
router.use(sub.allowedMethods());
|
|
27
27
|
}
|
|
28
|
-
if (opts.enableWebSocket) {
|
|
29
|
-
console.log('[CogitatorKoa] WebSocket support enabled — call setupWebSocket() with your HTTP server');
|
|
30
|
-
}
|
|
31
28
|
return router;
|
|
32
29
|
}
|
|
33
30
|
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,MAAM,MAAM,GAAG,IAAI,MAAM,EAAkB,CAAC;IAE5C,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,MAAM,MAAM,GAAG,IAAI,MAAM,EAAkB,CAAC;IAE5C,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACxD,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,UAAU,GAAG;QACjB,kBAAkB,EAAE;QACpB,iBAAiB,EAAE;QACnB,kBAAkB,EAAE;QACpB,gBAAgB,EAAE;QAClB,oBAAoB,EAAE;QACtB,iBAAiB,EAAE;KACpB,CAAC;IAEF,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,UAAU,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { cogitatorApp } from './app.js';
|
|
2
|
-
export type { AuthContext, AuthFunction, CogitatorAppOptions, CogitatorState, RouteContext, WebSocketConfig, AgentListResponse, AgentRunRequest, AgentRunResponse, ThreadResponse, AddMessageRequest, ToolListResponse, WorkflowListResponse, WorkflowRunRequest, WorkflowRunResponse, WorkflowStatusResponse, SwarmListResponse, SwarmRunRequest, SwarmRunResponse, BlackboardResponse, HealthResponse, ErrorResponse, SwaggerConfig, WebSocketMessage, WebSocketResponse, } from './types.js';
|
|
2
|
+
export type { AuthContext, AuthFunction, CogitatorAppOptions, CogitatorState, RouteContext, WebSocketConfig, WebSocketAuthFunction, AgentListResponse, AgentRunRequest, AgentRunResponse, ThreadResponse, AddMessageRequest, ToolListResponse, WorkflowListResponse, WorkflowRunRequest, WorkflowRunResponse, WorkflowStatusResponse, SwarmListResponse, SwarmRunRequest, SwarmRunResponse, BlackboardResponse, HealthResponse, ErrorResponse, SwaggerConfig, WebSocketMessage, WebSocketResponse, WebSocketRunPayload, } from './types.js';
|
|
3
3
|
export { createContextMiddleware, createAuthMiddleware, createBodyParser, createErrorHandler, } from './middleware/index.js';
|
|
4
|
+
export type { BodyParserOptions } from './middleware/body-parser.js';
|
|
4
5
|
export { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
|
|
5
6
|
export { createSwaggerRoutes } from './swagger/index.js';
|
|
6
7
|
export { KoaStreamWriter, setupSSEHeaders } from './streaming/koa-stream-writer.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,YAAY,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,YAAY,EACV,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEpF,OAAO,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,YAAY,EACV,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,WAAW,EACX,KAAK,GACN,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAgCxC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEpF,OAAO,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAiBrC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,KAAK,EAAe,YAAY,EAAkB,MAAM,aAAa,CAAC;AAE7E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,IACzC,KAAK,OAAO,EAAE,MAAM,IAAI,mBAiBvC"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
export function createAuthMiddleware(authFn) {
|
|
2
2
|
return async (ctx, next) => {
|
|
3
|
+
let auth;
|
|
3
4
|
try {
|
|
4
|
-
|
|
5
|
-
ctx.state.auth = auth;
|
|
6
|
-
await next();
|
|
5
|
+
auth = await authFn(ctx);
|
|
7
6
|
}
|
|
8
7
|
catch (err) {
|
|
9
|
-
const status = err
|
|
10
|
-
if (status && status >= 500) {
|
|
8
|
+
const status = err?.status;
|
|
9
|
+
if (status !== undefined && status >= 500) {
|
|
11
10
|
throw err;
|
|
12
11
|
}
|
|
13
12
|
ctx.status = 401;
|
|
14
|
-
ctx.body = {
|
|
15
|
-
|
|
16
|
-
message: 'Unauthorized',
|
|
17
|
-
code: 'UNAUTHORIZED',
|
|
18
|
-
},
|
|
19
|
-
};
|
|
13
|
+
ctx.body = { error: { message: 'Unauthorized', code: 'UNAUTHORIZED' } };
|
|
14
|
+
return;
|
|
20
15
|
}
|
|
16
|
+
ctx.state.auth = auth;
|
|
17
|
+
await next();
|
|
21
18
|
};
|
|
22
19
|
}
|
|
23
20
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACxC,IAAI,IAA6B,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAI,GAAkC,EAAE,MAAM,CAAC;YAC3D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;gBAC1C,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,CAAC;YACxE,OAAO;QACT,CAAC;QAEA,GAAG,CAAC,KAAwB,CAAC,IAAI,GAAG,IAAI,CAAC;QAC1C,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { Context, Next } from 'koa';
|
|
2
|
-
export declare
|
|
2
|
+
export declare const DEFAULT_BODY_LIMIT: number;
|
|
3
|
+
export interface BodyParserOptions {
|
|
4
|
+
limit?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function createBodyParser(options?: BodyParserOptions): (ctx: Context, next: Next) => Promise<void>;
|
|
3
7
|
//# sourceMappingURL=body-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body-parser.d.ts","sourceRoot":"","sources":["../../src/middleware/body-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"body-parser.d.ts","sourceRoot":"","sources":["../../src/middleware/body-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEzC,eAAO,MAAM,kBAAkB,QAAc,CAAC;AAI9C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,IAGhD,KAAK,OAAO,EAAE,MAAM,IAAI,mBAqBvC"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
export const DEFAULT_BODY_LIMIT = 1024 * 1024;
|
|
2
|
+
const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
|
|
3
|
+
export function createBodyParser(options = {}) {
|
|
4
|
+
const limit = options.limit ?? DEFAULT_BODY_LIMIT;
|
|
3
5
|
return async (ctx, next) => {
|
|
4
|
-
if (
|
|
5
|
-
const
|
|
6
|
-
if (
|
|
6
|
+
if (BODY_METHODS.has(ctx.method) && ctx.is('application/json') && !isBodyConsumed(ctx)) {
|
|
7
|
+
const declaredLength = Number(ctx.get('content-length'));
|
|
8
|
+
if (Number.isFinite(declaredLength) && declaredLength > limit) {
|
|
9
|
+
await discardBody(ctx);
|
|
10
|
+
throw new PayloadTooLargeError();
|
|
11
|
+
}
|
|
12
|
+
const raw = await readBody(ctx, limit);
|
|
13
|
+
if (raw.trim()) {
|
|
7
14
|
try {
|
|
8
|
-
ctx.request.body = JSON.parse(
|
|
15
|
+
ctx.request.body = JSON.parse(raw);
|
|
9
16
|
}
|
|
10
17
|
catch {
|
|
11
18
|
ctx.status = 400;
|
|
@@ -17,42 +24,80 @@ export function createBodyParser() {
|
|
|
17
24
|
await next();
|
|
18
25
|
};
|
|
19
26
|
}
|
|
20
|
-
function
|
|
27
|
+
function isBodyConsumed(ctx) {
|
|
28
|
+
return (ctx.request.body !== undefined ||
|
|
29
|
+
ctx.req.readableEnded);
|
|
30
|
+
}
|
|
31
|
+
function discardBody(ctx) {
|
|
32
|
+
const req = ctx.req;
|
|
33
|
+
if (req.readableEnded || req.destroyed)
|
|
34
|
+
return Promise.resolve();
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const done = () => {
|
|
37
|
+
req.off('end', done);
|
|
38
|
+
req.off('close', done);
|
|
39
|
+
req.off('error', done);
|
|
40
|
+
resolve();
|
|
41
|
+
};
|
|
42
|
+
req.on('end', done);
|
|
43
|
+
req.on('close', done);
|
|
44
|
+
req.on('error', done);
|
|
45
|
+
req.resume();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function readBody(ctx, limit) {
|
|
21
49
|
return new Promise((resolve, reject) => {
|
|
50
|
+
const req = ctx.req;
|
|
22
51
|
const chunks = [];
|
|
23
52
|
let size = 0;
|
|
24
53
|
let settled = false;
|
|
25
|
-
|
|
54
|
+
const cleanup = () => {
|
|
55
|
+
req.off('data', onData);
|
|
56
|
+
req.off('end', onEnd);
|
|
57
|
+
req.off('error', onError);
|
|
58
|
+
req.off('close', onClose);
|
|
59
|
+
};
|
|
60
|
+
const settle = (action) => {
|
|
26
61
|
if (settled)
|
|
27
62
|
return;
|
|
63
|
+
settled = true;
|
|
64
|
+
cleanup();
|
|
65
|
+
action();
|
|
66
|
+
};
|
|
67
|
+
const onData = (chunk) => {
|
|
28
68
|
size += chunk.length;
|
|
29
|
-
if (size >
|
|
30
|
-
settled = true;
|
|
69
|
+
if (size > limit) {
|
|
31
70
|
chunks.length = 0;
|
|
32
|
-
|
|
33
|
-
|
|
71
|
+
settle(() => {
|
|
72
|
+
void discardBody(ctx).then(() => reject(new PayloadTooLargeError()));
|
|
73
|
+
});
|
|
34
74
|
return;
|
|
35
75
|
}
|
|
36
76
|
chunks.push(chunk);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (settled)
|
|
46
|
-
return;
|
|
47
|
-
settled = true;
|
|
48
|
-
reject(err);
|
|
49
|
-
});
|
|
77
|
+
};
|
|
78
|
+
const onEnd = () => settle(() => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
79
|
+
const onError = (err) => settle(() => reject(err));
|
|
80
|
+
const onClose = () => settle(() => reject(new RequestAbortedError()));
|
|
81
|
+
req.on('data', onData);
|
|
82
|
+
req.on('end', onEnd);
|
|
83
|
+
req.on('error', onError);
|
|
84
|
+
req.on('close', onClose);
|
|
50
85
|
});
|
|
51
86
|
}
|
|
52
87
|
class PayloadTooLargeError extends Error {
|
|
53
88
|
status = 413;
|
|
89
|
+
expose = true;
|
|
54
90
|
constructor() {
|
|
55
91
|
super('Payload too large');
|
|
92
|
+
this.name = 'PayloadTooLargeError';
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
class RequestAbortedError extends Error {
|
|
96
|
+
status = 400;
|
|
97
|
+
expose = true;
|
|
98
|
+
constructor() {
|
|
99
|
+
super('Request aborted');
|
|
100
|
+
this.name = 'RequestAbortedError';
|
|
56
101
|
}
|
|
57
102
|
}
|
|
58
103
|
//# sourceMappingURL=body-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body-parser.js","sourceRoot":"","sources":["../../src/middleware/body-parser.ts"],"names":[],"mappings":"AAEA,MAAM,
|
|
1
|
+
{"version":3,"file":"body-parser.js","sourceRoot":"","sources":["../../src/middleware/body-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ export function createErrorHandler() {
|
|
|
8
8
|
if (ctx.headerSent)
|
|
9
9
|
return;
|
|
10
10
|
if (CogitatorError.isCogitatorError(err)) {
|
|
11
|
-
ctx.status = ERROR_STATUS_CODES[err.code]
|
|
11
|
+
ctx.status = err.statusCode ?? ERROR_STATUS_CODES[err.code] ?? 500;
|
|
12
12
|
ctx.body = {
|
|
13
13
|
error: {
|
|
14
14
|
message: err.message,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEpF,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,CAAC,UAAU;gBAAE,OAAO;YAE3B,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEpF,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,CAAC,UAAU;gBAAE,OAAO;YAE3B,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;gBACnE,GAAG,CAAC,IAAI,GAAG;oBACT,KAAK,EAAE;wBACL,OAAO,EAAE,GAAG,CAAC,OAAO;wBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;qBACf;iBACF,CAAC;gBACF,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAI,GAA2B,CAAC,MAAM,CAAC;YACnD,IAAI,MAAM,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;gBAC5C,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;gBACpB,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;oBAClB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;oBACtD,GAAG,CAAC,IAAI,GAAG;wBACT,KAAK,EAAE;4BACL,OAAO,EAAE,uBAAuB;4BAChC,IAAI,EAAE,SAAS,CAAC,cAAc;yBAC/B;qBACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,GAAG;wBACT,KAAK,EAAE;4BACL,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY;4BAC1D,IAAI,EAAE,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,YAAY;yBAC1D;qBACF,CAAC;gBACJ,CAAC;gBACD,OAAO;YACT,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;YAEtD,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG;gBACT,KAAK,EAAE;oBACL,OAAO,EAAE,uBAAuB;oBAChC,IAAI,EAAE,SAAS,CAAC,cAAc;iBAC/B;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAuC,MAAM,aAAa,CAAC;AASvF,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,cAAc,CAAC,CAkI1D"}
|
package/dist/routes/agents.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import Router from '@koa/router';
|
|
2
2
|
import { KoaStreamWriter, setupSSEHeaders } from '../streaming/index.js';
|
|
3
3
|
import { generateId } from '@cogitator-ai/server-shared';
|
|
4
|
+
import { getOwn } from '../utils/lookup.js';
|
|
5
|
+
import { resolveError } from '../utils/errors.js';
|
|
6
|
+
import { getRequestBody, onClientDisconnect } from '../utils/request.js';
|
|
7
|
+
import { parseAgentRunRequest } from '../utils/validation.js';
|
|
4
8
|
export function createAgentRoutes() {
|
|
5
9
|
const router = new Router();
|
|
6
10
|
router.get('/agents', (ctx) => {
|
|
7
11
|
const { agents } = ctx.state.cogitator;
|
|
8
12
|
const agentList = Object.entries(agents).map(([name, agent]) => ({
|
|
9
13
|
name,
|
|
10
|
-
description: agent.config.
|
|
11
|
-
tools: agent.config.tools?.map((t) => t.name)
|
|
14
|
+
description: agent.config.description,
|
|
15
|
+
tools: agent.config.tools?.map((t) => t.name) ?? [],
|
|
12
16
|
}));
|
|
13
17
|
const response = { agents: agentList };
|
|
14
18
|
ctx.body = response;
|
|
@@ -16,23 +20,24 @@ export function createAgentRoutes() {
|
|
|
16
20
|
router.post('/agents/:name/run', async (ctx) => {
|
|
17
21
|
const { agents, runtime } = ctx.state.cogitator;
|
|
18
22
|
const { name } = ctx.params;
|
|
19
|
-
const agent = agents
|
|
23
|
+
const agent = getOwn(agents, name);
|
|
20
24
|
if (!agent) {
|
|
21
25
|
ctx.status = 404;
|
|
22
26
|
ctx.body = { error: { message: `Agent '${name}' not found`, code: 'NOT_FOUND' } };
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
25
|
-
const
|
|
26
|
-
if (!
|
|
29
|
+
const parsed = parseAgentRunRequest(getRequestBody(ctx));
|
|
30
|
+
if (!parsed.ok) {
|
|
27
31
|
ctx.status = 400;
|
|
28
|
-
ctx.body = { error: { message:
|
|
32
|
+
ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
|
|
29
33
|
return;
|
|
30
34
|
}
|
|
35
|
+
const abortController = new AbortController();
|
|
36
|
+
onClientDisconnect(ctx, () => abortController.abort());
|
|
31
37
|
try {
|
|
32
38
|
const result = await runtime.run(agent, {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
threadId: body.threadId,
|
|
39
|
+
...parsed.value,
|
|
40
|
+
signal: abortController.signal,
|
|
36
41
|
});
|
|
37
42
|
const response = {
|
|
38
43
|
output: result.output,
|
|
@@ -47,55 +52,54 @@ export function createAgentRoutes() {
|
|
|
47
52
|
ctx.body = response;
|
|
48
53
|
}
|
|
49
54
|
catch (error) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
if (abortController.signal.aborted)
|
|
56
|
+
return;
|
|
57
|
+
const { status, body } = resolveError(error, 'Agent run error');
|
|
58
|
+
ctx.status = status;
|
|
59
|
+
ctx.body = body;
|
|
53
60
|
}
|
|
54
61
|
});
|
|
55
62
|
router.post('/agents/:name/stream', async (ctx) => {
|
|
56
63
|
const { agents, runtime } = ctx.state.cogitator;
|
|
57
64
|
const { name } = ctx.params;
|
|
58
|
-
const agent = agents
|
|
65
|
+
const agent = getOwn(agents, name);
|
|
59
66
|
if (!agent) {
|
|
60
67
|
ctx.status = 404;
|
|
61
68
|
ctx.body = { error: { message: `Agent '${name}' not found`, code: 'NOT_FOUND' } };
|
|
62
69
|
return;
|
|
63
70
|
}
|
|
64
|
-
const
|
|
65
|
-
if (!
|
|
71
|
+
const parsed = parseAgentRunRequest(getRequestBody(ctx));
|
|
72
|
+
if (!parsed.ok) {
|
|
66
73
|
ctx.status = 400;
|
|
67
|
-
ctx.body = { error: { message:
|
|
74
|
+
ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
70
77
|
setupSSEHeaders(ctx);
|
|
71
78
|
const writer = new KoaStreamWriter(ctx);
|
|
72
79
|
const messageId = generateId('msg');
|
|
73
|
-
|
|
80
|
+
const textId = generateId('txt');
|
|
81
|
+
const abortController = new AbortController();
|
|
82
|
+
onClientDisconnect(ctx, () => {
|
|
74
83
|
writer.close();
|
|
84
|
+
abortController.abort();
|
|
75
85
|
});
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
writer.start(messageId);
|
|
87
|
+
writer.textStart(textId);
|
|
78
88
|
try {
|
|
79
|
-
writer.start(messageId);
|
|
80
|
-
textId = generateId('txt');
|
|
81
|
-
textStarted = true;
|
|
82
|
-
writer.textStart(textId);
|
|
83
89
|
const result = await runtime.run(agent, {
|
|
84
|
-
|
|
85
|
-
context: body.context,
|
|
86
|
-
threadId: body.threadId,
|
|
90
|
+
...parsed.value,
|
|
87
91
|
stream: true,
|
|
92
|
+
signal: abortController.signal,
|
|
88
93
|
onToken: (token) => {
|
|
89
94
|
writer.textDelta(textId, token);
|
|
90
95
|
},
|
|
91
96
|
onToolCall: (toolCall) => {
|
|
92
|
-
|
|
93
|
-
writer.
|
|
94
|
-
writer.toolCallEnd(
|
|
97
|
+
writer.toolCallStart(toolCall.id, toolCall.name);
|
|
98
|
+
writer.toolCallDelta(toolCall.id, JSON.stringify(toolCall.arguments));
|
|
99
|
+
writer.toolCallEnd(toolCall.id);
|
|
95
100
|
},
|
|
96
101
|
onToolResult: (toolResult) => {
|
|
97
|
-
|
|
98
|
-
writer.toolResult(resultId, toolResult.callId, toolResult.result);
|
|
102
|
+
writer.toolResult(generateId('res'), toolResult.callId, toolResult.result);
|
|
99
103
|
},
|
|
100
104
|
});
|
|
101
105
|
writer.textEnd(textId);
|
|
@@ -106,11 +110,11 @@ export function createAgentRoutes() {
|
|
|
106
110
|
});
|
|
107
111
|
}
|
|
108
112
|
catch (error) {
|
|
109
|
-
if (
|
|
113
|
+
if (!abortController.signal.aborted) {
|
|
110
114
|
writer.textEnd(textId);
|
|
115
|
+
const { body } = resolveError(error, 'Agent stream error');
|
|
116
|
+
writer.error(body.error.message, body.error.code);
|
|
111
117
|
}
|
|
112
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
113
|
-
writer.error(message, 'INTERNAL');
|
|
114
118
|
}
|
|
115
119
|
finally {
|
|
116
120
|
writer.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swarms.d.ts","sourceRoot":"","sources":["../../src/routes/swarms.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"swarms.d.ts","sourceRoot":"","sources":["../../src/routes/swarms.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,aAAa,CAAC;AAUzF,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,cAAc,CAAC,CAqL1D"}
|