@agent-native/core 0.103.0 → 0.104.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.
Files changed (572) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +36 -0
  3. package/corpus/core/package.json +9 -2
  4. package/corpus/core/src/agent/engine/credential-errors.ts +2 -2
  5. package/corpus/core/src/agent/production-agent.ts +30 -0
  6. package/corpus/core/src/agent/run-store.ts +12 -2
  7. package/corpus/core/src/cli/create.ts +1 -0
  8. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +30 -11
  9. package/corpus/core/src/cli/templates-meta.ts +4 -3
  10. package/corpus/core/src/client/AgentAskPopover.tsx +89 -0
  11. package/corpus/core/src/client/AgentChatHome.tsx +4 -0
  12. package/corpus/core/src/client/AgentPanel.tsx +321 -223
  13. package/corpus/core/src/client/AssistantChat.tsx +6 -10
  14. package/corpus/core/src/client/MultiTabAssistantChat.tsx +53 -372
  15. package/corpus/core/src/client/agent-chat-adapter.ts +13 -1
  16. package/corpus/core/src/client/agent-page/AgentContextTab.tsx +133 -149
  17. package/corpus/core/src/client/agent-page/AgentEmptyState.tsx +44 -0
  18. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +153 -82
  19. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +39 -0
  20. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +368 -356
  21. package/corpus/core/src/client/agent-page/types.ts +1 -1
  22. package/corpus/core/src/client/analytics.ts +51 -5
  23. package/corpus/core/src/client/chat/run-recovery.tsx +12 -4
  24. package/corpus/core/src/client/composer/PromptComposer.tsx +5 -15
  25. package/corpus/core/src/client/composer/TiptapComposer.tsx +32 -3
  26. package/corpus/core/src/client/dynamic-suggestions.ts +3 -3
  27. package/corpus/core/src/client/index.ts +16 -1
  28. package/corpus/core/src/client/resources/ResourceTree.tsx +249 -38
  29. package/corpus/core/src/client/resources/ResourcesPanel.tsx +307 -140
  30. package/corpus/core/src/client/session-replay.ts +158 -5
  31. package/corpus/core/src/client/settings/AutomationsSection.tsx +30 -10
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +3 -2
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +2 -0
  34. package/corpus/core/src/client/settings/agent-settings-search.ts +2 -2
  35. package/corpus/core/src/client/use-chat-threads.ts +2 -0
  36. package/corpus/core/src/connections/catalog.ts +49 -7
  37. package/corpus/core/src/db/index.ts +6 -1
  38. package/corpus/core/src/extensions/actions.ts +106 -16
  39. package/corpus/core/src/extensions/content-patch.ts +22 -0
  40. package/corpus/core/src/extensions/routes.ts +18 -0
  41. package/corpus/core/src/extensions/store.ts +8 -0
  42. package/corpus/core/src/index.ts +3 -0
  43. package/corpus/core/src/ingestion/docx.ts +158 -0
  44. package/corpus/core/src/ingestion/figma-node-to-html.ts +1860 -0
  45. package/corpus/core/src/ingestion/figma.ts +548 -0
  46. package/corpus/core/src/ingestion/index.ts +107 -0
  47. package/corpus/core/src/ingestion/media.ts +264 -0
  48. package/corpus/core/src/ingestion/notion.ts +121 -0
  49. package/corpus/core/src/ingestion/office.ts +214 -0
  50. package/corpus/core/src/ingestion/orchestration.ts +160 -0
  51. package/corpus/core/src/ingestion/pptx.ts +333 -0
  52. package/corpus/core/src/ingestion/selection.ts +81 -0
  53. package/corpus/core/src/ingestion/website.ts +151 -0
  54. package/corpus/core/src/integrations/plugin.ts +45 -37
  55. package/corpus/core/src/localization/default-messages.ts +35 -12
  56. package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
  57. package/corpus/core/src/observability/traces.ts +5 -3
  58. package/corpus/core/src/provider-api/index.ts +452 -8
  59. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +18 -1
  60. package/corpus/core/src/search-utils/index.ts +112 -0
  61. package/corpus/core/src/secrets/register-framework-secrets.ts +61 -0
  62. package/corpus/core/src/server/action-discovery.ts +33 -8
  63. package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
  64. package/corpus/core/src/server/agent-chat/prompt-resources.ts +144 -0
  65. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  66. package/corpus/core/src/server/core-routes-plugin.ts +12 -0
  67. package/corpus/core/src/server/index.ts +30 -0
  68. package/corpus/core/src/server/workspace-provider-oauth.ts +583 -0
  69. package/corpus/core/src/styles/agent-native.css +9 -0
  70. package/corpus/core/src/templates/default/app/i18n/en-US.ts +3 -3
  71. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  72. package/corpus/core/src/templates/workspace-root/.env.example +12 -0
  73. package/corpus/core/src/vite/client.ts +2 -0
  74. package/corpus/core/src/workspace-connections/index.ts +6 -0
  75. package/corpus/core/src/workspace-connections/lifecycle.ts +43 -0
  76. package/corpus/core/src/workspace-connections/store.ts +16 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +46 -3
  78. package/corpus/templates/analytics/AGENTS.md +9 -0
  79. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +120 -6
  80. package/corpus/templates/analytics/actions/mutate-dashboard.ts +92 -30
  81. package/corpus/templates/analytics/actions/update-dashboard.ts +5 -5
  82. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +313 -220
  83. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -2
  84. package/corpus/templates/analytics/app/components/layout/Layout.tsx +9 -6
  85. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +90 -64
  86. package/corpus/templates/analytics/app/i18n-data.ts +3 -3
  87. package/corpus/templates/analytics/app/lib/dashboard-list-loading.ts +25 -0
  88. package/corpus/templates/analytics/app/lib/item-popularity.ts +13 -4
  89. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +1 -1
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/pivot.ts +8 -3
  91. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
  92. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +15 -3
  93. package/corpus/templates/analytics/changelog/2026-07-16-dashboard-filter-defaults-can-now-be-changed-reliably-withou.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-16-dashboard-lists-load-in-one-stable-order-without-popping-bet.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-16-fixed-dashboard-filter-dropdown-text-alignment.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-07-16-recurring-signed-in-users-can-now-be-viewed-as-weekly-bars-b.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-07-16-the-analytics-agent-can-now-duplicate-a-chart-and-place-the-.md +6 -0
  98. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +41 -1
  99. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -1
  100. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +47 -1
  101. package/corpus/templates/analytics/server/lib/session-replay.ts +68 -0
  102. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  103. package/corpus/templates/analytics/server/routes/sessions/lookup.get.ts +47 -0
  104. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +16 -9
  105. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +86 -0
  106. package/corpus/templates/assets/AGENTS.md +10 -0
  107. package/corpus/templates/assets/actions/create-generation-session.ts +59 -1
  108. package/corpus/templates/assets/actions/edit-image.ts +2 -0
  109. package/corpus/templates/assets/actions/generate-asset.ts +52 -0
  110. package/corpus/templates/assets/actions/generate-image-batch.ts +55 -0
  111. package/corpus/templates/assets/actions/generate-image.ts +219 -1
  112. package/corpus/templates/assets/actions/open-asset-picker.ts +14 -0
  113. package/corpus/templates/assets/actions/refine-image.ts +3 -0
  114. package/corpus/templates/assets/actions/restyle-image.ts +2 -0
  115. package/corpus/templates/assets/agent-native.app-skill.json +4 -0
  116. package/corpus/templates/assets/app/components/layout/Layout.tsx +2 -0
  117. package/corpus/templates/assets/app/i18n/zh-TW.ts +3 -0
  118. package/corpus/templates/assets/app/i18n-data.ts +29 -13
  119. package/corpus/templates/assets/app/routes/agent.tsx +7 -1
  120. package/corpus/templates/assets/app/routes/library.tsx +9 -0
  121. package/corpus/templates/assets/app/routes/settings.tsx +3 -0
  122. package/corpus/templates/assets/changelog/2026-07-16-creative-context-library.md +6 -0
  123. package/corpus/templates/assets/package.json +1 -0
  124. package/corpus/templates/assets/server/lib/image-processing.ts +1 -22
  125. package/corpus/templates/assets/server/plugins/creative-context.ts +205 -0
  126. package/corpus/templates/brain/app/i18n-data.ts +3 -3
  127. package/corpus/templates/brain/app/lib/brain.ts +1 -1
  128. package/corpus/templates/brain/server/lib/search.ts +17 -67
  129. package/corpus/templates/calendar/app/i18n-data.ts +3 -3
  130. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +19 -18
  131. package/corpus/templates/chat/app/i18n/en-US.ts +3 -3
  132. package/corpus/templates/chat/app/lib/agent-page.tsx +10 -1
  133. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +1 -1
  134. package/corpus/templates/clips/AGENTS.md +4 -0
  135. package/corpus/templates/clips/actions/cleanup-transcript.ts +35 -4
  136. package/corpus/templates/clips/actions/create-meeting.ts +6 -2
  137. package/corpus/templates/clips/actions/create-organization.ts +3 -2
  138. package/corpus/templates/clips/actions/create-recording.ts +4 -1
  139. package/corpus/templates/clips/actions/finalize-recording.ts +44 -7
  140. package/corpus/templates/clips/actions/import-loom-recording.ts +4 -1
  141. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +2 -2
  142. package/corpus/templates/clips/actions/list-meetings.ts +23 -5
  143. package/corpus/templates/clips/actions/list-organization-state.ts +1 -1
  144. package/corpus/templates/clips/actions/remove-silences.ts +10 -1
  145. package/corpus/templates/clips/actions/request-transcript.ts +53 -11
  146. package/corpus/templates/clips/actions/search-recordings-utils.ts +7 -0
  147. package/corpus/templates/clips/actions/search-recordings.ts +5 -8
  148. package/corpus/templates/clips/actions/set-organization-branding.ts +2 -2
  149. package/corpus/templates/clips/actions/stitch-recordings.ts +10 -5
  150. package/corpus/templates/clips/actions/update-ai-request-status.ts +38 -0
  151. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +3 -4
  152. package/corpus/templates/clips/app/components/editor/editor-selection.ts +19 -0
  153. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +10 -10
  154. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +1 -2
  155. package/corpus/templates/clips/app/components/library/library-grid.tsx +101 -93
  156. package/corpus/templates/clips/app/components/player/video-player.tsx +11 -0
  157. package/corpus/templates/clips/app/components/workspace/branding-editor.tsx +53 -1
  158. package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
  159. package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
  160. package/corpus/templates/clips/app/i18n/en-US.ts +10 -4
  161. package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
  162. package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
  163. package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
  164. package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
  165. package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
  166. package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
  167. package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -1
  168. package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -1
  169. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +5 -9
  170. package/corpus/templates/clips/app/routes/_app.settings.organization.tsx +6 -2
  171. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +129 -27
  172. package/corpus/templates/clips/app/routes/record.tsx +23 -2
  173. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -2
  174. package/corpus/templates/clips/changelog/2026-07-16-authorized-viewers-can-open-shared-private-clips-without-a-m.md +6 -0
  175. package/corpus/templates/clips/changelog/2026-07-16-camera-bubble-hover-controls-appear-above-the-face.md +6 -0
  176. package/corpus/templates/clips/changelog/2026-07-16-chrome-extension-recovers-stale-recorder-state.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-16-clips-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-16-clips-search-now-matches-recording-content-without-requiring.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-16-declined-meetings-no-longer-show-desktop-reminders.md +6 -0
  180. package/corpus/templates/clips/changelog/2026-07-16-failed-desktop-saves-now-show-their-local-recovery-copy.md +6 -0
  181. package/corpus/templates/clips/changelog/2026-07-16-long-desktop-clips-now-preserve-complete-playback-synced-aud.md +6 -0
  182. package/corpus/templates/clips/changelog/2026-07-16-long-recording-lists-keep-stitch-and-library-actions-visible.md +6 -0
  183. package/corpus/templates/clips/changelog/2026-07-16-organization-admins-can-choose-new-recording-visibility.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-16-remove-silences-now-shows-queued-active-completed-and-failed.md +6 -0
  185. package/corpus/templates/clips/changelog/2026-07-16-settings-no-longer-repeats-the-builder-connection-status-in-.md +6 -0
  186. package/corpus/templates/clips/changelog/2026-07-16-transcripts-now-appear-from-native-browser-speech-sooner-wit.md +6 -0
  187. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  188. package/corpus/templates/clips/chrome-extension/src/background.ts +73 -1
  189. package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +32 -0
  190. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +248 -0
  191. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +106 -0
  192. package/corpus/templates/clips/desktop/src/app.tsx +66 -28
  193. package/corpus/templates/clips/desktop/src/lib/recorder.ts +335 -285
  194. package/corpus/templates/clips/desktop/src/lib/single-flight.ts +7 -0
  195. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +51 -0
  196. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +2 -2
  197. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +10 -2
  198. package/corpus/templates/clips/desktop/src/styles.css +13 -11
  199. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +8 -9
  200. package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +1 -0
  201. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +88 -13
  202. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +13 -2
  203. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +241 -6
  204. package/corpus/templates/clips/server/db/schema.ts +2 -2
  205. package/corpus/templates/clips/server/lib/builder-media-compression.ts +64 -67
  206. package/corpus/templates/clips/server/lib/calendar-event-classification.ts +19 -0
  207. package/corpus/templates/clips/server/lib/google-calendar-client.ts +1 -0
  208. package/corpus/templates/clips/server/lib/recordings.ts +40 -1
  209. package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
  210. package/corpus/templates/clips/server/plugins/db.ts +2 -2
  211. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +1 -1
  212. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +14 -5
  213. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +51 -1
  214. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +1 -64
  215. package/corpus/templates/clips/shared/media-worker-contract.ts +32 -15
  216. package/corpus/templates/content/.agents/skills/content/SKILL.md +16 -0
  217. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +85 -0
  218. package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +8 -0
  219. package/corpus/templates/content/AGENTS.md +9 -0
  220. package/corpus/templates/content/actions/create-document.ts +94 -0
  221. package/corpus/templates/content/actions/edit-document.ts +144 -4
  222. package/corpus/templates/content/actions/update-document.ts +138 -0
  223. package/corpus/templates/content/agent-native.app-skill.json +4 -0
  224. package/corpus/templates/content/app/components/layout/Layout.tsx +2 -0
  225. package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
  226. package/corpus/templates/content/app/i18n-data.ts +13 -4
  227. package/corpus/templates/content/app/routes/_app.agent.tsx +2 -1
  228. package/corpus/templates/content/app/routes/_app.settings.tsx +3 -0
  229. package/corpus/templates/content/changelog/2026-07-16-creative-context-library.md +6 -0
  230. package/corpus/templates/content/package.json +1 -0
  231. package/corpus/templates/content/server/plugins/creative-context.ts +31 -0
  232. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +116 -0
  233. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +16 -0
  234. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
  235. package/corpus/templates/design/AGENTS.md +6 -0
  236. package/corpus/templates/design/actions/clone-creative-context-design.ts +176 -0
  237. package/corpus/templates/design/actions/edit-design.ts +128 -0
  238. package/corpus/templates/design/actions/generate-design.ts +278 -14
  239. package/corpus/templates/design/actions/generate-screens.ts +42 -1
  240. package/corpus/templates/design/agent-native.app-skill.json +4 -0
  241. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -3
  242. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  243. package/corpus/templates/design/app/i18n-data.ts +10 -4
  244. package/corpus/templates/design/app/routes/agent.tsx +2 -1
  245. package/corpus/templates/design/app/routes/settings.tsx +3 -0
  246. package/corpus/templates/design/changelog/2026-07-16-creative-context-library.md +6 -0
  247. package/corpus/templates/design/changelog/2026-07-16-design-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
  248. package/corpus/templates/design/package.json +1 -0
  249. package/corpus/templates/design/server/lib/figma-design-context.ts +5 -335
  250. package/corpus/templates/design/server/lib/figma-node-to-html.ts +1 -1859
  251. package/corpus/templates/design/server/lib/import-design-files.ts +6 -8
  252. package/corpus/templates/design/server/plugins/creative-context.ts +31 -0
  253. package/corpus/templates/design/shared/generation-session.ts +7 -0
  254. package/corpus/templates/dispatch/app/i18n-data.ts +3 -3
  255. package/corpus/templates/forms/app/i18n/en-US.ts +3 -3
  256. package/corpus/templates/macros/app/i18n/en-US.ts +3 -3
  257. package/corpus/templates/mail/app/components/email/EmailThread.tsx +35 -5
  258. package/corpus/templates/mail/app/i18n/en-US.ts +3 -3
  259. package/corpus/templates/mail/changelog/2026-07-16-mail-previews-now-expand-to-show-the-full-message-without-an.md +6 -0
  260. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +30 -11
  261. package/corpus/templates/plan/AGENTS.md +21 -1
  262. package/corpus/templates/plan/actions/get-visual-plan.ts +1 -1
  263. package/corpus/templates/plan/actions/patch-visual-plan-source.ts +161 -0
  264. package/corpus/templates/plan/actions/read-visual-plan-source.ts +1 -1
  265. package/corpus/templates/plan/actions/update-visual-plan.ts +126 -10
  266. package/corpus/templates/plan/app/hooks/use-plans.ts +2 -0
  267. package/corpus/templates/plan/app/i18n/en-US.ts +3 -3
  268. package/corpus/templates/plan/app/pages/PlansPage.tsx +65 -62
  269. package/corpus/templates/plan/changelog/2026-07-16-local-plan-previews-now-load-annotations-containing-html-lik.md +6 -0
  270. package/corpus/templates/plan/changelog/2026-07-16-plan-agents-now-prevent-stale-edits-from-overwriting-newer-p.md +6 -0
  271. package/corpus/templates/plan/server/plan-mdx.ts +75 -2
  272. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +21 -4
  273. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +122 -0
  274. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +11 -0
  275. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +12 -3
  276. package/corpus/templates/slides/AGENTS.md +6 -0
  277. package/corpus/templates/slides/actions/add-slide.ts +230 -14
  278. package/corpus/templates/slides/actions/clone-context-slide.ts +302 -0
  279. package/corpus/templates/slides/actions/create-deck.ts +130 -0
  280. package/corpus/templates/slides/actions/extract-pdf.ts +6 -2
  281. package/corpus/templates/slides/actions/import-file.ts +5 -4
  282. package/corpus/templates/slides/actions/patch-deck.ts +200 -10
  283. package/corpus/templates/slides/actions/update-slide.ts +208 -15
  284. package/corpus/templates/slides/app/components/layout/Layout.tsx +2 -0
  285. package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +16 -1
  286. package/corpus/templates/slides/app/i18n/ar-SA.ts +3 -0
  287. package/corpus/templates/slides/app/i18n/de-DE.ts +3 -0
  288. package/corpus/templates/slides/app/i18n/en-US.ts +6 -3
  289. package/corpus/templates/slides/app/i18n/es-ES.ts +3 -0
  290. package/corpus/templates/slides/app/i18n/fr-FR.ts +3 -0
  291. package/corpus/templates/slides/app/i18n/hi-IN.ts +3 -0
  292. package/corpus/templates/slides/app/i18n/ja-JP.ts +3 -0
  293. package/corpus/templates/slides/app/i18n/ko-KR.ts +3 -0
  294. package/corpus/templates/slides/app/i18n/pt-BR.ts +3 -0
  295. package/corpus/templates/slides/app/i18n/zh-CN.ts +3 -0
  296. package/corpus/templates/slides/app/i18n/zh-TW.ts +3 -0
  297. package/corpus/templates/slides/app/lib/validate-native-slide-html.ts +176 -0
  298. package/corpus/templates/slides/app/routes/agent.tsx +7 -1
  299. package/corpus/templates/slides/app/routes/settings.tsx +3 -0
  300. package/corpus/templates/slides/changelog/2026-07-16-creative-context-library.md +6 -0
  301. package/corpus/templates/slides/changelog/2026-07-16-google-slides-native-cloning.md +6 -0
  302. package/corpus/templates/slides/package.json +1 -0
  303. package/corpus/templates/slides/server/handlers/import/docx-parser.ts +4 -85
  304. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +7 -421
  305. package/corpus/templates/slides/server/plugins/creative-context.ts +166 -0
  306. package/dist/agent/engine/credential-errors.d.ts +1 -1
  307. package/dist/agent/engine/credential-errors.d.ts.map +1 -1
  308. package/dist/agent/engine/credential-errors.js +2 -2
  309. package/dist/agent/engine/credential-errors.js.map +1 -1
  310. package/dist/agent/production-agent.d.ts.map +1 -1
  311. package/dist/agent/production-agent.js +25 -0
  312. package/dist/agent/production-agent.js.map +1 -1
  313. package/dist/agent/run-store.d.ts.map +1 -1
  314. package/dist/agent/run-store.js +12 -2
  315. package/dist/agent/run-store.js.map +1 -1
  316. package/dist/cli/create.d.ts.map +1 -1
  317. package/dist/cli/create.js +1 -0
  318. package/dist/cli/create.js.map +1 -1
  319. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  320. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  321. package/dist/cli/skills-content/visual-plan-skill.js +30 -11
  322. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  323. package/dist/cli/templates-meta.d.ts.map +1 -1
  324. package/dist/cli/templates-meta.js +4 -3
  325. package/dist/cli/templates-meta.js.map +1 -1
  326. package/dist/client/AgentAskPopover.d.ts +11 -0
  327. package/dist/client/AgentAskPopover.d.ts.map +1 -0
  328. package/dist/client/AgentAskPopover.js +30 -0
  329. package/dist/client/AgentAskPopover.js.map +1 -0
  330. package/dist/client/AgentChatHome.d.ts +1 -1
  331. package/dist/client/AgentChatHome.d.ts.map +1 -1
  332. package/dist/client/AgentChatHome.js +2 -2
  333. package/dist/client/AgentChatHome.js.map +1 -1
  334. package/dist/client/AgentPanel.d.ts +9 -19
  335. package/dist/client/AgentPanel.d.ts.map +1 -1
  336. package/dist/client/AgentPanel.js +119 -80
  337. package/dist/client/AgentPanel.js.map +1 -1
  338. package/dist/client/AssistantChat.d.ts.map +1 -1
  339. package/dist/client/AssistantChat.js +4 -4
  340. package/dist/client/AssistantChat.js.map +1 -1
  341. package/dist/client/MultiTabAssistantChat.d.ts +3 -9
  342. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  343. package/dist/client/MultiTabAssistantChat.js +49 -189
  344. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  345. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  346. package/dist/client/agent-chat-adapter.js +12 -1
  347. package/dist/client/agent-chat-adapter.js.map +1 -1
  348. package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -1
  349. package/dist/client/agent-page/AgentContextTab.js +26 -28
  350. package/dist/client/agent-page/AgentContextTab.js.map +1 -1
  351. package/dist/client/agent-page/AgentEmptyState.d.ts +13 -0
  352. package/dist/client/agent-page/AgentEmptyState.d.ts.map +1 -0
  353. package/dist/client/agent-page/AgentEmptyState.js +6 -0
  354. package/dist/client/agent-page/AgentEmptyState.js.map +1 -0
  355. package/dist/client/agent-page/AgentJobsTab.d.ts +1 -1
  356. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  357. package/dist/client/agent-page/AgentJobsTab.js +90 -58
  358. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  359. package/dist/client/agent-page/AgentTabFrame.d.ts +12 -0
  360. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -0
  361. package/dist/client/agent-page/AgentTabFrame.js +7 -0
  362. package/dist/client/agent-page/AgentTabFrame.js.map +1 -0
  363. package/dist/client/agent-page/AgentTabsPage.d.ts +9 -1
  364. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  365. package/dist/client/agent-page/AgentTabsPage.js +135 -99
  366. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  367. package/dist/client/agent-page/types.d.ts +1 -1
  368. package/dist/client/agent-page/types.d.ts.map +1 -1
  369. package/dist/client/agent-page/types.js.map +1 -1
  370. package/dist/client/analytics.d.ts +10 -3
  371. package/dist/client/analytics.d.ts.map +1 -1
  372. package/dist/client/analytics.js +37 -2
  373. package/dist/client/analytics.js.map +1 -1
  374. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  375. package/dist/client/chat/run-recovery.js +10 -3
  376. package/dist/client/chat/run-recovery.js.map +1 -1
  377. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  378. package/dist/client/composer/PromptComposer.js +2 -2
  379. package/dist/client/composer/PromptComposer.js.map +1 -1
  380. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  381. package/dist/client/composer/TiptapComposer.js +15 -3
  382. package/dist/client/composer/TiptapComposer.js.map +1 -1
  383. package/dist/client/dynamic-suggestions.js +3 -3
  384. package/dist/client/dynamic-suggestions.js.map +1 -1
  385. package/dist/client/index.d.ts +4 -3
  386. package/dist/client/index.d.ts.map +1 -1
  387. package/dist/client/index.js +3 -2
  388. package/dist/client/index.js.map +1 -1
  389. package/dist/client/resources/ResourceTree.d.ts +5 -1
  390. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  391. package/dist/client/resources/ResourceTree.js +74 -5
  392. package/dist/client/resources/ResourceTree.js.map +1 -1
  393. package/dist/client/resources/ResourcesPanel.d.ts +11 -2
  394. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  395. package/dist/client/resources/ResourcesPanel.js +105 -31
  396. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  397. package/dist/client/session-replay.d.ts +28 -0
  398. package/dist/client/session-replay.d.ts.map +1 -1
  399. package/dist/client/session-replay.js +122 -8
  400. package/dist/client/session-replay.js.map +1 -1
  401. package/dist/client/settings/AutomationsSection.d.ts +3 -1
  402. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  403. package/dist/client/settings/AutomationsSection.js +16 -6
  404. package/dist/client/settings/AutomationsSection.js.map +1 -1
  405. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  406. package/dist/client/settings/SettingsPanel.js +3 -3
  407. package/dist/client/settings/SettingsPanel.js.map +1 -1
  408. package/dist/client/settings/SettingsTabsPage.d.ts +2 -0
  409. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  410. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  411. package/dist/client/settings/agent-settings-search.js +2 -2
  412. package/dist/client/settings/agent-settings-search.js.map +1 -1
  413. package/dist/client/use-chat-threads.d.ts +2 -0
  414. package/dist/client/use-chat-threads.d.ts.map +1 -1
  415. package/dist/client/use-chat-threads.js.map +1 -1
  416. package/dist/collab/awareness.d.ts +2 -2
  417. package/dist/collab/awareness.d.ts.map +1 -1
  418. package/dist/collab/routes.d.ts +1 -1
  419. package/dist/connections/catalog.d.ts +41 -7
  420. package/dist/connections/catalog.d.ts.map +1 -1
  421. package/dist/connections/catalog.js +40 -7
  422. package/dist/connections/catalog.js.map +1 -1
  423. package/dist/db/index.d.ts +2 -2
  424. package/dist/db/index.d.ts.map +1 -1
  425. package/dist/db/index.js +2 -2
  426. package/dist/db/index.js.map +1 -1
  427. package/dist/extensions/actions.d.ts.map +1 -1
  428. package/dist/extensions/actions.js +85 -15
  429. package/dist/extensions/actions.js.map +1 -1
  430. package/dist/extensions/content-patch.d.ts +4 -0
  431. package/dist/extensions/content-patch.d.ts.map +1 -1
  432. package/dist/extensions/content-patch.js +18 -0
  433. package/dist/extensions/content-patch.js.map +1 -1
  434. package/dist/extensions/routes.d.ts.map +1 -1
  435. package/dist/extensions/routes.js +14 -0
  436. package/dist/extensions/routes.js.map +1 -1
  437. package/dist/extensions/store.d.ts +1 -0
  438. package/dist/extensions/store.d.ts.map +1 -1
  439. package/dist/extensions/store.js +4 -1
  440. package/dist/extensions/store.js.map +1 -1
  441. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  442. package/dist/index.d.ts +1 -1
  443. package/dist/index.d.ts.map +1 -1
  444. package/dist/index.js +1 -1
  445. package/dist/index.js.map +1 -1
  446. package/dist/ingestion/docx.d.ts +16 -0
  447. package/dist/ingestion/docx.d.ts.map +1 -0
  448. package/dist/ingestion/docx.js +129 -0
  449. package/dist/ingestion/docx.js.map +1 -0
  450. package/dist/ingestion/figma-node-to-html.d.ts +304 -0
  451. package/dist/ingestion/figma-node-to-html.d.ts.map +1 -0
  452. package/dist/ingestion/figma-node-to-html.js +1292 -0
  453. package/dist/ingestion/figma-node-to-html.js.map +1 -0
  454. package/dist/ingestion/figma.d.ts +115 -0
  455. package/dist/ingestion/figma.d.ts.map +1 -0
  456. package/dist/ingestion/figma.js +399 -0
  457. package/dist/ingestion/figma.js.map +1 -0
  458. package/dist/ingestion/index.d.ts +11 -0
  459. package/dist/ingestion/index.d.ts.map +1 -0
  460. package/dist/ingestion/index.js +11 -0
  461. package/dist/ingestion/index.js.map +1 -0
  462. package/dist/ingestion/media.d.ts +36 -0
  463. package/dist/ingestion/media.d.ts.map +1 -0
  464. package/dist/ingestion/media.js +178 -0
  465. package/dist/ingestion/media.js.map +1 -0
  466. package/dist/ingestion/notion.d.ts +12 -0
  467. package/dist/ingestion/notion.d.ts.map +1 -0
  468. package/dist/ingestion/notion.js +104 -0
  469. package/dist/ingestion/notion.js.map +1 -0
  470. package/dist/ingestion/office.d.ts +45 -0
  471. package/dist/ingestion/office.d.ts.map +1 -0
  472. package/dist/ingestion/office.js +141 -0
  473. package/dist/ingestion/office.js.map +1 -0
  474. package/dist/ingestion/orchestration.d.ts +52 -0
  475. package/dist/ingestion/orchestration.d.ts.map +1 -0
  476. package/dist/ingestion/orchestration.js +89 -0
  477. package/dist/ingestion/orchestration.js.map +1 -0
  478. package/dist/ingestion/pptx.d.ts +28 -0
  479. package/dist/ingestion/pptx.d.ts.map +1 -0
  480. package/dist/ingestion/pptx.js +255 -0
  481. package/dist/ingestion/pptx.js.map +1 -0
  482. package/dist/ingestion/selection.d.ts +20 -0
  483. package/dist/ingestion/selection.d.ts.map +1 -0
  484. package/dist/ingestion/selection.js +52 -0
  485. package/dist/ingestion/selection.js.map +1 -0
  486. package/dist/ingestion/website.d.ts +27 -0
  487. package/dist/ingestion/website.d.ts.map +1 -0
  488. package/dist/ingestion/website.js +100 -0
  489. package/dist/ingestion/website.js.map +1 -0
  490. package/dist/integrations/plugin.d.ts.map +1 -1
  491. package/dist/integrations/plugin.js +32 -27
  492. package/dist/integrations/plugin.js.map +1 -1
  493. package/dist/localization/default-messages.d.ts +22 -0
  494. package/dist/localization/default-messages.d.ts.map +1 -1
  495. package/dist/localization/default-messages.js +31 -9
  496. package/dist/localization/default-messages.js.map +1 -1
  497. package/dist/observability/hosted-model-experiment.d.ts +39 -0
  498. package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
  499. package/dist/observability/hosted-model-experiment.js +90 -0
  500. package/dist/observability/hosted-model-experiment.js.map +1 -0
  501. package/dist/observability/routes.d.ts +5 -5
  502. package/dist/observability/traces.d.ts.map +1 -1
  503. package/dist/observability/traces.js +5 -3
  504. package/dist/observability/traces.js.map +1 -1
  505. package/dist/progress/routes.d.ts +1 -1
  506. package/dist/provider-api/index.d.ts +35 -4
  507. package/dist/provider-api/index.d.ts.map +1 -1
  508. package/dist/provider-api/index.js +339 -8
  509. package/dist/provider-api/index.js.map +1 -1
  510. package/dist/resources/handlers.d.ts +1 -1
  511. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  512. package/dist/scripts/agent-engines/list-agent-engines.js +18 -1
  513. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  514. package/dist/search-utils/index.d.ts +12 -0
  515. package/dist/search-utils/index.d.ts.map +1 -0
  516. package/dist/search-utils/index.js +95 -0
  517. package/dist/search-utils/index.js.map +1 -0
  518. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  519. package/dist/secrets/register-framework-secrets.js +57 -0
  520. package/dist/secrets/register-framework-secrets.js.map +1 -1
  521. package/dist/secrets/routes.d.ts +9 -9
  522. package/dist/server/action-discovery.d.ts +8 -0
  523. package/dist/server/action-discovery.d.ts.map +1 -1
  524. package/dist/server/action-discovery.js +26 -9
  525. package/dist/server/action-discovery.js.map +1 -1
  526. package/dist/server/agent-chat/framework-prompts.js +2 -2
  527. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  528. package/dist/server/agent-chat/prompt-resources.d.ts +19 -0
  529. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  530. package/dist/server/agent-chat/prompt-resources.js +95 -0
  531. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  532. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  533. package/dist/server/agent-chat-plugin.js +7 -0
  534. package/dist/server/agent-chat-plugin.js.map +1 -1
  535. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  536. package/dist/server/core-routes-plugin.js +5 -0
  537. package/dist/server/core-routes-plugin.js.map +1 -1
  538. package/dist/server/index.d.ts +5 -1
  539. package/dist/server/index.d.ts.map +1 -1
  540. package/dist/server/index.js +5 -1
  541. package/dist/server/index.js.map +1 -1
  542. package/dist/server/workspace-provider-oauth.d.ts +48 -0
  543. package/dist/server/workspace-provider-oauth.d.ts.map +1 -0
  544. package/dist/server/workspace-provider-oauth.js +415 -0
  545. package/dist/server/workspace-provider-oauth.js.map +1 -0
  546. package/dist/styles/agent-native.css +9 -0
  547. package/dist/templates/chat/app/i18n/en-US.ts +3 -3
  548. package/dist/templates/chat/app/lib/agent-page.tsx +10 -1
  549. package/dist/templates/default/app/i18n/en-US.ts +3 -3
  550. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  551. package/dist/templates/workspace-root/.env.example +12 -0
  552. package/dist/vite/client.d.ts.map +1 -1
  553. package/dist/vite/client.js +2 -0
  554. package/dist/vite/client.js.map +1 -1
  555. package/dist/workspace-connections/index.d.ts +1 -0
  556. package/dist/workspace-connections/index.d.ts.map +1 -1
  557. package/dist/workspace-connections/index.js +1 -0
  558. package/dist/workspace-connections/index.js.map +1 -1
  559. package/dist/workspace-connections/lifecycle.d.ts +16 -0
  560. package/dist/workspace-connections/lifecycle.d.ts.map +1 -0
  561. package/dist/workspace-connections/lifecycle.js +14 -0
  562. package/dist/workspace-connections/lifecycle.js.map +1 -0
  563. package/dist/workspace-connections/store.d.ts.map +1 -1
  564. package/dist/workspace-connections/store.js +16 -0
  565. package/dist/workspace-connections/store.js.map +1 -1
  566. package/package.json +10 -3
  567. package/src/templates/chat/app/i18n/en-US.ts +3 -3
  568. package/src/templates/chat/app/lib/agent-page.spec.tsx +10 -1
  569. package/src/templates/chat/app/lib/agent-page.tsx +10 -1
  570. package/src/templates/default/app/i18n/en-US.ts +3 -3
  571. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  572. package/src/templates/workspace-root/.env.example +12 -0
