@agent-native/core 0.84.27 → 0.84.28
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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +17 -2
- package/corpus/core/src/client/agent-chat.ts +118 -0
- package/corpus/core/src/client/index.ts +4 -0
- package/corpus/templates/design/app/components/layout/Header.tsx +16 -23
- package/corpus/templates/design/app/pages/DesignEditor.tsx +23 -9
- package/corpus/templates/design/changelog/2026-07-01-zoom-menus-in-the-design-editor-now-open-independently-from-.md +6 -0
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +14 -2
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +23 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +79 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +8 -8
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.28",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -26,7 +26,9 @@ import {
|
|
|
26
26
|
AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE,
|
|
27
27
|
AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE,
|
|
28
28
|
appendAgentChatContextToMessage,
|
|
29
|
+
claimAgentChatOpenRequest,
|
|
29
30
|
claimAgentChatSubmit,
|
|
31
|
+
drainBufferedAgentChatOpenRequests,
|
|
30
32
|
drainBufferedAgentChatSubmits,
|
|
31
33
|
normalizeAgentChatContextItem,
|
|
32
34
|
parseSubmitChatMessage,
|
|
@@ -2087,11 +2089,12 @@ export function MultiTabAssistantChat({
|
|
|
2087
2089
|
useEffect(() => {
|
|
2088
2090
|
const handleOpenThread = (event: Event) => {
|
|
2089
2091
|
const detail = (event as CustomEvent).detail as
|
|
2090
|
-
| { threadId?: unknown; newThread?: unknown }
|
|
2092
|
+
| { threadId?: unknown; newThread?: unknown; openRequestId?: unknown }
|
|
2091
2093
|
| undefined;
|
|
2092
2094
|
const threadId =
|
|
2093
2095
|
typeof detail?.threadId === "string" ? detail.threadId : "";
|
|
2094
|
-
if (!threadId) return;
|
|
2096
|
+
if (!detail || !threadId) return;
|
|
2097
|
+
if (!claimAgentChatOpenRequest(detail.openRequestId)) return;
|
|
2095
2098
|
|
|
2096
2099
|
if (detail?.newThread === true) {
|
|
2097
2100
|
newThreadIds.current.add(threadId);
|
|
@@ -2143,6 +2146,7 @@ export function MultiTabAssistantChat({
|
|
|
2143
2146
|
const detail = (e as CustomEvent).detail;
|
|
2144
2147
|
const threadId = detail?.threadId;
|
|
2145
2148
|
if (!threadId) return;
|
|
2149
|
+
if (!claimAgentChatOpenRequest(detail.openRequestId)) return;
|
|
2146
2150
|
dismissedSubAgentTabsRef.current.delete(threadId);
|
|
2147
2151
|
// Prefer an explicit parent (RunsTray/background hydration knows it);
|
|
2148
2152
|
// inline task cards fall back to the active orchestrator thread.
|
|
@@ -2196,6 +2200,17 @@ export function MultiTabAssistantChat({
|
|
|
2196
2200
|
return () => window.removeEventListener("agent-task-open", handleOpenTask);
|
|
2197
2201
|
}, [openTabIds, switchThread, refreshThreads, parentMap]);
|
|
2198
2202
|
|
|
2203
|
+
// Replay thread/task opens requested before this lazy panel's listeners
|
|
2204
|
+
// attached. Live events claim their id; replay drains only unclaimed requests.
|
|
2205
|
+
useEffect(() => {
|
|
2206
|
+
const buffered = drainBufferedAgentChatOpenRequests();
|
|
2207
|
+
for (const request of buffered) {
|
|
2208
|
+
window.dispatchEvent(
|
|
2209
|
+
new CustomEvent(request.eventType, { detail: request.detail }),
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2212
|
+
}, []);
|
|
2213
|
+
|
|
2199
2214
|
// Watch for agent-issued chat-command in application-state
|
|
2200
2215
|
const lastChatCommandRef = useRef(0);
|
|
2201
2216
|
useEffect(() => {
|
|
@@ -130,6 +130,26 @@ export interface AgentChatContextState {
|
|
|
130
130
|
updatedAt: number;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
export interface AgentChatOpenThreadRequest {
|
|
134
|
+
threadId: string;
|
|
135
|
+
newThread?: boolean;
|
|
136
|
+
openRequestId?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface AgentChatOpenTaskRequest {
|
|
140
|
+
threadId: string;
|
|
141
|
+
parentThreadId?: string;
|
|
142
|
+
description?: string;
|
|
143
|
+
name?: string;
|
|
144
|
+
openRequestId?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export type BufferedAgentChatOpenRequest = {
|
|
148
|
+
id: string;
|
|
149
|
+
eventType: "agent-chat:open-thread" | "agent-task-open";
|
|
150
|
+
detail: AgentChatOpenThreadRequest | AgentChatOpenTaskRequest;
|
|
151
|
+
};
|
|
152
|
+
|
|
133
153
|
export interface AgentComposerReference {
|
|
134
154
|
label: string;
|
|
135
155
|
icon?: string;
|
|
@@ -243,6 +263,14 @@ const SELF_SUBMIT_BUFFER_TTL_MS = 8000;
|
|
|
243
263
|
const bufferedSelfSubmits: BufferedSelfSubmit[] = [];
|
|
244
264
|
const claimedSubmitIds = new Set<string>();
|
|
245
265
|
|
|
266
|
+
interface BufferedOpenRequest extends BufferedAgentChatOpenRequest {
|
|
267
|
+
at: number;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const OPEN_REQUEST_BUFFER_TTL_MS = 8000;
|
|
271
|
+
const bufferedOpenRequests: BufferedOpenRequest[] = [];
|
|
272
|
+
const claimedOpenRequestIds = new Set<string>();
|
|
273
|
+
|
|
246
274
|
function pruneSelfSubmitBuffer(now: number): void {
|
|
247
275
|
for (let i = bufferedSelfSubmits.length - 1; i >= 0; i -= 1) {
|
|
248
276
|
if (now - bufferedSelfSubmits[i].at > SELF_SUBMIT_BUFFER_TTL_MS) {
|
|
@@ -261,6 +289,32 @@ function bufferSelfSubmit(data: Record<string, unknown>): void {
|
|
|
261
289
|
bufferedSelfSubmits.push({ id, data, at: now });
|
|
262
290
|
}
|
|
263
291
|
|
|
292
|
+
function pruneOpenRequestBuffer(now: number): void {
|
|
293
|
+
for (let i = bufferedOpenRequests.length - 1; i >= 0; i -= 1) {
|
|
294
|
+
if (now - bufferedOpenRequests[i].at > OPEN_REQUEST_BUFFER_TTL_MS) {
|
|
295
|
+
const [removed] = bufferedOpenRequests.splice(i, 1);
|
|
296
|
+
if (removed) claimedOpenRequestIds.delete(removed.id);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function bufferOpenRequest(
|
|
302
|
+
eventType: BufferedAgentChatOpenRequest["eventType"],
|
|
303
|
+
detail: AgentChatOpenThreadRequest | AgentChatOpenTaskRequest,
|
|
304
|
+
): BufferedOpenRequest {
|
|
305
|
+
const now = Date.now();
|
|
306
|
+
pruneOpenRequestBuffer(now);
|
|
307
|
+
const id = `open-${now}-${Math.random().toString(36).slice(2, 8)}`;
|
|
308
|
+
const entry: BufferedOpenRequest = {
|
|
309
|
+
id,
|
|
310
|
+
eventType,
|
|
311
|
+
detail: { ...detail, openRequestId: id },
|
|
312
|
+
at: now,
|
|
313
|
+
};
|
|
314
|
+
bufferedOpenRequests.push(entry);
|
|
315
|
+
return entry;
|
|
316
|
+
}
|
|
317
|
+
|
|
264
318
|
/** Unclaimed self-submit payloads, for the panel to replay once it mounts. */
|
|
265
319
|
export function drainBufferedAgentChatSubmits(): Array<
|
|
266
320
|
Record<string, unknown>
|
|
@@ -279,10 +333,28 @@ export function claimAgentChatSubmit(id: string | undefined): boolean {
|
|
|
279
333
|
return true;
|
|
280
334
|
}
|
|
281
335
|
|
|
336
|
+
/** Unclaimed open-thread/task requests, for the panel to replay once it mounts. */
|
|
337
|
+
export function drainBufferedAgentChatOpenRequests(): BufferedAgentChatOpenRequest[] {
|
|
338
|
+
pruneOpenRequestBuffer(Date.now());
|
|
339
|
+
return bufferedOpenRequests
|
|
340
|
+
.filter((entry) => !claimedOpenRequestIds.has(entry.id))
|
|
341
|
+
.map(({ id, eventType, detail }) => ({ id, eventType, detail }));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Claim an open-thread/task request; false if already handled. Idless events pass. */
|
|
345
|
+
export function claimAgentChatOpenRequest(id: unknown): boolean {
|
|
346
|
+
if (typeof id !== "string" || !id) return true;
|
|
347
|
+
if (claimedOpenRequestIds.has(id)) return false;
|
|
348
|
+
claimedOpenRequestIds.add(id);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
282
352
|
/** Test-only: reset the self-submit buffer and claim set. */
|
|
283
353
|
export function _resetAgentChatSubmitBufferForTests(): void {
|
|
284
354
|
bufferedSelfSubmits.length = 0;
|
|
285
355
|
claimedSubmitIds.clear();
|
|
356
|
+
bufferedOpenRequests.length = 0;
|
|
357
|
+
claimedOpenRequestIds.clear();
|
|
286
358
|
}
|
|
287
359
|
|
|
288
360
|
export function normalizeAgentChatContextItem(
|
|
@@ -638,6 +710,52 @@ function postAgentChatReferenceMessage(
|
|
|
638
710
|
}
|
|
639
711
|
}
|
|
640
712
|
|
|
713
|
+
function openAgentPanelForChat(): void {
|
|
714
|
+
if (typeof window === "undefined") return;
|
|
715
|
+
window.dispatchEvent(
|
|
716
|
+
new CustomEvent("agent-panel:set-mode", {
|
|
717
|
+
detail: { mode: "chat" },
|
|
718
|
+
}),
|
|
719
|
+
);
|
|
720
|
+
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function dispatchBufferedOpenRequest(entry: BufferedOpenRequest): void {
|
|
724
|
+
if (typeof window === "undefined") return;
|
|
725
|
+
const dispatch = () => {
|
|
726
|
+
window.dispatchEvent(
|
|
727
|
+
new CustomEvent(entry.eventType, { detail: entry.detail }),
|
|
728
|
+
);
|
|
729
|
+
};
|
|
730
|
+
setTimeout(dispatch, 0);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
export function requestAgentChatThreadOpen(
|
|
734
|
+
detail: AgentChatOpenThreadRequest,
|
|
735
|
+
): void {
|
|
736
|
+
if (typeof window === "undefined" || !detail.threadId.trim()) return;
|
|
737
|
+
openAgentPanelForChat();
|
|
738
|
+
dispatchBufferedOpenRequest(
|
|
739
|
+
bufferOpenRequest("agent-chat:open-thread", {
|
|
740
|
+
...detail,
|
|
741
|
+
threadId: detail.threadId.trim(),
|
|
742
|
+
}),
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
export function requestAgentTaskOpen(detail: AgentChatOpenTaskRequest): void {
|
|
747
|
+
if (typeof window === "undefined" || !detail.threadId.trim()) return;
|
|
748
|
+
openAgentPanelForChat();
|
|
749
|
+
const parentThreadId = detail.parentThreadId?.trim();
|
|
750
|
+
dispatchBufferedOpenRequest(
|
|
751
|
+
bufferOpenRequest("agent-task-open", {
|
|
752
|
+
...detail,
|
|
753
|
+
threadId: detail.threadId.trim(),
|
|
754
|
+
...(parentThreadId ? { parentThreadId } : {}),
|
|
755
|
+
}),
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
|
|
641
759
|
function isMcpAppChatBridgeEnabled(): boolean {
|
|
642
760
|
if (typeof window === "undefined" || window.parent === window) return false;
|
|
643
761
|
if (readEmbedMcpChatBridgeFlagFromUrl()) markEmbedMcpChatBridgeActive();
|
|
@@ -16,12 +16,16 @@ export {
|
|
|
16
16
|
normalizeAgentComposerReference,
|
|
17
17
|
refreshAgentChatContext,
|
|
18
18
|
removeAgentChatContextItem,
|
|
19
|
+
requestAgentChatThreadOpen,
|
|
20
|
+
requestAgentTaskOpen,
|
|
19
21
|
sendToAgentChat,
|
|
20
22
|
parseSubmitChatMessage,
|
|
21
23
|
setAgentChatContextItem,
|
|
22
24
|
setContextToAgentChat,
|
|
23
25
|
generateTabId,
|
|
24
26
|
type ParsedSubmitChat,
|
|
27
|
+
type AgentChatOpenTaskRequest,
|
|
28
|
+
type AgentChatOpenThreadRequest,
|
|
25
29
|
type AgentChatContextItem,
|
|
26
30
|
type AgentChatContextMessage,
|
|
27
31
|
type AgentChatContextMutationOptions,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
requestAgentChatThreadOpen,
|
|
3
|
+
requestAgentTaskOpen,
|
|
4
|
+
useActionQuery,
|
|
5
|
+
useT,
|
|
6
|
+
} from "@agent-native/core/client";
|
|
2
7
|
import { AgentToggleButton } from "@agent-native/core/client";
|
|
3
8
|
import { RunsTray } from "@agent-native/core/client/progress";
|
|
4
9
|
import { useCallback } from "react";
|
|
@@ -50,12 +55,6 @@ export function Header() {
|
|
|
50
55
|
const actions = useHeaderActions();
|
|
51
56
|
const openRunThread = useCallback(
|
|
52
57
|
(threadId: string, run?: HeaderAgentRun) => {
|
|
53
|
-
window.dispatchEvent(
|
|
54
|
-
new CustomEvent("agent-panel:set-mode", {
|
|
55
|
-
detail: { mode: "chat" },
|
|
56
|
-
}),
|
|
57
|
-
);
|
|
58
|
-
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
59
58
|
const metadata = run?.metadata ?? {};
|
|
60
59
|
const parentThreadId =
|
|
61
60
|
typeof metadata.parentThreadId === "string"
|
|
@@ -64,24 +63,18 @@ export function Header() {
|
|
|
64
63
|
const isAgentTeam =
|
|
65
64
|
metadata.kind === "agent-team" || metadata.source === "agent-teams";
|
|
66
65
|
if (isAgentTeam && parentThreadId && parentThreadId !== threadId) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
description
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
name: typeof metadata.name === "string" ? metadata.name : "",
|
|
77
|
-
},
|
|
78
|
-
}),
|
|
79
|
-
);
|
|
66
|
+
requestAgentTaskOpen({
|
|
67
|
+
threadId,
|
|
68
|
+
parentThreadId,
|
|
69
|
+
description:
|
|
70
|
+
typeof metadata.description === "string"
|
|
71
|
+
? metadata.description
|
|
72
|
+
: run?.title || "",
|
|
73
|
+
name: typeof metadata.name === "string" ? metadata.name : "",
|
|
74
|
+
});
|
|
80
75
|
return;
|
|
81
76
|
}
|
|
82
|
-
|
|
83
|
-
new CustomEvent("agent-chat:open-thread", { detail: { threadId } }),
|
|
84
|
-
);
|
|
77
|
+
requestAgentChatThreadOpen({ threadId });
|
|
85
78
|
},
|
|
86
79
|
[],
|
|
87
80
|
);
|
|
@@ -15617,11 +15617,13 @@ ${serializedHtml}
|
|
|
15617
15617
|
);
|
|
15618
15618
|
|
|
15619
15619
|
const zoomLabel = `${Math.round(zoom)}%`;
|
|
15620
|
-
const [
|
|
15620
|
+
const [openZoomControl, setOpenZoomControl] = useState<
|
|
15621
|
+
"toolbar" | "inspector" | null
|
|
15622
|
+
>(null);
|
|
15621
15623
|
const [zoomInputValue, setZoomInputValue] = useState(zoomLabel);
|
|
15622
15624
|
useEffect(() => {
|
|
15623
|
-
if (!
|
|
15624
|
-
}, [zoomLabel,
|
|
15625
|
+
if (!openZoomControl) setZoomInputValue(zoomLabel);
|
|
15626
|
+
}, [zoomLabel, openZoomControl]);
|
|
15625
15627
|
const commitZoomInput = useCallback(() => {
|
|
15626
15628
|
const next = Number(zoomInputValue.replace("%", "").trim());
|
|
15627
15629
|
if (!Number.isFinite(next)) {
|
|
@@ -15629,7 +15631,7 @@ ${serializedHtml}
|
|
|
15629
15631
|
return;
|
|
15630
15632
|
}
|
|
15631
15633
|
setZoom(Math.max(10, Math.min(500, next)));
|
|
15632
|
-
|
|
15634
|
+
setOpenZoomControl(null);
|
|
15633
15635
|
}, [setZoom, zoomInputValue, zoomLabel]);
|
|
15634
15636
|
|
|
15635
15637
|
const handleTokensApplied = useCallback(
|
|
@@ -15970,8 +15972,20 @@ ${serializedHtml}
|
|
|
15970
15972
|
</span>
|
|
15971
15973
|
);
|
|
15972
15974
|
|
|
15973
|
-
const renderZoomControl = () => (
|
|
15974
|
-
<DropdownMenu
|
|
15975
|
+
const renderZoomControl = (controlId: "toolbar" | "inspector") => (
|
|
15976
|
+
<DropdownMenu
|
|
15977
|
+
open={openZoomControl === controlId}
|
|
15978
|
+
onOpenChange={(open) => {
|
|
15979
|
+
if (open) {
|
|
15980
|
+
setZoomInputValue(zoomLabel);
|
|
15981
|
+
setOpenZoomControl(controlId);
|
|
15982
|
+
return;
|
|
15983
|
+
}
|
|
15984
|
+
setOpenZoomControl((current) =>
|
|
15985
|
+
current === controlId ? null : current,
|
|
15986
|
+
);
|
|
15987
|
+
}}
|
|
15988
|
+
>
|
|
15975
15989
|
<Tooltip>
|
|
15976
15990
|
<TooltipTrigger asChild>
|
|
15977
15991
|
<DropdownMenuTrigger asChild>
|
|
@@ -16005,7 +16019,7 @@ ${serializedHtml}
|
|
|
16005
16019
|
} else if (event.key === "Escape") {
|
|
16006
16020
|
event.preventDefault();
|
|
16007
16021
|
setZoomInputValue(zoomLabel);
|
|
16008
|
-
|
|
16022
|
+
setOpenZoomControl(null);
|
|
16009
16023
|
}
|
|
16010
16024
|
}}
|
|
16011
16025
|
className="h-10 rounded-md border-[var(--design-editor-accent-color)] bg-[var(--design-editor-control-bg)] px-3 text-base font-medium tabular-nums text-foreground shadow-none focus-visible:ring-2 focus-visible:ring-[var(--design-editor-accent-color)]"
|
|
@@ -16563,7 +16577,7 @@ ${serializedHtml}
|
|
|
16563
16577
|
</DropdownMenuContent>
|
|
16564
16578
|
</DropdownMenu>
|
|
16565
16579
|
|
|
16566
|
-
{renderZoomControl()}
|
|
16580
|
+
{renderZoomControl("toolbar")}
|
|
16567
16581
|
|
|
16568
16582
|
<div className="mx-1 h-5 w-px bg-border" />
|
|
16569
16583
|
</>
|
|
@@ -17637,7 +17651,7 @@ ${serializedHtml}
|
|
|
17637
17651
|
selectedElements={selectedInspectorElements}
|
|
17638
17652
|
pageStyles={pageStyles}
|
|
17639
17653
|
zoom={zoom}
|
|
17640
|
-
headerTrailing={renderZoomControl()}
|
|
17654
|
+
headerTrailing={renderZoomControl("inspector")}
|
|
17641
17655
|
width={rightSidebarWidth}
|
|
17642
17656
|
activeTab={activeInspectorTab}
|
|
17643
17657
|
onActiveTabChange={setActiveInspectorTab}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiTabAssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/MultiTabAssistantChat.tsx"],"names":[],"mappings":"AASA,OAAO,KAMN,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MultiTabAssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/MultiTabAssistantChat.tsx"],"names":[],"mappings":"AASA,OAAO,KAMN,MAAM,OAAO,CAAC;AAsBf,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAoB5B,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AA8mB/B,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsGD,MAAM,WAAW,wBAAwB;IACvC,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CACpE;AAyED,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,+BAA+B;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,kBAAkB,EAClB,OAAO,GAAG,UAAU,CACrB,GAAG;IACF,sCAAsC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5E,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7E,sGAAsG;IACtG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,wBAAwB,CAAC;IACnD;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EACpC,UAAiB,EACjB,YAAY,EACZ,aAAa,EACb,aAAqB,EACrB,MAAqD,EACrD,UAAU,EACV,mBAA0B,EAC1B,YAAY,EACZ,aAAqB,EACrB,KAAY,EACZ,cAAqB,EACrB,GAAG,KAAK,EACT,EAAE,0BAA0B,qBA6wD5B"}
|
|
@@ -3,7 +3,7 @@ import { IconX, IconPlus, IconHistory, IconSearch, IconLink, IconLinkOff, IconCh
|
|
|
3
3
|
import { useState, useRef, useEffect, useCallback, useMemo, } from "react";
|
|
4
4
|
import { DEFAULT_MODEL } from "../agent/default-model.js";
|
|
5
5
|
import { getReasoningEffortOptionsForModel, isReasoningEffort, } from "../shared/reasoning-effort.js";
|
|
6
|
-
import { AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE, appendAgentChatContextToMessage, claimAgentChatSubmit, drainBufferedAgentChatSubmits, normalizeAgentChatContextItem, parseSubmitChatMessage, } from "./agent-chat.js";
|
|
6
|
+
import { AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE, appendAgentChatContextToMessage, claimAgentChatOpenRequest, claimAgentChatSubmit, drainBufferedAgentChatOpenRequests, drainBufferedAgentChatSubmits, normalizeAgentChatContextItem, parseSubmitChatMessage, } from "./agent-chat.js";
|
|
7
7
|
import { agentNativePath, appPath } from "./api-path.js";
|
|
8
8
|
import { AssistantChat, } from "./AssistantChat.js";
|
|
9
9
|
import { buildChatModelGroups, } from "./chat-model-groups.js";
|
|
@@ -1402,7 +1402,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1402
1402
|
const handleOpenThread = (event) => {
|
|
1403
1403
|
const detail = event.detail;
|
|
1404
1404
|
const threadId = typeof detail?.threadId === "string" ? detail.threadId : "";
|
|
1405
|
-
if (!threadId)
|
|
1405
|
+
if (!detail || !threadId)
|
|
1406
|
+
return;
|
|
1407
|
+
if (!claimAgentChatOpenRequest(detail.openRequestId))
|
|
1406
1408
|
return;
|
|
1407
1409
|
if (detail?.newThread === true) {
|
|
1408
1410
|
newThreadIds.current.add(threadId);
|
|
@@ -1445,6 +1447,8 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1445
1447
|
const threadId = detail?.threadId;
|
|
1446
1448
|
if (!threadId)
|
|
1447
1449
|
return;
|
|
1450
|
+
if (!claimAgentChatOpenRequest(detail.openRequestId))
|
|
1451
|
+
return;
|
|
1448
1452
|
dismissedSubAgentTabsRef.current.delete(threadId);
|
|
1449
1453
|
// Prefer an explicit parent (RunsTray/background hydration knows it);
|
|
1450
1454
|
// inline task cards fall back to the active orchestrator thread.
|
|
@@ -1490,6 +1494,14 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1490
1494
|
window.addEventListener("agent-task-open", handleOpenTask);
|
|
1491
1495
|
return () => window.removeEventListener("agent-task-open", handleOpenTask);
|
|
1492
1496
|
}, [openTabIds, switchThread, refreshThreads, parentMap]);
|
|
1497
|
+
// Replay thread/task opens requested before this lazy panel's listeners
|
|
1498
|
+
// attached. Live events claim their id; replay drains only unclaimed requests.
|
|
1499
|
+
useEffect(() => {
|
|
1500
|
+
const buffered = drainBufferedAgentChatOpenRequests();
|
|
1501
|
+
for (const request of buffered) {
|
|
1502
|
+
window.dispatchEvent(new CustomEvent(request.eventType, { detail: request.detail }));
|
|
1503
|
+
}
|
|
1504
|
+
}, []);
|
|
1493
1505
|
// Watch for agent-issued chat-command in application-state
|
|
1494
1506
|
const lastChatCommandRef = useRef(0);
|
|
1495
1507
|
useEffect(() => {
|