@agent-native/core 0.92.10 → 0.92.11
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/core/CHANGELOG.md +23 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +181 -15
- package/corpus/core/src/agent/run-manager.ts +31 -4
- package/corpus/core/src/agent/run-store.ts +80 -0
- package/corpus/core/src/cli/design-connect.ts +433 -151
- package/corpus/core/src/cli/skills.ts +14 -0
- package/corpus/core/src/client/AssistantChat.tsx +25 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +40 -6
- package/corpus/core/src/client/agent-chat.ts +165 -1
- package/corpus/core/src/client/chat/index.ts +9 -1
- package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +38 -2
- package/corpus/core/src/client/index.ts +5 -0
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +18 -7
- package/corpus/core/src/collab/awareness-store.ts +23 -12
- package/corpus/core/src/collab/client.ts +16 -5
- package/corpus/core/src/collab/index.ts +4 -0
- package/corpus/core/src/collab/recent-edits.ts +65 -2
- package/corpus/core/src/index.browser.ts +1 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +98 -11
- package/corpus/core/src/server/builder-design-systems.ts +30 -4
- package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +1 -1
- package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +12 -6
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/create-recording.ts +2 -0
- package/corpus/templates/clips/actions/lib/create-recording-schema.ts +5 -3
- package/corpus/templates/clips/actions/request-transcript.ts +102 -33
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +59 -19
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +48 -4
- package/corpus/templates/clips/app/components/player/video-player.tsx +17 -12
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +70 -37
- package/corpus/templates/clips/app/routes/record.tsx +17 -4
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-popover-sits-closer-to-the-menu-bar.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-desktop-recording-optimization-progress-stays-visible-until-the-clip-opens.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-large-video-file-uploads-failing-before-their-resumabl.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-fixed-new-video-uploads-defaulting-to-private.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-long-recordings-now-get-enough-time-to-download-their-media-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-meeting-notes-no-longer-lowers-your-microphone-volume-for-ot.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-on-mobile-tapping-a-playing-clip-reveals-playback-controls-w.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-regenerate-any-clip-transcript-from-its-saved-recording-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-09-slack-previews-now-show-the-clip-length-alongside-its-descri.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +12 -2
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +8 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +8 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +5 -5
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +3 -0
- package/corpus/templates/clips/desktop/src/styles.css +6 -3
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +29 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +1 -1
- package/corpus/templates/clips/desktop/src-tauri/src/system_audio.rs +103 -21
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +117 -39
- package/corpus/templates/clips/server/lib/slack-unfurls.ts +20 -1
- package/corpus/templates/clips/server/lib/streaming-upload-mode.ts +10 -4
- package/corpus/templates/clips/shared/recording-core.ts +12 -0
- package/corpus/templates/content/AGENTS.md +7 -6
- package/corpus/templates/content/actions/_document-flush.ts +132 -17
- package/corpus/templates/content/actions/_notion-action-utils.ts +15 -0
- package/corpus/templates/content/actions/create-and-link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/link-notion-page.ts +2 -0
- package/corpus/templates/content/actions/pull-document.ts +5 -7
- package/corpus/templates/content/actions/pull-notion-page.ts +2 -0
- package/corpus/templates/content/actions/push-notion-page.ts +10 -0
- package/corpus/templates/content/actions/resolve-notion-sync-conflict.ts +2 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +88 -23
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +32 -2
- package/corpus/templates/content/app/hooks/use-notion.ts +6 -6
- package/corpus/templates/content/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/content/app/i18n-data.ts +18 -0
- package/corpus/templates/content/changelog/2026-07-09-notion-conflict-choices-and-version-restores-preserve-docume.md +6 -0
- package/corpus/templates/content/server/lib/notion-sync.ts +80 -64
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +29 -2
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +86 -0
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +57 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +11 -0
- package/corpus/templates/design/AGENTS.md +45 -10
- package/corpus/templates/design/actions/add-localhost-screens.ts +66 -13
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +45 -36
- package/corpus/templates/design/actions/apply-motion-edit.ts +25 -31
- package/corpus/templates/design/actions/apply-shader-fill.ts +29 -42
- package/corpus/templates/design/actions/detach-component-instance.ts +337 -0
- package/corpus/templates/design/actions/export-design-as-figma-svg.ts +219 -0
- package/corpus/templates/design/actions/generate-design.ts +79 -12
- package/corpus/templates/design/actions/generate-screens.ts +57 -12
- package/corpus/templates/design/actions/get-figma-styles.ts +115 -0
- package/corpus/templates/design/actions/go-to-main-component.ts +254 -0
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +4 -3
- package/corpus/templates/design/actions/import-design-source.ts +4 -31
- package/corpus/templates/design/actions/import-figma-clipboard.ts +134 -0
- package/corpus/templates/design/actions/import-figma-frame.ts +95 -0
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/design/actions/list-design-components.ts +104 -0
- package/corpus/templates/design/actions/list-figma-library-assets.ts +1 -24
- package/corpus/templates/design/actions/open-component-source.ts +2 -4
- package/corpus/templates/design/actions/present-design-variants.ts +412 -16
- package/corpus/templates/design/actions/preview-source-edit.ts +14 -1
- package/corpus/templates/design/actions/run-design-audit.ts +25 -3
- package/corpus/templates/design/actions/show-design-questions.ts +10 -0
- package/corpus/templates/design/actions/swap-component-instance.ts +544 -0
- package/corpus/templates/design/actions/take-design-screenshot.ts +45 -60
- package/corpus/templates/design/actions/write-local-file.ts +25 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +152 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1077 -58
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +5 -5
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +73 -21
- package/corpus/templates/design/app/components/design/EditPanel.tsx +16 -11
- package/corpus/templates/design/app/components/design/KeyboardShortcutsPanel.tsx +364 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +180 -53
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +0 -2
- package/corpus/templates/design/app/components/design/MotionDock.tsx +144 -21
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1152 -167
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +27 -5
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +23 -2
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +63 -49
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1293 -54
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +6 -1
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +23 -6
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +7 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +5 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +14 -2
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +37 -2
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open-guard.ts +25 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +19 -1
- package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +43 -5
- package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +27 -2
- package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +10 -1
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +19 -2
- package/corpus/templates/design/app/components/design/design-canvas/annotation-snapshot.ts +265 -0
- package/corpus/templates/design/app/components/design/design-canvas/annotation-submit.ts +16 -5
- package/corpus/templates/design/app/components/design/design-canvas/coordinate-transforms.ts +16 -2
- package/corpus/templates/design/app/components/design/design-canvas/embedded-frame.ts +7 -2
- package/corpus/templates/design/app/components/design/design-canvas/iframe-events.ts +3 -1
- package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +78 -8
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +451 -73
- package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +12 -4
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +398 -272
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +41 -7
- package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +16 -3
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +24 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +222 -4
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +171 -78
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +45 -5
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +299 -28
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +120 -150
- package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +53 -1
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +284 -117
- package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +81 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +19 -14
- package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +7 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +155 -0
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +268 -46
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +350 -31
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +233 -23
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +72 -2
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +51 -11
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +84 -11
- package/corpus/templates/design/app/components/design/inspector/index.ts +3 -0
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +552 -0
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +157 -0
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +53 -0
- package/corpus/templates/design/app/components/design/multi-screen/overview-layout.ts +184 -0
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +403 -26
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +20 -1
- package/corpus/templates/design/app/components/design/types.ts +33 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +59 -7
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +119 -17
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +275 -63
- package/corpus/templates/design/app/hooks/use-question-flow.ts +14 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +67 -10
- package/corpus/templates/design/app/i18n/zh-TW.ts +91 -1
- package/corpus/templates/design/app/i18n-data.ts +1217 -10
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +577 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +23 -0
- package/corpus/templates/design/app/lib/design-import.ts +24 -0
- package/corpus/templates/design/app/lib/figma-clipboard.ts +157 -0
- package/corpus/templates/design/app/lib/figma-svg-copy.ts +221 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +143 -30
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +15 -0
- package/corpus/templates/design/app/pages/design-editor/editor-session.ts +33 -0
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +38 -0
- package/corpus/templates/design/app/pages/design-editor/overview-annotation-context.ts +157 -0
- package/corpus/templates/design/app/pages/design-editor/overview-camera.ts +62 -6
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +245 -0
- package/corpus/templates/design/app/pages/design-editor/react-semantic-handoff.ts +586 -0
- package/corpus/templates/design/app/pages/design-editor/screen-auto-layout.ts +169 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +201 -1
- package/corpus/templates/design/changelog/2026-07-09-added-underline-strikethrough-and-text-case-uppercase-lowerc.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-annotate-now-draws-across-the-all-screens-canvas-without-swi.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-auto-layout-children-can-now-be-dragged-into-freeform-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-board-shapes-now-stay-visible-and-nest-correctly-across-the-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-component-source-navigation-now-opens-reliably-from-the-insp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-local-react-layer-moves-now-hand-off-exact-sour.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-cross-screen-moves-undo-and-redo-now-keep-both-screens-stabl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-detach-a-component-instance-into-plain-editable-eleme.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-dragging-layers-into-auto-layout-now-respects-ignore-auto-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-drawing-annotations-sent-to-the-agent-now-include-a-rendered.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-editor-sidebars-now-use-figma-matched-default-widths-for-a-r.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-empty-frames-and-rectangles-now-expose-full-auto-layout-cont.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-export-any-design-screen-as-a-real-vector-svg-for-figma-with.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-grid-auto-layout-now-uses-true-responsive-rows-and-columns-w.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-hidden-and-locked-screens-now-behave-consistently-between-la.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-image-fills-now-preserve-valid-urls-and-layered-fit-settings.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-import-figma-frames-as-pixel-accurate-design-screens-via-a-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspect-code-now-hides-internal-styling-metadata-and-wraps-l.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-inspector-blur-and-shadow-effects-now-preserve-other-effects.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-jump-to-a-components-other-instances-from-the-inspecto.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-keyboard-shortcuts-are-now-discoverable-in-a-figma-style-bot.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layer-selection-now-keeps-cmd-or-ctrl-toggles-and-shift-rang.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-layers-dropped-into-auto-layout-now-participate-correctly-in.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-live-edit-screens-now-enter-and-leave-full-view-withou.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-preview-urls-now-live-in-the-inspector-instead-of-taki.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-can-now-be-hidden-and-locked-from-layers-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-layers-now-keep-exact-source-provenance-and-supp.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-local-react-visual-editing-now-loads-reliably-and-shows-live.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-paste-from-figma-cmd-v-now-imports-exact-editable-nodes-when.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-pressing-escape-after-selecting-a-screen-now-reveals-page-pr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-right-click-overlapping-or-nested-objects-to-choose-the-exac.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-scale-edge-stretch-and-center-constraints-now-preserve-layer.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-rows-can-now-be-reordered-in-layers-with-matching-can.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-screen-selection-stays-responsive-in-designs-with-hundreds-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-shift-a-now-enables-auto-layout-on-a-selected-screen-with-fl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-09-swap-a-component-instance-for-another-from-the-libra.md +6 -0
- package/corpus/templates/design/changelog/2026-07-10-drawing-annotations-now-stay-available-to-retry-when-the.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +3 -6
- package/corpus/templates/design/e2e/helpers.ts +27 -6
- package/corpus/templates/design/server/lib/design-to-figma-svg.ts +1412 -0
- package/corpus/templates/design/server/lib/figma-clipboard-match.ts +196 -0
- package/corpus/templates/design/server/lib/figma-node-import.ts +311 -0
- package/corpus/templates/design/server/lib/figma-node-to-html.ts +1334 -0
- package/corpus/templates/design/server/lib/figma-paste-fallback.ts +64 -0
- package/corpus/templates/design/server/lib/playwright-runtime.ts +78 -0
- package/corpus/templates/design/server/plugins/db.ts +41 -0
- package/corpus/templates/design/server/source-workspace.ts +64 -0
- package/corpus/templates/design/shared/board-file.ts +13 -2
- package/corpus/templates/design/shared/canvas-math.ts +231 -33
- package/corpus/templates/design/shared/code-layer.ts +122 -8
- package/corpus/templates/design/shared/component-library.ts +161 -0
- package/corpus/templates/design/shared/db-conflict.ts +27 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +2 -1
- package/corpus/templates/design/shared/figma-url.ts +149 -0
- package/corpus/templates/design/shared/pen-path.ts +16 -7
- package/corpus/templates/design/shared/source-mode.ts +1 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +7 -19
- package/corpus/templates/plan/changelog/2026-07-09-canvas-panning-now-keeps-zoom-fixed-even-at-the-edges.md +6 -0
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +16 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +311 -70
- package/corpus/templates/slides/changelog/2026-07-09-fixed-the-slide-rail-going-permanently-stale-during-a-long-a.md +6 -0
- package/dist/agent/production-agent.d.ts +79 -6
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +161 -14
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +29 -5
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +46 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +61 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/cli/design-connect.d.ts +6 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +336 -139
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +14 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +19 -3
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +38 -18
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +60 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +122 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.d.ts +12 -0
- package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
- package/dist/client/extensions/EmbeddedExtension.js +36 -2
- package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +18 -6
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/collab/awareness-store.d.ts +5 -0
- package/dist/collab/awareness-store.d.ts.map +1 -1
- package/dist/collab/awareness-store.js +19 -12
- package/dist/collab/awareness-store.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +13 -5
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +1 -0
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +1 -0
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/recent-edits.d.ts +3 -1
- package/dist/collab/recent-edits.d.ts.map +1 -1
- package/dist/collab/recent-edits.js +57 -2
- package/dist/collab/recent-edits.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +87 -10
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +15 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -1
- package/dist/server/builder-design-systems.js +9 -4
- package/dist/server/builder-design-systems.js.map +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
package/corpus/core/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @agent-native/core
|
|
2
2
|
|
|
3
|
+
## 0.92.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4552931: Keep local React visual-edit previews hydrated by preserving Vite request metadata and response lengths through the bridge, and recover exact development source locations from React jsxDEV Fiber stacks.
|
|
8
|
+
- 4552931: Expose strict active-collaboration awareness reads so safety-critical sync flows can distinguish no open editor from presence-storage failures.
|
|
9
|
+
- 4552931: Add cancellation-safe `sendToAgentChatAndConfirm` delivery confirmation and its submit-result event contract so callers can preserve user work when a local chat message is rejected or times out, without allowing that timed-out message to arrive later.
|
|
10
|
+
- 4552931: Fix `.fig` and other binary files silently corrupting when uploaded through `index-design-system-with-builder`: `buildBuilderDesignSystemIndexFiles` always UTF-8-encoded file content even though `mimeTypeForBuilderDesignSystemFilename` already recognized `.fig` as binary (`application/octet-stream`). Add an optional per-file `encoding: "utf8" | "base64"` (defaults to `utf8`, unchanged for existing text-file callers) so binary files can be base64-encoded by the caller and decoded byte-exact here.
|
|
11
|
+
- 4552931: Prevent pre-seed collaborative editor updates from reaching autosave, and allow newer authoritative restores to reapply content previously emitted during mount while retaining stale-echo protection during active typing.
|
|
12
|
+
- 4552931: Prevent PR recap workflows from publishing screenshots of failed recap pages, and report SSR render failures through configured error monitoring.
|
|
13
|
+
- 4552931: Fix long agent-chat turns dying with a Netlify "508 Loop Detected" error after several server-driven continuation chunks: nested self-dispatch chains now break proactively before the platform's undocumented loop-protection limit, and a 508 that does occur is classified distinctly and deferred to the existing unclaimed-run sweep for recovery instead of failing the turn outright.
|
|
14
|
+
- 4552931: Recover background chat turns whose continuation handoff dispatch failed instead of failing them immediately: the pre-inserted successor run is left claimable so the unclaimed-run sweep can redispatch it (and the client poll defers to that sweep within a bound), backed by a backstop that still fails loud if the handoff never lands.
|
|
15
|
+
|
|
16
|
+
Operational note — terminal-reason change: when a continuation handoff exhausts its dispatch retry budget but the successor row exists, the run's `terminal_reason` is now `background_continuation_dispatch_deferred` (recoverable, awaiting sweep redispatch) instead of `background_continuation_dispatch_failed`. The old `background_continuation_dispatch_failed` reason is still emitted, but now only in the narrower case where the successor row itself could not be pre-inserted. Any dashboards, alerts, or audit queries matching `background_continuation_dispatch_failed` should add `background_continuation_dispatch_deferred` to keep covering this failure class.
|
|
17
|
+
|
|
18
|
+
- 4552931: Fix an awareness "storm" in `useCollaborativeDoc`: the shared collab connection's fast awareness-push path re-broadcast a client's own (unchanged) presence state whenever ANY remote participant's awareness changed, not just when the local user actually moved their cursor or updated their presence. With several people collaborating on the same document, every peer's cursor move caused every other connected client to also re-POST its own state, multiplying awareness traffic roughly quadratically with participant count. The fast-push listener now only fires on locally-originated awareness changes (`origin === "local"`), matching the equivalent guard already present in `usePresence`.
|
|
19
|
+
|
|
20
|
+
Also add a defensive size cap to the collab `recentEdits` ring (`appendRecentEdit`): descriptor strings (`quote`, `selector`, path entries) and the edit `label` are now truncated to 500 characters. The ring was already bounded in length, but an app forgetting to trim its own excerpt before publishing (e.g. passing a whole paragraph or document as `quote`) could otherwise push an oversized payload through the awareness fast-path broadcast and into the `_collab_awareness` SQL mirror.
|
|
21
|
+
|
|
22
|
+
- 4552931: Give the Design localhost bridge a per-boot `bridgeInstanceId`, exposed on `/health`, the `/live-edit-bridge` registration response, and the `/live-edit` "unknown bridge key" 409 (now carrying a machine-readable `code: "unknown-bridge-key"` and the echoed `bridgeKey`). This lets a client distinguish a bridge process restart — which silently empties the in-memory live-edit bridge script registry — from a genuine registration bug, instead of guessing from free-text error strings.
|
|
23
|
+
- 4552931: Fix a recurring `DataCloneError` console error when any embedded extension (Design's Tools/Extensions panel, or any other app using `EmbeddedExtension`) loads or its slot context updates. Slot contexts commonly carry live callback functions the host uses internally; `postMessage`'s structured clone algorithm throws on function-valued properties, so the context update silently never reached the extension iframe. Sanitize the context through a JSON round-trip (dropping functions) before posting it.
|
|
24
|
+
- 4552931: Harden local Design source writes with SHA-256 version checks, per-file serialization, atomic replacement, and repeated symlink containment validation.
|
|
25
|
+
|
|
3
26
|
## 0.92.10
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/corpus/core/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.92.
|
|
3
|
+
"version": "0.92.11",
|
|
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": {
|
|
@@ -5038,6 +5038,70 @@ export function resolveContinuationDispatchBudget(opts: {
|
|
|
5038
5038
|
};
|
|
5039
5039
|
}
|
|
5040
5040
|
|
|
5041
|
+
/**
|
|
5042
|
+
* True when a `fireInternalDispatch` failure is Netlify's Functions platform
|
|
5043
|
+
* loop-protection response (`HTTP 508 Loop Detected`), matched against the
|
|
5044
|
+
* exact message `self-dispatch.ts`'s `dispatchResponseError` constructs
|
|
5045
|
+
* (`Self-dispatch to ${path} returned HTTP ${res.status} ${res.statusText}...`).
|
|
5046
|
+
* Matches on the status code alone (not the reason phrase text) so it is
|
|
5047
|
+
* robust to any wording Netlify's edge puts in `statusText`.
|
|
5048
|
+
*
|
|
5049
|
+
* VERIFIED: production `agent_runs` diagnostics show exactly this failure mode
|
|
5050
|
+
* — 8 successful `chain_dispatch_sent` self-dispatches followed by a 9th/10th
|
|
5051
|
+
* that dies with `HTTP 508 Loop Detected`, terminal reason
|
|
5052
|
+
* `background_continuation_dispatch_failed`. UNVERIFIED (Netlify does not
|
|
5053
|
+
* document the mechanism — checked the Functions overview, Functions API
|
|
5054
|
+
* reference, Background Functions overview, Status Codes reference, and
|
|
5055
|
+
* Request Chain troubleshooting docs, none mention it): the ONLY public
|
|
5056
|
+
* confirmation is a Netlify staff forum reply — "we prevent multiple
|
|
5057
|
+
* executions after one-another as that's a 'loop' ... I believe we enforce
|
|
5058
|
+
* this after 9 or 10 self-invocations"
|
|
5059
|
+
* (https://answers.netlify.com/t/self-invoke-background-function-via-post-requests/146012)
|
|
5060
|
+
* — which also confirms Background Functions do NOT escape the limit (the
|
|
5061
|
+
* reporter's case was already a `-background` function self-invoking). See
|
|
5062
|
+
* `MAX_NESTED_SELF_DISPATCH_DEPTH` for how this classification is used.
|
|
5063
|
+
*/
|
|
5064
|
+
export function isLoopProtectionDispatchError(err: unknown): boolean {
|
|
5065
|
+
if (!(err instanceof Error)) return false;
|
|
5066
|
+
return /\bHTTP\s*508\b/i.test(err.message);
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
/**
|
|
5070
|
+
* Conservative safety margin on NESTED self-dispatch chaining — a
|
|
5071
|
+
* continuation dispatched directly from within the live invocation that is
|
|
5072
|
+
* about to finish, as opposed to being picked up later by the
|
|
5073
|
+
* unclaimed-background-run sweep (`agent-chat-plugin.ts`), which fires its
|
|
5074
|
+
* redispatch from an unrelated, timer-driven invocation rather than from
|
|
5075
|
+
* inside the chain's own execution.
|
|
5076
|
+
*
|
|
5077
|
+
* Netlify's loop-protection ceiling is undocumented and platform-reported
|
|
5078
|
+
* only approximately ("I believe... 9 or 10" — see
|
|
5079
|
+
* `isLoopProtectionDispatchError`), so hard-coding that exact number here
|
|
5080
|
+
* would be pinning behavior to a number Netlify itself won't commit to, and
|
|
5081
|
+
* production evidence shows it can trigger by the 9th self-dispatch. Rather
|
|
5082
|
+
* than only reacting after triggering that undocumented limit,
|
|
5083
|
+
* `chainServerDrivenContinuation` proactively hands a chunk to the sweep once
|
|
5084
|
+
* `backgroundContinuationCount` (nested hops since the last chain break)
|
|
5085
|
+
* reaches this value — comfortably below the observed ~9-10 failure point —
|
|
5086
|
+
* instead of attempting another nested dispatch. This is the SAME deferred-
|
|
5087
|
+
* recovery path already used when a dispatch fails outright: the row is left
|
|
5088
|
+
* `status='running', dispatch_mode='background'` for the sweep to redispatch,
|
|
5089
|
+
* never silently dropped.
|
|
5090
|
+
*
|
|
5091
|
+
* The sweep's redispatch marker intentionally omits `continuationCount` (see
|
|
5092
|
+
* the "Unclaimed background-run sweep" in `agent-chat-plugin.ts`), so a
|
|
5093
|
+
* sweep-recovered chunk's own `backgroundContinuationCount` resets to 0 —
|
|
5094
|
+
* this constant therefore bounds each NESTED segment between chain breaks,
|
|
5095
|
+
* not the whole turn. The TRUE ceiling on total turn length is unaffected by
|
|
5096
|
+
* that reset: it is the durable per-turn SQL ledger (`countRunsForTurn`,
|
|
5097
|
+
* checked above in this function) plus `MAX_BACKGROUND_RUN_CONTINUATIONS` —
|
|
5098
|
+
* both counted independently of this in-marker value — so a legitimately
|
|
5099
|
+
* long turn keeps making progress in bounded nested segments, each recovered
|
|
5100
|
+
* by the sweep, until it genuinely exhausts the intentional overall budget
|
|
5101
|
+
* and fails loud with `turn_continuation_budget_exhausted`.
|
|
5102
|
+
*/
|
|
5103
|
+
export const MAX_NESTED_SELF_DISPATCH_DEPTH = 6;
|
|
5104
|
+
|
|
5041
5105
|
/**
|
|
5042
5106
|
* Server-driven continuation handoff for a chunk that hit its soft-timeout
|
|
5043
5107
|
* boundary still unfinished: mint the next chunk's runId, PRE-INSERT its run
|
|
@@ -5046,12 +5110,26 @@ export function resolveContinuationDispatchBudget(opts: {
|
|
|
5046
5110
|
* `_process-run` self-dispatch carrying ids only (the body is persisted on
|
|
5047
5111
|
* the row as `dispatch_payload`), fully AWAIT the dispatch acknowledgment
|
|
5048
5112
|
* with retries, and mark this chunk terminal only after the handoff landed.
|
|
5049
|
-
* On failure
|
|
5050
|
-
*
|
|
5051
|
-
*
|
|
5052
|
-
* the
|
|
5053
|
-
*
|
|
5054
|
-
*
|
|
5113
|
+
* On failure this chunk always goes terminal loudly (diag stage + terminal
|
|
5114
|
+
* reason recorded — never a silent loss), but the successor row's fate
|
|
5115
|
+
* depends on WHY the dispatch failed:
|
|
5116
|
+
* - the pre-insert itself failed (no successor row exists) — nothing for a
|
|
5117
|
+
* sweep to find, so this is unrecoverable: fail loud immediately with
|
|
5118
|
+
* `background_continuation_dispatch_failed`.
|
|
5119
|
+
* - every dispatch attempt failed but the successor row DOES exist with its
|
|
5120
|
+
* `dispatch_payload` intact — this is RECOVERABLE: the row is left alone
|
|
5121
|
+
* (`status='running', dispatch_mode='background'`) instead of being
|
|
5122
|
+
* errored, so the unclaimed-background-run sweep in `agent-chat-plugin.ts`
|
|
5123
|
+
* can redispatch it once `UNCLAIMED_BACKGROUND_RUN_GRACE_MS` has passed.
|
|
5124
|
+
* This chunk is flipped to errored with the distinct, honest
|
|
5125
|
+
* `background_continuation_dispatch_deferred` reason — the TURN is
|
|
5126
|
+
* deferred, not dead. The sweep still bounds this by
|
|
5127
|
+
* `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS`: past that it falls back
|
|
5128
|
+
* to the existing loud reap, so a genuinely dead handoff never hangs
|
|
5129
|
+
* silently forever. (For a FOREGROUND self-chain the client additionally
|
|
5130
|
+
* still receives the terminal `auto_continue` event — run-manager emits
|
|
5131
|
+
* it after this callback — so the existing client re-POST path is a
|
|
5132
|
+
* second, faster fallback alongside the sweep.)
|
|
5055
5133
|
*
|
|
5056
5134
|
* `chainViaDurableBackground` selects the dispatch target:
|
|
5057
5135
|
* - true → the durable-background worker chain (unchanged behavior): the
|
|
@@ -5244,9 +5322,23 @@ export async function chainServerDrivenContinuation(opts: {
|
|
|
5244
5322
|
};
|
|
5245
5323
|
let dispatched = false;
|
|
5246
5324
|
let lastDispatchErr: unknown;
|
|
5325
|
+
// Proactive nested-chain safety margin — see `MAX_NESTED_SELF_DISPATCH_DEPTH`.
|
|
5326
|
+
// Skip the nested dispatch attempt entirely once this segment's hop count
|
|
5327
|
+
// reaches the cap; a nested attempt at this depth is expected to trip
|
|
5328
|
+
// Netlify's loop protection, so there is nothing to gain by trying it and
|
|
5329
|
+
// burning this worker's remaining wall clock on a doomed call. Falls
|
|
5330
|
+
// straight into the same deferred-recovery path below as an exhausted
|
|
5331
|
+
// retry budget.
|
|
5332
|
+
const nestedDepthExceeded =
|
|
5333
|
+
opts.backgroundContinuationCount >= MAX_NESTED_SELF_DISPATCH_DEPTH;
|
|
5334
|
+
if (nestedDepthExceeded) {
|
|
5335
|
+
lastDispatchErr = new Error(
|
|
5336
|
+
`proactive nested-dispatch depth cap reached (backgroundContinuationCount=${opts.backgroundContinuationCount} >= MAX_NESTED_SELF_DISPATCH_DEPTH=${MAX_NESTED_SELF_DISPATCH_DEPTH}) — deferring to the unclaimed-background-run sweep instead of risking Netlify loop protection`,
|
|
5337
|
+
);
|
|
5338
|
+
}
|
|
5247
5339
|
for (
|
|
5248
5340
|
let attempt = 0;
|
|
5249
|
-
attempt < maxDispatchAttempts && !dispatched;
|
|
5341
|
+
!nestedDepthExceeded && attempt < maxDispatchAttempts && !dispatched;
|
|
5250
5342
|
attempt++
|
|
5251
5343
|
) {
|
|
5252
5344
|
try {
|
|
@@ -5313,25 +5405,99 @@ export async function chainServerDrivenContinuation(opts: {
|
|
|
5313
5405
|
`[agent-chat] background continuation dispatch attempt ${attempt + 1} failed:`,
|
|
5314
5406
|
dispatchErr instanceof Error ? dispatchErr.message : dispatchErr,
|
|
5315
5407
|
);
|
|
5408
|
+
// Netlify loop protection (see `isLoopProtectionDispatchError`) is a
|
|
5409
|
+
// property of this same live, nested call chain — retrying the exact
|
|
5410
|
+
// same nested self-dispatch within the next few seconds will not
|
|
5411
|
+
// change that, so further attempts are a guaranteed-doomed use of
|
|
5412
|
+
// this worker's remaining wall clock. Stop immediately (instead of
|
|
5413
|
+
// burning the full `maxDispatchAttempts` budget) and fall into the
|
|
5414
|
+
// same deferred-recovery path below, which hands the successor to the
|
|
5415
|
+
// sweep — a genuinely different, non-nested invocation.
|
|
5416
|
+
if (isLoopProtectionDispatchError(dispatchErr)) {
|
|
5417
|
+
break;
|
|
5418
|
+
}
|
|
5316
5419
|
}
|
|
5317
5420
|
}
|
|
5318
5421
|
if (!dispatched) {
|
|
5319
|
-
// The pre-inserted successor row would otherwise sit unclaimed until
|
|
5320
|
-
// the sweep reaps it — error it now so the failure is immediate and
|
|
5321
|
-
// truthful.
|
|
5322
5422
|
if (nextRowInserted) {
|
|
5323
|
-
|
|
5324
|
-
|
|
5423
|
+
// Classify WHY this handoff is being deferred — distinct, greppable
|
|
5424
|
+
// tags so production diagnostics (which is all that is readable from
|
|
5425
|
+
// a background worker) can tell "we proactively avoided Netlify loop
|
|
5426
|
+
// protection", "we hit loop protection and stopped retrying", and "a
|
|
5427
|
+
// generic transient dispatch failure exhausted its retry budget"
|
|
5428
|
+
// apart, instead of lumping every deferred handoff into one bucket.
|
|
5429
|
+
const deferralClassification = nestedDepthExceeded
|
|
5430
|
+
? "proactive_depth_cap"
|
|
5431
|
+
: isLoopProtectionDispatchError(lastDispatchErr)
|
|
5432
|
+
? "netlify_loop_protection"
|
|
5433
|
+
: "dispatch_budget_exhausted";
|
|
5434
|
+
// RECOVERABLE: the successor row already exists in SQL with its
|
|
5435
|
+
// rehydration payload (`dispatch_payload`) intact and is still
|
|
5436
|
+
// `status='running', dispatch_mode='background'` — exactly the state
|
|
5437
|
+
// the unclaimed-background-run sweep (`agent-chat-plugin.ts`) already
|
|
5438
|
+
// scans for. Do NOT error it here: leave it alone so the sweep can
|
|
5439
|
+
// redispatch it once `UNCLAIMED_BACKGROUND_RUN_GRACE_MS` has passed,
|
|
5440
|
+
// bounded by `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` before it
|
|
5441
|
+
// falls back to the existing loud reap
|
|
5442
|
+
// (`background_worker_never_started`) — so this is deferred, never a
|
|
5443
|
+
// silent hang. This chunk still goes terminal (its own soft-timeout
|
|
5444
|
+
// budget is genuinely spent), but with an honest reason: the TURN is
|
|
5445
|
+
// not dead, only this handoff attempt was.
|
|
5446
|
+
//
|
|
5447
|
+
// THREE-SITE INVARIANT (keep in lockstep — a future reader must not
|
|
5448
|
+
// "fix" one without the others): this deferral only survives because
|
|
5449
|
+
// the ~1s client poll in `getActiveRunForThreadAsync`
|
|
5450
|
+
// (run-manager.ts) ALSO skips `reapUnclaimedBackgroundRun` while the
|
|
5451
|
+
// successor is within `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS`
|
|
5452
|
+
// (via `shouldRedispatchUnclaimedBackgroundRun`). Without that guard a
|
|
5453
|
+
// connected client would reap this row at the 25s grace, before the
|
|
5454
|
+
// ~2-min sweep, defeating the deferral. The sweep in agent-chat-plugin
|
|
5455
|
+
// is the recovery actor; run-manager is the guard; this is the
|
|
5456
|
+
// producer.
|
|
5457
|
+
await d
|
|
5458
|
+
.recordRunDiagnostic(
|
|
5459
|
+
nextRunId,
|
|
5460
|
+
RUN_DIAG_STAGE.workerThrew,
|
|
5461
|
+
`chain_dispatch_deferred[${deferralClassification}]: dispatch budget exhausted (${maxDispatchAttempts} attempts) awaiting unclaimed-run sweep redispatch; ${
|
|
5462
|
+
lastDispatchErr instanceof Error
|
|
5463
|
+
? lastDispatchErr.message
|
|
5464
|
+
: String(lastDispatchErr)
|
|
5465
|
+
}`,
|
|
5466
|
+
)
|
|
5467
|
+
.catch(() => {});
|
|
5468
|
+
await d
|
|
5469
|
+
.recordRunDiagnostic(
|
|
5470
|
+
runId,
|
|
5471
|
+
RUN_DIAG_STAGE.workerThrew,
|
|
5472
|
+
`chain_dispatch_deferred[${deferralClassification}] nextRunId=${nextRunId} ${
|
|
5473
|
+
lastDispatchErr instanceof Error
|
|
5474
|
+
? lastDispatchErr.message
|
|
5475
|
+
: String(lastDispatchErr)
|
|
5476
|
+
}`,
|
|
5477
|
+
)
|
|
5478
|
+
.catch(() => {});
|
|
5479
|
+
console.error(
|
|
5480
|
+
`[agent-chat] background continuation dispatch deferred (${deferralClassification}); leaving the pre-inserted successor for the unclaimed-run sweep to redispatch:`,
|
|
5481
|
+
lastDispatchErr instanceof Error
|
|
5482
|
+
? lastDispatchErr.message
|
|
5483
|
+
: lastDispatchErr,
|
|
5484
|
+
);
|
|
5485
|
+
const statusUpdated = await d
|
|
5486
|
+
.updateRunStatusIfRunning(runId, "errored")
|
|
5325
5487
|
.catch(() => false);
|
|
5326
|
-
if (
|
|
5488
|
+
if (statusUpdated) {
|
|
5327
5489
|
await d
|
|
5328
5490
|
.setRunTerminalReason(
|
|
5329
|
-
|
|
5330
|
-
"
|
|
5491
|
+
runId,
|
|
5492
|
+
"background_continuation_dispatch_deferred",
|
|
5331
5493
|
)
|
|
5332
5494
|
.catch(() => {});
|
|
5333
5495
|
}
|
|
5496
|
+
return;
|
|
5334
5497
|
}
|
|
5498
|
+
// No successor row exists at all (the pre-insert itself failed) — there
|
|
5499
|
+
// is nothing for the sweep to find and recover, so this really is
|
|
5500
|
+
// fatal. Fail loud immediately via the shared catch block below.
|
|
5335
5501
|
throw lastDispatchErr instanceof Error
|
|
5336
5502
|
? lastDispatchErr
|
|
5337
5503
|
: new Error(String(lastDispatchErr));
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
bumpRunProgress,
|
|
17
17
|
reapIfStale,
|
|
18
18
|
reapUnclaimedBackgroundRun,
|
|
19
|
+
shouldRedispatchUnclaimedBackgroundRun,
|
|
19
20
|
reconcileTerminalRunFromEvents,
|
|
20
21
|
ensureTerminalRunEvent,
|
|
21
22
|
getLastTerminalRunEvent,
|
|
@@ -1469,10 +1470,36 @@ export async function getActiveRunForThreadAsync(threadId: string): Promise<{
|
|
|
1469
1470
|
// past the tight grace means the bg-fn worker never started — a silent
|
|
1470
1471
|
// async-worker death that the 202-ack inline fallback can't catch. Reap it
|
|
1471
1472
|
// early and recoverably (background_worker_never_started) so the run no
|
|
1472
|
-
// longer hangs for the full 90s window
|
|
1473
|
-
//
|
|
1474
|
-
//
|
|
1475
|
-
|
|
1473
|
+
// longer hangs for the full 90s window. Only fires when there is provably
|
|
1474
|
+
// no live worker; a claimed/heartbeating run is left alone by the
|
|
1475
|
+
// conditional SQL.
|
|
1476
|
+
//
|
|
1477
|
+
// REDISPATCH-BOUND GUARD (must be kept in lockstep with the "Unclaimed
|
|
1478
|
+
// background-run sweep" in agent-chat-plugin.ts and with
|
|
1479
|
+
// chainServerDrivenContinuation's deferral in production-agent.ts — do NOT
|
|
1480
|
+
// remove this guard without reading those two sites):
|
|
1481
|
+
// `chainServerDrivenContinuation` now DEFERS a dispatch-failed successor
|
|
1482
|
+
// instead of erroring it — it leaves the row status='running',
|
|
1483
|
+
// dispatch_mode='background' with its dispatch_payload intact so the sweep
|
|
1484
|
+
// can silently redispatch it. This client poll runs every ~1s while a
|
|
1485
|
+
// client is connected, so without this guard it would reap that deferred
|
|
1486
|
+
// successor at the 25s unclaimed grace — long before the ~2-min sweep —
|
|
1487
|
+
// converting the intended SILENT server-side recovery into a user-visible
|
|
1488
|
+
// `background_worker_never_started` manual-retry error (that terminal
|
|
1489
|
+
// reason does NOT auto-continue in the client follow loop; only `stale_run`
|
|
1490
|
+
// does). While the successor is still inside its redispatch bound we skip
|
|
1491
|
+
// this reap and leave it for the sweep. The outer backstops still bound it:
|
|
1492
|
+
// `reapIfStale` below reaps a heartbeat-stale background row at 90s
|
|
1493
|
+
// (BACKGROUND_RUN_STALE_MS) to the recoverable `stale_run` — which the
|
|
1494
|
+
// follow loop AUTO-continues — and once the redispatch bound is exceeded
|
|
1495
|
+
// this reap fires loudly as before. So recovery stays automatic in the
|
|
1496
|
+
// common case and loud failure is only moved later, never removed.
|
|
1497
|
+
if (
|
|
1498
|
+
sqlRun.dispatchMode === "background" &&
|
|
1499
|
+
!shouldRedispatchUnclaimedBackgroundRun({
|
|
1500
|
+
startedAt: sqlRun.startedAt,
|
|
1501
|
+
})
|
|
1502
|
+
) {
|
|
1476
1503
|
const recovered = await reapUnclaimedBackgroundRun(sqlRun.id).catch(
|
|
1477
1504
|
() => false,
|
|
1478
1505
|
);
|
|
@@ -99,6 +99,21 @@ export const CLAIMED_BACKGROUND_WORKER_FAILED_ERROR_EVENT = {
|
|
|
99
99
|
*/
|
|
100
100
|
export const UNCLAIMED_BACKGROUND_RUN_GRACE_MS = 25_000;
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Backstop ceiling — measured from the row's ORIGINAL `started_at`, which never
|
|
104
|
+
* changes — after which the unclaimed-background-run sweep stops attempting to
|
|
105
|
+
* redispatch a lost handoff and instead reaps it via `reapUnclaimedBackgroundRun`
|
|
106
|
+
* (loud, attributable `errored`). This is what keeps redispatch recoverable
|
|
107
|
+
* WITHOUT becoming a silent hang: a handoff that cannot be delivered within this
|
|
108
|
+
* window (a genuinely dead platform, not a transient blip) still fails loudly,
|
|
109
|
+
* it just gets a few sweep-cycle chances first. 5 minutes comfortably allows
|
|
110
|
+
* multiple 2-minute sweep ticks (see `agent-chat-plugin.ts`'s
|
|
111
|
+
* "Unclaimed background-run sweep") while staying well inside both the 40s
|
|
112
|
+
* foreground chunk clamp and the ~13min background soft-timeout ceiling that
|
|
113
|
+
* bound how long a real user turn is worth waiting on before failing loud.
|
|
114
|
+
*/
|
|
115
|
+
export const UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS = 5 * 60_000;
|
|
116
|
+
|
|
102
117
|
async function ensureRunTables(): Promise<void> {
|
|
103
118
|
if (!_initPromise) {
|
|
104
119
|
_initPromise = (async () => {
|
|
@@ -648,6 +663,71 @@ export async function listUnclaimedBackgroundRunIds(): Promise<string[]> {
|
|
|
648
663
|
return ids;
|
|
649
664
|
}
|
|
650
665
|
|
|
666
|
+
/** A row returned by `listUnclaimedBackgroundRunRows`. */
|
|
667
|
+
export interface UnclaimedBackgroundRunRow {
|
|
668
|
+
id: string;
|
|
669
|
+
/** The row's ORIGINAL `started_at` (never bumped by heartbeats), so a
|
|
670
|
+
* caller can measure total elapsed time since the handoff was first
|
|
671
|
+
* pre-inserted — independent of any liveness bump a redispatch attempt
|
|
672
|
+
* makes along the way. */
|
|
673
|
+
startedAt: number;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Same eligibility as `listUnclaimedBackgroundRunIds`, but also returns each
|
|
678
|
+
* row's original `started_at` so a caller can bound total redispatch time
|
|
679
|
+
* (see `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS`) independent of the
|
|
680
|
+
* liveness bumps a redispatch attempt makes along the way. Used by the
|
|
681
|
+
* unclaimed-background-run sweep's redispatch pass; `listUnclaimedBackgroundRunIds`
|
|
682
|
+
* is kept as the simpler, pre-existing surface for callers that only need ids.
|
|
683
|
+
*/
|
|
684
|
+
export async function listUnclaimedBackgroundRunRows(): Promise<
|
|
685
|
+
UnclaimedBackgroundRunRow[]
|
|
686
|
+
> {
|
|
687
|
+
await ensureRunTables();
|
|
688
|
+
const client = getDbExec();
|
|
689
|
+
const { rows } = await client.execute({
|
|
690
|
+
// CAST keeps the ms-epoch param 64-bit on Postgres (see
|
|
691
|
+
// backgroundAwareStaleCutoffSql for the int4-inference failure mode).
|
|
692
|
+
sql: `SELECT id, started_at FROM agent_runs
|
|
693
|
+
WHERE status = 'running'
|
|
694
|
+
AND dispatch_mode = 'background'
|
|
695
|
+
AND COALESCE(heartbeat_at, started_at) < (CAST(? AS BIGINT) - ${UNCLAIMED_BACKGROUND_RUN_GRACE_MS})`,
|
|
696
|
+
args: [Date.now()],
|
|
697
|
+
});
|
|
698
|
+
const result: UnclaimedBackgroundRunRow[] = [];
|
|
699
|
+
for (const row of rows ?? []) {
|
|
700
|
+
const id = (row as { id?: unknown }).id;
|
|
701
|
+
const startedAt = (row as { started_at?: unknown }).started_at;
|
|
702
|
+
if (typeof id === "string" && id) {
|
|
703
|
+
result.push({
|
|
704
|
+
id,
|
|
705
|
+
startedAt:
|
|
706
|
+
typeof startedAt === "number" ? startedAt : Number(startedAt) || 0,
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return result;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Pure decision for the unclaimed-background-run sweep: should THIS row get
|
|
715
|
+
* another redispatch attempt, or has it exceeded
|
|
716
|
+
* `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` and must fall back to the
|
|
717
|
+
* loud reap (`reapUnclaimedBackgroundRun`)? Measured from the row's ORIGINAL
|
|
718
|
+
* `started_at` (never bumped by a redispatch's heartbeat write), so this is
|
|
719
|
+
* the total-elapsed-time backstop that keeps recovery bounded — a handoff
|
|
720
|
+
* that cannot be delivered within the window is not spinning forever, it
|
|
721
|
+
* fails loud. Exported as a pure function (no DB access) so the bound is unit
|
|
722
|
+
* -testable independent of the sweep's setInterval wiring.
|
|
723
|
+
*/
|
|
724
|
+
export function shouldRedispatchUnclaimedBackgroundRun(
|
|
725
|
+
row: { startedAt: number },
|
|
726
|
+
now: number = Date.now(),
|
|
727
|
+
): boolean {
|
|
728
|
+
return now - row.startedAt < UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS;
|
|
729
|
+
}
|
|
730
|
+
|
|
651
731
|
/**
|
|
652
732
|
* Count how many runs (chunks) a logical turn has consumed so far. This is the
|
|
653
733
|
* durable per-turn recovery ledger: unlike the in-marker `continuationCount`
|