@agent-native/core 0.84.56 → 0.84.58

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 (151) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/docs/content/locales/ar-SA/template-analytics.mdx +2 -0
  4. package/corpus/core/docs/content/locales/ar-SA/template-clips.mdx +2 -0
  5. package/corpus/core/docs/content/locales/de-DE/template-analytics.mdx +2 -0
  6. package/corpus/core/docs/content/locales/de-DE/template-clips.mdx +2 -0
  7. package/corpus/core/docs/content/locales/es-ES/template-analytics.mdx +2 -0
  8. package/corpus/core/docs/content/locales/es-ES/template-clips.mdx +2 -0
  9. package/corpus/core/docs/content/locales/fr-FR/template-analytics.mdx +2 -0
  10. package/corpus/core/docs/content/locales/fr-FR/template-clips.mdx +2 -0
  11. package/corpus/core/docs/content/locales/hi-IN/template-analytics.mdx +2 -0
  12. package/corpus/core/docs/content/locales/hi-IN/template-clips.mdx +2 -0
  13. package/corpus/core/docs/content/locales/ja-JP/template-analytics.mdx +2 -0
  14. package/corpus/core/docs/content/locales/ja-JP/template-clips.mdx +2 -0
  15. package/corpus/core/docs/content/locales/ko-KR/template-analytics.mdx +2 -0
  16. package/corpus/core/docs/content/locales/ko-KR/template-clips.mdx +2 -0
  17. package/corpus/core/docs/content/locales/pt-BR/template-analytics.mdx +2 -0
  18. package/corpus/core/docs/content/locales/pt-BR/template-clips.mdx +2 -0
  19. package/corpus/core/docs/content/locales/zh-CN/template-analytics.mdx +2 -0
  20. package/corpus/core/docs/content/locales/zh-CN/template-clips.mdx +2 -0
  21. package/corpus/core/docs/content/locales/zh-TW/template-analytics.mdx +2 -0
  22. package/corpus/core/docs/content/locales/zh-TW/template-clips.mdx +2 -0
  23. package/corpus/core/docs/content/template-analytics.mdx +2 -0
  24. package/corpus/core/docs/content/template-clips.mdx +22 -10
  25. package/corpus/core/docs/content/tracking.mdx +2 -0
  26. package/corpus/core/package.json +1 -1
  27. package/corpus/core/src/action.ts +11 -0
  28. package/corpus/core/src/agent/production-agent.ts +24 -46
  29. package/corpus/core/src/client/AssistantChat.tsx +69 -12
  30. package/corpus/core/src/client/MultiTabAssistantChat.tsx +1 -1
  31. package/corpus/core/src/client/conversation/use-near-bottom-autoscroll.ts +45 -2
  32. package/corpus/core/src/coding-tools/run-code.ts +1 -0
  33. package/corpus/core/src/integrations/webhook-handler.ts +10 -9
  34. package/corpus/core/src/server/action-discovery.ts +3 -0
  35. package/corpus/core/src/server/credential-provider.ts +11 -6
  36. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +8 -0
  37. package/corpus/templates/analytics/AGENTS.md +5 -0
  38. package/corpus/templates/analytics/actions/create-session-replay-agent-link.ts +31 -0
  39. package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
  40. package/corpus/templates/analytics/app/i18n-data.ts +20 -0
  41. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +65 -3
  42. package/corpus/templates/analytics/changelog/2026-07-02-session-replays-can-be-copied-as-temporary-private-links-for-agents.md +6 -0
  43. package/corpus/templates/analytics/server/handlers/session-replay.ts +78 -0
  44. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +29 -0
  45. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +313 -0
  46. package/corpus/templates/analytics/server/lib/session-replay.ts +198 -3
  47. package/corpus/templates/analytics/server/plugins/agent-chat.ts +9 -1
  48. package/corpus/templates/analytics/server/routes/[...page].get.ts +104 -1
  49. package/corpus/templates/analytics/server/routes/api/session-replay/agent-context.json.get.ts +48 -0
  50. package/corpus/templates/analytics/server/routes/api/session-replay/agent-events.json.get.ts +63 -0
  51. package/corpus/templates/analytics/shared/session-replay-agent-access.ts +10 -0
  52. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +14 -8
  53. package/corpus/templates/clips/AGENTS.md +3 -2
  54. package/corpus/templates/clips/actions/create-recording-agent-link.ts +90 -0
  55. package/corpus/templates/clips/app/components/player/share-dialog.tsx +43 -46
  56. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +5 -3
  57. package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -1
  58. package/corpus/templates/clips/app/i18n/de-DE.ts +1 -1
  59. package/corpus/templates/clips/app/i18n/en-US.ts +1 -1
  60. package/corpus/templates/clips/app/i18n/es-ES.ts +1 -1
  61. package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -1
  62. package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -1
  63. package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -1
  64. package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -1
  65. package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -1
  66. package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -1
  67. package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -1
  68. package/corpus/templates/clips/app/routes/share.$shareId.tsx +100 -46
  69. package/corpus/templates/clips/changelog/2026-07-02-private-recordings-can-be-shared-with-agents-through-temporary-links-without-making-them-public.md +6 -0
  70. package/corpus/templates/clips/server/lib/public-agent-context.ts +26 -13
  71. package/corpus/templates/clips/server/routes/api/agent-context.json.get.ts +2 -1
  72. package/corpus/templates/clips/server/routes/api/agent-frame.jpg.get.ts +2 -1
  73. package/corpus/templates/clips/server/routes/api/agent-transcript.json.get.ts +2 -1
  74. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +7 -2
  75. package/corpus/templates/clips/shared/agent-context.ts +5 -0
  76. package/corpus/templates/design/actions/list-design-extensions.ts +2 -2
  77. package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +11 -89
  78. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +314 -181
  79. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +92 -134
  80. package/corpus/templates/design/app/components/design/EditPanel.tsx +93 -19
  81. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +18 -26
  82. package/corpus/templates/design/app/components/design/TokensPanel.tsx +220 -192
  83. package/corpus/templates/design/app/components/design/code-workbench-theme.ts +150 -0
  84. package/corpus/templates/design/app/i18n/zh-TW.ts +5 -7
  85. package/corpus/templates/design/app/i18n-data.ts +61 -77
  86. package/corpus/templates/design/app/lib/design-import.ts +4 -1
  87. package/corpus/templates/design/app/pages/DesignEditor.tsx +97 -48
  88. package/corpus/templates/design/changelog/2026-07-02-design-inspector-and-canvas-controls-stay-consistent-when-se.md +6 -0
  89. package/corpus/templates/design/changelog/2026-07-02-fixed-a-crash-when-opening-the-code-editor.md +6 -0
  90. package/corpus/templates/design/changelog/2026-07-02-fixed-motion-drawer-open-transition.md +6 -0
  91. package/corpus/templates/design/changelog/2026-07-02-improved-design-assets-panel.md +6 -0
  92. package/dist/action.d.ts +8 -0
  93. package/dist/action.d.ts.map +1 -1
  94. package/dist/action.js +3 -0
  95. package/dist/action.js.map +1 -1
  96. package/dist/agent/production-agent.d.ts +10 -11
  97. package/dist/agent/production-agent.d.ts.map +1 -1
  98. package/dist/agent/production-agent.js +21 -44
  99. package/dist/agent/production-agent.js.map +1 -1
  100. package/dist/client/AssistantChat.d.ts +1 -0
  101. package/dist/client/AssistantChat.d.ts.map +1 -1
  102. package/dist/client/AssistantChat.js +61 -11
  103. package/dist/client/AssistantChat.js.map +1 -1
  104. package/dist/client/MultiTabAssistantChat.js +1 -1
  105. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  106. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
  107. package/dist/client/conversation/use-near-bottom-autoscroll.js +43 -2
  108. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
  109. package/dist/coding-tools/run-code.d.ts.map +1 -1
  110. package/dist/coding-tools/run-code.js +1 -0
  111. package/dist/coding-tools/run-code.js.map +1 -1
  112. package/dist/collab/routes.d.ts +2 -2
  113. package/dist/integrations/webhook-handler.d.ts +1 -0
  114. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  115. package/dist/integrations/webhook-handler.js +9 -9
  116. package/dist/integrations/webhook-handler.js.map +1 -1
  117. package/dist/notifications/routes.d.ts +3 -3
  118. package/dist/observability/routes.d.ts +3 -3
  119. package/dist/resources/handlers.d.ts +1 -1
  120. package/dist/server/action-discovery.d.ts.map +1 -1
  121. package/dist/server/action-discovery.js +3 -0
  122. package/dist/server/action-discovery.js.map +1 -1
  123. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  124. package/dist/server/credential-provider.d.ts +4 -0
  125. package/dist/server/credential-provider.d.ts.map +1 -1
  126. package/dist/server/credential-provider.js +13 -7
  127. package/dist/server/credential-provider.js.map +1 -1
  128. package/docs/content/locales/ar-SA/template-analytics.mdx +2 -0
  129. package/docs/content/locales/ar-SA/template-clips.mdx +2 -0
  130. package/docs/content/locales/de-DE/template-analytics.mdx +2 -0
  131. package/docs/content/locales/de-DE/template-clips.mdx +2 -0
  132. package/docs/content/locales/es-ES/template-analytics.mdx +2 -0
  133. package/docs/content/locales/es-ES/template-clips.mdx +2 -0
  134. package/docs/content/locales/fr-FR/template-analytics.mdx +2 -0
  135. package/docs/content/locales/fr-FR/template-clips.mdx +2 -0
  136. package/docs/content/locales/hi-IN/template-analytics.mdx +2 -0
  137. package/docs/content/locales/hi-IN/template-clips.mdx +2 -0
  138. package/docs/content/locales/ja-JP/template-analytics.mdx +2 -0
  139. package/docs/content/locales/ja-JP/template-clips.mdx +2 -0
  140. package/docs/content/locales/ko-KR/template-analytics.mdx +2 -0
  141. package/docs/content/locales/ko-KR/template-clips.mdx +2 -0
  142. package/docs/content/locales/pt-BR/template-analytics.mdx +2 -0
  143. package/docs/content/locales/pt-BR/template-clips.mdx +2 -0
  144. package/docs/content/locales/zh-CN/template-analytics.mdx +2 -0
  145. package/docs/content/locales/zh-CN/template-clips.mdx +2 -0
  146. package/docs/content/locales/zh-TW/template-analytics.mdx +2 -0
  147. package/docs/content/locales/zh-TW/template-clips.mdx +2 -0
  148. package/docs/content/template-analytics.mdx +2 -0
  149. package/docs/content/template-clips.mdx +22 -10
  150. package/docs/content/tracking.mdx +2 -0
  151. package/package.json +1 -1
