@agent-native/core 0.188.0 → 0.189.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/content/CHANGELOG.md +6 -0
- package/corpus/templates/content/actions/list-document-versions.ts +102 -2
- package/corpus/templates/content/actions/restore-document-version.ts +50 -2
- package/corpus/templates/content/app/components/layout/Layout.tsx +6 -1
- package/corpus/templates/content/changelog/2026-09-25-chat-messages-can-be-reverted-to-their-autosaved-version-inc.md +6 -0
- package/corpus/templates/content/server/lib/document-history.ts +59 -8
- package/corpus/templates/content/server/lib/document-version-context.ts +5 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +164 -0
- package/corpus/templates/content/vite.config.ts +2 -38
- package/corpus/templates/design/CHANGELOG.md +4 -0
- package/corpus/templates/design/actions/list-design-versions.ts +3 -1
- package/corpus/templates/design/app/components/layout/Layout.tsx +17 -2
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +10 -3
- package/corpus/templates/design/changelog/2026-09-25-chat-messages-can-be-reverted-to-their-autosaved-version-inc.md +6 -0
- package/corpus/templates/design/server/lib/design-versions.ts +136 -20
- package/corpus/templates/design/server/plugins/agent-chat.ts +18 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +36 -11
- package/corpus/templates/mail/app/hooks/use-inbox-threads.ts +82 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +18 -19
- package/corpus/templates/mail/changelog/2026-09-25-keep-inbox-tab-counts-consistent-when-switching-tabs.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +4 -0
- package/corpus/templates/slides/actions/list-deck-versions.ts +62 -10
- package/corpus/templates/slides/app/components/layout/Layout.tsx +10 -2
- package/corpus/templates/slides/changelog/2026-09-25-chat-messages-can-be-reverted-to-their-autosaved-version-inc.md +6 -0
- package/corpus/templates/slides/server/lib/deck-versions.ts +36 -1
- package/corpus/templates/slides/server/plugins/agent-chat.ts +26 -2
- package/dist/automation/index.d.ts +1 -1
- package/dist/cli/index.js +1 -2
- package/dist/client/AssistantChat.js +112 -35
- package/dist/client/chat/assistant-chat-history-version.d.ts +1 -0
- package/dist/client/chat/message-components.d.ts +8 -1
- package/dist/client/chat/message-components.js +52 -11
- package/dist/client/resources/mcp-integration-catalog.js +1 -1
- package/dist/client/resources/mcp-integration-logos.js +29 -30
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/deploy/build.d.ts +1 -1
- package/dist/deploy/build.js +9 -348
- package/dist/deploy/workspace-deploy.d.ts +2 -2
- package/dist/deploy/workspace-deploy.js +9 -130
- package/dist/localization/core-messages/ar-SA.js +2 -0
- package/dist/localization/core-messages/de-DE.js +2 -0
- package/dist/localization/core-messages/en-US.d.ts +2 -0
- package/dist/localization/core-messages/en-US.js +2 -0
- package/dist/localization/core-messages/es-ES.js +2 -0
- package/dist/localization/core-messages/fr-FR.js +2 -0
- package/dist/localization/core-messages/hi-IN.js +2 -0
- package/dist/localization/core-messages/ja-JP.js +2 -0
- package/dist/localization/core-messages/ko-KR.js +2 -0
- package/dist/localization/core-messages/pt-BR.js +2 -0
- package/dist/localization/core-messages/zh-CN.js +2 -0
- package/dist/localization/core-messages/zh-TW.js +2 -0
- package/dist/localization/core-messages.d.ts +2 -0
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/plugin-options.d.ts +2 -0
- package/dist/server/agent-chat-plugin.d.ts +1 -0
- package/dist/server/agent-chat-plugin.js +26 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/onboarding-html.js +28 -5
- package/dist/vite/client.d.ts +1 -1
- package/docs/content/a2a-protocol.mdx +2 -2
- package/docs/content/cloudflare.mdx +2 -10
- package/docs/content/deploy-an-app.mdx +0 -1
- package/docs/content/deployment.mdx +14 -9
- package/docs/content/environment-variables.mdx +1 -1
- package/docs/content/multi-app-workspace.mdx +1 -1
- package/docs/content/netlify.mdx +1 -1
- package/docs/content/real-time-collaboration.mdx +6 -6
- package/docs/content/workspace-deployment.mdx +4 -15
- package/package.json +4 -4
|
@@ -497,10 +497,12 @@ const messages = {
|
|
|
497
497
|
"message.regenerate": "إعادة إنشاء الرد",
|
|
498
498
|
"message.restoreFailed": "فشلت الاستعادة ({{status}}).",
|
|
499
499
|
"message.restoreQuestion": "هل تريد الاستعادة إلى هنا؟",
|
|
500
|
+
"message.revertQuestion": "هل تريد الرجوع إلى هذه النقطة؟ ستفقد التغييرات التي أُجريت بعدها.",
|
|
500
501
|
"message.restoreRequestFailed": "فشل طلب الاستعادة.",
|
|
501
502
|
"message.threadNotFound": "لم تعد سلسلة الدردشة هذه متاحة. ابدأ دردشة جديدة أو أعد المحاولة إذا كان ذلك غير متوقع.",
|
|
502
503
|
"message.restoring": "جارٍ الاستعادة...",
|
|
503
504
|
"message.revertHere": "الرجوع إلى هنا",
|
|
505
|
+
"message.revertToBeginning": "الرجوع إلى البداية",
|
|
504
506
|
"message.sentAt": "أُرسلت في {{time}}",
|
|
505
507
|
"contextMeter.ariaLabel": "السياق {{percent}}%، {{totalTokens}}{{breakdown}}. افتح تحليل السياق.",
|
|
506
508
|
"contextMeter.breakdown": " الإجمالي: {{systemTokens}} للنظام + {{conversationTokens}} للمحادثة",
|
|
@@ -258,10 +258,12 @@ const messages = {
|
|
|
258
258
|
"message.regenerate": "Antwort neu generieren",
|
|
259
259
|
"message.restoreFailed": "Wiederherstellung fehlgeschlagen ({{status}}).",
|
|
260
260
|
"message.restoreQuestion": "Bis hierher wiederherstellen?",
|
|
261
|
+
"message.revertQuestion": "Zu diesem Punkt zurückkehren? Änderungen danach gehen verloren.",
|
|
261
262
|
"message.restoreRequestFailed": "Wiederherstellungsanfrage fehlgeschlagen.",
|
|
262
263
|
"message.threadNotFound": "Dieser Chat-Thread ist nicht mehr verfügbar. Starte einen neuen Chat oder versuche es erneut, falls das unerwartet war.",
|
|
263
264
|
"message.restoring": "Wird wiederhergestellt...",
|
|
264
265
|
"message.revertHere": "Bis hierher zurücksetzen",
|
|
266
|
+
"message.revertToBeginning": "Zum Anfang zurückkehren",
|
|
265
267
|
"message.sentAt": "Gesendet {{time}}",
|
|
266
268
|
"plan.act": "Ausführen",
|
|
267
269
|
"plan.implement": "Umsetzen",
|
|
@@ -485,10 +485,12 @@ declare const messages: {
|
|
|
485
485
|
readonly "message.regenerate": "Regenerate response";
|
|
486
486
|
readonly "message.restoreFailed": "Restore failed ({{status}}).";
|
|
487
487
|
readonly "message.restoreQuestion": "Restore to here?";
|
|
488
|
+
readonly "message.revertQuestion": "Revert to this point? Changes made after this point will be lost.";
|
|
488
489
|
readonly "message.restoreRequestFailed": "Restore request failed.";
|
|
489
490
|
readonly "message.threadNotFound": "This chat thread is no longer available. Start a new chat or retry if this was unexpected.";
|
|
490
491
|
readonly "message.restoring": "Restoring...";
|
|
491
492
|
readonly "message.revertHere": "Revert to here";
|
|
493
|
+
readonly "message.revertToBeginning": "Revert to beginning";
|
|
492
494
|
readonly "message.sentAt": "Sent {{time}}";
|
|
493
495
|
readonly "contextMeter.ariaLabel": "Context {{percent}}%, {{totalTokens}}{{breakdown}}. Open Context X-Ray.";
|
|
494
496
|
readonly "contextMeter.breakdown": " total: {{systemTokens}} system + {{conversationTokens}} conversation";
|
|
@@ -485,10 +485,12 @@ const messages = {
|
|
|
485
485
|
"message.regenerate": "Regenerate response",
|
|
486
486
|
"message.restoreFailed": "Restore failed ({{status}}).",
|
|
487
487
|
"message.restoreQuestion": "Restore to here?",
|
|
488
|
+
"message.revertQuestion": "Revert to this point? Changes made after this point will be lost.",
|
|
488
489
|
"message.restoreRequestFailed": "Restore request failed.",
|
|
489
490
|
"message.threadNotFound": "This chat thread is no longer available. Start a new chat or retry if this was unexpected.",
|
|
490
491
|
"message.restoring": "Restoring...",
|
|
491
492
|
"message.revertHere": "Revert to here",
|
|
493
|
+
"message.revertToBeginning": "Revert to beginning",
|
|
492
494
|
"message.sentAt": "Sent {{time}}",
|
|
493
495
|
"contextMeter.ariaLabel": "Context {{percent}}%, {{totalTokens}}{{breakdown}}. Open Context X-Ray.",
|
|
494
496
|
"contextMeter.breakdown": " total: {{systemTokens}} system + {{conversationTokens}} conversation",
|
|
@@ -258,10 +258,12 @@ const messages = {
|
|
|
258
258
|
"message.regenerate": "Regenerar respuesta",
|
|
259
259
|
"message.restoreFailed": "Error al restaurar ({{status}}).",
|
|
260
260
|
"message.restoreQuestion": "¿Restaurar hasta aquí?",
|
|
261
|
+
"message.revertQuestion": "¿Volver a este punto? Se perderán los cambios posteriores.",
|
|
261
262
|
"message.restoreRequestFailed": "Error en la solicitud de restauración.",
|
|
262
263
|
"message.threadNotFound": "Este hilo de chat ya no está disponible. Inicia un chat nuevo o inténtalo de nuevo si esto no era esperado.",
|
|
263
264
|
"message.restoring": "Restaurando...",
|
|
264
265
|
"message.revertHere": "Revertir hasta aquí",
|
|
266
|
+
"message.revertToBeginning": "Volver al inicio",
|
|
265
267
|
"message.sentAt": "Enviado a las {{time}}",
|
|
266
268
|
"plan.act": "Actuar",
|
|
267
269
|
"plan.implement": "Implementar",
|
|
@@ -258,10 +258,12 @@ const messages = {
|
|
|
258
258
|
"message.regenerate": "Régénérer la réponse",
|
|
259
259
|
"message.restoreFailed": "Échec de la restauration ({{status}}).",
|
|
260
260
|
"message.restoreQuestion": "Restaurer jusqu’ici ?",
|
|
261
|
+
"message.revertQuestion": "Revenir à ce point ? Les modifications ultérieures seront perdues.",
|
|
261
262
|
"message.restoreRequestFailed": "Échec de la demande de restauration.",
|
|
262
263
|
"message.threadNotFound": "Ce fil de discussion n’est plus disponible. Démarrez une nouvelle discussion ou réessayez si cela est inattendu.",
|
|
263
264
|
"message.restoring": "Restauration...",
|
|
264
265
|
"message.revertHere": "Revenir jusqu’ici",
|
|
266
|
+
"message.revertToBeginning": "Revenir au début",
|
|
265
267
|
"message.sentAt": "Envoyé à {{time}}",
|
|
266
268
|
"plan.act": "Agir",
|
|
267
269
|
"plan.implement": "Implémenter",
|
|
@@ -485,10 +485,12 @@ const messages = {
|
|
|
485
485
|
"message.regenerate": "जवाब फिर से बनाएँ",
|
|
486
486
|
"message.restoreFailed": "पुनर्स्थापना विफल रही ({{status}})।",
|
|
487
487
|
"message.restoreQuestion": "यहाँ तक पुनर्स्थापित करें?",
|
|
488
|
+
"message.revertQuestion": "इस बिंदु पर वापस जाएँ? इसके बाद किए गए बदलाव खो जाएँगे।",
|
|
488
489
|
"message.restoreRequestFailed": "पुनर्स्थापना अनुरोध विफल रहा।",
|
|
489
490
|
"message.threadNotFound": "यह चैट थ्रेड अब उपलब्ध नहीं है। नई चैट शुरू करें या यदि यह अप्रत्याशित है तो फिर कोशिश करें।",
|
|
490
491
|
"message.restoring": "पुनर्स्थापित किया जा रहा है...",
|
|
491
492
|
"message.revertHere": "यहाँ तक वापस जाएँ",
|
|
493
|
+
"message.revertToBeginning": "शुरुआत पर वापस जाएँ",
|
|
492
494
|
"message.sentAt": "{{time}} पर भेजा गया",
|
|
493
495
|
"contextMeter.ariaLabel": "संदर्भ {{percent}}%, {{totalTokens}}{{breakdown}}। संदर्भ विश्लेषण खोलें।",
|
|
494
496
|
"contextMeter.breakdown": " कुल: {{systemTokens}} सिस्टम + {{conversationTokens}} बातचीत",
|
|
@@ -482,10 +482,12 @@ const messages = {
|
|
|
482
482
|
"message.regenerate": "応答を再生成",
|
|
483
483
|
"message.restoreFailed": "復元に失敗しました({{status}})。",
|
|
484
484
|
"message.restoreQuestion": "ここまで復元しますか?",
|
|
485
|
+
"message.revertQuestion": "この時点に戻しますか?この後の変更は失われます。",
|
|
485
486
|
"message.restoreRequestFailed": "復元リクエストに失敗しました。",
|
|
486
487
|
"message.threadNotFound": "このチャットスレッドは利用できなくなりました。新しいチャットを開始するか、想定外の場合は再試行してください。",
|
|
487
488
|
"message.restoring": "復元中...",
|
|
488
489
|
"message.revertHere": "ここまで戻す",
|
|
490
|
+
"message.revertToBeginning": "最初に戻す",
|
|
489
491
|
"message.sentAt": "{{time}} に送信",
|
|
490
492
|
"contextMeter.ariaLabel": "コンテキスト {{percent}}%、合計 {{totalTokens}}{{breakdown}}。コンテキスト X-Ray を開きます。",
|
|
491
493
|
"contextMeter.breakdown": ":システム {{systemTokens}} + 会話 {{conversationTokens}}",
|
|
@@ -482,10 +482,12 @@ const messages = {
|
|
|
482
482
|
"message.regenerate": "응답 다시 생성",
|
|
483
483
|
"message.restoreFailed": "복원 실패({{status}}).",
|
|
484
484
|
"message.restoreQuestion": "여기로 복원하시겠습니까?",
|
|
485
|
+
"message.revertQuestion": "이 지점으로 되돌릴까요? 이후 변경 사항은 사라집니다.",
|
|
485
486
|
"message.restoreRequestFailed": "복원 요청에 실패했습니다.",
|
|
486
487
|
"message.threadNotFound": "이 채팅 스레드는 더 이상 사용할 수 없습니다. 새 채팅을 시작하거나 예상치 못한 문제라면 다시 시도하세요.",
|
|
487
488
|
"message.restoring": "복원 중...",
|
|
488
489
|
"message.revertHere": "여기로 되돌리기",
|
|
490
|
+
"message.revertToBeginning": "처음으로 되돌리기",
|
|
489
491
|
"message.sentAt": "{{time}}에 전송",
|
|
490
492
|
"contextMeter.ariaLabel": "컨텍스트 {{percent}}%, 총 {{totalTokens}}{{breakdown}}. 컨텍스트 X-Ray를 엽니다.",
|
|
491
493
|
"contextMeter.breakdown": ": 시스템 {{systemTokens}} + 대화 {{conversationTokens}}",
|
|
@@ -258,10 +258,12 @@ const messages = {
|
|
|
258
258
|
"message.regenerate": "Gerar resposta novamente",
|
|
259
259
|
"message.restoreFailed": "Falha ao restaurar ({{status}}).",
|
|
260
260
|
"message.restoreQuestion": "Restaurar até aqui?",
|
|
261
|
+
"message.revertQuestion": "Reverter para este ponto? As alterações feitas depois serão perdidas.",
|
|
261
262
|
"message.restoreRequestFailed": "Falha na solicitação de restauração.",
|
|
262
263
|
"message.threadNotFound": "Esta conversa não está mais disponível. Inicie uma nova conversa ou tente novamente se isso for inesperado.",
|
|
263
264
|
"message.restoring": "Restaurando...",
|
|
264
265
|
"message.revertHere": "Reverter até aqui",
|
|
266
|
+
"message.revertToBeginning": "Reverter ao início",
|
|
265
267
|
"message.sentAt": "Enviado às {{time}}",
|
|
266
268
|
"plan.act": "Agir",
|
|
267
269
|
"plan.implement": "Implementar",
|
|
@@ -482,10 +482,12 @@ const messages = {
|
|
|
482
482
|
"message.regenerate": "重新生成响应",
|
|
483
483
|
"message.restoreFailed": "恢复失败({{status}})。",
|
|
484
484
|
"message.restoreQuestion": "恢复到此处?",
|
|
485
|
+
"message.revertQuestion": "还原到此处?此后所做的更改将会丢失。",
|
|
485
486
|
"message.restoreRequestFailed": "恢复请求失败。",
|
|
486
487
|
"message.threadNotFound": "此聊天线程已不可用。请开始新聊天;如果这是意外情况,也可以重试。",
|
|
487
488
|
"message.restoring": "正在恢复...",
|
|
488
489
|
"message.revertHere": "还原到此处",
|
|
490
|
+
"message.revertToBeginning": "还原到开头",
|
|
489
491
|
"message.sentAt": "发送于 {{time}}",
|
|
490
492
|
"contextMeter.ariaLabel": "上下文 {{percent}}%,共 {{totalTokens}}{{breakdown}}。打开上下文透视。",
|
|
491
493
|
"contextMeter.breakdown": ":{{systemTokens}} 系统 + {{conversationTokens}} 对话",
|
|
@@ -482,10 +482,12 @@ const messages = {
|
|
|
482
482
|
"message.regenerate": "重新產生回應",
|
|
483
483
|
"message.restoreFailed": "還原失敗({{status}})。",
|
|
484
484
|
"message.restoreQuestion": "要還原到這裡嗎?",
|
|
485
|
+
"message.revertQuestion": "要還原到這裡嗎?之後所做的變更將會遺失。",
|
|
485
486
|
"message.restoreRequestFailed": "還原要求失敗。",
|
|
486
487
|
"message.threadNotFound": "此聊天串已無法使用。請開始新的聊天;如果這是意外情況,也可以重試。",
|
|
487
488
|
"message.restoring": "正在還原...",
|
|
488
489
|
"message.revertHere": "還原到這裡",
|
|
490
|
+
"message.revertToBeginning": "還原到開頭",
|
|
489
491
|
"message.sentAt": "傳送於 {{time}}",
|
|
490
492
|
"contextMeter.ariaLabel": "上下文 {{percent}}%,共 {{totalTokens}}{{breakdown}}。開啟上下文透視。",
|
|
491
493
|
"contextMeter.breakdown": ":{{systemTokens}} 系統 + {{conversationTokens}} 對話",
|
|
@@ -487,10 +487,12 @@ export declare const englishAgentChatMessages: {
|
|
|
487
487
|
readonly "message.regenerate": "Regenerate response";
|
|
488
488
|
readonly "message.restoreFailed": "Restore failed ({{status}}).";
|
|
489
489
|
readonly "message.restoreQuestion": "Restore to here?";
|
|
490
|
+
readonly "message.revertQuestion": "Revert to this point? Changes made after this point will be lost.";
|
|
490
491
|
readonly "message.restoreRequestFailed": "Restore request failed.";
|
|
491
492
|
readonly "message.threadNotFound": "This chat thread is no longer available. Start a new chat or retry if this was unexpected.";
|
|
492
493
|
readonly "message.restoring": "Restoring...";
|
|
493
494
|
readonly "message.revertHere": "Revert to here";
|
|
495
|
+
readonly "message.revertToBeginning": "Revert to beginning";
|
|
494
496
|
readonly "message.sentAt": "Sent {{time}}";
|
|
495
497
|
readonly "contextMeter.ariaLabel": "Context {{percent}}%, {{totalTokens}}{{breakdown}}. Open Context X-Ray.";
|
|
496
498
|
readonly "contextMeter.breakdown": " total: {{systemTokens}} system + {{conversationTokens}} conversation";
|
|
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
41
41
|
thumbsUpRate: number;
|
|
42
42
|
avgEvalScore: number;
|
|
43
43
|
} | {
|
|
44
|
+
error?: undefined;
|
|
44
45
|
summary: import("./types.js").TraceSummary;
|
|
45
46
|
spans: import("./types.js").TraceSpan[];
|
|
46
47
|
id?: undefined;
|
|
47
|
-
error?: undefined;
|
|
48
48
|
ok?: undefined;
|
|
49
49
|
} | {
|
|
50
|
+
error?: undefined;
|
|
50
51
|
summary?: undefined;
|
|
51
52
|
spans?: undefined;
|
|
52
53
|
id: string;
|
|
53
|
-
error?: undefined;
|
|
54
54
|
ok?: undefined;
|
|
55
55
|
} | {
|
|
56
56
|
summary?: undefined;
|
|
@@ -59,9 +59,9 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
|
|
|
59
59
|
error: any;
|
|
60
60
|
ok?: undefined;
|
|
61
61
|
} | {
|
|
62
|
+
error?: undefined;
|
|
62
63
|
summary?: undefined;
|
|
63
64
|
spans?: undefined;
|
|
64
65
|
id?: undefined;
|
|
65
|
-
error?: undefined;
|
|
66
66
|
ok: boolean;
|
|
67
67
|
}>>;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -57,37 +57,37 @@ export declare function createListSecretsHandler(): import("h3").EventHandlerWit
|
|
|
57
57
|
/** POST /_agent-native/secrets/:key — write a secret. */
|
|
58
58
|
export declare function createWriteSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
59
59
|
error: string;
|
|
60
|
-
ok?: undefined;
|
|
61
60
|
status?: undefined;
|
|
61
|
+
ok?: undefined;
|
|
62
62
|
} | {
|
|
63
|
-
error?: undefined;
|
|
64
63
|
ok: boolean;
|
|
65
64
|
status: string;
|
|
65
|
+
error?: undefined;
|
|
66
66
|
} | {
|
|
67
|
-
ok?: undefined;
|
|
68
67
|
error: string;
|
|
69
68
|
removed?: undefined;
|
|
69
|
+
ok?: undefined;
|
|
70
70
|
} | {
|
|
71
|
-
error?: undefined;
|
|
72
71
|
ok: boolean;
|
|
73
72
|
removed: boolean;
|
|
73
|
+
error?: undefined;
|
|
74
74
|
}>>;
|
|
75
75
|
/**
|
|
76
76
|
* POST /_agent-native/secrets/:key/test — validate an optional candidate value
|
|
77
77
|
* or the current stored value without changing anything.
|
|
78
78
|
*/
|
|
79
79
|
export declare function createTestSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
80
|
-
ok?: undefined;
|
|
81
80
|
error: string;
|
|
82
81
|
note?: undefined;
|
|
82
|
+
ok?: undefined;
|
|
83
83
|
} | {
|
|
84
|
-
error?: undefined;
|
|
85
84
|
ok: boolean;
|
|
86
85
|
note?: undefined;
|
|
87
|
-
} | {
|
|
88
86
|
error?: undefined;
|
|
87
|
+
} | {
|
|
89
88
|
ok: boolean;
|
|
90
89
|
note: string;
|
|
90
|
+
error?: undefined;
|
|
91
91
|
} | {
|
|
92
92
|
note?: undefined;
|
|
93
93
|
ok: boolean;
|
|
@@ -119,11 +119,11 @@ export interface AdHocSecretPayload {
|
|
|
119
119
|
export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
|
|
120
120
|
error: string;
|
|
121
121
|
} | {
|
|
122
|
-
error?: undefined;
|
|
123
122
|
ok: boolean;
|
|
124
123
|
key: string;
|
|
125
|
-
} | {
|
|
126
124
|
error?: undefined;
|
|
125
|
+
} | {
|
|
127
126
|
ok: boolean;
|
|
128
127
|
removed: boolean;
|
|
128
|
+
error?: undefined;
|
|
129
129
|
}>>;
|
|
@@ -11,6 +11,8 @@ import type { AgentChatMcpIcon, AgentChatMcpOptions } from "./mcp-options.js";
|
|
|
11
11
|
* startup and may register routes/hooks synchronously or asynchronously. */
|
|
12
12
|
export type NitroPluginDef = (nitroApp: any) => void | Promise<void>;
|
|
13
13
|
export interface AgentChatPluginOptions {
|
|
14
|
+
/** Best-effort app checkpoint taken before the first model generation. */
|
|
15
|
+
onAgentTurnStart?: (scope: AgentChatScope, run: Pick<ActiveRun, "threadId" | "runId">) => void | Promise<void>;
|
|
14
16
|
/**
|
|
15
17
|
* Best-effort app autosave hook. It runs after the chat thread has been
|
|
16
18
|
* persisted and only when the run completed a side effect. Errors are
|
|
@@ -41,6 +41,7 @@ export { scheduledTriggerAvailability };
|
|
|
41
41
|
export { shouldDisableRecurringJobsRuntime };
|
|
42
42
|
export { finalizeClaimedAgentChatProcessRunFailure };
|
|
43
43
|
export declare function runPostAgentTurnAutosave(callback: AgentChatPluginOptions["onAgentTurnComplete"] | undefined, scope: AgentChatScope | null | undefined, run: ActiveRun): Promise<void>;
|
|
44
|
+
export declare function runPreAgentTurnAutosave(callback: AgentChatPluginOptions["onAgentTurnStart"] | undefined, scope: AgentChatScope | null | undefined, run: Pick<ActiveRun, "threadId" | "runId">): Promise<void>;
|
|
44
45
|
/**
|
|
45
46
|
* The model this mount runs with, when the caller does not pass one per request.
|
|
46
47
|
*
|
|
@@ -184,6 +184,30 @@ export async function runPostAgentTurnAutosave(callback, scope, run) {
|
|
|
184
184
|
console.error("[agent-chat] post-agent-turn autosave failed:", error);
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
+
export async function runPreAgentTurnAutosave(callback, scope, run) {
|
|
188
|
+
if (!callback || !scope)
|
|
189
|
+
return;
|
|
190
|
+
try {
|
|
191
|
+
await callback(scope, run);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
captureError(error, {
|
|
195
|
+
route: "agent-chat",
|
|
196
|
+
aiTraceId: run.runId,
|
|
197
|
+
tags: {
|
|
198
|
+
source: "agent-chat",
|
|
199
|
+
failureClass: "pre-agent-turn-autosave",
|
|
200
|
+
},
|
|
201
|
+
extra: {
|
|
202
|
+
runId: run.runId,
|
|
203
|
+
threadId: run.threadId,
|
|
204
|
+
scopeType: scope.type,
|
|
205
|
+
scopeId: scope.id,
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
console.error("[agent-chat] pre-agent-turn autosave failed:", error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
187
211
|
/**
|
|
188
212
|
* The model this mount runs with, when the caller does not pass one per request.
|
|
189
213
|
*
|
|
@@ -3266,6 +3290,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
3266
3290
|
runCtx.threadId = threadId;
|
|
3267
3291
|
runCtx.runId = runId;
|
|
3268
3292
|
}
|
|
3293
|
+
await runPreAgentTurnAutosave(options?.onAgentTurnStart, runCtx?.chatScope, { threadId, runId });
|
|
3269
3294
|
},
|
|
3270
3295
|
onRunComplete: async (run, threadId) => {
|
|
3271
3296
|
if (threadId)
|
|
@@ -3524,6 +3549,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
3524
3549
|
runCtx.threadId = threadId;
|
|
3525
3550
|
runCtx.runId = runId;
|
|
3526
3551
|
}
|
|
3552
|
+
await runPreAgentTurnAutosave(options?.onAgentTurnStart, runCtx?.chatScope, { threadId, runId });
|
|
3527
3553
|
},
|
|
3528
3554
|
onRunComplete: async (run, threadId) => {
|
|
3529
3555
|
if (threadId)
|
|
@@ -56,10 +56,10 @@ export declare function createAgentEngineApiKeyHandler(): import("h3").EventHand
|
|
|
56
56
|
ok: boolean;
|
|
57
57
|
error: string;
|
|
58
58
|
} | {
|
|
59
|
-
error?: undefined;
|
|
60
59
|
ok: boolean;
|
|
61
60
|
key: string;
|
|
62
61
|
baseUrlKey?: string;
|
|
63
62
|
scope: AgentEngineApiKeyScope;
|
|
63
|
+
error?: undefined;
|
|
64
64
|
}>>;
|
|
65
65
|
export {};
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* static suggestion list in `model-config.ts`.
|
|
6
6
|
*/
|
|
7
7
|
export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
8
|
-
ok?: undefined;
|
|
9
8
|
error: string;
|
|
9
|
+
ok?: undefined;
|
|
10
10
|
models?: undefined;
|
|
11
11
|
} | {
|
|
12
|
-
error?: undefined;
|
|
13
12
|
ok: boolean;
|
|
14
13
|
models: string[];
|
|
14
|
+
error?: undefined;
|
|
15
15
|
}>>;
|
|
@@ -2199,9 +2199,8 @@ ${marketingStyles}
|
|
|
2199
2199
|
flex: none;
|
|
2200
2200
|
width: 100%;
|
|
2201
2201
|
min-height: auto;
|
|
2202
|
-
padding:
|
|
2202
|
+
padding: 1.5rem 1.25rem;
|
|
2203
2203
|
border-inline-start: 0;
|
|
2204
|
-
border-top: 1px solid color-mix(in srgb, CanvasText 10%, transparent);
|
|
2205
2204
|
}
|
|
2206
2205
|
.auth-marketing-home .auth-marketing-layout { min-height: auto; }
|
|
2207
2206
|
.auth-marketing-home .auth-marketing-shell { display: block; }
|
|
@@ -2434,6 +2433,10 @@ ${marketingStyles}
|
|
|
2434
2433
|
}
|
|
2435
2434
|
}
|
|
2436
2435
|
@media (max-width: 900px) {
|
|
2436
|
+
.auth-marketing-home {
|
|
2437
|
+
min-height: 100vh;
|
|
2438
|
+
min-height: 100svh;
|
|
2439
|
+
}
|
|
2437
2440
|
.auth-marketing-home .auth-marketing-shell-with-top-right {
|
|
2438
2441
|
flex-direction: column;
|
|
2439
2442
|
}
|
|
@@ -2455,11 +2458,31 @@ ${marketingStyles}
|
|
|
2455
2458
|
}
|
|
2456
2459
|
.auth-marketing-home .form-panel {
|
|
2457
2460
|
order: 1;
|
|
2458
|
-
padding:
|
|
2461
|
+
padding: max(1.5rem, env(safe-area-inset-top)) 1.25rem max(1.5rem, env(safe-area-inset-bottom));
|
|
2459
2462
|
border-inline-start: 0;
|
|
2460
|
-
border-top: 1px solid var(--auth-marketing-border);
|
|
2461
2463
|
}
|
|
2462
|
-
.auth-marketing-home .marketing-panel {
|
|
2464
|
+
.auth-marketing-home .marketing-panel { display: none; }
|
|
2465
|
+
.auth-marketing-home .card h1 {
|
|
2466
|
+
font-size: clamp(1.625rem, 6vw, 2rem);
|
|
2467
|
+
line-height: 1.15;
|
|
2468
|
+
margin-bottom: 0.5rem;
|
|
2469
|
+
}
|
|
2470
|
+
.auth-marketing-home .card .subtitle {
|
|
2471
|
+
margin-bottom: 1.5rem;
|
|
2472
|
+
font-size: 1rem;
|
|
2473
|
+
line-height: 1.4;
|
|
2474
|
+
}
|
|
2475
|
+
.auth-marketing-home .card .divider { margin: 1rem 0; }
|
|
2476
|
+
.auth-marketing-home .card .legal-note { margin-top: 1.5rem; }
|
|
2477
|
+
.auth-marketing-home .card input,
|
|
2478
|
+
.auth-marketing-home .card button {
|
|
2479
|
+
min-height: 2.75rem;
|
|
2480
|
+
}
|
|
2481
|
+
body.has-marketing .locale-trigger {
|
|
2482
|
+
min-width: 2.75rem;
|
|
2483
|
+
min-height: 2.75rem;
|
|
2484
|
+
}
|
|
2485
|
+
.auth-marketing-home .card input { font-size: 1rem; }
|
|
2463
2486
|
}
|
|
2464
2487
|
`;
|
|
2465
2488
|
const authClientScriptPath = authClientAssetPath(appBasePath);
|
package/dist/vite/client.d.ts
CHANGED
|
@@ -81,7 +81,7 @@ declare function getReactRouterAliases(cwd: string): Array<{
|
|
|
81
81
|
}>;
|
|
82
82
|
declare function getDefaultOptimizeDeps(cwd: string): string[];
|
|
83
83
|
export interface NitroOptions {
|
|
84
|
-
/** Nitro deployment preset (e.g. "node", "vercel", "netlify", "aws_amplify", "
|
|
84
|
+
/** Nitro deployment preset (e.g. "node", "vercel", "netlify", "aws_amplify", "cloudflare_module"). Default: "node" */
|
|
85
85
|
preset?: string;
|
|
86
86
|
/** Source directory for server files. Default: "./server" */
|
|
87
87
|
srcDir?: string;
|
|
@@ -280,7 +280,7 @@ When `message/send` is called with `async: true`, the JSON-RPC handler enqueues
|
|
|
280
280
|
|
|
281
281
|
<Callout tone="warning">
|
|
282
282
|
|
|
283
|
-
**Serverless webhook and gateway timeouts.** Hosted environment gateways (such as Netlify, Vercel, or Cloudflare
|
|
283
|
+
**Serverless webhook and gateway timeouts.** Hosted environment gateways (such as Netlify, Vercel, or Cloudflare Workers) impose strict execution limits (often 10 to 30 seconds) on public-facing HTTP routes. Because agent loops can take significant time to run queries, fetch context, and execute tools, you **must use `async: true`** when calling A2A endpoints or handling external webhooks. This immediately returns a `working` status to the API gateway, keeping the connection open only for a few milliseconds, while the self-fired `/process-task` POST executes the agent loop in the background. Do not block the primary HTTP request waiting for the agent loop to finish.
|
|
284
284
|
|
|
285
285
|
</Callout>
|
|
286
286
|
|
|
@@ -641,7 +641,7 @@ The agent card endpoint is always public (no auth) so other agents can discover
|
|
|
641
641
|
|
|
642
642
|
Bearer validation runs at the request boundary — in the JSON-RPC handler — before the agent loop ever sees the message. The shared helpers in `packages/core/src/a2a/auth-policy.ts` decide what the deployment requires:
|
|
643
643
|
|
|
644
|
-
- `isA2AProductionRuntime()` returns `true` on Netlify, AWS Lambda, Cloudflare
|
|
644
|
+
- `isA2AProductionRuntime()` returns `true` on Netlify, AWS Lambda, Cloudflare Workers, Vercel, Render, Fly, and Cloud Run — even when `NODE_ENV` isn't `"production"`. Some serverless providers don't set `NODE_ENV` consistently, so the policy reads provider-specific flags too.
|
|
645
645
|
- `hasConfiguredA2ASecret()` returns `true` when `A2A_SECRET` is set.
|
|
646
646
|
- `shouldAdvertiseJwtA2AAuth()` is what the agent card uses to decide whether to publish a `jwtBearer` security scheme.
|
|
647
647
|
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Cloudflare"
|
|
3
|
-
description: "Deploy an agent-native app to Cloudflare
|
|
3
|
+
description: "Deploy an agent-native app to Cloudflare Workers with the cloudflare_module Nitro preset."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Cloudflare
|
|
7
7
|
|
|
8
|
-
## Cloudflare Pages {#cloudflare-pages}
|
|
9
|
-
|
|
10
|
-
```ts filename="vite.config.ts"
|
|
11
|
-
export default defineConfig({
|
|
12
|
-
plugins: [agentNative({ nitro: { preset: "cloudflare_pages" } })],
|
|
13
|
-
});
|
|
14
|
-
```
|
|
15
|
-
|
|
16
8
|
## Cloudflare Workers {#cloudflare-workers}
|
|
17
9
|
|
|
18
10
|
Use Nitro's native module output for a Cloudflare Worker. This keeps SSR
|
|
@@ -39,5 +31,5 @@ before deploying. A Worker filesystem is not a persistent application store.
|
|
|
39
31
|
## What's next
|
|
40
32
|
|
|
41
33
|
- [**Deployment**](/docs/deployment) — pick a persistent database and a preset before your first production deploy
|
|
42
|
-
- [**Workspace Deployment**](/docs/workspace-deployment) —
|
|
34
|
+
- [**Workspace Deployment**](/docs/workspace-deployment) — deploy every workspace app to one origin with Netlify or Vercel
|
|
43
35
|
- [**Node.js**](/docs/node-js), [**Docker**](/docs/docker), [**Vercel**](/docs/vercel), [**Netlify**](/docs/netlify), [**AWS Lambda**](/docs/aws-lambda), and [**Deno Deploy**](/docs/deno-deploy) — the other Nitro presets
|
|
@@ -44,7 +44,6 @@ See the target page for the provider command and runtime details:
|
|
|
44
44
|
- [**Docker**](/docs/docker)
|
|
45
45
|
- [**Vercel**](/docs/vercel)
|
|
46
46
|
- [**Netlify**](/docs/netlify)
|
|
47
|
-
- [**Cloudflare Pages**](/docs/cloudflare#cloudflare-pages)
|
|
48
47
|
- [**Cloudflare Workers**](/docs/cloudflare#cloudflare-workers)
|
|
49
48
|
- [**AWS Amplify**](/docs/aws-amplify)
|
|
50
49
|
- [**AWS Lambda**](/docs/aws-lambda)
|
|
@@ -84,7 +84,7 @@ contract stay the same.
|
|
|
84
84
|
|
|
85
85
|
<!-- i18n-copy-ignore: renderer-only Diagram attributes keep this shared UI block in clean mode. -->
|
|
86
86
|
|
|
87
|
-
<Diagram id="doc-block-deployment-targets" title="Supported deployment targets" summary="Agent-Native apps can deploy to Node.js, Docker, Vercel, Netlify, Cloudflare
|
|
87
|
+
<Diagram id="doc-block-deployment-targets" title="Supported deployment targets" summary="Agent-Native apps can deploy to Node.js, Docker, Vercel, Netlify, Cloudflare Workers, AWS Amplify, AWS Lambda, Deno Deploy, Azure Static Web Apps, Koyeb, and Render." frame="hide" renderMode="design">
|
|
88
88
|
|
|
89
89
|
```html
|
|
90
90
|
<!-- i18n-copy-ignore: deployment target logo markup is visual-only; labels are unchanged. -->
|
|
@@ -127,16 +127,21 @@ contract stay the same.
|
|
|
127
127
|
</a>
|
|
128
128
|
<a class="deployment-target" href="/docs/netlify">
|
|
129
129
|
<span class="deployment-target-mark">
|
|
130
|
-
|
|
130
|
+
<!-- i18n-copy-ignore: Netlify's light/dark logo pair is image markup; localized deployment pages have no logo grid. -->
|
|
131
|
+
<img
|
|
132
|
+
class="deployment-target-logo deployment-target-logo-light"
|
|
133
|
+
src="/integration-logos/netlify.svg"
|
|
134
|
+
alt=""
|
|
135
|
+
/>
|
|
136
|
+
<img
|
|
137
|
+
class="deployment-target-logo deployment-target-logo-dark"
|
|
138
|
+
src="/integration-logos/netlify-darkmode.svg"
|
|
139
|
+
alt=""
|
|
140
|
+
aria-hidden="true"
|
|
141
|
+
/>
|
|
131
142
|
</span>
|
|
132
143
|
<strong>Netlify</strong>
|
|
133
144
|
</a>
|
|
134
|
-
<a class="deployment-target" href="/docs/cloudflare#cloudflare-pages">
|
|
135
|
-
<span class="deployment-target-mark">
|
|
136
|
-
<img src="/integration-logos/cloudflare.svg" alt="" />
|
|
137
|
-
</span>
|
|
138
|
-
<strong>Cloudflare Pages</strong>
|
|
139
|
-
</a>
|
|
140
145
|
<a class="deployment-target" href="/docs/cloudflare#cloudflare-workers">
|
|
141
146
|
<span class="deployment-target-mark">
|
|
142
147
|
<img src="/integration-logos/cloudflare.svg" alt="" />
|
|
@@ -282,7 +287,7 @@ settings or production controls:
|
|
|
282
287
|
|
|
283
288
|
- [**Node.js**](/docs/node-js) - run the default Nitro server preset
|
|
284
289
|
- [**Docker**](/docs/docker) - package the Node.js server in a container
|
|
285
|
-
- [**Vercel**](/docs/vercel), [**Netlify**](/docs/netlify),
|
|
290
|
+
- [**Vercel**](/docs/vercel), [**Netlify**](/docs/netlify), and [**Cloudflare Workers**](/docs/cloudflare#cloudflare-workers) - configure hosted targets
|
|
286
291
|
- [**AWS Amplify**](/docs/aws-amplify) and [**AWS Lambda**](/docs/aws-lambda) - deploy Nitro's serverless output on AWS
|
|
287
292
|
- [**Deno Deploy**](/docs/deno-deploy) - deploy to the Deno runtime
|
|
288
293
|
- [**Azure Static Web Apps**](/docs/azure-static-web-apps), [**Koyeb**](/docs/koyeb), and [**Render**](/docs/render) - use additional Nitro providers
|
|
@@ -72,7 +72,7 @@ public app behavior, use the config paths above instead.
|
|
|
72
72
|
| `BETTER_AUTH_TRUSTED_ORIGINS` | Exact browser origins trusted by Better Auth, including configured host aliases. | A comma-separated list of absolute `http(s)` origins; wildcards are not accepted. |
|
|
73
73
|
| `APP_BASE_PATH` | Mounts an app under a path such as `/mail`. | Unset for a standalone app, or a slash-prefixed path. |
|
|
74
74
|
| `PORT` | Local Node/Nitro server port. | A decimal TCP port. |
|
|
75
|
-
| `NITRO_PRESET` | Build and deployment adapter. | A preset supported by the target host, such as `node`, `netlify`, `vercel`, or `
|
|
75
|
+
| `NITRO_PRESET` | Build and deployment adapter. | A preset supported by the target host, such as `node`, `netlify`, `vercel`, or `cloudflare_module`. |
|
|
76
76
|
| `BETTER_AUTH_SECRET` | Stable Better Auth session signing secret for standalone production apps. Workspace deploys can derive it from `A2A_SECRET`. | A fresh random value of at least 32 characters. |
|
|
77
77
|
| `OAUTH_STATE_SECRET` | Dedicated signing key for OAuth state envelopes. Falls back to `BETTER_AUTH_SECRET` when unset. | A fresh random value of at least 32 characters. |
|
|
78
78
|
| `A2A_SECRET` | Shared HMAC for trusted cross-app A2A calls and signed handoffs. | One shared random value across trusted apps. |
|
|
@@ -304,7 +304,7 @@ Brand colors, typography, spacing scales, and any shared component classes can l
|
|
|
304
304
|
|
|
305
305
|
## Deployment {#deployment}
|
|
306
306
|
|
|
307
|
-
You have two options: **unified deploy** (the default for workspaces) or per-app independent deploy. [Workspace Deployment — One Origin, Many Apps](/docs/workspace-deployment#workspace-deploy) covers the full command, per-preset details (
|
|
307
|
+
You have two options: **unified deploy** (the default for workspaces) or per-app independent deploy. [Workspace Deployment — One Origin, Many Apps](/docs/workspace-deployment#workspace-deploy) covers the full command, per-preset details (Netlify and Vercel), and a diagram of the shape; the tradeoff:
|
|
308
308
|
|
|
309
309
|
- **Unified deploy (recommended)** — `npx @agent-native/core@latest deploy` builds every app in the workspace and ships them behind a single origin, one path per app (`your-agents.com/mail/*`, `/calendar/*`, ...). Being on the same origin is where the real payoff lives: a shared login session (log into any app, every app is logged in), zero-config cross-app A2A (`@mail` tagging `@calendar` is a same-origin fetch — no CORS, no JWT signing between siblings), and one DNS record, cert, and CDN cache to manage.
|
|
310
310
|
- **Per-app independent deploy** — prefer each app on its own domain (`mail.company.com`, `calendar.company.com`)? Every app in the workspace is still an independent deployable — `cd apps/mail && pnpm build` behaves exactly like a standalone scaffold. Cross-app A2A then goes through the standard JWT-signed path with a shared `A2A_SECRET`. Cross-domain SSO between separately-deployed apps is handled by identity federation with Dispatch as the hub — see [Cross-App SSO](/docs/cross-app-sso); the unified single-origin deploy avoids needing it. For a self-hosted VPS or Docker Compose setup on one origin instead, see [Workspace Deployment — Self-hosted Workspace with Docker Compose](/docs/workspace-deployment#workspace-docker-compose).
|
package/docs/content/netlify.mdx
CHANGED
|
@@ -5,7 +5,7 @@ description: "Deploy an agent-native app to Netlify with the Netlify Nitro prese
|
|
|
5
5
|
|
|
6
6
|
# Netlify
|
|
7
7
|
|
|
8
|
-
The Nitro `netlify` preset works well and, in practice, has given us much faster cold starts
|
|
8
|
+
The Nitro `netlify` preset works well and, in practice, has given us much faster cold starts (~200ms TTFB) for templates that talk to external Postgres (Neon). For a minimal configuration outside the generated scaffold, set the preset in `vite.config.ts`:
|
|
9
9
|
|
|
10
10
|
```ts filename="vite.config.ts"
|
|
11
11
|
export default defineConfig({
|
|
@@ -640,12 +640,12 @@ Nothing here happens on a deployment that has not set it.
|
|
|
640
640
|
The deployment must also already satisfy four things, all of which a normal
|
|
641
641
|
production app does:
|
|
642
642
|
|
|
643
|
-
| Requirement | Why | How to check
|
|
644
|
-
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
645
|
-
| **Postgres on a publicly reachable host** | The gateway dials the database from its own network. PGlite, `localhost`, `*.internal` and bare IP addresses are refused before the connection string ever leaves your machine. | `DATABASE_URL` points at a managed Postgres such as Neon
|
|
646
|
-
| **`BUILDER_PRIVATE_KEY` set as a DEPLOY environment variable** | This authenticates the registration and decides which Builder organization owns the channel. | See the note below — this is the step people miss
|
|
647
|
-
| **A production deploy** | Deploy previews keep local sync, so a throwaway branch credential never leaves the machine and a busy repo does not mint one channel per pull request. | `CONTEXT=production` / `BRANCH=production`, or `VERCEL_ENV=production`
|
|
648
|
-
| **The platform identifies the deployment** | Registration is keyed on the app's public origin, so a process that is not actually the deployment must not claim it. | Netlify, Vercel, AWS Lambda, Cloud Run,
|
|
643
|
+
| Requirement | Why | How to check |
|
|
644
|
+
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
645
|
+
| **Postgres on a publicly reachable host** | The gateway dials the database from its own network. PGlite, `localhost`, `*.internal` and bare IP addresses are refused before the connection string ever leaves your machine. | `DATABASE_URL` points at a managed Postgres such as Neon |
|
|
646
|
+
| **`BUILDER_PRIVATE_KEY` set as a DEPLOY environment variable** | This authenticates the registration and decides which Builder organization owns the channel. | See the note below — this is the step people miss |
|
|
647
|
+
| **A production deploy** | Deploy previews keep local sync, so a throwaway branch credential never leaves the machine and a busy repo does not mint one channel per pull request. | `CONTEXT=production` / `BRANCH=production`, or `VERCEL_ENV=production` |
|
|
648
|
+
| **The platform identifies the deployment** | Registration is keyed on the app's public origin, so a process that is not actually the deployment must not claim it. | Netlify, Vercel, AWS Lambda, Cloud Run, and Render mark themselves. Cloudflare Workers do not, so set `AGENT_NATIVE_REALTIME_APP_URL` to the deployment's own origin. On a bare container or VM, set that same variable |
|
|
649
649
|
|
|
650
650
|
<Callout tone="warning">
|
|
651
651
|
|