@cogitator-ai/hono 0.1.14 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +67 -2
  2. package/dist/app.d.ts.map +1 -1
  3. package/dist/app.js +3 -1
  4. package/dist/app.js.map +1 -1
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/middleware/body-limit.d.ts +5 -0
  10. package/dist/middleware/body-limit.d.ts.map +1 -0
  11. package/dist/middleware/body-limit.js +9 -0
  12. package/dist/middleware/body-limit.js.map +1 -0
  13. package/dist/middleware/error-handler.d.ts.map +1 -1
  14. package/dist/middleware/error-handler.js +7 -3
  15. package/dist/middleware/error-handler.js.map +1 -1
  16. package/dist/routes/agents.d.ts.map +1 -1
  17. package/dist/routes/agents.js +43 -56
  18. package/dist/routes/agents.js.map +1 -1
  19. package/dist/routes/swarms.d.ts.map +1 -1
  20. package/dist/routes/swarms.js +50 -71
  21. package/dist/routes/swarms.js.map +1 -1
  22. package/dist/routes/threads.d.ts.map +1 -1
  23. package/dist/routes/threads.js +35 -53
  24. package/dist/routes/threads.js.map +1 -1
  25. package/dist/routes/workflows.d.ts.map +1 -1
  26. package/dist/routes/workflows.js +53 -45
  27. package/dist/routes/workflows.js.map +1 -1
  28. package/dist/streaming/hono-stream-writer.d.ts +0 -1
  29. package/dist/streaming/hono-stream-writer.d.ts.map +1 -1
  30. package/dist/streaming/hono-stream-writer.js +0 -10
  31. package/dist/streaming/hono-stream-writer.js.map +1 -1
  32. package/dist/types.d.ts +19 -1
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/utils/errors.d.ts +11 -0
  35. package/dist/utils/errors.d.ts.map +1 -0
  36. package/dist/utils/errors.js +28 -0
  37. package/dist/utils/errors.js.map +1 -0
  38. package/dist/utils/lookup.d.ts +2 -0
  39. package/dist/utils/lookup.d.ts.map +1 -0
  40. package/dist/utils/lookup.js +4 -0
  41. package/dist/utils/lookup.js.map +1 -0
  42. package/dist/utils/request.d.ts +15 -0
  43. package/dist/utils/request.d.ts.map +1 -0
  44. package/dist/utils/request.js +37 -0
  45. package/dist/utils/request.js.map +1 -0
  46. package/dist/utils/results.d.ts +22 -0
  47. package/dist/utils/results.d.ts.map +1 -0
  48. package/dist/utils/results.js +37 -0
  49. package/dist/utils/results.js.map +1 -0
  50. package/dist/utils/validation.d.ts +14 -0
  51. package/dist/utils/validation.d.ts.map +1 -0
  52. package/dist/utils/validation.js +103 -0
  53. package/dist/utils/validation.js.map +1 -0
  54. package/dist/websocket/handler.d.ts +4 -12
  55. package/dist/websocket/handler.d.ts.map +1 -1
  56. package/dist/websocket/handler.js +204 -131
  57. package/dist/websocket/handler.js.map +1 -1
  58. package/package.json +10 -9
package/README.md CHANGED
@@ -49,8 +49,20 @@ Creates a Hono sub-application with all Cogitator endpoints.
49
49
  | `auth` | `(c: Context) => AuthContext` | Authentication function (receives Hono Context) |
50
50
  | `enableSwagger` | `boolean` | Enable Swagger/OpenAPI docs |
51
51
  | `swagger` | `SwaggerConfig` | Swagger configuration |