package/corpus/README.md CHANGED
@@ -28,4 +28,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
28
28
  ## Generated Counts
29
29
 
30
30
  - core files: 2044
31
- - template files: 5004
31
+ - template files: 5018
@@ -1,5 +1,19 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.84.58
4
+
5
+ ### Patch Changes
6
+
7
+ - cdc9033: Recover durable background chat runs when action input preparation stops making byte progress, and avoid duplicate tool cards when reconnects replay completed tool events.
8
+ - cdc9033: Remove the shadow from agent chat context scope pills.
9
+ - cdc9033: Prevent agent chat sidebars from jittering around nested scroll areas and suppress replayed reconnect tool cards that are already rendered in the saved thread.
10
+
11
+ ## 0.84.57
12
+
13
+ ### Patch Changes
14
+
15
+ - 5250e7f: Document temporary agent links for session replays and private clips.
16
+
3
17
  ## 0.84.56
4
18
 
5
19
  ### Patch Changes
@@ -147,6 +147,8 @@ pnpm dev
147
147
 
148
148
  **سطح موصل واسع.** تأتي أحداث BigQuery وGA4 وتحليلات المنتج وCRM والدعم والمجتمع وGitHub/Jira وSEO وأحداث `/track` للطرف الأول من خلال actions التي يمكن للوكيل الاتصال بها.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### العمل مع الوكيل
