@agent-native/dispatch 0.15.16 → 0.15.18

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 (36) hide show
  1. package/dist/actions/provider-api-register.d.ts +6 -6
  2. package/dist/components/dispatch-control-plane.d.ts.map +1 -1
  3. package/dist/components/dispatch-control-plane.js +5 -3
  4. package/dist/components/dispatch-control-plane.js.map +1 -1
  5. package/dist/components/layout/Layout.d.ts.map +1 -1
  6. package/dist/components/layout/Layout.js +3 -3
  7. package/dist/components/layout/Layout.js.map +1 -1
  8. package/dist/lib/automation-display.d.ts +1 -0
  9. package/dist/lib/automation-display.d.ts.map +1 -1
  10. package/dist/lib/automation-display.js +4 -0
  11. package/dist/lib/automation-display.js.map +1 -1
  12. package/dist/lib/overview-chat.d.ts +7 -2
  13. package/dist/lib/overview-chat.d.ts.map +1 -1
  14. package/dist/lib/overview-chat.js +3 -1
  15. package/dist/lib/overview-chat.js.map +1 -1
  16. package/dist/routes/pages/automations.d.ts.map +1 -1
  17. package/dist/routes/pages/automations.js +4 -3
  18. package/dist/routes/pages/automations.js.map +1 -1
  19. package/dist/routes/pages/chat.d.ts.map +1 -1
  20. package/dist/routes/pages/chat.js +4 -0
  21. package/dist/routes/pages/chat.js.map +1 -1
  22. package/dist/routes/pages/thread-debug.d.ts.map +1 -1
  23. package/dist/routes/pages/thread-debug.js +11 -6
  24. package/dist/routes/pages/thread-debug.js.map +1 -1
  25. package/package.json +2 -2
  26. package/src/components/dispatch-control-plane.spec.tsx +41 -16
  27. package/src/components/dispatch-control-plane.tsx +18 -1
  28. package/src/components/layout/Layout.spec.tsx +2 -5
  29. package/src/components/layout/Layout.tsx +15 -6
  30. package/src/lib/automation-display.spec.ts +7 -0
  31. package/src/lib/automation-display.ts +7 -0
  32. package/src/lib/overview-chat.spec.ts +4 -0
  33. package/src/lib/overview-chat.ts +13 -2
  34. package/src/routes/pages/automations.tsx +19 -3
  35. package/src/routes/pages/chat.tsx +6 -0
  36. package/src/routes/pages/thread-debug.tsx +11 -6
@@ -8,7 +8,6 @@ import {
8
8
  type ChatThreadSummary,
9
9
  } from "@agent-native/core/client/agent-chat";
10
10
  import { appBasePath, appPath } from "@agent-native/core/client/api-path";
11
- import { ExtensionsSidebarSection } from "@agent-native/core/client/extensions";
12
11
  import { useActionQuery } from "@agent-native/core/client/hooks";
13
12
  import { useT } from "@agent-native/core/client/i18n";
14
13
  import { InvitationBanner, OrgSwitcher } from "@agent-native/core/client/org";
@@ -177,12 +176,14 @@ const OPERATIONS_NAV_ITEMS = [
177
176
  icon: IconLayersSubtract,
178
177
  section: "operations",
179
178
  },
179
+ ] as const satisfies readonly DispatchNavItem[];
180
+
181
+ const BOTTOM_NAV_ITEMS = [
180
182
  {
181
183
  id: "settings",
182
184
  to: "/settings",
183
185
  label: "Settings",
184
186
  icon: IconSettings,
185
- section: "operations",
186
187
  },
187
188
  ] as const satisfies readonly DispatchNavItem[];
188
189
 
@@ -707,12 +708,20 @@ export function NavContent({
707
708
  )}
708
709
  </nav>
709
710
 
