@agent-native/core 0.32.2 → 0.32.17
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/README.md +3 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +48 -10
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +12 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +104 -6
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/cli/app-skill.js +2 -2
- package/dist/cli/app-skill.js.map +1 -1
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +6 -1
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-output-smoother.d.ts +7 -0
- package/dist/cli/code-agent-output-smoother.d.ts.map +1 -0
- package/dist/cli/code-agent-output-smoother.js +111 -0
- package/dist/cli/code-agent-output-smoother.js.map +1 -0
- package/dist/cli/connect.d.ts.map +1 -1
- package/dist/cli/connect.js +5 -0
- package/dist/cli/connect.js.map +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +17 -42
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/skills.d.ts +23 -2
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +405 -41
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +7 -105
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +41 -7
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +0 -28
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +8 -23
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +359 -205
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +254 -14
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +14 -9
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +24 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +73 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/assistant-ui-recovery.d.ts +34 -0
- package/dist/client/assistant-ui-recovery.d.ts.map +1 -0
- package/dist/client/assistant-ui-recovery.js +122 -0
- package/dist/client/assistant-ui-recovery.js.map +1 -0
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +7 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +7 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +22 -2
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +6 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts +13 -3
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +105 -36
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/route-warmup.d.ts +61 -0
- package/dist/client/route-warmup.d.ts.map +1 -0
- package/dist/client/route-warmup.js +456 -0
- package/dist/client/route-warmup.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +2 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +5 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +10 -4
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/use-action.d.ts +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +22 -4
- package/dist/client/use-action.js.map +1 -1
- package/dist/code-agents/background-run.d.ts +2 -0
- package/dist/code-agents/background-run.d.ts.map +1 -1
- package/dist/code-agents/background-run.js.map +1 -1
- package/dist/db/client.d.ts +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +25 -1
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts +4 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +171 -14
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/immutable-assets.d.ts +1 -0
- package/dist/deploy/immutable-assets.d.ts.map +1 -1
- package/dist/deploy/immutable-assets.js +1 -0
- package/dist/deploy/immutable-assets.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +118 -82
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/progress/routes.d.ts.map +1 -1
- package/dist/progress/routes.js +1 -0
- package/dist/progress/routes.js.map +1 -1
- package/dist/progress/store.d.ts +13 -0
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +18 -0
- package/dist/progress/store.js.map +1 -1
- package/dist/progress/types.d.ts +2 -0
- package/dist/progress/types.d.ts.map +1 -1
- package/dist/progress/types.js.map +1 -1
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts +2 -2
- package/dist/scripts/db/wipe-leaked-builder-keys.d.ts.map +1 -1
- package/dist/scripts/db/wipe-leaked-builder-keys.js +14 -3
- package/dist/scripts/db/wipe-leaked-builder-keys.js.map +1 -1
- package/dist/server/action-routes.d.ts +1 -0
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +36 -2
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +123 -25
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +14 -1
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams-run-queue.d.ts +80 -0
- package/dist/server/agent-teams-run-queue.d.ts.map +1 -0
- package/dist/server/agent-teams-run-queue.js +208 -0
- package/dist/server/agent-teams-run-queue.js.map +1 -0
- package/dist/server/agent-teams.d.ts +67 -0
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +607 -180
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +0 -64
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +67 -14
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts +12 -2
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +24 -0
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +66 -5
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +10 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +82 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/csrf.js +3 -0
- package/dist/server/csrf.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +1 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +14 -1
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/self-dispatch.d.ts +44 -0
- package/dist/server/self-dispatch.d.ts.map +1 -0
- package/dist/server/self-dispatch.js +113 -0
- package/dist/server/self-dispatch.js.map +1 -0
- package/dist/server/social-og-image.d.ts +14 -0
- package/dist/server/social-og-image.d.ts.map +1 -0
- package/dist/server/social-og-image.js +251 -0
- package/dist/server/social-og-image.js.map +1 -0
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +27 -11
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/shared/cache-control.d.ts +7 -0
- package/dist/shared/cache-control.d.ts.map +1 -1
- package/dist/shared/cache-control.js +7 -0
- package/dist/shared/cache-control.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/route-warmup-config.d.ts +28 -0
- package/dist/shared/route-warmup-config.d.ts.map +1 -0
- package/dist/shared/route-warmup-config.js +58 -0
- package/dist/shared/route-warmup-config.js.map +1 -0
- package/dist/shared/social-meta.d.ts +5 -0
- package/dist/shared/social-meta.d.ts.map +1 -1
- package/dist/shared/social-meta.js +36 -2
- package/dist/shared/social-meta.js.map +1 -1
- package/dist/shared/streaming-text-smoothing.d.ts +12 -0
- package/dist/shared/streaming-text-smoothing.d.ts.map +1 -0
- package/dist/shared/streaming-text-smoothing.js +52 -0
- package/dist/shared/streaming-text-smoothing.js.map +1 -0
- package/dist/styles/agent-native.css +4 -4
- package/dist/templates/default/AGENTS.md +9 -4
- package/dist/templates/default/DEVELOPING.md +15 -1
- package/dist/templates/workspace-core/AGENTS.md +7 -3
- package/dist/templates/workspace-root/AGENTS.md +7 -3
- package/dist/vite/client.d.ts +13 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +26 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js.map +1 -1
- package/docs/content/client.md +62 -1
- package/docs/content/code-agents-ui.md +6 -13
- package/docs/content/context-awareness.md +186 -21
- package/docs/content/deployment.md +8 -11
- package/docs/content/dispatch.md +1 -1
- package/docs/content/external-agents.md +32 -2
- package/docs/content/migration-workbench.md +4 -21
- package/docs/content/multi-app-workspace.md +1 -1
- package/docs/content/recurring-jobs.md +1 -1
- package/docs/content/security.md +0 -1
- package/docs/content/sharing.md +1 -3
- package/docs/content/skills-guide.md +12 -10
- package/docs/content/template-assets.md +21 -1
- package/docs/content/template-design.md +23 -5
- package/docs/content/template-dispatch.md +1 -1
- package/package.json +2 -1
- package/src/templates/default/AGENTS.md +9 -4
- package/src/templates/default/DEVELOPING.md +15 -1
- package/src/templates/workspace-core/AGENTS.md +7 -3
- package/src/templates/workspace-root/AGENTS.md +7 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiTabAssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/MultiTabAssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAUf,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAc5B,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"MultiTabAssistantChat.d.ts","sourceRoot":"","sources":["../../src/client/MultiTabAssistantChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAUf,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAc5B,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AA8nB/B,UAAU,OAAO;IACf,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;AA4ED,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;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EACpC,UAAiB,EACjB,YAAY,EACZ,aAAa,EACb,aAAqB,EACrB,MAAqD,EACrD,UAAU,EACV,mBAA0B,EAC1B,YAAY,EACZ,KAAY,EACZ,GAAG,KAAK,EACT,EAAE,0BAA0B,2CAykD5B"}
|
|
@@ -11,6 +11,7 @@ import { agentNativePath } from "./api-path.js";
|
|
|
11
11
|
import { RunStuckBanner } from "./RunStuckBanner.js";
|
|
12
12
|
import { DEFAULT_MODEL } from "../agent/default-model.js";
|
|
13
13
|
import { getReasoningEffortOptionsForModel, isReasoningEffort, } from "../shared/reasoning-effort.js";
|
|
14
|
+
import { appendAgentChatContextToMessage, normalizeAgentChatContextItem, } from "./agent-chat.js";
|
|
14
15
|
const MODEL_SELECTION_STORAGE_KEY = "agent-native:chat-models:selection";
|
|
15
16
|
function readStoredModelSelection(key) {
|
|
16
17
|
if (typeof window === "undefined")
|
|
@@ -266,6 +267,41 @@ function HelpPopover({ onClose }) {
|
|
|
266
267
|
];
|
|
267
268
|
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40", onClick: onClose }), _jsxs("div", { className: "absolute right-2 top-0 z-50 w-72 rounded-lg border border-border bg-popover shadow-lg", children: [_jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-border", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: "Available Commands" }), _jsx("button", { onClick: onClose, "aria-label": "Close help", className: "flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:text-foreground", children: _jsx(IconX, { size: 12 }) })] }), _jsx("div", { className: "py-1", children: commands.map((cmd) => (_jsxs("div", { className: "px-3 py-1.5", children: [_jsx("div", { className: "text-xs font-medium text-foreground", children: cmd.name }), _jsx("div", { className: "text-[11px] text-muted-foreground", children: cmd.description })] }, cmd.name))) })] })] }));
|
|
268
269
|
}
|
|
270
|
+
function readString(value) {
|
|
271
|
+
return typeof value === "string" ? value.trim() : "";
|
|
272
|
+
}
|
|
273
|
+
function isActiveAgentTeamStatus(status) {
|
|
274
|
+
return (status === "queued" ||
|
|
275
|
+
status === "running" ||
|
|
276
|
+
status === "paused" ||
|
|
277
|
+
status === "needs-approval");
|
|
278
|
+
}
|
|
279
|
+
function chatTabStatusFromAgentTeamStatus(status) {
|
|
280
|
+
if (!status)
|
|
281
|
+
return undefined;
|
|
282
|
+
return isActiveAgentTeamStatus(status) ? "running" : "completed";
|
|
283
|
+
}
|
|
284
|
+
function runToAgentTeamTabInfo(run) {
|
|
285
|
+
if (run.sourceRecord?.type && run.sourceRecord.type !== "agent-team-task") {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const metadata = run.metadata ?? {};
|
|
289
|
+
const threadId = readString(run.sourceRecord?.threadId) || readString(metadata.threadId);
|
|
290
|
+
const parentThreadId = readString(run.sourceRecord?.parentThreadId) ||
|
|
291
|
+
readString(metadata.parentThreadId);
|
|
292
|
+
if (!threadId || !parentThreadId || threadId === parentThreadId)
|
|
293
|
+
return null;
|
|
294
|
+
const name = readString(run.sourceRecord?.name) ||
|
|
295
|
+
readString(metadata.name) ||
|
|
296
|
+
readString(run.title) ||
|
|
297
|
+
"Sub-agent";
|
|
298
|
+
return {
|
|
299
|
+
threadId,
|
|
300
|
+
parentThreadId,
|
|
301
|
+
name,
|
|
302
|
+
status: run.status ?? "unknown",
|
|
303
|
+
};
|
|
304
|
+
}
|
|
269
305
|
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, scope = null, ...props }) {
|
|
270
306
|
const { threads, activeThreadId, isLoading, createThread, switchThread, detachThread, forkThread, saveThreadData, generateTitle, searchThreads, refreshThreads, isNewThread, } = useChatThreads(apiUrl, storageKey, scope, { restoreActiveThread });
|
|
271
307
|
// Namespace all localStorage keys by storageKey when provided (for per-app isolation in frame)
|
|
@@ -280,6 +316,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
280
316
|
mountedTabsRef.current.add(activeThreadId);
|
|
281
317
|
const chatRefs = useRef(new Map());
|
|
282
318
|
const pendingSends = useRef(new Map());
|
|
319
|
+
const pendingContextItems = useRef(new Map());
|
|
283
320
|
const [runningThreads, setRunningThreads] = useState(new Set());
|
|
284
321
|
const [showHistory, setShowHistory] = useState(false);
|
|
285
322
|
const newThreadIds = useRef(new Set());
|
|
@@ -296,6 +333,19 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
296
333
|
setModelSelectionVersion((version) => version + 1);
|
|
297
334
|
}, []);
|
|
298
335
|
const postMessageSubmissionsDisabled = props.composerDisabled === true;
|
|
336
|
+
const setContextInTab = useCallback((threadId, item) => {
|
|
337
|
+
const ref = chatRefs.current.get(threadId);
|
|
338
|
+
if (ref) {
|
|
339
|
+
ref.setComposerContextItem(item);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const existing = pendingContextItems.current.get(threadId) ?? [];
|
|
343
|
+
const index = existing.findIndex((current) => current.key === item.key);
|
|
344
|
+
const next = index === -1
|
|
345
|
+
? [...existing, item]
|
|
346
|
+
: existing.map((current, currentIndex) => currentIndex === index ? item : current);
|
|
347
|
+
pendingContextItems.current.set(threadId, next);
|
|
348
|
+
}, []);
|
|
299
349
|
const resolveThreadModelSelection = useCallback((threadId) => resolveModelSelection(threadModelRef.current.get(threadId) ?? persistedModelSelection, availableModels), [availableModels, persistedModelSelection, modelSelectionVersion]);
|
|
300
350
|
const persistModelSelection = useCallback((selection) => {
|
|
301
351
|
setPersistedModelSelection(selection);
|
|
@@ -459,6 +509,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
459
509
|
catch { }
|
|
460
510
|
return {};
|
|
461
511
|
});
|
|
512
|
+
const parentMapRef = useRef(parentMap);
|
|
513
|
+
parentMapRef.current = parentMap;
|
|
514
|
+
const dismissedSubAgentTabsRef = useRef(new Set());
|
|
462
515
|
// Persist parent map to localStorage
|
|
463
516
|
useEffect(() => {
|
|
464
517
|
try {
|
|
@@ -478,6 +531,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
478
531
|
catch { }
|
|
479
532
|
return {};
|
|
480
533
|
});
|
|
534
|
+
const subAgentNamesRef = useRef(subAgentNames);
|
|
535
|
+
subAgentNamesRef.current = subAgentNames;
|
|
536
|
+
const [subAgentStatuses, setSubAgentStatuses] = useState({});
|
|
481
537
|
useEffect(() => {
|
|
482
538
|
try {
|
|
483
539
|
localStorage.setItem(SUB_AGENT_NAMES_KEY, JSON.stringify(subAgentNames));
|
|
@@ -511,6 +567,8 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
511
567
|
catch { }
|
|
512
568
|
return [];
|
|
513
569
|
});
|
|
570
|
+
const openTabIdsRef = useRef(openTabIds);
|
|
571
|
+
openTabIdsRef.current = openTabIds;
|
|
514
572
|
const initializedRef = useRef(false);
|
|
515
573
|
// Rehydrate open tabs when the scope flips. Mirrors `persistedKeyRef` in
|
|
516
574
|
// `useChatThreads`: on a scope change we need to read the new key BEFORE
|
|
@@ -677,6 +735,107 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
677
735
|
});
|
|
678
736
|
}
|
|
679
737
|
}, [isLoading, openTabIds, activeThreadId, createThread]);
|
|
738
|
+
useEffect(() => {
|
|
739
|
+
let stopped = false;
|
|
740
|
+
let timer = null;
|
|
741
|
+
const runsUrl = `${apiUrl.replace(/\/$/, "")}/runs/list?goalId=agent-team`;
|
|
742
|
+
async function hydrateAgentTeamTabs() {
|
|
743
|
+
try {
|
|
744
|
+
const res = await fetch(runsUrl);
|
|
745
|
+
if (res.ok) {
|
|
746
|
+
const data = (await res.json());
|
|
747
|
+
const infos = Array.isArray(data.runs)
|
|
748
|
+
? data.runs
|
|
749
|
+
.map(runToAgentTeamTabInfo)
|
|
750
|
+
.filter((info) => Boolean(info))
|
|
751
|
+
: [];
|
|
752
|
+
setSubAgentStatuses((prev) => {
|
|
753
|
+
let changed = false;
|
|
754
|
+
const next = {};
|
|
755
|
+
for (const info of infos) {
|
|
756
|
+
next[info.threadId] = info.status;
|
|
757
|
+
if (prev[info.threadId] !== info.status)
|
|
758
|
+
changed = true;
|
|
759
|
+
}
|
|
760
|
+
if (Object.keys(prev).length !== Object.keys(next).length) {
|
|
761
|
+
changed = true;
|
|
762
|
+
}
|
|
763
|
+
return changed ? next : prev;
|
|
764
|
+
});
|
|
765
|
+
const openSet = new Set(openTabIdsRef.current);
|
|
766
|
+
const candidates = infos.filter((info) => !dismissedSubAgentTabsRef.current.has(info.threadId) &&
|
|
767
|
+
(openSet.has(info.parentThreadId) || openSet.has(info.threadId)));
|
|
768
|
+
if (candidates.length > 0) {
|
|
769
|
+
const shouldRefreshThreads = candidates.some((info) => !openSet.has(info.threadId) && openSet.has(info.parentThreadId));
|
|
770
|
+
const candidateParents = new Map(candidates.map((info) => [info.threadId, info.parentThreadId]));
|
|
771
|
+
setParentMap((prev) => {
|
|
772
|
+
let next = prev;
|
|
773
|
+
for (const info of candidates) {
|
|
774
|
+
if (next[info.threadId] === info.parentThreadId)
|
|
775
|
+
continue;
|
|
776
|
+
next =
|
|
777
|
+
next === prev
|
|
778
|
+
? { ...prev, [info.threadId]: info.parentThreadId }
|
|
779
|
+
: { ...next, [info.threadId]: info.parentThreadId };
|
|
780
|
+
}
|
|
781
|
+
return next;
|
|
782
|
+
});
|
|
783
|
+
setSubAgentNames((prev) => {
|
|
784
|
+
let next = prev;
|
|
785
|
+
for (const info of candidates) {
|
|
786
|
+
if (!info.name || next[info.threadId] === info.name)
|
|
787
|
+
continue;
|
|
788
|
+
next =
|
|
789
|
+
next === prev
|
|
790
|
+
? { ...prev, [info.threadId]: info.name }
|
|
791
|
+
: { ...next, [info.threadId]: info.name };
|
|
792
|
+
}
|
|
793
|
+
return next;
|
|
794
|
+
});
|
|
795
|
+
setOpenTabIds((prev) => {
|
|
796
|
+
let next = prev;
|
|
797
|
+
for (const info of candidates) {
|
|
798
|
+
if (next.includes(info.threadId))
|
|
799
|
+
continue;
|
|
800
|
+
const parentIdx = next.indexOf(info.parentThreadId);
|
|
801
|
+
if (parentIdx === -1)
|
|
802
|
+
continue;
|
|
803
|
+
if (next === prev)
|
|
804
|
+
next = [...prev];
|
|
805
|
+
let insertIdx = parentIdx + 1;
|
|
806
|
+
while (insertIdx < next.length) {
|
|
807
|
+
const siblingParent = parentMapRef.current[next[insertIdx]] ||
|
|
808
|
+
candidateParents.get(next[insertIdx]);
|
|
809
|
+
if (siblingParent !== info.parentThreadId)
|
|
810
|
+
break;
|
|
811
|
+
insertIdx++;
|
|
812
|
+
}
|
|
813
|
+
next.splice(insertIdx, 0, info.threadId);
|
|
814
|
+
}
|
|
815
|
+
return next;
|
|
816
|
+
});
|
|
817
|
+
if (shouldRefreshThreads) {
|
|
818
|
+
void refreshThreads();
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
catch {
|
|
824
|
+
// Best effort: task cards and manual history still work if this poll fails.
|
|
825
|
+
}
|
|
826
|
+
finally {
|
|
827
|
+
if (!stopped) {
|
|
828
|
+
timer = setTimeout(hydrateAgentTeamTabs, 3000);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
hydrateAgentTeamTabs();
|
|
833
|
+
return () => {
|
|
834
|
+
stopped = true;
|
|
835
|
+
if (timer)
|
|
836
|
+
clearTimeout(timer);
|
|
837
|
+
};
|
|
838
|
+
}, [apiUrl, refreshThreads]);
|
|
680
839
|
// Focus the composer when switching tabs
|
|
681
840
|
useEffect(() => {
|
|
682
841
|
if (!activeThreadId)
|
|
@@ -730,6 +889,22 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
730
889
|
const handler = (event) => {
|
|
731
890
|
if (!isTrustedFrameMessage(event))
|
|
732
891
|
return;
|
|
892
|
+
if (event.data?.type === "agentNative.setChatContext") {
|
|
893
|
+
const item = normalizeAgentChatContextItem(event.data.data);
|
|
894
|
+
if (!item)
|
|
895
|
+
return;
|
|
896
|
+
const openSidebar = event.data.data?.openSidebar;
|
|
897
|
+
if (openSidebar !== false) {
|
|
898
|
+
window.dispatchEvent(new CustomEvent("agent-panel:open"));
|
|
899
|
+
}
|
|
900
|
+
if (postMessageSubmissionsDisabled)
|
|
901
|
+
return;
|
|
902
|
+
const currentTabId = activeThreadIdRef.current;
|
|
903
|
+
if (!currentTabId)
|
|
904
|
+
return;
|
|
905
|
+
setContextInTab(currentTabId, item);
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
733
908
|
if (event.data?.type !== "agentNative.submitChat")
|
|
734
909
|
return;
|
|
735
910
|
const message = event.data.data?.message;
|
|
@@ -743,6 +918,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
743
918
|
const tabId = event.data.data?.tabId;
|
|
744
919
|
const requestedTabId = typeof tabId === "string" ? tabId : undefined;
|
|
745
920
|
const background = event.data.data?.background;
|
|
921
|
+
const submit = event.data.data?.submit !== false;
|
|
746
922
|
const rawImages = event.data.data?.images;
|
|
747
923
|
const images = Array.isArray(rawImages)
|
|
748
924
|
? rawImages.filter((image) => typeof image === "string" && image.length > 0)
|
|
@@ -757,7 +933,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
757
933
|
// Plan mode is sent as request metadata by the chat adapter. Keep the
|
|
758
934
|
// user-visible message clean so mode instructions never enter history.
|
|
759
935
|
const fullMessage = context
|
|
760
|
-
?
|
|
936
|
+
? appendAgentChatContextToMessage(message, context)
|
|
761
937
|
: message;
|
|
762
938
|
const sendToTab = (threadId) => {
|
|
763
939
|
// If a model override was specified, apply it only if we recognize it
|
|
@@ -780,10 +956,19 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
780
956
|
}
|
|
781
957
|
const ref = chatRefs.current.get(threadId);
|
|
782
958
|
if (ref) {
|
|
783
|
-
|
|
959
|
+
if (submit) {
|
|
960
|
+
ref.sendMessage(fullMessage, images);
|
|
961
|
+
}
|
|
962
|
+
else {
|
|
963
|
+
ref.prefillMessage(fullMessage);
|
|
964
|
+
}
|
|
784
965
|
}
|
|
785
966
|
else {
|
|
786
|
-
pendingSends.current.set(threadId, {
|
|
967
|
+
pendingSends.current.set(threadId, {
|
|
968
|
+
message: fullMessage,
|
|
969
|
+
images,
|
|
970
|
+
submit,
|
|
971
|
+
});
|
|
787
972
|
}
|
|
788
973
|
};
|
|
789
974
|
if (newTab) {
|
|
@@ -812,15 +997,37 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
812
997
|
bumpModelSelectionVersion,
|
|
813
998
|
createThread,
|
|
814
999
|
postMessageSubmissionsDisabled,
|
|
1000
|
+
setContextInTab,
|
|
815
1001
|
switchThread,
|
|
816
1002
|
]);
|
|
817
1003
|
// Process pending sends when refs mount
|
|
818
1004
|
useEffect(() => {
|
|
819
|
-
|
|
1005
|
+
const pendingTabIds = new Set([
|
|
1006
|
+
...pendingSends.current.keys(),
|
|
1007
|
+
...pendingContextItems.current.keys(),
|
|
1008
|
+
]);
|
|
1009
|
+
for (const tabId of pendingTabIds) {
|
|
820
1010
|
const ref = chatRefs.current.get(tabId);
|
|
821
1011
|
if (ref) {
|
|
822
|
-
|
|
823
|
-
|
|
1012
|
+
const pendingContext = pendingContextItems.current.get(tabId);
|
|
1013
|
+
if (pendingContext) {
|
|
1014
|
+
for (const item of pendingContext) {
|
|
1015
|
+
ref.setComposerContextItem(item);
|
|
1016
|
+
}
|
|
1017
|
+
pendingContextItems.current.delete(tabId);
|
|
1018
|
+
}
|
|
1019
|
+
const pending = pendingSends.current.get(tabId);
|
|
1020
|
+
if (pending) {
|
|
1021
|
+
setTimeout(() => {
|
|
1022
|
+
if (pending.submit) {
|
|
1023
|
+
ref.sendMessage(pending.message, pending.images);
|
|
1024
|
+
}
|
|
1025
|
+
else {
|
|
1026
|
+
ref.prefillMessage(pending.message);
|
|
1027
|
+
}
|
|
1028
|
+
}, 50);
|
|
1029
|
+
pendingSends.current.delete(tabId);
|
|
1030
|
+
}
|
|
824
1031
|
}
|
|
825
1032
|
}
|
|
826
1033
|
}, [openTabIds]);
|
|
@@ -854,6 +1061,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
854
1061
|
}
|
|
855
1062
|
}, [createThread]);
|
|
856
1063
|
const closeTab = useCallback((tabId) => {
|
|
1064
|
+
if (parentMapRef.current[tabId]) {
|
|
1065
|
+
dismissedSubAgentTabsRef.current.add(tabId);
|
|
1066
|
+
}
|
|
857
1067
|
setOpenTabIds((prev) => {
|
|
858
1068
|
if (prev.length <= 1) {
|
|
859
1069
|
// Last tab — create a new one and replace the old tab atomically
|
|
@@ -874,6 +1084,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
874
1084
|
});
|
|
875
1085
|
chatRefs.current.delete(tabId);
|
|
876
1086
|
pendingSends.current.delete(tabId);
|
|
1087
|
+
pendingContextItems.current.delete(tabId);
|
|
877
1088
|
newThreadIds.current.delete(tabId);
|
|
878
1089
|
threadModelRef.current.delete(tabId);
|
|
879
1090
|
// Clean up parent map and sub-agent names
|
|
@@ -889,8 +1100,19 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
889
1100
|
const { [tabId]: _, ...rest } = prev;
|
|
890
1101
|
return rest;
|
|
891
1102
|
});
|
|
1103
|
+
setSubAgentStatuses((prev) => {
|
|
1104
|
+
if (!(tabId in prev))
|
|
1105
|
+
return prev;
|
|
1106
|
+
const { [tabId]: _, ...rest } = prev;
|
|
1107
|
+
return rest;
|
|
1108
|
+
});
|
|
892
1109
|
}, [switchThread, createThread]);
|
|
893
1110
|
const closeOtherTabs = useCallback((tabId) => {
|
|
1111
|
+
for (const id of openTabIdsRef.current) {
|
|
1112
|
+
if (id !== tabId && parentMapRef.current[id]) {
|
|
1113
|
+
dismissedSubAgentTabsRef.current.add(id);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
894
1116
|
setOpenTabIds([tabId]);
|
|
895
1117
|
if (activeThreadIdRef.current !== tabId) {
|
|
896
1118
|
switchThread(tabId);
|
|
@@ -898,6 +1120,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
898
1120
|
// Clean up refs for closed tabs
|
|
899
1121
|
for (const key of chatRefs.current.keys()) {
|
|
900
1122
|
if (key !== tabId) {
|
|
1123
|
+
if (parentMapRef.current[key]) {
|
|
1124
|
+
dismissedSubAgentTabsRef.current.add(key);
|
|
1125
|
+
}
|
|
901
1126
|
chatRefs.current.delete(key);
|
|
902
1127
|
pendingSends.current.delete(key);
|
|
903
1128
|
newThreadIds.current.delete(key);
|
|
@@ -915,6 +1140,11 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
915
1140
|
return { [tabId]: prev[tabId] };
|
|
916
1141
|
return {};
|
|
917
1142
|
});
|
|
1143
|
+
setSubAgentStatuses((prev) => {
|
|
1144
|
+
if (tabId in prev)
|
|
1145
|
+
return { [tabId]: prev[tabId] };
|
|
1146
|
+
return {};
|
|
1147
|
+
});
|
|
918
1148
|
}, [switchThread]);
|
|
919
1149
|
const closeAllTabs = useCallback(async () => {
|
|
920
1150
|
const id = await createThread();
|
|
@@ -922,12 +1152,14 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
922
1152
|
newThreadIds.current.add(id);
|
|
923
1153
|
setOpenTabIds([id]);
|
|
924
1154
|
switchThread(id);
|
|
1155
|
+
dismissedSubAgentTabsRef.current.clear();
|
|
925
1156
|
// Clean up all old refs
|
|
926
1157
|
chatRefs.current.clear();
|
|
927
1158
|
pendingSends.current.clear();
|
|
928
1159
|
threadModelRef.current.clear();
|
|
929
1160
|
setParentMap({});
|
|
930
1161
|
setSubAgentNames({});
|
|
1162
|
+
setSubAgentStatuses({});
|
|
931
1163
|
}
|
|
932
1164
|
}, [createThread, switchThread]);
|
|
933
1165
|
// Keyboard shortcuts dispatched from AgentPanel based on the active mode
|
|
@@ -983,8 +1215,13 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
983
1215
|
const threadId = detail?.threadId;
|
|
984
1216
|
if (!threadId)
|
|
985
1217
|
return;
|
|
986
|
-
|
|
987
|
-
|
|
1218
|
+
dismissedSubAgentTabsRef.current.delete(threadId);
|
|
1219
|
+
// Prefer an explicit parent (RunsTray/background hydration knows it);
|
|
1220
|
+
// inline task cards fall back to the active orchestrator thread.
|
|
1221
|
+
const explicitParentId = typeof detail?.parentThreadId === "string"
|
|
1222
|
+
? detail.parentThreadId.trim()
|
|
1223
|
+
: "";
|
|
1224
|
+
const parentId = explicitParentId || activeThreadIdRef.current;
|
|
988
1225
|
if (parentId && parentId !== threadId) {
|
|
989
1226
|
setParentMap((prev) => prev[threadId] === parentId
|
|
990
1227
|
? prev
|
|
@@ -1126,14 +1363,16 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1126
1363
|
.filter((id) => threadMap.has(id) || id === activeThreadId)
|
|
1127
1364
|
.map((id) => {
|
|
1128
1365
|
const t = threadMap.get(id);
|
|
1366
|
+
const agentTeamStatus = chatTabStatusFromAgentTeamStatus(subAgentStatuses[id]);
|
|
1129
1367
|
return {
|
|
1130
1368
|
id,
|
|
1131
1369
|
label: t?.title || t?.preview?.slice(0, 30) || "New chat",
|
|
1132
|
-
status:
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1370
|
+
status: agentTeamStatus ??
|
|
1371
|
+
(runningThreads.has(id)
|
|
1372
|
+
? "running"
|
|
1373
|
+
: (messageCounts[id] ?? t?.messageCount ?? 0) > 0
|
|
1374
|
+
? "completed"
|
|
1375
|
+
: "idle"),
|
|
1137
1376
|
parentThreadId: parentMap[id],
|
|
1138
1377
|
subAgentName: subAgentNames[id],
|
|
1139
1378
|
};
|
|
@@ -1144,7 +1383,8 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1144
1383
|
tabs.push({
|
|
1145
1384
|
id,
|
|
1146
1385
|
label: subAgentNames[id] || (parentMap[id] ? "Sub-agent..." : "New chat"),
|
|
1147
|
-
status:
|
|
1386
|
+
status: chatTabStatusFromAgentTeamStatus(subAgentStatuses[id]) ??
|
|
1387
|
+
"running",
|
|
1148
1388
|
parentThreadId: parentMap[id],
|
|
1149
1389
|
subAgentName: subAgentNames[id],
|
|
1150
1390
|
});
|