151
153
 
152
154
  يعرف الوكيل دائمًا ما تنظر إليه. يتم إدخال حالة الشاشة الحالية في كل رسالة ككتلة `<current-screen>` - فهي تحتوي على العرض النشط، ولوحة المعلومات المفتوحة أو التحليل، وأي عوامل تصفية محددة.
@@ -131,6 +131,8 @@ API، لذا فإن النماذج التي تقبل النص أو الصور ا
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | أجزاء النص ذات الطابع الزمني مع `startMs`، `endMs`، والطوابع الزمنية القابلة للقراءة، والنص، وتسميات المصدر الاختيارية |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | إطار JPEG مستخرج من الفيديو بطابع زمني للفيديو الأصلي |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  تتبع نقاط النهاية نفس القواعد العامة/كلمة المرور/انتهاء الصلاحية مثل صفحة المشاركة.
135
137
  تتطلب المقاطع المحمية بكلمة مرور كلمة المرور مرة واحدة؛ تعود الاستجابات الناجحة
136
138
  روابط رمزية قصيرة العمر بحيث لا يحتاج وكلاء المراحل النهائية إلى النص العادي
@@ -147,6 +147,8 @@ CLI gibt den lokalen Entwickler URL aus. Melden Sie sich bei Google an und öffn
147
147
 
148
148
  **Breite Konnektoroberfläche.** BigQuery, GA4, Produktanalyse, CRM, Support, Community, GitHub/Jira, SEO und Erstanbieter-`/track`-Ereignisse kommen alle über actions, das der Agent anrufen kann.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### Zusammenarbeit mit dem Agenten
151
153
 
152
154
  Der Agent weiß immer, was Sie sehen. Der aktuelle Bildschirmstatus wird als `<current-screen>`-Block in jede Nachricht eingefügt – er enthält die aktive Ansicht, das geöffnete Dashboard oder die geöffnete Analyse und alle ausgewählten Filter.
@@ -131,6 +131,8 @@ Agent.
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | Transkriptsegmente mit Zeitstempel mit `startMs`, `endMs`, lesbaren Zeitstempeln, Text und optionalen Quellenbezeichnungen |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | Ein JPEG-Frame, der mit einem Originalvideo-Zeitstempel aus dem Video extrahiert wurde |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  Die Endpunkte folgen denselben öffentlichen/Passwort-/Ablaufregeln wie die Freigabeseite.
135
137
  Passwortgeschützte Clips erfordern das einmalige Passwort; Erfolgreiche Antworten werden zurückgegeben
136
138
  kurzlebige tokenisierte Links, sodass nachgeschaltete Agenten den Klartext nicht benötigen
@@ -147,6 +147,8 @@ El CLI imprime el desarrollador local URL. Inicia sesión con Google y luego abr
147
147
 
148
148
  **Amplia superficie de conector.** BigQuery, GA4, análisis de productos, CRM, soporte, comunidad, GitHub/Jira, SEO y eventos propios `/track` llegan a través de actions al que el agente puede llamar.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### Trabajar con el agente
151
153
 
152
154
  El agente siempre sabe lo que estás mirando. El estado actual de la pantalla se inyecta en cada mensaje como un bloque `<current-screen>`: contiene la vista activa, el panel o análisis abierto y los filtros seleccionados.
@@ -131,6 +131,8 @@ agente.
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | Segmentos de transcripción con marca de tiempo con `startMs`, `endMs`, marcas de tiempo legibles, texto y etiquetas de origen opcionales |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | Un fotograma JPEG extraído del vídeo en una marca de tiempo del vídeo original |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  Los puntos finales siguen las mismas reglas de público/contraseña/caducidad que la página para compartir.
135
137
  Los clips protegidos con contraseña requieren la contraseña una vez; regresan respuestas exitosas
136
138
  Enlaces tokenizados de corta duración para que los agentes posteriores no necesiten el texto sin formato
@@ -147,6 +147,8 @@ Le CLI imprime le développement local URL. Connectez-vous avec Google, puis ouv
147
147
 
148
148
  **Large surface de connecteur.** Les événements BigQuery, GA4, analyses de produits, CRM, support, communauté, GitHub/Jira, SEO et `/track` propriétaires passent tous par actions que l'agent peut appeler.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### Travailler avec l'agent
151
153
 
152
154
  L'agent sait toujours ce que vous regardez. L'état actuel de l'écran est injecté dans chaque message sous forme de bloc `<current-screen>` : il contient la vue active, le tableau de bord ou l'analyse ouvert et tous les filtres sélectionnés.
