@cogitator-ai/koa 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 +49 -25
  2. package/dist/app.d.ts.map +1 -1
  3. package/dist/app.js +1 -4
  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.map +1 -1
  8. package/dist/middleware/auth.d.ts.map +1 -1
  9. package/dist/middleware/auth.js +8 -11
  10. package/dist/middleware/auth.js.map +1 -1
  11. package/dist/middleware/body-parser.d.ts +5 -1
  12. package/dist/middleware/body-parser.d.ts.map +1 -1
  13. package/dist/middleware/body-parser.js +70 -25
  14. package/dist/middleware/body-parser.js.map +1 -1
  15. package/dist/middleware/error-handler.js +1 -1
  16. package/dist/middleware/error-handler.js.map +1 -1
  17. package/dist/routes/agents.d.ts.map +1 -1
  18. package/dist/routes/agents.js +38 -34
  19. package/dist/routes/agents.js.map +1 -1
  20. package/dist/routes/swarms.d.ts.map +1 -1
  21. package/dist/routes/swarms.js +49 -53
  22. package/dist/routes/swarms.js.map +1 -1
  23. package/dist/routes/threads.d.ts.map +1 -1
  24. package/dist/routes/threads.js +33 -37
  25. package/dist/routes/threads.js.map +1 -1
  26. package/dist/routes/tools.d.ts.map +1 -1
  27. package/dist/routes/tools.js +11 -17
  28. package/dist/routes/tools.js.map +1 -1
  29. package/dist/routes/workflows.d.ts.map +1 -1
  30. package/dist/routes/workflows.js +55 -28
  31. package/dist/routes/workflows.js.map +1 -1
  32. package/dist/types.d.ts +11 -2
  33. package/dist/types.d.ts.map +1 -1
  34. package/dist/utils/errors.d.ts +8 -0
  35. package/dist/utils/errors.d.ts.map +1 -0
  36. package/dist/utils/errors.js +21 -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 +4 -0
  43. package/dist/utils/request.d.ts.map +1 -0
  44. package/dist/utils/request.js +11 -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 +1 -1
  55. package/dist/websocket/handler.d.ts.map +1 -1
  56. package/dist/websocket/handler.js +260 -151
  57. package/dist/websocket/handler.js.map +1 -1
  58. package/package.json +10 -9
