@desplega.ai/agent-swarm 1.52.1 → 1.53.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.
Files changed (43) hide show
  1. package/openapi.json +1517 -488
  2. package/package.json +5 -2
  3. package/src/be/db.ts +530 -0
  4. package/src/be/events.ts +322 -0
  5. package/src/be/migrations/021_events.sql +24 -0
  6. package/src/be/migrations/022_context_usage.sql +34 -0
  7. package/src/be/migrations/023_mcp_servers.sql +44 -0
  8. package/src/commands/runner.ts +348 -1
  9. package/src/http/context.ts +118 -0
  10. package/src/http/events.ts +188 -0
  11. package/src/http/index.ts +6 -0
  12. package/src/http/mcp-servers.ts +364 -0
  13. package/src/http/tasks.ts +33 -0
  14. package/src/linear/outbound.ts +8 -1
  15. package/src/linear/sync.ts +3 -0
  16. package/src/oauth/ensure-token.ts +50 -0
  17. package/src/prompts/base-prompt.ts +7 -0
  18. package/src/providers/claude-adapter.ts +156 -15
  19. package/src/providers/pi-mono-adapter.ts +68 -0
  20. package/src/providers/pi-mono-extension.ts +56 -2
  21. package/src/providers/pi-mono-mcp-client.ts +10 -1
  22. package/src/providers/types.ts +14 -1
  23. package/src/server.ts +19 -0
  24. package/src/tests/context-window.test.ts +66 -0
  25. package/src/tests/ensure-token.test.ts +170 -0
  26. package/src/tests/events-db.test.ts +314 -0
  27. package/src/tests/events-http.test.ts +267 -0
  28. package/src/tests/prompt-template-remaining.test.ts +5 -5
  29. package/src/tests/tool-annotations.test.ts +2 -2
  30. package/src/tests/vcs-tracking.test.ts +176 -0
  31. package/src/tests/workflow-executors.test.ts +8 -1
  32. package/src/tools/mcp-servers/index.ts +7 -0
  33. package/src/tools/mcp-servers/mcp-server-create.ts +138 -0
  34. package/src/tools/mcp-servers/mcp-server-delete.ts +72 -0
  35. package/src/tools/mcp-servers/mcp-server-get.ts +80 -0
  36. package/src/tools/mcp-servers/mcp-server-install.ts +110 -0
  37. package/src/tools/mcp-servers/mcp-server-list.ts +67 -0
  38. package/src/tools/mcp-servers/mcp-server-uninstall.ts +71 -0
  39. package/src/tools/mcp-servers/mcp-server-update.ts +120 -0
  40. package/src/tools/tool-config.ts +9 -0
  41. package/src/types.ts +153 -0
  42. package/src/utils/context-window.ts +41 -0
  43. package/src/workflows/executors/base.ts +9 -1
package/src/types.ts CHANGED
@@ -143,6 +143,12 @@ export const AgentTaskSchema = z.object({
143
143
 
144
144
  // Structured output schema (optional — JSON Schema that task output must conform to)
145
145
  outputSchema: z.record(z.string(), z.unknown()).optional(),
146
+
147
+ // Context usage aggregates
148
+ compactionCount: z.number().int().min(0).optional(),
149
+ peakContextPercent: z.number().min(0).max(100).optional(),
150
+ totalContextTokensUsed: z.number().int().min(0).optional(),
151
+ contextWindowSize: z.number().int().min(0).optional(),
146
152
  });
147
153
 
148
154
  export const AgentStatusSchema = z.enum(["idle", "busy", "offline"]);