@@ -131,6 +131,8 @@ agent.
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | Segments de transcription horodatés avec `startMs`, `endMs`, horodatages lisibles, texte et étiquettes de source facultatives |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | Une image JPEG extraite de la vidéo avec un horodatage de la vidéo d'origine |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  Les points de terminaison suivent les mêmes règles de public/mot de passe/expiration que la page de partage.
135
137
  Les clips protégés par mot de passe nécessitent le mot de passe une seule fois ; les réponses positives reviennent
136
138
  Liens tokenisés de courte durée afin que les agents en aval n'aient pas besoin du texte brut
@@ -147,6 +147,8 @@ CLI स्थानीय डेव URL प्रिंट करता है
147
147
 
148
148
  **व्यापक कनेक्टर सतह।** BigQuery, GA4, उत्पाद विश्लेषण, CRM, समर्थन, समुदाय, GitHub/Jira, SEO, और प्रथम-पक्ष `/track` इवेंट सभी actions के माध्यम से आते हैं जिन्हें एजेंट कॉल कर सकता है।
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### एजेंट के साथ काम करना
151
153
 
152
154
  एजेंट को हमेशा पता होता है कि आप क्या देख रहे हैं। वर्तमान स्क्रीन स्थिति को प्रत्येक संदेश में `<current-screen>` ब्लॉक के रूप में इंजेक्ट किया जाता है - इसमें सक्रिय दृश्य, खुला डैशबोर्ड या विश्लेषण और कोई भी चयनित फ़िल्टर शामिल होता है।
@@ -131,6 +131,8 @@ APIs, इसलिए मॉडल जो केवल पाठ या स्
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | `startMs`, `endMs`, पठनीय टाइमस्टैम्प, टेक्स्ट और वैकल्पिक स्रोत लेबल के साथ टाइमस्टैम्प्ड ट्रांसक्रिप्ट सेगमेंट |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | मूल-वीडियो टाइमस्टैम्प पर वीडियो से निकाला गया एक JPEG फ्रेम |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  एंडपॉइंट शेयर पेज के समान सार्वजनिक/पासवर्ड/समाप्ति नियमों का पालन करते हैं।
135
137
  पासवर्ड-सुरक्षित क्लिप को एक बार पासवर्ड की आवश्यकता होती है; सफल प्रत्युत्तर वापस आते हैं
136
138
  अल्पकालिक टोकनयुक्त लिंक ताकि डाउनस्ट्रीम एजेंटों को प्लेनटेक्स्ट की आवश्यकता न हो
@@ -147,6 +147,8 @@ CLI はローカル開発 URL を出力します。 Google でログインし、
147
147
 
148
148
  **幅広いコネクタ サーフェス。** BigQuery、GA4、製品分析、CRM、サポート、コミュニティ、GitHub/Jira、SEO、ファーストパーティ `/track` イベントはすべて、エージェントが呼び出すことができる actions 経由で行われます。
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### エージェントとの連携
151
153
 
152
154
  エージェントは、あなたが何を見ているのかを常に知っています。現在の画面状態は、`<current-screen>` ブロックとしてすべてのメッセージに挿入されます。これには、アクティブなビュー、開いているダッシュボードまたは分析、選択したフィルターが含まれます。
@@ -131,6 +131,8 @@ API なので、テキストまたは静止画像のみを受け入れるモデ
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | `startMs`、`endMs`、読み取り可能なタイムスタンプ、テキスト、およびオプションのソース ラベルを含むタイムスタンプ付きトランスクリプト セグメント |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | 元のビデオのタイムスタンプでビデオから抽出された JPEG フレーム |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  エンドポイントは、共有ページと同じパブリック/パスワード/有効期限ルールに従います。
135
137
  パスワードで保護されたクリップでは、パスワードが 1 回必要になります。成功した応答が返されます
136
138
  トークン化されたリンクは有効期間が短いため、ダウンストリーム エージェントはプレーンテキストを必要としません
@@ -147,6 +147,8 @@ CLI는 로컬 개발자 URL를 인쇄합니다. Google에 로그인한 다음 **
147
147
 
148
148
  **광범위한 커넥터 표면.** BigQuery, GA4, 제품 분석, CRM, 지원, 커뮤니티, GitHub/Jira, SEO 및 자사 `/track` 이벤트는 모두 에이전트가 호출할 수 있는 actions를 통해 제공됩니다.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### 에이전트와 협력하기
151
153
 
152
154
  에이전트는 항상 귀하가 무엇을 보고 있는지 알고 있습니다. 현재 화면 상태는 모든 메시지에 `<current-screen>` 블록으로 삽입됩니다. 여기에는 활성 보기, 열려 있는 대시보드 또는 분석, 선택한 필터가 포함됩니다.
@@ -131,6 +131,8 @@ API, 텍스트나 정지 이미지만 허용하는 모델도 여전히 무엇을
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | `startMs`, `endMs`, 읽을 수 있는 타임스탬프, 텍스트 및 선택적 소스 라벨이 포함된 타임스탬프 기록 세그먼트 |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | 원본 비디오 타임스탬프의 비디오에서 추출된 JPEG 프레임 |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  엔드포인트는 공유 페이지와 동일한 공개/비밀번호/만료 규칙을 따릅니다.
135
137
  비밀번호로 보호된 클립에는 비밀번호가 한 번만 필요합니다. 성공적인 응답 반환
136
138
  다운스트림 에이전트에 일반 텍스트가 필요하지 않도록 단기 토큰화된 링크
@@ -147,6 +147,8 @@ O CLI imprime o dev local URL. Faça login com o Google e abra a página **Fonte
147
147
 
