@agent-native/core 0.91.1 → 0.92.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/blueprints/action/crud.md +1 -1
- package/blueprints/channel/discord.md +1 -1
- package/blueprints/provider/stripe.md +1 -1
- package/blueprints/sandbox/docker.md +1 -1
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +31 -0
- package/corpus/core/blueprints/action/crud.md +1 -1
- package/corpus/core/blueprints/channel/discord.md +1 -1
- package/corpus/core/blueprints/provider/stripe.md +1 -1
- package/corpus/core/blueprints/sandbox/docker.md +1 -1
- package/corpus/core/docs/content/faq.mdx +17 -0
- package/corpus/core/docs/content/notifications.mdx +12 -6
- package/corpus/core/package.json +6 -5
- package/corpus/core/src/agent/production-agent.ts +140 -46
- package/corpus/core/src/agent/run-manager.ts +23 -2
- package/corpus/core/src/agent/run-store.ts +2 -2
- package/corpus/core/src/agent/tool-search.ts +71 -4
- package/corpus/core/src/cli/add.ts +1 -1
- package/corpus/core/src/cli/create.ts +8 -3
- package/corpus/core/src/cli/index.ts +25 -4
- package/corpus/core/src/cli/upgrade.ts +798 -0
- package/corpus/core/src/client/AssistantChat.tsx +1 -1
- package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
- package/corpus/core/src/client/agent-chat-adapter.ts +31 -6
- package/corpus/core/src/client/chat/message-components.tsx +85 -8
- package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
- package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +7 -0
- package/corpus/core/src/client/settings/SettingsPanel.tsx +533 -389
- package/corpus/core/src/client/settings/SettingsSection.tsx +154 -17
- package/corpus/core/src/client/sse-event-processor.ts +29 -2
- package/corpus/core/src/extensions/actions.ts +113 -5
- package/corpus/core/src/jobs/scheduler.ts +30 -1
- package/corpus/core/src/localization/default-messages.ts +21 -0
- package/corpus/core/src/notifications/channels.ts +88 -25
- package/corpus/core/src/notifications/registry.ts +17 -3
- package/corpus/core/src/notifications/types.ts +4 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
- package/corpus/core/src/server/request-context.ts +7 -0
- package/corpus/core/src/styles/agent-conversation.css +1 -1
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/default/AGENTS.md +10 -3
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/default/package.json +4 -3
- package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/headless/AGENTS.md +9 -3
- package/corpus/core/src/templates/headless/package.json +4 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/core/src/templates/workspace-core/package.json +6 -6
- package/corpus/core/src/templates/workspace-root/AGENTS.md +10 -4
- package/corpus/core/src/templates/workspace-root/package.json +3 -2
- package/corpus/core/src/triggers/dispatcher.ts +30 -2
- package/corpus/core/src/vite/client.ts +96 -1
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +20 -2
- package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/analytics/AGENTS.md +7 -5
- package/corpus/templates/analytics/actions/save-monitor.ts +14 -0
- package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
- package/corpus/templates/analytics/app/global.css +26 -10
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +25 -0
- package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +151 -32
- package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
- package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +461 -286
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +285 -294
- package/corpus/templates/analytics/changelog/2026-07-08-console-details-expand-inline-under-each-row-and-the-event-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-keeps-a-usable-stage-when-dev-tools-is-open-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-resumes-after-scrubbing-and-expands-console-r.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-session-replays-wait-for-full-load-keep-a-normal-viewport-an.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
- package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
- package/corpus/templates/analytics/package.json +2 -2
- package/corpus/templates/analytics/server/db/schema-monitoring.ts +4 -0
- package/corpus/templates/analytics/server/lib/uptime-monitors.ts +60 -12
- package/corpus/templates/analytics/server/plugins/db.ts +10 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/assets/package.json +2 -2
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/brain/package.json +2 -2
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/calendar/AGENTS.md +10 -0
- package/corpus/templates/calendar/actions/create-event.ts +5 -1
- package/corpus/templates/calendar/actions/event-action-helpers.ts +41 -0
- package/corpus/templates/calendar/actions/get-attendee-timezones.ts +28 -0
- package/corpus/templates/calendar/actions/set-attendee-timezone.ts +68 -0
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +150 -11
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +36 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +32 -0
- package/corpus/templates/calendar/app/hooks/use-attendee-timezones.ts +24 -0
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/app/lib/attendee-local-time.ts +122 -0
- package/corpus/templates/calendar/changelog/2026-07-08-event-details-now-support-extension-widgets-and-you-can-see-.md +6 -0
- package/corpus/templates/calendar/changelog/2026-07-08-when-you-invite-guests-to-a-new-event-you-now-appear-in.md +6 -0
- package/corpus/templates/calendar/package.json +2 -2
- package/corpus/templates/calendar/server/handlers/events.ts +5 -1
- package/corpus/templates/calendar/shared/api.ts +6 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/chat/package.json +2 -2
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +6 -2
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/clips/actions/create-meeting.ts +8 -3
- package/corpus/templates/clips/actions/list-meetings.ts +31 -3
- package/corpus/templates/clips/changelog/2026-07-08-after-finishing-a-desktop-recording-reopening-clips-restor.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-clips-now-pops-up-to-take-notes-when-you-join-an-adhoc-zoom-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-clip-recordings-are-louder-after-capture-mic-only.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-meeting-reminders-now-appear-1-minute-before-start-stay-unti.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-08-the-desktop-meetings-panel-has-room-for-its-drop-shadow-and-.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +2 -2
- package/corpus/templates/clips/desktop/package.json +2 -2
- package/corpus/templates/clips/desktop/src/app.tsx +214 -37
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +30 -6
- package/corpus/templates/clips/desktop/src/lib/meeting-notification-timing.ts +83 -0
- package/corpus/templates/clips/desktop/src/lib/native-recording-warm.ts +21 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +98 -20
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +197 -50
- package/corpus/templates/clips/desktop/src/styles.css +150 -53
- package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +362 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +41 -7
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +9 -2
- package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +89 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +71 -17
- package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +36 -1
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +62 -10
- package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +1 -25
- package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +36 -1
- package/corpus/templates/clips/package.json +2 -2
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/content/actions/_batch-utils.ts +8 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
- package/corpus/templates/content/actions/_content-database-personal-view.ts +80 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
- package/corpus/templates/content/actions/_database-utils.ts +6 -1
- package/corpus/templates/content/actions/_property-utils.ts +168 -0
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
- package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
- package/corpus/templates/content/actions/delete-document.ts +9 -13
- package/corpus/templates/content/actions/get-content-database-personal-view.ts +27 -0
- package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
- package/corpus/templates/content/actions/update-content-database-personal-view.ts +31 -0
- package/corpus/templates/content/actions/update-content-database-view.ts +3 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +1 -1
- package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2631 -551
- package/corpus/templates/content/app/components/editor/database/filter-sort.ts +220 -18
- package/corpus/templates/content/app/hooks/use-content-database.ts +32 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
- package/corpus/templates/content/app/i18n/zh-TW.ts +16 -0
- package/corpus/templates/content/app/i18n-data.ts +154 -0
- package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-database-filters-now-support-notion-style-reset-save-for-eve.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-date-filters-can-now-target-a-between-range.md +6 -0
- package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
- package/corpus/templates/content/package.json +2 -2
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +2 -0
- package/corpus/templates/content/server/plugins/db.ts +19 -0
- package/corpus/templates/content/shared/api.ts +24 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/design/package.json +2 -2
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/dispatch/app/i18n/zh-TW.ts +34 -1
- package/corpus/templates/dispatch/app/i18n-data.ts +387 -10
- package/corpus/templates/dispatch/app/routes/automations.tsx +1 -0
- package/corpus/templates/dispatch/changelog/2026-07-08-added-an-automations-page-to-review-pause-and-create.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-08-destinations-now-shows-outbound-delivery-queue-health.md +6 -0
- package/corpus/templates/dispatch/package.json +2 -2
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/forms/package.json +2 -2
- package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/macros/package.json +2 -2
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/mail/app/hooks/use-emails.ts +56 -44
- package/corpus/templates/mail/app/lib/gmail-mutation-queue.ts +325 -0
- package/corpus/templates/mail/changelog/2026-07-08-rapid-archive-and-mark-read-now-batch-gmail-updates-so-the-i.md +6 -0
- package/corpus/templates/mail/package.json +2 -2
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/plan/package.json +2 -2
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/slides/app/components/editor/ImageDropPromptPopover.tsx +46 -29
- package/corpus/templates/slides/app/context/DeckContext.tsx +45 -18
- package/corpus/templates/slides/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +115 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +22 -13
- package/corpus/templates/slides/changelog/2026-07-08-dropping-an-image-onto-a-slide-and-sending-it-to-the-agent-w.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-08-undo-works-after-the-agent-edits-a-slide-so-you-can-reverse.md +6 -0
- package/corpus/templates/slides/package.json +2 -2
- package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/agent/production-agent.d.ts +5 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +112 -42
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +23 -2
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.js +2 -2
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/tool-search.d.ts +2 -0
- package/dist/agent/tool-search.d.ts.map +1 -1
- package/dist/agent/tool-search.js +60 -4
- package/dist/agent/tool-search.js.map +1 -1
- package/dist/catalog.json +2 -2
- package/dist/cli/add.js +1 -1
- package/dist/cli/add.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +8 -3
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +24 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/upgrade.d.ts +100 -0
- package/dist/cli/upgrade.d.ts.map +1 -0
- package/dist/cli/upgrade.js +678 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/client/AssistantChat.js +1 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/HighlightedCodeBlock.d.ts +2 -0
- package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
- package/dist/client/HighlightedCodeBlock.js +10 -1
- package/dist/client/HighlightedCodeBlock.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +32 -4
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +61 -8
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +12 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +136 -42
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/code-agent-chat-adapter.js +2 -9
- package/dist/client/code-agent-chat-adapter.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +6 -0
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +52 -19
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/SettingsSection.d.ts +19 -4
- package/dist/client/settings/SettingsSection.d.ts.map +1 -1
- package/dist/client/settings/SettingsSection.js +33 -4
- package/dist/client/settings/SettingsSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +9 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +20 -2
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +85 -5
- package/dist/extensions/actions.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/scheduler.js +26 -1
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/localization/default-messages.d.ts +19 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +19 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/channels.d.ts +8 -3
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +61 -22
- package/dist/notifications/channels.js.map +1 -1
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +14 -3
- package/dist/notifications/registry.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/types.d.ts +4 -1
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/notifications/types.js.map +1 -1
- package/dist/observability/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-chat-plugin.d.ts +5 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js.map +1 -1
- package/dist/styles/agent-conversation.css +1 -1
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/default/AGENTS.md +10 -3
- package/dist/templates/default/app/i18n/ar-SA.ts +21 -0
- package/dist/templates/default/app/i18n/de-DE.ts +21 -0
- package/dist/templates/default/app/i18n/en-US.ts +21 -0
- package/dist/templates/default/app/i18n/es-ES.ts +21 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +20 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +21 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +20 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +21 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +20 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/default/package.json +4 -3
- package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/headless/AGENTS.md +9 -3
- package/dist/templates/headless/package.json +4 -3
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/workspace-core/package.json +6 -6
- package/dist/templates/workspace-root/AGENTS.md +10 -4
- package/dist/templates/workspace-root/package.json +3 -2
- package/dist/triggers/dispatcher.js +27 -2
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +70 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/faq.mdx +17 -0
- package/docs/content/notifications.mdx +12 -6
- package/package.json +7 -6
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/default/AGENTS.md +10 -3
- package/src/templates/default/app/i18n/ar-SA.ts +21 -0
- package/src/templates/default/app/i18n/de-DE.ts +21 -0
- package/src/templates/default/app/i18n/en-US.ts +21 -0
- package/src/templates/default/app/i18n/es-ES.ts +21 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +20 -0
- package/src/templates/default/app/i18n/ja-JP.ts +21 -0
- package/src/templates/default/app/i18n/ko-KR.ts +20 -0
- package/src/templates/default/app/i18n/pt-BR.ts +21 -0
- package/src/templates/default/app/i18n/zh-CN.ts +20 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/default/package.json +4 -3
- package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/headless/AGENTS.md +9 -3
- package/src/templates/headless/package.json +4 -3
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
- package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/workspace-core/package.json +6 -6
- package/src/templates/workspace-root/AGENTS.md +10 -4
- package/src/templates/workspace-root/package.json +3 -2
|
@@ -6,6 +6,12 @@ import { createPortal } from "react-dom";
|
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
import { Textarea } from "@/components/ui/textarea";
|
|
8
8
|
import { toast } from "@/hooks/use-toast";
|
|
9
|
+
import {
|
|
10
|
+
buildImageDropAgentPayload,
|
|
11
|
+
readFileAsDataUrl,
|
|
12
|
+
type HostedImageUploadResult,
|
|
13
|
+
} from "@/lib/image-drop-to-agent";
|
|
14
|
+
import { parseUploadResponse } from "@/lib/upload-response";
|
|
9
15
|
|
|
10
16
|
const POPOVER_WIDTH = 360;
|
|
11
17
|
const POPOVER_MARGIN = 12;
|
|
@@ -24,8 +30,12 @@ interface ImageDropPromptPopoverProps {
|
|
|
24
30
|
* Popover shown after a user drops an image somewhere on the slides editor
|
|
25
31
|
* that doesn't have a clear target (i.e. not on an image placeholder or
|
|
26
32
|
* existing `<img>`). The popover previews the image, lets the user describe
|
|
27
|
-
* what to do with it, and hands the task off to the agent chat
|
|
28
|
-
*
|
|
33
|
+
* what to do with it, and hands the task off to the agent chat.
|
|
34
|
+
*
|
|
35
|
+
* Prefers a hosted CDN URL via `/api/assets/upload` when a file-upload
|
|
36
|
+
* provider (Builder.io / S3 / …) is configured. When nothing is configured,
|
|
37
|
+
* falls back to an inline data-URL attachment so the drop still reaches the
|
|
38
|
+
* agent instead of toasting a 503.
|
|
29
39
|
*
|
|
30
40
|
* Why this exists: dropping image files onto an unclear target previously did
|
|
31
41
|
* one of two unhelpful things — opened the file in a new browser tab (when the
|
|
@@ -113,44 +123,51 @@ export default function ImageDropPromptPopover({
|
|
|
113
123
|
try {
|
|
114
124
|
const form = new FormData();
|
|
115
125
|
form.append("file", file);
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
126
|
+
// Prefer the hosted provider chain. When none is configured the route
|
|
127
|
+
// returns 503 — fall back to an inline data URL so the agent still gets
|
|
128
|
+
// the image (chat already accepts `images` data URLs).
|
|
119
129
|
const res = await fetch(`${appBasePath()}/api/assets/upload`, {
|
|
120
130
|
method: "POST",
|
|
121
131
|
body: form,
|
|
122
132
|
});
|
|
123
|
-
const data =
|
|
133
|
+
const data = await parseUploadResponse<{
|
|
124
134
|
url?: string;
|
|
125
135
|
error?: string;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
136
|
+
}>(res, t("raw.imageUploadGenericError"));
|
|
137
|
+
const upload: HostedImageUploadResult = {
|
|
138
|
+
ok: res.ok && !!data.url,
|
|
139
|
+
status: res.status,
|
|
140
|
+
url: data.url,
|
|
141
|
+
error: data.error,
|
|
142
|
+
};
|
|
133
143
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
? userIntent
|
|
138
|
-
: "Use this image on the current slide.";
|
|
139
|
-
const lines = [intentLine];
|
|
140
|
-
if (contextHint && contextHint.trim().length > 0) {
|
|
141
|
-
lines.push(contextHint.trim());
|
|
144
|
+
let dataUrl: string | undefined;
|
|
145
|
+
if (!upload.ok) {
|
|
146
|
+
dataUrl = await readFileAsDataUrl(file);
|
|
142
147
|
}
|
|
143
|
-
lines.push(
|
|
144
|
-
`Image URL (already uploaded): ${data.url}`,
|
|
145
|
-
`Filename: ${file.name}`,
|
|
146
|
-
);
|
|
147
148
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
const payload = buildImageDropAgentPayload({
|
|
150
|
+
intent: prompt,
|
|
151
|
+
contextHint,
|
|
152
|
+
filename: file.name,
|
|
153
|
+
upload,
|
|
154
|
+
dataUrl,
|
|
152
155
|
});
|
|
153
156
|
|
|
157
|
+
if (payload.kind === "hosted") {
|
|
158
|
+
sendToAgentChat({
|
|
159
|
+
message: payload.message,
|
|
160
|
+
submit: true,
|
|
161
|
+
referenceImagePaths: payload.referenceImagePaths,
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
sendToAgentChat({
|
|
165
|
+
message: payload.message,
|
|
166
|
+
submit: true,
|
|
167
|
+
images: payload.images,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
154
171
|
onClose();
|
|
155
172
|
toast({
|
|
156
173
|
title: t("raw.sentToAgent"),
|
|
@@ -554,6 +554,16 @@ export function applyUndoOpToDecks(decks: Deck[], op: DeckUndoOp): Deck[] {
|
|
|
554
554
|
}
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
+
/**
|
|
558
|
+
* Compare deck content for remote-sync undo. Ignores `updatedAt` so a
|
|
559
|
+
* metadata-only refresh does not create a no-op undo entry.
|
|
560
|
+
*/
|
|
561
|
+
export function deckContentSignature(deck: Deck): string {
|
|
562
|
+
const { updatedAt: _updatedAt, ...rest } = deck;
|
|
563
|
+
void _updatedAt;
|
|
564
|
+
return JSON.stringify(rest);
|
|
565
|
+
}
|
|
566
|
+
|
|
557
567
|
/**
|
|
558
568
|
* Build the inverse of a granular op given the deck state BEFORE the op was
|
|
559
569
|
* applied. Returns an array of ops to apply (usually one, occasionally two) or
|
|
@@ -939,6 +949,37 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
939
949
|
[],
|
|
940
950
|
);
|
|
941
951
|
|
|
952
|
+
/**
|
|
953
|
+
* Apply a remote deck snapshot (agent / collaborator via SSE or poll) and
|
|
954
|
+
* record a replace-deck undo entry when content actually changed. Without
|
|
955
|
+
* this, chat-driven edits land in the editor with Undo disabled.
|
|
956
|
+
*/
|
|
957
|
+
const applyRemoteDeckUpdate = useCallback(
|
|
958
|
+
(updated: Deck, label = "Agent edit") => {
|
|
959
|
+
const before = decksRef.current.find((d) => d.id === updated.id);
|
|
960
|
+
if (
|
|
961
|
+
before &&
|
|
962
|
+
deckContentSignature(before) !== deckContentSignature(updated)
|
|
963
|
+
) {
|
|
964
|
+
undoControllerRef.current?.push({
|
|
965
|
+
undo: [{ op: "replace-deck", deckId: updated.id, deck: before }],
|
|
966
|
+
redo: [{ op: "replace-deck", deckId: updated.id, deck: updated }],
|
|
967
|
+
label,
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
setDecks((prev) => {
|
|
971
|
+
const idx = prev.findIndex((d) => d.id === updated.id);
|
|
972
|
+
if (idx >= 0) {
|
|
973
|
+
const next = [...prev];
|
|
974
|
+
next[idx] = updated;
|
|
975
|
+
return next;
|
|
976
|
+
}
|
|
977
|
+
return [...prev, updated];
|
|
978
|
+
});
|
|
979
|
+
},
|
|
980
|
+
[],
|
|
981
|
+
);
|
|
982
|
+
|
|
942
983
|
const resetDeckBaseline = useCallback((nextDecks: Deck[]) => {
|
|
943
984
|
setDecks(nextDecks);
|
|
944
985
|
// A baseline reset (initial mount, route change, or access reload) starts a
|
|
@@ -1082,13 +1123,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1082
1123
|
clientDeck.slides.length !== serverDeck.slides.length;
|
|
1083
1124
|
if (changed) {
|
|
1084
1125
|
lastExternalUpdateRef.current = Date.now();
|
|
1085
|
-
|
|
1086
|
-
const idx = prev.findIndex((d) => d.id === currentOpenId);
|
|
1087
|
-
if (idx < 0) return [...prev, serverDeck];
|
|
1088
|
-
const next = [...prev];
|
|
1089
|
-
next[idx] = serverDeck;
|
|
1090
|
-
return next;
|
|
1091
|
-
});
|
|
1126
|
+
applyRemoteDeckUpdate(serverDeck);
|
|
1092
1127
|
}
|
|
1093
1128
|
}
|
|
1094
1129
|
} catch {}
|
|
@@ -1125,7 +1160,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1125
1160
|
window.removeEventListener("focus", pollNow);
|
|
1126
1161
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1127
1162
|
};
|
|
1128
|
-
}, [loading]);
|
|
1163
|
+
}, [applyRemoteDeckUpdate, loading]);
|
|
1129
1164
|
|
|
1130
1165
|
// The dirty-deck set is now only used as a sentinel that "something changed
|
|
1131
1166
|
// for this deck". Ops are enqueued directly in each mutation handler below;
|
|
@@ -1172,20 +1207,12 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1172
1207
|
const updated = await fetchDeckFromAPI(data.deckId);
|
|
1173
1208
|
if (!updated) return;
|
|
1174
1209
|
lastExternalUpdateRef.current = Date.now(); // Suppress save-back
|
|
1175
|
-
|
|
1176
|
-
const idx = prev.findIndex((d) => d.id === data.deckId);
|
|
1177
|
-
if (idx >= 0) {
|
|
1178
|
-
const next = [...prev];
|
|
1179
|
-
next[idx] = updated;
|
|
1180
|
-
return next;
|
|
1181
|
-
}
|
|
1182
|
-
return [...prev, updated];
|
|
1183
|
-
});
|
|
1210
|
+
applyRemoteDeckUpdate(updated);
|
|
1184
1211
|
}
|
|
1185
1212
|
} catch {}
|
|
1186
1213
|
};
|
|
1187
1214
|
return () => evtSource.close();
|
|
1188
|
-
}, []);
|
|
1215
|
+
}, [applyRemoteDeckUpdate]);
|
|
1189
1216
|
|
|
1190
1217
|
// Flush pending (debounced) saves before the tab is hidden or unloaded so the
|
|
1191
1218
|
// last ~500ms of edits aren't lost on close/navigation. `pagehide` is the
|
|
@@ -91,6 +91,8 @@ const messages = {
|
|
|
91
91
|
googlePickerNeedsKeys:
|
|
92
92
|
"Google Picker precisa de GOOGLE_PICKER_API_KEY e GOOGLE_PICKER_APP_ID.",
|
|
93
93
|
imageUploadFailed: "Falha ao enviar imagem",
|
|
94
|
+
imageUploadNeedsBuilder:
|
|
95
|
+
"وصّل Builder.io من قائمة النموذج في مؤلف الوكيل لتحميل الصور إلى الشرائح. لا يزال بإمكانك إفلات صورة على اللوحة الفارغة لإرسالها إلى الوكيل بدون مزود.",
|
|
94
96
|
sentToAgent: "Enviado ao agente",
|
|
95
97
|
imageUploadGenericError: "Algo deu errado ao enviar esta imagem.",
|
|
96
98
|
uploading: "Enviando…",
|
|
@@ -489,6 +491,8 @@ const messages = {
|
|
|
489
491
|
backToDecks: "Volver a decks",
|
|
490
492
|
tryAgain: "Intentar de nuevo",
|
|
491
493
|
imageUploadFailed: "Error al subir imagen",
|
|
494
|
+
imageUploadNeedsBuilder:
|
|
495
|
+
"وصّل Builder.io من قائمة النموذج في مؤلف الوكيل لتحميل الصور إلى الشرائح. لا يزال بإمكانك إفلات صورة على اللوحة الفارغة لإرسالها إلى الوكيل بدون مزود.",
|
|
492
496
|
imageAdded: "Imagen añadida",
|
|
493
497
|
imageUploadError: "Algo salió mal al subir esta imagen.",
|
|
494
498
|
exportFailed: "Error al exportar",
|
|
@@ -93,6 +93,8 @@ const messages = {
|
|
|
93
93
|
googlePickerNeedsKeys:
|
|
94
94
|
"Google Picker benötigt GOOGLE_PICKER_API_KEY und GOOGLE_PICKER_APP_ID.",
|
|
95
95
|
imageUploadFailed: "Bildupload fehlgeschlagen",
|
|
96
|
+
imageUploadNeedsBuilder:
|
|
97
|
+
"Verbinde Builder.io im Modellmenü des Agent-Composers, um Bilder auf Folien hochzuladen. Wenn du ein Bild auf die leere Arbeitsfläche ziehst, kann es auch ohne Anbieter an den Agenten gesendet werden.",
|
|
96
98
|
sentToAgent: "An Agent gesendet",
|
|
97
99
|
imageUploadGenericError:
|
|
98
100
|
"Beim Hochladen dieses Bildes ist etwas schiefgelaufen.",
|
|
@@ -484,6 +486,8 @@ const messages = {
|
|
|
484
486
|
backToDecks: "Volver a decks",
|
|
485
487
|
tryAgain: "Intentar de nuevo",
|
|
486
488
|
imageUploadFailed: "Error al subir imagen",
|
|
489
|
+
imageUploadNeedsBuilder:
|
|
490
|
+
"Verbinde Builder.io im Modellmenü des Agent-Composers, um Bilder auf Folien hochzuladen. Wenn du ein Bild auf die leere Arbeitsfläche ziehst, kann es auch ohne Anbieter an den Agenten gesendet werden.",
|
|
487
491
|
imageAdded: "Imagen añadida",
|
|
488
492
|
imageUploadError: "Algo salió mal al subir esta imagen.",
|
|
489
493
|
exportFailed: "Error al exportar",
|
|
@@ -92,6 +92,8 @@ const messages = {
|
|
|
92
92
|
googlePickerNeedsKeys:
|
|
93
93
|
"Google Picker needs GOOGLE_PICKER_API_KEY and GOOGLE_PICKER_APP_ID.",
|
|
94
94
|
imageUploadFailed: "Image upload failed",
|
|
95
|
+
imageUploadNeedsBuilder:
|
|
96
|
+
"Connect Builder.io from the agent composer model menu to upload images onto slides. Dropping an image onto empty canvas can still send it to the agent without a provider.",
|
|
95
97
|
sentToAgent: "Sent to agent",
|
|
96
98
|
imageUploadGenericError: "Something went wrong uploading this image.",
|
|
97
99
|
uploading: "Uploading…",
|
|
@@ -477,6 +479,8 @@ const messages = {
|
|
|
477
479
|
backToDecks: "Back to Decks",
|
|
478
480
|
tryAgain: "Try again",
|
|
479
481
|
imageUploadFailed: "Image upload failed",
|
|
482
|
+
imageUploadNeedsBuilder:
|
|
483
|
+
"Connect Builder.io from the agent composer model menu to upload images onto slides. Dropping an image onto empty canvas can still send it to the agent without a provider.",
|
|
480
484
|
imageAdded: "Image added",
|
|
481
485
|
imageUploadError: "Something went wrong uploading this image.",
|
|
482
486
|
exportFailed: "Export failed",
|
|
@@ -93,6 +93,8 @@ const messages = {
|
|
|
93
93
|
googlePickerNeedsKeys:
|
|
94
94
|
"Google Picker necesita GOOGLE_PICKER_API_KEY y GOOGLE_PICKER_APP_ID.",
|
|
95
95
|
imageUploadFailed: "Error al subir la imagen",
|
|
96
|
+
imageUploadNeedsBuilder:
|
|
97
|
+
"Conecta Builder.io desde el menú de modelos del compositor del agente para subir imágenes a las diapositivas. Soltar una imagen en el lienzo vacío aún puede enviarla al agente sin proveedor.",
|
|
96
98
|
sentToAgent: "Enviado al agente",
|
|
97
99
|
imageUploadGenericError: "Algo salió mal al subir esta imagen.",
|
|
98
100
|
uploading: "Subiendo…",
|
|
@@ -488,6 +490,8 @@ const messages = {
|
|
|
488
490
|
backToDecks: "Volver a decks",
|
|
489
491
|
tryAgain: "Intentar de nuevo",
|
|
490
492
|
imageUploadFailed: "Error al subir imagen",
|
|
493
|
+
imageUploadNeedsBuilder:
|
|
494
|
+
"Conecta Builder.io desde el menú de modelos del compositor del agente para subir imágenes a las diapositivas. Soltar una imagen en el lienzo vacío aún puede enviarla al agente sin proveedor.",
|
|
491
495
|
imageAdded: "Imagen añadida",
|
|
492
496
|
imageUploadError: "Algo salió mal al subir esta imagen.",
|
|
493
497
|
exportFailed: "Error al exportar",
|
|
@@ -93,6 +93,8 @@ const messages = {
|
|
|
93
93
|
googlePickerNeedsKeys:
|
|
94
94
|
"Google Picker nécessite GOOGLE_PICKER_API_KEY et GOOGLE_PICKER_APP_ID.",
|
|
95
95
|
imageUploadFailed: "Échec de l’envoi de l’image",
|
|
96
|
+
imageUploadNeedsBuilder:
|
|
97
|
+
"Connectez Builder.io depuis le menu de modèle du composeur d’agent pour téléverser des images sur les diapositives. Déposer une image sur le canevas vide peut toujours l’envoyer à l’agent sans fournisseur.",
|
|
96
98
|
sentToAgent: "Envoyé à l’agent",
|
|
97
99
|
imageUploadGenericError:
|
|
98
100
|
"Une erreur est survenue lors de l’envoi de cette image.",
|
|
@@ -492,6 +494,8 @@ const messages = {
|
|
|
492
494
|
backToDecks: "Volver a decks",
|
|
493
495
|
tryAgain: "Intentar de nuevo",
|
|
494
496
|
imageUploadFailed: "Error al subir imagen",
|
|
497
|
+
imageUploadNeedsBuilder:
|
|
498
|
+
"Connectez Builder.io depuis le menu de modèle du composeur d’agent pour téléverser des images sur les diapositives. Déposer une image sur le canevas vide peut toujours l’envoyer à l’agent sans fournisseur.",
|
|
495
499
|
imageAdded: "Imagen añadida",
|
|
496
500
|
imageUploadError: "Algo salió mal al subir esta imagen.",
|
|
497
501
|
exportFailed: "Error al exportar",
|
|
@@ -91,6 +91,8 @@ const messages = {
|
|
|
91
91
|
googlePickerNeedsKeys:
|
|
92
92
|
"Google Picker precisa de GOOGLE_PICKER_API_KEY e GOOGLE_PICKER_APP_ID.",
|
|
93
93
|
imageUploadFailed: "Falha ao enviar imagem",
|
|
94
|
+
imageUploadNeedsBuilder:
|
|
95
|
+
"स्लाइड पर चित्र अपलोड करने के लिए एजेंट composer के मॉडल मेनू से Builder.io कनेक्ट करें। खाली कैनवास पर चित्र छोड़ने से वह बिना provider के भी एजेंट को भेजा जा सकता है।",
|
|
94
96
|
sentToAgent: "Enviado ao agente",
|
|
95
97
|
imageUploadGenericError: "Algo deu errado ao enviar esta imagem.",
|
|
96
98
|
uploading: "Enviando…",
|
|
@@ -472,6 +474,8 @@ const messages = {
|
|
|
472
474
|
backToDecks: "डेक पर वापस जाएं",
|
|
473
475
|
tryAgain: "फिर कोशिश करें",
|
|
474
476
|
imageUploadFailed: "चित्र अपलोड विफल",
|
|
477
|
+
imageUploadNeedsBuilder:
|
|
478
|
+
"स्लाइड पर चित्र अपलोड करने के लिए एजेंट composer के मॉडल मेनू से Builder.io कनेक्ट करें। खाली कैनवास पर चित्र छोड़ने से वह बिना provider के भी एजेंट को भेजा जा सकता है।",
|
|
475
479
|
imageAdded: "चित्र जोड़ा गया",
|
|
476
480
|
imageUploadError: "यह चित्र अपलोड करते समय कुछ गलत हुआ।",
|
|
477
481
|
exportFailed: "निर्यात विफल",
|
|
@@ -92,6 +92,8 @@ const messages = {
|
|
|
92
92
|
googlePickerNeedsKeys:
|
|
93
93
|
"Google PickerにはGOOGLE_PICKER_API_KEYとGOOGLE_PICKER_APP_IDが必要です。",
|
|
94
94
|
imageUploadFailed: "画像のアップロードに失敗しました",
|
|
95
|
+
imageUploadNeedsBuilder:
|
|
96
|
+
"スライドに画像をアップロードするには、エージェント作成欄のモデルメニューから Builder.io に接続してください。空のキャンバスに画像をドロップすると、プロバイダーなしでもエージェントに送信できます。",
|
|
95
97
|
sentToAgent: "エージェントに送信しました",
|
|
96
98
|
imageUploadGenericError: "この画像のアップロード中に問題が発生しました。",
|
|
97
99
|
uploading: "アップロード中…",
|
|
@@ -471,6 +473,8 @@ const messages = {
|
|
|
471
473
|
backToDecks: "返回幻灯片",
|
|
472
474
|
tryAgain: "重试",
|
|
473
475
|
imageUploadFailed: "图片上传失败",
|
|
476
|
+
imageUploadNeedsBuilder:
|
|
477
|
+
"スライドに画像をアップロードするには、エージェント作成欄のモデルメニューから Builder.io に接続してください。空のキャンバスに画像をドロップすると、プロバイダーなしでもエージェントに送信できます。",
|
|
474
478
|
imageAdded: "图片已添加",
|
|
475
479
|
imageUploadError: "上传此图片时出了点问题。",
|
|
476
480
|
exportFailed: "导出失败",
|
|
@@ -92,6 +92,8 @@ const messages = {
|
|
|
92
92
|
googlePickerNeedsKeys:
|
|
93
93
|
"Google PickerにはGOOGLE_PICKER_API_KEYとGOOGLE_PICKER_APP_IDが必要です。",
|
|
94
94
|
imageUploadFailed: "画像のアップロードに失敗しました",
|
|
95
|
+
imageUploadNeedsBuilder:
|
|
96
|
+
"슬라이드에 이미지를 업로드하려면 에이전트 작성기의 모델 메뉴에서 Builder.io를 연결하세요. 빈 캔버스에 이미지를 놓으면 제공자 없이도 에이전트로 보낼 수 있습니다.",
|
|
95
97
|
sentToAgent: "エージェントに送信しました",
|
|
96
98
|
imageUploadGenericError: "この画像のアップロード中に問題が発生しました。",
|
|
97
99
|
uploading: "アップロード中…",
|
|
@@ -469,6 +471,8 @@ const messages = {
|
|
|
469
471
|
backToDecks: "返回幻灯片",
|
|
470
472
|
tryAgain: "重试",
|
|
471
473
|
imageUploadFailed: "图片上传失败",
|
|
474
|
+
imageUploadNeedsBuilder:
|
|
475
|
+
"슬라이드에 이미지를 업로드하려면 에이전트 작성기의 모델 메뉴에서 Builder.io를 연결하세요. 빈 캔버스에 이미지를 놓으면 제공자 없이도 에이전트로 보낼 수 있습니다.",
|
|
472
476
|
imageAdded: "图片已添加",
|
|
473
477
|
imageUploadError: "上传此图片时出了点问题。",
|
|
474
478
|
exportFailed: "导出失败",
|
|
@@ -92,6 +92,8 @@ const messages = {
|
|
|
92
92
|
googlePickerNeedsKeys:
|
|
93
93
|
"Google Picker precisa de GOOGLE_PICKER_API_KEY e GOOGLE_PICKER_APP_ID.",
|
|
94
94
|
imageUploadFailed: "Falha ao enviar imagem",
|
|
95
|
+
imageUploadNeedsBuilder:
|
|
96
|
+
"Conecte o Builder.io no menu de modelo do compositor do agente para enviar imagens aos slides. Soltar uma imagem na tela vazia ainda pode enviá-la ao agente sem provedor.",
|
|
95
97
|
sentToAgent: "Enviado ao agente",
|
|
96
98
|
imageUploadGenericError: "Algo deu errado ao enviar esta imagem.",
|
|
97
99
|
uploading: "Enviando…",
|
|
@@ -483,6 +485,8 @@ const messages = {
|
|
|
483
485
|
backToDecks: "Volver a decks",
|
|
484
486
|
tryAgain: "Intentar de nuevo",
|
|
485
487
|
imageUploadFailed: "Error al subir imagen",
|
|
488
|
+
imageUploadNeedsBuilder:
|
|
489
|
+
"Conecte o Builder.io no menu de modelo do compositor do agente para enviar imagens aos slides. Soltar uma imagem na tela vazia ainda pode enviá-la ao agente sem provedor.",
|
|
486
490
|
imageAdded: "Imagen añadida",
|
|
487
491
|
imageUploadError: "Algo salió mal al subir esta imagen.",
|
|
488
492
|
exportFailed: "Error al exportar",
|
|
@@ -90,6 +90,8 @@ const messages = {
|
|
|
90
90
|
googlePickerNeedsKeys:
|
|
91
91
|
"Google PickerにはGOOGLE_PICKER_API_KEYとGOOGLE_PICKER_APP_IDが必要です。",
|
|
92
92
|
imageUploadFailed: "画像のアップロードに失敗しました",
|
|
93
|
+
imageUploadNeedsBuilder:
|
|
94
|
+
"请从代理编写器的模型菜单连接 Builder.io,以便将图片上传到幻灯片。即使没有提供方,把图片拖到空白画布上仍可发送给代理。",
|
|
93
95
|
sentToAgent: "エージェントに送信しました",
|
|
94
96
|
imageUploadGenericError: "この画像のアップロード中に問題が発生しました。",
|
|
95
97
|
uploading: "アップロード中…",
|
|
@@ -465,6 +467,8 @@ const messages = {
|
|
|
465
467
|
backToDecks: "返回幻灯片",
|
|
466
468
|
tryAgain: "重试",
|
|
467
469
|
imageUploadFailed: "图片上传失败",
|
|
470
|
+
imageUploadNeedsBuilder:
|
|
471
|
+
"请从代理编写器的模型菜单连接 Builder.io,以便将图片上传到幻灯片。即使没有提供方,把图片拖到空白画布上仍可发送给代理。",
|
|
468
472
|
imageAdded: "图片已添加",
|
|
469
473
|
imageUploadError: "上传此图片时出了点问题。",
|
|
470
474
|
exportFailed: "导出失败",
|
|
@@ -88,6 +88,8 @@ const messages = {
|
|
|
88
88
|
googlePickerNeedsKeys:
|
|
89
89
|
"Google Picker 需要 GOOGLE_PICKER_API_KEY 和 GOOGLE_PICKER_APP_ID。",
|
|
90
90
|
imageUploadFailed: "圖片上傳失敗",
|
|
91
|
+
imageUploadNeedsBuilder:
|
|
92
|
+
"請從代理編寫器的模型選單連接 Builder.io,以便將圖片上傳到投影片。即使沒有提供者,將圖片拖到空白畫布上仍可傳送給代理。",
|
|
91
93
|
sentToAgent: "已傳送給代理",
|
|
92
94
|
imageUploadGenericError: "上傳這張圖片時發生問題。",
|
|
93
95
|
uploading: "正在上傳…",
|
|
@@ -460,6 +462,8 @@ const messages = {
|
|
|
460
462
|
backToDecks: "返回幻燈片",
|
|
461
463
|
tryAgain: "重試",
|
|
462
464
|
imageUploadFailed: "圖片上傳失敗",
|
|
465
|
+
imageUploadNeedsBuilder:
|
|
466
|
+
"請從代理編寫器的模型選單連接 Builder.io,以便將圖片上傳到投影片。即使沒有提供者,將圖片拖到空白畫布上仍可傳送給代理。",
|
|
463
467
|
imageAdded: "圖片已新增",
|
|
464
468
|
imageUploadError: "上傳此圖片時出了點問題。",
|
|
465
469
|
exportFailed: "匯出失敗",
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve how to hand a dropped image to the agent chat.
|
|
3
|
+
*
|
|
4
|
+
* Prefer a hosted CDN URL from `/api/assets/upload` when a file-upload
|
|
5
|
+
* provider is configured. When nothing is configured (or the upload fails),
|
|
6
|
+
* fall back to an inline data URL so the agent can still see the image —
|
|
7
|
+
* chat already accepts `images: string[]` data URLs without a storage
|
|
8
|
+
* provider. The agent can call `upload-image` later if the slide needs a
|
|
9
|
+
* durable hosted URL.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export interface HostedImageUploadResult {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
status: number;
|
|
15
|
+
url?: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ImageDropAgentPayload =
|
|
20
|
+
| {
|
|
21
|
+
kind: "hosted";
|
|
22
|
+
message: string;
|
|
23
|
+
referenceImagePaths: string[];
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
kind: "inline";
|
|
27
|
+
message: string;
|
|
28
|
+
images: string[];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function isMissingUploadProviderError(
|
|
32
|
+
status: number,
|
|
33
|
+
error: string | undefined,
|
|
34
|
+
): boolean {
|
|
35
|
+
if (status === 503) return true;
|
|
36
|
+
const lower = (error ?? "").toLowerCase();
|
|
37
|
+
return (
|
|
38
|
+
lower.includes("no file upload provider") ||
|
|
39
|
+
lower.includes("registerfileuploadprovider") ||
|
|
40
|
+
lower.includes("connect builder.io")
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function buildImageDropAgentPayload(args: {
|
|
45
|
+
intent: string;
|
|
46
|
+
contextHint?: string;
|
|
47
|
+
filename: string;
|
|
48
|
+
upload: HostedImageUploadResult;
|
|
49
|
+
dataUrl?: string;
|
|
50
|
+
}): ImageDropAgentPayload {
|
|
51
|
+
const intentLine =
|
|
52
|
+
args.intent.trim().length > 0
|
|
53
|
+
? args.intent.trim()
|
|
54
|
+
: "Use this image on the current slide.";
|
|
55
|
+
const lines = [intentLine];
|
|
56
|
+
if (args.contextHint && args.contextHint.trim().length > 0) {
|
|
57
|
+
lines.push(args.contextHint.trim());
|
|
58
|
+
}
|
|
59
|
+
lines.push(`Filename: ${args.filename}`);
|
|
60
|
+
|
|
61
|
+
if (args.upload.ok && args.upload.url) {
|
|
62
|
+
lines.splice(
|
|
63
|
+
lines.length - 1,
|
|
64
|
+
0,
|
|
65
|
+
`Image URL (already uploaded): ${args.upload.url}`,
|
|
66
|
+
);
|
|
67
|
+
return {
|
|
68
|
+
kind: "hosted",
|
|
69
|
+
message: lines.join("\n\n"),
|
|
70
|
+
referenceImagePaths: [args.upload.url],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!args.dataUrl) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
args.upload.error ||
|
|
77
|
+
"Image upload failed. Connect Builder.io from the agent composer model menu, or register a custom provider via registerFileUploadProvider().",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!isMissingUploadProviderError(args.upload.status, args.upload.error)) {
|
|
82
|
+
// Unexpected upload failure — still try the inline path so the user can
|
|
83
|
+
// keep working, but tell the agent the hosted upload didn't land.
|
|
84
|
+
lines.push(
|
|
85
|
+
"Hosted upload failed; the image is attached inline as a data URL. Call upload-image on it before placing it on the slide if a durable URL is required.",
|
|
86
|
+
);
|
|
87
|
+
} else {
|
|
88
|
+
lines.push(
|
|
89
|
+
"No file upload provider is configured, so the image is attached inline as a data URL. Call upload-image to obtain a hosted URL before inserting it into slide HTML.",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
kind: "inline",
|
|
95
|
+
message: lines.join("\n\n"),
|
|
96
|
+
images: [args.dataUrl],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function readFileAsDataUrl(file: File): Promise<string> {
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const reader = new FileReader();
|
|
103
|
+
reader.onload = () => {
|
|
104
|
+
const result = reader.result;
|
|
105
|
+
if (typeof result === "string" && result.startsWith("data:")) {
|
|
106
|
+
resolve(result);
|
|
107
|
+
} else {
|
|
108
|
+
reject(new Error("Failed to read image file."));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
reader.onerror = () =>
|
|
112
|
+
reject(reader.error ?? new Error("Failed to read image file."));
|
|
113
|
+
reader.readAsDataURL(file);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
shouldClearNewDeckGeneratingState,
|
|
71
71
|
shouldShowNewDeckGeneratingOverlay,
|
|
72
72
|
} from "@/lib/generation-state";
|
|
73
|
+
import { isMissingUploadProviderError } from "@/lib/image-drop-to-agent";
|
|
73
74
|
import { imageFileLooksSupported } from "@/lib/slide-image-replacement";
|
|
74
75
|
import { replaceImageTargetInSlideHtml } from "@/lib/slide-image-replacement";
|
|
75
76
|
import { TAB_ID } from "@/lib/tab-id";
|
|
@@ -323,19 +324,27 @@ export default function DeckEditor() {
|
|
|
323
324
|
[deck, id, reorderSlides],
|
|
324
325
|
);
|
|
325
326
|
|
|
326
|
-
const uploadImageAsset = useCallback(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
327
|
+
const uploadImageAsset = useCallback(
|
|
328
|
+
async (file: File): Promise<string> => {
|
|
329
|
+
const form = new FormData();
|
|
330
|
+
form.append("file", file);
|
|
331
|
+
const res = await fetch(`${appBasePath()}/api/assets/upload`, {
|
|
332
|
+
method: "POST",
|
|
333
|
+
body: form,
|
|
334
|
+
});
|
|
335
|
+
const data = await res.json().catch(() => null);
|
|
336
|
+
if (!res.ok || !data?.url) {
|
|
337
|
+
const serverError =
|
|
338
|
+
typeof data?.error === "string" ? data.error : undefined;
|
|
339
|
+
if (isMissingUploadProviderError(res.status, serverError)) {
|
|
340
|
+
throw new Error(t("deckEditor.imageUploadNeedsBuilder"));
|
|
341
|
+
}
|
|
342
|
+
throw new Error(serverError || t("deckEditor.imageUploadFailed"));
|
|
343
|
+
}
|
|
344
|
+
return data.url as string;
|
|
345
|
+
},
|
|
346
|
+
[t],
|
|
347
|
+
);
|
|
339
348
|
|
|
340
349
|
// Replace an image or placeholder in the current slide's HTML content.
|
|
341
350
|
const replaceImageInSlide = useCallback(
|
|
@@ -103,7 +103,6 @@
|
|
|
103
103
|
"@types/react": "catalog:",
|
|
104
104
|
"@types/react-dom": "catalog:",
|
|
105
105
|
"@types/three": "^0.176.0",
|
|
106
|
-
"@typescript/native-preview": "catalog:",
|
|
107
106
|
"@vitejs/plugin-react-swc": "^4.0.0",
|
|
108
107
|
"class-variance-authority": "^0.7.1",
|
|
109
108
|
"clsx": "^2.1.1",
|
|
@@ -129,7 +128,8 @@
|
|
|
129
128
|
"tailwindcss": "catalog:",
|
|
130
129
|
"three": "^0.176.0",
|
|
131
130
|
"tsx": "^4.20.3",
|
|
132
|
-
"typescript": "
|
|
131
|
+
"typescript": "catalog:",
|
|
132
|
+
"typescript-7": "catalog:",
|
|
133
133
|
"vaul": "^1.1.2",
|
|
134
134
|
"vite": "catalog:",
|
|
135
135
|
"vitest": "catalog:"
|