@agent-native/dispatch 0.20.4 → 0.22.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 (87) hide show
  1. package/dist/actions/get-agent-thread-debug.d.ts +2 -0
  2. package/dist/actions/provider-api-register.d.ts +7 -7
  3. package/dist/actions/search-agent-threads.js +2 -2
  4. package/dist/actions/search-agent-threads.js.map +1 -1
  5. package/dist/actions/start-workspace-app-creation.js +1 -1
  6. package/dist/actions/start-workspace-app-creation.js.map +1 -1
  7. package/dist/components/create-app-popover.d.ts.map +1 -1
  8. package/dist/components/create-app-popover.js +5 -71
  9. package/dist/components/create-app-popover.js.map +1 -1
  10. package/dist/components/layout/HeaderActions.d.ts +1 -17
  11. package/dist/components/layout/HeaderActions.d.ts.map +1 -1
  12. package/dist/components/layout/HeaderActions.js +1 -51
  13. package/dist/components/layout/HeaderActions.js.map +1 -1
  14. package/dist/components/layout/Layout.d.ts +23 -1
  15. package/dist/components/layout/Layout.d.ts.map +1 -1
  16. package/dist/components/layout/Layout.js +707 -18
  17. package/dist/components/layout/Layout.js.map +1 -1
  18. package/dist/components/ui/dialog.d.ts +1 -19
  19. package/dist/components/ui/dialog.d.ts.map +1 -1
  20. package/dist/components/ui/dialog.js +1 -22
  21. package/dist/components/ui/dialog.js.map +1 -1
  22. package/dist/components/ui/dropdown-menu.d.ts +1 -27
  23. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  24. package/dist/components/ui/dropdown-menu.js +1 -35
  25. package/dist/components/ui/dropdown-menu.js.map +1 -1
  26. package/dist/components/ui/popover.d.ts +2 -1
  27. package/dist/components/ui/popover.d.ts.map +1 -1
  28. package/dist/components/ui/popover.js +2 -1
  29. package/dist/components/ui/popover.js.map +1 -1
  30. package/dist/components/ui/select.d.ts +1 -13
  31. package/dist/components/ui/select.d.ts.map +1 -1
  32. package/dist/components/ui/select.js +1 -26
  33. package/dist/components/ui/select.js.map +1 -1
  34. package/dist/hooks/use-mobile.d.ts +1 -1
  35. package/dist/hooks/use-mobile.d.ts.map +1 -1
  36. package/dist/hooks/use-mobile.js +1 -15
  37. package/dist/hooks/use-mobile.js.map +1 -1
  38. package/dist/lib/automation-display.js +1 -1
  39. package/dist/lib/automation-display.js.map +1 -1
  40. package/dist/lib/workspace-apps.d.ts +6 -0
  41. package/dist/lib/workspace-apps.d.ts.map +1 -1
  42. package/dist/lib/workspace-apps.js +21 -0
  43. package/dist/lib/workspace-apps.js.map +1 -1
  44. package/dist/routes/pages/settings.d.ts.map +1 -1
  45. package/dist/routes/pages/settings.js +21 -1
  46. package/dist/routes/pages/settings.js.map +1 -1
  47. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  48. package/dist/routes/pages/thread-debug.js +288 -118
  49. package/dist/routes/pages/thread-debug.js.map +1 -1
  50. package/dist/server/lib/app-creation-store.d.ts.map +1 -1
  51. package/dist/server/lib/app-creation-store.js +13 -0
  52. package/dist/server/lib/app-creation-store.js.map +1 -1
  53. package/dist/server/lib/thread-debug-store.d.ts +2 -0
  54. package/dist/server/lib/thread-debug-store.d.ts.map +1 -1
  55. package/dist/server/lib/thread-debug-store.js +6 -2
  56. package/dist/server/lib/thread-debug-store.js.map +1 -1
  57. package/dist/server/plugins/agent-chat.js +1 -0
  58. package/dist/server/plugins/agent-chat.js.map +1 -1
  59. package/dist/server/plugins/integrations.js +1 -1
  60. package/dist/server/plugins/integrations.js.map +1 -1
  61. package/package.json +3 -3
  62. package/src/actions/search-agent-threads.ts +2 -2
  63. package/src/actions/start-workspace-app-creation.ts +1 -1
  64. package/src/components/create-app-popover.spec.tsx +22 -0
  65. package/src/components/create-app-popover.tsx +30 -94
  66. package/src/components/layout/HeaderActions.tsx +1 -84
  67. package/src/components/layout/Layout.spec.tsx +35 -10
  68. package/src/components/layout/Layout.tsx +1394 -74
  69. package/src/components/ui/dialog.tsx +1 -120
  70. package/src/components/ui/dropdown-menu.tsx +1 -198
  71. package/src/components/ui/popover.tsx +3 -1
  72. package/src/components/ui/select.tsx +1 -158
  73. package/src/hooks/use-mobile.tsx +1 -21
  74. package/src/lib/automation-display.spec.ts +1 -1
  75. package/src/lib/automation-display.ts +1 -1
  76. package/src/lib/workspace-apps.ts +24 -0
  77. package/src/routes/pages/settings.tsx +72 -0
  78. package/src/routes/pages/thread-debug.spec.tsx +103 -5
  79. package/src/routes/pages/thread-debug.tsx +1051 -451
  80. package/src/server/lib/app-creation-store.spec.ts +13 -0
  81. package/src/server/lib/app-creation-store.ts +13 -0
  82. package/src/server/lib/mcp-gateway.spec.ts +18 -0
  83. package/src/server/lib/thread-debug-store.spec.ts +17 -0
  84. package/src/server/lib/thread-debug-store.ts +9 -2
  85. package/src/server/plugins/agent-chat.ts +1 -0
  86. package/src/server/plugins/integrations.ts +1 -1
  87. package/src/styles/dispatch.css +29 -0