148
148
  **Superfície de conector ampla.** BigQuery, GA4, análise de produto, CRM, suporte, comunidade, GitHub/Jira, SEO e eventos `/track` primários, todos vêm por meio do actions que o agente pode ligar.
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### Trabalhando com o agente
151
153
 
152
154
  O agente sempre sabe o que você está vendo. O estado atual da tela é injetado em cada mensagem como um bloco `<current-screen>` — ele contém a visualização ativa, o painel ou análise aberta e quaisquer filtros selecionados.
@@ -131,6 +131,8 @@ agente.
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | Segmentos de transcrição com carimbo de data e hora com `startMs`, `endMs`, carimbos de data e hora legíveis, texto e rótulos de origem opcionais |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | Um quadro JPEG extraído do vídeo em um carimbo de data/hora do vídeo original |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  Os endpoints seguem as mesmas regras de público/senha/expiração da página de compartilhamento.
135
137
  Clipes protegidos por senha exigem a senha uma vez; retorno de respostas bem-sucedidas
136
138
  links tokenizados de curta duração para que os agentes downstream não precisem do texto simples
@@ -147,6 +147,8 @@ CLI 打印本地开发 URL。使用 Google 登录,然后打开 **数据源**
147
147
 
148
148
  **广泛的连接器表面。** BigQuery、GA4、产品分析、CRM、支持、社区、GitHub/Jira、SEO 和第一方 `/track` 事件均来自代理可以调用的 actions。
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### 与代理合作
151
153
 
152
154
  代理始终知道您在看什么。当前屏幕状态作为 `<current-screen>` 块注入到每条消息中 - 它包含活动视图、打开的仪表板或分析以及任何选定的过滤器。
@@ -131,6 +131,8 @@ APIs,因此仅接受文本或静态图像的模型仍然可以理解内容
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | 带有 `startMs`、`endMs`、可读时间戳、文本和可选源标签的时间戳转录片段 |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | 以原始视频时间戳从视频中提取的 JPEG 帧 |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  端点遵循与共享页面相同的公共/密码/过期规则。
135
137
  受密码保护的剪辑需要密码一次;成功响应返回
136
138
  短暂的标记化链接,因此下游代理不需要明文
@@ -147,6 +147,8 @@ CLI 列印本機開發 URL。使用 Google 登入,然後開啟 **資料來源*
147
147
 
148
148
  **廣泛的連線器表面。** BigQuery、GA4、產品分析、CRM、支援、社群、GitHub/Jira、SEO 和第一方 `/track` 事件均來自代理可以呼叫的 actions。
149
149
 
150
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
151
+
150
152
  ### 與代理合作
151
153
 
152
154
  代理始終知道您在看什麼。目前螢幕狀態作為 `<current-screen>` 塊注入到每條訊息中 - 它包含活動檢視、開啟的儀表板或分析以及任何選定的過濾器。
@@ -131,6 +131,8 @@ APIs,因此僅接受文字或靜態圖片的模型仍然可以理解內容
131
131
  | `/api/agent-transcript.json?id=<recordingId>` | 帶有 `startMs`、`endMs`、可讀時間戳、文字和可選來源標籤的時間戳轉錄片段 |
132
132
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | 以原始影片時間戳從影片中擷取的 JPEG 幀 |
133
133
 
134
+ Temporary private agent links are also supported: the Share dialog can mint a two-hour `agent_access` URL for any recording the viewer can access. Agents use that token with the share page and JSON APIs, and the clip does not become public.
135
+
134
136
  端點遵循與共用頁面相同的公開/密碼/過期規則。
135
137
  受密碼保護的剪輯需要密碼一次;成功回應返回
136
138
  短暫的標記化連結,因此下游代理不需要明文
@@ -152,6 +152,8 @@ The CLI prints the local dev URL. Sign in with Google, then open the **Data Sour
152
152
 
153
153
  **Broad connector surface.** BigQuery, GA4, product analytics, CRM, support, community, GitHub/Jira, SEO, and first-party `/track` events all come through actions the agent can call.
154
154
 
155
+ **Session replay agent handoff.** Session recordings stay private, but the session detail page can mint a temporary **Copy for agent** link. The two-hour `agent_access` URL lets an external agent read replay summaries, timelines, and bounded event details without exposing blob/provider URLs or making the recording public.
156
+
155
157
  ### Working with the agent
156
158
 
157
159
  The agent always knows what you're looking at. The current screen state is injected into every message as a `<current-screen>` block — it contains the active view, the open dashboard or analysis, and any selected filters.
@@ -17,7 +17,7 @@ A capture-everything app: screen recordings, meeting notes from your calendar, a
17
17
  />
18
18
  </WireframeBlock>
19
19
 
20
- Think along the lines of Loom + Granola + Wispr Flow rolled into one app — but the agent is a first-class editor across every surface, and the recordings, meetings, and dictations are yours, not a SaaS vendor's. Clips also makes shared recordings agent-readable: paste a normal Clips share link into an agent and it can "hear" the transcript as text and "see" timestamped screen frames as images — no raw video needed. Frame-viewing works in any image-capable agent (ChatGPT, Claude Code, Cursor, Codex); text-only web chats still get the full transcript and can take a frame you upload.
20
+ Think along the lines of Loom + Granola + Wispr Flow rolled into one app — but the agent is a first-class editor across every surface, and the recordings, meetings, and dictations are yours, not a SaaS vendor's. Clips also makes shared recordings agent-readable: paste a public Clips share link or a temporary **Copy for agent** link into an agent and it can "hear" the transcript as text and "see" timestamped screen frames as images — no raw video needed. Frame-viewing works in any image-capable agent (ChatGPT, Claude Code, Cursor, Codex); text-only web chats still get the full transcript and can take a frame you upload.
21
21
 
