@agent-native/core 0.102.1 → 0.103.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 +15 -0
- package/corpus/core/docs/content/local-file-mode.mdx +99 -489
- package/corpus/core/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/corpus/core/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/corpus/core/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/corpus/core/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/corpus/core/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/corpus/core/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/corpus/core/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/corpus/core/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/corpus/core/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/corpus/core/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/corpus/core/docs/content/template-content.mdx +26 -42
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/content-local.ts +86 -18
- package/corpus/core/src/cli/index.ts +2 -2
- package/corpus/core/src/cli/skills-content/content-skill.ts +36 -25
- package/corpus/core/src/cli/skills.ts +47 -13
- package/corpus/core/src/client/AgentPanel.tsx +7 -0
- package/corpus/core/src/client/AssistantChat.tsx +7 -0
- package/corpus/core/src/client/agent-chat-adapter.ts +7 -1
- package/corpus/core/src/client/chat/message-components.tsx +17 -3
- package/corpus/core/src/client/composer/ComposerPlusMenu.tsx +96 -6
- package/corpus/core/src/client/composer/asset-picker-url.ts +80 -0
- package/corpus/core/src/client/error-format.ts +24 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +8 -1
- package/corpus/core/src/local-artifacts/index.ts +65 -0
- package/corpus/templates/assets/app/components/library/GenerationPresetsPanel.tsx +325 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +12 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/assets/app/i18n-data.ts +215 -0
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +19 -479
- package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id_.settings.tsx +446 -0
- package/corpus/templates/assets/app/routes/library.tsx +69 -0
- package/corpus/templates/assets/changelog/2026-07-15-fixed-top-level-image-picker-selections-returning-to-the-com.md +6 -0
- package/corpus/templates/clips/actions/disconnect-calendar.ts +57 -9
- package/corpus/templates/clips/actions/generate-workflow.ts +102 -59
- package/corpus/templates/clips/actions/get-recording-player-data.ts +64 -1
- package/corpus/templates/clips/actions/regenerate-summary.ts +7 -0
- package/corpus/templates/clips/actions/regenerate-title.ts +29 -11
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +34 -13
- package/corpus/templates/clips/app/components/editor/thumbnail-picker.tsx +87 -9
- package/corpus/templates/clips/app/components/editor/trim-handles.tsx +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +21 -8
- package/corpus/templates/clips/app/components/library/folder-tree.tsx +52 -0
- package/corpus/templates/clips/app/components/player/settings-panel.tsx +116 -58
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +43 -37
- package/corpus/templates/clips/app/components/player/video-player.tsx +50 -2
- package/corpus/templates/clips/app/components/recorder/microphone-visualizer.tsx +22 -3
- package/corpus/templates/clips/app/i18n/ar-SA.ts +5 -2
- package/corpus/templates/clips/app/i18n/de-DE.ts +6 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -2
- package/corpus/templates/clips/app/i18n/es-ES.ts +6 -2
- package/corpus/templates/clips/app/i18n/fr-FR.ts +5 -2
- package/corpus/templates/clips/app/i18n/hi-IN.ts +5 -2
- package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +5 -2
- package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -2
- package/corpus/templates/clips/app/i18n/zh-CN.ts +5 -2
- package/corpus/templates/clips/app/i18n/zh-TW.ts +5 -2
- package/corpus/templates/clips/app/lib/timestamp-mapping.ts +14 -0
- package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -2
- package/corpus/templates/clips/app/routes/_index.tsx +1 -2
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +98 -32
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +4 -1
- package/corpus/templates/clips/changelog/2026-07-15-ai-workflow-generation-now-stays-visible-avoids-duplicate-re.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-playback-and-cta-controls-remain-interactive-through-ed.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-clip-titles-no-longer-describe-the-product-as-a-loom-alterna.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-description-regeneration-now-opens-the-agent-chat-so-progres.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-direct-recording-urls-now-respect-share-link-and-password-ac.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-disconnecting-a-calendar-now-clears-unrecorded-synced-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-folders-now-expose-rename-and-delete-actions-directly-in-the.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-recording-pages-now-explain-sign-in-access-and-avoid-showing.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-clips-extension-quick-actions-toolbar-can-be-moved-out-o.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-the-editor-now-skips-cut-sections-during-preview-and-keeps-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-thumbnail-capture-now-updates-previews-while-scrubbing-and-l.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-15-windows-permission-links-open-the-matching-settings-page.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +117 -2
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +27 -0
- package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -1
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +139 -101
- package/corpus/templates/clips/server/lib/recording-page-access.ts +35 -0
- package/corpus/templates/clips/server/lib/share-password.ts +6 -3
- package/corpus/templates/content/.agents/skills/content/SKILL.md +26 -39
- package/corpus/templates/content/AGENTS.md +25 -30
- package/corpus/templates/content/actions/_builder-docs-client.ts +23 -0
- package/corpus/templates/content/actions/_content-database-source-adapters.ts +21 -3
- package/corpus/templates/content/actions/_content-files.ts +338 -0
- package/corpus/templates/content/actions/_content-space-access.ts +135 -0
- package/corpus/templates/content/actions/_content-spaces.ts +640 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +90 -7
- package/corpus/templates/content/actions/_database-utils.ts +7 -1
- package/corpus/templates/content/actions/_local-file-documents.ts +0 -9
- package/corpus/templates/content/actions/_local-folder-source.ts +53 -0
- package/corpus/templates/content/actions/_property-utils.ts +9 -4
- package/corpus/templates/content/actions/add-database-item.ts +108 -65
- package/corpus/templates/content/actions/backfill-content-files.ts +22 -0
- package/corpus/templates/content/actions/connect-local-folder-source.ts +221 -0
- package/corpus/templates/content/actions/create-content-database.ts +129 -3
- package/corpus/templates/content/actions/create-document.ts +65 -55
- package/corpus/templates/content/actions/create-inline-content-database.ts +6 -1
- package/corpus/templates/content/actions/delete-content-database.ts +3 -0
- package/corpus/templates/content/actions/delete-document.ts +7 -11
- package/corpus/templates/content/actions/disconnect-local-folder-source.ts +175 -0
- package/corpus/templates/content/actions/duplicate-database-item.ts +10 -0
- package/corpus/templates/content/actions/duplicate-database-items.ts +13 -0
- package/corpus/templates/content/actions/edit-document.ts +2 -28
- package/corpus/templates/content/actions/ensure-content-spaces.ts +26 -0
- package/corpus/templates/content/actions/export-content-source.ts +47 -9
- package/corpus/templates/content/actions/get-document.ts +0 -14
- package/corpus/templates/content/actions/import-content-source.ts +43 -3
- package/corpus/templates/content/actions/list-content-spaces.ts +103 -0
- package/corpus/templates/content/actions/list-documents.ts +12 -9
- package/corpus/templates/content/actions/move-document.ts +3 -14
- package/corpus/templates/content/actions/pull-document.ts +0 -23
- package/corpus/templates/content/actions/remove-local-file-source.ts +50 -29
- package/corpus/templates/content/actions/resolve-local-folder-conflict.ts +442 -0
- package/corpus/templates/content/actions/reveal-local-source-file.ts +6 -17
- package/corpus/templates/content/actions/search-documents.ts +0 -34
- package/corpus/templates/content/actions/share-local-file-document.ts +25 -1
- package/corpus/templates/content/actions/submit-content-database-form.ts +12 -0
- package/corpus/templates/content/actions/sync-local-folder-source.ts +731 -0
- package/corpus/templates/content/actions/sync-manifest-local-folder-source.ts +123 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +10 -1
- package/corpus/templates/content/actions/update-document.ts +0 -15
- package/corpus/templates/content/actions/view-screen.ts +2 -50
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +76 -62
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +70 -22
- package/corpus/templates/content/app/components/editor/database/grouping.ts +2 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +23 -20
- package/corpus/templates/content/app/components/editor/database/shared.tsx +2 -0
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +330 -0
- package/corpus/templates/content/app/components/editor/database/types.ts +1 -0
- package/corpus/templates/content/app/components/editor/database/view-config.ts +3 -1
- package/corpus/templates/content/app/components/layout/Layout.tsx +25 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +209 -113
- package/corpus/templates/content/app/components/sidebar/select-content-space.ts +31 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -0
- package/corpus/templates/content/app/hooks/use-content-spaces.ts +39 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +11 -0
- package/corpus/templates/content/app/i18n-data.ts +75 -0
- package/corpus/templates/content/app/routes/_app.local-files.tsx +174 -65
- package/corpus/templates/content/changelog/2026-07-16-content-callouts-can-now-be-reviewed-and-published-to-builder.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-heading-5-and-heading-6-are-available-from-the-editor-slash-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-16-organize-every-workspace-through-a-customizable-files-databa.md +6 -0
- package/corpus/templates/content/parity/matrix.md +2 -1
- package/corpus/templates/content/parity/matrix.ts +37 -1
- package/corpus/templates/content/scripts/dev-database.mjs +7 -5
- package/corpus/templates/content/server/db/schema.ts +113 -40
- package/corpus/templates/content/server/lib/document-context.ts +15 -1
- package/corpus/templates/content/server/lib/notion-sync.ts +6 -0
- package/corpus/templates/content/server/plugins/db.ts +153 -0
- package/corpus/templates/content/shared/api.ts +17 -3
- package/corpus/templates/content/shared/builder-mdx.ts +163 -16
- package/corpus/templates/design/.agents/skills/design-templates/SKILL.md +59 -0
- package/corpus/templates/design/AGENTS.md +6 -1
- package/corpus/templates/design/actions/create-design-from-template.ts +19 -7
- package/corpus/templates/design/actions/list-design-templates.ts +69 -21
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/view-screen.ts +15 -2
- package/corpus/templates/design/agent-native.app-skill.json +5 -0
- package/corpus/templates/design/app/components/design/design-canvas/external-preview.ts +7 -3
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +281 -56
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +14 -2
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +3 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +3 -3
- package/corpus/templates/design/app/i18n-data.ts +21 -2
- package/corpus/templates/design/app/i18n-template-feature.ts +218 -10
- package/corpus/templates/design/app/pages/Index.tsx +195 -24
- package/corpus/templates/design/app/pages/Templates.tsx +144 -55
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +12 -1
- package/corpus/templates/design/changelog/2026-07-14-templates-now-appear-in-the-new-design-picker-with-previews-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-prototype-print-and-download-buttons-now-work-in-preview.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-templates-now-open-immediately-after-copying-even-while-the-.md +6 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/mail/AGENTS.md +23 -18
- package/corpus/templates/mail/actions/bulk-archive.ts +32 -28
- package/corpus/templates/mail/actions/mark-read.ts +131 -20
- package/corpus/templates/mail/actions/mark-thread-read.ts +1 -1
- package/corpus/templates/mail/actions/move-email.ts +30 -24
- package/corpus/templates/mail/actions/send-email.ts +73 -68
- package/corpus/templates/mail/changelog/2026-07-15-unread-inbox-cleanup-now-completes-reliably.md +6 -0
- package/corpus/templates/mail/server/handlers/emails.ts +218 -209
- package/corpus/templates/mail/server/lib/bulk-mark-read.ts +30 -0
- package/corpus/templates/mail/server/lib/email-state.ts +198 -113
- package/corpus/templates/mail/server/lib/google-auth.ts +218 -25
- package/corpus/templates/mail/server/lib/jobs.ts +69 -74
- package/corpus/templates/mail/server/lib/local-email-store.ts +265 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/slides/actions/extract-pdf.ts +1 -1
- package/corpus/templates/slides/actions/import-file.ts +4 -1
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +9 -12
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +29 -21
- package/corpus/templates/slides/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/slides/changelog/2026-07-15-image-search-and-generation-controls-now-use-the-registered-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-pdf-deck-references-can-be-imported-for-slide-inspiration-ag.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-15-stable-style-inspector-dock.md +6 -0
- package/dist/cli/content-local.d.ts +1 -0
- package/dist/cli/content-local.d.ts.map +1 -1
- package/dist/cli/content-local.js +75 -17
- package/dist/cli/content-local.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills-content/content-skill.d.ts +1 -1
- package/dist/cli/skills-content/content-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/content-skill.js +36 -25
- package/dist/cli/skills-content/content-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +47 -14
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +5 -0
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +7 -0
- 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 +8 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +4 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +10 -3
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
- package/dist/client/composer/ComposerPlusMenu.js +58 -6
- package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
- package/dist/client/composer/asset-picker-url.d.ts +16 -0
- package/dist/client/composer/asset-picker-url.d.ts.map +1 -0
- package/dist/client/composer/asset-picker-url.js +64 -0
- package/dist/client/composer/asset-picker-url.js.map +1 -0
- package/dist/client/error-format.d.ts.map +1 -1
- package/dist/client/error-format.js +17 -0
- package/dist/client/error-format.js.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +6 -1
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/local-artifacts/index.d.ts +10 -0
- package/dist/local-artifacts/index.d.ts.map +1 -1
- package/dist/local-artifacts/index.js +39 -0
- package/dist/local-artifacts/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/docs/content/local-file-mode.mdx +99 -489
- package/docs/content/locales/ar-SA/local-file-mode.mdx +35 -490
- package/docs/content/locales/ar-SA/template-content.mdx +10 -24
- package/docs/content/locales/de-DE/local-file-mode.mdx +37 -491
- package/docs/content/locales/de-DE/template-content.mdx +10 -24
- package/docs/content/locales/es-ES/local-file-mode.mdx +35 -493
- package/docs/content/locales/es-ES/template-content.mdx +10 -24
- package/docs/content/locales/fr-FR/local-file-mode.mdx +38 -491
- package/docs/content/locales/fr-FR/template-content.mdx +10 -24
- package/docs/content/locales/hi-IN/local-file-mode.mdx +33 -492
- package/docs/content/locales/hi-IN/template-content.mdx +10 -24
- package/docs/content/locales/ja-JP/local-file-mode.mdx +36 -492
- package/docs/content/locales/ja-JP/template-content.mdx +10 -24
- package/docs/content/locales/ko-KR/local-file-mode.mdx +35 -490
- package/docs/content/locales/ko-KR/template-content.mdx +10 -24
- package/docs/content/locales/pt-BR/local-file-mode.mdx +35 -493
- package/docs/content/locales/pt-BR/template-content.mdx +10 -24
- package/docs/content/locales/zh-CN/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-CN/template-content.mdx +9 -24
- package/docs/content/locales/zh-TW/local-file-mode.mdx +31 -489
- package/docs/content/locales/zh-TW/template-content.mdx +9 -24
- package/docs/content/template-content.mdx +26 -42
- package/package.json +1 -1
- package/corpus/templates/assets/app/components/library/EditLibraryDialog.tsx +0 -126
|
@@ -909,10 +909,24 @@ function ReasoningMessagePart() {
|
|
|
909
909
|
);
|
|
910
910
|
}
|
|
911
911
|
|
|
912
|
+
const ALWAYS_VISIBLE_ASSISTANT_TOOLS = new Set(["connect-builder"]);
|
|
913
|
+
|
|
914
|
+
export function isCollapsibleAssistantWorkPart(part: {
|
|
915
|
+
type?: string;
|
|
916
|
+
toolName?: string;
|
|
917
|
+
}): boolean {
|
|
918
|
+
if (part.type === "reasoning") return true;
|
|
919
|
+
return (
|
|
920
|
+
part.type === "tool-call" &&
|
|
921
|
+
!ALWAYS_VISIBLE_ASSISTANT_TOOLS.has(part.toolName ?? "")
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
|
|
912
925
|
function groupAssistantWorkParts(part: {
|
|
913
926
|
type?: string;
|
|
927
|
+
toolName?: string;
|
|
914
928
|
}): ["group-work"] | null {
|
|
915
|
-
if (part
|
|
929
|
+
if (isCollapsibleAssistantWorkPart(part)) {
|
|
916
930
|
return ["group-work"];
|
|
917
931
|
}
|
|
918
932
|
return null;
|
|
@@ -1044,8 +1058,8 @@ export function AssistantMessage() {
|
|
|
1044
1058
|
Array.isArray(msgContent) &&
|
|
1045
1059
|
msgContent.some(
|
|
1046
1060
|
(p) =>
|
|
1047
|
-
p.type
|
|
1048
|
-
(p
|
|
1061
|
+
(p.type !== "tool-call" || p.activity !== true) &&
|
|
1062
|
+
isCollapsibleAssistantWorkPart(p),
|
|
1049
1063
|
);
|
|
1050
1064
|
|
|
1051
1065
|
if (!hasRenderableContent) return null;
|
|
@@ -42,6 +42,11 @@ import {
|
|
|
42
42
|
type McpServerScope,
|
|
43
43
|
} from "../resources/use-mcp-servers.js";
|
|
44
44
|
import { cn } from "../utils.js";
|
|
45
|
+
import {
|
|
46
|
+
createAssetPickerHandoffId,
|
|
47
|
+
isExternalAssetPickerUrl,
|
|
48
|
+
standaloneAssetPickerUrl,
|
|
49
|
+
} from "./asset-picker-url.js";
|
|
45
50
|
import type { ComposerMode } from "./types.js";
|
|
46
51
|
|
|
47
52
|
interface ComposerPlusMenuProps {
|
|
@@ -73,6 +78,7 @@ interface EmbedEnvelope<TPayload = unknown> {
|
|
|
73
78
|
|
|
74
79
|
interface AssetPickerPayload {
|
|
75
80
|
assetId?: unknown;
|
|
81
|
+
handoffId?: unknown;
|
|
76
82
|
url?: unknown;
|
|
77
83
|
previewUrl?: unknown;
|
|
78
84
|
downloadUrl?: unknown;
|
|
@@ -742,8 +748,31 @@ function AssetsPickerModal({
|
|
|
742
748
|
onOpenChange: (open: boolean) => void;
|
|
743
749
|
}) {
|
|
744
750
|
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
751
|
+
const standaloneWindowRef = useRef<Window | null>(null);
|
|
745
752
|
const [pickerReady, setPickerReady] = useState(false);
|
|
753
|
+
const [standaloneHandoffId, setStandaloneHandoffId] = useState<string | null>(
|
|
754
|
+
null,
|
|
755
|
+
);
|
|
746
756
|
const sourceUrl = useMemo(() => assetPickerUrl(), []);
|
|
757
|
+
const externalPicker = useMemo(
|
|
758
|
+
() =>
|
|
759
|
+
typeof window !== "undefined" &&
|
|
760
|
+
isExternalAssetPickerUrl(sourceUrl, window.location.origin),
|
|
761
|
+
[sourceUrl],
|
|
762
|
+
);
|
|
763
|
+
const standaloneUrl = useMemo(
|
|
764
|
+
() =>
|
|
765
|
+
standaloneAssetPickerUrl(
|
|
766
|
+
sourceUrl,
|
|
767
|
+
typeof window !== "undefined" ? window.location.href : undefined,
|
|
768
|
+
{
|
|
769
|
+
handoffId: standaloneHandoffId ?? undefined,
|
|
770
|
+
returnOrigin:
|
|
771
|
+
typeof window !== "undefined" ? window.location.origin : undefined,
|
|
772
|
+
},
|
|
773
|
+
),
|
|
774
|
+
[sourceUrl, standaloneHandoffId],
|
|
775
|
+
);
|
|
747
776
|
const iframeUrl = useMemo(() => withEmbeddedParams(sourceUrl), [sourceUrl]);
|
|
748
777
|
const targetOrigin = useMemo(() => assetPickerOrigin(iframeUrl), [iframeUrl]);
|
|
749
778
|
const configurePicker = useCallback(() => {
|
|
@@ -758,14 +787,32 @@ function AssetsPickerModal({
|
|
|
758
787
|
}, [targetOrigin]);
|
|
759
788
|
|
|
760
789
|
useEffect(() => {
|
|
761
|
-
if (open)
|
|
762
|
-
|
|
790
|
+
if (open) {
|
|
791
|
+
setPickerReady(false);
|
|
792
|
+
if (externalPicker) {
|
|
793
|
+
standaloneWindowRef.current = null;
|
|
794
|
+
setStandaloneHandoffId(createAssetPickerHandoffId());
|
|
795
|
+
} else {
|
|
796
|
+
setStandaloneHandoffId(null);
|
|
797
|
+
}
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
if (!standaloneWindowRef.current) setStandaloneHandoffId(null);
|
|
801
|
+
}, [externalPicker, iframeUrl, open]);
|
|
763
802
|
|
|
764
803
|
useEffect(() => {
|
|
765
|
-
if (
|
|
804
|
+
if (
|
|
805
|
+
!targetOrigin ||
|
|
806
|
+
(!open && !standaloneWindowRef.current) ||
|
|
807
|
+
(externalPicker && !standaloneHandoffId)
|
|
808
|
+
)
|
|
809
|
+
return;
|
|
766
810
|
|
|
767
811
|
const handleMessage = (event: MessageEvent) => {
|
|
768
|
-
|
|
812
|
+
const expectedSource = externalPicker
|
|
813
|
+
? standaloneWindowRef.current
|
|
814
|
+
: iframeRef.current?.contentWindow;
|
|
815
|
+
if (!expectedSource || event.source !== expectedSource) return;
|
|
769
816
|
if (event.origin !== targetOrigin) return;
|
|
770
817
|
if (!isEmbedEnvelope(event.data)) return;
|
|
771
818
|
|
|
@@ -776,6 +823,14 @@ function AssetsPickerModal({
|
|
|
776
823
|
}
|
|
777
824
|
|
|
778
825
|
if (event.data.type !== "message") return;
|
|
826
|
+
if (externalPicker) {
|
|
827
|
+
const payload = event.data.payload;
|
|
828
|
+
const handoffId =
|
|
829
|
+
payload && typeof payload === "object"
|
|
830
|
+
? assetString((payload as AssetPickerPayload).handoffId)
|
|
831
|
+
: null;
|
|
832
|
+
if (handoffId !== standaloneHandoffId) return;
|
|
833
|
+
}
|
|
779
834
|
if (event.data.name === "close") {
|
|
780
835
|
onOpenChange(false);
|
|
781
836
|
return;
|
|
@@ -798,6 +853,8 @@ function AssetsPickerModal({
|
|
|
798
853
|
title: `Image: ${title}`,
|
|
799
854
|
context: assetContext(event.data.payload, url),
|
|
800
855
|
});
|
|
856
|
+
standaloneWindowRef.current = null;
|
|
857
|
+
setStandaloneHandoffId(null);
|
|
801
858
|
onOpenChange(false);
|
|
802
859
|
};
|
|
803
860
|
|
|
@@ -811,7 +868,26 @@ function AssetsPickerModal({
|
|
|
811
868
|
window.removeEventListener("message", handleMessage);
|
|
812
869
|
window.removeEventListener("keydown", handleKey);
|
|
813
870
|
};
|
|
814
|
-
}, [
|
|
871
|
+
}, [
|
|
872
|
+
configurePicker,
|
|
873
|
+
externalPicker,
|
|
874
|
+
onOpenChange,
|
|
875
|
+
open,
|
|
876
|
+
standaloneHandoffId,
|
|
877
|
+
targetOrigin,
|
|
878
|
+
]);
|
|
879
|
+
|
|
880
|
+
const openStandalonePicker = useCallback(
|
|
881
|
+
(event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
882
|
+
if (!standaloneHandoffId) return;
|
|
883
|
+
event.preventDefault();
|
|
884
|
+
const pickerWindow = window.open(standaloneUrl, "_blank");
|
|
885
|
+
if (!pickerWindow) return;
|
|
886
|
+
standaloneWindowRef.current = pickerWindow;
|
|
887
|
+
onOpenChange(false);
|
|
888
|
+
},
|
|
889
|
+
[onOpenChange, standaloneHandoffId, standaloneUrl],
|
|
890
|
+
);
|
|
815
891
|
|
|
816
892
|
if (!open || typeof document === "undefined") return null;
|
|
817
893
|
|
|
@@ -842,7 +918,21 @@ function AssetsPickerModal({
|
|
|
842
918
|
<IconX className="h-4 w-4" />
|
|
843
919
|
</button>
|
|
844
920
|
</div>
|
|
845
|
-
{
|
|
921
|
+
{externalPicker ? (
|
|
922
|
+
<div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-8 text-center">
|
|
923
|
+
<div className="max-w-md text-sm text-muted-foreground">
|
|
924
|
+
Open Assets in a new tab to sign in and choose an image securely.
|
|
925
|
+
</div>
|
|
926
|
+
<a
|
|
927
|
+
href={standaloneUrl}
|
|
928
|
+
target="_blank"
|
|
929
|
+
onClick={openStandalonePicker}
|
|
930
|
+
className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:bg-primary/90"
|
|
931
|
+
>
|
|
932
|
+
Open Assets image picker
|
|
933
|
+
</a>
|
|
934
|
+
</div>
|
|
935
|
+
) : targetOrigin ? (
|
|
846
936
|
<div className="relative min-h-0 flex-1 overflow-hidden bg-background">
|
|
847
937
|
{!pickerReady && <AssetsPickerLoadingSkeleton />}
|
|
848
938
|
<iframe
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const FALLBACK_BASE_URL = "http://agent-native.invalid";
|
|
2
|
+
|
|
3
|
+
export const ASSET_PICKER_HANDOFF_PARAM = "__an_asset_picker_handoff";
|
|
4
|
+
export const ASSET_PICKER_RETURN_ORIGIN_PARAM =
|
|
5
|
+
"__an_asset_picker_return_origin";
|
|
6
|
+
|
|
7
|
+
export interface StandaloneAssetPickerOptions {
|
|
8
|
+
handoffId?: string;
|
|
9
|
+
returnOrigin?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createAssetPickerHandoffId(): string {
|
|
13
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
14
|
+
return crypto.randomUUID();
|
|
15
|
+
}
|
|
16
|
+
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
|
|
17
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
18
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join(
|
|
19
|
+
"",
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Cross-origin Assets pages cannot inherit the host app's authenticated
|
|
27
|
+
* session inside an iframe. Treat those URLs as link-out targets so provider
|
|
28
|
+
* sign-in runs in a normal top-level browser context.
|
|
29
|
+
*/
|
|
30
|
+
export function isExternalAssetPickerUrl(
|
|
31
|
+
value: string,
|
|
32
|
+
currentOrigin: string,
|
|
33
|
+
): boolean {
|
|
34
|
+
try {
|
|
35
|
+
return new URL(value, currentOrigin).origin !== currentOrigin;
|
|
36
|
+
} catch {
|
|
37
|
+
// A malformed configured URL should fail closed instead of being loaded in
|
|
38
|
+
// an iframe with an unknown auth boundary.
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Build a top-level picker URL without iframe-only auth flags. */
|
|
44
|
+
export function standaloneAssetPickerUrl(
|
|
45
|
+
value: string,
|
|
46
|
+
baseUrl = FALLBACK_BASE_URL,
|
|
47
|
+
options: StandaloneAssetPickerOptions = {},
|
|
48
|
+
): string {
|
|
49
|
+
try {
|
|
50
|
+
const parsed = new URL(value, baseUrl);
|
|
51
|
+
parsed.searchParams.delete("embedded");
|
|
52
|
+
parsed.searchParams.delete("__an_embed_token");
|
|
53
|
+
parsed.searchParams.set("mediaType", "image");
|
|
54
|
+
let returnOrigin: string | null = null;
|
|
55
|
+
if (options.returnOrigin) {
|
|
56
|
+
try {
|
|
57
|
+
const parsedOrigin = new URL(options.returnOrigin);
|
|
58
|
+
if (
|
|
59
|
+
parsedOrigin.protocol === "http:" ||
|
|
60
|
+
parsedOrigin.protocol === "https:"
|
|
61
|
+
) {
|
|
62
|
+
returnOrigin = parsedOrigin.origin;
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
// Omit an invalid return target rather than emitting an unverified
|
|
66
|
+
// cross-origin callback URL.
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (options.handoffId && returnOrigin) {
|
|
70
|
+
parsed.searchParams.set(ASSET_PICKER_HANDOFF_PARAM, options.handoffId);
|
|
71
|
+
parsed.searchParams.set(ASSET_PICKER_RETURN_ORIGIN_PARAM, returnOrigin);
|
|
72
|
+
} else {
|
|
73
|
+
parsed.searchParams.delete(ASSET_PICKER_HANDOFF_PARAM);
|
|
74
|
+
parsed.searchParams.delete(ASSET_PICKER_RETURN_ORIGIN_PARAM);
|
|
75
|
+
}
|
|
76
|
+
return parsed.toString();
|
|
77
|
+
} catch {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -102,6 +102,18 @@ function isProviderAuthenticationError(
|
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
+
function isConnectionError(text: string, errorCode?: string): boolean {
|
|
106
|
+
const code = normalizeErrorCode(errorCode);
|
|
107
|
+
return (
|
|
108
|
+
code === "provider_network_error" ||
|
|
109
|
+
code === "connection_error" ||
|
|
110
|
+
code === "network_error" ||
|
|
111
|
+
/^(?:provider_network_error|connection_error|network_error)$/i.test(
|
|
112
|
+
text.trim(),
|
|
113
|
+
)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
105
117
|
export function normalizeChatError(
|
|
106
118
|
errorMessage: string,
|
|
107
119
|
errorCode?: string,
|
|
@@ -126,6 +138,18 @@ export function normalizeChatError(
|
|
|
126
138
|
};
|
|
127
139
|
}
|
|
128
140
|
|
|
141
|
+
if (isConnectionError(text, errorCode)) {
|
|
142
|
+
const providerNetworkError =
|
|
143
|
+
normalizeErrorCode(errorCode) === "provider_network_error" ||
|
|
144
|
+
/provider_network_error/i.test(text);
|
|
145
|
+
return {
|
|
146
|
+
message: providerNetworkError
|
|
147
|
+
? "The model provider could not be reached. Check your connection and retry."
|
|
148
|
+
: "The agent connection was interrupted. Check your connection and retry.",
|
|
149
|
+
details: text,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
129
153
|
if (/^Gateway error \(no detail; raw event:/i.test(text)) {
|
|
130
154
|
// The previous copy promised auto-recovery and suggested switching models,
|
|
131
155
|
// but neither helps for this code: the server already retried once and
|
|
@@ -115,7 +115,14 @@ export function McpIntegrationDialog({
|
|
|
115
115
|
...(mcpServersQuery.data?.user ?? []),
|
|
116
116
|
...(mcpServersQuery.data?.org ?? []),
|
|
117
117
|
];
|
|
118
|
-
|
|
118
|
+
// A saved server is not necessarily a working connection. The settings
|
|
119
|
+
// page reports failed and unknown health states separately, so only mark
|
|
120
|
+
// catalog entries as connected after the health probe succeeds.
|
|
121
|
+
return new Set(
|
|
122
|
+
servers
|
|
123
|
+
.filter((server) => server.status.state === "connected")
|
|
124
|
+
.map((server) => compareUrl(server.url)),
|
|
125
|
+
);
|
|
119
126
|
}, [mcpServersQuery.data]);
|
|
120
127
|
|
|
121
128
|
const filteredIntegrations = useMemo(
|
|
@@ -16,6 +16,14 @@ export interface AgentNativeManifestRoot {
|
|
|
16
16
|
extensions?: string[];
|
|
17
17
|
include?: string[];
|
|
18
18
|
hide?: string[];
|
|
19
|
+
source?: {
|
|
20
|
+
type: "local-folder";
|
|
21
|
+
connectionId: string;
|
|
22
|
+
truthPolicy?:
|
|
23
|
+
| "database_primary"
|
|
24
|
+
| "source_primary"
|
|
25
|
+
| "reviewed_bidirectional";
|
|
26
|
+
};
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
export interface AgentNativeManifestApp {
|
|
@@ -73,6 +81,7 @@ export interface LoadedLocalArtifactRoot {
|
|
|
73
81
|
extensions: string[];
|
|
74
82
|
hide: string[];
|
|
75
83
|
include: string[];
|
|
84
|
+
source?: AgentNativeManifestRoot["source"];
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
export interface LoadedLocalArtifactApp {
|
|
@@ -267,6 +276,26 @@ function rootNameFromPath(rootPath: string): string {
|
|
|
267
276
|
function normalizeManifestRoot(value: unknown): AgentNativeManifestRoot | null {
|
|
268
277
|
if (typeof value === "string") return { path: value };
|
|
269
278
|
if (!isRecord(value) || typeof value.path !== "string") return null;
|
|
279
|
+
const truthPolicy:
|
|
280
|
+
| NonNullable<AgentNativeManifestRoot["source"]>["truthPolicy"]
|
|
281
|
+
| undefined =
|
|
282
|
+
value.source &&
|
|
283
|
+
isRecord(value.source) &&
|
|
284
|
+
(value.source.truthPolicy === "database_primary" ||
|
|
285
|
+
value.source.truthPolicy === "source_primary" ||
|
|
286
|
+
value.source.truthPolicy === "reviewed_bidirectional")
|
|
287
|
+
? value.source.truthPolicy
|
|
288
|
+
: undefined;
|
|
289
|
+
const source =
|
|
290
|
+
isRecord(value.source) &&
|
|
291
|
+
value.source.type === "local-folder" &&
|
|
292
|
+
typeof value.source.connectionId === "string"
|
|
293
|
+
? {
|
|
294
|
+
type: "local-folder" as const,
|
|
295
|
+
connectionId: value.source.connectionId,
|
|
296
|
+
...(truthPolicy ? { truthPolicy } : {}),
|
|
297
|
+
}
|
|
298
|
+
: undefined;
|
|
270
299
|
return {
|
|
271
300
|
name: typeof value.name === "string" ? value.name : undefined,
|
|
272
301
|
path: value.path,
|
|
@@ -275,6 +304,7 @@ function normalizeManifestRoot(value: unknown): AgentNativeManifestRoot | null {
|
|
|
275
304
|
extensions: normalizeExtensions(value.extensions),
|
|
276
305
|
include: asStringArray(value.include),
|
|
277
306
|
hide: asStringArray(value.hide),
|
|
307
|
+
...(source ? { source } : {}),
|
|
278
308
|
};
|
|
279
309
|
}
|
|
280
310
|
|
|
@@ -483,6 +513,7 @@ export async function getLocalArtifactApp(
|
|
|
483
513
|
extensions,
|
|
484
514
|
hide: [...DEFAULT_HIDE_PATTERNS, ...asStringArray(root.hide)],
|
|
485
515
|
include: asStringArray(root.include),
|
|
516
|
+
source: root.source,
|
|
486
517
|
};
|
|
487
518
|
});
|
|
488
519
|
|
|
@@ -683,6 +714,16 @@ export async function listLocalArtifactFiles(
|
|
|
683
714
|
return files.sort((a, b) => a.path.localeCompare(b.path));
|
|
684
715
|
}
|
|
685
716
|
|
|
717
|
+
export async function listConfiguredLocalArtifactFiles(
|
|
718
|
+
options: LocalArtifactOptions,
|
|
719
|
+
): Promise<LocalArtifactFileMeta[]> {
|
|
720
|
+
const app = await getLocalArtifactApp(options);
|
|
721
|
+
const files = (await Promise.all(app.roots.map((root) => walkRoot(root))))
|
|
722
|
+
.flat()
|
|
723
|
+
.filter((file) => !matchesPatterns(file.path, app.hide));
|
|
724
|
+
return files.sort((a, b) => a.path.localeCompare(b.path));
|
|
725
|
+
}
|
|
726
|
+
|
|
686
727
|
function rootForArtifactPath(
|
|
687
728
|
app: LoadedLocalArtifactApp,
|
|
688
729
|
artifactPath: string,
|
|
@@ -758,6 +799,30 @@ export async function readLocalArtifactFile(
|
|
|
758
799
|
}
|
|
759
800
|
}
|
|
760
801
|
|
|
802
|
+
export async function readConfiguredLocalArtifactFile(
|
|
803
|
+
options: LocalArtifactOptions & { path: string },
|
|
804
|
+
): Promise<LocalArtifactFile | null> {
|
|
805
|
+
const app = await getLocalArtifactApp(options);
|
|
806
|
+
const { root, safePath, absolutePath } = await resolveArtifactPath(
|
|
807
|
+
app,
|
|
808
|
+
options.path,
|
|
809
|
+
);
|
|
810
|
+
try {
|
|
811
|
+
const { content, stat } = readTextFileWithoutSymlink(root, absolutePath);
|
|
812
|
+
const meta = await fileMetaForPath(
|
|
813
|
+
root,
|
|
814
|
+
safePath,
|
|
815
|
+
absolutePath,
|
|
816
|
+
content,
|
|
817
|
+
stat,
|
|
818
|
+
);
|
|
819
|
+
return { ...meta, content };
|
|
820
|
+
} catch (error) {
|
|
821
|
+
if (errorCode(error) === "ENOENT") return null;
|
|
822
|
+
throw error;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
761
826
|
export async function writeLocalArtifactFile(
|
|
762
827
|
options: WriteLocalArtifactFileOptions & { path: string },
|
|
763
828
|
): Promise<LocalArtifactFileMeta> {
|