@@ -27,13 +27,17 @@ const failedRun = {
27
27
  threadTitle: "Mail agent failed",
28
28
  threadPreview: "Provider timed out",
29
29
  status: "errored",
30
- errorCode: "provider_timeout",
31
- errorDetail: "The provider did not respond.",
32
- terminalReason: "provider_timeout",
30
+ errorCode: "stale_run",
31
+ errorDetail:
32
+ "The run heartbeat stopped while the run was still marked running.",
33
+ terminalReason: "stale_run",
33
34
  abortReason: null,
34
35
  dispatchMode: "background-processing",
35
36
  diagStage: null,
36
37
  workerStage: "model",
38
+ heartbeatAt: 1_722_400_029_000,
39
+ lastProgressAt: 1_722_400_028_000,
40
+ regime: "scheduled",
37
41
  startedAt: 1_722_400_000_000,
38
42
  completedAt: 1_722_400_030_000,
39
43
  durationMs: 30_000,
@@ -67,7 +71,25 @@ const detail = {
67
71
  queuedMessages: [],
68
72
  threadData: {},
69
73
  rawThreadData: "{}",
70
- runs: [],
74
+ runs: [
75
+ {
76
+ ...failedRun,
77
+ events: [
78
+ {
79
+ seq: 1,
80
+ event: { type: "tool_start", tool: "search-mail" },
81
+ rawEventData: '{"type":"tool_start","tool":"search-mail"}',
82
+ },
83
+ {
84
+ seq: 2,
85
+ event: { type: "error", errorCode: "stale_run" },
86
+ rawEventData: '{"type":"error","errorCode":"stale_run"}',
87
+ },
88
+ ],
89
+ completedAt: null,
90
+ durationMs: null,
91
+ },
92
+ ],
71
93
  traces: { summaries: [], spans: [] },
72
94
  feedback: [],
73
95
  satisfaction: [],
@@ -75,6 +97,17 @@ const detail = {
75
97
  checkpoints: [],
76
98
  };
77
99
 
100
+ const threadResult = {
101
+ id: "thread-chat-1",
102
+ ownerEmail: "ops@example.com",
103
+ title: "Job: builder-agent-refresh — 8/9/2026",
104
+ preview: "thread-chat-1",
105
+ messageCount: 3,
106
+ createdAt: 1_722_400_000_000,
107
+ updatedAt: 1_722_400_030_000,
108
+ snippet: "{}",
109
+ };
110
+
78
111
  vi.mock("@agent-native/core/client/hooks", () => ({
79
112
  useActionQuery: (
80
113
  name: string,
@@ -158,6 +191,25 @@ vi.mock("@agent-native/core/client/hooks", () => ({
158
191
  if (name === "get-agent-thread-debug") {
159
192
  return { ...base, data: enabled ? detail : undefined };
160
193
  }
194
+ if (name === "search-agent-threads") {
195
+ return {
196
+ ...base,
197
+ data: enabled
198
+ ? {
199
+ count: 1,
200
+ threads: [threadResult],
201
+ access: {
202
+ scope: "current organization",
203
+ canInspectAll: true,
204
+ },
205
+ source: {
206
+ id: "current",
207
+ label: "Current Dispatch DB",
208
+ },
209
+ }
210
+ : undefined,
211
+ };
212
+ }
161
213
  return { ...base, data: undefined };
162
214
  },
163
215
  }));
@@ -219,10 +271,13 @@ describe("ThreadDebugRoute", () => {
219
271
  ).toMatchObject({
220
272
  sourceId: "all",
221
273
  status: "all",
274
+ regime: "all",
222
275
  lookbackHours: 24,
223
276
  });
224
277
  expect(container.textContent).toContain("Partial results");
225
278
  expect(container.textContent).toContain("Clips (unavailable)");
279
+ expect(container.textContent).not.toContain(failedRun.id);
280
+ expect(container.textContent).not.toContain(failedRun.threadId);
226
281
 
227
282
  const failureButton = [...container.querySelectorAll("button")].find(
228
283
  (button) => button.textContent?.includes("Inspect failed run"),
@@ -243,6 +298,8 @@ describe("ThreadDebugRoute", () => {
243
298
  sourceId: "mail",
244
299
  runId: failedRun.id,
245
300
  });
301
+ expect(container.textContent).toContain("Worker stopped reporting");
302
+ expect(container.textContent).toContain("retained 2 execution events");
246
303
  });
247
304
 
248
305
  it("passes valid URL-backed failure filters to the action", async () => {
@@ -250,7 +307,7 @@ describe("ThreadDebugRoute", () => {
250
307
  root.render(
251
308
  <MemoryRouter
252
309
  initialEntries={[
253
- "/thread-debug?source=mail&owner=ops%40example.com&status=errored&range=7d",
310
+ "/thread-debug?source=mail&owner=ops%40example.com&status=errored&regime=scheduled&range=7d",
254
311
  ]}
255
312
  >
256
313
  <ThreadDebugRoute />
@@ -266,7 +323,48 @@ describe("ThreadDebugRoute", () => {
266
323
  sourceId: "mail",
267
324
  ownerEmail: "ops@example.com",
268
325
  status: "errored",
326
+ regime: "scheduled",
269
327
  lookbackHours: 168,
270
328
  });
271
329
  });
330
+
331
+ it("keeps thread list rows human-readable without technical identifiers", async () => {
332
+ await act(async () => {
333
+ root.render(
334
+ <MemoryRouter initialEntries={["/thread-debug?mode=threads"]}>
335
+ <ThreadDebugRoute />
336
+ </MemoryRouter>,
337
+ );
338
+ });
339
+
340
+ expect(container.textContent).toContain("Builder Agent Refresh");
341
+ expect(container.textContent).toContain("3 messages");
342
+ expect(container.textContent).toContain("ops@example.com");
343
+ expect(container.textContent).toContain("Advanced");
344
+ expect(container.textContent).not.toContain("Owner email");
345
+ expect(container.textContent).not.toContain("Find a thread");
346
+ expect(container.textContent).not.toContain("Search by title");
347
+ expect(container.textContent).not.toContain(threadResult.id);
348
+ expect(container.textContent).not.toContain("{}");
349
+ expect(container.querySelector("summary svg")).toBeTruthy();
350
+ const searchCall = queryState.calls.find(
351
+ (call) => call.name === "search-agent-threads" && call.enabled,
352
+ );
353
+ expect(searchCall?.params).toMatchObject({
354
+ sourceId: "current",
355
+ limit: 25,
356
+ });
357
+ expect(searchCall?.params).not.toHaveProperty("ownerEmail");
358
+
359
+ const searchInput = container.querySelector(
360
+ 'input[aria-label="Search threads or email"]',
361
+ );
362
+ expect(searchInput).toBeTruthy();
363
+ await act(async () => {
364
+ (searchInput as HTMLInputElement).focus();
365
+ });
366
+ expect(document.body.querySelector('[role="option"]')?.textContent).toBe(
367
+ "ops@example.com",
368
+ );
369
+ });
272
370
  });