22
22
  <Diagram id="doc-block-pqnd4p" title="Capture, transcribe, reuse" summary={"Three capture types land in one library; the agent transcribes, titles, and summarizes, then every transcript is searchable and shareable."}>
23
23
 
@@ -87,7 +87,7 @@ Think along the lines of Loom + Granola + Wispr Flow rolled into one app — but
87
87
  - **Capture browser logs with the Chrome extension.** Browser recordings can
88
88
  attach redacted console logs and fetch/XHR metadata, which is helpful for
89
89
  product bugs and browser-only repros.
90
- - **Paste Clips links into agents** so they can discover the agent-readable context: metadata, transcript segments, recommended frames, and timestamped frame images without receiving the raw video file.
90
+ - **Paste Clips links into agents** so they can discover the agent-readable context: metadata, transcript segments, recommended frames, and timestamped frame images without receiving the raw video file. Private clips use a temporary scoped link instead of changing visibility.
91
91
  - **Smart library views.** Group by project, filter by speaker, auto-tag based on content.
92
92
  - **Edit the transcript through chat.** "Fix the mis-transcribed word at 1:42." "Pull three quotes for a blog post." The agent edits the transcript and the UI updates live.
93
93
 
@@ -158,10 +158,14 @@ directly to anonymous users.
158
158
 
159
159
  ## Agent-readable clips
160
160
 
161
- Paste a normal public Clips share link into an agent. The share page advertises
162
- a compact agent context URL, and that context points to the transcript and frame
163
- APIs, so models that only accept text or still images can still understand what
164
- happened in the recording.
161
+ Paste a public Clips share link into an agent, or use **Share → Copy** in the
162
+ **Share with agents** row to mint a temporary private agent link. Private,
163
+ organization, and passworded clips do not need to become public: the copied URL
164
+ carries a recording-scoped `agent_access` token that expires after two hours.
165
+
166
+ The share page advertises a compact agent context URL, and that context points
167
+ to the transcript and frame APIs, so models that only accept text or still
168
+ images can still understand what happened in the recording.
165
169
 
166
170
  Any agent that can fetch an image URL into its vision — ChatGPT, Claude Code,
167
171
  Cursor, Codex, and MCP-connected agents — reads the transcript and sees the
@@ -175,7 +179,8 @@ agent.
175
179
  | `/api/agent-transcript.json?id=<recordingId>` | Timestamped transcript segments with `startMs`, `endMs`, readable timestamps, text, and optional source labels |
176
180
  | `/api/agent-frame.jpg?id=<recordingId>&atMs=<ms>` | A JPEG frame extracted from the video at an original-video timestamp |
177
181
 
178
- The endpoints follow the same public/password/expiry rules as the share page.
182
+ The endpoints follow the same public/password/expiry rules as the share page,
183
+ or accept the scoped `agent_access` token from a temporary agent link.
179
184
  Password-protected clips require the password once; successful responses return
180
185
  short-lived tokenized links so downstream agents do not need the plaintext
181
186
  password.
@@ -194,13 +199,20 @@ only returns a playable Slack `video` block for ready, public clips without a
194
199
  password, expiry hit, archive marker, or trash marker. Other clips still get the
195
200
  normal share-page title/thumbnail metadata and require opening Clips.
196
201
 
