@agent-native/core 0.129.2 → 0.130.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +72 -0
- package/corpus/core/docs/content/cloneable-saas.mdx +114 -0
- package/corpus/core/docs/content/creating-templates.mdx +28 -2
- package/corpus/core/docs/content/syncing-template-changes.mdx +7 -0
- package/corpus/core/docs/content/template-clips-developers.mdx +12 -5
- package/corpus/core/docs/content/template-dispatch-developers.mdx +1 -1
- package/corpus/core/docs/content/template-dispatch.mdx +1 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/action-ui.ts +1 -0
- package/corpus/core/src/action.ts +5 -1
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/corpus/core/src/agent/harness/runner.ts +5 -0
- package/corpus/core/src/agent/production-agent.ts +33 -0
- package/corpus/core/src/agent/run-loop-with-resume.ts +5 -0
- package/corpus/core/src/agent/run-manager.ts +126 -1
- package/corpus/core/src/agent/thread-data-builder.ts +47 -2
- package/corpus/core/src/agent/types.ts +2 -0
- package/corpus/core/src/chat-threads/store.ts +4 -5
- package/corpus/core/src/cli/create.ts +1139 -65
- package/corpus/core/src/cli/design-connect.ts +3 -7
- package/corpus/core/src/cli/index.ts +5 -3
- package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/corpus/core/src/client/AssistantChat.tsx +27 -16
- package/corpus/core/src/client/agent-chat-adapter.ts +24 -0
- package/corpus/core/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/message-components.tsx +104 -1
- package/corpus/core/src/client/chat/run-recovery.tsx +15 -3
- package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/corpus/core/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/corpus/core/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/corpus/core/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/corpus/core/src/client/embed-auth.ts +2 -0
- package/corpus/core/src/client/org/InvitationBanner.tsx +14 -1
- package/corpus/core/src/client/org/OrgSwitcher.tsx +23 -0
- package/corpus/core/src/client/org/TeamPage.tsx +130 -0
- package/corpus/core/src/client/org/WorkspaceNotice.tsx +85 -0
- package/corpus/core/src/client/org/hooks.ts +14 -0
- package/corpus/core/src/client/org/index.ts +2 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/corpus/core/src/client/resources/ResourcesPanel.tsx +134 -51
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/corpus/core/src/client/resources/use-resources.ts +6 -0
- package/corpus/core/src/client/use-action.ts +3 -1
- package/corpus/core/src/client/widgets/index.ts +1 -0
- package/corpus/core/src/coding-tools/run-code.ts +2 -1
- package/corpus/core/src/db/client.ts +28 -4
- package/corpus/core/src/deploy/build.ts +31 -3
- package/corpus/core/src/eject/remote-mcp-presets.ts +1 -1
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/index.ts +1 -0
- package/corpus/core/src/integrations/google-docs-poller.ts +3 -0
- package/corpus/core/src/integrations/webhook-handler.ts +28 -11
- package/corpus/core/src/jobs/scheduler.ts +4 -0
- package/corpus/core/src/localization/default-messages.ts +3 -2
- package/corpus/core/src/observability/traces.ts +48 -12
- package/corpus/core/src/org/handlers.ts +52 -1
- package/corpus/core/src/org/migrations.ts +4 -0
- package/corpus/core/src/org/plugin.ts +14 -0
- package/corpus/core/src/org/schema.ts +1 -0
- package/corpus/core/src/org/types.ts +8 -0
- package/corpus/core/src/org/workspace-url.ts +74 -0
- package/corpus/core/src/resources/handlers.ts +35 -5
- package/corpus/core/src/scripts/runner.ts +183 -5
- package/corpus/core/src/server/action-routes.ts +32 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +29 -0
- package/corpus/core/src/server/agent-teams.ts +10 -1
- package/corpus/core/src/server/auth.ts +33 -7
- package/corpus/core/src/server/embed-route.ts +9 -0
- package/corpus/core/src/server/embed-session.ts +62 -3
- package/corpus/core/src/server/open-route.ts +20 -6
- package/corpus/core/src/server/prompts/framework-core-compact.ts +1 -1
- package/corpus/core/src/server/prompts/framework-core.ts +1 -0
- package/corpus/core/src/server/request-context.ts +36 -1
- package/corpus/core/src/shared/embed-auth.ts +1 -0
- package/corpus/core/src/shared/html-document.ts +115 -0
- package/corpus/core/src/shared/index.ts +1 -0
- package/corpus/core/src/sharing/access.ts +8 -1
- package/corpus/core/src/sharing/registry.ts +11 -2
- package/corpus/core/src/workspace-files/actions.ts +100 -0
- package/corpus/core/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +4 -0
- package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +9 -1
- package/corpus/templates/analytics/AGENTS.md +17 -24
- package/corpus/templates/analytics/actions/data-source-status.ts +11 -1
- package/corpus/templates/analytics/app/i18n-data.ts +34 -0
- package/corpus/templates/analytics/app/lib/data-source-status.ts +86 -0
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +9 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +184 -20
- package/corpus/templates/analytics/changelog/2026-07-28-native-analytics-data-sources-no-longer-show-duplicate-mc.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-exports-now-appear-in-chat-with-a-direct-download-instead-of.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-queued-chat-prompts-no-longer-resend-after-analytics-navigat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-29-scheduled-dashboard-emails-load-every-panel-reliably-without.md +6 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +6 -3
- package/corpus/templates/analytics/server/lib/credential-keys.ts +1 -1
- package/corpus/templates/analytics/server/lib/hubspot.ts +1 -1
- package/corpus/templates/analytics/server/lib/provider-credentials.ts +55 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +123 -27
- package/corpus/templates/analytics/server/routes/[...page].get.ts +2 -7
- package/corpus/templates/analytics/vite.config.ts +7 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +100 -2
- package/corpus/templates/brain/app/lib/brain.ts +10 -0
- package/corpus/templates/brain/app/routes/sources.tsx +15 -4
- package/corpus/templates/brain/changelog/2026-07-29-brain-automatically-retries-failed-source-syncs-and-guides-y.md +6 -0
- package/corpus/templates/brain/jobs/process-ingest-queue.ts +13 -0
- package/corpus/templates/brain/server/jobs/sync-sources.ts +27 -22
- package/corpus/templates/brain/server/plugins/agent-chat.ts +2 -1
- package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +7 -1
- package/corpus/templates/clips/AGENTS.md +1 -1
- package/corpus/templates/clips/actions/create-recording-agent-link.ts +11 -1
- package/corpus/templates/clips/actions/update-comment.ts +68 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +0 -1
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +221 -65
- package/corpus/templates/clips/app/components/player/video-player.tsx +101 -27
- package/corpus/templates/clips/app/i18n/en-US.ts +2 -1
- package/corpus/templates/clips/app/routes/bug-report.done.tsx +48 -27
- package/corpus/templates/clips/app/routes/bug-report.tsx +43 -4
- package/corpus/templates/clips/app/routes/record.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-29-clip-playback-now-recovers-instead-of-getting-stuck-when-a-b.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-comments-can-now-be-edited-after-posting.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-download-actions-now-use-a-shorter-clearer-label.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-embedded-bug-reports-now-return-a-temporary-agent-readable.md +6 -0
- package/corpus/templates/clips/shared/bug-report.ts +99 -0
- package/corpus/templates/content/actions/_content-database-personal-view.ts +7 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +5 -2
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +20 -8
- package/corpus/templates/content/changelog/2026-07-29-missing-databases-no-longer-trigger-repeated-personal-view-e.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +83 -47
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +474 -55
- package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +3 -0
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +18 -1
- package/corpus/templates/design/.generated/bridge/source-location.generated.ts +348 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +2 -7
- package/corpus/templates/design/actions/apply-visual-edit.ts +7 -1
- package/corpus/templates/design/actions/connect-localhost.ts +5 -9
- package/corpus/templates/design/actions/create-component.ts +16 -13
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +4 -7
- package/corpus/templates/design/actions/list-local-files.ts +26 -50
- package/corpus/templates/design/actions/list-localhost-connections.ts +2 -7
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +2 -2
- package/corpus/templates/design/actions/open-visual-edit.ts +234 -135
- package/corpus/templates/design/actions/read-local-file.ts +26 -50
- package/corpus/templates/design/actions/request-localhost-write-consent.ts +2 -7
- package/corpus/templates/design/actions/write-local-file.ts +31 -73
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +307 -133
- package/corpus/templates/design/app/components/design/EditPanel.tsx +94 -22
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +137 -60
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +75 -14
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +755 -97
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +8 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +24 -1
- package/corpus/templates/design/app/components/design/bridge/source-location.bridge.ts +530 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbenchLoader.tsx +278 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +32 -12
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +14 -3
- package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +87 -24
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +36 -0
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +2 -1
- package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +48 -8
- package/corpus/templates/design/app/components/design/design-canvas/content-size-report.ts +3 -13
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +4 -2
- package/corpus/templates/design/app/components/design/design-canvas/hit-test.ts +3 -13
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/inspect-code-source.ts +93 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -2
- package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +35 -0
- package/corpus/templates/design/app/components/design/multi-screen/iframe-targeting.ts +24 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -0
- package/corpus/templates/design/app/components/design/types.ts +29 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -4
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +153 -46
- package/corpus/templates/design/app/i18n-responsive-interact.ts +12 -12
- package/corpus/templates/design/app/lib/design-editor-route.ts +23 -0
- package/corpus/templates/design/app/pages/VisualEdit.tsx +19 -6
- package/corpus/templates/design/app/pages/design-editor/action-error.ts +19 -0
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +29 -0
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +6 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +277 -15
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +75 -9
- package/corpus/templates/design/app/pages/design-editor/layer-state-scope.ts +28 -0
- package/corpus/templates/design/app/pages/design-editor/live-screen-layer-drop.ts +41 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +496 -41
- package/corpus/templates/design/app/pages/design-editor/pending-live-edit-unload-guard.ts +27 -0
- package/corpus/templates/design/app/pages/design-editor/pending-structure-verification.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +168 -9
- package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +41 -3
- package/corpus/templates/design/app/pages/design-editor/screen-command-utils.ts +5 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +42 -13
- package/corpus/templates/design/app/pages/design-editor/source-location.ts +180 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +17 -0
- package/corpus/templates/design/app/public-routes.ts +1 -0
- package/corpus/templates/design/app/routes/visual-edit.$id.tsx +15 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-is-easier-to-find-and-named-screens-open-dir.md +1 -1
- package/corpus/templates/design/changelog/2026-07-28-deleting-a-selected-element-now-removes-it-from-the-live-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-deleting-an-element-on-a-connected-localhost-screen-now-queu.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-shows-a-responsive-device-preview-with-pre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layer-hide-and-lock-now-apply-to-the-live-preview-instead-of.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-layers-panel-selections-on-a-connected-localhost-screen-can-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-locked-layers-now-show-a-subtle-dashed-outline-in-the-live-p.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-apply-design-updates-button-now-counts-pending-live-text.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-the-design-canvas-no-longer-stalls-on-a-render-loop-while-a-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edit-on-a-local-dev-server-no-longer-requires-signing.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-visual-edits-on-a-react-19-app-no-longer-report-a-source-lin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-an-edit-that-cannot-be-written-to-source-now-names-the-reaso.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-applying-a-primitive-dropped-onto-a-connected-localhost-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-changing-a-style-in-the-inspector-now-updates-a-connected-lo.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-choosing-edit-or-annotate-from-a-focused-screen-now-returns-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-concurrent-source-edits-now-return-a-clear-conflict-response.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-creating-a-component-from-an-element-that-repeats-in-the-sou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-deleting-an-element-you-just-dropped-onto-a-live-screen-no-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-a-layer-across-screens-no-longer-dies-when-the-poin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-dragging-an-element-from-a-stored-screen-into-a-live-localho.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-drawing-a-box-on-the-canvas-and-dragging-it-into-a-connected.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-fixed-a-loading-screen-flicker-when-reopening-designs-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-interact-mode-has-edit-and-annotate-buttons-again-so-you-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-layer-groups-can-be-dropped-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-localhost-source-errors-now-say-what-actually-went-wrong-whi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-opening-or-refreshing-a-live-localhost-screen-in-single-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-redo-after-undoing-a-drop-onto-a-live-screen-puts-the-elemen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-can-be-drawn-directly-onto-live-localhost-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-shapes-drawn-on-the-canvas-board-now-appear-immediately-inst.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-style-edits-on-a-running-localhost-screen-now-preview-live-a.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-the-apply-design-updates-control-now-appears-as-a-clean-conn.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-visual-edits-on-a-mapped-component-instance-now-tell-the-age.md +6 -0
- package/corpus/templates/design/server/lib/design-data-access.ts +21 -7
- package/corpus/templates/design/server/lib/localhost-connection.ts +240 -0
- package/corpus/templates/design/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/design/server/source-workspace.ts +2 -0
- package/corpus/templates/design/shared/code-layer.ts +43 -0
- package/corpus/templates/design/shared/html-content.ts +26 -0
- package/corpus/templates/design/shared/html-integrity.ts +21 -1
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +15 -0
- package/corpus/templates/design/shared/source-mode.ts +76 -0
- package/corpus/templates/dispatch/changelog/2026-07-29-workspace-members-without-admin-access-now-see-a-clear-permi.md +6 -0
- package/corpus/templates/dispatch/server/lib/usage-metrics.ts +2 -1
- package/corpus/templates/plan/app/lib/plan-annotation-runtime.ts +3 -4
- package/corpus/templates/plan/server/routes/[...page].get.ts +2 -5
- package/corpus/templates/slides/actions/patch-deck.ts +29 -17
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +3 -2
- package/dist/action-ui.d.ts +1 -0
- package/dist/action-ui.d.ts.map +1 -1
- package/dist/action-ui.js +1 -0
- package/dist/action-ui.js.map +1 -1
- package/dist/action.d.ts +5 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +13 -5
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/harness/runner.d.ts.map +1 -1
- package/dist/agent/harness/runner.js +5 -0
- package/dist/agent/harness/runner.js.map +1 -1
- package/dist/agent/production-agent.d.ts +16 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +18 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +6 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/agent/run-manager.d.ts +14 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +91 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +3 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +35 -3
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +2 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +4 -6
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts +66 -6
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +765 -66
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +2 -7
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/index.js +5 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +83 -47
- package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +16 -9
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -0
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.d.ts +2 -0
- package/dist/client/blocks/library/wireframe-kit.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe-kit.js +8 -2
- package/dist/client/blocks/library/wireframe-kit.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +17 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +24 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts +6 -0
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +13 -3
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
- package/dist/client/chat/widgets/DataTableWidget.js +2 -3
- package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts +5 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.d.ts.map +1 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js +34 -0
- package/dist/client/chat/widgets/WorkspaceFileWidget.js.map +1 -0
- package/dist/client/chat/widgets/builtin-tool-renderers.d.ts.map +1 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js +13 -1
- package/dist/client/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/client/chat/widgets/workspace-file-result.d.ts +12 -0
- package/dist/client/chat/widgets/workspace-file-result.d.ts.map +1 -0
- package/dist/client/chat/widgets/workspace-file-result.js +34 -0
- package/dist/client/chat/widgets/workspace-file-result.js.map +1 -0
- package/dist/client/embed-auth.d.ts.map +1 -1
- package/dist/client/embed-auth.js +2 -1
- package/dist/client/embed-auth.js.map +1 -1
- package/dist/client/org/InvitationBanner.d.ts +5 -2
- package/dist/client/org/InvitationBanner.d.ts.map +1 -1
- package/dist/client/org/InvitationBanner.js +9 -2
- package/dist/client/org/InvitationBanner.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +3 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +27 -3
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/WorkspaceNotice.d.ts +18 -0
- package/dist/client/org/WorkspaceNotice.d.ts.map +1 -0
- package/dist/client/org/WorkspaceNotice.js +56 -0
- package/dist/client/org/WorkspaceNotice.js.map +1 -0
- package/dist/client/org/hooks.d.ts +1 -0
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +12 -0
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/org/index.d.ts +2 -1
- package/dist/client/org/index.d.ts.map +1 -1
- package/dist/client/org/index.js +2 -1
- package/dist/client/org/index.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +8 -12
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts +3 -0
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +49 -20
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- 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 +3 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +1 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +3 -0
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/use-action.d.ts +3 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +3 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/widgets/index.d.ts +1 -1
- package/dist/client/widgets/index.d.ts.map +1 -1
- package/dist/client/widgets/index.js +1 -1
- package/dist/client/widgets/index.js.map +1 -1
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/run-code.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/db/client.d.ts +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +24 -3
- package/dist/db/client.js.map +1 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +25 -3
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/remote-mcp-presets.js +1 -1
- package/dist/eject/remote-mcp-presets.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/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +4 -1
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +23 -11
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.js +4 -0
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -2
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -2
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +27 -7
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/handlers.d.ts +15 -0
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +45 -1
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/migrations.d.ts.map +1 -1
- package/dist/org/migrations.js +4 -0
- package/dist/org/migrations.js.map +1 -1
- package/dist/org/plugin.d.ts +1 -0
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +10 -1
- package/dist/org/plugin.js.map +1 -1
- package/dist/org/schema.d.ts +19 -0
- package/dist/org/schema.d.ts.map +1 -1
- package/dist/org/schema.js +1 -0
- package/dist/org/schema.js.map +1 -1
- package/dist/org/types.d.ts +8 -0
- package/dist/org/types.d.ts.map +1 -1
- package/dist/org/types.js.map +1 -1
- package/dist/org/workspace-url.d.ts +32 -0
- package/dist/org/workspace-url.d.ts.map +1 -0
- package/dist/org/workspace-url.js +63 -0
- package/dist/org/workspace-url.js.map +1 -0
- 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/resources/handlers.d.ts +2 -3
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +25 -5
- package/dist/resources/handlers.js.map +1 -1
- package/dist/scripts/runner.d.ts +17 -0
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +130 -5
- package/dist/scripts/runner.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +24 -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 +26 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +10 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/auth.d.ts +22 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +33 -7
- package/dist/server/auth.js.map +1 -1
- package/dist/server/embed-route.d.ts.map +1 -1
- package/dist/server/embed-route.js +6 -1
- package/dist/server/embed-route.js.map +1 -1
- package/dist/server/embed-session.d.ts +7 -0
- package/dist/server/embed-session.d.ts.map +1 -1
- package/dist/server/embed-session.js +46 -4
- package/dist/server/embed-session.js.map +1 -1
- package/dist/server/open-route.d.ts.map +1 -1
- package/dist/server/open-route.js +17 -7
- package/dist/server/open-route.js.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +1 -1
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +1 -0
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +26 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +18 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/embed-auth.d.ts +1 -0
- package/dist/shared/embed-auth.d.ts.map +1 -1
- package/dist/shared/embed-auth.js +1 -0
- package/dist/shared/embed-auth.js.map +1 -1
- package/dist/shared/html-document.d.ts +12 -0
- package/dist/shared/html-document.d.ts.map +1 -0
- package/dist/shared/html-document.js +92 -0
- package/dist/shared/html-document.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/index.js +1 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/sharing/access.d.ts +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +8 -2
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/registry.d.ts +3 -0
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/workspace-files/actions.d.ts +28 -0
- package/dist/workspace-files/actions.d.ts.map +1 -0
- package/dist/workspace-files/actions.js +75 -0
- package/dist/workspace-files/actions.js.map +1 -0
- package/dist/workspace-files/tool.d.ts.map +1 -1
- package/dist/workspace-files/tool.js +4 -0
- package/dist/workspace-files/tool.js.map +1 -1
- package/docs/content/cloneable-saas.mdx +114 -0
- package/docs/content/creating-templates.mdx +28 -2
- package/docs/content/syncing-template-changes.mdx +7 -0
- package/docs/content/template-clips-developers.mdx +12 -5
- package/docs/content/template-dispatch-developers.mdx +1 -1
- package/docs/content/template-dispatch.mdx +1 -1
- package/package.json +2 -2
- package/src/action-ui.ts +1 -0
- package/src/action.ts +5 -1
- package/src/agent/engine/ai-sdk-engine.ts +15 -5
- package/src/agent/harness/runner.ts +5 -0
- package/src/agent/production-agent.ts +33 -0
- package/src/agent/run-loop-with-resume.ts +5 -0
- package/src/agent/run-manager.ts +126 -1
- package/src/agent/thread-data-builder.ts +47 -2
- package/src/agent/types.ts +2 -0
- package/src/chat-threads/store.ts +4 -5
- package/src/cli/create.ts +1139 -65
- package/src/cli/design-connect.ts +3 -7
- package/src/cli/index.ts +5 -3
- package/src/cli/skills-content/design-visual-edit-skill.ts +83 -47
- package/src/client/AssistantChat.tsx +27 -16
- package/src/client/agent-chat-adapter.ts +24 -0
- package/src/client/blocks/library/wireframe-kit.tsx +17 -2
- package/src/client/chat/index.ts +1 -0
- package/src/client/chat/message-components.tsx +104 -1
- package/src/client/chat/run-recovery.tsx +15 -3
- package/src/client/chat/widgets/DataTableWidget.tsx +10 -29
- package/src/client/chat/widgets/WorkspaceFileWidget.tsx +71 -0
- package/src/client/chat/widgets/builtin-tool-renderers.tsx +22 -0
- package/src/client/chat/widgets/workspace-file-result.ts +49 -0
- package/src/client/embed-auth.ts +2 -0
- package/src/client/org/InvitationBanner.tsx +14 -1
- package/src/client/org/OrgSwitcher.tsx +23 -0
- package/src/client/org/TeamPage.tsx +130 -0
- package/src/client/org/WorkspaceNotice.tsx +85 -0
- package/src/client/org/hooks.ts +14 -0
- package/src/client/org/index.ts +2 -0
- package/src/client/resources/McpIntegrationDialog.tsx +27 -40
- package/src/client/resources/ResourcesPanel.tsx +134 -51
- package/src/client/resources/mcp-integration-catalog.ts +7 -0
- package/src/client/resources/use-resources.ts +6 -0
- package/src/client/use-action.ts +3 -1
- package/src/client/widgets/index.ts +1 -0
- package/src/coding-tools/run-code.ts +2 -1
- package/src/db/client.ts +28 -4
- package/src/deploy/build.ts +31 -3
- package/src/eject/remote-mcp-presets.ts +1 -1
- package/src/index.browser.ts +1 -0
- package/src/index.ts +1 -0
- package/src/integrations/google-docs-poller.ts +3 -0
- package/src/integrations/webhook-handler.ts +28 -11
- package/src/jobs/scheduler.ts +4 -0
- package/src/localization/default-messages.ts +3 -2
- package/src/observability/traces.ts +48 -12
- package/src/org/handlers.ts +52 -1
- package/src/org/migrations.ts +4 -0
- package/src/org/plugin.ts +14 -0
- package/src/org/schema.ts +1 -0
- package/src/org/types.ts +8 -0
- package/src/org/workspace-url.ts +74 -0
- package/src/resources/handlers.ts +35 -5
- package/src/scripts/runner.ts +183 -5
- package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +2 -1
- package/src/server/action-routes.ts +32 -2
- package/src/server/agent-chat-plugin.ts +29 -0
- package/src/server/agent-teams.ts +10 -1
- package/src/server/auth.ts +33 -7
- package/src/server/embed-route.ts +9 -0
- package/src/server/embed-session.ts +62 -3
- package/src/server/open-route.ts +20 -6
- package/src/server/prompts/framework-core-compact.ts +1 -1
- package/src/server/prompts/framework-core.ts +1 -0
- package/src/server/request-context.ts +36 -1
- package/src/shared/embed-auth.ts +1 -0
- package/src/shared/html-document.ts +115 -0
- package/src/shared/index.ts +1 -0
- package/src/sharing/access.ts +8 -1
- package/src/sharing/registry.ts +11 -2
- package/src/workspace-files/actions.ts +100 -0
- package/src/workspace-files/tool.ts +4 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +0 -6
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +0 -6
|
@@ -172,7 +172,9 @@ interface DataSourceStatusSummary {
|
|
|
172
172
|
externalSourceLabels: string[];
|
|
173
173
|
availableExternalSources: Array<{
|
|
174
174
|
aliases: string[];
|
|
175
|
-
configured: boolean;
|
|
175
|
+
configured: boolean | null;
|
|
176
|
+
label?: string;
|
|
177
|
+
setupLink?: string;
|
|
176
178
|
}>;
|
|
177
179
|
setupLink: string;
|
|
178
180
|
}
|
|
@@ -242,7 +244,7 @@ function hasMissingRequestedExternalSource(
|
|
|
242
244
|
const configuredAliases = [
|
|
243
245
|
...configuredSourceLabels.map((label) => [label]),
|
|
244
246
|
...availableExternalSources
|
|
245
|
-
.filter(({ configured }) => configured)
|
|
247
|
+
.filter(({ configured }) => configured === true)
|
|
246
248
|
.map(({ aliases }) => aliases),
|
|
247
249
|
];
|
|
248
250
|
const sourceAliases = [
|
|
@@ -256,12 +258,21 @@ function hasMissingRequestedExternalSource(
|
|
|
256
258
|
.filter(({ terms }) =>
|
|
257
259
|
terms.some((term) => containsNormalizedPhrase(userText, term)),
|
|
258
260
|
)
|
|
259
|
-
.some(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
.some(({ aliases }) => {
|
|
262
|
+
const matchingStatuses = availableExternalSources.filter((source) =>
|
|
263
|
+
sourceAliasesOverlap(source.aliases, aliases),
|
|
264
|
+
);
|
|
265
|
+
if (
|
|
266
|
+
matchingStatuses.some(
|
|
267
|
+
({ configured }) => configured === true || configured === null,
|
|
268
|
+
)
|
|
269
|
+
) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
return !configuredAliases.some((configured) =>
|
|
273
|
+
sourceAliasesOverlap(configured, aliases),
|
|
274
|
+
);
|
|
275
|
+
});
|
|
265
276
|
}
|
|
266
277
|
|
|
267
278
|
function dataSourceStatusSummary(
|
|
@@ -270,7 +281,7 @@ function dataSourceStatusSummary(
|
|
|
270
281
|
const externalSourceLabels = new Set<string>();
|
|
271
282
|
const availableExternalSources = new Map<
|
|
272
283
|
string,
|
|
273
|
-
|
|
284
|
+
DataSourceStatusSummary["availableExternalSources"][number]
|
|
274
285
|
>();
|
|
275
286
|
let checked = false;
|
|
276
287
|
let setupLink = ANALYTICS_DATA_SOURCES_LINK;
|
|
@@ -278,7 +289,8 @@ function dataSourceStatusSummary(
|
|
|
278
289
|
const addAvailableExternalSource = (
|
|
279
290
|
provider: unknown,
|
|
280
291
|
label: unknown,
|
|
281
|
-
configured: boolean,
|
|
292
|
+
configured: boolean | null,
|
|
293
|
+
providerSetupLink?: unknown,
|
|
282
294
|
) => {
|
|
283
295
|
const aliases = [provider, label]
|
|
284
296
|
.filter((value): value is string => typeof value === "string")
|
|
@@ -288,11 +300,35 @@ function dataSourceStatusSummary(
|
|
|
288
300
|
if (!key) return;
|
|
289
301
|
const existing = availableExternalSources.get(key);
|
|
290
302
|
if (existing) {
|
|
291
|
-
existing.configured
|
|
303
|
+
existing.configured =
|
|
304
|
+
existing.configured === true || configured === true
|
|
305
|
+
? true
|
|
306
|
+
: existing.configured === null || configured === null
|
|
307
|
+
? null
|
|
308
|
+
: false;
|
|
292
309
|
existing.aliases = [...new Set([...existing.aliases, ...aliases])];
|
|
310
|
+
if (!existing.label && typeof label === "string" && label.trim()) {
|
|
311
|
+
existing.label = label.trim();
|
|
312
|
+
}
|
|
313
|
+
if (
|
|
314
|
+
!existing.setupLink &&
|
|
315
|
+
typeof providerSetupLink === "string" &&
|
|
316
|
+
providerSetupLink.trim()
|
|
317
|
+
) {
|
|
318
|
+
existing.setupLink = providerSetupLink.trim();
|
|
319
|
+
}
|
|
293
320
|
return;
|
|
294
321
|
}
|
|
295
|
-
availableExternalSources.set(key, {
|
|
322
|
+
availableExternalSources.set(key, {
|
|
323
|
+
aliases,
|
|
324
|
+
configured,
|
|
325
|
+
...(typeof label === "string" && label.trim()
|
|
326
|
+
? { label: label.trim() }
|
|
327
|
+
: {}),
|
|
328
|
+
...(typeof providerSetupLink === "string" && providerSetupLink.trim()
|
|
329
|
+
? { setupLink: providerSetupLink.trim() }
|
|
330
|
+
: {}),
|
|
331
|
+
});
|
|
296
332
|
};
|
|
297
333
|
|
|
298
334
|
for (const result of toolResults ?? []) {
|
|
@@ -373,7 +409,12 @@ function dataSourceStatusSummary(
|
|
|
373
409
|
if (typeof label === "string" && label.trim()) {
|
|
374
410
|
externalSourceLabels.add(label.trim());
|
|
375
411
|
}
|
|
376
|
-
addAvailableExternalSource(
|
|
412
|
+
addAvailableExternalSource(
|
|
413
|
+
record.provider,
|
|
414
|
+
label,
|
|
415
|
+
true,
|
|
416
|
+
record.setupLink,
|
|
417
|
+
);
|
|
377
418
|
}
|
|
378
419
|
|
|
379
420
|
// Backward compatibility for status responses that predate the compact
|
|
@@ -393,12 +434,15 @@ function dataSourceStatusSummary(
|
|
|
393
434
|
.toLowerCase();
|
|
394
435
|
if (providerId === "first-party") continue;
|
|
395
436
|
const label = record.label ?? record.provider;
|
|
437
|
+
const configured =
|
|
438
|
+
typeof record.configured === "boolean" ? record.configured : null;
|
|
396
439
|
addAvailableExternalSource(
|
|
397
440
|
record.provider,
|
|
398
441
|
label,
|
|
399
|
-
|
|
442
|
+
configured,
|
|
443
|
+
record.setupLink,
|
|
400
444
|
);
|
|
401
|
-
if (
|
|
445
|
+
if (configured !== true) continue;
|
|
402
446
|
if (typeof label === "string" && label.trim()) {
|
|
403
447
|
externalSourceLabels.add(label.trim());
|
|
404
448
|
}
|
|
@@ -418,8 +462,17 @@ function dataSourceStatusSummary(
|
|
|
418
462
|
const record = provider as Record<string, unknown>;
|
|
419
463
|
const providerId = record.id ?? record.provider;
|
|
420
464
|
const label = record.label ?? providerId;
|
|
465
|
+
const grantState =
|
|
466
|
+
typeof record.grantState === "string" ? record.grantState : null;
|
|
421
467
|
const configured =
|
|
422
|
-
record.configured === true ||
|
|
468
|
+
record.configured === true || grantState === "connected"
|
|
469
|
+
? true
|
|
470
|
+
: record.configured === false ||
|
|
471
|
+
grantState === "granted" ||
|
|
472
|
+
grantState === "needs_grant" ||
|
|
473
|
+
grantState === "not_connected"
|
|
474
|
+
? false
|
|
475
|
+
: null;
|
|
423
476
|
addAvailableExternalSource(providerId, label, configured);
|
|
424
477
|
if (configured && typeof label === "string" && label.trim()) {
|
|
425
478
|
externalSourceLabels.add(label.trim());
|
|
@@ -435,6 +488,34 @@ function dataSourceStatusSummary(
|
|
|
435
488
|
};
|
|
436
489
|
}
|
|
437
490
|
|
|
491
|
+
function requestedExternalSourceSetup(
|
|
492
|
+
userText: string,
|
|
493
|
+
summary: DataSourceStatusSummary,
|
|
494
|
+
): { label: string; setupLink: string } | null {
|
|
495
|
+
let source:
|
|
496
|
+
| DataSourceStatusSummary["availableExternalSources"][number]
|
|
497
|
+
| undefined;
|
|
498
|
+
let bestMatchLength = -1;
|
|
499
|
+
for (const candidate of summary.availableExternalSources) {
|
|
500
|
+
if (candidate.configured !== false || !candidate.setupLink) continue;
|
|
501
|
+
const matchLength = Math.max(
|
|
502
|
+
-1,
|
|
503
|
+
...candidate.aliases
|
|
504
|
+
.filter((alias) => containsNormalizedPhrase(userText, alias))
|
|
505
|
+
.map((alias) => normalizeSourceLabel(alias).length),
|
|
506
|
+
);
|
|
507
|
+
if (matchLength > bestMatchLength) {
|
|
508
|
+
source = candidate;
|
|
509
|
+
bestMatchLength = matchLength;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if (!source?.setupLink) return null;
|
|
513
|
+
return {
|
|
514
|
+
label: source.label ?? source.aliases[0] ?? "data source",
|
|
515
|
+
setupLink: source.setupLink,
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
438
519
|
function includesDataSourcesLink(text: string, setupLink: string): boolean {
|
|
439
520
|
const normalizedSetupLink = setupLink.trim().replace(/&/g, "&");
|
|
440
521
|
if (!normalizedSetupLink) return false;
|
|
@@ -475,8 +556,23 @@ export function realDataFinalGuard(
|
|
|
475
556
|
const incompleteEvidence = hasIncompleteDataEvidence(context.toolResults);
|
|
476
557
|
const dataQueryAttempted = hasDataQueryAttempt(context.toolResults);
|
|
477
558
|
const sourceStatus = dataSourceStatusSummary(context.toolResults);
|
|
559
|
+
const requestedSourceSetup = requestedExternalSourceSetup(
|
|
560
|
+
userText,
|
|
561
|
+
sourceStatus,
|
|
562
|
+
);
|
|
563
|
+
const setupLink = requestedSourceSetup?.setupLink ?? sourceStatus.setupLink;
|
|
564
|
+
const setupLabel = requestedSourceSetup
|
|
565
|
+
? `Connect ${requestedSourceSetup.label}`
|
|
566
|
+
: "Connect data sources";
|
|
567
|
+
const setupMarkdown = `[${setupLabel}](${setupLink})`;
|
|
568
|
+
const hasUnknownExternalSourceStatus =
|
|
569
|
+
sourceStatus.availableExternalSources.some(
|
|
570
|
+
({ configured }) => configured === null,
|
|
571
|
+
);
|
|
478
572
|
const noConnectedExternalSources =
|
|
479
|
-
sourceStatus.checked &&
|
|
573
|
+
sourceStatus.checked &&
|
|
574
|
+
sourceStatus.externalSourceLabels.length === 0 &&
|
|
575
|
+
!hasUnknownExternalSourceStatus;
|
|
480
576
|
const externalSourceRequest = looksLikeExternalSourceRequest(userText);
|
|
481
577
|
const missingRequestedExternalSource = hasMissingRequestedExternalSource(
|
|
482
578
|
userText,
|
|
@@ -601,11 +697,11 @@ export function realDataFinalGuard(
|
|
|
601
697
|
}
|
|
602
698
|
if (
|
|
603
699
|
needsDataSourceLink &&
|
|
604
|
-
!includesDataSourcesLink(context.text,
|
|
700
|
+
!includesDataSourcesLink(context.text, setupLink)
|
|
605
701
|
) {
|
|
606
702
|
return {
|
|
607
|
-
retryMessage: `The response correctly explains that the requested live data is unavailable, but it needs a contextual next step. Explain which external source is missing, keep the conversation open, and include this exact markdown link:
|
|
608
|
-
fallbackMessage: `I can help with that once the relevant source is connected.
|
|
703
|
+
retryMessage: `The response correctly explains that the requested live data is unavailable, but it needs a contextual next step. Explain which external source is missing, keep the conversation open, and include this exact markdown link: ${setupMarkdown}. Do not use the generic no-grounded-data fallback.`,
|
|
704
|
+
fallbackMessage: `I can help with that once the relevant source is connected. ${setupMarkdown}`,
|
|
609
705
|
maxRetries: 2,
|
|
610
706
|
};
|
|
611
707
|
}
|
|
@@ -615,11 +711,11 @@ export function realDataFinalGuard(
|
|
|
615
711
|
if (failedQueryMessage) {
|
|
616
712
|
if (
|
|
617
713
|
needsDataSourceLink &&
|
|
618
|
-
!includesDataSourcesLink(context.text,
|
|
714
|
+
!includesDataSourcesLink(context.text, setupLink)
|
|
619
715
|
) {
|
|
620
716
|
return {
|
|
621
|
-
retryMessage: `${failedQueryMessage} Explain which external source is missing and include this exact markdown link:
|
|
622
|
-
fallbackMessage: `${failedQueryMessage}
|
|
717
|
+
retryMessage: `${failedQueryMessage} Explain which external source is missing and include this exact markdown link: ${setupMarkdown}.`,
|
|
718
|
+
fallbackMessage: `${failedQueryMessage} ${setupMarkdown}`,
|
|
623
719
|
maxRetries: 2,
|
|
624
720
|
};
|
|
625
721
|
}
|
|
@@ -635,8 +731,8 @@ export function realDataFinalGuard(
|
|
|
635
731
|
(noConnectedExternalSources && externalSourceRequest))
|
|
636
732
|
) {
|
|
637
733
|
return {
|
|
638
|
-
retryMessage: `The requested external source is not connected. Explain what is missing in the context of the user's question and include this exact markdown link:
|
|
639
|
-
fallbackMessage: `I can help with that once the relevant source is connected.
|
|
734
|
+
retryMessage: `The requested external source is not connected. Explain what is missing in the context of the user's question and include this exact markdown link: ${setupMarkdown}. Do not use the generic no-grounded-data fallback.`,
|
|
735
|
+
fallbackMessage: `I can help with that once the relevant source is connected. ${setupMarkdown}`,
|
|
640
736
|
maxRetries: 2,
|
|
641
737
|
expandToolSurface: true,
|
|
642
738
|
};
|
|
@@ -655,8 +751,8 @@ export function realDataFinalGuard(
|
|
|
655
751
|
}
|
|
656
752
|
if (noConnectedExternalSources) {
|
|
657
753
|
return {
|
|
658
|
-
retryMessage: `The user asked for live analytics, but data-source-status found no connected external providers. The built-in first-party source is still available for first-party Analytics data. If this request needs an external source, respond naturally in the context of the user's question, explain what is missing, and include
|
|
659
|
-
fallbackMessage: `I can help with that once the relevant source is connected.
|
|
754
|
+
retryMessage: `The user asked for live analytics, but data-source-status found no connected external providers. The built-in first-party source is still available for first-party Analytics data. If this request needs an external source, respond naturally in the context of the user's question, explain what is missing, and include ${setupMarkdown}. Do not use a generic canned no-data response.`,
|
|
755
|
+
fallbackMessage: `I can help with that once the relevant source is connected. ${setupMarkdown}`,
|
|
660
756
|
maxRetries: 2,
|
|
661
757
|
expandToolSurface: true,
|
|
662
758
|
};
|
|
@@ -2,6 +2,7 @@ import { AGENT_ACCESS_PARAM } from "@agent-native/core/server";
|
|
|
2
2
|
import { createH3SSRHandler } from "@agent-native/core/server/ssr-handler";
|
|
3
3
|
import {
|
|
4
4
|
buildAgentReadableResourceDiscovery,
|
|
5
|
+
injectDocumentMarkup,
|
|
5
6
|
renderAgentReadableResourceDiscoveryScript,
|
|
6
7
|
} from "@agent-native/core/shared";
|
|
7
8
|
import {
|
|
@@ -140,13 +141,7 @@ function injectAgentDiscovery(html: string, script: string): string {
|
|
|
140
141
|
if (scriptId && html.includes(`id="${scriptId}"`)) {
|
|
141
142
|
return html;
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
-
return html.replace("</head>", `${script}</head>`);
|
|
145
|
-
}
|
|
146
|
-
if (html.includes("</body>")) {
|
|
147
|
-
return html.replace("</body>", `${script}</body>`);
|
|
148
|
-
}
|
|
149
|
-
return `${html}${script}`;
|
|
144
|
+
return injectDocumentMarkup(html, script, { target: "head" });
|
|
150
145
|
}
|
|
151
146
|
|
|
152
147
|
export default defineEventHandler(async (event) => {
|
|
@@ -2,6 +2,8 @@ import { agentNative } from "@agent-native/core/vite";
|
|
|
2
2
|
import { reactRouter } from "@react-router/dev/vite";
|
|
3
3
|
import { defineConfig } from "vite";
|
|
4
4
|
|
|
5
|
+
import { ANALYTICS_NATIVE_MCP_PRESET_EXCLUSIONS } from "./app/lib/native-mcp-exclusions";
|
|
6
|
+
|
|
5
7
|
const reactRouterPlugins = reactRouter as unknown as () => any[];
|
|
6
8
|
const agentNativePlugins = agentNative as unknown as (
|
|
7
9
|
options?: Parameters<typeof agentNative>[0],
|
|
@@ -14,6 +16,11 @@ export default defineConfig({
|
|
|
14
16
|
// shiki only runs in AssistantChat's useEffect — keep it out of the
|
|
15
17
|
// CF Pages Functions bundle (25 MiB limit).
|
|
16
18
|
ssrStubs: ["shiki"],
|
|
19
|
+
// Native data-source actions own these providers in Analytics; showing
|
|
20
|
+
// their MCP presets would create a second, conflicting setup path.
|
|
21
|
+
mcpIntegrations: {
|
|
22
|
+
defaults: { exclude: [...ANALYTICS_NATIVE_MCP_PRESET_EXCLUSIONS] },
|
|
23
|
+
},
|
|
17
24
|
}),
|
|
18
25
|
],
|
|
19
26
|
});
|
|
@@ -30,6 +30,59 @@ const SUPPORTED_SOURCE_PROVIDERS = new Set([
|
|
|
30
30
|
"github",
|
|
31
31
|
]);
|
|
32
32
|
|
|
33
|
+
function dispatchIntegrationsHref(providerId: string) {
|
|
34
|
+
const params = new URLSearchParams({
|
|
35
|
+
provider: providerId,
|
|
36
|
+
appId: APP_ID,
|
|
37
|
+
returnTo: "ask",
|
|
38
|
+
});
|
|
39
|
+
return `/dispatch/integrations?${params.toString()}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function providerApiConfigured({
|
|
43
|
+
credentialHealth,
|
|
44
|
+
providerApi,
|
|
45
|
+
workspace,
|
|
46
|
+
}: {
|
|
47
|
+
credentialHealth: Awaited<ReturnType<typeof credentialHealthForProvider>>;
|
|
48
|
+
providerApi: ReturnType<typeof listProviderApiCatalog>[number] | null;
|
|
49
|
+
workspace: WorkspaceConnectionProviderAppSummary;
|
|
50
|
+
}): boolean | null {
|
|
51
|
+
if (!providerApi) return null;
|
|
52
|
+
if (workspace.hasActiveWorkspaceConnection) return true;
|
|
53
|
+
if (providerApi.auth === "none") return true;
|
|
54
|
+
|
|
55
|
+
const availableKeys = new Set(
|
|
56
|
+
credentialHealth.details
|
|
57
|
+
.filter((detail) => detail.available)
|
|
58
|
+
.map((detail) => detail.key),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// Jira's legacy fallback is one complete Basic-auth tuple. The catalog keys
|
|
62
|
+
// are individually optional because OAuth is preferred, so the generic
|
|
63
|
+
// required-key count cannot prove that an unconnected Jira provider is ready.
|
|
64
|
+
if (providerApi.id === "jira") {
|
|
65
|
+
return ["JIRA_BASE_URL", "JIRA_USER_EMAIL", "JIRA_API_TOKEN"].every((key) =>
|
|
66
|
+
availableKeys.has(key),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (
|
|
71
|
+
providerApi.auth.startsWith("oauth-bearer:") &&
|
|
72
|
+
!providerApi.auth.includes("-or-")
|
|
73
|
+
) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (providerApi.credentialKeys.length === 0) return false;
|
|
77
|
+
if (
|
|
78
|
+
providerApi.auth.includes("-or-api-key-header:") ||
|
|
79
|
+
providerApi.auth.includes("-or-bearer-key:")
|
|
80
|
+
) {
|
|
81
|
+
return providerApi.credentialKeys.some((key) => availableKeys.has(key));
|
|
82
|
+
}
|
|
83
|
+
return providerApi.credentialKeys.every((key) => availableKeys.has(key));
|
|
84
|
+
}
|
|
85
|
+
|
|
33
86
|
async function credentialHealthForProvider(
|
|
34
87
|
provider: WorkspaceConnectionProviderCatalogForAppItem,
|
|
35
88
|
): Promise<{
|
|
@@ -100,14 +153,48 @@ async function credentialHealthForProvider(
|
|
|
100
153
|
|
|
101
154
|
function providerHealthForProvider({
|
|
102
155
|
credentialHealth,
|
|
156
|
+
providerApi,
|
|
157
|
+
providerApiIsConfigured,
|
|
103
158
|
sourceProviderSupported,
|
|
104
159
|
workspace,
|
|
105
160
|
}: {
|
|
106
161
|
credentialHealth: Awaited<ReturnType<typeof credentialHealthForProvider>>;
|
|
162
|
+
providerApi: ReturnType<typeof listProviderApiCatalog>[number] | null;
|
|
163
|
+
providerApiIsConfigured: boolean | null;
|
|
107
164
|
sourceProviderSupported: boolean;
|
|
108
165
|
workspace: WorkspaceConnectionProviderAppSummary;
|
|
109
166
|
}) {
|
|
167
|
+
if (providerApi && providerApiIsConfigured === false) {
|
|
168
|
+
if (workspace.grantState === "needs_grant") {
|
|
169
|
+
return {
|
|
170
|
+
status: "needs_grant" as const,
|
|
171
|
+
message: workspace.grantAvailabilityMessage,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (
|
|
175
|
+
workspace.hasGrantedWorkspaceConnection &&
|
|
176
|
+
!workspace.hasActiveWorkspaceConnection
|
|
177
|
+
) {
|
|
178
|
+
return {
|
|
179
|
+
status: "unhealthy" as const,
|
|
180
|
+
message:
|
|
181
|
+
"Brain has a grant, but the shared connection needs reauth or repair.",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
status: "missing_credentials" as const,
|
|
186
|
+
message:
|
|
187
|
+
"Connect this provider before Brain makes an on-demand API request.",
|
|
188
|
+
};
|
|
189
|
+
}
|
|
110
190
|
if (!sourceProviderSupported) {
|
|
191
|
+
if (providerApi) {
|
|
192
|
+
return {
|
|
193
|
+
status: "ready" as const,
|
|
194
|
+
message:
|
|
195
|
+
"Authenticated provider API access is ready for on-demand Brain queries.",
|
|
196
|
+
};
|
|
197
|
+
}
|
|
111
198
|
return {
|
|
112
199
|
status: "unsupported" as const,
|
|
113
200
|
message:
|
|
@@ -175,7 +262,7 @@ async function listWorkspaceConnectionsForCatalog(): Promise<{
|
|
|
175
262
|
|
|
176
263
|
export default defineAction({
|
|
177
264
|
description:
|
|
178
|
-
"
|
|
265
|
+
"Check reusable Brain source and provider API readiness before using a provider. Each provider reports whether authenticated access is configured and includes a focused setupLink. When a requested provider is unavailable, explain the missing connection and return its setupLink instead of attempting provider-api-request.",
|
|
179
266
|
schema: z.object({}),
|
|
180
267
|
http: { method: "GET" },
|
|
181
268
|
readOnly: true,
|
|
@@ -206,8 +293,13 @@ export default defineAction({
|
|
|
206
293
|
const workspaceConnection = provider.workspaceConnection;
|
|
207
294
|
const credentialHealth = await credentialHealthForProvider(provider);
|
|
208
295
|
const providerApi = isProviderApiId(provider.id)
|
|
209
|
-
? listProviderApiCatalog(provider.id)[0]
|
|
296
|
+
? (listProviderApiCatalog(provider.id)[0] ?? null)
|
|
210
297
|
: null;
|
|
298
|
+
const providerApiIsConfigured = providerApiConfigured({
|
|
299
|
+
credentialHealth,
|
|
300
|
+
providerApi,
|
|
301
|
+
workspace: workspaceConnection,
|
|
302
|
+
});
|
|
211
303
|
return {
|
|
212
304
|
id: provider.id,
|
|
213
305
|
label: provider.label,
|
|
@@ -222,9 +314,15 @@ export default defineAction({
|
|
|
222
314
|
configuredSourceCount,
|
|
223
315
|
hasConfiguredSources: configuredSourceCount > 0,
|
|
224
316
|
sourceProviderSupported,
|
|
317
|
+
configured:
|
|
318
|
+
providerApiIsConfigured ??
|
|
319
|
+
(sourceProviderSupported ? credentialHealth.available : null),
|
|
320
|
+
setupLink: dispatchIntegrationsHref(provider.id),
|
|
225
321
|
credentialHealth,
|
|
226
322
|
providerHealth: providerHealthForProvider({
|
|
227
323
|
credentialHealth,
|
|
324
|
+
providerApi,
|
|
325
|
+
providerApiIsConfigured,
|
|
228
326
|
sourceProviderSupported,
|
|
229
327
|
workspace: workspaceConnection,
|
|
230
328
|
}),
|
|
@@ -549,8 +549,18 @@ export interface BrainConnectionProvider {
|
|
|
549
549
|
configuredSourceCount: number;
|
|
550
550
|
hasConfiguredSources: boolean;
|
|
551
551
|
sourceProviderSupported: boolean;
|
|
552
|
+
configured?: boolean | null;
|
|
553
|
+
setupLink?: string;
|
|
552
554
|
credentialHealth?: BrainCredentialHealth;
|
|
553
555
|
providerHealth?: BrainProviderHealth;
|
|
556
|
+
rawProviderApi?: {
|
|
557
|
+
available: boolean;
|
|
558
|
+
actionNames: string[];
|
|
559
|
+
docsUrls: string[];
|
|
560
|
+
specUrls: string[];
|
|
561
|
+
auth: string | null;
|
|
562
|
+
examples: unknown[];
|
|
563
|
+
};
|
|
554
564
|
workspaceConnection?: BrainWorkspaceConnectionSummary;
|
|
555
565
|
}
|
|
556
566
|
|
|
@@ -1115,6 +1115,14 @@ function ProviderCatalog({
|
|
|
1115
1115
|
const readinessCallout = providerReadinessCallout(provider, t);
|
|
1116
1116
|
const ReadinessIcon = readinessCallout.icon;
|
|
1117
1117
|
const readinessItems = providerReadinessItems(provider, t);
|
|
1118
|
+
const providerNeedsSetup =
|
|
1119
|
+
provider.configured !== true &&
|
|
1120
|
+
provider.rawProviderApi?.available === true &&
|
|
1121
|
+
(provider.providerHealth?.status === "needs_grant" ||
|
|
1122
|
+
provider.providerHealth?.status === "unhealthy" ||
|
|
1123
|
+
provider.providerHealth?.status === "missing_credentials");
|
|
1124
|
+
const providerSetupHref =
|
|
1125
|
+
provider.setupLink ?? dispatchIntegrationsHref(provider.id);
|
|
1118
1126
|
return (
|
|
1119
1127
|
<div
|
|
1120
1128
|
key={provider.id}
|
|
@@ -1378,7 +1386,8 @@ function ProviderCatalog({
|
|
|
1378
1386
|
{t("sources.noSharedWorkspaceConnection")}
|
|
1379
1387
|
</p>
|
|
1380
1388
|
)}
|
|
1381
|
-
{!provider.sourceProviderSupported
|
|
1389
|
+
{!provider.sourceProviderSupported &&
|
|
1390
|
+
provider.rawProviderApi?.available !== true ? (
|
|
1382
1391
|
<p className="text-xs leading-5 text-muted-foreground">
|
|
1383
1392
|
{t("sources.connectionMetadataOnlyDetail")}
|
|
1384
1393
|
</p>
|
|
@@ -1400,11 +1409,13 @@ function ProviderCatalog({
|
|
|
1400
1409
|
<IconSettings2 className="size-4" />
|
|
1401
1410
|
{expanded ? t("sources.hideDetails") : t("sources.details")}
|
|
1402
1411
|
</Button>
|
|
1403
|
-
{grantState === "needs_grant" ? (
|
|
1412
|
+
{grantState === "needs_grant" || providerNeedsSetup ? (
|
|
1404
1413
|
<Button size="sm" variant="outline" asChild>
|
|
1405
|
-
<a href={
|
|
1414
|
+
<a href={providerSetupHref}>
|
|
1406
1415
|
<IconExternalLink className="size-4" />
|
|
1407
|
-
{
|
|
1416
|
+
{grantState === "needs_grant"
|
|
1417
|
+
? t("sources.grantInDispatch")
|
|
1418
|
+
: t("sources.connectProvider")}
|
|
1408
1419
|
</a>
|
|
1409
1420
|
</Button>
|
|
1410
1421
|
) : null}
|
|
@@ -30,6 +30,7 @@ export type DistillationAgentRunner = (
|
|
|
30
30
|
export interface ProcessBrainIngestQueueOptions {
|
|
31
31
|
limit?: number;
|
|
32
32
|
runDistillation?: boolean;
|
|
33
|
+
maxDistillations?: number;
|
|
33
34
|
distillationRunner?: DistillationAgentRunner;
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -331,9 +332,20 @@ export async function processBrainIngestQueueOnce(
|
|
|
331
332
|
const processed: string[] = [];
|
|
332
333
|
const deferred: string[] = [];
|
|
333
334
|
const failed: string[] = [];
|
|
335
|
+
const maxDistillations = Math.max(
|
|
336
|
+
0,
|
|
337
|
+
Math.floor(options.maxDistillations ?? Number.POSITIVE_INFINITY),
|
|
338
|
+
);
|
|
339
|
+
let distillationsStarted = 0;
|
|
334
340
|
for (const row of rows) {
|
|
335
341
|
const payload = parseJson<Record<string, unknown>>(row.payloadJson, {});
|
|
336
342
|
if (row.operation === "distill") {
|
|
343
|
+
if (
|
|
344
|
+
options.runDistillation &&
|
|
345
|
+
distillationsStarted >= maxDistillations
|
|
346
|
+
) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
337
349
|
if (!options.runDistillation) {
|
|
338
350
|
const claimToken = await claimForHeadlessRunner(row, payload);
|
|
339
351
|
if (!claimToken) continue;
|
|
@@ -367,6 +379,7 @@ export async function processBrainIngestQueueOnce(
|
|
|
367
379
|
};
|
|
368
380
|
const claimToken = await claimForHeadlessRunner(row, nextPayload);
|
|
369
381
|
if (!claimToken) continue;
|
|
382
|
+
distillationsStarted += 1;
|
|
370
383
|
|
|
371
384
|
try {
|
|
372
385
|
const runner =
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { runWithRequestContext } from "@agent-native/core/server/request-context";
|
|
2
2
|
import { accessFilter } from "@agent-native/core/sharing";
|
|
3
|
-
import { and,
|
|
3
|
+
import { and, inArray, ne } from "drizzle-orm";
|
|
4
4
|
|
|
5
5
|
import type { BrainSourceProvider } from "../../shared/types.js";
|
|
6
6
|
import { getDb, schema } from "../db/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { parseJson } from "../lib/brain.js";
|
|
8
8
|
import { runConnectorSync } from "../lib/connectors.js";
|
|
9
9
|
|
|
10
10
|
const DEFAULT_POLL_MINUTES = 60;
|
|
@@ -13,6 +13,7 @@ let skippingLogged = false;
|
|
|
13
13
|
let running = false;
|
|
14
14
|
|
|
15
15
|
type SourceRow = typeof schema.brainSources.$inferSelect;
|
|
16
|
+
const RETRYABLE_SOURCE_STATUSES: SourceRow["status"][] = ["active", "error"];
|
|
16
17
|
|
|
17
18
|
function configuredPollMinutes(source: SourceRow): number {
|
|
18
19
|
const config = parseJson<Record<string, unknown>>(source.configJson, {});
|
|
@@ -56,30 +57,34 @@ function retryAfterAt(source: SourceRow): number | null {
|
|
|
56
57
|
return Number.isFinite(retryAt) ? retryAt : null;
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
function sourceSyncDueAt(source: SourceRow, nowMs: number): number | null {
|
|
61
|
+
if (!RETRYABLE_SOURCE_STATUSES.includes(source.status)) return null;
|
|
62
|
+
if (!isAutoSyncEnabled(source)) return null;
|
|
63
|
+
|
|
64
|
+
const pollIntervalMs = configuredPollMinutes(source) * 60 * 1000;
|
|
65
|
+
let pollAt = nowMs;
|
|
66
|
+
if (source.status === "error") {
|
|
67
|
+
const failedAt = Date.parse(source.updatedAt);
|
|
68
|
+
if (Number.isFinite(failedAt)) pollAt = failedAt + pollIntervalMs;
|
|
69
|
+
} else if (source.lastSyncedAt) {
|
|
70
|
+
const lastSynced = Date.parse(source.lastSyncedAt);
|
|
71
|
+
if (Number.isFinite(lastSynced)) pollAt = lastSynced + pollIntervalMs;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return Math.max(pollAt, retryAfterAt(source) ?? Number.NEGATIVE_INFINITY);
|
|
75
|
+
}
|
|
76
|
+
|
|
59
77
|
export function isBrainSourceDue(
|
|
60
78
|
source: SourceRow,
|
|
61
79
|
nowMs = Date.now(),
|
|
62
80
|
): boolean {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const retryAt = retryAfterAt(source);
|
|
66
|
-
if (retryAt && retryAt > nowMs) return false;
|
|
67
|
-
if (!source.lastSyncedAt) return true;
|
|
68
|
-
const lastSynced = Date.parse(source.lastSyncedAt);
|
|
69
|
-
if (!Number.isFinite(lastSynced)) return true;
|
|
70
|
-
return nowMs - lastSynced >= configuredPollMinutes(source) * 60 * 1000;
|
|
81
|
+
const dueAt = sourceSyncDueAt(source, nowMs);
|
|
82
|
+
return dueAt !== null && dueAt <= nowMs;
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
export function nextBrainSourceSyncAt(source: SourceRow): string | null {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (retryAt) return new Date(retryAt).toISOString();
|
|
77
|
-
if (!source.lastSyncedAt) return nowIso();
|
|
78
|
-
const lastSynced = Date.parse(source.lastSyncedAt);
|
|
79
|
-
if (!Number.isFinite(lastSynced)) return nowIso();
|
|
80
|
-
return new Date(
|
|
81
|
-
lastSynced + configuredPollMinutes(source) * 60 * 1000,
|
|
82
|
-
).toISOString();
|
|
86
|
+
const dueAt = sourceSyncDueAt(source, Date.now());
|
|
87
|
+
return dueAt === null ? null : new Date(dueAt).toISOString();
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
export async function listDueBrainSources(
|
|
@@ -90,15 +95,15 @@ export async function listDueBrainSources(
|
|
|
90
95
|
) {
|
|
91
96
|
const db = getDb();
|
|
92
97
|
const where = options.system
|
|
93
|
-
? // guard:allow-unscoped — system scheduler enumerates
|
|
98
|
+
? // guard:allow-unscoped — system scheduler enumerates retryable sources,
|
|
94
99
|
// then re-enters each row's owner/org context before syncing.
|
|
95
100
|
and(
|
|
96
|
-
|
|
101
|
+
inArray(schema.brainSources.status, RETRYABLE_SOURCE_STATUSES),
|
|
97
102
|
ne(schema.brainSources.provider, "manual"),
|
|
98
103
|
)
|
|
99
104
|
: and(
|
|
100
105
|
accessFilter(schema.brainSources, schema.brainSourceShares),
|
|
101
|
-
|
|
106
|
+
inArray(schema.brainSources.status, RETRYABLE_SOURCE_STATUSES),
|
|
102
107
|
ne(schema.brainSources.provider, "manual"),
|
|
103
108
|
);
|
|
104
109
|
const rows = await db
|
|
@@ -24,6 +24,7 @@ const INITIAL_TOOL_NAMES = [
|
|
|
24
24
|
"write-knowledge",
|
|
25
25
|
"list-sources",
|
|
26
26
|
"get-source",
|
|
27
|
+
"list-connection-providers",
|
|
27
28
|
"create-source",
|
|
28
29
|
"sync-source",
|
|
29
30
|
"enqueue-distillation",
|
|
@@ -56,7 +57,7 @@ Important rules:
|
|
|
56
57
|
- Source policy matters: strict means answer from reviewed knowledge only; balanced means raw captures are fallback context when reviewed knowledge is thin; exploratory means raw captures and sources may be surfaced as clearly labeled leads.
|
|
57
58
|
- Company-tier knowledge may create a proposal instead of publishing immediately, depending on settings.
|
|
58
59
|
- Slack and Granola sources are configurable v1 connectors. Generic transcript import is always available.
|
|
59
|
-
- Source/read actions are convenience readers, not provider capability limits. For ad hoc provider analysis that needs an endpoint, filter, payload, pagination mode, or API version not modeled by a Brain action, call provider-api-catalog/provider-api-docs, then provider-api-request against the provider's real HTTP API. Use connectionId for a specific shared grant and accountId for a specific OAuth account.
|
|
60
|
+
- Source/read actions are convenience readers, not provider capability limits. Before any provider API request, call list-connection-providers and inspect the matching provider. If configured is not true, do not attempt the request; explain that the connection needs setup or repair and include setupLink. Jira is queried on demand through the provider API rather than indexed as a Brain source. For ad hoc provider analysis that needs an endpoint, filter, payload, pagination mode, or API version not modeled by a Brain action, call provider-api-catalog/provider-api-docs, then provider-api-request against the provider's real HTTP API. Use connectionId for a specific shared grant and accountId for a specific OAuth account.
|
|
60
61
|
- For broad searches, joins, classification, source-corpus counts, or absence claims across provider records, fetch every relevant page or an explicitly bounded cohort, stage/save large responses with stageAs/saveToFile/fetchAllPages, then use query-staged-dataset or run-code to reduce the corpus. Report source, filters, row counts, pagination, truncation, and gaps.`,
|
|
61
62
|
a2aMessageFallback: async ({ text }) => tryAnswerBrainA2AQuestion(text),
|
|
62
63
|
mentionProviders: async () => {
|