@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
@@ -197,7 +197,7 @@ export const FIRST_PARTY_DASHBOARD_FILTERS: FirstPartyDashboardFilter[] = [
197
197
  id: "emailFilter",
198
198
  type: "select",
199
199
  label: "Email filter",
200
- default: "all",
200
+ default: "exclude_builder",
201
201
  options: [
202
202
  { value: "all", label: "All users" },
203
203
  { value: "exclude_builder", label: "Exclude @builder.io" },
@@ -223,6 +223,8 @@ const RETENTION_OVER_TIME_SQL = `WITH base AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_S
223
223
  const ONE_DAY_RETENTION_BY_TEMPLATE_SQL = `WITH base AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_SQL} AS user_key, ${TEMPLATE_EXPR} AS template, ${EVENT_DATE_SQL} AS event_date, user_id FROM analytics_events WHERE ${SIGNED_IN_ACTIVITY_FILTER} AND ${DASHBOARD_EMAIL_FILTER} AND ${KNOWN_PRODUCT_ACTIVITY_TEMPLATE_FILTER}), ranked_first_seen AS (SELECT user_key, template, event_date AS cohort_date, ROW_NUMBER() OVER (PARTITION BY user_key ORDER BY event_date, template) AS rn FROM base), first_seen AS (SELECT user_key, template, cohort_date FROM ranked_first_seen WHERE rn = 1), cohorts AS (SELECT user_key, template, cohort_date FROM first_seen WHERE cohort_date <= ${daysAgoSql(7)} AND ${dashboardTimeRangeFilter("cohort_date")}), cohort_sizes AS (SELECT template, COUNT(DISTINCT user_key) AS users FROM cohorts GROUP BY template), retained AS (SELECT c.template, COUNT(DISTINCT c.user_key) AS retained FROM cohorts c JOIN base b ON b.user_key = c.user_key AND b.event_date > c.cohort_date AND b.event_date <= to_char(c.cohort_date::date + INTERVAL '7 days', 'YYYY-MM-DD') GROUP BY c.template) SELECT cs.template, COALESCE(r.retained, 0) AS retained_users, cs.users AS cohort_users, COALESCE(r.retained::float / NULLIF(cs.users, 0), 0) AS rate FROM cohort_sizes cs LEFT JOIN retained r ON r.template = cs.template WHERE cs.users >= ${PER_TEMPLATE_RETENTION_MIN_COHORT_SIZE} ORDER BY rate DESC, cs.users DESC, cs.template`;
224
224
  const SEVEN_DAY_RETENTION_BY_TEMPLATE_SQL = `WITH base AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_SQL} AS user_key, ${TEMPLATE_EXPR} AS template, ${EVENT_DATE_SQL} AS event_date, user_id FROM analytics_events WHERE ${SIGNED_IN_ACTIVITY_FILTER} AND ${DASHBOARD_EMAIL_FILTER} AND ${KNOWN_PRODUCT_ACTIVITY_TEMPLATE_FILTER}), ranked_first_seen AS (SELECT user_key, template, event_date AS cohort_date, ROW_NUMBER() OVER (PARTITION BY user_key ORDER BY event_date, template) AS rn FROM base), first_seen AS (SELECT user_key, template, cohort_date FROM ranked_first_seen WHERE rn = 1), cohorts AS (SELECT user_key, template, cohort_date FROM first_seen WHERE cohort_date <= ${daysAgoSql(14)} AND ${dashboardTimeRangeFilter("cohort_date")}), cohort_sizes AS (SELECT template, COUNT(DISTINCT user_key) AS users FROM cohorts GROUP BY template), retained AS (SELECT c.template, COUNT(DISTINCT c.user_key) AS retained FROM cohorts c JOIN base b ON b.user_key = c.user_key AND b.event_date >= to_char(c.cohort_date::date + INTERVAL '7 days', 'YYYY-MM-DD') AND b.event_date <= to_char(c.cohort_date::date + INTERVAL '14 days', 'YYYY-MM-DD') GROUP BY c.template) SELECT cs.template, COALESCE(r.retained, 0) AS retained_users, cs.users AS cohort_users, COALESCE(r.retained::float / NULLIF(cs.users, 0), 0) AS rate FROM cohort_sizes cs LEFT JOIN retained r ON r.template = cs.template WHERE cs.users >= ${PER_TEMPLATE_RETENTION_MIN_COHORT_SIZE} ORDER BY rate DESC, cs.users DESC, cs.template`;
225
225
  const SIGNUPS_BY_TEMPLATE_SQL = `SELECT ${TEMPLATE_EXPR} AS template, COUNT(*) AS count FROM analytics_events WHERE event_name = 'signup' AND ${DASHBOARD_TIME_RANGE_FILTER} AND ${DASHBOARD_EMAIL_FILTER} GROUP BY ${TEMPLATE_EXPR} ORDER BY count DESC`;
226
+ const RECURRING_USERS_BY_TEMPLATE_SQL = `WITH all_users AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_SQL} AS user_key, ${EVENT_DATE_SQL}, user_id, ${TEMPLATE_EXPR} AS template FROM analytics_events WHERE ${SIGNED_IN_PRODUCT_ACTIVITY_FILTER} AND ${DASHBOARD_EMAIL_FILTER}), first_seen AS (SELECT user_key, MIN(event_date) AS first_date FROM all_users GROUP BY user_key) SELECT a.event_date AS date, a.template AS template, COUNT(DISTINCT a.user_key) AS users FROM all_users a JOIN first_seen f ON f.user_key = a.user_key WHERE a.event_date <> f.first_date AND a.template <> 'unknown' AND ${dashboardTimeRangeFilter("a.event_date")} GROUP BY 1, 2 ORDER BY date, template`;
227
+ const RECURRING_USERS_BY_TEMPLATE_WEEKLY_SQL = `WITH all_users AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_SQL} AS user_key, ${EVENT_DATE_SQL}, user_id, ${TEMPLATE_EXPR} AS template FROM analytics_events WHERE ${SIGNED_IN_PRODUCT_ACTIVITY_FILTER} AND ${DASHBOARD_EMAIL_FILTER}), first_seen AS (SELECT user_key, MIN(event_date) AS first_date FROM all_users GROUP BY user_key) SELECT to_char(date_trunc('week', a.event_date::date), 'YYYY-MM-DD') AS date, a.template AS template, COUNT(DISTINCT a.user_key) AS users FROM all_users a JOIN first_seen f ON f.user_key = a.user_key WHERE a.event_date <> f.first_date AND a.template <> 'unknown' AND ${dashboardTimeRangeFilter("a.event_date")} GROUP BY 1, 2 ORDER BY date, template`;
226
228
  const DAU_BY_TEMPLATE_SQL = `SELECT ${EVENT_DATE_SQL} AS date, ${TEMPLATE_EXPR} AS template, COUNT(DISTINCT ${SIGNED_IN_ACTIVITY_KEY_SQL}) AS visitors FROM analytics_events WHERE ${SIGNED_IN_ACTIVITY_FILTER} AND ${DASHBOARD_TIME_RANGE_FILTER} AND ${DASHBOARD_EMAIL_FILTER} AND ${KNOWN_PRODUCT_ACTIVITY_TEMPLATE_FILTER} GROUP BY ${EVENT_DATE_SQL}, ${TEMPLATE_EXPR} ORDER BY date, template`;
227
229
  const WAU_BY_TEMPLATE_SQL = `WITH base AS (SELECT ${SIGNED_IN_ACTIVITY_KEY_SQL} AS visitor_key, ${TEMPLATE_EXPR} AS template, ${EVENT_DATE_SQL} AS event_date, user_id FROM analytics_events WHERE ${SIGNED_IN_ACTIVITY_FILTER} AND ${DASHBOARD_EMAIL_FILTER} AND ${KNOWN_PRODUCT_ACTIVITY_TEMPLATE_FILTER} AND ${DASHBOARD_WAU_BASE_RANGE_FILTER}), days AS (SELECT DISTINCT event_date AS date FROM base WHERE ${DASHBOARD_EVENT_DATE_RANGE_FILTER}) SELECT d.date, b.template, COUNT(DISTINCT b.visitor_key) AS visitors FROM days d JOIN base b ON b.event_date >= to_char(d.date::date - INTERVAL '6 days', 'YYYY-MM-DD') AND b.event_date <= d.date GROUP BY d.date, b.template ORDER BY d.date, b.template`;
228
230
 
@@ -664,6 +666,50 @@ const ENTRIES: FirstPartyMetric[] = [
664
666
  "Signed-in browser identities with non-docs app session activity on at least two days in the selected time range.",
665
667
  },
666
668
  },
669
+ {
670
+ key: "recurring-users-by-template",
671
+ title: "Recurring Signed-In Users by Template",
672
+ chartType: "area",
673
+ source: "first-party",
674
+ width: 2,
675
+ windowed: false,
676
+ buildSql: fixed(RECURRING_USERS_BY_TEMPLATE_SQL),
677
+ config: {
678
+ xKey: "date",
679
+ yKey: "users",
680
+ yFormatter: "number",
681
+ pivot: {
682
+ xKey: "date",
683
+ seriesKey: "template",
684
+ valueKey: "users",
685
+ },
686
+ stacked: true,
687
+ description:
688
+ "Daily signed-in visitors who are NOT on their all-time first active day (Recurring only), stacked by inferred template/app used that day. Docs traffic and unknown template are excluded.",
689
+ },
690
+ },
691
+ {
692
+ key: "recurring-users-by-template-bar",
693
+ title: "Recurring Signed-In Users by Template (Bar)",
694
+ chartType: "bar",
695
+ source: "first-party",
696
+ width: 1,
697
+ windowed: false,
698
+ buildSql: fixed(RECURRING_USERS_BY_TEMPLATE_WEEKLY_SQL),
699
+ config: {
700
+ xKey: "date",
701
+ yKey: "users",
702
+ yFormatter: "number",
703
+ pivot: {
704
+ xKey: "date",
705
+ seriesKey: "template",
706
+ valueKey: "users",
707
+ },
708
+ stacked: true,
709
+ description:
710
+ "Weekly distinct signed-in visitors who are NOT on their all-time first active day (Recurring only), stacked by inferred template/app used that week. Weeks start Monday; docs traffic and unknown template are excluded.",
711
+ },
712
+ },
667
713
  {
668
714
  key: "retention-over-time",
669
715
  title: "7d Rolling Signed-In Return Rate",
@@ -48,6 +48,12 @@ export interface ReplayScope {
48
48
  orgId: string | null;
49
49
  }
50
50
 
51
+ export interface SessionReplayLinkResolution {
52
+ recordingId: string;
53
+ offsetMs: number;
54
+ path: string;
55
+ }
56
+
51
57
  function rangeStartIso(range: ReplayRange): string | null {
52
58
  if (range === "all") return null;
53
59
  const hours =
@@ -1683,6 +1689,68 @@ export async function getSessionReplaySummary(
1683
1689
  return rowToSessionRecordingSummary(access.resource, access.role);
1684
1690
  }
1685
1691
 
1692
+ export async function resolveSessionReplayLink(
1693
+ input: {
1694
+ sessionId: string;
1695
+ clientRecordingId: string;
1696
+ at?: string | null;
1697
+ },
1698
+ scope: SessionReplayScope,
1699
+ ): Promise<SessionReplayLinkResolution | null> {
1700
+ const db = getDb() as any;
1701
+ const [row] = await db
1702
+ .select({
1703
+ id: schema.sessionRecordings.id,
1704
+ startedAt: schema.sessionRecordings.startedAt,
1705
+ endedAt: schema.sessionRecordings.endedAt,
1706
+ durationMs: schema.sessionRecordings.durationMs,
1707
+ ownerEmail: schema.sessionRecordings.ownerEmail,
1708
+ orgId: schema.sessionRecordings.orgId,
1709
+ visibility: schema.sessionRecordings.visibility,
1710
+ chunkCount: schema.sessionRecordings.chunkCount,
1711
+ eventCount: schema.sessionRecordings.eventCount,
1712
+ userId: schema.sessionRecordings.userId,
1713
+ userKey: schema.sessionRecordings.userKey,
1714
+ })
1715
+ .from(schema.sessionRecordings)
1716
+ .where(
1717
+ and(
1718
+ eq(schema.sessionRecordings.sessionId, input.sessionId),
1719
+ eq(schema.sessionRecordings.clientRecordingId, input.clientRecordingId),
1720
+ eq(schema.sessionRecordings.ownerEmail, scope.userEmail),
1721
+ scope.orgId
1722
+ ? eq(schema.sessionRecordings.orgId, scope.orgId)
1723
+ : isNull(schema.sessionRecordings.orgId),
1724
+ ),
1725
+ )
1726
+ .limit(1);
1727
+
1728
+ if (!row || !isVisibleSessionRecording(row)) return null;
1729
+
1730
+ const startedAtMs = Date.parse(row.startedAt);
1731
+ if (!Number.isFinite(startedAtMs)) return null;
1732
+ const requestedAtMs = input.at ? Date.parse(input.at) : Date.now();
1733
+ const safeRequestedAtMs = Number.isFinite(requestedAtMs)
1734
+ ? requestedAtMs
1735
+ : startedAtMs;
1736
+ const inferredDurationMs = row.endedAt
1737
+ ? Math.max(0, Date.parse(row.endedAt) - startedAtMs)
1738
+ : 0;
1739
+ const durationMs =
1740
+ typeof row.durationMs === "number" && Number.isFinite(row.durationMs)
1741
+ ? Math.max(0, row.durationMs)
1742
+ : inferredDurationMs;
1743
+ const offsetMs = Math.max(
1744
+ 0,
1745
+ Math.min(Math.max(0, safeRequestedAtMs - startedAtMs), durationMs),
1746
+ );
1747
+ return {
1748
+ recordingId: row.id,
1749
+ offsetMs,
1750
+ path: `/sessions/${encodeURIComponent(row.id)}?atMs=${Math.round(offsetMs)}`,
1751
+ };
1752
+ }
1753
+
1686
1754
  export async function getSessionReplayTokenizedSummary(
1687
1755
  recordingId: string,
1688
1756
  viewerEmail: string,
@@ -704,6 +704,7 @@ export default createAgentChatPlugin({
704
704
  analyticsSourceGuidanceOpening() +
705
705
  "DASHBOARD CREATION RULE — You may create dashboards, analyses, SQL panels, or other resources only when the user explicitly asks you to (e.g. 'build me a dashboard for...', 'create a new analysis', 'add a chart for...'). Never create any resource proactively during research, trend analysis, or answering questions. If you think a dashboard would be useful, suggest it and wait for explicit confirmation before creating anything. Never add new items to the sidebar or modify existing dashboards without an explicit user directive. " +
706
706
  "DASHBOARD MUTATION RULE — For dashboard edits, default to `mutate-dashboard` with the typed `dashboard.*` script API so the main payload is a string and avoids native-array serialization traps. It can move panels by id, edit titles/SQL/config, insert, duplicate, remove, and patch dashboard fields in one atomic save. The script API is constrained: no variables/imports/loops/functions, only JSON-compatible arguments on documented dashboard methods. Do not count shifting `/panels/<index>` positions for ordinary dashboard edits unless the user specifically asks for low-level JSON-pointer operations. " +
707
+ "EXTENSION DATA-REPAIR RULE — When fixing data in an existing extension-backed dashboard or migrated surface such as Risk Meeting, inspect the current dashboard and extension first, then use `update-extension` `patches`/`edits` that change only the data-loading seam. Preserve the existing layout, CSS, copy, and interactions; never reconstruct the full HTML body for a data-only fix. Full-body replacement is blocked unless `allowFullReplacement=true`, which is reserved for an explicit visual rewrite or a complete replacement body supplied by the user. If a focused edit fails, change the target instead of retrying identical arguments. " +
707
708
  'FIRST-PARTY DASHBOARD TIME RULE — AI-generated `source: "first-party"` panels are dashboard-time-bound by default: set `config.timeScope` to `dashboard` and include a matching dashboard time predicate. `{{timeRange}}` requires a matching `filters` entry with `id: "timeRange"` and `type: "select"`; `{{<id>Start}}`/`{{<id>End}}` require a matching `type: "date-range"` filter with that id. Allowed `timeScope` values are `dashboard`, `fixed-window`, `cohort-history`, and `all-time`; use `all-time` only when the user requests full available history and put all-time, lifetime, or historical in the title or description. Server validation rejects unbound first-party SQL. ' +
708
709
  "DASHBOARD READ RULE — `get-sql-dashboard` is compact by default: use its `panels` summaries plus `layout.panelOrder`, `layout.firstPanelIds`, and `layout.groups[].rows[].rowNumber/panelIds` for orientation and verification. Pass `includeConfig: true` only when you truly need full panel SQL/config. " +
709
710
  'DASHBOARD REORDER RULE — For simple chart/section moves, use `mutate-dashboard` code such as `dashboard.panels(["panel-a","panel-b"]).moveToTop();`. For visible placement requests like "second row" or "next to return rates", use row-aware placement such as `dashboard.insertPanel({...}).nextTo("retention-over-time")`, `.atRow(2)`, or `dashboard.panel("panel-a").moveNextTo("panel-b")`; these keep panels in the intended rendered row and expand/rebalance that row when needed. Never count shifting `/panels/<index>` positions for ordinary \'move this chart\' requests. Use `get-sql-dashboard.layout.groups[].rows` as proof of visible row placement, not only flat `panelOrder`. ' +
@@ -0,0 +1,47 @@
1
+ import {
2
+ defineEventHandler,
3
+ getQuery,
4
+ sendRedirect,
5
+ setResponseStatus,
6
+ } from "h3";
7
+
8
+ import { runApiHandlerWithContext } from "../../lib/credentials";
9
+ import { resolveSessionReplayLink } from "../../lib/session-replay.js";
10
+
11
+ function queryString(value: unknown): string | null {
12
+ if (typeof value === "string" && value.trim()) return value.trim();
13
+ if (Array.isArray(value) && typeof value[0] === "string" && value[0].trim()) {
14
+ return value[0].trim();
15
+ }
16
+ return null;
17
+ }
18
+
19
+ export default defineEventHandler(async (event) => {
20
+ return runApiHandlerWithContext(event, async (ctx) => {
21
+ const query = getQuery(event);
22
+ const sessionId = queryString(query.sessionId);
23
+ const clientRecordingId = queryString(
24
+ query.clientRecordingId ?? query.replayId,
25
+ );
26
+ if (!sessionId || !clientRecordingId) {
27
+ setResponseStatus(event, 400);
28
+ return {
29
+ error: "sessionId and replayId are required",
30
+ };
31
+ }
32
+
33
+ const resolution = await resolveSessionReplayLink(
34
+ {
35
+ sessionId,
36
+ clientRecordingId,
37
+ at: queryString(query.at),
38
+ },
39
+ { userEmail: ctx.userEmail, orgId: ctx.orgId ?? null },
40
+ );
41
+ if (!resolution) {
42
+ setResponseStatus(event, 404);
43
+ return { error: "Session recording not found" };
44
+ }
45
+ return sendRedirect(event, resolution.path, 302);
46
+ });
47
+ });
@@ -53,36 +53,43 @@ or generated image/video assets that another app can reference by ID and URL.
53
53
 
54
54
  ## Image Workflows
55
55
 
56
- 1. For human-in-the-loop generation, call `generate-asset` first and preserve
56
+ 1. Read the `creative-context` skill and retrieve visual references separately
57
+ from factual evidence. Respect `contextMode: "off"`, pinned packs, and the
58
+ exact reuse ladder before generation: approved native asset unchanged,
59
+ compose approved pieces, lightly adapt a real example, condition generation
60
+ on narrow references, then net-new only when the relevant corpus is empty.
61
+ 2. For human-in-the-loop generation, call `generate-asset` first and preserve
57
62
  the returned picker/candidate metadata. For unattended generation, pick or
58
63
  match the library with `list-libraries` or `match-library`.
59
64
  If the user wants a default look rather than a brand library, call
60
65
  `list-library-presets` and then `create-library-from-preset`; the resulting
61
66
  library is editable and reusable like any other library.
62
- 2. For one asset, call `generate-image`; for multiple independent slots, call
67
+ 3. For one asset, call `generate-image`; for multiple independent slots, call
63
68
  `generate-image-batch` with stable `slotId` values.
64
- 3. Image generation actions are synchronous. After `generate-image` or
69
+ 4. Image generation actions are synchronous. After `generate-image` or
65
70
  `generate-image-batch` returns, use its returned `images` / asset fields
66
71
  directly; do not call `get-generation-run`, `refresh-generation-run`, or
67
72
  regenerate just to verify image runs.
68
- 4. For preset-backed work, pass a mentioned or selected `presetId`; for handoff
73
+ 5. For preset-backed work, pass a mentioned or selected `presetId`; for handoff
69
74
  work, pass `sessionId`.
70
- 5. Let the server choose a small deterministic reference set unless the user
75
+ 6. Let the server choose a small deterministic reference set unless the user
71
76
  named exact assets. Canonical style anchors come from
72
77
  `assetLibraries.settings.canonicalStyleAssetIds` and
73
78
  `assets.metadata.isStyleAnchor`.
74
- 6. Pass `tier: "fast"` for exploration, `tier: "best"` for final/high-value
79
+ 7. Pass `tier: "fast"` for exploration, `tier: "best"` for final/high-value
75
80
  output, or `tier: "auto"` when there is no clear preference.
76
81
  - Model/ratio compatibility: Gemini image models accept any `aspectRatio`, but
77
82
  `gpt-image-2` supports only `1:1`, `2:3`, and `3:2`. When the user needs
78
83
  another ratio (16:9, 9:16, 4:5, 21:9, …), pick a Gemini model rather than
79
84
  `gpt-image-2` — an unsupported pairing is rejected upstream. Source of truth
80
85
  is `supportedAspectRatiosForModel` / `MODEL_ASPECT_RATIOS` in `shared/api.ts`.
81
- 7. Preserve returned `assetId`, `runId`, `previewUrl`, and `downloadUrl`.
82
- 8. Use `refine-image` for feedback on an existing asset, `edit-image` for
86
+ 8. Preserve returned `assetId`, `runId`, `previewUrl`, and `downloadUrl`.
87
+ Preserve the immutable `contextPackId` and reuse labels on both generation
88
+ run and output-asset metadata; rendered pixels are not provenance.
89
+ 9. Use `refine-image` for feedback on an existing asset, `edit-image` for
83
90
  targeted changes, and `restyle-image` with `subjectAssetId` and
84
91
  `styleStrength` for subject-preserving brand restyles.
85
- 9. If a designer will take over, call `create-generation-session` or
92
+ 10. If a designer will take over, call `create-generation-session` or
86
93
  `update-generation-session`, then `prepare-generation-session-continuation`
87
94
  when they want a chat preloaded with the session context.
88
95
 
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: creative-context
3
+ description: >-
4
+ Reuse creative context across generation while respecting explicit context
5
+ choices, pinned packs, provenance, and opt-out state.
6
+ scope: app
7
+ metadata:
8
+ internal: true
9
+ ---
10
+
11
+ # Creative Context
12
+
13
+ Use the shared creative-context library to reuse verified source material
14
+ without turning prior work into an invisible global prompt.
15
+
16
+ ## Reuse ladder
17
+
18
+ Apply the first viable option in this exact order:
19
+
20
+ 1. Reuse an approved native asset, component, or template unchanged.
21
+ 2. Compose approved native pieces without flattening or recreating them.
22
+ 3. Duplicate and lightly adapt a real approved example.
23
+ 4. Generate new work conditioned on narrowly retrieved references.
24
+ 5. Generate net-new work only when the relevant corpus is empty.
25
+
26
+ Do not skip directly to imitation or net-new generation when an approved native
27
+ primitive already fits.
28
+
29
+ ## Retrieval procedure
30
+
31
+ Retrieve context in this order, stopping as soon as the current request is
32
+ sufficiently grounded. Keep factual evidence, visual/style references,
33
+ voice/terminology, and structural/layout examples in separate queries so one
34
+ role cannot silently stand in for another:
35
+
36
+ 1. Follow the user's explicit instructions and the object currently selected in
37
+ the app.
38
+ 2. Read the `creative-context` application-state record. If
39
+ `pinnedPackId` is set, prefer that immutable pack. Otherwise use
40
+ `currentPackId` when it records context already selected for this session.
41
+ 3. Call `search-creative-context` with a narrow query for exact facts, visual
42
+ language, audience guidance, prior decisions, or reusable references.
43
+ 4. Call `get-context-item` only for the specific search result versions
44
+ needed for the work. Preserve source and version provenance.
45
+ 5. Fall back to app-local design systems, assets, documents, and current-user
46
+ instructions when the shared library has no relevant evidence.
47
+
48
+ Do not load the whole library or paste large source dumps into a prompt.
49
+ Context packs are generation snapshots; do not silently rewrite a historical
50
+ pack after it has been used.
51
+
52
+ For an inbound Creative Context machine-protocol A2A request, call
53
+ `creative-context-a2a` exactly once with its opaque `requestToken`, then return
54
+ the action's `responseToken` verbatim. Never decode or broaden the request.
55
+
56
+ ## Context opt-out
57
+
58
+ The single state key is `creative-context`:
59
+
60
+ ```json
61
+ {
62
+ "contextMode": "auto",
63
+ "currentPackId": null,
64
+ "pinnedPackId": null
65
+ }
66
+ ```
67
+
68
+ When `contextMode` is `off`, do not search, select, or apply saved creative
69
+ context for subsequent generations. Do not restore a previous pack
70
+ automatically. Historical output may keep its original pack provenance. A
71
+ one-turn instruction such as "ignore the library for this version" wins for
72
+ that turn, but does not change the saved preference unless the user asks.
73
+
74
+ When the user corrects reused context, call `record-context-feedback` against
75
+ the exact item/version and signal whether it was unhelpful, incorrect, or
76
+ outdated. Never invent a source or silently overwrite source history.
77
+
78
+ ## Assets reuse
79
+
80
+ Search visual references separately from factual evidence. When a retrieved
81
+ image should directly guide generation, import its stable media URL with
82
+ `import-asset-from-url` as a reference asset in the selected brand kit, then
83
+ pass that asset id through the normal `referenceAssetIds` path. Do not pass a
84
+ context-item URL directly to an image provider. Keep the returned
85
+ `contextPackId` and reuse labels in generation-run and output-asset metadata
86
+ alongside the normal reference selection provenance.
@@ -40,6 +40,13 @@ Detailed library, generation, image, embed, and engine rules live in
40
40
 
41
41
  ## Application State
42
42
 
43
+ - Before generation, follow the creative-context reuse ladder in
44
+ `.agents/skills/creative-context/SKILL.md`: explicit request and current
45
+ asset/kit first, then a pinned/current pack, then narrow library search.
46
+ Respect `creative-context.contextMode: "off"` without silently restoring a
47
+ pack. This shared Agent-page Library does not replace Assets' existing
48
+ `/library` media workflow.
49
+
43
50
  - `navigation` exposes library, asset, generation, picker, embed, and selection
44
51
  context. Human Library state uses
45
52
  `{ view: "library", selection: "all" | libraryId, tab, scope, folderId, search }`.
@@ -110,6 +117,9 @@ prompt, aspectRatio }`.
110
117
 
