@agent-native/core 0.115.4 → 0.116.0
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/agent-native.eject.json +1 -0
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/agent-native.eject.json +1 -0
- package/corpus/core/docs/AGENTS.md +1 -1
- package/corpus/core/docs/content/agent-mentions.mdx +2 -2
- package/corpus/core/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
- package/corpus/core/docs/content/agent-teams.mdx +4 -4
- package/corpus/core/docs/content/dispatch.mdx +10 -10
- package/corpus/core/docs/content/drop-in-agent.mdx +4 -4
- package/corpus/core/docs/content/external-agents.mdx +1 -1
- package/corpus/core/docs/content/frames.mdx +1 -1
- package/corpus/core/docs/content/integrations.mdx +13 -2
- package/corpus/core/docs/content/key-concepts.mdx +2 -2
- package/corpus/core/docs/content/mcp-clients.mdx +7 -1
- package/corpus/core/docs/content/multi-app-workspace.mdx +3 -3
- package/corpus/core/docs/content/real-time-collaboration.mdx +33 -15
- package/corpus/core/docs/content/recurring-jobs.mdx +7 -7
- package/corpus/core/docs/content/skills-guide.mdx +4 -4
- package/corpus/core/docs/content/template-brain.mdx +1 -1
- package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
- package/corpus/core/docs/content/using-your-agent.mdx +1 -1
- package/corpus/core/docs/content/what-is-agent-native.mdx +4 -4
- package/corpus/core/docs/content/workspace-management.mdx +4 -4
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +13 -3
- package/corpus/core/src/cli/doctor.ts +6 -1
- package/corpus/core/src/client/AgentPanel.tsx +79 -41
- package/corpus/core/src/client/AssistantChat.tsx +71 -25
- package/corpus/core/src/client/FeedbackButton.tsx +33 -7
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +6 -8
- package/corpus/core/src/client/agent-chat-adapter.ts +11 -2
- package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +22 -3
- package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +34 -19
- package/corpus/core/src/client/chat/message-components.tsx +43 -16
- package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
- package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
- package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
- package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
- package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
- package/corpus/core/src/client/sse-event-processor.ts +50 -14
- package/corpus/core/src/client/use-db-sync.ts +16 -6
- package/corpus/core/src/connections/catalog.ts +7 -1
- package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
- package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
- package/corpus/core/src/guards/index.ts +1 -0
- package/corpus/core/src/localization/default-messages.ts +54 -5
- package/corpus/core/src/mcp/connect-route.ts +34 -51
- package/corpus/core/src/provider-api/index.ts +1 -1
- package/corpus/core/src/server/collab-plugin.ts +137 -18
- package/corpus/core/src/server/index.ts +2 -0
- package/corpus/core/src/styles/agent-native.css +40 -0
- package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
- package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/analytics/AGENTS.md +7 -2
- package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
- package/corpus/templates/analytics/app/i18n-data.ts +107 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
- package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
- package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
- package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
- package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
- package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
- package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
- package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
- package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
- package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
- package/corpus/templates/assets/app/routes/_index.tsx +8 -5
- package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
- package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/brain/app/i18n-data.ts +120 -0
- package/corpus/templates/brain/app/routes/sources.tsx +156 -5
- package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
- package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
- package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
- package/corpus/templates/brain/netlify.toml +5 -1
- package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
- package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
- package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/corpus/templates/chat/app/routes/_index.tsx +8 -5
- package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/clips/AGENTS.md +9 -1
- package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
- package/corpus/templates/clips/actions/request-transcript.ts +25 -14
- package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
- package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
- package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
- package/corpus/templates/clips/netlify.toml +4 -1
- package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
- package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
- package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
- package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
- package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
- package/corpus/templates/clips/server/register-secrets.ts +42 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
- package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
- package/corpus/templates/content/server/plugins/collab.ts +1 -1
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
- package/corpus/templates/crm/actions/run.ts +2 -6
- package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/server/plugins/collab.ts +11 -8
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/forms/app/root.tsx +1 -6
- package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
- package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
- package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
- package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
- package/corpus/templates/plan/server/plugins/collab.ts +5 -2
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/slides/server/plugins/collab.ts +11 -8
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
- package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/corpus/toolkit/CHANGELOG.md +7 -0
- package/corpus/toolkit/README.md +12 -3
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
- package/corpus/toolkit/src/chat-history/index.ts +5 -0
- package/corpus/toolkit/src/chat-history.css +59 -0
- package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
- package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
- package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
- package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
- package/corpus/toolkit/src/styles.css +35 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +13 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/doctor.d.ts +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +5 -2
- package/dist/cli/doctor.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +1 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +38 -18
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +55 -20
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/FeedbackButton.d.ts +4 -2
- package/dist/client/FeedbackButton.d.ts.map +1 -1
- package/dist/client/FeedbackButton.js +18 -2
- package/dist/client/FeedbackButton.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +2 -3
- 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 +11 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
- package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabFrame.js +3 -2
- package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
- package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
- package/dist/client/agent-page/AgentTabsPage.js +26 -15
- package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +6 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +17 -11
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +11 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +16 -17
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/tool-render-registry.d.ts +2 -0
- package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
- package/dist/client/chat/tool-render-registry.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.js +15 -1
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +3 -3
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +1 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +34 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
- package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
- package/dist/client/resources/mcp-connection-resume.js +95 -0
- package/dist/client/resources/mcp-connection-resume.js.map +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +63 -8
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-logos.js +4 -0
- package/dist/client/resources/mcp-integration-logos.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +5 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +39 -13
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +3 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +17 -6
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +1 -1
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +7 -1
- package/dist/connections/catalog.js.map +1 -1
- package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
- package/dist/eject/remote-mcp-presets.js +33 -3
- package/dist/eject/remote-mcp-presets.js.map +1 -1
- package/dist/guards/explicit-collab-access.d.ts +8 -0
- package/dist/guards/explicit-collab-access.d.ts.map +1 -0
- package/dist/guards/explicit-collab-access.js +214 -0
- package/dist/guards/explicit-collab-access.js.map +1 -0
- package/dist/guards/index.d.ts +1 -0
- package/dist/guards/index.d.ts.map +1 -1
- package/dist/guards/index.js +1 -0
- package/dist/guards/index.js.map +1 -1
- package/dist/localization/default-messages.d.ts +43 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +48 -5
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +34 -48
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +7 -7
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +1 -1
- package/dist/provider-api/index.js.map +1 -1
- package/dist/server/collab-plugin.d.ts +34 -3
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +65 -12
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/styles/agent-native.css +40 -0
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/dist/templates/chat/app/routes/_index.tsx +8 -5
- package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
- package/docs/AGENTS.md +1 -1
- package/docs/content/agent-mentions.mdx +2 -2
- package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
- package/docs/content/agent-teams.mdx +4 -4
- package/docs/content/dispatch.mdx +10 -10
- package/docs/content/drop-in-agent.mdx +4 -4
- package/docs/content/external-agents.mdx +1 -1
- package/docs/content/frames.mdx +1 -1
- package/docs/content/integrations.mdx +13 -2
- package/docs/content/key-concepts.mdx +2 -2
- package/docs/content/mcp-clients.mdx +7 -1
- package/docs/content/multi-app-workspace.mdx +3 -3
- package/docs/content/real-time-collaboration.mdx +33 -15
- package/docs/content/recurring-jobs.mdx +7 -7
- package/docs/content/skills-guide.mdx +4 -4
- package/docs/content/template-brain.mdx +1 -1
- package/docs/content/toolkit-collaboration.mdx +1 -1
- package/docs/content/using-your-agent.mdx +1 -1
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/docs/content/workspace-management.mdx +4 -4
- package/package.json +3 -3
- package/src/agent/production-agent.ts +13 -3
- package/src/cli/doctor.ts +6 -1
- package/src/client/AgentPanel.tsx +79 -41
- package/src/client/AssistantChat.tsx +71 -25
- package/src/client/FeedbackButton.tsx +33 -7
- package/src/client/MultiTabAssistantChat.tsx +6 -8
- package/src/client/agent-chat-adapter.ts +11 -2
- package/src/client/agent-page/AgentTabFrame.tsx +22 -3
- package/src/client/agent-page/AgentTabsPage.tsx +34 -19
- package/src/client/chat/message-components.tsx +43 -16
- package/src/client/chat/tool-call-display.tsx +30 -18
- package/src/client/chat/tool-render-registry.tsx +2 -0
- package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
- package/src/client/resources/ResourceTree.tsx +7 -10
- package/src/client/resources/ResourcesPanel.tsx +33 -70
- package/src/client/resources/mcp-connection-resume.ts +107 -0
- package/src/client/resources/mcp-integration-catalog.ts +65 -12
- package/src/client/resources/mcp-integration-logos.ts +4 -0
- package/src/client/sse-event-processor.ts +50 -14
- package/src/client/use-db-sync.ts +16 -6
- package/src/connections/catalog.ts +7 -1
- package/src/eject/remote-mcp-presets.ts +37 -5
- package/src/guards/explicit-collab-access.ts +229 -0
- package/src/guards/index.ts +1 -0
- package/src/localization/default-messages.ts +54 -5
- package/src/mcp/connect-route.ts +34 -51
- package/src/provider-api/index.ts +1 -1
- package/src/server/collab-plugin.ts +137 -18
- package/src/server/index.ts +2 -0
- package/src/styles/agent-native.css +40 -0
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
- package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
- package/src/templates/chat/app/routes/_index.tsx +8 -5
- package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
- package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
- package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
import { getDbExec } from "@agent-native/core/db";
|
|
5
|
+
|
|
6
|
+
const tokenFile = process.env.BRAIN_CLIPS_TOKEN_FILE;
|
|
7
|
+
if (!tokenFile) throw new Error("BRAIN_CLIPS_TOKEN_FILE is required");
|
|
8
|
+
|
|
9
|
+
const db = getDbExec();
|
|
10
|
+
const { rows } = await db.execute({
|
|
11
|
+
sql: "SELECT id, source_key, config_json FROM brain_sources WHERE provider = ? AND title = ?",
|
|
12
|
+
args: ["clips", "Clips exports"],
|
|
13
|
+
});
|
|
14
|
+
if (rows.length !== 1) {
|
|
15
|
+
throw new Error(`Expected one Clips exports source, found ${rows.length}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const source = rows[0] as {
|
|
19
|
+
id: string;
|
|
20
|
+
source_key?: string | null;
|
|
21
|
+
config_json?: string | null;
|
|
22
|
+
};
|
|
23
|
+
const sourceKey = source.source_key?.trim() || "clips";
|
|
24
|
+
const token = `brain_${randomBytes(32).toString("base64url")}`;
|
|
25
|
+
const tokenHash = createHash("sha256").update(token).digest("hex");
|
|
26
|
+
const config = JSON.parse(source.config_json || "{}") as Record<
|
|
27
|
+
string,
|
|
28
|
+
unknown
|
|
29
|
+
>;
|
|
30
|
+
config.sourceKey = sourceKey;
|
|
31
|
+
config.ingestTokenHash = tokenHash;
|
|
32
|
+
|
|
33
|
+
await db.execute({
|
|
34
|
+
sql: "UPDATE brain_sources SET source_key = ?, ingest_token_hash = ?, config_json = ?, updated_at = ? WHERE id = ?",
|
|
35
|
+
args: [
|
|
36
|
+
sourceKey,
|
|
37
|
+
tokenHash,
|
|
38
|
+
JSON.stringify(config),
|
|
39
|
+
new Date().toISOString(),
|
|
40
|
+
source.id,
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
await writeFile(tokenFile, token, {
|
|
44
|
+
encoding: "utf8",
|
|
45
|
+
flag: "wx",
|
|
46
|
+
mode: 0o600,
|
|
47
|
+
});
|
|
48
|
+
console.log(
|
|
49
|
+
JSON.stringify({ configured: true, sourceId: source.id, sourceKey }),
|
|
50
|
+
);
|
|
@@ -168,6 +168,10 @@ function preferredDeterministicSection(content: string): string {
|
|
|
168
168
|
return content;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
function hasSummarySection(content: string): boolean {
|
|
172
|
+
return /(?:^|\n)\s*Summary\s*\n/i.test(content);
|
|
173
|
+
}
|
|
174
|
+
|
|
171
175
|
function looksLikeRawTranscriptLine(line: string): boolean {
|
|
172
176
|
return (
|
|
173
177
|
/^\[[^\]\n]{1,80}\]\s*/.test(line) ||
|
|
@@ -208,6 +212,35 @@ function deterministicSanitizeContent(
|
|
|
208
212
|
return retained.join("\n").slice(0, 80_000).trim();
|
|
209
213
|
}
|
|
210
214
|
|
|
215
|
+
function deterministicMeetingOutageFallback(
|
|
216
|
+
input: CaptureSanitizationInput,
|
|
217
|
+
decision: BrainSensitivityDecision,
|
|
218
|
+
capturedAt: string,
|
|
219
|
+
): string | null {
|
|
220
|
+
if (
|
|
221
|
+
decision.disposition !== "allowed" ||
|
|
222
|
+
input.kind !== "transcript" ||
|
|
223
|
+
!["granola", "clips"].includes(input.source.provider) ||
|
|
224
|
+
!shouldSanitizeCaptureBeforeStorage(input) ||
|
|
225
|
+
!hasSummarySection(decision.safeContent) ||
|
|
226
|
+
PERSONAL_SIGNAL.test(decision.safeContent) ||
|
|
227
|
+
RECRUITING_SIGNAL.test(decision.safeContent)
|
|
228
|
+
) {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const content = deterministicSanitizeContent(
|
|
233
|
+
sanitizeSensitiveText(decision.safeContent),
|
|
234
|
+
{ dropTranscriptLines: true },
|
|
235
|
+
);
|
|
236
|
+
if (content === DEFAULT_SANITIZATION_OUTPUT) return null;
|
|
237
|
+
|
|
238
|
+
return fallbackSensitivityDecision(content, capturedAt).disposition ===
|
|
239
|
+
"allowed"
|
|
240
|
+
? content
|
|
241
|
+
: null;
|
|
242
|
+
}
|
|
243
|
+
|
|
211
244
|
function safeTranscriptTitle(input: CaptureSanitizationInput): string {
|
|
212
245
|
const date = input.capturedAt?.slice(0, 10);
|
|
213
246
|
const providerLabel =
|
|
@@ -506,7 +539,9 @@ export async function sanitizeCaptureForStorage(
|
|
|
506
539
|
deterministicQuarantineDecision(input.title, capturedAt) ??
|
|
507
540
|
(titleDecision.disposition === "allowed" ? null : titleDecision) ??
|
|
508
541
|
deterministicQuarantineDecision(input.content, capturedAt);
|
|
542
|
+
const sanitizationRequested = shouldSanitizeCaptureBeforeStorage(input);
|
|
509
543
|
let fallbackReason: string | undefined;
|
|
544
|
+
let classifierOutageFallback = false;
|
|
510
545
|
const classifierConfigured = Boolean(
|
|
511
546
|
stringSetting(input.settings.privacyClassifierModel) &&
|
|
512
547
|
stringSetting(input.settings.privacyClassifierEngine),
|
|
@@ -526,13 +561,35 @@ export async function sanitizeCaptureForStorage(
|
|
|
526
561
|
}
|
|
527
562
|
decision ??= fallbackSensitivityDecision(input.content, capturedAt);
|
|
528
563
|
if (classifierFailed) {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
564
|
+
const deterministicMeetingContent = deterministicMeetingOutageFallback(
|
|
565
|
+
input,
|
|
566
|
+
decision,
|
|
567
|
+
capturedAt,
|
|
568
|
+
);
|
|
569
|
+
if (deterministicMeetingContent) {
|
|
570
|
+
classifierOutageFallback = true;
|
|
571
|
+
decision = {
|
|
572
|
+
...decision,
|
|
573
|
+
safeContent: deterministicMeetingContent,
|
|
574
|
+
safeSegments: [
|
|
575
|
+
{
|
|
576
|
+
id: "deterministic-meeting-summary",
|
|
577
|
+
capturedAt,
|
|
578
|
+
text: deterministicMeetingContent,
|
|
579
|
+
reactionCount: 0,
|
|
580
|
+
},
|
|
581
|
+
],
|
|
582
|
+
confidenceBand: "deterministic",
|
|
583
|
+
classifier: "deterministic",
|
|
584
|
+
};
|
|
585
|
+
} else {
|
|
586
|
+
decision = {
|
|
587
|
+
...decision,
|
|
588
|
+
disposition: "quarantined",
|
|
589
|
+
confidenceBand: "uncertain",
|
|
590
|
+
};
|
|
591
|
+
}
|
|
534
592
|
}
|
|
535
|
-
const sanitizationRequested = shouldSanitizeCaptureBeforeStorage(input);
|
|
536
593
|
|
|
537
594
|
const sanitizedContent =
|
|
538
595
|
decision.disposition === "allowed"
|
|
@@ -575,6 +632,7 @@ export async function sanitizeCaptureForStorage(
|
|
|
575
632
|
? input.settings.privacyClassifierModel
|
|
576
633
|
: undefined,
|
|
577
634
|
fallbackReason,
|
|
635
|
+
classifierOutageFallback: classifierOutageFallback || undefined,
|
|
578
636
|
disposition: decision.disposition,
|
|
579
637
|
categories: decision.categories,
|
|
580
638
|
confidenceBand: decision.confidenceBand,
|
|
@@ -10,6 +10,8 @@ import { and, desc, like, or } from "drizzle-orm";
|
|
|
10
10
|
import actionsRegistry from "../../.generated/actions-registry.js";
|
|
11
11
|
import { tryAnswerBrainA2AQuestion } from "../lib/a2a-fallback.js";
|
|
12
12
|
|
|
13
|
+
const BRAIN_BACKGROUND_RUN_SOFT_TIMEOUT_MS = 13 * 60_000;
|
|
14
|
+
|
|
13
15
|
const INITIAL_TOOL_NAMES = [
|
|
14
16
|
"get-brain-settings",
|
|
15
17
|
"ask-brain",
|
|
@@ -39,6 +41,8 @@ export default createAgentChatPlugin({
|
|
|
39
41
|
appId: "brain",
|
|
40
42
|
actions: loadActionsFromStaticRegistry(actionsRegistry),
|
|
41
43
|
initialToolNames: INITIAL_TOOL_NAMES,
|
|
44
|
+
durableBackgroundRuns: true,
|
|
45
|
+
runSoftTimeoutMs: BRAIN_BACKGROUND_RUN_SOFT_TIMEOUT_MS,
|
|
42
46
|
resolveOrgId: async (event) => (await getOrgContext(event)).orgId,
|
|
43
47
|
codeExecution: { production: "sandboxed" },
|
|
44
48
|
systemPrompt: `You are the Brain institutional-knowledge agent.
|
|
@@ -2,6 +2,7 @@ import registerBrainDistillationQueueJob from "../jobs/distillation-queue.js";
|
|
|
2
2
|
import registerBrainSourceSyncJob from "../jobs/sync-sources.js";
|
|
3
3
|
|
|
4
4
|
export default () => {
|
|
5
|
+
if (process.env.NETLIFY === "true") return;
|
|
5
6
|
registerBrainSourceSyncJob();
|
|
6
7
|
registerBrainDistillationQueueJob();
|
|
7
8
|
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { timingSafeEqual } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { createError, defineEventHandler, getHeader } from "h3";
|
|
4
|
+
|
|
5
|
+
import { processBrainIngestQueueOnce } from "../../../../../jobs/process-ingest-queue.js";
|
|
6
|
+
import { syncDueBrainSourcesOnce } from "../../../../jobs/sync-sources.js";
|
|
7
|
+
import { expireSensitivityQuarantines } from "../../../../lib/brain.js";
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
var __AGENT_NATIVE_BRAIN_SCHEDULED_RUNTIME__: boolean | undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function productionLike() {
|
|
14
|
+
return (
|
|
15
|
+
process.env.NODE_ENV === "production" || process.env.NETLIFY === "true"
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function scheduledFunctionRuntime() {
|
|
20
|
+
return globalThis.__AGENT_NATIVE_BRAIN_SCHEDULED_RUNTIME__ === true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function headerMatchesSecret(header: string | undefined, secret: string) {
|
|
24
|
+
const expected = `Bearer ${secret}`;
|
|
25
|
+
const value = header?.trim() ?? "";
|
|
26
|
+
return (
|
|
27
|
+
value.length === expected.length &&
|
|
28
|
+
timingSafeEqual(Buffer.from(value), Buffer.from(expected))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default defineEventHandler(async (event) => {
|
|
33
|
+
const secret = process.env.BRAIN_JOBS_SECRET?.trim(); // guard:allow-env-credential — deployment-level scheduler route secret
|
|
34
|
+
const scheduled = scheduledFunctionRuntime();
|
|
35
|
+
if (!secret && productionLike() && !scheduled) {
|
|
36
|
+
throw createError({
|
|
37
|
+
statusCode: 503,
|
|
38
|
+
statusMessage: "BRAIN_JOBS_SECRET is required",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (
|
|
42
|
+
secret &&
|
|
43
|
+
!scheduled &&
|
|
44
|
+
!headerMatchesSecret(getHeader(event, "authorization"), secret)
|
|
45
|
+
) {
|
|
46
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const [sync, queue, expiredSensitivityQuarantines] = await Promise.all([
|
|
50
|
+
syncDueBrainSourcesOnce({ system: true, limit: 5 }),
|
|
51
|
+
processBrainIngestQueueOnce({ limit: 1, runDistillation: true }),
|
|
52
|
+
expireSensitivityQuarantines(),
|
|
53
|
+
]);
|
|
54
|
+
return { ok: true, sync, queue, expiredSensitivityQuarantines };
|
|
55
|
+
});
|
|
@@ -85,7 +85,10 @@ in the moment of agent use.
|
|
|
85
85
|
approval, generative UI, progress, and screen-state exposure.
|
|
86
86
|
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
87
|
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
-
page-to-sidebar handoff.
|
|
88
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
89
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
90
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
91
|
+
actions.
|
|
89
92
|
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
93
|
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
94
|
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
|
|
75
|
+
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
|
|
76
76
|
|
|
77
77
|
## Which sources to depend on
|
|
78
78
|
|
|
@@ -85,7 +85,10 @@ in the moment of agent use.
|
|
|
85
85
|
approval, generative UI, progress, and screen-state exposure.
|
|
86
86
|
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
87
|
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
-
page-to-sidebar handoff.
|
|
88
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
89
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
90
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
91
|
+
actions.
|
|
89
92
|
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
93
|
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
94
|
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
@@ -72,7 +72,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
|
|
|
72
72
|
});
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events.
|
|
75
|
+
`useDbSync` and every `subscribeSyncEvents` subscriber share one `EventSource` and one fallback poll loop per tab — this is how collaborative documents receive doc updates and cursor/awareness events. Hidden tabs keep that shared transport alive by default: SSE stays connected and active fallback polling relaxes to a 10-second floor (idle polling remains once per minute). Pass `pauseWhenHidden: true` only for a consumer that explicitly must stop all hidden-tab sync.
|
|
76
76
|
|
|
77
77
|
## Which sources to depend on
|
|
78
78
|
|
|
@@ -9,7 +9,7 @@ import { useT } from "@agent-native/core/client/i18n";
|
|
|
9
9
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
10
10
|
import { FeedbackButton } from "@agent-native/core/client/ui";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
ChatHistoryRail,
|
|
13
13
|
type ChatHistoryItem,
|
|
14
14
|
} from "@agent-native/toolkit/chat-history";
|
|
15
15
|
import {
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
IconLayoutSidebarLeftCollapse,
|
|
18
18
|
IconLayoutSidebarLeftExpand,
|
|
19
19
|
IconMessageCircle,
|
|
20
|
-
IconPlus,
|
|
21
20
|
IconSettings,
|
|
22
21
|
} from "@tabler/icons-react";
|
|
23
22
|
import { useEffect, useMemo } from "react";
|
|
@@ -104,6 +103,12 @@ function persistedActiveThreadId() {
|
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
|
|
106
|
+
function persistActiveThreadId(threadId: string) {
|
|
107
|
+
try {
|
|
108
|
+
localStorage.setItem(CHAT_ACTIVE_THREAD_KEY, threadId);
|
|
109
|
+
} catch {}
|
|
110
|
+
}
|
|
111
|
+
|
|
107
112
|
function threadIdFromPath(pathname: string) {
|
|
108
113
|
const match = pathname.match(/^\/chat\/([^/]+)/);
|
|
109
114
|
if (!match) return null;
|
|
@@ -142,7 +147,7 @@ function ChatThreadsSection() {
|
|
|
142
147
|
threads
|
|
143
148
|
.filter((thread) => thread.messageCount > 0 && !thread.archivedAt)
|
|
144
149
|
.sort(compareThreads)
|
|
145
|
-
.slice(0,
|
|
150
|
+
.slice(0, 15),
|
|
146
151
|
[threads],
|
|
147
152
|
);
|
|
148
153
|
const displayedActiveThreadId =
|
|
@@ -184,6 +189,7 @@ function ChatThreadsSection() {
|
|
|
184
189
|
|
|
185
190
|
function openThread(threadId: string, options?: { isNew?: boolean }) {
|
|
186
191
|
switchThread(threadId);
|
|
192
|
+
persistActiveThreadId(threadId);
|
|
187
193
|
navigateWithAgentChatViewTransition(
|
|
188
194
|
navigate,
|
|
189
195
|
options?.isNew ? "/" : chatThreadPath(threadId),
|
|
@@ -223,50 +229,35 @@ function ChatThreadsSection() {
|
|
|
223
229
|
|
|
224
230
|
return (
|
|
225
231
|
<div className="mt-2 border-s border-sidebar-border/70 ps-3">
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
256
|
-
labels={{
|
|
257
|
-
options: (item) =>
|
|
258
|
-
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
259
|
-
renameInput: (item) =>
|
|
260
|
-
t("chat.renameThread", { title: item.titleText ?? "" }),
|
|
261
|
-
rename: t("chat.renameChat"),
|
|
262
|
-
pin: t("chat.pinChat"),
|
|
263
|
-
unpin: t("chat.unpinChat"),
|
|
264
|
-
delete: t("chat.archiveChat"),
|
|
265
|
-
}}
|
|
266
|
-
variant="rail"
|
|
267
|
-
className="min-w-0"
|
|
268
|
-
/>
|
|
269
|
-
)}
|
|
232
|
+
<ChatHistoryRail
|
|
233
|
+
items={chatItems}
|
|
234
|
+
activeId={displayedActiveThreadId}
|
|
235
|
+
onSelect={(threadId) => openThread(threadId)}
|
|
236
|
+
onNewChat={() => void handleNewChat()}
|
|
237
|
+
railLabels={{
|
|
238
|
+
newChat: t("chat.newChat"),
|
|
239
|
+
showMore: t("chat.chats"),
|
|
240
|
+
showLess: t("chat.chats"),
|
|
241
|
+
}}
|
|
242
|
+
renameMaxLength={160}
|
|
243
|
+
onTogglePin={(threadId) => {
|
|
244
|
+
const thread = visibleThreads.find((item) => item.id === threadId);
|
|
245
|
+
if (thread) void pinThread(threadId, !thread.pinnedAt);
|
|
246
|
+
}}
|
|
247
|
+
onRename={handleRenameThread}
|
|
248
|
+
onDelete={(threadId) => void handleArchiveThread(threadId)}
|
|
249
|
+
labels={{
|
|
250
|
+
options: (item) =>
|
|
251
|
+
t("chat.optionsFor", { title: item.titleText ?? "" }),
|
|
252
|
+
renameInput: (item) =>
|
|
253
|
+
t("chat.renameThread", { title: item.titleText ?? "" }),
|
|
254
|
+
rename: t("chat.renameChat"),
|
|
255
|
+
pin: t("chat.pinChat"),
|
|
256
|
+
unpin: t("chat.unpinChat"),
|
|
257
|
+
delete: t("chat.archiveChat"),
|
|
258
|
+
}}
|
|
259
|
+
className="min-w-0"
|
|
260
|
+
/>
|
|
270
261
|
</div>
|
|
271
262
|
);
|
|
272
263
|
}
|
|
@@ -445,28 +436,13 @@ export function Sidebar({
|
|
|
445
436
|
/>
|
|
446
437
|
</div>
|
|
447
438
|
|
|
448
|
-
|
|
449
|
-
className=
|
|
450
|
-
|
|
451
|
-
)}
|
|
452
|
-
>
|
|
453
|
-
<FeedbackButton
|
|
454
|
-
variant={collapsed ? "icon" : "sidebar"}
|
|
455
|
-
side="right"
|
|
456
|
-
align={collapsed ? "center" : "end"}
|
|
457
|
-
/>
|
|
458
|
-
</div>
|
|
459
|
-
|
|
460
|
-
{collapseButton ? (
|
|
461
|
-
<div
|
|
462
|
-
className={cn(
|
|
463
|
-
collapsed
|
|
464
|
-
? "flex justify-center px-1 py-1"
|
|
465
|
-
: "flex justify-end px-3 py-2",
|
|
466
|
-
)}
|
|
467
|
-
>
|
|
439
|
+
{!collapsed ? (
|
|
440
|
+
<div className="flex items-center justify-end gap-1 px-3 py-2">
|
|
441
|
+
<FeedbackButton className="min-w-0 flex-1" side="right" />
|
|
468
442
|
{collapseButton}
|
|
469
443
|
</div>
|
|
444
|
+
) : collapseButton ? (
|
|
445
|
+
<div className="flex justify-center px-1 py-1">{collapseButton}</div>
|
|
470
446
|
) : null}
|
|
471
447
|
</div>
|
|
472
448
|
</aside>
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isAgentChatHomeHandoffActive,
|
|
3
|
-
markAgentChatHomeHandoff,
|
|
4
|
-
} from "@agent-native/core/client/agent-chat";
|
|
1
|
+
import { markAgentChatHomeHandoff } from "@agent-native/core/client/agent-chat";
|
|
5
2
|
import { appBasePath, appPath } from "@agent-native/core/client/api-path";
|
|
6
3
|
import { useAgentRouteState } from "@agent-native/core/client/navigation";
|
|
7
4
|
import { useLocation } from "react-router";
|
|
@@ -34,9 +31,7 @@ export function useNavigationState() {
|
|
|
34
31
|
isChatPath(location.pathname) &&
|
|
35
32
|
!isChatPath(pathnameFromPath(path))
|
|
36
33
|
) {
|
|
37
|
-
|
|
38
|
-
markAgentChatHomeHandoff("chat");
|
|
39
|
-
}
|
|
34
|
+
markAgentChatHomeHandoff("chat");
|
|
40
35
|
}
|
|
41
36
|
},
|
|
42
37
|
});
|
|
@@ -36,6 +36,13 @@ export default function ChatRoute() {
|
|
|
36
36
|
const { threadId } = useParams();
|
|
37
37
|
const navigate = useNavigate();
|
|
38
38
|
const t = useT();
|
|
39
|
+
const threadUrlSync = threadId
|
|
40
|
+
? {
|
|
41
|
+
routeThreadId: threadId,
|
|
42
|
+
getPath: chatThreadPath,
|
|
43
|
+
navigate,
|
|
44
|
+
}
|
|
45
|
+
: undefined;
|
|
39
46
|
|
|
40
47
|
useEffect(() => {
|
|
41
48
|
function handleChatRunning(event: Event) {
|
|
@@ -56,11 +63,7 @@ export default function ChatRoute() {
|
|
|
56
63
|
className="h-full"
|
|
57
64
|
defaultMode="chat"
|
|
58
65
|
storageKey="chat"
|
|
59
|
-
threadUrlSync={
|
|
60
|
-
routeThreadId: threadId ?? null,
|
|
61
|
-
getPath: chatThreadPath,
|
|
62
|
-
navigate,
|
|
63
|
-
}}
|
|
66
|
+
threadUrlSync={threadUrlSync}
|
|
64
67
|
browserTabId={TAB_ID}
|
|
65
68
|
showHeader={false}
|
|
66
69
|
showTabBar={false}
|
|
@@ -85,7 +85,10 @@ in the moment of agent use.
|
|
|
85
85
|
approval, generative UI, progress, and screen-state exposure.
|
|
86
86
|
- **Chat history kit**: presentational chat lists and recent-chat rails belong
|
|
87
87
|
in Toolkit; Core keeps thread persistence, agent execution, transport, and
|
|
88
|
-
page-to-sidebar handoff.
|
|
88
|
+
page-to-sidebar handoff. Use Toolkit's `ChatHistoryRail` for the standard
|
|
89
|
+
five-item sidebar preview and a footer row with New chat followed by an
|
|
90
|
+
ellipsis disclosure up to fifteen. Apps inject routing, labels, and domain
|
|
91
|
+
actions.
|
|
89
92
|
- **Agent page kit**: the full-page `/agent` surface (`AgentTabsPage` from
|
|
90
93
|
`@agent-native/core/client`) with Context, Files, Connections, Jobs, and
|
|
91
94
|
Access tabs plus a Personal/Organization scope toggle. The canonical home
|
|
@@ -69,7 +69,15 @@ ladder.
|
|
|
69
69
|
current-user recordings with ready transcripts in the active organization
|
|
70
70
|
and reports exported, quarantined, skipped, and failed counts. Both
|
|
71
71
|
`BRAIN_INGEST_URL` and `BRAIN_INGEST_TOKEN` must be available as scoped Clips
|
|
72
|
-
secrets.
|
|
72
|
+
secrets. Transcript completion persists a pending export before handing it to
|
|
73
|
+
the durable post-finalize worker; delivery receipts include the Brain capture
|
|
74
|
+
or sensitivity receipt id, while transient failures are swept and retried.
|
|
75
|
+
The sweep also discovers ready transcripts from the last seven days that
|
|
76
|
+
predate export-state tracking, in bounded batches, so recent recordings are
|
|
77
|
+
backfilled after the connection is configured.
|
|
78
|
+
Netlify builds emit a protected per-minute scheduled sweep because in-process
|
|
79
|
+
intervals are not durable there. Other serverless hosts must invoke
|
|
80
|
+
`runBrainExportSweepOnce` from their own scheduler.
|
|
73
81
|
- The transcript embedded by `view-screen` is a bounded preview. If
|
|
74
82
|
`previewTruncated` is true, it may end mid-sentence and does not show where
|
|
75
83
|
transcription ended. Call `get-recording-player-data` before judging
|