@desplega.ai/agent-swarm 1.74.4 → 1.76.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 (88) hide show
  1. package/README.md +1 -1
  2. package/openapi.json +1264 -46
  3. package/package.json +2 -2
  4. package/src/be/db.ts +563 -9
  5. package/src/be/memory/edges-store.ts +69 -0
  6. package/src/be/memory/providers/sqlite-store.ts +4 -0
  7. package/src/be/memory/raters/explicit-self.ts +22 -0
  8. package/src/be/memory/raters/implicit-citation.ts +44 -0
  9. package/src/be/memory/raters/llm-client.ts +172 -0
  10. package/src/be/memory/raters/llm-summarizer.ts +218 -0
  11. package/src/be/memory/raters/llm.ts +375 -0
  12. package/src/be/memory/raters/noop.ts +14 -0
  13. package/src/be/memory/raters/registry.ts +86 -0
  14. package/src/be/memory/raters/retrieval.ts +88 -0
  15. package/src/be/memory/raters/run-server-raters.ts +97 -0
  16. package/src/be/memory/raters/store.ts +228 -0
  17. package/src/be/memory/raters/types.ts +101 -0
  18. package/src/be/memory/reranker.ts +32 -2
  19. package/src/be/memory/retrieval-store.ts +116 -0
  20. package/src/be/memory/types.ts +3 -0
  21. package/src/be/migrations/051_memory_posteriors_and_retrieval.sql +67 -0
  22. package/src/be/migrations/052_memory_edges.sql +36 -0
  23. package/src/be/migrations/053_agent_waiting_for_credentials_status.sql +61 -0
  24. package/src/be/migrations/054_agent_harness_provider.sql +21 -0
  25. package/src/be/migrations/055_agent_cred_status.sql +15 -0
  26. package/src/be/migrations/056_drop_agent_tasks_source_check.sql +139 -0
  27. package/src/be/migrations/057_inbox_item_state.sql +27 -0
  28. package/src/be/migrations/058_task_templates.sql +31 -0
  29. package/src/be/swarm-config-guard.ts +24 -0
  30. package/src/commands/credential-wait.ts +186 -0
  31. package/src/commands/provider-credentials.ts +434 -0
  32. package/src/commands/runner.ts +253 -21
  33. package/src/hooks/hook.ts +143 -66
  34. package/src/http/agents.ts +191 -1
  35. package/src/http/config.ts +11 -1
  36. package/src/http/core.ts +5 -0
  37. package/src/http/inbox-state.ts +89 -0
  38. package/src/http/index.ts +10 -0
  39. package/src/http/memory.ts +230 -1
  40. package/src/http/sessions.ts +86 -0
  41. package/src/http/status.ts +665 -0
  42. package/src/http/task-templates.ts +51 -0
  43. package/src/http/tasks.ts +85 -5
  44. package/src/http/users.ts +134 -0
  45. package/src/prompts/memories.ts +62 -0
  46. package/src/providers/claude-adapter.ts +22 -0
  47. package/src/providers/claude-managed-adapter.ts +24 -0
  48. package/src/providers/codex-adapter.ts +43 -1
  49. package/src/providers/devin-adapter.ts +18 -0
  50. package/src/providers/index.ts +7 -0
  51. package/src/providers/opencode-adapter.ts +60 -0
  52. package/src/providers/pi-mono-adapter.ts +71 -0
  53. package/src/providers/types.ts +34 -0
  54. package/src/server.ts +2 -0
  55. package/src/slack/handlers.ts +0 -1
  56. package/src/tests/agents-harness-provider.test.ts +333 -0
  57. package/src/tests/credential-check.test.ts +367 -0
  58. package/src/tests/credential-status-api.test.ts +223 -0
  59. package/src/tests/credential-status-routing.test.ts +150 -0
  60. package/src/tests/credential-wait.test.ts +282 -0
  61. package/src/tests/harness-provider-resolution.test.ts +242 -0
  62. package/src/tests/jira-sync.test.ts +1 -1
  63. package/src/tests/memory-edges.test.ts +722 -0
  64. package/src/tests/memory-rate-endpoint.test.ts +330 -0
  65. package/src/tests/memory-rate-tool.test.ts +252 -0
  66. package/src/tests/memory-rater-e2e.test.ts +578 -0
  67. package/src/tests/memory-rater-implicit-citation.test.ts +304 -0
  68. package/src/tests/memory-rater-llm-summarizer.test.ts +317 -0
  69. package/src/tests/memory-rater-llm.test.ts +964 -0
  70. package/src/tests/memory-rater-store.test.ts +249 -0
  71. package/src/tests/memory-reranker.test.ts +161 -2
  72. package/src/tests/migration-runner-regressions.test.ts +17 -2
  73. package/src/tests/mocks/mock-llm-rater-client.ts +35 -0
  74. package/src/tests/run-server-raters.test.ts +291 -0
  75. package/src/tests/sessions.test.ts +141 -0
  76. package/src/tests/status.test.ts +843 -0
  77. package/src/tests/stop-hook-task-resolution.test.ts +98 -0
  78. package/src/tests/template-recommendations.test.ts +148 -0
  79. package/src/tests/tool-annotations.test.ts +2 -2
  80. package/src/tests/use-dismissible-card.test.ts +140 -0
  81. package/src/tools/memory-rate.ts +166 -0
  82. package/src/tools/memory-search.ts +18 -0
  83. package/src/tools/store-progress.ts +37 -0
  84. package/src/tools/swarm-config/set-config.ts +17 -1
  85. package/src/tools/tool-config.ts +1 -0
  86. package/src/types.ts +122 -1
  87. package/src/utils/harness-provider.ts +32 -0
  88. package/tsconfig.json +0 -2