111
118
  ## Skills
112
119
 
120
+ - `creative-context` for cross-app source reuse, pinned packs, provenance, and
121
+ context opt-out.
122
+
113
123
  Read the relevant skill before deeper work:
114
124
 
115
125
  - `library-management`, `asset-generation`, `image-generation`, and
@@ -1,6 +1,11 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import { getRequestUserEmail } from "@agent-native/core/server/request-context";
3
3
  import { assertAccess } from "@agent-native/core/sharing";
4
+ import {
5
+ recordGenerationCreativeContext,
6
+ resolveGenerationCreativeContext,
7
+ } from "@agent-native/creative-context/server";
8
+ import type { CreativeContextReuseLabel } from "@agent-native/creative-context/types";
4
9
  import { eq, inArray } from "drizzle-orm";
5
10
  import { nanoid } from "nanoid";
6
11
  import { z } from "zod";
@@ -23,8 +28,26 @@ export default defineAction({
23
28
  runIds: z.array(z.string()).optional(),
24
29
  feedback: z.string().optional(),
25
30
  metadata: z.record(z.string(), z.unknown()).optional(),
31
+ contextModeOverride: z
32
+ .literal("off")
33
+ .optional()
34
+ .describe(
35
+ "Disable Creative Context for this generation session only without changing the saved preference.",
36
+ ),
26
37
  }),
