@agent-native/dispatch 0.30.2 → 0.30.5

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.
@@ -3,21 +3,26 @@ import {
3
3
  insertAgentComposerReference,
4
4
  markAgentChatHomeHandoff,
5
5
  readChatFirstMode,
6
+ useActiveAgentChatRunId,
6
7
  } from "@agent-native/core/client/agent-chat";
7
8
  import { appBasePath, appPath } from "@agent-native/core/client/api-path";
9
+ import { writeClipboardText } from "@agent-native/core/client/clipboard";
8
10
  import { useActionQuery } from "@agent-native/core/client/hooks";
9
11
  import { useT } from "@agent-native/core/client/i18n";
12
+ import { IconCheck, IconCopy } from "@tabler/icons-react";
10
13
  import {
11
14
  useCallback,
12
15
  useEffect,
13
16
  useMemo,
14
17
  useRef,
18
+ useState,
15
19
  type ComponentProps,
16
20
  } from "react";
17
21
  import { useLocation, useNavigate } from "react-router";
18
22
 
19
23
  import { ActionQueryError } from "../../components/action-query-error";
20
24
  import { useDispatchExtensions } from "../../components/layout/Layout";
25
+ import { Button } from "../../components/ui/button";
21
26
  import { Skeleton } from "../../components/ui/skeleton";
22
27
  import { submitOverviewPrompt } from "../../lib/overview-chat";
23
28
 
@@ -86,6 +91,46 @@ function DispatchAgentChatSurface(props: DispatchAgentChatSurfaceProps) {
86
91
  return <AgentChatSurface {...props} />;
87
92
  }
88
93
 
94
+ function DispatchRequestIdButton({ requestId }: { requestId: string | null }) {
95
+ const t = useT();
96
+ const [copied, setCopied] = useState(false);
97
+
98
+ const handleCopy = useCallback(() => {
99
+ if (!requestId) return;
100
+ void writeClipboardText(requestId).then((ok) => {
101
+ if (!ok) return;
102
+ setCopied(true);
103
+ window.setTimeout(() => setCopied(false), 1000);
104
+ });
105
+ }, [requestId]);
106
+
107
+ return (
108
+ <Button
109
+ type="button"
110
+ variant="outline"
111
+ size="sm"
112
+ disabled={!requestId}
113
+ onClick={handleCopy}
114
+ aria-label={t("dispatch.pages.copyRequestId", {
115
+ defaultValue: requestId ? "Copy request ID" : "Request ID unavailable",
116
+ })}
117
+ >
118
+ {copied ? (
119
+ <IconCheck aria-hidden="true" />
120
+ ) : (
121
+ <IconCopy aria-hidden="true" />
122
+ )}
123
+ {copied
124
+ ? t("dispatch.pages.copied", { defaultValue: "Copied" })
125
+ : t("dispatch.pages.copyRequestId", {
126
+ defaultValue: requestId
127
+ ? "Copy request ID"
128
+ : "Request ID unavailable",
129
+ })}
130
+ </Button>
131
+ );
132
+ }
133
+
89
134
  interface DispatchChatLocationState {
90
135
  dispatchPrompt?: {
91
136
  id?: string | number;
@@ -109,6 +154,7 @@ export default function ChatRoute() {
109
154
  const location = useLocation();
110
155
  const navigate = useNavigate();
111
156
  const routeThreadId = threadIdFromPath(location.pathname);
157
+ const activeRunId = useActiveAgentChatRunId(routeThreadId);
112
158
  const agentPath = new URLSearchParams(location.search).get("agent");
113
159
  const agentsQuery = useActionQuery<WorkspaceAgentResource[]>(
114
160
  "list-workspace-resources",
@@ -275,6 +321,11 @@ export default function ChatRoute() {
275
321
 
276
322
  return (
277
323
  <div className="flex h-full min-h-0 flex-col bg-background">
324
+ {threadUrlSync.routeThreadId ? (
325
+ <div className="flex justify-end px-4 pt-4 sm:px-6">
326
+ <DispatchRequestIdButton requestId={activeRunId} />
327
+ </div>
328
+ ) : null}
278
329
  <DispatchAgentChatSurface
279
330
  key={agent ? `agent-${agent.id}` : "dispatch"}
280
331
  mode="page"