@@ -1,10 +1,11 @@
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
- function isModuleNotFoundError(error) {
5
- const code = error.code;
6
- return code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND';
7
- }
4
+ import { getOwn } from '../utils/lookup.js';
5
+ import { isModuleNotFoundError, resolveError } from '../utils/errors.js';
6
+ import { getRequestBody, onClientDisconnect } from '../utils/request.js';
7
+ import { serializeSwarmUsage, toSwarmRunResponse } from '../utils/results.js';
8
+ import { parseSwarmRunRequest } from '../utils/validation.js';
8
9
  export function createSwarmRoutes() {
9
10
  const router = new Router();
10
11
  router.get('/swarms', (ctx) => {
@@ -31,90 +32,82 @@ export function createSwarmRoutes() {
31
32
  router.post('/swarms/:name/run', async (ctx) => {
32
33
  const { swarms, runtime } = ctx.state.cogitator;
33
34
  const { name } = ctx.params;
34
- const swarmConfig = swarms[name];
35
+ const swarmConfig = getOwn(swarms, name);
35
36
  if (!swarmConfig) {
36
37
  ctx.status = 404;
37
38
  ctx.body = { error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } };
38
39
  return;
39
40
  }
40
- const body = ctx.request.body;
41
- if (!body?.input) {
41
+ const parsed = parseSwarmRunRequest(getRequestBody(ctx));
42
+ if (!parsed.ok) {
42
43
  ctx.status = 400;
43
- ctx.body = { error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } };
44
+ ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
44
45
  return;
45
46
  }
47
+ let aborted = false;
48
+ let abortSwarm;
49
+ onClientDisconnect(ctx, () => {
50
+ aborted = true;
51
+ abortSwarm?.();
52
+ });
46
53
  try {
47
54
  const { Swarm } = await import('@cogitator-ai/swarms');
48
55
  const swarm = new Swarm(runtime, swarmConfig);
49
- const result = await swarm.run({
50
- input: body.input,
51
- context: body.context,
52
- threadId: body.threadId,
53
- timeout: body.timeout,
54
- });
55
- const agentResults = {};
56
- for (const [agentName, agentResult] of result.agentResults.entries()) {
57
- agentResults[agentName] = {
58
- output: agentResult.output,
59
- usage: agentResult.usage,
60
- };
61
- }
62
- const resourceUsage = swarm.getResourceUsage();
63
- const response = {
64
- swarmId: swarm.id,
65
- swarmName: swarm.name,
66
- strategy: swarm.strategyType,
67
- output: result.output,
68
- agentResults,
69
- usage: {
70
- totalTokens: resourceUsage.totalTokens,
71
- totalCost: resourceUsage.totalCost,
72
- elapsedTime: resourceUsage.elapsedTime,
73
- },
74
- };
75
- ctx.body = response;
56
+ abortSwarm = () => swarm.abort();
57
+ if (aborted)
58
+ return;
59
+ const result = await swarm.run(parsed.value);
60
+ if (aborted)
61
+ return;
62
+ ctx.body = toSwarmRunResponse(swarm, result);
76
63
  }
77
64
  catch (error) {
65
+ if (aborted)
66
+ return;
78
67
  if (isModuleNotFoundError(error)) {
79
68
  ctx.status = 501;
80
69
  ctx.body = { error: { message: 'Swarms package not installed', code: 'UNIMPLEMENTED' } };
81
70
  return;
82
71
  }
83
- const message = error instanceof Error ? error.message : 'Unknown error';
84
- ctx.status = 500;
85
- ctx.body = { error: { message, code: 'INTERNAL' } };
72
+ const { status, body } = resolveError(error, 'Swarm run error');
73
+ ctx.status = status;
74
+ ctx.body = body;
86
75
  }
87
76
  });
88
77
  router.post('/swarms/:name/stream', async (ctx) => {
89
78
  const { swarms, runtime } = ctx.state.cogitator;
90
79
  const { name } = ctx.params;
91
- const swarmConfig = swarms[name];
80
+ const swarmConfig = getOwn(swarms, name);
92
81
  if (!swarmConfig) {
93
82
  ctx.status = 404;
94
83
  ctx.body = { error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } };
95
84
  return;
96
85
  }
97
- const body = ctx.request.body;
98
- if (!body?.input) {
86
+ const parsed = parseSwarmRunRequest(getRequestBody(ctx));
87
+ if (!parsed.ok) {
99
88
  ctx.status = 400;
100
- ctx.body = { error: { message: 'Missing required field: input', code: 'INVALID_INPUT' } };
89
+ ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
101
90
  return;
102
91
  }
103
92
  setupSSEHeaders(ctx);
104
93
  const writer = new KoaStreamWriter(ctx);
105
94
  const messageId = generateId('swarm');
106
- ctx.req.on('close', () => {
95
+ let aborted = false;
96
+ let abortSwarm;
97
+ onClientDisconnect(ctx, () => {
98
+ aborted = true;
107
99
  writer.close();
100
+ abortSwarm?.();
108
101
  });
109
102
  try {
110
103
  const { Swarm } = await import('@cogitator-ai/swarms');
111
104
  const swarm = new Swarm(runtime, swarmConfig);
105
+ abortSwarm = () => swarm.abort();
106
+ if (aborted)
107
+ return;
112
108
  writer.start(messageId);
113
109
  const result = await swarm.run({
114
- input: body.input,
115
- context: body.context,
116
- threadId: body.threadId,
117
- timeout: body.timeout,
110
+ ...parsed.value,
118
111
  onAgentStart: (agentName) => {
119
112
  writer.swarmEvent('agent_start', { agentName, timestamp: Date.now() });
120
113
  },
@@ -135,21 +128,24 @@ export function createSwarmRoutes() {
135
128
  writer.swarmEvent(event.type, event.data);
136
129
  },
137
130
  });
138
- const resourceUsage = swarm.getResourceUsage();
131
+ if (aborted)
132
+ return;
139
133
  writer.swarmEvent('swarm_completed', {
140
134
  swarmId: swarm.id,
141
135
  output: result.output,
142
- usage: resourceUsage,
136
+ usage: serializeSwarmUsage(swarm.getResourceUsage()),
143
137
  });
144
138
  writer.finish(messageId);
145
139
  }
146
140
  catch (error) {
141
+ if (aborted)
142
+ return;
147
143
  if (isModuleNotFoundError(error)) {
148
144
  writer.error('Swarms package not installed', 'UNIMPLEMENTED');
149
145
  }
150
146
  else {
151
- const message = error instanceof Error ? error.message : 'Unknown error';
152
- writer.error(message, 'INTERNAL');
147
+ const { body } = resolveError(error, 'Swarm stream error');
148
+ writer.error(body.error.message, body.error.code);
153
149
  }
154
150
  }
155
151
  finally {
@@ -159,7 +155,7 @@ export function createSwarmRoutes() {
159
155
  router.get('/swarms/:name/blackboard', (ctx) => {
160
156
  const { swarms } = ctx.state.cogitator;
161
157
  const { name } = ctx.params;
162
- const swarmConfig = swarms[name];
158
+ const swarmConfig = getOwn(swarms, name);
163
159
  if (!swarmConfig) {
164
160
  ctx.status = 404;
165
161
  ctx.body = { error: { message: `Swarm '${name}' not found`, code: 'NOT_FOUND' } };
@@ -173,7 +169,7 @@ export function createSwarmRoutes() {
173
169
  return;
174
170
  }
175
171
  const response = {
176
- sections: swarmConfig.blackboard.sections || {},
172
+ sections: swarmConfig.blackboard.sections ?? {},
177
173
  };
178
174
  ctx.body = response;
179
175
  });
@@ -1 +1 @@
1
- {"version":3,"file":"swarms.js","sourceRoot":"","sources":["../../src/routes/swarms.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"swarms.js","sourceRoot":"","sources":["../../src/routes/swarms.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../src/routes/threads.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAqC,MAAM,aAAa,CAAC;AAErF,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,cAAc,CAAC,CA+G3D"}
1
+ {"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../src/routes/threads.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,aAAa,CAAC;AAkBlE,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,cAAc,CAAC,CA4F3D"}
@@ -1,99 +1,95 @@
1
1
  import Router from '@koa/router';
2
+ import { countMessageTokens } from '@cogitator-ai/memory';
3
+ import { resolveError } from '../utils/errors.js';
4
+ import { getRequestBody } from '../utils/request.js';
5
+ import { parseAddMessageRequest } from '../utils/validation.js';
6
+ function respondWithError(ctx, error, label) {
7
+ const { status, body } = resolveError(error, label);
8
+ ctx.status = status;
9
+ ctx.body = body;
10
+ }
11
+ function respondMemoryUnavailable(ctx) {
12
+ ctx.status = 503;
13
+ ctx.body = { error: { message: 'Memory not configured', code: 'UNAVAILABLE' } };
14
+ }
2
15
  export function createThreadRoutes() {
3
16
  const router = new Router();
4
17
  router.get('/threads/:id', async (ctx) => {
5
18
  const memory = ctx.state.cogitator.runtime.memory;
6
19
  if (!memory) {
7
- ctx.status = 503;
8
- ctx.body = { error: { message: 'Memory not configured', code: 'UNAVAILABLE' } };
20
+ respondMemoryUnavailable(ctx);
9
21
  return;
10
22
  }
11
23
  const { id } = ctx.params;
12
24
  try {
13
25
  const result = await memory.getEntries({ threadId: id });
14
26
  if (!result.success) {
15
- ctx.status = 500;
16
- ctx.body = { error: { message: result.error, code: 'INTERNAL' } };
27
+ respondWithError(ctx, new Error(result.error), 'Thread get error');
17
28
  return;
18
29
  }
19
30
  const entries = result.data;
20
- const messages = entries.map((entry) => entry.message);
21
- const createdAt = entries.length > 0 ? entries[0].createdAt.getTime() : Date.now();
22
- const updatedAt = entries.length > 0 ? entries[entries.length - 1].createdAt.getTime() : Date.now();
31
+ const now = Date.now();
23
32
  const response = {
24
33
  id,
25
- messages,
26
- createdAt,
27
- updatedAt,
34
+ messages: entries.map((entry) => entry.message),
35
+ createdAt: entries.length > 0 ? entries[0].createdAt.getTime() : now,
36
+ updatedAt: entries.length > 0 ? entries[entries.length - 1].createdAt.getTime() : now,
28
37
  };
29
38
  ctx.body = response;
30
39
  }
31
40
  catch (error) {
32
- const message = error instanceof Error ? error.message : 'Unknown error';
33
- ctx.status = 500;
34
- ctx.body = { error: { message, code: 'INTERNAL' } };
41
+ respondWithError(ctx, error, 'Thread get error');
35
42
  }
36
43
  });
37
44
  router.post('/threads/:id/messages', async (ctx) => {
38
45
  const memory = ctx.state.cogitator.runtime.memory;
39
46
  if (!memory) {
40
- ctx.status = 503;
41
- ctx.body = { error: { message: 'Memory not configured', code: 'UNAVAILABLE' } };
47
+ respondMemoryUnavailable(ctx);
42
48
  return;
43
49
  }
44
50
  const { id } = ctx.params;
45
- const body = ctx.request.body;
46
- if (!body?.role || !body?.content) {
51
+ const parsed = parseAddMessageRequest(getRequestBody(ctx));
52
+ if (!parsed.ok) {
47
53
  ctx.status = 400;
48
- ctx.body = {
49
- error: { message: 'Missing required fields: role, content', code: 'INVALID_INPUT' },
50
- };
54
+ ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
51
55
  return;
52
56
  }
57
+ const message = { role: parsed.value.role, content: parsed.value.content };
53
58
  try {
54
59
  const result = await memory.addEntry({
55
60
  threadId: id,
56
- message: {
57
- role: body.role,
58
- content: body.content,
59
- },
60
- tokenCount: 0,
61
+ message,
62
+ tokenCount: countMessageTokens(message),
63
+ ...(parsed.value.metadata && { metadata: parsed.value.metadata }),
61
64
  });
62
65
  if (!result.success) {
63
- ctx.status = 500;
64
- ctx.body = { error: { message: result.error, code: 'INTERNAL' } };
66
+ respondWithError(ctx, new Error(result.error), 'Thread add message error');
65
67
  return;
66
68
  }
67
69
  ctx.status = 201;
68
70
  ctx.body = { success: true };
69
71
  }
70
72
  catch (error) {
71
- const message = error instanceof Error ? error.message : 'Unknown error';
72
- ctx.status = 500;
73
- ctx.body = { error: { message, code: 'INTERNAL' } };
73
+ respondWithError(ctx, error, 'Thread add message error');
74
74
  }
75
75
  });
76
76
  router.delete('/threads/:id', async (ctx) => {
77
77
  const memory = ctx.state.cogitator.runtime.memory;
78
78
  if (!memory) {
79
- ctx.status = 503;
80
- ctx.body = { error: { message: 'Memory not configured', code: 'UNAVAILABLE' } };
79
+ respondMemoryUnavailable(ctx);
81
80
  return;
82
81
  }
83
82
  const { id } = ctx.params;
84
83
  try {
85
84
  const result = await memory.clearThread(id);
86
85
  if (!result.success) {
87
- ctx.status = 500;
88
- ctx.body = { error: { message: result.error, code: 'INTERNAL' } };
86
+ respondWithError(ctx, new Error(result.error), 'Thread delete error');
89
87
  return;
90
88
  }
91
89
  ctx.status = 204;
92
90
  }
93
91
  catch (error) {
94
- const message = error instanceof Error ? error.message : 'Unknown error';
95
- ctx.status = 500;
96
- ctx.body = { error: { message, code: 'INTERNAL' } };
92
+ respondWithError(ctx, error, 'Thread delete error');
97
93
  }
98
94
  });
99
95
  return router;
@@ -1 +1 @@
1
- {"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/routes/threads.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/routes/threads.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/routes/tools.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAEpE,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,cAAc,CAAC,CAgCzD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/routes/tools.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,aAAa,CAAC;AAEpE,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,cAAc,CAAC,CAwBzD"}
@@ -3,26 +3,20 @@ export function createToolRoutes() {
3
3
  const router = new Router();
4
4
  router.get('/tools', (ctx) => {
5
5
  const { agents } = ctx.state.cogitator;
6
- const toolsSet = new Map();
6
+ const tools = new Map();
7
7
  for (const agent of Object.values(agents)) {
8
- const tools = agent.config.tools || [];
9
- for (const tool of tools) {
10
- if (!toolsSet.has(tool.name)) {
11
- toolsSet.set(tool.name, {
12
- name: tool.name,
13
- description: tool.description,
14
- parameters: tool.parameters,
15
- });
16
- }
8
+ for (const tool of agent.config.tools ?? []) {
9
+ if (tools.has(tool.name))
10
+ continue;
11
+ const schema = tool.toJSON();
12
+ tools.set(tool.name, {
13
+ name: schema.name,
14
+ description: schema.description,
15
+ parameters: schema.parameters,
16
+ });
17
17
  }
18
18
  }
19
- const response = {
20
- tools: Array.from(toolsSet.values()).map((t) => ({
21
- name: t.name,
22
- description: t.description,
23
- parameters: t.parameters,
24
- })),
25
- };
19
+ const response = { tools: Array.from(tools.values()) };
26
20
  ctx.body = response;
27
21
  });
28
22
  return router;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/routes/tools.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,IAAI,MAAM,EAAkB,CAAC;IAE5C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuE,CAAC;QAEhG,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;YACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7B,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;wBACtB,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;qBAC5B,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAqB;YACjC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/C,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,UAAU,EAAE,CAAC,CAAC,UAAqC;aACpD,CAAC,CAAC;SACJ,CAAC;QAEF,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/routes/tools.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAGjC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,IAAI,MAAM,EAAkB,CAAC;IAE5C,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6C,CAAC;QAEnE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBAC5C,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;oBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;iBAC9B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAqB,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QACzE,GAAG,CAAC,IAAI,GAAG,QAAQ,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/routes/workflows.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,aAAa,CAAC;AASrB,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,cAAc,CAAC,CA2H7D"}
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/routes/workflows.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AASxE,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,cAAc,CAAC,CAmJ7D"}
@@ -1,10 +1,11 @@
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
- function isModuleNotFoundError(error) {
5
- const code = error.code;
6
- return code === 'MODULE_NOT_FOUND' || code === 'ERR_MODULE_NOT_FOUND';
7
- }
4
+ import { getOwn } from '../utils/lookup.js';
5
+ import { isModuleNotFoundError, resolveError } from '../utils/errors.js';
6
+ import { getRequestBody, onClientDisconnect } from '../utils/request.js';
7
+ import { toWorkflowRunResponse } from '../utils/results.js';
8
+ import { parseWorkflowRunRequest } from '../utils/validation.js';
8
9
  export function createWorkflowRoutes() {
9
10
  const router = new Router();
10
11
  router.get('/workflows', (ctx) => {
@@ -20,63 +21,80 @@ export function createWorkflowRoutes() {
20
21
  router.post('/workflows/:name/run', async (ctx) => {
21
22
  const { workflows, runtime } = ctx.state.cogitator;
22
23
  const { name } = ctx.params;
23
- const workflow = workflows[name];
24
+ const workflow = getOwn(workflows, name);
24
25
  if (!workflow) {
25
26
  ctx.status = 404;
26
27
  ctx.body = { error: { message: `Workflow '${name}' not found`, code: 'NOT_FOUND' } };
27
28
  return;
28
29
  }
29
- const body = ctx.request.body;
30
+ const parsed = parseWorkflowRunRequest(getRequestBody(ctx));
31
+ if (!parsed.ok) {
32
+ ctx.status = 400;
33
+ ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
34
+ return;
35
+ }
36
+ const abortController = new AbortController();
37
+ onClientDisconnect(ctx, () => abortController.abort());
30
38
  try {
31
39
  const { WorkflowExecutor } = await import('@cogitator-ai/workflows');
32
40
  const executor = new WorkflowExecutor(runtime);
33
- const result = await executor.execute(workflow, body?.input, body?.options);
34
- const nodeResults = {};
35
- for (const [nodeName, nodeResult] of result.nodeResults.entries()) {
36
- nodeResults[nodeName] = nodeResult;
41
+ const result = await executor.execute(workflow, parsed.value.input, {
42
+ ...parsed.value.options,
43
+ signal: abortController.signal,
44
+ });
45
+ if (abortController.signal.aborted)
46
+ return;
47
+ if (result.error) {
48
+ const { status, body } = resolveError(result.error, 'Workflow run error');
49
+ ctx.status = status;
50
+ ctx.body = body;
51
+ return;
37
52
  }
38
- const response = {
39
- workflowId: result.workflowId,
40
- workflowName: result.workflowName,
41
- state: result.state,
42
- duration: result.duration,
43
- nodeResults,
44
- };
45
- ctx.body = response;
53
+ ctx.body = toWorkflowRunResponse(result);
46
54
  }
47
55
  catch (error) {
56
+ if (abortController.signal.aborted)
57
+ return;
48
58
  if (isModuleNotFoundError(error)) {
49
59
  ctx.status = 501;
50
60
  ctx.body = { error: { message: 'Workflows package not installed', code: 'UNIMPLEMENTED' } };
51
61
  return;
52
62
  }
53
- const message = error instanceof Error ? error.message : 'Unknown error';
54
- ctx.status = 500;
55
- ctx.body = { error: { message, code: 'INTERNAL' } };
63
+ const { status, body } = resolveError(error, 'Workflow run error');
64
+ ctx.status = status;
65
+ ctx.body = body;
56
66
  }
57
67
  });
58
68
  router.post('/workflows/:name/stream', async (ctx) => {
59
69
  const { workflows, runtime } = ctx.state.cogitator;
60
70
  const { name } = ctx.params;
61
- const workflow = workflows[name];
71
+ const workflow = getOwn(workflows, name);
62
72
  if (!workflow) {
63
73
  ctx.status = 404;
64
74
  ctx.body = { error: { message: `Workflow '${name}' not found`, code: 'NOT_FOUND' } };
65
75
  return;
66
76
  }
67
- const body = ctx.request.body;
77
+ const parsed = parseWorkflowRunRequest(getRequestBody(ctx));
78
+ if (!parsed.ok) {
79
+ ctx.status = 400;
80
+ ctx.body = { error: { message: parsed.message, code: 'INVALID_INPUT' } };
81
+ return;
82
+ }
68
83
  setupSSEHeaders(ctx);
69
84
  const writer = new KoaStreamWriter(ctx);
70
85
  const messageId = generateId('wf');
71
- ctx.req.on('close', () => {
86
+ const abortController = new AbortController();
87
+ onClientDisconnect(ctx, () => {
72
88
  writer.close();
89
+ abortController.abort();
73
90
  });
74
91
  try {
75
92
  const { WorkflowExecutor } = await import('@cogitator-ai/workflows');
76
93
  const executor = new WorkflowExecutor(runtime);
77
94
  writer.start(messageId);
78
- const result = await executor.execute(workflow, body?.input, {
79
- ...body?.options,
95
+ const result = await executor.execute(workflow, parsed.value.input, {
96
+ ...parsed.value.options,
97
+ signal: abortController.signal,
80
98
  onNodeStart: (node) => {
81
99
  writer.workflowEvent('node_started', { nodeName: node, timestamp: Date.now() });
82
100
  },
@@ -90,6 +108,13 @@ export function createWorkflowRoutes() {
90
108
  writer.workflowEvent('node_progress', { nodeName: node, progress });
91
109
  },
92
110
  });
111
+ if (abortController.signal.aborted)
112
+ return;
113
+ if (result.error) {
114
+ const { body } = resolveError(result.error, 'Workflow stream error');
115
+ writer.error(body.error.message, body.error.code);
116
+ return;
117
+ }
93
118
  writer.workflowEvent('workflow_completed', {
94
119
  workflowId: result.workflowId,
95
120
  duration: result.duration,
@@ -97,12 +122,14 @@ export function createWorkflowRoutes() {
97
122
  writer.finish(messageId);
98
123
  }
99
124
  catch (error) {
125
+ if (abortController.signal.aborted)
126
+ return;
100
127
  if (isModuleNotFoundError(error)) {
101
128
  writer.error('Workflows package not installed', 'UNIMPLEMENTED');
102
129
  }
103
130
  else {
104
- const message = error instanceof Error ? error.message : 'Unknown error';
105
- writer.error(message, 'INTERNAL');
131
+ const { body } = resolveError(error, 'Workflow stream error');
132
+ writer.error(body.error.message, body.error.code);
106
133
  }
107
134
  }
108
135
  finally {