27
38
  run: async (args) => {
39
+ const creativeContext = await resolveGenerationCreativeContext({
40
+ query: [args.title, args.brief].filter(Boolean).join("\n"),
41
+ role: "assets",
42
+ contextModeOverride: args.contextModeOverride,
43
+ });
44
+ const reuseLabels =
45
+ creativeContext.reuseLabels as CreativeContextReuseLabel[];
46
+ const creativeContextProvenance = {
47
+ contextMode: creativeContext.contextMode,
48
+ contextPackId: creativeContext.contextPackId,
49
+ reuseLabels,
50
+ };
28
51
  await assertAccess("asset-library", args.libraryId, "editor");
29
52
  const db = getDb();
30
53
  if (args.collectionId) {
@@ -104,6 +127,7 @@ export default defineAction({
104
127
  feedbackSummary: args.feedback ?? "",
105
128
  metadata: stringifyJson({
106
129
  ...(args.metadata ?? {}),
130
+ creativeContext: creativeContextProvenance,
107
131
  feedbackHistory: args.feedback
108
132
  ? [{ at: now, feedback: args.feedback }]
109
133
  : [],
@@ -140,6 +164,40 @@ export default defineAction({
140
164
  });
141
165
  sortOrder += 10;
142
166
  }
143
- return serializeGenerationSession(session);
167
+ await recordGenerationCreativeContext(
168
+ {
169
+ appId: "assets",
170
+ artifactType: "generation-session",
171
+ artifactId: session.id,
172
+ ...creativeContextProvenance,
173
+ elementProvenance: reuseLabels.length
174
+ ? reuseLabels.map((label) => ({
175
+ elementId: session.id,
176
+ influence: label.influence ?? ("reference-conditioned" as const),
177
+ ...(label.itemId ? { itemId: label.itemId } : {}),
178
+ ...(label.itemVersionId
179
+ ? { itemVersionId: label.itemVersionId }
180
+ : {}),
181
+ label: label.label,
182
+ }))
183
+ : [
184
+ {
185
+ elementId: session.id,
186
+ influence: "generated",
187
+ label: "Asset generation session",
188
+ },
189
+ ],
190
+ },
191
+ {
192
+ artifactAccess: {
193
+ resourceType: "asset-library",
194
+ resourceId: args.libraryId,
195
+ },
196
+ },
197
+ );
198
+ return {
199
+ ...serializeGenerationSession(session),
200
+ ...creativeContextProvenance,
201
+ };
144
202
  },
145
203
  });
@@ -21,6 +21,7 @@ export default defineAction({
21
21
  .describe(
22
22
  "Set by A2A callers (e.g. 'slides', 'design') so audit logs can filter by app.",
23
23
  ),
24
+ contextModeOverride: z.literal("off").optional(),
24
25
  }),
25
26
  parallelSafe: true,
26
27
  run: async (args) => {
@@ -42,6 +43,7 @@ export default defineAction({
42
43
  slotId: args.slotId,
43
44
  source: args.source,
44
45
  callerAppId: args.callerAppId,
46
+ contextModeOverride: args.contextModeOverride,
45
47
  });
46
48
  },
47
49
  });