@@ -31,6 +31,7 @@ export const CORE_TOOLS = new Set([
31
31
  "memory-search", // recall relevant context
32
32
  "memory-get", // retrieve full memory content
33
33
  "memory-delete", // delete own memories
34
+ "memory_rate", // rate a memory used in this task (worker→server)
34
35
 
35
36
  // Swarm awareness
36
37
  "get-swarm", // check who's online
package/src/types.ts CHANGED
@@ -57,6 +57,7 @@ export const AgentTaskSourceSchema = z.enum([
57
57
  "mcp",
58
58
  "slack",
59
59
  "api",
60
+ "ui",
60
61
  "github",
61
62
  "gitlab",
62
63
  "agentmail",
@@ -233,7 +234,73 @@ export const UserSchema = z.object({
233
234
 
234
235
  export type User = z.infer<typeof UserSchema>;
235
236
 
236
- export const AgentStatusSchema = z.enum(["idle", "busy", "offline"]);
237
+ // ============================================================================
238
+ // Inbox Item State (per-user dismiss/snooze/done for action-items inbox)
239
+ // ============================================================================
240
+ //
241
+ // Action-items inbox buckets:
242
+ // - approval — pending approval requests
243
+ // - credential_missing — agents in waiting_for_credentials state
244
+ // - broken_task — tasks in failed/cancelled status
245
+ // - to_read — sessions/tasks marked unread for the user
246
+ // - to_start_template — task-templates the user hasn't dismissed
247
+ //
248
+ // Statuses:
249
+ // - open — visible in inbox
250
+ // - snoozed — hidden until snoozeUntil; reappears as `open`
251
+ // - dismissed — hidden permanently (until item itself reactivates)
252
+ // - done — user marked complete
253
+ export const InboxItemTypeSchema = z.enum([
254
+ "approval",
255
+ "credential_missing",
256
+ "broken_task",
257
+ "to_read",
258
+ "to_start_template",
259
+ ]);
260
+ export type InboxItemType = z.infer<typeof InboxItemTypeSchema>;
261
+
262
+ export const InboxItemStatusSchema = z.enum(["open", "snoozed", "dismissed", "done"]);
263
+ export type InboxItemStatus = z.infer<typeof InboxItemStatusSchema>;
264
+
265
+ export const InboxItemStateSchema = z.object({
266
+ id: z.string(),
267
+ userId: z.string(),
268
+ itemType: InboxItemTypeSchema,
269
+ itemId: z.string(),
270
+ status: InboxItemStatusSchema,
271
+ snoozeUntil: z.string().optional(),
272
+ dismissedAt: z.string().optional(),
273
+ doneAt: z.string().optional(),
274
+ createdAt: z.string(),
275
+ lastUpdatedAt: z.string(),
276
+ });
277
+ export type InboxItemState = z.infer<typeof InboxItemStateSchema>;
278
+
279
+ // ============================================================================
280
+ // Task Templates ("To start" bucket — polymorphic starters registry)
281
+ // ============================================================================
282
+ //
283
+ // kind:
284
+ // - task — v1 default; payload is `{}` and the task prompt lives in `prompt`
285
+ // - workflow — v2 hook; payload `{ workflowId: string }`, prompt may be empty
286
+ // - schedule — v2 hook; payload `{ cron: string, prompt: string }`
287
+ export const TaskTemplateKindSchema = z.enum(["task", "workflow", "schedule"]);
288
+ export type TaskTemplateKind = z.infer<typeof TaskTemplateKindSchema>;
289
+
290
+ export const TaskTemplateSchema = z.object({
291
+ id: z.string(),
292
+ title: z.string().min(1),
293
+ description: z.string(),
294
+ prompt: z.string(),
295
+ kind: TaskTemplateKindSchema.default("task"),
296
+ payload: z.record(z.string(), z.unknown()).default({}),
297
+ category: z.string().optional(),
298
+ tags: z.array(z.string()).default([]),
299
+ createdAt: z.string(),
300
+ });
301
+ export type TaskTemplate = z.infer<typeof TaskTemplateSchema>;
302
+
303
+ export const AgentStatusSchema = z.enum(["idle", "busy", "offline", "waiting_for_credentials"]);
237
304
 
238
305
  export const AgentSchema = z.object({
239
306
  id: z.uuid(),
@@ -272,10 +339,64 @@ export const AgentSchema = z.object({
272
339
  // Harness provider this agent runs (claude, opencode, codex, ...)
273
340
  provider: ProviderNameSchema.optional(),
274
341
 
342
+ // Phase 1.5 (cloud-personalization): harness provider pushed by the worker
343
+ // on registration. Mirrors `provider` but lives in its own column so the
344
+ // server can answer "what harnesses are deployed?" without joining
345
+ // anywhere else, and so an operator can re-assign via
346
+ // PATCH /api/agents/:id/harness-provider without restarting the worker.
347
+ // Worker boot path is NOT yet rewritten (DES-359 tracks that) — the
348
+ // PATCH is a planning/forecast mechanism today; on next worker restart,
349
+ // the env-driven value wins.
350
+ harnessProvider: ProviderNameSchema.nullable().optional(),
351
+
352
+ // Env-var names the worker is blocked on when status is
353
+ // `waiting_for_credentials`. Null otherwise.
354
+ credentialMissing: z.array(z.string()).nullable().optional(),
355
+
356
+ // Worker-self-reported credential snapshot for this agent's harness.
357
+ // Pairs with `harnessProvider`. Null = unreported (worker hasn't booted
358
+ // yet, or CRED_CHECK_DISABLE=1 was set). Migration 055 adds the column.
359
+ credStatus: z
360
+ .lazy(() => AgentCredStatusSchema)
361
+ .nullable()
362
+ .optional(),
363
+
275
364
  createdAt: z.iso.datetime().default(() => new Date().toISOString()),
276
365
  lastUpdatedAt: z.iso.datetime().default(() => new Date().toISOString()),
277
366
  });
278
367
 
368
+ // ---------------------------------------------------------------------------
369
+ // Worker-reported credential snapshot
370
+ // ---------------------------------------------------------------------------
371
+ // `provider` is intentionally absent from the JSON — already on the agent row
372
+ // as `harnessProvider`; the status endpoint joins them at read time.
373
+ //
374
+ // `reportKind` records the trigger that produced the report:
375
+ // - "boot": worker startup, full check (presence + live test).
376
+ // - "post_task": worker finished a task and `harness_provider` differed
377
+ // from its cached value, so it re-ran a full check (presence + live test).
378
+ //
379
+ // The cache-hit post-task path does NOT produce a new report; the row's
380
+ // `reportedAt` deliberately stays at the last actual check.
381
+ export const AgentCredStatusLiveTestSchema = z.object({
382
+ ok: z.boolean(),
383
+ error: z.string().nullable().default(null),
384
+ latency_ms: z.number(),
385
+ testedAt: z.number(), // unix ms
386
+ });
387
+ export type AgentCredStatusLiveTest = z.infer<typeof AgentCredStatusLiveTestSchema>;
388
+
389
+ export const AgentCredStatusSchema = z.object({
390
+ ready: z.boolean(),
391
+ missing: z.array(z.string()).default([]),
392
+ satisfiedBy: z.enum(["env", "file", "side-effect-pending"]).nullable().default(null),
393
+ hint: z.string().nullable().default(null),
394
+ liveTest: AgentCredStatusLiveTestSchema.nullable().default(null),
395
+ reportedAt: z.number(), // unix ms
396
+ reportKind: z.enum(["boot", "post_task"]).default("boot"),
397
+ });
398
+ export type AgentCredStatus = z.infer<typeof AgentCredStatusSchema>;
399
+
279
400
  export const AgentWithTasksSchema = AgentSchema.extend({
280
401
  tasks: z.array(AgentTaskSchema).default([]),
281
402
  });
@@ -0,0 +1,32 @@
1
+ import { type ProviderName, ProviderNameSchema } from "../types";
2
+
3
+ const SUPPORTED_PROVIDERS = ProviderNameSchema.options;
4
+
5
+ /**
6
+ * Resolve the effective `HARNESS_PROVIDER` for a worker.
7
+ *
8
+ * Precedence (highest first):
9
+ * 1. `resolvedEnv.HARNESS_PROVIDER` — value coming from `swarm_config`
10
+ * (overlay produced by `fetchResolvedEnv`, scoped repo > agent > global).
11
+ * 2. `fallbackEnv.HARNESS_PROVIDER` — raw `process.env`.
12
+ * 3. `"claude"` — final default.
13
+ *
14
+ * Invalid values (anything outside `ProviderNameSchema`) log a warning and
15
+ * fall back to `"claude"` rather than throwing — boot must not be killed
16
+ * by a typo'd swarm_config row.
17
+ */
18
+ export function resolveHarnessProvider(
19
+ resolvedEnv: Record<string, string | undefined>,
20
+ fallbackEnv: Record<string, string | undefined> = process.env,
21
+ ): ProviderName {
22
+ const candidate = resolvedEnv.HARNESS_PROVIDER?.trim() || fallbackEnv.HARNESS_PROVIDER?.trim();
23
+ if (!candidate) return "claude";
24
+ const parsed = ProviderNameSchema.safeParse(candidate);
25
+ if (!parsed.success) {
26
+ console.warn(
27
+ `[harness-provider] Invalid HARNESS_PROVIDER="${candidate}" (must be one of: ${SUPPORTED_PROVIDERS.join(", ")}); falling back to "claude"`,
28
+ );
29
+ return "claude";
30
+ }
31
+ return parsed.data;
32
+ }
package/tsconfig.json CHANGED
@@ -35,9 +35,7 @@
35
35
  },
36
36
  "exclude": [
37
37
  "ui",
38
- "new-ui",
39
38
  "templates-ui",
40
- "landing",
41
39
  "node_modules",
42
40
  "scripts",
43
41
  "src/tests",