@@ -363,6 +369,76 @@ export const SessionCostSchema = z.object({
363
369
 
364
370
  export type SessionCost = z.infer<typeof SessionCostSchema>;
365
371
 
372
+ // ============================================================================
373
+ // Events
374
+ // ============================================================================
375
+
376
+ export const EventCategorySchema = z.enum([
377
+ "tool",
378
+ "skill",
379
+ "session",
380
+ "api",
381
+ "task",
382
+ "workflow",
383
+ "system",
384
+ ]);
385
+
386
+ export const EventStatusSchema = z.enum(["ok", "error", "timeout", "skipped"]);
387
+
388
+ export const EventSourceSchema = z.enum(["worker", "api", "hook", "scheduler", "cli"]);
389
+
390
+ export const EventNameSchema = z.enum([
391
+ // Tool events
392
+ "tool.start",
393
+ "tool.end",
394
+ // Skill events
395
+ "skill.invoke",
396
+ "skill.complete",
397
+ // Session events
398
+ "session.start",
399
+ "session.end",
400
+ "session.resume",
401
+ "session.cost",
402
+ // API events
403
+ "api.request",
404
+ "api.error",
405
+ // Task events
406
+ "task.poll",
407
+ "task.assign",
408
+ "task.timeout",
409
+ // Workflow events
410
+ "workflow.step.start",
411
+ "workflow.step.end",
412
+ "workflow.run.start",
413
+ "workflow.run.end",
414
+ // System events
415
+ "system.boot",
416
+ "system.migration",
417
+ "system.error",
418
+ ]);
419
+
420
+ export const SwarmEventSchema = z.object({
421
+ id: z.uuid(),
422
+ category: EventCategorySchema,
423
+ event: EventNameSchema,
424
+ status: EventStatusSchema,
425
+ source: EventSourceSchema,
426
+ agentId: z.string().optional(),
427
+ taskId: z.string().optional(),
428
+ sessionId: z.string().optional(),
429
+ parentEventId: z.string().optional(),
430
+ numericValue: z.number().optional(),
431
+ durationMs: z.number().int().optional(),
432
+ data: z.record(z.string(), z.unknown()).optional(),
433
+ createdAt: z.iso.datetime(),
434
+ });
435
+
436
+ export type EventCategory = z.infer<typeof EventCategorySchema>;
437
+ export type EventStatus = z.infer<typeof EventStatusSchema>;
438
+ export type EventSource = z.infer<typeof EventSourceSchema>;
439
+ export type EventName = z.infer<typeof EventNameSchema>;
440
+ export type SwarmEvent = z.infer<typeof SwarmEventSchema>;
441
+
366
442
  // ============================================================================
367
443
  // Scheduled Task Types
368
444
  // ============================================================================
@@ -923,3 +999,80 @@ export const SkillWithInstallInfoSchema = SkillSchema.extend({
923
999
  installedAt: z.string(),
924
1000
  });
925
1001
  export type SkillWithInstallInfo = z.infer<typeof SkillWithInstallInfoSchema>;
1002
+
1003
+ // ── MCP Servers ──────────────────────────────────────────────────────────
1004
+
1005
+ export const McpServerTransportSchema = z.enum(["stdio", "http", "sse"]);
1006
+ export type McpServerTransport = z.infer<typeof McpServerTransportSchema>;
1007
+
1008
+ export const McpServerScopeSchema = z.enum(["global", "swarm", "agent"]);
1009
+ export type McpServerScope = z.infer<typeof McpServerScopeSchema>;
1010
+
1011
+ export const McpServerSchema = z.object({
1012
+ id: z.string(),
1013
+ name: z.string(),
1014
+ description: z.string().nullable(),
1015
+ scope: McpServerScopeSchema,
1016
+ ownerAgentId: z.string().nullable(),
1017
+ transport: McpServerTransportSchema,
1018
+ command: z.string().nullable(),
1019
+ args: z.string().nullable(),
1020
+ url: z.string().nullable(),
1021
+ headers: z.string().nullable(),
1022
+ envConfigKeys: z.string().nullable(),
1023
+ headerConfigKeys: z.string().nullable(),
1024
+ isEnabled: z.boolean(),
1025
+ version: z.number(),
1026
+ createdAt: z.string(),
1027
+ lastUpdatedAt: z.string(),
1028
+ });
1029
+ export type McpServer = z.infer<typeof McpServerSchema>;
1030
+
1031
+ export const AgentMcpServerSchema = z.object({
1032
+ id: z.string(),
1033
+ agentId: z.string(),
1034
+ mcpServerId: z.string(),
1035
+ isActive: z.boolean(),
1036
+ installedAt: z.string(),
1037
+ });
1038
+ export type AgentMcpServer = z.infer<typeof AgentMcpServerSchema>;
1039
+
1040
+ export const McpServerWithInstallInfoSchema = McpServerSchema.extend({
1041
+ isActive: z.boolean(),
1042
+ installedAt: z.string(),
1043
+ });
1044
+ export type McpServerWithInstallInfo = z.infer<typeof McpServerWithInstallInfoSchema>;
1045
+
1046
+ // ============================================================================
1047
+ // Context Usage Tracking Types
1048
+ // ============================================================================
1049
+
1050
+ export const ContextSnapshotEventTypeSchema = z.enum(["progress", "compaction", "completion"]);
1051
+ export type ContextSnapshotEventType = z.infer<typeof ContextSnapshotEventTypeSchema>;
1052
+
1053
+ export const ContextSnapshotSchema = z.object({
1054
+ id: z.uuid(),
1055
+ taskId: z.uuid(),
1056
+ agentId: z.uuid(),
1057
+ sessionId: z.string(),
1058
+
1059
+ // Context window state
1060
+ contextUsedTokens: z.number().int().min(0).optional(),
1061
+ contextTotalTokens: z.number().int().min(0).optional(),
1062
+ contextPercent: z.number().min(0).max(100).optional(),
1063
+
1064
+ // Event metadata
1065
+ eventType: ContextSnapshotEventTypeSchema,
1066
+
1067
+ // Compaction-specific (null for non-compaction)
1068
+ compactTrigger: z.enum(["auto", "manual"]).optional(),
1069
+ preCompactTokens: z.number().int().min(0).optional(),
1070
+
1071
+ // Cumulative counters at this point
1072
+ cumulativeInputTokens: z.number().int().min(0).default(0),
1073
+ cumulativeOutputTokens: z.number().int().min(0).default(0),
1074
+
1075
+ createdAt: z.iso.datetime(),
1076
+ });
1077
+
1078
+ export type ContextSnapshot = z.infer<typeof ContextSnapshotSchema>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Context window size lookup and usage computation utilities.
3
+ *
4
+ * This module is safe for both API and worker code — it has NO database imports.
5
+ */
6
+
7
+ const CONTEXT_WINDOW_DEFAULTS: Record<string, number> = {
8
+ "claude-opus-4-6": 1_000_000,
9
+ "claude-sonnet-4-6": 1_000_000,
10
+ "claude-haiku-4-5": 200_000,
11
+ opus: 1_000_000,
12
+ sonnet: 1_000_000,
13
+ haiku: 200_000,
14
+ default: 200_000,
15
+ };
16
+
17
+ /**
18
+ * Look up the context window size (in tokens) for a given model identifier.
19
+ * Falls back to the "default" entry when the model is not explicitly mapped.
20
+ */
21
+ const DEFAULT_CONTEXT_WINDOW = 200_000;
22
+
23
+ export function getContextWindowSize(model: string): number {
24
+ return CONTEXT_WINDOW_DEFAULTS[model] ?? DEFAULT_CONTEXT_WINDOW;
25
+ }
26
+
27
+ /**
28
+ * Compute the total context tokens used from a Claude API usage object.
29
+ * Sums input_tokens + cache_creation_input_tokens + cache_read_input_tokens.
30
+ */
31
+ export function computeContextUsed(usage: {
32
+ input_tokens?: number | null;
33
+ cache_creation_input_tokens?: number | null;
34
+ cache_read_input_tokens?: number | null;
35
+ }): number {
36
+ return (
37
+ (usage.input_tokens ?? 0) +
38
+ (usage.cache_creation_input_tokens ?? 0) +
39
+ (usage.cache_read_input_tokens ?? 0)
40
+ );
41
+ }
@@ -61,7 +61,15 @@ export abstract class BaseExecutor<
61
61
  };
62
62
  }
63
63
 
64
- const result = await this.execute(configResult.data, input.context, input.meta);
64
+ let result: ExecutorResult<z.infer<TOutput>>;
65
+ try {
66
+ result = await this.execute(configResult.data, input.context, input.meta);
67
+ } catch (err) {
68
+ return {
69
+ status: "failed",
70
+ error: `Executor threw: ${err instanceof Error ? err.message : String(err)}`,
71
+ };
72
+ }
65
73
 
66
74
  // Validate output for successful results
67
75
  if (result.status === "success" && result.output !== undefined) {