197
- <Endpoint id="doc-block-6q76u0" title="Agent context entry point" method="GET" path="/api/agent-context.json" summary="Compact, agent-readable description of a shared clip" auth="Same public / password / expiry rules as the share page" params={[
202
+ <Endpoint id="doc-block-6q76u0" title="Agent context entry point" method="GET" path="/api/agent-context.json" summary="Compact, agent-readable description of a shared clip" auth="Same public / password / expiry rules as the share page, or a scoped agent_access token" params={[
198
203
  {
199
204
  "name": "id",
200
205
  "in": "query",
201
206
  "type": "string",
202
207
  "required": true,
203
208
  "description": "Recording id"
209
+ },
210
+ {
211
+ "name": "agent_access",
212
+ "in": "query",
213
+ "type": "string",
214
+ "required": false,
215
+ "description": "Temporary token from Copy for agent links"
204
216
  }
205
217
  ]} responses={[
206
218
  {
@@ -209,7 +221,7 @@ normal share-page title/thumbnail metadata and require opening Clips.
209
221
  }
210
222
  ]}>
211
223
 
212
- Returns clip metadata, transcript status, chapters, CTAs, recommended frames, and links to the transcript and frame APIs. Advertised by the public share page so a text- or image-only agent can understand a recording without ingesting raw video.
224
+ Returns clip metadata, transcript status, chapters, CTAs, recommended frames, and links to the transcript and frame APIs. Advertised by public share pages and temporary private agent links so a text- or image-only agent can understand a recording without ingesting raw video.
213
225
 
214
226
  </Endpoint>
215
227
 
@@ -358,7 +370,7 @@ tray app at `http://localhost:8094`.
358
370
 
359
371
  **Non-destructive editing.** Trim, split, filler-word removal, silence removal, and stitching stay in `edits_json` so original media remains intact.
360
372
 
361
- **Agent-readable share links.** Public share links expose transcript and frame APIs so agents can understand recordings without ingesting raw video.
373
+ **Agent-readable share links.** Public share links and temporary private agent links expose transcript and frame APIs so agents can understand recordings without ingesting raw video.
362
374
 
363
375
  **Slack playable unfurls.** Public share links can render a Slack `video` block
364
376
  that points at the existing `/embed/:id` player. This is a workspace Slack app
@@ -237,6 +237,8 @@ Privacy defaults are intentionally conservative but still useful for playback:
237
237
 
238
238
  The Analytics template stores replay metadata in SQL (`session_recordings`) and stores chunks through private blob refs (`session_replay_chunks`). Browsers and agents never receive provider URLs. Playback goes through scoped server routes and the default agent tools return summaries or bounded replay events, not raw chunk table access.
239
239
 
240
+ When you need to hand a private recording to an external agent, use the session detail page's **Copy for agent** control. It mints a two-hour, recording-scoped `agent_access` link, SSRs a small discovery payload on `/sessions/:recordingId`, and exposes only the agent context/events JSON APIs. The recording's visibility does not change.
241
+
240
242
  For local development only, Analytics can fall back to capped SQL inline chunks when private blob storage is unavailable. Production deployments should configure private or encrypted blob storage rather than relying on Postgres for replay payloads.
241
243
 
242
244
  ## Advanced: custom providers & internals {#advanced}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.84.56",
3
+ "version": "0.84.58",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -345,6 +345,10 @@ interface DefineActionWithSchema<
345
345
  * Only set this manually when you need to override the inference — e.g. a
346
346
  * POST action that only reads data but can't use GET for a protocol reason. */
347
347
  readOnly?: boolean;
348
+ /** Set false for read-only tools that should stay available in Act mode but
349
+ * must not run during Plan mode because they perform substantive work
350
+ * rather than lightweight inspection. Defaults to allowed when read-only. */
351
+ allowInPlanMode?: boolean;
348
352
  /** If true, the agent may execute this action concurrently with other
349
353
  * read-only or parallel-safe tool calls emitted in the same model turn.
350
354
  * Only set this for mutating actions that are internally concurrency-safe
@@ -460,6 +464,9 @@ interface DefineActionWithParams<
460
464
  /** If true, the framework will NOT emit a screen-refresh change event after a
461
465
  * successful call. Auto-inferred as `true` when `http.method === "GET"`. */
462
466
  readOnly?: boolean;
467
+ /** Set false for read-only tools that should stay available in Act mode but
468
+ * must not run during Plan mode. See the schema overload above. */
469
+ allowInPlanMode?: boolean;
463
470
  /** If true, the agent may execute this action concurrently with other
464
471
  * read-only or parallel-safe tool calls emitted in the same model turn. */
465
472
  parallelSafe?: boolean;
@@ -525,6 +532,7 @@ export interface ActionDefinition<TInput, TReturn> {
525
532
  readonly maxBodyBytes?: number;
526
533
  readonly agentTool?: boolean;
527
534
  readonly readOnly?: boolean;
535
+ readonly allowInPlanMode?: boolean;
528
536
  readonly parallelSafe?: boolean;
529
537
  readonly toolCallable?: boolean;
530
538
  readonly publicAgent?: PublicAgentActionConfig;
@@ -752,6 +760,9 @@ export function defineAction(options: any) {
752
760
  : {}),
753
761
  ...(typeof agentTool === "boolean" ? { agentTool } : {}),
754
762
  ...(typeof readOnly === "boolean" ? { readOnly } : {}),
763
+ ...(typeof options.allowInPlanMode === "boolean"
764
+ ? { allowInPlanMode: options.allowInPlanMode }
765
+ : {}),
755
766
  ...(typeof parallelSafe === "boolean" ? { parallelSafe } : {}),
756
767
  ...(typeof toolCallable === "boolean" ? { toolCallable } : {}),
757
768
  ...(publicAgent ? { publicAgent } : {}),
@@ -26,7 +26,7 @@ import {
26
26
  parseFrontmatter,
27
27
  } from "../resources/metadata.js";
28
28
  import {
29
- isDeployCredentialFallbackAllowed,
29
+ canUseDeployCredentialFallbackForRequest,
30
30
  readDeployCredentialEnv,
31
31
  } from "../server/credential-provider.js";
32
32
  import { readBody } from "../server/h3-helpers.js";
@@ -457,32 +457,16 @@ export function engineToProvider(engineName: string): string {
457
457
  return engineName.startsWith("ai-sdk:") ? engineName.slice(7) : engineName;
458
458
  }
459
459
 
460
- /**
461
- * Returns true when this process should block generic deploy-level provider
462
- * credentials for signed-in chat requests.
463
- *
464
- * Self-hosted single-tenant deployments keep the env-var fallback so the
465
- * original BYO-server UX continues to work without a per-user key.
466
- */
467
- function shouldBlockDeployCredentialFallback(): boolean {
468
- return !isDeployCredentialFallbackAllowed();
469
- }
470
-
471
460
  /**
472
461
  * Resolve the active engine's provider and look up the user's API key for it.
473
462
  *
474
- * In shared hosted deploys we deliberately refuse the deploy-level fallback
475
- * for authenticated users. Without that gate any
476
- * signed-in user who hasn't configured their own provider key would silently
477
- * inherit the deployment's key (uncapped billing on the owner's account,
478
- * prompt logging tied to the deployment owner) — exactly the prior-incident
479
- * pattern we hit on 2026-04-29.
480
- *
481
- * Single-tenant (local-dev, self-hosted SQLite) keeps the env fallback.
463
+ * If the owner has no scoped key, fall back to provider keys supplied by the
464
+ * hosting environment only when the current request can safely use deploy-level
465
+ * credentials. This is a read from process-level config, not a request-scoped
466
+ * write to `process.env`.
482
467
  *
483
- * Callers in `agent-chat-plugin.ts`, `triggers/dispatcher.ts`,
484
- * `jobs/scheduler.ts`, and `integrations/plugin.ts` historically layer
485
- * another deployment-key fallback after this must keep the same gate.
468
+ * Callers that layer another deployment-key fallback after this should keep the
469
+ * same precedence: scoped key first, host-provided env key second.
486
470
  */
487
471
  export async function getOwnerActiveApiKey(
488
472
  ownerEmail: string | null | undefined,
@@ -495,14 +479,7 @@ export async function getOwnerActiveApiKey(
495
479
  const provider = engineToProvider(activeEngine);
496
480
  const userKey = await getOwnerApiKey(provider, ownerEmail);
497
481
  if (userKey) return userKey;
498
- if (shouldBlockDeployCredentialFallback()) {
499
- // Shared hosted default: refuse the env fallback. A null user
500
- // (unauthenticated / background context with no owner) gets undefined
501
- // here too — there's no user to bill, and the call site must surface a
502
- // "configure a key" error to the requester rather than silently using
503
- // the deploy key.
504
- return undefined;
505
- }
482
+ if (!canUseDeployCredentialFallbackForRequest()) return undefined;
506
483
  const envVar = PROVIDER_TO_ENV[provider];
507
484
  return envVar ? readDeployCredentialEnv(envVar) : undefined;
508
485
  } catch {
@@ -552,6 +529,10 @@ export interface ActionEntry {
552
529
  /** If true, completion does NOT trigger a screen-refresh change event.
553
530
  * Set automatically by `defineAction` when `http.method === "GET"`. */
554
531
  readOnly?: boolean;
532
+ /** False keeps a read-only tool available in Act mode but hides/blocks it in
533
+ * Plan mode. Use for tools that perform substantive work even without
534
+ * mutating state. */
535
+ allowInPlanMode?: boolean;
555
536
  /** If true, this action can run concurrently with other same-turn
556
537
  * read-only/parallel-safe tool calls. Only use for actions that handle
557
538
  * their own write ordering and idempotency. */
@@ -705,6 +686,7 @@ export function isPlanModeToolCallAllowed(
705
686
  input: unknown,
706
687
  entry: ActionEntry,
707
688
  ): boolean {
689
+ if (entry.allowInPlanMode === false) return false;
708
690
  if (PLAN_MODE_BLOCKED_READONLY_TOOLS.has(name)) return false;
709
691
 
710
692
  if (name === "web-request") {
@@ -802,6 +784,7 @@ export function createPlanModeActionRegistry(
802
784
 
803
785
  for (const [name, entry] of Object.entries(actions)) {
804
786
  if (name === TOOL_SEARCH_ACTION_NAME) continue;
787
+ if (entry.allowInPlanMode === false) continue;
805
788
  if (PLAN_MODE_BLOCKED_READONLY_TOOLS.has(name)) continue;
806
789
 
807
790
  const allowedActions = PLAN_MODE_ALLOWED_ACTIONS[name];
@@ -4760,15 +4743,14 @@ export function createProductionAgentHandler(
4760
4743
  // for that provider instead of the global active engine's provider.
4761
4744
  // DIAGNOSTIC-ONLY: bracket per-owner API-key resolution (settings/app_secrets reads).
4762
4745
  workerStep("apikey_start");
4746
+ const allowDeployCredentialFallback =
4747
+ canUseDeployCredentialFallbackForRequest();
4763
4748
  let userApiKey: string | undefined;
4764
4749
  if (requestEngine) {
4765
4750
  const provider = engineToProvider(requestEngine);
4766
4751
  userApiKey = await getOwnerApiKey(provider, ownerEmail);
4767
- if (!userApiKey && !shouldBlockDeployCredentialFallback()) {
4768
- // Single-tenant only: env fallback for the requested provider. Shared
4769
- // hosted deploys never silently substitute the deploy-level key for
4770
- // an authenticated user (see getOwnerActiveApiKey for the full
4771
- // rationale).
4752
+ if (!userApiKey && allowDeployCredentialFallback) {
4753
+ // Read-only env fallback for the requested provider.
4772
4754
  const envVar = PROVIDER_TO_ENV[provider];
4773
4755
  userApiKey = envVar ? readDeployCredentialEnv(envVar) : undefined;
4774
4756
  }
@@ -4779,16 +4761,12 @@ export function createProductionAgentHandler(
4779
4761
  workerStep("apikey_done");
4780
4762
 
4781
4763
  // `options.apiKey` is the value the template constructed the plugin with
4782
- // (e.g. wired from a deployment env var). On a shared hosted deploy this
4783
- // is the same cross-tenant hazard as any deploy-level provider key:
4784
- // accepting it as the final fallback would silently bill every key-less
4785
- // user to the deployment's account. Honour it only when the generic
4786
- // deploy fallback policy allows it.
4787
- const effectiveApiKey = shouldBlockDeployCredentialFallback()
4788
- ? userApiKey
4789
- : (userApiKey ??
4790
- options.apiKey ??
4791
- readDeployCredentialEnv("ANTHROPIC_API_KEY"));
4764
+ // (often wired from a deployment env var). Honor it as host-provided
4765
+ // read-only configuration after scoped keys when deploy fallback is safe.
4766
+ const hostApiKey = allowDeployCredentialFallback
4767
+ ? (options.apiKey ?? readDeployCredentialEnv("ANTHROPIC_API_KEY"))
4768
+ : undefined;
4769
+ const effectiveApiKey = userApiKey ?? hostApiKey;
4792
4770
 
4793
4771
  // Resolve engine — per-request engine override takes priority
4794
4772
  // DIAGNOSTIC-ONLY: bracket engine resolution (Builder credential / app-default