@@ -1,421 +1,7 @@
1
- import { XMLParser } from "fast-xml-parser";
2
- import JSZip from "jszip";
3
-
4
- export interface ParsedTextRun {
5
- content: string;
6
- bold?: boolean;
7
- italic?: boolean;
8
- fontSize?: number;
9
- color?: string;
10
- }
11
-
12
- export interface ParsedImage {
13
- data: Buffer;
14
- mimeType: string;
15
- name: string;
16
- }
17
-
18
- export interface ParsedSlide {
19
- texts: ParsedTextRun[];
20
- images: ParsedImage[];
21
- notes?: string;
22
- layoutHint?: string;
23
- }
24
-
25
- export interface ParsedPresentation {
26
- title: string;
27
- slides: ParsedSlide[];
28
- theme?: { colors: string[]; fonts: string[] };
29
- }
30
-
31
- const parser = new XMLParser({
32
- ignoreAttributes: false,
33
- attributeNamePrefix: "@_",
34
- });
35
-
36
- /** Normalise a value into an array (handles XML single-child vs multi-child). */
37
- function asArray<T>(val: T | T[] | undefined | null): T[] {
38
- if (val == null) return [];
39
- return Array.isArray(val) ? val : [val];
40
- }
41
-
42
- /** Recursively collect all `a:t` text nodes from a tree. */
43
- function collectTexts(
44
- node: unknown,
45
- runs: ParsedTextRun[],
46
- inheritedProps?: {
47
- bold?: boolean;
48
- italic?: boolean;
49
- fontSize?: number;
50
- color?: string;
51
- },
52
- ): void {
53
- if (node == null || typeof node !== "object") return;
54
-
55
- const obj = node as Record<string, unknown>;
56
-
57
- // a:r — a text run with optional formatting in a:rPr
58
- if (obj["a:r"] != null) {
59
- for (const run of asArray(obj["a:r"])) {
60
- const rObj = run as Record<string, unknown>;
61
- const rPr = rObj["a:rPr"] as Record<string, unknown> | undefined;
62
- const text = extractInnerText(rObj["a:t"]);
63
- if (!text) continue;
64
-
65
- const props = parseRunProps(rPr, inheritedProps);
66
- runs.push({ content: text, ...props });
67
- }
68
- }
69
-
70
- // a:t directly (e.g. inside a:fld)
71
- if (obj["a:t"] != null && obj["a:r"] == null) {
72
- const text = extractInnerText(obj["a:t"]);
73
- if (text) {
74
- runs.push({ content: text, ...inheritedProps });
75
- }
76
- }
77
-
78
- // Recurse into child elements (skip keys we already handled to avoid
79
- // double-counting text runs that were extracted from a:r above)
80
- for (const key of Object.keys(obj)) {
81
- if (key.startsWith("@_")) continue;
82
- if (key === "a:r" || key === "a:t") continue;
83
- const child = obj[key];
84
- if (child != null && typeof child === "object") {
85
- if (Array.isArray(child)) {
86
- for (const item of child) {
87
- collectTexts(item, runs, inheritedProps);
88
- }
89
- } else {
90
- collectTexts(child, runs, inheritedProps);
91
- }
92
- }
93
- }
94
- }
95
-
96
- function extractInnerText(val: unknown): string {
97
- if (val == null) return "";
98
- if (typeof val === "string") return val;
99
- if (typeof val === "number") return String(val);
100
- if (typeof val === "object" && val !== null) {
101
- const obj = val as Record<string, unknown>;
102
- // fast-xml-parser may wrap text in #text when attributes are present
103
- if (obj["#text"] != null) return String(obj["#text"]);
104
- }
105
- return String(val);
106
- }
107
-
108
- function parseRunProps(
109
- rPr: Record<string, unknown> | undefined,
110
- inherited?: {
111
- bold?: boolean;
112
- italic?: boolean;
113
- fontSize?: number;
114
- color?: string;
115
- },
116
- ): { bold?: boolean; italic?: boolean; fontSize?: number; color?: string } {
117
- const props: {
118
- bold?: boolean;
119
- italic?: boolean;
120
- fontSize?: number;
121
- color?: string;
122
- } = {
123
- ...inherited,
124
- };
125
- if (!rPr) return props;
126
-
127
- if (rPr["@_b"] === "1" || rPr["@_b"] === 1 || rPr["@_b"] === true) {
128
- props.bold = true;
129
- }
130
- if (rPr["@_i"] === "1" || rPr["@_i"] === 1 || rPr["@_i"] === true) {
131
- props.italic = true;
132
- }
133
- // Font size in hundredths of a point — convert to pt
134
- if (rPr["@_sz"] != null) {
135
- const sz = Number(rPr["@_sz"]);
136
- if (!isNaN(sz) && sz > 0) {
137
- props.fontSize = sz / 100;
138
- }
139
- }
140
- // Solid fill color
141
- const solidFill = rPr["a:solidFill"] as Record<string, unknown> | undefined;
142
- if (solidFill) {
143
- const srgbClr = solidFill["a:srgbClr"] as
144
- | Record<string, unknown>
145
- | undefined;
146
- if (srgbClr?.["@_val"]) {
147
- props.color = `#${srgbClr["@_val"]}`;
148
- }
149
- }
150
- return props;
151
- }
152
-
153
- /** Extract all text runs from a slide XML object. */
154
- function extractSlideTexts(slideObj: Record<string, unknown>): ParsedTextRun[] {
155
- const runs: ParsedTextRun[] = [];
156
- collectTexts(slideObj, runs);
157
- return runs;
158
- }
159
-
160
- /** Parse relationship file to get rId -> target mappings. */
161
- function parseRels(
162
- relsXml: string,
163
- ): Map<string, { target: string; type: string }> {
164
- const parsed = parser.parse(relsXml);
165
- const map = new Map<string, { target: string; type: string }>();
166
- const rels = parsed?.Relationships?.Relationship;
167
- for (const rel of asArray(rels)) {
168
- const r = rel as Record<string, unknown>;
169
- if (r["@_Id"] && r["@_Target"]) {
170
- map.set(String(r["@_Id"]), {
171
- target: String(r["@_Target"]),
172
- type: String(r["@_Type"] ?? ""),
173
- });
174
- }
175
- }
176
- return map;
177
- }
178
-
179
- /** Determine the MIME type from a file extension. */
180
- function mimeFromExt(name: string): string {
181
- const ext = name.split(".").pop()?.toLowerCase() ?? "";
182
- const map: Record<string, string> = {
183
- png: "image/png",
184
- jpg: "image/jpeg",
185
- jpeg: "image/jpeg",
186
- gif: "image/gif",
187
- svg: "image/svg+xml",
188
- webp: "image/webp",
189
- bmp: "image/bmp",
190
- tiff: "image/tiff",
191
- tif: "image/tiff",
192
- emf: "image/emf",
193
- wmf: "image/wmf",
194
- };
195
- return map[ext] ?? "application/octet-stream";
196
- }
197
-
198
- /** Guess a layout hint from the content. */
199
- function guessLayoutHint(texts: ParsedTextRun[], hasImages: boolean): string {
200
- if (hasImages) return "image";
201
-
202
- // Title slide: typically 1-3 short text runs, largest font
203
- const maxFontSize = Math.max(...texts.map((t) => t.fontSize ?? 0), 0);
204
- const totalLength = texts.reduce((sum, t) => sum + t.content.length, 0);
205
-
206
- if (texts.length <= 3 && totalLength < 200 && maxFontSize >= 28) {
207
- return "title";
208
- }
209
- if (texts.length <= 2 && totalLength < 100) {
210
- return "section";
211
- }
212
- return "content";
213
- }
214
-
215
- export async function parsePptx(
216
- fileBuffer: Buffer,
217
- ): Promise<ParsedPresentation> {
218
- const zip = await JSZip.loadAsync(fileBuffer);
219
-
220
- // --- Slide ordering from presentation.xml ---
221
- const presentationXml = await zip
222
- .file("ppt/presentation.xml")
223
- ?.async("string");
224
- if (!presentationXml) {
225
- throw new Error("Invalid PPTX: missing ppt/presentation.xml");
226
- }
227
- const presentationObj = parser.parse(presentationXml);
228
- const sldIdList =
229
- presentationObj?.["p:presentation"]?.["p:sldIdLst"]?.["p:sldId"];
230
- const slideRIds = asArray(sldIdList).map((s) =>
231
- String((s as Record<string, unknown>)["@_r:id"] ?? ""),
232
- );
233
-
234
- // Resolve rIds to slide file paths via presentation.xml.rels
235
- const presRelsXml = await zip
236
- .file("ppt/_rels/presentation.xml.rels")
237
- ?.async("string");
238
- const presRels = presRelsXml
239
- ? parseRels(presRelsXml)
240
- : new Map<string, { target: string; type: string }>();
241
-
242
- const slideFilenames: string[] = [];
243
- for (const rId of slideRIds) {
244
- const rel = presRels.get(rId);
245
- if (rel) {
246
- // target is relative to ppt/, e.g. "slides/slide1.xml"
247
- const fullPath = rel.target.startsWith("/")
248
- ? rel.target.slice(1)
249
- : `ppt/${rel.target}`;
250
- slideFilenames.push(fullPath);
251
- }
252
- }
253
-
254
- // Fallback: if rels didn't resolve, discover slide files directly
255
- if (slideFilenames.length === 0) {
256
- const slideFiles = Object.keys(zip.files)
257
- .filter((f) => /^ppt\/slides\/slide\d+\.xml$/.test(f))
258
- .sort((a, b) => {
259
- const na = parseInt(a.match(/slide(\d+)/)?.[1] ?? "0", 10);
260
- const nb = parseInt(b.match(/slide(\d+)/)?.[1] ?? "0", 10);
261
- return na - nb;
262
- });
263
- slideFilenames.push(...slideFiles);
264
- }
265
-
266
- // --- Theme extraction ---
267
- let theme: { colors: string[]; fonts: string[] } | undefined;
268
- const themeXml = await zip.file("ppt/theme/theme1.xml")?.async("string");
269
- if (themeXml) {
270
- const themeObj = parser.parse(themeXml);
271
- const colors: string[] = [];
272
- const fonts: string[] = [];
273
-
274
- // Extract theme colors from a:clrScheme
275
- const clrScheme =
276
- themeObj?.["a:theme"]?.["a:themeElements"]?.["a:clrScheme"];
277
- if (clrScheme && typeof clrScheme === "object") {
278
- for (const key of Object.keys(clrScheme)) {
279
- if (key.startsWith("@_")) continue;
280
- const colorEl = (clrScheme as Record<string, unknown>)[key] as
281
- | Record<string, unknown>
282
- | undefined;
283
- if (!colorEl) continue;
284
- const srgb = colorEl["a:srgbClr"] as
285
- | Record<string, unknown>
286
- | undefined;
287
- const sysClr = colorEl["a:sysClr"] as
288
- | Record<string, unknown>
289
- | undefined;
290
- if (srgb?.["@_val"]) {
291
- colors.push(`#${srgb["@_val"]}`);
292
- } else if (sysClr?.["@_lastClr"]) {
293
- colors.push(`#${sysClr["@_lastClr"]}`);
294
- }
295
- }
296
- }
297
-
298
- // Extract fonts
299
- const fontScheme =
300
- themeObj?.["a:theme"]?.["a:themeElements"]?.["a:fontScheme"];
301
- if (fontScheme) {
302
- const majorFont = (fontScheme as Record<string, unknown>)[
303
- "a:majorFont"
304
- ] as Record<string, unknown> | undefined;
305
- const minorFont = (fontScheme as Record<string, unknown>)[
306
- "a:minorFont"
307
- ] as Record<string, unknown> | undefined;
308
- const latin1 = majorFont?.["a:latin"] as
309
- | Record<string, unknown>
310
- | undefined;
311
- const latin2 = minorFont?.["a:latin"] as
312
- | Record<string, unknown>
313
- | undefined;
314
- if (latin1?.["@_typeface"]) fonts.push(String(latin1["@_typeface"]));
315
- if (latin2?.["@_typeface"]) fonts.push(String(latin2["@_typeface"]));
316
- }
317
-
318
- if (colors.length > 0 || fonts.length > 0) {
319
- theme = { colors, fonts };
320
- }
321
- }
322
-
323
- // --- Parse each slide ---
324
- const parsedSlides: ParsedSlide[] = [];
325
-
326
- for (const slidePath of slideFilenames) {
327
- const slideXml = await zip.file(slidePath)?.async("string");
328
- if (!slideXml) continue;
329
-
330
- let slideObj: Record<string, unknown>;
331
- try {
332
- slideObj = parser.parse(slideXml);
333
- } catch {
334
- // Skip slides with malformed XML rather than crashing the whole import
335
- continue;
336
- }
337
- const texts = extractSlideTexts(slideObj);
338
-
339
- // Extract images via slide rels
340
- const images: ParsedImage[] = [];
341
- const slideBasename = slidePath.split("/").pop() ?? "";
342
- const relsPath = slidePath.replace(
343
- /slides\/(slide\d+\.xml)/,
344
- "slides/_rels/$1.rels",
345
- );
346
- const slideRelsXml = await zip.file(relsPath)?.async("string");
347
- if (slideRelsXml) {
348
- const slideRels = parseRels(slideRelsXml);
349
- for (const [, rel] of slideRels) {
350
- if (
351
- rel.type.includes("/image") ||
352
- /\.(png|jpe?g|gif|svg|webp|bmp|tiff?|emf|wmf)$/i.test(rel.target)
353
- ) {
354
- // Resolve relative target to full zip path
355
- const imgPath = rel.target.startsWith("/")
356
- ? rel.target.slice(1)
357
- : rel.target.startsWith("../")
358
- ? `ppt/${rel.target.replace(/^\.\.\//, "")}`
359
- : `ppt/slides/${rel.target}`;
360
-
361
- const imgFile = zip.file(imgPath);
362
- if (imgFile) {
363
- const imgData = await imgFile.async("nodebuffer");
364
- const imgName = imgPath.split("/").pop() ?? "image";
365
- images.push({
366
- data: imgData,
367
- mimeType: mimeFromExt(imgName),
368
- name: imgName,
369
- });
370
- }
371
- }
372
- }
373
- }
374
-
375
- // Extract speaker notes
376
- let notes: string | undefined;
377
- const slideNum = slideBasename.match(/slide(\d+)/)?.[1];
378
- if (slideNum) {
379
- const notesPath = `ppt/notesSlides/notesSlide${slideNum}.xml`;
380
- const notesXml = await zip.file(notesPath)?.async("string");
381
- if (notesXml) {
382
- const notesObj = parser.parse(notesXml);
383
- const noteRuns: ParsedTextRun[] = [];
384
- collectTexts(notesObj, noteRuns);
385
- const noteText = noteRuns
386
- .map((r) => r.content)
387
- .join(" ")
388
- .trim();
389
- // Filter out placeholder patterns like slide number references
390
- if (noteText && noteText.length > 1) {
391
- notes = noteText;
392
- }
393
- }
394
- }
395
-
396
- const layoutHint = guessLayoutHint(texts, images.length > 0);
397
-
398
- parsedSlides.push({
399
- texts,
400
- images,
401
- notes,
402
- layoutHint,
403
- });
404
- }
405
-
406
- // Derive title from the first slide's largest text
407
- let title = "Imported Presentation";
408
- if (parsedSlides.length > 0 && parsedSlides[0].texts.length > 0) {
409
- // Pick the text run with the largest font, or the first one
410
- const firstSlideTexts = parsedSlides[0].texts;
411
- const sorted = [...firstSlideTexts].sort(
412
- (a, b) => (b.fontSize ?? 0) - (a.fontSize ?? 0),
413
- );
414
- const candidate = sorted[0]?.content?.trim();
415
- if (candidate && candidate.length > 0 && candidate.length < 200) {
416
- title = candidate;
417
- }
418
- }
419
-
420
- return { title, slides: parsedSlides, theme };
421
- }
1
+ export {
2
+ parsePptxPresentation as parsePptx,
3
+ type ParsedPptxImage as ParsedImage,
4
+ type ParsedPptxPresentation as ParsedPresentation,
5
+ type ParsedPptxSlide as ParsedSlide,
6
+ type ParsedPptxTextRun as ParsedTextRun,
7
+ } from "@agent-native/core/ingestion";
@@ -0,0 +1,166 @@
1
+ import { registerOnboardingStep } from "@agent-native/core/onboarding";
2
+ import {
3
+ getRequestOrgId,
4
+ getRequestUserEmail,
5
+ } from "@agent-native/core/server/request-context";
6
+ import {
7
+ setupCreativeContext,
8
+ type CreativeContextProjectionAdapters,
9
+ } from "@agent-native/creative-context/server";
10
+ import { listContextSources } from "@agent-native/creative-context/store";
11
+ import { desc, eq } from "drizzle-orm";
12
+ import { nanoid } from "nanoid";
13
+
14
+ import { getDb, schema } from "../db/index.js";
15
+
16
+ type ProjectedLayoutTemplate = {
17
+ id: string;
18
+ type: "layout-template";
19
+ name: string;
20
+ sourceType: "brand-import";
21
+ htmlSnapshot: string | null;
22
+ creativeContext: {
23
+ suggestionId: string;
24
+ itemId: string;
25
+ itemVersionId: string;
26
+ projectionItemId: string;
27
+ };
28
+ };
29
+
30
+ function parseAssets(value: string | null): unknown[] {
31
+ if (!value) return [];
32
+ try {
33
+ const parsed = JSON.parse(value);
34
+ return Array.isArray(parsed) ? parsed : [];
35
+ } catch {
36
+ return [];
37
+ }
38
+ }
39
+
40
+ function isProjectedLayout(value: unknown): value is ProjectedLayoutTemplate {
41
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
42
+ const candidate = value as Partial<ProjectedLayoutTemplate>;
43
+ return (
44
+ candidate.type === "layout-template" &&
45
+ candidate.sourceType === "brand-import" &&
46
+ typeof candidate.creativeContext?.projectionItemId === "string"
47
+ );
48
+ }
49
+
50
+ async function ownedDesignSystems() {
51
+ const ownerEmail = getRequestUserEmail();
52
+ if (!ownerEmail) throw new Error("no authenticated user");
53
+ return getDb()
54
+ .select()
55
+ .from(schema.designSystems)
56
+ .where(eq(schema.designSystems.ownerEmail, ownerEmail))
57
+ .orderBy(
58
+ desc(schema.designSystems.isDefault),
59
+ desc(schema.designSystems.updatedAt),
60
+ );
61
+ }
62
+
63
+ async function ensureLayoutTarget() {
64
+ const existing = await ownedDesignSystems();
65
+ if (existing[0]) return existing[0];
66
+ const ownerEmail = getRequestUserEmail();
67
+ if (!ownerEmail) throw new Error("no authenticated user");
68
+ const now = new Date().toISOString();
69
+ const row = {
70
+ id: nanoid(),
71
+ title: "Creative context layouts",
72
+ description: "Approved reusable layouts promoted from Creative Context.",
73
+ data: "{}",
74
+ assets: "[]",
75
+ customInstructions:
76
+ "Prefer approved Creative Context layout templates unchanged before adapting or generating a new layout.",
77
+ isDefault: true,
78
+ ownerEmail,
79
+ orgId: getRequestOrgId(),
80
+ createdAt: now,
81
+ updatedAt: now,
82
+ };
83
+ await getDb().insert(schema.designSystems).values(row);
84
+ return row;
85
+ }
86
+
87
+ const projections: CreativeContextProjectionAdapters = {
88
+ layoutTemplate: {
89
+ promote: async (input) => {
90
+ const designSystem = await ensureLayoutTarget();
91
+ const assets = parseAssets(designSystem.assets).filter(
92
+ (asset) =>
93
+ !isProjectedLayout(asset) ||
94
+ asset.creativeContext.projectionItemId !== input.projectionItemId,
95
+ );
96
+ const projection: ProjectedLayoutTemplate = {
97
+ id: `creative-context-layout:${input.projectionItemId}`,
98
+ type: "layout-template",
99
+ name: `Approved layout ${assets.filter(isProjectedLayout).length + 1}`,
100
+ sourceType: "brand-import",
101
+ htmlSnapshot: input.htmlSnapshot,
102
+ creativeContext: {
103
+ suggestionId: input.suggestionId,
104
+ itemId: input.itemId,
105
+ itemVersionId: input.itemVersionId,
106
+ projectionItemId: input.projectionItemId,
107
+ },
108
+ };
109
+ await getDb()
110
+ .update(schema.designSystems)
111
+ .set({
112
+ assets: JSON.stringify([...assets, projection]),
113
+ updatedAt: new Date().toISOString(),
114
+ })
115
+ .where(eq(schema.designSystems.id, designSystem.id));
116
+ },
117
+ demote: async ({ projectionItemId }) => {
118
+ if (!projectionItemId) return;
119
+ const designSystems = await ownedDesignSystems();
120
+ for (const designSystem of designSystems) {
121
+ const assets = parseAssets(designSystem.assets);
122
+ const filtered = assets.filter(
123
+ (asset) =>
124
+ !isProjectedLayout(asset) ||
125
+ asset.creativeContext.projectionItemId !== projectionItemId,
126
+ );
127
+ if (filtered.length === assets.length) continue;
128
+ await getDb()
129
+ .update(schema.designSystems)
130
+ .set({
131
+ assets: JSON.stringify(filtered),
132
+ updatedAt: new Date().toISOString(),
133
+ })
134
+ .where(eq(schema.designSystems.id, designSystem.id));
135
+ }
136
+ },
137
+ },
138
+ };
139
+
140
+ registerOnboardingStep({
141
+ id: "creative-context-library",
142
+ order: 18,
143
+ required: false,
144
+ title: "Connect your creative library",
145
+ description:
146
+ "Connect prior work and reference sources so agents can reuse approved creative context.",
147
+ methods: [
148
+ {
149
+ id: "library",
150
+ kind: "link",
151
+ primary: true,
152
+ label: "Open Library",
153
+ payload: { url: "/agent#library", external: false },
154
+ },
155
+ ],
156
+ isComplete: async () => {
157
+ try {
158
+ const result = await listContextSources({ limit: 1 });
159
+ return result.sources.length > 0;
160
+ } catch {
161
+ return false;
162
+ }
163
+ },
164
+ });
165
+
166
+ export default setupCreativeContext({ appId: "slides", projections });
@@ -1,5 +1,5 @@
1
1
  export declare const LLM_MISSING_CREDENTIALS_ERROR_CODE = "missing_credentials";