@@ -1,5 +1,11 @@
1
1
  import { defineAction, embedApp } from "@agent-native/core";
2
2
  import type { ActionRunContext } from "@agent-native/core/action";
3
+ import {
4
+ recordGenerationCreativeContext,
5
+ resolveGenerationCreativeContext,
6
+ } from "@agent-native/creative-context/server";
7
+ import type { CreativeContextReuseLabel } from "@agent-native/creative-context/types";
8
+ import { nanoid } from "nanoid";
3
9
  import { z } from "zod";
4
10
 
5
11
  import {
@@ -57,6 +63,12 @@ const schema = z.object({
57
63
  .string()
58
64
  .optional()
59
65
  .describe("Calling app id, for audit grouping, e.g. design."),
66
+ contextModeOverride: z
67
+ .literal("off")
68
+ .optional()
69
+ .describe(
70
+ "Disable Creative Context for this picker generation only without changing the saved preference.",
71
+ ),
60
72
  });
61
73
 
62
74
  type ActionWithToolParameters = {
@@ -122,6 +134,42 @@ const action = defineAction({
122
134
  };
123
135
  },
124
136
  run: async (args, context?: ActionRunContext) => {
137
+ const creativeContext = await resolveGenerationCreativeContext({
138
+ query: args.prompt,
139
+ role: "assets",
140
+ contextModeOverride: args.contextModeOverride,
141
+ });
142
+ const reuseLabels =
143
+ creativeContext.reuseLabels as CreativeContextReuseLabel[];
144
+ const creativeContextProvenance = {
145
+ contextMode: creativeContext.contextMode,
146
+ contextPackId: creativeContext.contextPackId,
147
+ reuseLabels,
148
+ };
149
+ const creativeContextRequestId = nanoid();
150
+ await recordGenerationCreativeContext({
151
+ appId: "assets",
152
+ artifactType: "generation-request",
153
+ artifactId: creativeContextRequestId,
154
+ ...creativeContextProvenance,
155
+ elementProvenance: reuseLabels.length
156
+ ? reuseLabels.map((label) => ({
157
+ elementId: creativeContextRequestId,
158
+ influence: label.influence ?? ("reference-conditioned" as const),
159
+ ...(label.itemId ? { itemId: label.itemId } : {}),
160
+ ...(label.itemVersionId
161
+ ? { itemVersionId: label.itemVersionId }
162
+ : {}),
163
+ label: label.label,
164
+ }))
165
+ : [
166
+ {
167
+ elementId: creativeContextRequestId,
168
+ influence: "generated",
169
+ label: "Asset generation request",
170
+ },
171
+ ],
172
+ });
125
173
  if (args.mediaType === "video") {
126
174
  const picker = (await openAssetPicker.run(
127
175
  {
@@ -131,6 +179,7 @@ const action = defineAction({
131
179
  libraryHint: args.libraryHint,
132
180
  count: args.count,
133
181
  callerAppId: args.callerAppId,
182
+ creativeContextRequestId,
134
183
  },
135
184
  context,
136
185
  )) as Record<string, unknown>;
@@ -139,6 +188,7 @@ const action = defineAction({
139
188
  generated: false,
140
189
  message:
141
190
  "Assets video picker is ready. Generate or select the video in the picker, then choose the asset to send it back.",
191
+ ...creativeContextProvenance,
142
192
  };
143
193
  }
144
194
 
@@ -156,6 +206,7 @@ const action = defineAction({
156
206
  styleStrength: args.styleStrength,
157
207
  includeLogo: args.includeLogo,
158
208
  callerAppId: args.callerAppId,
209
+ creativeContextRequestId,
159
210
  },
160
211
  context,
161
212
  )) as Record<string, unknown>;
@@ -166,6 +217,7 @@ const action = defineAction({
166
217
  generationMode: "picker-auto-generate",
167
218
  message:
168
219
  "Assets picker is ready and will start image generation inside the picker. If this org has no libraries yet, the picker will create a starter library first. Ask the user to pick one candidate; preserve the chosen assetId, runId, and URLs exactly.",
220
+ ...creativeContextProvenance,
169
221
  };
170
222
  },
171
223
  });
@@ -1,6 +1,11 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import type { ActionRunContext } from "@agent-native/core/action";
3
3
  import { assertAccess } from "@agent-native/core/sharing";
4
+ import {
5
+ recordGenerationCreativeContext,
6
+ resolveGenerationCreativeContext,
7
+ } from "@agent-native/creative-context/server";
8
+ import type { CreativeContextReuseLabel } from "@agent-native/creative-context/types";
4
9
  import { eq } from "drizzle-orm";
5
10
  import { nanoid } from "nanoid";
6
11
  import pLimit from "p-limit";
@@ -117,6 +122,18 @@ export default defineAction({
117
122
  .describe(
118
123
  "Set by A2A callers (e.g. 'slides', 'design') so audit logs can filter by app.",
119
124
  ),
125
+ creativeContextRequestId: z
126
+ .string()
127
+ .optional()
128
+ .describe(
129
+ "Internal immutable creative-context request ID supplied by the Assets picker.",
130
+ ),
131
+ contextModeOverride: z
132
+ .literal("off")
133
+ .optional()
134
+ .describe(
135
+ "Disable Creative Context for this batch only without changing the saved preference.",
136
+ ),
120
137
  }),
121
138
  parallelSafe: true,
122
139
  timeoutMs: IMAGE_GENERATION_TOOL_TIMEOUT_MS,
@@ -135,6 +152,42 @@ export default defineAction({
135
152
  if (base.sessionId) {
136
153
  await requireGenerationSessionInLibrary(base.sessionId, base.libraryId);
137
154
  }
155
+ const creativeContextRequestId =
156
+ base.creativeContextRequestId ?? (base.sessionId ? undefined : nanoid());
157
+ if (!base.creativeContextRequestId && creativeContextRequestId) {
158
+ const creativeContext = await resolveGenerationCreativeContext({
159
+ query: slots.map((slot) => slot.prompt).join("\n"),
160
+ role: "assets",
161
+ contextModeOverride: base.contextModeOverride,
162
+ });
163
+ const reuseLabels =
164
+ creativeContext.reuseLabels as CreativeContextReuseLabel[];
165
+ await recordGenerationCreativeContext({
166
+ appId: "assets",
167
+ artifactType: "generation-request",
168
+ artifactId: creativeContextRequestId,
169
+ contextMode: creativeContext.contextMode,
170
+ contextPackId: creativeContext.contextPackId,
171
+ reuseLabels,
172
+ elementProvenance: reuseLabels.length
173
+ ? reuseLabels.map((label) => ({
174
+ elementId: creativeContextRequestId,
175
+ influence: label.influence ?? ("reference-conditioned" as const),
176
+ ...(label.itemId ? { itemId: label.itemId } : {}),
177
+ ...(label.itemVersionId
178
+ ? { itemVersionId: label.itemVersionId }
179
+ : {}),
180
+ label: label.label,
181
+ }))
182
+ : [
183
+ {
184
+ elementId: creativeContextRequestId,
185
+ influence: "generated",
186
+ label: "Image batch request",
187
+ },
188
+ ],
189
+ });
190
+ }
138
191
  const variantBatchId = nanoid();
139
192
  await Promise.all(
140
193
  slots.map((slot, index) =>
@@ -185,6 +238,8 @@ export default defineAction({
185
238
  subjectAssetId: slot.subjectAssetId,
186
239
  source: base.source,
187
240
  callerAppId: base.callerAppId,
241
+ creativeContextRequestId,
242
+ contextModeOverride: base.contextModeOverride,
188
243
  activateSessionAsset: false,
189
244
  },
190
245
  context,