52
- | `enableWebSocket` | `boolean` | Enable WebSocket support |
53
- | `websocket` | `WebSocketConfig` | WebSocket configuration |
52
+ | `enableWebSocket` | `boolean` | Enable the WebSocket endpoint |
53
+ | `websocket` | `WebSocketConfig` | WebSocket configuration (see below) |
54
+ | `bodyLimit` | `number` | Max request body size in bytes (default 1 MiB) |
55
+
56
+ ## Request Handling
57
+
58
+ - 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.
59
+ - 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`.
60
+ - Thread messages accept `role` of `user`, `assistant` or `system`; `metadata` is stored with the entry and a token estimate is recorded.
61
+ - Bodies above `bodyLimit` return `413 PAYLOAD_TOO_LARGE`.
62
+ - `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.
63
+ - When the client disconnects, the running agent, workflow or swarm is aborted, for both JSON and SSE endpoints.
64
+ - `GET /agents` returns each agent's `description` and never exposes its `instructions`.
65
+ - `GET /tools` returns tool parameters as JSON Schema.
54
66
 
55
67
  ## Endpoints
56
68
 
@@ -130,6 +142,51 @@ Deno.serve(app.fetch);
130
142
 
131
143
  The adapter uses Hono's built-in `streamSSE` for Server-Sent Events — no raw response manipulation needed. Works across all runtimes.
132
144
 
145
+ 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.
146
+
147
+ ## WebSocket
148
+
149
+ WebSocket upgrades are runtime-specific in Hono, so pass the `upgradeWebSocket` helper of your runtime. The endpoint goes through the same middleware as the REST routes, including `auth`.
150
+
151
+ ```typescript
152
+ import { serve } from '@hono/node-server';
153
+ import { createNodeWebSocket } from '@hono/node-ws';
154
+
155
+ const app = new Hono();
156
+ const { upgradeWebSocket, injectWebSocket } = createNodeWebSocket({ app });
157
+
158
+ app.route(
159
+ '/cogitator',
160
+ cogitatorApp({
161
+ cogitator,
162
+ agents: { chat: chatAgent },
163
+ enableWebSocket: true,
164
+ websocket: { path: '/ws', upgradeWebSocket, maxPayloadSize: 1024 * 1024 },
165
+ })
166
+ );
167
+
168
+ const server = serve({ fetch: app.fetch, port: 3000 });
169
+ injectWebSocket(server);
170
+ ```
171
+
172
+ On Bun use `upgradeWebSocket` from `hono/bun`, on Deno from `hono/deno`, on Cloudflare Workers from `hono/cloudflare-workers`. Without `upgradeWebSocket` the endpoint answers `501 UNIMPLEMENTED`.
173
+
174
+ **Protocol:**
175
+
176
+ | Client sends | Payload |
177
+ | ------------ | ------------------------------------------------------------------------------ |
178
+ | `run` | `{ type: 'agent' \| 'workflow' \| 'swarm', name, input, context?, threadId? }` |
179
+ | `stop` | Cancels the current run |
180
+ | `ping` | Answered with `pong` (echoes `id`) |
181
+
182
+ | Server sends | Description |
183
+ | ------------ | ----------------------------------------------------------------------------------------- |
184
+ | `event` | `token`, `tool-call`, `tool-result`, `complete` (with the serialized result), `cancelled` |
185
+ | `error` | Invalid message, unknown resource, run already in progress, or a masked run failure |
186
+ | `pong` | Heartbeat reply |
187
+
188
+ Messages larger than `maxPayloadSize` are rejected and the socket is closed with code `1009`. Closing the socket aborts the active run. `handleWebSocketMessage` and `createClientState` are exported for custom WebSocket integrations.
189
+
133
190
  ## Individual Route Access
134
191
 
135
192
  ```typescript
@@ -137,7 +194,15 @@ import {
137
194
  createAgentRoutes,
138
195
  createThreadRoutes,
139
196
  createToolRoutes,
197
+ createWorkflowRoutes,
198
+ createSwarmRoutes,
140
199
  createHealthRoutes,
200
+ createSwaggerRoutes,
201
+ createWebSocketRoutes,
202
+ createContextMiddleware,
203
+ createAuthMiddleware,
204
+ createBodyLimitMiddleware,
205
+ errorHandler,
141
206
  } from '@cogitator-ai/hono';
142
207
  ```