2
- export declare const LLM_MISSING_CREDENTIALS_MESSAGE = "No LLM provider is connected. Open this app's Agent settings > LLM, then connect Builder.io or add a provider key.";
2
+ export declare const LLM_MISSING_CREDENTIALS_MESSAGE = "No LLM provider is connected. Open this app's Agent workspace > LLM, then connect Builder.io or add a provider key.";
3
3
  export declare function isLlmCredentialError(error: unknown, errorCode?: string | null): boolean;
4
4
  export declare function formatLlmCredentialErrorMessage(options?: {
5
5
  agentName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"credential-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/credential-errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kCAAkC,wBAAwB,CAAC;AAExE,eAAO,MAAM,+BAA+B,uHAC0E,CAAC;AAevH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAiBT;AAED,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAMT;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,MAAM,GAAG,IAAI,CAIf"}
1
+ {"version":3,"file":"credential-errors.d.ts","sourceRoot":"","sources":["../../../src/agent/engine/credential-errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kCAAkC,wBAAwB,CAAC;AAExE,eAAO,MAAM,+BAA+B,wHAC2E,CAAC;AAexH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAiBT;AAED,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAMT;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,MAAM,GAAG,IAAI,CAIf"}
@@ -1,6 +1,6 @@
1
1
  import { PROVIDER_ENV_VARS } from "./provider-env-vars.js";
2
2
  export const LLM_MISSING_CREDENTIALS_ERROR_CODE = "missing_credentials";
3
- export const LLM_MISSING_CREDENTIALS_MESSAGE = "No LLM provider is connected. Open this app's Agent settings > LLM, then connect Builder.io or add a provider key.";
3
+ export const LLM_MISSING_CREDENTIALS_MESSAGE = "No LLM provider is connected. Open this app's Agent workspace > LLM, then connect Builder.io or add a provider key.";
4
4
  const LLM_CREDENTIAL_KEYS = new Set([
5
5
  ...PROVIDER_ENV_VARS,
6
6
  "BUILDER_PRIVATE_KEY",
@@ -30,7 +30,7 @@ export function isLlmCredentialError(error, errorCode) {
30
30
  export function formatLlmCredentialErrorMessage(options) {
31
31
  const agentName = options?.agentName?.trim();
32
32
  if (agentName) {
33
- return `The ${agentName} agent could not finish this request because that app needs an LLM connection. Open ${agentName}'s Agent settings > LLM, then connect Builder.io or add a provider key.`;
33
+ return `The ${agentName} agent could not finish this request because that app needs an LLM connection. Open ${agentName}'s Agent workspace > LLM, then connect Builder.io or add a provider key.`;
34
34
  }
35
35
  return LLM_MISSING_CREDENTIALS_MESSAGE;
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"credential-errors.js","sourceRoot":"","sources":["../../../src/agent/engine/credential-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,CAAC,MAAM,kCAAkC,GAAG,qBAAqB,CAAC;AAExE,MAAM,CAAC,MAAM,+BAA+B,GAC1C,oHAAoH,CAAC;AAEvH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,GAAG,iBAAiB;IACpB,qBAAqB;IACrB,oBAAoB;CACrB,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG;IAClC,kGAAkG;IAClG,kGAAkG;IAClG,8FAA8F;IAC9F,8FAA8F;CAC/F,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,SAAyB;IAEzB,MAAM,IAAI,GACR,SAAS;QACT,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,WAAW,IAAI,KAAK;YACzD,CAAC,CAAC,MAAM,CAAE,KAAiC,CAAC,SAAS,IAAI,EAAE,CAAC;YAC5D,CAAC,CAAC,EAAE,CAAC,CAAC;IACV,IAAI,IAAI,KAAK,kCAAkC;QAAE,OAAO,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,0BAA0B,GAAG,CAAC,GAAG,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACvE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CACtB,CAAC;IACF,IAAI,0BAA0B;QAAE,OAAO,IAAI,CAAC;IAE5C,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,OAE/C;IACC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,OAAO,SAAS,uFAAuF,SAAS,yEAAyE,CAAC;IACnM,CAAC;IACD,OAAO,+BAA+B,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAc,EACd,OAAgC;IAEhC,OAAO,oBAAoB,CAAC,KAAK,CAAC;QAChC,CAAC,CAAC,+BAA+B,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAE,KAA+B,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC","sourcesContent":["import { PROVIDER_ENV_VARS } from \"./provider-env-vars.js\";\n\nexport const LLM_MISSING_CREDENTIALS_ERROR_CODE = \"missing_credentials\";\n\nexport const LLM_MISSING_CREDENTIALS_MESSAGE =\n \"No LLM provider is connected. Open this app's Agent settings > LLM, then connect Builder.io or add a provider key.\";\n\nconst LLM_CREDENTIAL_KEYS = new Set([\n ...PROVIDER_ENV_VARS,\n \"BUILDER_PRIVATE_KEY\",\n \"BUILDER_PUBLIC_KEY\",\n]);\n\nconst MISSING_CREDENTIAL_PATTERNS = [\n /\\b(?:llm|model provider|ai engine)\\b.*\\b(?:missing|not set|not configured|required|connected)\\b/i,\n /\\b(?:missing|not set|not configured|required|connected)\\b.*\\b(?:llm|model provider|ai engine)\\b/i,\n /\\b(?:llm|model provider|ai engine)\\b.*\\b(?:api\\s*key|credential|credentials|provider key)\\b/i,\n /\\b(?:api\\s*key|credential|credentials|provider key)\\b.*\\b(?:llm|model provider|ai engine)\\b/i,\n];\n\nexport function isLlmCredentialError(\n error: unknown,\n errorCode?: string | null,\n): boolean {\n const code =\n errorCode ??\n (typeof error === \"object\" && error && \"errorCode\" in error\n ? String((error as { errorCode?: unknown }).errorCode ?? \"\")\n : \"\");\n if (code === LLM_MISSING_CREDENTIALS_ERROR_CODE) return true;\n\n const message = getErrorMessage(error);\n if (!message) return false;\n\n const mentionsKnownLlmCredential = [...LLM_CREDENTIAL_KEYS].some((key) =>\n message.includes(key),\n );\n if (mentionsKnownLlmCredential) return true;\n\n return MISSING_CREDENTIAL_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport function formatLlmCredentialErrorMessage(options?: {\n agentName?: string;\n}): string {\n const agentName = options?.agentName?.trim();\n if (agentName) {\n return `The ${agentName} agent could not finish this request because that app needs an LLM connection. Open ${agentName}'s Agent settings > LLM, then connect Builder.io or add a provider key.`;\n }\n return LLM_MISSING_CREDENTIALS_MESSAGE;\n}\n\nexport function userFacingLlmCredentialError(\n error: unknown,\n options?: { agentName?: string },\n): string | null {\n return isLlmCredentialError(error)\n ? formatLlmCredentialErrorMessage(options)\n : null;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (typeof error === \"string\") return error;\n if (error instanceof Error) return error.message;\n if (typeof error === \"object\" && error && \"message\" in error) {\n return String((error as { message?: unknown }).message ?? \"\");\n }\n return \"\";\n}\n"]}
1
+ {"version":3,"file":"credential-errors.js","sourceRoot":"","sources":["../../../src/agent/engine/credential-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,MAAM,CAAC,MAAM,kCAAkC,GAAG,qBAAqB,CAAC;AAExE,MAAM,CAAC,MAAM,+BAA+B,GAC1C,qHAAqH,CAAC;AAExH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,GAAG,iBAAiB;IACpB,qBAAqB;IACrB,oBAAoB;CACrB,CAAC,CAAC;AAEH,MAAM,2BAA2B,GAAG;IAClC,kGAAkG;IAClG,kGAAkG;IAClG,8FAA8F;IAC9F,8FAA8F;CAC/F,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,SAAyB;IAEzB,MAAM,IAAI,GACR,SAAS;QACT,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,WAAW,IAAI,KAAK;YACzD,CAAC,CAAC,MAAM,CAAE,KAAiC,CAAC,SAAS,IAAI,EAAE,CAAC;YAC5D,CAAC,CAAC,EAAE,CAAC,CAAC;IACV,IAAI,IAAI,KAAK,kCAAkC;QAAE,OAAO,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,0BAA0B,GAAG,CAAC,GAAG,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CACvE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CACtB,CAAC;IACF,IAAI,0BAA0B;QAAE,OAAO,IAAI,CAAC;IAE5C,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,OAE/C;IACC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,OAAO,SAAS,uFAAuF,SAAS,0EAA0E,CAAC;IACpM,CAAC;IACD,OAAO,+BAA+B,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAc,EACd,OAAgC;IAEhC,OAAO,oBAAoB,CAAC,KAAK,CAAC;QAChC,CAAC,CAAC,+BAA+B,CAAC,OAAO,CAAC;QAC1C,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAE,KAA+B,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC","sourcesContent":["import { PROVIDER_ENV_VARS } from \"./provider-env-vars.js\";\n\nexport const LLM_MISSING_CREDENTIALS_ERROR_CODE = \"missing_credentials\";\n\nexport const LLM_MISSING_CREDENTIALS_MESSAGE =\n \"No LLM provider is connected. Open this app's Agent workspace > LLM, then connect Builder.io or add a provider key.\";\n\nconst LLM_CREDENTIAL_KEYS = new Set([\n ...PROVIDER_ENV_VARS,\n \"BUILDER_PRIVATE_KEY\",\n \"BUILDER_PUBLIC_KEY\",\n]);\n\nconst MISSING_CREDENTIAL_PATTERNS = [\n /\\b(?:llm|model provider|ai engine)\\b.*\\b(?:missing|not set|not configured|required|connected)\\b/i,\n /\\b(?:missing|not set|not configured|required|connected)\\b.*\\b(?:llm|model provider|ai engine)\\b/i,\n /\\b(?:llm|model provider|ai engine)\\b.*\\b(?:api\\s*key|credential|credentials|provider key)\\b/i,\n /\\b(?:api\\s*key|credential|credentials|provider key)\\b.*\\b(?:llm|model provider|ai engine)\\b/i,\n];\n\nexport function isLlmCredentialError(\n error: unknown,\n errorCode?: string | null,\n): boolean {\n const code =\n errorCode ??\n (typeof error === \"object\" && error && \"errorCode\" in error\n ? String((error as { errorCode?: unknown }).errorCode ?? \"\")\n : \"\");\n if (code === LLM_MISSING_CREDENTIALS_ERROR_CODE) return true;\n\n const message = getErrorMessage(error);\n if (!message) return false;\n\n const mentionsKnownLlmCredential = [...LLM_CREDENTIAL_KEYS].some((key) =>\n message.includes(key),\n );\n if (mentionsKnownLlmCredential) return true;\n\n return MISSING_CREDENTIAL_PATTERNS.some((pattern) => pattern.test(message));\n}\n\nexport function formatLlmCredentialErrorMessage(options?: {\n agentName?: string;\n}): string {\n const agentName = options?.agentName?.trim();\n if (agentName) {\n return `The ${agentName} agent could not finish this request because that app needs an LLM connection. Open ${agentName}'s Agent workspace > LLM, then connect Builder.io or add a provider key.`;\n }\n return LLM_MISSING_CREDENTIALS_MESSAGE;\n}\n\nexport function userFacingLlmCredentialError(\n error: unknown,\n options?: { agentName?: string },\n): string | null {\n return isLlmCredentialError(error)\n ? formatLlmCredentialErrorMessage(options)\n : null;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (typeof error === \"string\") return error;\n if (error instanceof Error) return error.message;\n if (typeof error === \"object\" && error && \"message\" in error) {\n return String((error as { message?: unknown }).message ?? \"\");\n }\n return \"\";\n}\n"]}