711
+ <div className="mt-auto shrink-0">
712
+ <nav className={cn("py-1", collapsed ? "px-1" : "px-2")}>
713
+ <ul
714
+ className={cn(
715
+ collapsed ? "flex flex-col items-center gap-1" : "space-y-0.5",
716
+ )}
717
+ >
718
+ {BOTTOM_NAV_ITEMS.map(renderNavItem)}
719
+ </ul>
720
+ </nav>
721
+ </div>
722
+
710
723
  {!collapsed ? (
711
724
  <div className="mt-auto shrink-0">
712
- <div className="px-2 py-1">
713
- <ExtensionsSidebarSection />
714
- </div>
715
-
716
725
  <div className="px-3 py-2">
717
726
  <OrgSwitcher />
718
727
  </div>
@@ -5,6 +5,7 @@ import {
5
5
  automationNextRun,
6
6
  automationStatus,
7
7
  automationTarget,
8
+ automationTroubleshootPath,
8
9
  sortAutomations,
9
10
  } from "./automation-display.js";
10
11
  import type { DispatchAutomationItem } from "./automations.js";
@@ -26,6 +27,12 @@ describe("automation-display", () => {
26
27
  ).toBe("user@example.com:jobs/digest.md");
27
28
  });
28
29
 
30
+ it("prepares a thread-debug search for an automation", () => {
31
+ expect(
32
+ automationTroubleshootPath({ name: "coach onboarding reminder" }),
33
+ ).toBe("/thread-debug?query=coach+onboarding+reminder");
34
+ });
35
+
29
36
  it("prefers event names, then schedule descriptions", () => {
30
37
  expect(
31
38
  automationTarget(
@@ -13,6 +13,13 @@ export function automationIdentity(
13
13
  return `${item.owner}:${item.path}`;
14
14
  }
15
15
 
16
+ export function automationTroubleshootPath(
17
+ item: Pick<DispatchAutomationItem, "name">,
18
+ ): string {
19
+ const params = new URLSearchParams({ query: item.name });
20
+ return `/thread-debug?${params.toString()}`;
21
+ }
22
+
16
23
  export function automationTarget(item: DispatchAutomationItem): string {
17
24
  if (item.triggerType === "event" && item.event) return item.event;
18
25
  if (item.scheduleDescription) return item.scheduleDescription;
@@ -34,6 +34,8 @@ describe("submitOverviewPrompt", () => {
34
34
  it("can submit to a mounted page chat without opening the sidebar", () => {
35
35
  const tabId = submitOverviewPrompt(" build a metrics app ", "auto", {
36
36
  openSidebar: false,
37
+ selectedEngine: "openai",
38
+ selectedEffort: "high",
37
39
  });
38
40
 
39
41
  expect(tabId).toBe("chat-tab");
@@ -42,6 +44,8 @@ describe("submitOverviewPrompt", () => {
42
44
  submit: true,
43
45
  newTab: true,
44
46
  model: "auto",
47
+ engine: "openai",
48
+ effort: "high",
45
49
  openSidebar: false,
46
50
  });
47
51
  });
@@ -1,10 +1,19 @@
1
- import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
1
+ import {
2
+ sendToAgentChat,
3
+ type AgentChatMessage,
4
+ } from "@agent-native/core/client/agent-chat";
2
5
  import { isInBuilderFrame } from "@agent-native/core/client/host";
3
6
 
7
+ interface OverviewChatOptions {
8
+ openSidebar?: boolean;
9
+ selectedEngine?: string | null;
10
+ selectedEffort?: AgentChatMessage["effort"];
11
+ }
12
+
4
13
  export function submitOverviewPrompt(
5
14
  message: string,
6
15
  selectedModel?: string | null,
7
- options?: { openSidebar?: boolean },
16
+ options?: OverviewChatOptions,
8
17
  ): string | null {
9
18
  const trimmed = message.trim();
10
19
  if (!trimmed) return null;
@@ -22,6 +31,8 @@ export function submitOverviewPrompt(
22
31
  submit: true,
23
32
  newTab: true,
24
33
  model: selectedModel || undefined,
34
+ ...(options?.selectedEngine ? { engine: options.selectedEngine } : {}),
35
+ ...(options?.selectedEffort ? { effort: options.selectedEffort } : {}),
25
36
  ...(options?.openSidebar === false ? { openSidebar: false } : {}),
26
37
  });
27
38
  }
@@ -1,9 +1,14 @@
1
1
  import { sendToAgentChat } from "@agent-native/core/client/agent-chat";
2
2
  import { PromptComposer } from "@agent-native/core/client/composer";
3
3
  import { useChangeVersions } from "@agent-native/core/client/hooks";
4
- import { IconPlus, IconSettingsAutomation } from "@tabler/icons-react";
4
+ import {
5
+ IconFileSearch,
6
+ IconPlus,
7
+ IconSettingsAutomation,
8
+ } from "@tabler/icons-react";
5
9
  import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
6
10
  import { useMemo, useState } from "react";
11
+ import { Link } from "react-router";
7
12
  import { toast } from "sonner";
8
13
 
9
14
  import { DispatchShell } from "../../components/dispatch-shell";
@@ -22,6 +27,7 @@ import {
22
27
  automationNextRun,
23
28
  automationStatus,
24
29
  automationTarget,
30
+ automationTroubleshootPath,
25
31
  sortAutomations,
26
32
  type AutomationStatusTone,
27
33
  } from "../../lib/automation-display";
@@ -234,8 +240,18 @@ export default function AutomationsRoute() {
234
240
  <span>Next {automationNextRun(item)}</span>
235
241
  </div>
236
242
  {item.lastError ? (
237
- <div className="mt-1 truncate text-xs text-destructive">
238
- {item.lastError}
243
+ <div className="mt-1 flex flex-wrap items-baseline gap-x-2 gap-y-1 text-xs text-destructive">
244
+ <span className="min-w-0 break-words">
245
+ {item.lastError}
246
+ </span>
247
+ <Link
248
+ to={automationTroubleshootPath(item)}
249
+ className="inline-flex shrink-0 items-center gap-1 font-medium text-foreground underline-offset-4 hover:underline"
250
+ aria-label={`Troubleshoot ${item.name} in Thread Debug`}
251
+ >
252
+ <IconFileSearch size={13} aria-hidden="true" />
253
+ Troubleshoot in Thread Debug
254
+ </Link>
239
255
  </div>
240
256
  ) : null}
241
257
  </div>
@@ -74,6 +74,8 @@ interface DispatchChatLocationState {
74
74
  id?: string | number;
75
75
  message?: string;
76
76
  selectedModel?: string | null;
77
+ selectedEngine?: string | null;
78
+ selectedEffort?: ComponentProps<typeof AgentChatSurface>["selectedEffort"];
77
79
  };
78
80
  dispatchThread?: {
79
81
  id?: string | number;
@@ -131,6 +133,8 @@ export default function ChatRoute() {
131
133
  if (message) {
132
134
  submitOverviewPrompt(message, prompt?.selectedModel, {
133
135
  openSidebar: false,
136
+ selectedEngine: prompt?.selectedEngine,
137
+ selectedEffort: prompt?.selectedEffort,
134
138
  });
135
139
  }
136
140
  navigate(`${location.pathname}${location.search}${location.hash}`, {
@@ -148,6 +152,8 @@ export default function ChatRoute() {
148
152
  prompt?.id,
149
153
  prompt?.message,
150
154
  prompt?.selectedModel,
155
+ prompt?.selectedEngine,
156
+ prompt?.selectedEffort,
151
157
  thread?.id,
152
158
  thread?.threadId,
153
159
  ]);
@@ -7,6 +7,7 @@ import {
7
7
  IconSearch,
8
8
  } from "@tabler/icons-react";
9
9
  import { useEffect, useMemo, useState } from "react";
10
+ import { useSearchParams } from "react-router";
10
11
 
11
12
  import { ActionQueryError } from "../../components/action-query-error";
12
13
  import { DispatchShell } from "../../components/dispatch-shell";
@@ -416,14 +417,18 @@ function ThreadDetail({ detail }: { detail: ThreadDebugResponse }) {
416
417
  }
417
418
 
418
419
  export default function ThreadDebugRoute() {
419
- const [sourceId, setSourceId] = useState("current");
420
- const [query, setQuery] = useState("");
421
- const [ownerEmail, setOwnerEmail] = useState("");
420
+ const [routeSearchParams] = useSearchParams();
421
+ const initialSourceId = routeSearchParams.get("source") || "current";
422
+ const initialQuery = routeSearchParams.get("query") || "";
423
+ const initialOwnerEmail = routeSearchParams.get("ownerEmail") || "";
424
+ const [sourceId, setSourceId] = useState(initialSourceId);
425
+ const [query, setQuery] = useState(initialQuery);
426
+ const [ownerEmail, setOwnerEmail] = useState(initialOwnerEmail);
422
427
  const [threadId, setThreadId] = useState("");
423
428
  const [submittedSearch, setSubmittedSearch] = useState({
424
- sourceId: "current",
425
- query: "",
426
- ownerEmail: "",
429
+ sourceId: initialSourceId,
430
+ query: initialQuery,
431
+ ownerEmail: initialOwnerEmail,
427
432
  });
428
433
  const [selected, setSelected] = useState<{
429
434
  sourceId: string;