143
208
 
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,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAe/D,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,CA2BrE"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAgB/D,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,CA4BrE"}
package/dist/app.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Hono } from 'hono';
2
2
  import { createContextMiddleware } from './middleware/context.js';
3
3
  import { createAuthMiddleware } from './middleware/auth.js';
4
+ import { createBodyLimitMiddleware } from './middleware/body-limit.js';
4
5
  import { errorHandler } from './middleware/error-handler.js';
5
6
  import { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
6
7
  import { createSwaggerRoutes } from './swagger/index.js';
@@ -8,6 +9,7 @@ import { createWebSocketRoutes } from './websocket/handler.js';
8
9
  export function cogitatorApp(opts) {
9
10
  const app = new Hono();
10
11
  app.use('*', createContextMiddleware(opts));
12
+ app.use('*', createBodyLimitMiddleware(opts.bodyLimit));
11
13
  if (opts.auth) {
12
14
  app.use('*', createAuthMiddleware(opts.auth));
13
15
  }
@@ -21,7 +23,7 @@ export function cogitatorApp(opts) {
21
23
  app.route('/', createSwaggerRoutes(opts.swagger));
22
24
  }
23
25
  if (opts.enableWebSocket) {
24
- app.route('/', createWebSocketRoutes(opts.websocket?.path));
26
+ app.route('/', createWebSocketRoutes(opts.websocket));
25
27
  }
26
28
  app.onError(errorHandler);
27
29
  return app;
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,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;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAW,CAAC;IAEhC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACpC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACvC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAEpC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE1B,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,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;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,UAAU,YAAY,CAAC,IAAyB;IACpD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAW,CAAC;IAEhC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5C,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAExD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACpC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACvC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAEpC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE1B,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export { cogitatorApp } from './app.js';
2
- export type { CogitatorAppOptions, CogitatorContext, HonoEnv, AuthContext, AuthFunction, 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 { CogitatorAppOptions, CogitatorContext, HonoEnv, AuthContext, AuthFunction, WebSocketConfig, AgentListResponse, AgentRunRequest, AgentRunResponse, ThreadResponse, AddMessageRequest, ToolListResponse, WorkflowListResponse, WorkflowRunRequest, WorkflowRunResponse, WorkflowStatusResponse, SwarmListResponse, SwarmRunRequest, SwarmRunResponse, BlackboardResponse, HealthResponse, ErrorResponse, SwaggerConfig, WebSocketMessage, WebSocketResponse, WebSocketRunPayload, WebSocketClientState, WebSocketLike, } from './types.js';
3
3
  export { HonoStreamWriter } from './streaming/hono-stream-writer.js';
4
4
  export { createContextMiddleware } from './middleware/context.js';
5
5
  export { createAuthMiddleware } from './middleware/auth.js';
6
6
  export { errorHandler } from './middleware/error-handler.js';
7
+ export { createBodyLimitMiddleware } from './middleware/body-limit.js';
7
8
  export { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
8
9
  export { createSwaggerRoutes } from './swagger/index.js';
9
10
  export { createWebSocketRoutes, handleWebSocketMessage, createClientState, } from './websocket/handler.js';
@@ -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,mBAAmB,EACnB,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,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,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,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,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,6BAA6B,CAAC"}
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,mBAAmB,EACnB,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,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,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,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,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export { HonoStreamWriter } from './streaming/hono-stream-writer.js';
3
3
  export { createContextMiddleware } from './middleware/context.js';
4
4
  export { createAuthMiddleware } from './middleware/auth.js';
5
5
  export { errorHandler } from './middleware/error-handler.js';
6
+ export { createBodyLimitMiddleware } from './middleware/body-limit.js';
6
7
  export { createHealthRoutes, createAgentRoutes, createThreadRoutes, createToolRoutes, createWorkflowRoutes, createSwarmRoutes, } from './routes/index.js';
7
8
  export { createSwaggerRoutes } from './swagger/index.js';
8
9
  export { createWebSocketRoutes, handleWebSocketMessage, createClientState, } from './websocket/handler.js';
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;AA8BxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,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,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAiCxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,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,EACL,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,GACX,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import type { HonoEnv } from '../types.js';
3
+ export declare const DEFAULT_BODY_LIMIT: number;
4
+ export declare function createBodyLimitMiddleware(maxSize?: number): MiddlewareHandler<HonoEnv>;
5
+ //# sourceMappingURL=body-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-limit.d.ts","sourceRoot":"","sources":["../../src/middleware/body-limit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,kBAAkB,QAAc,CAAC;AAE9C,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,MAA2B,GACnC,iBAAiB,CAAC,OAAO,CAAC,CAM5B"}
@@ -0,0 +1,9 @@
1
+ import { bodyLimit } from 'hono/body-limit';
2
+ export const DEFAULT_BODY_LIMIT = 1024 * 1024;
3
+ export function createBodyLimitMiddleware(maxSize = DEFAULT_BODY_LIMIT) {
4
+ return bodyLimit({
5
+ maxSize,
6
+ onError: (c) => c.json({ error: { message: 'Payload too large', code: 'PAYLOAD_TOO_LARGE' } }, 413),
7
+ });
8
+ }
9
+ //# sourceMappingURL=body-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-limit.js","sourceRoot":"","sources":["../../src/middleware/body-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9C,MAAM,UAAU,yBAAyB,CACvC,UAAkB,kBAAkB;IAEpC,OAAO,SAAS,CAAC;QACf,OAAO;QACP,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,GAAG,CAAC;KACtF,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,OAAO,CAe9C,CAAC"}
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,OAAO,CAe9C,CAAC"}
@@ -1,8 +1,12 @@
1
- import { CogitatorError, ERROR_STATUS_CODES, ErrorCode } from '@cogitator-ai/types';
1
+ import { HTTPException } from 'hono/http-exception';
2
+ import { CogitatorError, ErrorCode } from '@cogitator-ai/types';
3
+ import { cogitatorErrorStatus } from '../utils/errors.js';
2
4
  export const errorHandler = (err, c) => {
5
+ if (err instanceof HTTPException) {
6
+ return err.getResponse();
7
+ }
3
8
  if (CogitatorError.isCogitatorError(err)) {
4
- const statusCode = ERROR_STATUS_CODES[err.code] || 500;
5
- return c.json({ error: { message: err.message, code: err.code } }, statusCode);
9
+ return c.json({ error: { message: err.message, code: err.code } }, cogitatorErrorStatus(err));
6
10
  }
7
11
  console.error('[CogitatorHono] Unhandled error:', err);
8
12
  return c.json({ error: { message: 'Internal server error', code: ErrorCode.INTERNAL_ERROR } }, 500);
@@ -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;AAGpF,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;IAC5D,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QACvD,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EACnD,UAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;IAEvD,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,EAC/E,GAAG,CACJ,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;IAC5D,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;IAEvD,OAAO,CAAC,CAAC,IAAI,CACX,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,EAC/E,GAAG,CACJ,CAAC;AACJ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,OAAO,EAAwD,MAAM,aAAa,CAAC;AAGjG,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,CAkJjD"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,OAAO,EAAuC,MAAM,aAAa,CAAC;AAchF,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,CAwHjD"}
@@ -2,15 +2,18 @@ import { Hono } from 'hono';
2
2
  import { streamSSE } from 'hono/streaming';
3
3
  import { generateId } from '@cogitator-ai/server-shared';
4
4
  import { HonoStreamWriter } from '../streaming/hono-stream-writer.js';
5
- import { CogitatorError } from '@cogitator-ai/types';
5
+ import { getOwn } from '../utils/lookup.js';
6
+ import { resolveError } from '../utils/errors.js';
7
+ import { createRequestAbortController, errorResponse, invalidInput, invalidJson, readJsonBody, requestAborted, } from '../utils/request.js';
8
+ import { parseAgentRunRequest } from '../utils/validation.js';
6
9
  export function createAgentRoutes() {
7
10
  const app = new Hono();
8
11
  app.get('/agents', (c) => {
9
12
  const ctx = c.get('cogitator');
10
13
  const agentList = Object.entries(ctx.agents).map(([name, agent]) => ({
11
14
  name,
12
- description: agent.config.instructions?.slice(0, 100),
13
- tools: agent.config.tools?.map((t) => t.name) || [],
15
+ description: agent.config.description,
16
+ tools: agent.config.tools?.map((t) => t.name) ?? [],
14
17
  }));
15
18
  const response = { agents: agentList };
16
19
  return c.json(response);
@@ -18,25 +21,21 @@ export function createAgentRoutes() {
18
21
  app.post('/agents/:name/run', async (c) => {
19
22
  const ctx = c.get('cogitator');
20
23
  const name = c.req.param('name');
21
- const agent = Object.hasOwn(ctx.agents, name) ? ctx.agents[name] : undefined;
24
+ const agent = getOwn(ctx.agents, name);
22
25
  if (!agent) {
23
26
  return c.json({ error: { message: `Agent '${name}' not found`, code: 'NOT_FOUND' } }, 404);
24
27
  }
25
- let body;
26
- try {
27
- body = await c.req.json();
28
- }
29
- catch {
30
- return c.json({ error: { message: 'Invalid JSON body', code: 'INVALID_INPUT' } }, 400);
31
- }
32
- if (!body?.input) {
33
- return c.json({ error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } }, 400);
34
- }
28
+ const body = await readJsonBody(c);
29
+ if (!body.ok)
30
+ return invalidJson(c);
31
+ const parsed = parseAgentRunRequest(body.value);
32
+ if (!parsed.ok)
33
+ return invalidInput(c, parsed.message);
34
+ const abortController = createRequestAbortController(c);
35
35
  try {
36
36
  const result = await ctx.runtime.run(agent, {
37
- input: body.input,
38
- context: body.context,
39
- threadId: body.threadId,
37
+ ...parsed.value,
38
+ signal: abortController.signal,
40
39
  });
41
40
  const response = {
42
41
  output: result.output,
@@ -51,57 +50,50 @@ export function createAgentRoutes() {
51
50
  return c.json(response);
52
51
  }
53
52
  catch (error) {
54
- if (CogitatorError.isCogitatorError(error)) {
55
- return c.json({ error: { message: error.message, code: error.code } }, 500);
56
- }
57
- console.error('[CogitatorHono] Agent run error:', error);
58
- return c.json({ error: { message: 'Internal server error', code: 'INTERNAL' } }, 500);
53
+ if (abortController.signal.aborted)
54
+ return requestAborted(c);
55
+ return errorResponse(c, error, 'Agent run error');
59
56
  }
60
57
  });
61
58
  app.post('/agents/:name/stream', async (c) => {
62
59
  const ctx = c.get('cogitator');
63
60
  const name = c.req.param('name');
64
- const agent = Object.hasOwn(ctx.agents, name) ? ctx.agents[name] : undefined;
61
+ const agent = getOwn(ctx.agents, name);
65
62
  if (!agent) {
66
63
  return c.json({ error: { message: `Agent '${name}' not found`, code: 'NOT_FOUND' } }, 404);
67
64
  }
68
- let body;
69
- try {
70
- body = await c.req.json();
71
- }
72
- catch {
73
- return c.json({ error: { message: 'Invalid JSON body', code: 'INVALID_INPUT' } }, 400);
74
- }
75
- if (!body?.input) {
76
- return c.json({ error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } }, 400);
77
- }
65
+ const body = await readJsonBody(c);
66
+ if (!body.ok)
67
+ return invalidJson(c);
68
+ const parsed = parseAgentRunRequest(body.value);
69
+ if (!parsed.ok)
70
+ return invalidInput(c, parsed.message);
71
+ const abortController = createRequestAbortController(c);
78
72
  return streamSSE(c, async (stream) => {
79
73
  const writer = new HonoStreamWriter(stream);
80
74
  const messageId = generateId('msg');
81
- stream.onAbort(() => writer.close());
82
- let textStarted = false;
83
- let textId = '';
75
+ const textId = generateId('txt');
76
+ stream.onAbort(() => {
77
+ writer.close();
78
+ abortController.abort();
79
+ });
84
80
  try {
85
81
  await writer.start(messageId);
86
- textId = generateId('txt');
87
- textStarted = true;
88
82
  await writer.textStart(textId);
89
83
  const result = await ctx.runtime.run(agent, {
90
- input: body.input,
91
- context: body.context,
92
- threadId: body.threadId,
84
+ ...parsed.value,
93
85
  stream: true,
86
+ signal: abortController.signal,
94
87
  onToken: (token) => {
95
88
  void writer.textDelta(textId, token);
96
89
  },
97
90
  onToolCall: (toolCall) => {
98
- const toolId = generateId('tool');
99
- void writer.toolCallStart(toolId, toolCall.name);
100
- void writer.toolCallEnd(toolId);
91
+ void writer.toolCallStart(toolCall.id, toolCall.name);
92
+ void writer.toolCallDelta(toolCall.id, JSON.stringify(toolCall.arguments));
93
+ void writer.toolCallEnd(toolCall.id);
101
94
  },
102
95
  onToolResult: (toolResult) => {
103
- const resultId = generateId('res');
104
- void writer.toolResult(resultId, toolResult.callId, toolResult.result);
96
+ void writer.toolResult(generateId('res'), toolResult.callId, toolResult.result);
105
97
  },
106
98
  });
107
99
  await writer.textEnd(textId);
@@ -112,16 +104,11 @@ export function createAgentRoutes() {
112
104
  });
113
105
  }
114
106
  catch (error) {
115
- if (textStarted) {
116
- await writer.textEnd(textId);
117
- }
118
- if (CogitatorError.isCogitatorError(error)) {
119
- await writer.error(error.message, error.code);
120
- }
121
- else {
122
- console.error('[CogitatorHono] Agent stream error:', error);
123
- await writer.error('Internal server error', 'INTERNAL');
124
- }
107
+ if (abortController.signal.aborted)
108
+ return;
109
+ await writer.textEnd(textId);
110
+ const { body: errorBody } = resolveError(error, 'Agent stream error');
111
+ await writer.error(errorBody.error.message, errorBody.error.code);
125
112
  }
126
113
  finally {
127
114
  writer.close();
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":"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"}
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,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EACV,OAAO,EAKR,MAAM,aAAa,CAAC;AAQrB,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,CAwMjD"}
1
+ {"version":3,"file":"swarms.d.ts","sourceRoot":"","sources":["../../src/routes/swarms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,aAAa,CAAC;AAelF,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,CA+JjD"}
@@ -2,7 +2,11 @@ import { Hono } from 'hono';
2
2
  import { streamSSE } from 'hono/streaming';
3
3
  import { generateId } from '@cogitator-ai/server-shared';
4
4
  import { HonoStreamWriter } from '../streaming/hono-stream-writer.js';
5
- import { CogitatorError, } from '@cogitator-ai/types';
5
+ import { getOwn } from '../utils/lookup.js';
6
+ import { isModuleNotFoundError, resolveError } from '../utils/errors.js';
7
+ import { createRequestAbortController, errorResponse, invalidInput, invalidJson, readJsonBody, requestAborted, } from '../utils/request.js';
8
+ import { serializeSwarmUsage, toSwarmRunResponse } from '../utils/results.js';
9
+ import { parseSwarmRunRequest } from '../utils/validation.js';
6
10
  export function createSwarmRoutes() {
7
11
  const app = new Hono();
8
12
  app.get('/swarms', (c) => {
@@ -25,92 +29,67 @@ export function createSwarmRoutes() {
25
29
  app.post('/swarms/:name/run', async (c) => {
26
30
  const ctx = c.get('cogitator');
27
31
  const name = c.req.param('name');
28
- const swarmConfig = Object.hasOwn(ctx.swarms, name) ? ctx.swarms[name] : undefined;
32
+ const swarmConfig = getOwn(ctx.swarms, name);
29
33
  if (!swarmConfig) {
30
34
  return c.json({ error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } }, 404);
31
35
  }
32
- let body;
33
- try {
34
- body = await c.req.json();
35
- }
36
- catch {
37
- return c.json({ error: { message: 'Invalid JSON body', code: 'INVALID_INPUT' } }, 400);
38
- }
39
- if (!body?.input) {
40
- return c.json({ error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } }, 400);
41
- }
36
+ const body = await readJsonBody(c);
37
+ if (!body.ok)
38
+ return invalidJson(c);
39
+ const parsed = parseSwarmRunRequest(body.value);
40
+ if (!parsed.ok)
41
+ return invalidInput(c, parsed.message);
42
+ const abortController = createRequestAbortController(c);
42
43
  try {
43
44
  const { Swarm } = await import('@cogitator-ai/swarms');
44
45
  const swarm = new Swarm(ctx.runtime, swarmConfig);
45
- const result = await swarm.run({
46
- input: body.input,
47
- context: body.context,
48
- threadId: body.threadId,
49
- timeout: body.timeout,
50
- });
51
- const agentResults = {};
52
- for (const [agentName, agentResult] of result.agentResults.entries()) {
53
- agentResults[agentName] = {
54
- output: agentResult.output,
55
- usage: agentResult.usage,
56
- };
57
- }
58
- const resourceUsage = swarm.getResourceUsage();
59
- const response = {
60
- swarmId: swarm.id,
61
- swarmName: swarm.name,
62
- strategy: swarm.strategyType,
63
- output: result.output,
64
- agentResults,
65
- usage: {
66
- totalTokens: resourceUsage.totalTokens,
67
- totalCost: resourceUsage.totalCost,
68
- elapsedTime: resourceUsage.elapsedTime,
69
- },
70
- };
71
- return c.json(response);
46
+ if (abortController.signal.aborted)
47
+ return requestAborted(c);
48
+ abortController.signal.addEventListener('abort', () => swarm.abort(), { once: true });
49
+ const result = await swarm.run(parsed.value);
50
+ if (abortController.signal.aborted)
51
+ return requestAborted(c);
52
+ return c.json(toSwarmRunResponse(swarm, result));
72
53
  }
73
54
  catch (error) {
74
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
55
+ if (abortController.signal.aborted)
56
+ return requestAborted(c);
57
+ if (isModuleNotFoundError(error)) {
75
58
  return c.json({ error: { message: 'Swarms package not installed', code: 'UNIMPLEMENTED' } }, 501);
76
59
  }
77
- if (CogitatorError.isCogitatorError(error)) {
78
- return c.json({ error: { message: error.message, code: error.code } }, 500);
79
- }
80
- console.error('[CogitatorHono] Swarm run error:', error);
81
- return c.json({ error: { message: 'Internal server error', code: 'INTERNAL' } }, 500);
60
+ return errorResponse(c, error, 'Swarm run error');
82
61
  }
83
62
  });
84
63
  app.post('/swarms/:name/stream', async (c) => {
85
64
  const ctx = c.get('cogitator');
86
65
  const name = c.req.param('name');
87
- const swarmConfig = Object.hasOwn(ctx.swarms, name) ? ctx.swarms[name] : undefined;
66
+ const swarmConfig = getOwn(ctx.swarms, name);
88
67
  if (!swarmConfig) {
89
68
  return c.json({ error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } }, 404);
90
69
  }
91
- let body;
92
- try {
93
- body = await c.req.json();
94
- }
95
- catch {
96
- return c.json({ error: { message: 'Invalid JSON body', code: 'INVALID_INPUT' } }, 400);
97
- }
98
- if (!body?.input) {
99
- return c.json({ error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } }, 400);
100
- }
70
+ const body = await readJsonBody(c);
71
+ if (!body.ok)
72
+ return invalidJson(c);
73
+ const parsed = parseSwarmRunRequest(body.value);
74
+ if (!parsed.ok)
75
+ return invalidInput(c, parsed.message);
76
+ const abortController = createRequestAbortController(c);
101
77
  return streamSSE(c, async (stream) => {
102
78
  const writer = new HonoStreamWriter(stream);
103
79
  const messageId = generateId('swarm');
104
- stream.onAbort(() => writer.close());
80
+ stream.onAbort(() => {
81
+ writer.close();
82
+ abortController.abort();
83
+ });
105
84
  try {
106
85
  const { Swarm } = await import('@cogitator-ai/swarms');
107
86
  const swarm = new Swarm(ctx.runtime, swarmConfig);
87
+ if (abortController.signal.aborted)
88
+ return;
89
+ abortController.signal.addEventListener('abort', () => swarm.abort(), { once: true });
108
90
  await writer.start(messageId);
109
91
  const result = await swarm.run({
110
- input: body.input,
111
- context: body.context,
112
- threadId: body.threadId,
113
- timeout: body.timeout,
92
+ ...parsed.value,
114
93
  onAgentStart: (agentName) => {
115
94
  void writer.swarmEvent('agent_start', { agentName, timestamp: Date.now() });
116
95
  },
@@ -131,24 +110,24 @@ export function createSwarmRoutes() {
131
110
  void writer.swarmEvent(event.type, event.data);
132
111
  },
133
112
  });
134
- const resourceUsage = swarm.getResourceUsage();
113
+ if (abortController.signal.aborted)
114
+ return;
135
115
  await writer.swarmEvent('swarm_completed', {
136
116
  swarmId: swarm.id,
137
117
  output: result.output,
138
- usage: resourceUsage,
118
+ usage: serializeSwarmUsage(swarm.getResourceUsage()),
139
119
  });
140
120
  await writer.finish(messageId);
141
121
  }
142
122
  catch (error) {
143
- if (error.code === 'ERR_MODULE_NOT_FOUND') {
123
+ if (abortController.signal.aborted)
124
+ return;
125
+ if (isModuleNotFoundError(error)) {
144
126
  await writer.error('Swarms package not installed', 'UNIMPLEMENTED');
145
127
  }
146
- else if (CogitatorError.isCogitatorError(error)) {
147
- await writer.error(error.message, error.code);
148
- }
149
128
  else {
150
- console.error('[CogitatorHono] Swarm stream error:', error);
151
- await writer.error('Internal server error', 'INTERNAL');
129
+ const { body: errorBody } = resolveError(error, 'Swarm stream error');
130
+ await writer.error(errorBody.error.message, errorBody.error.code);
152
131
  }
153
132
  }
154
133
  finally {
@@ -159,7 +138,7 @@ export function createSwarmRoutes() {
159
138
  app.get('/swarms/:name/blackboard', (c) => {
160
139
  const ctx = c.get('cogitator');
161
140
  const name = c.req.param('name');
162
- const swarmConfig = Object.hasOwn(ctx.swarms, name) ? ctx.swarms[name] : undefined;
141
+ const swarmConfig = getOwn(ctx.swarms, name);
163
142
  if (!swarmConfig) {
164
143
  return c.json({ error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } }, 404);
165
144
  }
@@ -167,7 +146,7 @@ export function createSwarmRoutes() {
167
146
  return c.json({ error: { message: 'Blackboard not enabled for this swarm', code: 'INVALID_INPUT' } }, 400);
168
147
  }
169
148
  const response = {
170
- sections: swarmConfig.blackboard.sections || {},
149
+ sections: swarmConfig.blackboard.sections ?? {},
171
150
  };
172
151
  return c.json(response);
173
152
  });