@agent-native/core 0.119.3 → 0.119.4
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 +2 -2
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +3 -3
- package/corpus/core/src/agent/production-agent.ts +107 -125
- package/corpus/core/src/agent/run-manager.ts +45 -2
- package/corpus/core/src/agent/thread-data-builder.ts +85 -8
- package/corpus/core/src/client/AssistantChat.tsx +37 -9
- package/corpus/core/src/client/chat/message-components.tsx +9 -1
- package/corpus/core/src/client/chat/repo-helpers.ts +77 -0
- package/corpus/core/src/client/chat/tool-call-display.tsx +51 -15
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +3 -1
- package/corpus/core/src/server/agent-chat/plugin-options.ts +9 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +12 -3
- package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +512 -0
- package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +189 -0
- package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +177 -0
- package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +221 -0
- package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +220 -0
- package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +160 -0
- package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +280 -0
- package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +118 -0
- package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +119 -0
- package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
- package/corpus/core/src/templates/chat/.env.example +5 -0
- package/corpus/core/src/templates/chat/.ignore +0 -0
- package/corpus/core/src/templates/chat/.oxfmtrc.json +8 -0
- package/corpus/core/src/templates/chat/AGENTS.md +69 -0
- package/corpus/core/src/templates/chat/CHANGELOG.md +10 -0
- package/corpus/core/src/templates/chat/DEVELOPING.md +185 -0
- package/corpus/core/src/templates/chat/README.md +32 -0
- package/corpus/core/src/templates/chat/_gitignore +43 -0
- package/corpus/core/src/templates/chat/actions/hello.ts +13 -0
- package/corpus/core/src/templates/chat/actions/navigate.ts +41 -0
- package/corpus/core/src/templates/chat/actions/run.ts +2 -0
- package/corpus/core/src/templates/chat/actions/view-screen.ts +31 -0
- package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +60 -0
- package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +185 -0
- package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +450 -0
- package/corpus/core/src/templates/chat/app/components/ui/button.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/card.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/input.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/label.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +1 -0
- package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +17 -0
- package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +1 -0
- package/corpus/core/src/templates/chat/app/design-system.ts +3 -0
- package/corpus/core/src/templates/chat/app/entry.client.tsx +19 -0
- package/corpus/core/src/templates/chat/app/entry.server.tsx +10 -0
- package/corpus/core/src/templates/chat/app/global.css +93 -0
- package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +93 -0
- package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +68 -0
- package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +71 -0
- package/corpus/core/src/templates/chat/app/i18n/en-US.ts +70 -0
- package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +71 -0
- package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +71 -0
- package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +69 -0
- package/corpus/core/src/templates/chat/app/i18n/index.ts +34 -0
- package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +70 -0
- package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +70 -0
- package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +71 -0
- package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +66 -0
- package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +66 -0
- package/corpus/core/src/templates/chat/app/i18n-data.ts +556 -0
- package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +49 -0
- package/corpus/core/src/templates/chat/app/lib/app-config.ts +11 -0
- package/corpus/core/src/templates/chat/app/lib/tab-id.ts +1 -0
- package/corpus/core/src/templates/chat/app/lib/utils.ts +1 -0
- package/corpus/core/src/templates/chat/app/root.tsx +173 -0
- package/corpus/core/src/templates/chat/app/routes/_index.tsx +94 -0
- package/corpus/core/src/templates/chat/app/routes/agent.tsx +24 -0
- package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +1 -0
- package/corpus/core/src/templates/chat/app/routes/database.tsx +17 -0
- package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +2 -0
- package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +11 -0
- package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +11 -0
- package/corpus/core/src/templates/chat/app/routes/extensions.tsx +5 -0
- package/corpus/core/src/templates/chat/app/routes/observability.tsx +19 -0
- package/corpus/core/src/templates/chat/app/routes/settings.tsx +89 -0
- package/corpus/core/src/templates/chat/app/routes/team.tsx +11 -0
- package/corpus/core/src/templates/chat/app/routes.ts +4 -0
- package/corpus/core/src/templates/chat/app/vite-env.d.ts +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
- package/corpus/core/src/templates/chat/components.json +20 -0
- package/corpus/core/src/templates/chat/learnings.defaults.md +5 -0
- package/corpus/core/src/templates/chat/netlify.toml +10 -0
- package/corpus/core/src/templates/chat/package.json +92 -0
- package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +10 -0
- package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +10 -0
- package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +21 -0
- package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +21 -0
- package/corpus/core/src/templates/chat/public/favicon.svg +1 -0
- package/corpus/core/src/templates/chat/public/icon-180.svg +1 -0
- package/corpus/core/src/templates/chat/public/icon-192.svg +1 -0
- package/corpus/core/src/templates/chat/public/icon-512.svg +1 -0
- package/corpus/core/src/templates/chat/public/manifest.json +21 -0
- package/corpus/core/src/templates/chat/react-router.config.ts +7 -0
- package/corpus/core/src/templates/chat/server/middleware/auth.ts +15 -0
- package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +21 -0
- package/corpus/core/src/templates/chat/server/plugins/auth.ts +17 -0
- package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +5 -0
- package/corpus/core/src/templates/chat/ssr-entry.ts +15 -0
- package/corpus/core/src/templates/chat/tsconfig.json +21 -0
- package/corpus/core/src/templates/chat/vite.config.ts +19 -0
- package/corpus/templates/analytics/AGENTS.md +19 -11
- package/corpus/templates/analytics/actions/list-data-dictionary.ts +3 -1
- package/corpus/templates/analytics/actions/save-data-dictionary-entry.ts +14 -0
- package/corpus/templates/analytics/actions/search-analytics-query-catalog.ts +41 -0
- package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +13 -0
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +12 -11
- package/corpus/templates/analytics/app/pages/adhoc/DashboardSkeleton.tsx +3 -3
- package/corpus/templates/analytics/changelog/2026-07-23-dashboard-chart-loading-placeholders-are-easier-to-see-in-da.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-23-routine-analytics-lookups-reuse-existing-query-definitions.md +6 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -12
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +405 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -16
- package/corpus/templates/content/changelog/2026-07-23-database-toolbar-sort-and-filter-controls-open-reliably.md +6 -0
- package/corpus/templates/forms/app/lib/public-form-link.ts +14 -0
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +6 -14
- package/corpus/templates/forms/changelog/2026-07-23-published-form-links-can-be-copied-without-being-asked-to-re.md +6 -0
- package/corpus/templates/mail/changelog/2026-07-23-scheduled-emails-now-send-only-once-when-multiple-requests-r.md +6 -0
- package/corpus/templates/mail/server/lib/jobs.ts +13 -4
- package/corpus/templates/mail/server/plugins/mail-jobs.ts +1 -1
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +7 -18
- package/corpus/templates/slides/app/lib/agent-visible-message.ts +28 -0
- package/corpus/templates/slides/app/pages/Index.tsx +6 -34
- package/corpus/templates/slides/changelog/2026-07-23-full-prompts-stay-visible-in-chat-when-creating-decks-or-add.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +13 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/editor/SharedRichEditor.tsx +23 -2
- package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +68 -2
- package/corpus/toolkit/src/editor/index.ts +1 -0
- package/corpus/toolkit/src/editor.css +75 -0
- package/corpus/toolkit/src/ui/button.tsx +3 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +96 -115
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +9 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +26 -0
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +2 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +69 -9
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +32 -10
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +2 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +9 -3
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/repo-helpers.d.ts +4 -0
- package/dist/client/chat/repo-helpers.d.ts.map +1 -1
- package/dist/client/chat/repo-helpers.js +61 -0
- package/dist/client/chat/repo-helpers.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +2 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +10 -9
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +3 -1
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat/plugin-options.d.ts +9 -0
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +11 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +4 -4
- package/src/agent/production-agent.ts +107 -125
- package/src/agent/run-manager.ts +45 -2
- package/src/agent/thread-data-builder.ts +85 -8
- package/src/client/AssistantChat.tsx +37 -9
- package/src/client/chat/message-components.tsx +9 -1
- package/src/client/chat/repo-helpers.ts +77 -0
- package/src/client/chat/tool-call-display.tsx +51 -15
- package/src/server/agent-chat/framework-prompts.ts +3 -1
- package/src/server/agent-chat/plugin-options.ts +9 -0
- package/src/server/agent-chat-plugin.ts +12 -3
- package/src/templates/chat/actions/hello.spec.ts +0 -23
- package/src/templates/chat/actions/navigate.spec.ts +0 -68
- package/src/templates/chat/actions/view-screen.spec.ts +0 -40
- package/src/templates/chat/app/lib/agent-page.spec.tsx +0 -61
|
@@ -110,6 +110,7 @@ import {
|
|
|
110
110
|
shouldImportServerThreadData,
|
|
111
111
|
dedupeRepoMessagesById,
|
|
112
112
|
dropEmptyAssistantMessages,
|
|
113
|
+
withLastAssistantRunDuration,
|
|
113
114
|
} from "./chat/repo-helpers.js";
|
|
114
115
|
import {
|
|
115
116
|
BuilderSetupContent,
|
|
@@ -2842,6 +2843,26 @@ const AssistantChatInner = forwardRef<
|
|
|
2842
2843
|
ensureMessageMetadata(normalizeThreadRepository(threadRuntime.export())),
|
|
2843
2844
|
[threadRuntime],
|
|
2844
2845
|
);
|
|
2846
|
+
const exportPersistableThreadRepo = useCallback(
|
|
2847
|
+
() =>
|
|
2848
|
+
withLastAssistantRunDuration(
|
|
2849
|
+
exportCleanThreadRepo(),
|
|
2850
|
+
showRunningInUI ? null : lastChatRunDurationMs,
|
|
2851
|
+
),
|
|
2852
|
+
[exportCleanThreadRepo, lastChatRunDurationMs, showRunningInUI],
|
|
2853
|
+
);
|
|
2854
|
+
useEffect(() => {
|
|
2855
|
+
if (showRunningInUI || lastChatRunDurationMs == null) return;
|
|
2856
|
+
const repo = exportCleanThreadRepo();
|
|
2857
|
+
const persisted = withLastAssistantRunDuration(repo, lastChatRunDurationMs);
|
|
2858
|
+
if (persisted === repo) return;
|
|
2859
|
+
threadRuntime.import(ensureMessageMetadata(persisted));
|
|
2860
|
+
}, [
|
|
2861
|
+
exportCleanThreadRepo,
|
|
2862
|
+
lastChatRunDurationMs,
|
|
2863
|
+
showRunningInUI,
|
|
2864
|
+
threadRuntime,
|
|
2865
|
+
]);
|
|
2845
2866
|
|
|
2846
2867
|
const appendRealtimeVoiceTranscript = useCallback(
|
|
2847
2868
|
(
|
|
@@ -2896,7 +2917,7 @@ const AssistantChatInner = forwardRef<
|
|
|
2896
2917
|
|
|
2897
2918
|
const cacheCurrentThreadSnapshot = useCallback(() => {
|
|
2898
2919
|
if (!threadId || messages.length === 0) return;
|
|
2899
|
-
const repo =
|
|
2920
|
+
const repo = exportPersistableThreadRepo();
|
|
2900
2921
|
const threadData = JSON.stringify(stripBase64FromRepo(repo));
|
|
2901
2922
|
const { title, preview } = extractThreadMeta(repo);
|
|
2902
2923
|
writeCachedThreadSnapshot(apiUrl, threadId, {
|
|
@@ -2905,7 +2926,7 @@ const AssistantChatInner = forwardRef<
|
|
|
2905
2926
|
preview,
|
|
2906
2927
|
messageCount: messages.length,
|
|
2907
2928
|
});
|
|
2908
|
-
}, [apiUrl,
|
|
2929
|
+
}, [apiUrl, exportPersistableThreadRepo, messages.length, threadId]);
|
|
2909
2930
|
|
|
2910
2931
|
useBrowserLayoutEffect(() => {
|
|
2911
2932
|
if (hasImportedInitialCachedSnapshotRef.current) return;
|
|
@@ -3669,7 +3690,7 @@ const AssistantChatInner = forwardRef<
|
|
|
3669
3690
|
const timeSinceLastSave = now - lastSaveTimeRef.current;
|
|
3670
3691
|
if (timeSinceLastSave < 5000) return;
|
|
3671
3692
|
|
|
3672
|
-
const repo =
|
|
3693
|
+
const repo = exportPersistableThreadRepo();
|
|
3673
3694
|
const { title, preview } = extractThreadMeta(repo);
|
|
3674
3695
|
const threadData = JSON.stringify(stripBase64FromRepo(repo));
|
|
3675
3696
|
const snapshot = {
|
|
@@ -3683,7 +3704,7 @@ const AssistantChatInner = forwardRef<
|
|
|
3683
3704
|
savedTitleRef.current = title;
|
|
3684
3705
|
writeCachedThreadSnapshot(apiUrl, threadId, snapshot);
|
|
3685
3706
|
onSaveThreadRef.current(threadId, snapshot);
|
|
3686
|
-
}, [apiUrl,
|
|
3707
|
+
}, [apiUrl, exportPersistableThreadRepo, messages, isRunning, threadId]);
|
|
3687
3708
|
|
|
3688
3709
|
// Persist full thread data after each completed response
|
|
3689
3710
|
useEffect(() => {
|
|
@@ -3691,7 +3712,7 @@ const AssistantChatInner = forwardRef<
|
|
|
3691
3712
|
if (isRunning) return;
|
|
3692
3713
|
if (messages.length === 0) return;
|
|
3693
3714
|
|
|
3694
|
-
const repo =
|
|
3715
|
+
const repo = exportPersistableThreadRepo();
|
|
3695
3716
|
|
|
3696
3717
|
if (threadId && onSaveThreadRef.current) {
|
|
3697
3718
|
// Save to server via the hook callback
|
|
@@ -3713,7 +3734,14 @@ const AssistantChatInner = forwardRef<
|
|
|
3713
3734
|
sessionStorage.setItem(storageKey, JSON.stringify(repo));
|
|
3714
3735
|
} catch {}
|
|
3715
3736
|
}
|
|
3716
|
-
}, [
|
|
3737
|
+
}, [
|
|
3738
|
+
apiUrl,
|
|
3739
|
+
exportPersistableThreadRepo,
|
|
3740
|
+
messages,
|
|
3741
|
+
isRunning,
|
|
3742
|
+
threadId,
|
|
3743
|
+
tabId,
|
|
3744
|
+
]);
|
|
3717
3745
|
|
|
3718
3746
|
useEffect(() => {
|
|
3719
3747
|
onMessageCountChange?.(messages.length);
|
|
@@ -4368,8 +4396,8 @@ const AssistantChatInner = forwardRef<
|
|
|
4368
4396
|
}
|
|
4369
4397
|
reconnectTailOnlyRef.current = false;
|
|
4370
4398
|
}
|
|
4371
|
-
threadRuntime.cancelRun();
|
|
4372
4399
|
settleVisibleInterruptedTools();
|
|
4400
|
+
threadRuntime.cancelRun();
|
|
4373
4401
|
if (typeof window !== "undefined") {
|
|
4374
4402
|
window.dispatchEvent(
|
|
4375
4403
|
new CustomEvent("agentNative.chatRunning", {
|
|
@@ -4810,7 +4838,7 @@ const AssistantChatInner = forwardRef<
|
|
|
4810
4838
|
},
|
|
4811
4839
|
exportThreadSnapshot() {
|
|
4812
4840
|
if (messages.length === 0) return null;
|
|
4813
|
-
const repo =
|
|
4841
|
+
const repo = exportPersistableThreadRepo();
|
|
4814
4842
|
const { title, preview } = extractThreadMeta(repo);
|
|
4815
4843
|
return {
|
|
4816
4844
|
threadData: JSON.stringify(repo),
|
|
@@ -4822,7 +4850,7 @@ const AssistantChatInner = forwardRef<
|
|
|
4822
4850
|
}),
|
|
4823
4851
|
[
|
|
4824
4852
|
addToQueue,
|
|
4825
|
-
|
|
4853
|
+
exportPersistableThreadRepo,
|
|
4826
4854
|
isRunning,
|
|
4827
4855
|
messages.length,
|
|
4828
4856
|
stageComposerContextItem,
|
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
MarkdownText,
|
|
74
74
|
renderMarkdownToClipboardHtml,
|
|
75
75
|
} from "./markdown-renderer.js";
|
|
76
|
+
import { getAssistantRunDurationMs } from "./repo-helpers.js";
|
|
76
77
|
import {
|
|
77
78
|
ToolCallFallback,
|
|
78
79
|
ToolActivityPresentation,
|
|
@@ -989,17 +990,22 @@ export function shouldShowAssistantMessageFooter({
|
|
|
989
990
|
}
|
|
990
991
|
|
|
991
992
|
export function shouldShowMissingFinalResponse({
|
|
993
|
+
isCurrentTurnRunning,
|
|
992
994
|
statusIsTerminal,
|
|
993
995
|
hasAssistantText,
|
|
994
996
|
hasUnresolvedTool,
|
|
995
997
|
hasCompletedCustomUi,
|
|
996
998
|
}: {
|
|
999
|
+
isCurrentTurnRunning: boolean;
|
|
997
1000
|
statusIsTerminal: boolean;
|
|
998
1001
|
hasAssistantText: boolean;
|
|
999
1002
|
hasUnresolvedTool: boolean;
|
|
1000
1003
|
hasCompletedCustomUi?: boolean;
|
|
1001
1004
|
}): boolean {
|
|
1005
|
+
// A completed tool can make the latest message look terminal before the
|
|
1006
|
+
// active turn attaches its follow-up text.
|
|
1002
1007
|
return (
|
|
1008
|
+
!isCurrentTurnRunning &&
|
|
1003
1009
|
statusIsTerminal &&
|
|
1004
1010
|
!hasAssistantText &&
|
|
1005
1011
|
!hasUnresolvedTool &&
|
|
@@ -1202,6 +1208,7 @@ export function AssistantMessage() {
|
|
|
1202
1208
|
const chatRunning = React.useContext(ChatRunningContext);
|
|
1203
1209
|
const lastRunDurationMs = React.useContext(ChatRunDurationContext);
|
|
1204
1210
|
const msg = messageRuntime.getState();
|
|
1211
|
+
const persistedDurationMs = getAssistantRunDurationMs(msg);
|
|
1205
1212
|
const timestamp = formatMessageTimestamp(msg.createdAt);
|
|
1206
1213
|
const isLast =
|
|
1207
1214
|
thread.messages.length > 0 &&
|
|
@@ -1215,6 +1222,7 @@ export function AssistantMessage() {
|
|
|
1215
1222
|
);
|
|
1216
1223
|
const hasCustomUi = assistantMessageHasCustomUi(msg.content);
|
|
1217
1224
|
const showMissingFinalResponse = shouldShowMissingFinalResponse({
|
|
1225
|
+
isCurrentTurnRunning: isLast && chatRunning,
|
|
1218
1226
|
statusIsTerminal,
|
|
1219
1227
|
hasAssistantText: responseConnectionText.trim().length > 0,
|
|
1220
1228
|
hasUnresolvedTool,
|
|
@@ -1370,7 +1378,7 @@ export function AssistantMessage() {
|
|
|
1370
1378
|
if (!showSummary) return <>{children}</>;
|
|
1371
1379
|
return (
|
|
1372
1380
|
<WorkedForSummary
|
|
1373
|
-
durationMs={capturedDurationMs}
|
|
1381
|
+
durationMs={capturedDurationMs ?? persistedDurationMs}
|
|
1374
1382
|
defaultOpen={hasCustomUi}
|
|
1375
1383
|
autoCollapse={animateCollapse && !hasCustomUi}
|
|
1376
1384
|
>
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
// interface covering the shapes both `threadRuntime.export()` and
|
|
6
6
|
// `normalizeThreadRepository()` produce, and use it everywhere instead of `any`.
|
|
7
7
|
|
|
8
|
+
import { ASSISTANT_RUN_DURATION_METADATA_KEY } from "../../agent/thread-data-builder.js";
|
|
9
|
+
|
|
8
10
|
export interface RepoMessageStatus {
|
|
9
11
|
type?: string;
|
|
10
12
|
reason?: string;
|
|
@@ -56,6 +58,81 @@ export function getRepoMessage(entry: RepoEntry): RepoMessage | null {
|
|
|
56
58
|
return (entry?.message ?? entry) as RepoMessage | null;
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
export function getAssistantRunDurationMs(
|
|
62
|
+
message:
|
|
63
|
+
| {
|
|
64
|
+
metadata?: unknown;
|
|
65
|
+
}
|
|
66
|
+
| null
|
|
67
|
+
| undefined,
|
|
68
|
+
): number | null {
|
|
69
|
+
const metadata =
|
|
70
|
+
message?.metadata && typeof message.metadata === "object"
|
|
71
|
+
? (message.metadata as Record<string, unknown>)
|
|
72
|
+
: null;
|
|
73
|
+
const custom =
|
|
74
|
+
metadata?.custom && typeof metadata.custom === "object"
|
|
75
|
+
? (metadata.custom as Record<string, unknown>)
|
|
76
|
+
: null;
|
|
77
|
+
const durationMs = custom?.[ASSISTANT_RUN_DURATION_METADATA_KEY];
|
|
78
|
+
return typeof durationMs === "number" &&
|
|
79
|
+
Number.isFinite(durationMs) &&
|
|
80
|
+
durationMs >= 0
|
|
81
|
+
? durationMs
|
|
82
|
+
: null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function withLastAssistantRunDuration<T extends NormalizedRepo>(
|
|
86
|
+
repo: T,
|
|
87
|
+
durationMs: number | null | undefined,
|
|
88
|
+
): T {
|
|
89
|
+
if (
|
|
90
|
+
!Array.isArray(repo.messages) ||
|
|
91
|
+
typeof durationMs !== "number" ||
|
|
92
|
+
!Number.isFinite(durationMs) ||
|
|
93
|
+
durationMs < 0
|
|
94
|
+
) {
|
|
95
|
+
return repo;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let messageIndex = -1;
|
|
99
|
+
for (let index = repo.messages.length - 1; index >= 0; index -= 1) {
|
|
100
|
+
if (getRepoMessage(repo.messages[index]!)?.role === "assistant") {
|
|
101
|
+
messageIndex = index;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (messageIndex < 0) return repo;
|
|
106
|
+
|
|
107
|
+
const entry = repo.messages[messageIndex]!;
|
|
108
|
+
const message = getRepoMessage(entry);
|
|
109
|
+
if (!message || getAssistantRunDurationMs(message) === durationMs) {
|
|
110
|
+
return repo;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const metadata = message.metadata ?? {};
|
|
114
|
+
const custom =
|
|
115
|
+
metadata.custom && typeof metadata.custom === "object"
|
|
116
|
+
? (metadata.custom as Record<string, unknown>)
|
|
117
|
+
: {};
|
|
118
|
+
const nextMessage: RepoMessage = {
|
|
119
|
+
...message,
|
|
120
|
+
metadata: {
|
|
121
|
+
...metadata,
|
|
122
|
+
custom: {
|
|
123
|
+
...custom,
|
|
124
|
+
[ASSISTANT_RUN_DURATION_METADATA_KEY]: durationMs,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
const messages = repo.messages.slice();
|
|
129
|
+
messages[messageIndex] =
|
|
130
|
+
entry.message === undefined
|
|
131
|
+
? (nextMessage as RepoEntry)
|
|
132
|
+
: { ...entry, message: nextMessage };
|
|
133
|
+
return { ...repo, messages };
|
|
134
|
+
}
|
|
135
|
+
|
|
59
136
|
/**
|
|
60
137
|
* Collapse duplicate message ids before a repository is handed to
|
|
61
138
|
* `threadRuntime.import()`. assistant-ui's `MessageRepository` throws
|
|
@@ -25,7 +25,10 @@ import React, {
|
|
|
25
25
|
useRef,
|
|
26
26
|
} from "react";
|
|
27
27
|
|
|
28
|
-
import type {
|
|
28
|
+
import type {
|
|
29
|
+
A2AAgentActivitySnapshot,
|
|
30
|
+
A2AAgentActivityToolCall,
|
|
31
|
+
} from "../../a2a/activity.js";
|
|
29
32
|
import type { ActionChatUIConfig } from "../../action-ui.js";
|
|
30
33
|
import type { AgentMcpAppPayload } from "../../mcp-client/app-result.js";
|
|
31
34
|
import { AgentTaskCard } from "../AgentTaskCard.js";
|
|
@@ -100,11 +103,13 @@ export function ToolActivityPresentation({
|
|
|
100
103
|
toolName,
|
|
101
104
|
isRunning,
|
|
102
105
|
isActiveTail,
|
|
106
|
+
suppressLongRunningHint = false,
|
|
103
107
|
children,
|
|
104
108
|
}: {
|
|
105
109
|
toolName: string;
|
|
106
110
|
isRunning: boolean;
|
|
107
111
|
isActiveTail: boolean;
|
|
112
|
+
suppressLongRunningHint?: boolean;
|
|
108
113
|
children: React.ReactNode;
|
|
109
114
|
}) {
|
|
110
115
|
const [showLongRunningHint, setShowLongRunningHint] = useState(false);
|
|
@@ -114,7 +119,7 @@ export function ToolActivityPresentation({
|
|
|
114
119
|
const [animateEntry] = useState(isActiveTail);
|
|
115
120
|
|
|
116
121
|
useEffect(() => {
|
|
117
|
-
if (!isRunning) {
|
|
122
|
+
if (!isRunning || suppressLongRunningHint) {
|
|
118
123
|
setShowLongRunningHint(false);
|
|
119
124
|
return;
|
|
120
125
|
}
|
|
@@ -123,7 +128,7 @@ export function ToolActivityPresentation({
|
|
|
123
128
|
setShowLongRunningHint(true);
|
|
124
129
|
}, TOOL_LONG_RUNNING_HINT_DELAY_MS);
|
|
125
130
|
return () => window.clearTimeout(timeout);
|
|
126
|
-
}, [isRunning, toolName]);
|
|
131
|
+
}, [isRunning, suppressLongRunningHint, toolName]);
|
|
127
132
|
|
|
128
133
|
return (
|
|
129
134
|
<div
|
|
@@ -584,6 +589,9 @@ export function ToolCallDisplay({
|
|
|
584
589
|
toolName={toolName}
|
|
585
590
|
isRunning={isRunning}
|
|
586
591
|
isActiveTail={showActiveTail}
|
|
592
|
+
suppressLongRunningHint={
|
|
593
|
+
toolName === "call-agent" || toolName.startsWith("agent:")
|
|
594
|
+
}
|
|
587
595
|
>
|
|
588
596
|
{children}
|
|
589
597
|
</ToolActivityPresentation>
|
|
@@ -955,18 +963,8 @@ function AgentCallCell({
|
|
|
955
963
|
/>
|
|
956
964
|
)}
|
|
957
965
|
{tool && (
|
|
958
|
-
<
|
|
959
|
-
|
|
960
|
-
args={{}}
|
|
961
|
-
argsText=""
|
|
962
|
-
isRunning={tool.status === "running"}
|
|
963
|
-
result={
|
|
964
|
-
tool.status === "failed"
|
|
965
|
-
? "Failed"
|
|
966
|
-
: tool.status === "completed"
|
|
967
|
-
? "Done"
|
|
968
|
-
: undefined
|
|
969
|
-
}
|
|
966
|
+
<AgentActivityToolCallRow
|
|
967
|
+
tool={tool}
|
|
970
968
|
isActiveTail={
|
|
971
969
|
isRunning && index === activity.toolCalls.length - 1
|
|
972
970
|
}
|
|
@@ -1051,6 +1049,44 @@ function AgentCallCell({
|
|
|
1051
1049
|
);
|
|
1052
1050
|
}
|
|
1053
1051
|
|
|
1052
|
+
function AgentActivityToolCallRow({
|
|
1053
|
+
tool,
|
|
1054
|
+
isActiveTail,
|
|
1055
|
+
}: {
|
|
1056
|
+
tool: A2AAgentActivityToolCall;
|
|
1057
|
+
isActiveTail: boolean;
|
|
1058
|
+
}) {
|
|
1059
|
+
const isRunning = tool.status === "running";
|
|
1060
|
+
const ToolIcon = resolveToolIcon(tool.name);
|
|
1061
|
+
|
|
1062
|
+
return (
|
|
1063
|
+
<ToolActivityPresentation
|
|
1064
|
+
toolName={tool.name}
|
|
1065
|
+
isRunning={isRunning}
|
|
1066
|
+
isActiveTail={isActiveTail}
|
|
1067
|
+
suppressLongRunningHint
|
|
1068
|
+
>
|
|
1069
|
+
<div className="my-0.5 flex w-full items-center gap-1.5 rounded-md py-0.5 text-left text-[13px] text-muted-foreground">
|
|
1070
|
+
<span className="flex size-4 shrink-0 items-center justify-center">
|
|
1071
|
+
{isRunning ? (
|
|
1072
|
+
<IconLoader2 className="size-3.5 animate-spin" />
|
|
1073
|
+
) : (
|
|
1074
|
+
<ToolIcon className="size-3.5" />
|
|
1075
|
+
)}
|
|
1076
|
+
</span>
|
|
1077
|
+
<span
|
|
1078
|
+
className={cn(
|
|
1079
|
+
"min-w-0 truncate font-normal",
|
|
1080
|
+
isActiveTail && "agent-running-shimmer",
|
|
1081
|
+
)}
|
|
1082
|
+
>
|
|
1083
|
+
{humanizeToolName(tool.name)}
|
|
1084
|
+
</span>
|
|
1085
|
+
</div>
|
|
1086
|
+
</ToolActivityPresentation>
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1054
1090
|
// ─── ToolCallFallback ──────────────────────────────────────────────────────────
|
|
1055
1091
|
|
|
1056
1092
|
export function ToolCallFallback({
|
|
@@ -413,7 +413,9 @@ export function generateCorpusToolsPrompt(
|
|
|
413
413
|
|
|
414
414
|
Available corpus-capable tools: ${available.join(", ")}.
|
|
415
415
|
|
|
416
|
-
|
|
416
|
+
This workflow does not apply to ordinary structured lookups, bounded aggregates, or counts grouped over one known source. For those requests, use the single most directly authoritative source, run one bounded query, and answer as soon as it succeeds. Do not cross-check or expand into a corpus workflow unless the user asks for multiple sources, exhaustive unstructured-record coverage, or an absence claim.
|
|
417
|
+
|
|
418
|
+
For broad provider searches, raw API access, multi-page cohorts, cross-source joins, classification over unstructured records, or absence-sensitive answers, do not stop at a bounded shortcut action. Use the provider's broad API/search/list surface, fetch every relevant page or an explicit bounded cohort, stage/save large responses when needed, and reduce the corpus with durable corpus jobs, staged-dataset queries, or code execution.
|
|
417
419
|
|
|
418
420
|
When \`provider-corpus-job\` is available, prefer it for transcript/message/ticket/issue/document scans that may exceed one turn, need provider-side backoff, or need a defensible "not found" conclusion. Use operation="start" with mode="paginated-search" for any paginated provider endpoint, or mode="batch-search" when a prior cohort of ids/records must feed a second provider endpoint. Continue paused jobs with operation="continue" until status is completed or quota_wait, then read operation="results". In run-code, prefer providerFetchAll() for short cursor/page/offset pagination and providerRequest() when response status, headers, or truncation metadata matters. Report source, filters, row counts, pagination/truncation, failed pages, quota_wait times, and remaining gaps.`;
|
|
419
421
|
}
|
|
@@ -216,6 +216,15 @@ export interface AgentChatPluginOptions {
|
|
|
216
216
|
* tool-search unless the app explicitly includes them in this list.
|
|
217
217
|
*/
|
|
218
218
|
initialToolNames?: string[];
|
|
219
|
+
/**
|
|
220
|
+
* Controls whether broad provider/corpus tools and their workflow prompt are
|
|
221
|
+
* loaded into the first model request. Use `"lazy"` for apps that can answer
|
|
222
|
+
* ordinary lookups from a compact curated tool set; corpus tools remain
|
|
223
|
+
* discoverable through tool-search and the full retry surface.
|
|
224
|
+
*
|
|
225
|
+
* @default "initial"
|
|
226
|
+
*/
|
|
227
|
+
corpusTools?: "initial" | "lazy";
|
|
219
228
|
/**
|
|
220
229
|
* Use a compact system prompt with on-demand context loading. The system
|
|
221
230
|
* prompt includes essential behavioral rules and action signatures, but
|
|
@@ -1179,8 +1179,10 @@ export function createAgentChatPlugin(
|
|
|
1179
1179
|
// that never emit the corpus prompt (no provider/run-code tools
|
|
1180
1180
|
// registered), so this never silently expands the initial set for
|
|
1181
1181
|
// apps that don't teach these tools by name.
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1182
|
+
const loadCorpusToolsInitially = options?.corpusTools !== "lazy";
|
|
1183
|
+
const corpusToolNames = loadCorpusToolsInitially
|
|
1184
|
+
? corpusToolNamesTaughtByPrompt(corpusPromptRegistry)
|
|
1185
|
+
: [];
|
|
1184
1186
|
const effectiveInitialToolNames =
|
|
1185
1187
|
corpusToolNames.length > 0
|
|
1186
1188
|
? [...new Set([...templateInitialToolNames, ...corpusToolNames])]
|
|
@@ -1907,7 +1909,9 @@ export function createAgentChatPlugin(
|
|
|
1907
1909
|
// Dev: actions are invoked via bash — emit `pnpm action name --arg <type>`
|
|
1908
1910
|
// and include discoveredActions too, since those are also missing
|
|
1909
1911
|
// from the dev tool registry.
|
|
1910
|
-
const corpusToolsPrompt =
|
|
1912
|
+
const corpusToolsPrompt = loadCorpusToolsInitially
|
|
1913
|
+
? generateCorpusToolsPrompt(corpusPromptRegistry)
|
|
1914
|
+
: "";
|
|
1911
1915
|
const prodActionsPrompt =
|
|
1912
1916
|
generateActionsPrompt(
|
|
1913
1917
|
templateScripts,
|
|
@@ -2250,6 +2254,11 @@ export function createAgentChatPlugin(
|
|
|
2250
2254
|
typeof run.turnId === "string" && run.turnId
|
|
2251
2255
|
? run.turnId
|
|
2252
2256
|
: undefined,
|
|
2257
|
+
runDurationMs:
|
|
2258
|
+
typeof run.startedAt === "number" &&
|
|
2259
|
+
Number.isFinite(run.startedAt)
|
|
2260
|
+
? Math.max(0, Date.now() - run.startedAt)
|
|
2261
|
+
: undefined,
|
|
2253
2262
|
},
|
|
2254
2263
|
);
|
|
2255
2264
|
if (!assistantMsg) {
|