@agent-native/core 0.149.2 → 0.149.3
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/analytics/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/analytics/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/analytics/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/analytics/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/analytics/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +4 -2
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/analytics/AGENTS.md +25 -32
- package/corpus/templates/analytics/app/global.css +1 -1
- package/corpus/templates/analytics/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
- package/corpus/templates/assets/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/assets/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/assets/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/assets/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/assets/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +4 -2
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/assets/AGENTS.md +6 -9
- package/corpus/templates/assets/app/global.css +1 -1
- package/corpus/templates/assets/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
- package/corpus/templates/brain/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/brain/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/brain/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/brain/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/brain/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/brain/AGENTS.md +5 -12
- package/corpus/templates/brain/app/global.css +1 -1
- package/corpus/templates/brain/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
- package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/calendar/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/calendar/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/calendar/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/calendar/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/calendar/AGENTS.md +8 -9
- package/corpus/templates/chat/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/chat/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/chat/AGENTS.md +32 -80
- package/corpus/templates/clips/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/clips/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/clips/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/clips/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/clips/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/clips/AGENTS.md +25 -31
- package/corpus/templates/content/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/content/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/content/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/content/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/content/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +4 -2
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/content/AGENTS.md +5 -9
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/crm/AGENTS.md +7 -11
- package/corpus/templates/crm/app/global.css +1 -1
- package/corpus/templates/crm/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
- package/corpus/templates/design/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/design/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/design/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/design/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/design/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +4 -2
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +70 -3
- package/corpus/templates/design/AGENTS.md +13 -21
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +12 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +19 -2
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +115 -7
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +82 -7
- package/corpus/templates/design/app/components/design/design-trace.ts +120 -0
- package/corpus/templates/design/app/components/design/dnd-debug.ts +2 -1
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +40 -26
- package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +4 -1
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +12 -3
- package/corpus/templates/design/app/components/design/multi-screen/screen-content-cache.ts +4 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +7 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -2
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -2
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +1 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +5 -5
- package/corpus/templates/design/app/pages/DesignSystems.tsx +3 -2
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +100 -13
- package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/data-operations.ts +14 -0
- package/corpus/templates/design/changelog/2026-08-10-marquee-selecting-layers-far-down-a-tall-screen-now-selects-.md +6 -0
- package/corpus/templates/design/changelog/2026-08-10-the-frame-tool-draws-a-plain-frame-by-default-with-screen-av.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +27 -32
- package/corpus/templates/design/playwright.config.ts +3 -5
- package/corpus/templates/design/shared/breakpoint-media.ts +9 -2
- package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/dispatch/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/dispatch/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/dispatch/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/dispatch/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/dispatch/AGENTS.md +9 -16
- package/corpus/templates/factory/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/factory/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/factory/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/factory/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/factory/AGENTS.md +10 -24
- package/corpus/templates/forms/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/forms/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/forms/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/forms/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/forms/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/forms/AGENTS.md +11 -17
- package/corpus/templates/forms/app/global.css +1 -0
- package/corpus/templates/forms/changelog/2026-08-11-full-page-chat-composers-stay-at-a-focused-750px-width.md +6 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/macros/AGENTS.md +8 -8
- package/corpus/templates/mail/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/mail/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/mail/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/mail/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/mail/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/mail/AGENTS.md +5 -6
- package/corpus/templates/plan/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/plan/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/plan/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/plan/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/plan/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/plan/AGENTS.md +5 -14
- package/corpus/templates/plan/changelog/2026-08-11-plan-no-longer-reloads-when-runtime-state-changes.md +6 -0
- package/corpus/templates/plan/vite.config.ts +5 -0
- package/corpus/templates/slides/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/slides/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/slides/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/slides/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +2 -2
- package/corpus/templates/slides/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +6 -3
- package/corpus/templates/slides/.agents/skills/deck-management/SKILL.md +6 -1
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +3 -2
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +3 -0
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +3 -3
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/slides/AGENTS.md +22 -25
- package/corpus/templates/slides/actions/get-deck-reference-context.ts +2 -2
- package/corpus/templates/slides/actions/get-deck.ts +57 -9
- package/corpus/templates/slides/actions/import-file.ts +2 -1
- package/corpus/templates/slides/actions/patch-deck.ts +45 -2
- package/corpus/templates/slides/actions/update-slide.ts +1 -1
- package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +2 -2
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -23
- package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +2 -2
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +6 -6
- package/corpus/templates/slides/app/components/editor/AnimationsPanel.tsx +3 -3
- package/corpus/templates/slides/app/components/editor/DeckEditorSkeleton.tsx +4 -4
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +428 -180
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +294 -266
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +7 -5
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +40 -12
- package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +6 -12
- package/corpus/templates/slides/app/components/editor/editor-command-model.ts +35 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +8 -10
- package/corpus/templates/slides/app/context/DeckContext.tsx +2 -1
- package/corpus/templates/slides/app/global.css +76 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +51 -23
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +68 -5
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +13 -6
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +2 -2
- package/corpus/templates/slides/app/pages/Index.tsx +87 -74
- package/corpus/templates/slides/app/root.tsx +43 -0
- package/corpus/templates/slides/changelog/2026-08-11-faster-slides-chat-deck-reads.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-chat-can-read-one-slide-without-loading-the-full-deck.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-11-slides-clearly-indicate-when-an-ai-agent-is-editing-alongsid.md +6 -0
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/server/lib/validate-slide-animations.ts +163 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
- package/corpus/templates/slides/shared/api.ts +46 -15
- package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +54 -488
- package/corpus/templates/tasks/.agents/skills/actions/references/action-fields.md +136 -0
- package/corpus/templates/tasks/.agents/skills/actions/references/examples.md +94 -0
- package/corpus/templates/tasks/.agents/skills/actions/references/provider-apis.md +95 -0
- package/corpus/templates/tasks/.agents/skills/agent-watchdog/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/create-skill/SKILL.md +9 -35
- package/corpus/templates/tasks/.agents/skills/efficient-fable/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/efficient-frontier/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -5
- package/corpus/templates/tasks/.agents/skills/plan-arbiter/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/plow-ahead/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/quick-recap/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/read-the-damn-docs/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/stay-within-limits/SKILL.md +1 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/corpus/templates/tasks/AGENTS.md +5 -20
- package/dist/agent/production-agent.js +376 -345
- package/dist/agent/run-manager.js +156 -14
- package/dist/agent/run-store.d.ts +11 -10
- package/dist/agent/run-store.js +17 -13
- package/dist/client/AssistantChat.d.ts +6 -2
- package/dist/client/AssistantChat.js +216 -131
- package/dist/client/active-run-state.d.ts +9 -1
- package/dist/client/active-run-state.js +34 -3
- package/dist/client/agent-chat-adapter.d.ts +8 -0
- package/dist/client/agent-chat-adapter.js +114 -28
- package/dist/client/chat/message-components.d.ts +7 -1
- package/dist/client/chat/message-components.js +32 -5
- package/dist/client/chat/run-recovery.d.ts +1 -0
- package/dist/client/chat/run-recovery.js +8 -0
- package/dist/client/chat/tool-call-display.d.ts +2 -0
- package/dist/client/chat/tool-call-display.js +2 -0
- package/dist/client/chat-first/apps-rail.js +1 -1
- package/dist/client/chat-first/chat-history.d.ts +1 -1
- package/dist/client/chat-first/chat-history.js +5 -2
- package/dist/client/sse-event-processor.d.ts +4 -2
- package/dist/client/sse-event-processor.js +36 -6
- package/dist/client/use-run-stuck-detection.d.ts +2 -0
- package/dist/client/use-run-stuck-detection.js +85 -9
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/integrations/adapters/slack.d.ts +0 -4
- package/dist/integrations/adapters/slack.js +6 -30
- package/dist/integrations/catalog.js +1 -1
- package/dist/integrations/pending-tasks-store.d.ts +0 -8
- package/dist/integrations/pending-tasks-store.js +0 -21
- package/dist/integrations/slack-manifest.d.ts +2 -2
- package/dist/integrations/slack-manifest.js +0 -3
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/docs/source-search.js +2 -2
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/framework-prompts.js +7 -2
- package/dist/server/agent-chat/prompt-resources.js +2 -2
- package/dist/server/agent-chat/skill-frontmatter.d.ts +31 -2
- package/dist/server/agent-chat/skill-frontmatter.js +41 -15
- package/dist/server/agent-chat-plugin.js +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agents-bundle.d.ts +16 -19
- package/dist/server/agents-bundle.js +19 -35
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/better-auth-instance.js +17 -2
- package/dist/server/prompts/framework-core-compact.d.ts +6 -1
- package/dist/server/prompts/framework-core-compact.js +12 -9
- package/dist/server/prompts/framework-core.d.ts +6 -1
- package/dist/server/prompts/framework-core.js +11 -9
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/shared-rules.d.ts +15 -11
- package/dist/server/prompts/shared-rules.js +17 -13
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/actions/SKILL.md +54 -488
- package/dist/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
- package/dist/templates/chat/.agents/skills/actions/references/examples.md +94 -0
- package/dist/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
- package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/dist/templates/chat/AGENTS.md +32 -80
- package/dist/templates/default/.agents/skills/actions/SKILL.md +54 -488
- package/dist/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
- package/dist/templates/default/.agents/skills/actions/references/examples.md +94 -0
- package/dist/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
- package/dist/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/dist/templates/headless/.agents/skills/actions/SKILL.md +54 -488
- package/dist/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
- package/dist/templates/headless/.agents/skills/actions/references/examples.md +94 -0
- package/dist/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
- package/dist/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
- package/dist/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
- package/dist/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
- package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
- package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
- package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
- package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
- package/dist/templates/workspace-core/AGENTS.md +7 -16
- package/docs/content/messaging.mdx +6 -7
- package/package.json +1 -1
- package/src/templates/chat/.agents/skills/actions/SKILL.md +54 -488
- package/src/templates/chat/.agents/skills/actions/references/action-fields.md +136 -0
- package/src/templates/chat/.agents/skills/actions/references/examples.md +94 -0
- package/src/templates/chat/.agents/skills/actions/references/provider-apis.md +95 -0
- package/src/templates/chat/.agents/skills/create-skill/SKILL.md +9 -35
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -5
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/src/templates/chat/AGENTS.md +32 -80
- package/src/templates/default/.agents/skills/actions/SKILL.md +54 -488
- package/src/templates/default/.agents/skills/actions/references/action-fields.md +136 -0
- package/src/templates/default/.agents/skills/actions/references/examples.md +94 -0
- package/src/templates/default/.agents/skills/actions/references/provider-apis.md +95 -0
- package/src/templates/default/.agents/skills/create-skill/SKILL.md +9 -35
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -5
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/src/templates/headless/.agents/skills/actions/SKILL.md +54 -488
- package/src/templates/headless/.agents/skills/actions/references/action-fields.md +136 -0
- package/src/templates/headless/.agents/skills/actions/references/examples.md +94 -0
- package/src/templates/headless/.agents/skills/actions/references/provider-apis.md +95 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +54 -488
- package/src/templates/workspace-core/.agents/skills/actions/references/action-fields.md +136 -0
- package/src/templates/workspace-core/.agents/skills/actions/references/examples.md +94 -0
- package/src/templates/workspace-core/.agents/skills/actions/references/provider-apis.md +95 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +1 -0
- package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +1 -0
- package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +9 -35
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -5
- package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +21 -29
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -31
- package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -17
- package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +3 -3
- package/src/templates/workspace-core/AGENTS.md +7 -16
|
@@ -99,5 +99,5 @@ export const ChatFirstAppsRail = memo(function ChatFirstAppsRail({ apps, activeA
|
|
|
99
99
|
? "bg-sidebar-accent text-sidebar-accent-foreground"
|
|
100
100
|
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"), onClick: () => onOpenApp(app), "aria-label": copy("openApp", { name: app.name }), title: app.name, children: renderIcon(app) }, app.id))), onOpenAllApps ? (_jsx("button", { type: "button", "data-chat-first-all-apps": true, className: "flex size-9 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", onClick: onOpenAllApps, "aria-label": copy("allApps"), title: copy("allApps"), children: _jsx(IconApps, { size: 16, "aria-hidden": "true" }) })) : null, error ? (_jsx("span", { className: "size-1.5 rounded-full bg-destructive", title: error, "aria-label": error })) : null] }));
|
|
101
101
|
}
|
|
102
|
-
return (_jsxs("section", { "data-chat-first-apps-rail": true, className: "mt-3 px-
|
|
102
|
+
return (_jsxs("section", { "data-chat-first-apps-rail": true, className: "mt-3 px-2 pb-2 pt-2", "aria-label": copy("workspaceApps"), children: [_jsxs("div", { className: "mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium text-sidebar-foreground/50", children: [_jsx("span", { children: copy("workspaceApps") }), _jsx("span", { className: "ml-auto", children: createTrigger })] }), loading && apps.length === 0 ? (_jsx("div", { className: "space-y-0.5 px-2", children: [0, 1, 2].map((index) => (_jsx(Skeleton, { className: "h-8 w-full rounded-md" }, index))) })) : apps.length === 0 ? (_jsxs("div", { className: "px-2", children: [_jsx("p", { className: "text-xs text-sidebar-foreground/55", children: copy("noWorkspaceApps") }), createAppTrigger ? (createTrigger) : onCreateApp ? (_jsxs("button", { type: "button", className: "mt-1 inline-flex h-6 items-center gap-1.5 rounded-md border border-sidebar-border px-2 text-xs text-sidebar-foreground/75 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onCreateApp, children: [_jsx(IconPlus, { size: 13, "aria-hidden": "true" }), copy("createApp")] })) : (createTrigger)] })) : (_jsx(AppRows, { apps: visibleApps, activeAppId: activeAppId, layout: layout, onDragStart: setDraggedAppId, onDrop: reorderApps, onDragEnd: () => setDraggedAppId(null), onOpenApp: onOpenApp, onTogglePinned: togglePinned, onMove: moveApp, renderIcon: renderIcon, copy: copy })), hasMoreApps || showAllApps ? (_jsxs("button", { type: "button", className: "mt-0.5 flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/50 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: () => setShowAllApps((value) => !value), children: [showAllApps ? (_jsx(IconChevronUp, { size: 14, "aria-hidden": "true" })) : (_jsx(IconChevronDown, { size: 14, "aria-hidden": "true" })), showAllApps ? copy("showLess") : copy("showMore")] })) : null, onOpenAllApps ? (_jsx("div", { className: "mt-1 border-t border-sidebar-border/60 pt-1", children: _jsxs("button", { type: "button", "data-chat-first-all-apps": true, className: "flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/55 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onOpenAllApps, children: [_jsx(IconApps, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: copy("allApps") })] }) })) : null, error ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "mt-1 flex items-center gap-1 px-2 text-[10px] text-destructive/80", onClick: onRetry, "aria-label": error, children: [_jsx("span", { className: "size-1.5 rounded-full bg-destructive" }), onRetry ? copy("retry") : copy("appsLoadError")] }) }), _jsx(TooltipContent, { side: "right", children: error })] })) : null] }));
|
|
103
103
|
});
|
|
@@ -11,4 +11,4 @@ export interface ChatFirstChatHistoryProps extends Omit<ChatHistoryListProps, "i
|
|
|
11
11
|
* host. Hosts still own thread fetching and actions, but row rhythm and the
|
|
12
12
|
* Chats section treatment stay identical.
|
|
13
13
|
*/
|
|
14
|
-
export declare function ChatFirstChatHistory({ items, label, headerAction, className, ...props }: ChatFirstChatHistoryProps): import("react").JSX.Element
|
|
14
|
+
export declare function ChatFirstChatHistory({ items, label, headerAction, className, ...props }: ChatFirstChatHistoryProps): import("react").JSX.Element;
|
|
@@ -6,7 +6,10 @@ import { ChatHistoryList, } from "../chat/ChatHistoryList.js";
|
|
|
6
6
|
* Chats section treatment stay identical.
|
|
7
7
|
*/
|
|
8
8
|
export function ChatFirstChatHistory({ items, label = "Chats", headerAction, className, ...props }) {
|
|
9
|
-
if (items.length === 0)
|
|
10
|
-
return
|
|
9
|
+
if (items.length === 0) {
|
|
10
|
+
return (_jsx("section", { "data-chat-first-chat-history": true, className: ["min-h-0 min-w-0 flex-1", className]
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.join(" ") }));
|
|
13
|
+
}
|
|
11
14
|
return (_jsxs("section", { "data-chat-first-chat-history": true, className: ["min-h-0 min-w-0", className].filter(Boolean).join(" "), children: [_jsxs("div", { "data-chat-first-chat-history-header": true, className: "group mb-1 flex min-h-6 items-center justify-between gap-2 px-2", children: [_jsx("p", { className: "min-w-0 text-[11px] font-medium text-sidebar-foreground/50", children: label }), headerAction ? (_jsx("div", { className: "shrink-0 opacity-0 transition-opacity duration-100 group-hover:opacity-100 group-focus-within:opacity-100", children: headerAction })) : null] }), _jsx(ChatHistoryList, { ...props, items: items, variant: "rail", className: "min-w-0" })] }));
|
|
12
15
|
}
|
|
@@ -196,6 +196,8 @@ export interface SSEStreamOptions {
|
|
|
196
196
|
noProgressTimeoutMs?: number;
|
|
197
197
|
/** Reader-local counterpart to `noProgressTimeoutMs` for action preparation. */
|
|
198
198
|
actionPreparationStallTimeoutMs?: number;
|
|
199
|
+
/** Mark the adapter's final `done` snapshot terminal before it is yielded. */
|
|
200
|
+
markTerminalResults?: boolean;
|
|
199
201
|
/**
|
|
200
202
|
* Optional caller-owned preparation watchdog state. Passing the same object
|
|
201
203
|
* across reconnect reads keeps a stuck action preparation from getting a
|
|
@@ -261,7 +263,7 @@ export declare function processEvent(ev: SSEEvent, content: ContentPart[], toolC
|
|
|
261
263
|
*/
|
|
262
264
|
export declare function readSSEStream(body: ReadableStream<Uint8Array>, content: ContentPart[], toolCallCounter: {
|
|
263
265
|
value: number;
|
|
264
|
-
}, tabId: string | undefined, onSeq?: (seq: number) => void, runId?: string | null, options?: SSEStreamOptions): AsyncGenerator<ChatModelRunResult>;
|
|
266
|
+
}, tabId: string | undefined, onSeq?: (seq: number, isProgress?: boolean) => void, runId?: string | null, options?: SSEStreamOptions): AsyncGenerator<ChatModelRunResult>;
|
|
265
267
|
/**
|
|
266
268
|
* Read raw SSE events from a ReadableStream and process them into ContentPart[].
|
|
267
269
|
* Unlike readSSEStream, this doesn't yield ChatModelRunResult — it updates the
|
|
@@ -270,5 +272,5 @@ export declare function readSSEStream(body: ReadableStream<Uint8Array>, content:
|
|
|
270
272
|
*/
|
|
271
273
|
export declare function readSSEStreamRaw(body: ReadableStream<Uint8Array>, content: ContentPart[], toolCallCounter: {
|
|
272
274
|
value: number;
|
|
273
|
-
}, tabId: string | undefined, onUpdate: (content: ContentPart[]) => void, onSeq?: (seq: number) => void, options?: SSEStreamOptions): Promise<void>;
|
|
275
|
+
}, tabId: string | undefined, onUpdate: (content: ContentPart[]) => void, onSeq?: (seq: number, isProgress?: boolean) => void, options?: SSEStreamOptions): Promise<void>;
|
|
274
276
|
export {};
|
|
@@ -154,6 +154,20 @@ function isMeaningfulProgressEvent(ev, actionPreparationProgress, options) {
|
|
|
154
154
|
}
|
|
155
155
|
return true;
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* The browser's durable liveness cursor must mirror the server's
|
|
159
|
+
* `last_progress_at` predicate. The stream watchdog intentionally has a
|
|
160
|
+
* broader background policy, so it cannot be reused for this cursor: raw
|
|
161
|
+
* keepalives and repeated zero-byte preparation are not proof of real work.
|
|
162
|
+
*/
|
|
163
|
+
function isDurableProgressEvent(ev, actionPreparationProgress) {
|
|
164
|
+
if (ev.type === "stream_keepalive" || ev.type === "clear")
|
|
165
|
+
return false;
|
|
166
|
+
if (ev.type === "activity" && isPreparingActionActivity(ev)) {
|
|
167
|
+
return actionPreparationProgress === true;
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
157
171
|
function baseActivityLabel(ev, tool) {
|
|
158
172
|
return humanizeToolLabelText(ev.label ?? "Working", tool);
|
|
159
173
|
}
|
|
@@ -1603,13 +1617,15 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
|
|
|
1603
1617
|
const now = Date.now();
|
|
1604
1618
|
inFlightWork = Math.max(0, inFlightWork + sseInFlightWorkDelta(ev));
|
|
1605
1619
|
const actionPreparationProgress = updatePreparingActionState(preparingActionState, ev, now);
|
|
1606
|
-
|
|
1620
|
+
const meaningfulProgress = isMeaningfulProgressEvent(ev, actionPreparationProgress, options);
|
|
1621
|
+
const durableProgress = isDurableProgressEvent(ev, actionPreparationProgress);
|
|
1622
|
+
if (meaningfulProgress) {
|
|
1607
1623
|
sawProgressEvent = true;
|
|
1608
1624
|
lastMeaningfulEventAt = now;
|
|
1609
1625
|
}
|
|
1610
1626
|
// Track sequence number for reconnection
|
|
1611
1627
|
if (ev.seq !== undefined && onSeq) {
|
|
1612
|
-
onSeq(ev.seq);
|
|
1628
|
+
onSeq(ev.seq, durableProgress);
|
|
1613
1629
|
}
|
|
1614
1630
|
if (ev.type === "clear") {
|
|
1615
1631
|
activityTrail.length = 0;
|
|
@@ -1637,9 +1653,21 @@ export async function* readSSEStream(body, content, toolCallCounter, tabId, onSe
|
|
|
1637
1653
|
}
|
|
1638
1654
|
}
|
|
1639
1655
|
const { action, result, autoContinue } = processEvent(ev, content, toolCallCounter, tabId, processEventState);
|
|
1640
|
-
|
|
1656
|
+
const terminalResult = result &&
|
|
1657
|
+
options?.markTerminalResults === true &&
|
|
1658
|
+
action === "done" &&
|
|
1659
|
+
result.status == null
|
|
1660
|
+
? {
|
|
1661
|
+
...result,
|
|
1662
|
+
status: {
|
|
1663
|
+
type: "complete",
|
|
1664
|
+
reason: "stop",
|
|
1665
|
+
},
|
|
1666
|
+
}
|
|
1667
|
+
: result;
|
|
1668
|
+
if (terminalResult) {
|
|
1641
1669
|
await paceRenderUpdate();
|
|
1642
|
-
yield withStreamMetadata(
|
|
1670
|
+
yield withStreamMetadata(terminalResult);
|
|
1643
1671
|
}
|
|
1644
1672
|
if (hasStalledPreparingAction(preparingActionState, Date.now(), preparationStallTimeoutMs)) {
|
|
1645
1673
|
throw new AgentAutoContinueSignal({
|
|
@@ -1757,12 +1785,14 @@ export async function readSSEStreamRaw(body, content, toolCallCounter, tabId, on
|
|
|
1757
1785
|
const now = Date.now();
|
|
1758
1786
|
inFlightWork = Math.max(0, inFlightWork + sseInFlightWorkDelta(ev));
|
|
1759
1787
|
const actionPreparationProgress = updatePreparingActionState(preparingActionState, ev, now);
|
|
1760
|
-
|
|
1788
|
+
const meaningfulProgress = isMeaningfulProgressEvent(ev, actionPreparationProgress, options);
|
|
1789
|
+
const durableProgress = isDurableProgressEvent(ev, actionPreparationProgress);
|
|
1790
|
+
if (meaningfulProgress) {
|
|
1761
1791
|
sawProgressEvent = true;
|
|
1762
1792
|
lastMeaningfulEventAt = now;
|
|
1763
1793
|
}
|
|
1764
1794
|
if (ev.seq !== undefined && onSeq) {
|
|
1765
|
-
onSeq(ev.seq);
|
|
1795
|
+
onSeq(ev.seq, durableProgress);
|
|
1766
1796
|
}
|
|
1767
1797
|
if (ev.type === "clear") {
|
|
1768
1798
|
activityTrail.length = 0;
|
|
@@ -18,6 +18,8 @@ export interface RunStuckState {
|
|
|
18
18
|
lastProgressAt: number | null;
|
|
19
19
|
/** Milliseconds since `lastProgressAt`, or null. */
|
|
20
20
|
stuckSinceMs: number | null;
|
|
21
|
+
/** Last browser SSE sequence classified as real work progress, or null. */
|
|
22
|
+
lastProgressSeq: number | null;
|
|
21
23
|
/** Server timestamp (ms) of the last process-alive heartbeat. */
|
|
22
24
|
heartbeatAt: number | null;
|
|
23
25
|
/** Milliseconds since `heartbeatAt`, computed against the server clock. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback } from "react";
|
|
2
2
|
import { createPollEngine } from "../shared/poll-engine.js";
|
|
3
|
+
import { ACTIVE_RUN_STATE_EVENT, getActiveRun, } from "./active-run-state.js";
|
|
3
4
|
import { agentNativePath } from "./api-path.js";
|
|
4
5
|
const DEFAULT_STUCK_THRESHOLD_MS = 90_000;
|
|
5
6
|
export const DEFAULT_BACKGROUND_STUCK_THRESHOLD_MS = 180_000;
|
|
@@ -20,6 +21,7 @@ const EMPTY_STATE = {
|
|
|
20
21
|
status: null,
|
|
21
22
|
lastProgressAt: null,
|
|
22
23
|
stuckSinceMs: null,
|
|
24
|
+
lastProgressSeq: null,
|
|
23
25
|
heartbeatAt: null,
|
|
24
26
|
heartbeatSinceMs: null,
|
|
25
27
|
dispatchMode: null,
|
|
@@ -37,6 +39,8 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
37
39
|
let cancelled = false;
|
|
38
40
|
let snapshotTransitionTimer = null;
|
|
39
41
|
let snapshotVersion = 0;
|
|
42
|
+
let lastObservedLocalProgressAt = null;
|
|
43
|
+
let lastObservedLocalProgressSeq = null;
|
|
40
44
|
let consecutivePollFailures = 0;
|
|
41
45
|
// The engine's own cadence varies per tick (idle backoff, error backoff),
|
|
42
46
|
// which is why intervalMs below reads from this ref instead of a fixed
|
|
@@ -86,8 +90,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
86
90
|
const currentStuckSinceMs = snapshot.stuckSinceMs == null
|
|
87
91
|
? null
|
|
88
92
|
: snapshot.stuckSinceMs + currentElapsedMs;
|
|
93
|
+
const currentLocalProgressSinceMs = snapshot.localProgressObservedAt == null
|
|
94
|
+
? null
|
|
95
|
+
: Math.max(0, Date.now() - snapshot.localProgressObservedAt);
|
|
89
96
|
const effectiveThresholdMs = effectiveThresholdFor(snapshot.dispatchMode, currentHeartbeatSinceMs);
|
|
90
|
-
const
|
|
97
|
+
const localProgressFresh = Boolean(currentLocalProgressSinceMs != null &&
|
|
98
|
+
currentLocalProgressSinceMs <= effectiveThresholdMs);
|
|
99
|
+
const currentlyStuck = Boolean(!localProgressFresh &&
|
|
100
|
+
currentStuckSinceMs != null &&
|
|
91
101
|
currentStuckSinceMs > effectiveThresholdMs);
|
|
92
102
|
const transitionDelaysMs = [];
|
|
93
103
|
if (currentHeartbeatSinceMs != null &&
|
|
@@ -95,9 +105,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
95
105
|
currentHeartbeatSinceMs < FRESH_BACKGROUND_HEARTBEAT_MS) {
|
|
96
106
|
transitionDelaysMs.push(FRESH_BACKGROUND_HEARTBEAT_MS - currentHeartbeatSinceMs + 1);
|
|
97
107
|
}
|
|
98
|
-
if (
|
|
108
|
+
if (!localProgressFresh &&
|
|
109
|
+
currentStuckSinceMs != null &&
|
|
110
|
+
!currentlyStuck) {
|
|
99
111
|
transitionDelaysMs.push(Math.max(1, effectiveThresholdMs - currentStuckSinceMs + 1));
|
|
100
112
|
}
|
|
113
|
+
if (localProgressFresh && currentLocalProgressSinceMs != null) {
|
|
114
|
+
transitionDelaysMs.push(Math.max(1, effectiveThresholdMs - currentLocalProgressSinceMs + 1));
|
|
115
|
+
}
|
|
101
116
|
if (transitionDelaysMs.length === 0)
|
|
102
117
|
return;
|
|
103
118
|
// Both ages originate from the server clock. Advance those snapshots by
|
|
@@ -116,26 +131,66 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
116
131
|
const nextStuckSinceMs = snapshot.stuckSinceMs == null
|
|
117
132
|
? null
|
|
118
133
|
: snapshot.stuckSinceMs + elapsedSinceObservationMs;
|
|
134
|
+
const nextLocalProgressSinceMs = snapshot.localProgressObservedAt == null
|
|
135
|
+
? null
|
|
136
|
+
: Math.max(0, Date.now() - snapshot.localProgressObservedAt);
|
|
119
137
|
const nextEffectiveThresholdMs = effectiveThresholdFor(snapshot.dispatchMode, nextHeartbeatSinceMs);
|
|
120
|
-
const
|
|
138
|
+
const nextLocalProgressFresh = Boolean(nextLocalProgressSinceMs != null &&
|
|
139
|
+
nextLocalProgressSinceMs <= nextEffectiveThresholdMs);
|
|
140
|
+
const nextIsStuck = Boolean(!nextLocalProgressFresh &&
|
|
141
|
+
nextStuckSinceMs != null &&
|
|
121
142
|
nextStuckSinceMs > nextEffectiveThresholdMs);
|
|
122
143
|
setState((current) => {
|
|
123
144
|
if (version !== snapshotVersion ||
|
|
124
145
|
current.runId !== snapshot.runId ||
|
|
125
146
|
current.lastProgressAt !== snapshot.lastProgressAt ||
|
|
126
|
-
current.heartbeatAt !== snapshot.heartbeatAt
|
|
147
|
+
current.heartbeatAt !== snapshot.heartbeatAt ||
|
|
148
|
+
current.lastProgressSeq !== snapshot.lastProgressSeq) {
|
|
127
149
|
return current;
|
|
128
150
|
}
|
|
129
151
|
return {
|
|
130
152
|
...current,
|
|
131
153
|
isStuck: nextIsStuck,
|
|
132
|
-
stuckSinceMs: nextStuckSinceMs,
|
|
154
|
+
stuckSinceMs: nextLocalProgressFresh ? null : nextStuckSinceMs,
|
|
133
155
|
heartbeatSinceMs: nextHeartbeatSinceMs,
|
|
134
156
|
};
|
|
135
157
|
});
|
|
136
158
|
scheduleSnapshotTransition(snapshot, observedAtMs, version);
|
|
137
159
|
}, delayMs);
|
|
138
160
|
};
|
|
161
|
+
// A healthy SSE stream is a stronger local proof of progress than a
|
|
162
|
+
// delayed SQL timestamp. Listen only to the real-progress cursor - raw
|
|
163
|
+
// keepalives still advance the reconnect cursor but must not suppress the
|
|
164
|
+
// stuck detector forever.
|
|
165
|
+
const onActiveRunStateChange = (event) => {
|
|
166
|
+
const activeRun = (event.detail?.state ?? getActiveRun());
|
|
167
|
+
const progressSeq = activeRun?.lastProgressSeq ?? null;
|
|
168
|
+
const hasNewerProgress = typeof activeRun?.lastProgressObservedAt === "number" &&
|
|
169
|
+
(activeRun.lastProgressObservedAt >
|
|
170
|
+
(lastObservedLocalProgressAt ?? -1) ||
|
|
171
|
+
(activeRun.lastProgressObservedAt === lastObservedLocalProgressAt &&
|
|
172
|
+
progressSeq != null &&
|
|
173
|
+
progressSeq > (lastObservedLocalProgressSeq ?? -1)));
|
|
174
|
+
if (!activeRun ||
|
|
175
|
+
activeRun.threadId !== threadId ||
|
|
176
|
+
typeof activeRun.lastProgressObservedAt !== "number" ||
|
|
177
|
+
!hasNewerProgress) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
lastObservedLocalProgressAt = activeRun.lastProgressObservedAt;
|
|
181
|
+
lastObservedLocalProgressSeq = progressSeq;
|
|
182
|
+
snapshotVersion += 1;
|
|
183
|
+
if (snapshotTransitionTimer)
|
|
184
|
+
clearTimeout(snapshotTransitionTimer);
|
|
185
|
+
snapshotTransitionTimer = null;
|
|
186
|
+
setState((current) => {
|
|
187
|
+
if (current.runId !== activeRun.runId || !current.isStuck) {
|
|
188
|
+
return current;
|
|
189
|
+
}
|
|
190
|
+
return { ...current, isStuck: false, stuckSinceMs: null };
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
window.addEventListener(ACTIVE_RUN_STATE_EVENT, onActiveRunStateChange);
|
|
139
194
|
const attempt = async (signal) => {
|
|
140
195
|
let nextDelay = pollIntervalMs;
|
|
141
196
|
try {
|
|
@@ -156,6 +211,14 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
156
211
|
const heartbeatAt = data.heartbeatAt ?? null;
|
|
157
212
|
const heartbeatSinceMs = heartbeatAt != null ? nowMs - heartbeatAt : null;
|
|
158
213
|
const dispatchMode = typeof data.dispatchMode === "string" ? data.dispatchMode : null;
|
|
214
|
+
const runId = data.runId ?? null;
|
|
215
|
+
const activeRun = getActiveRun();
|
|
216
|
+
const localProgressObservedAt = activeRun?.threadId === threadId && activeRun.runId === runId
|
|
217
|
+
? (activeRun.lastProgressObservedAt ?? null)
|
|
218
|
+
: null;
|
|
219
|
+
const localProgressSinceMs = localProgressObservedAt == null
|
|
220
|
+
? null
|
|
221
|
+
: Math.max(0, Date.now() - localProgressObservedAt);
|
|
159
222
|
// A claimed durable worker with a fresh heartbeat can legitimately
|
|
160
223
|
// be waiting on a bounded long-running tool/sub-agent call. Still
|
|
161
224
|
// surface informational status at the normal background threshold;
|
|
@@ -166,25 +229,37 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
166
229
|
const isStuck = Boolean(data.active &&
|
|
167
230
|
data.status === "running" &&
|
|
168
231
|
stuckSinceMs != null &&
|
|
169
|
-
stuckSinceMs > effectiveThresholdMs
|
|
232
|
+
stuckSinceMs > effectiveThresholdMs &&
|
|
233
|
+
(localProgressSinceMs == null ||
|
|
234
|
+
localProgressSinceMs > effectiveThresholdMs));
|
|
170
235
|
const observedAtMs = Date.now();
|
|
171
236
|
const version = ++snapshotVersion;
|
|
172
237
|
scheduleSnapshotTransition({
|
|
173
238
|
active: data.active,
|
|
174
|
-
runId
|
|
239
|
+
runId,
|
|
175
240
|
status: data.status ?? null,
|
|
176
241
|
lastProgressAt,
|
|
177
242
|
stuckSinceMs,
|
|
243
|
+
localProgressObservedAt,
|
|
244
|
+
lastProgressSeq: activeRun?.threadId === threadId && activeRun.runId === runId
|
|
245
|
+
? (activeRun.lastProgressSeq ?? null)
|
|
246
|
+
: null,
|
|
178
247
|
heartbeatAt,
|
|
179
248
|
heartbeatSinceMs,
|
|
180
249
|
dispatchMode,
|
|
181
250
|
}, observedAtMs, version);
|
|
182
251
|
setState({
|
|
183
252
|
isStuck,
|
|
184
|
-
runId
|
|
253
|
+
runId,
|
|
185
254
|
status: data.status ?? null,
|
|
186
255
|
lastProgressAt,
|
|
187
|
-
stuckSinceMs
|
|
256
|
+
stuckSinceMs: localProgressSinceMs != null &&
|
|
257
|
+
localProgressSinceMs <= effectiveThresholdMs
|
|
258
|
+
? null
|
|
259
|
+
: stuckSinceMs,
|
|
260
|
+
lastProgressSeq: activeRun?.threadId === threadId && activeRun.runId === runId
|
|
261
|
+
? (activeRun.lastProgressSeq ?? null)
|
|
262
|
+
: null,
|
|
188
263
|
heartbeatAt,
|
|
189
264
|
heartbeatSinceMs,
|
|
190
265
|
dispatchMode,
|
|
@@ -245,6 +320,7 @@ export function useRunStuckDetection({ threadId, enabled = true, stuckThresholdM
|
|
|
245
320
|
engine.stop();
|
|
246
321
|
if (snapshotTransitionTimer)
|
|
247
322
|
clearTimeout(snapshotTransitionTimer);
|
|
323
|
+
window.removeEventListener(ACTIVE_RUN_STATE_EVENT, onActiveRunStateChange);
|
|
248
324
|
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
249
325
|
};
|
|
250
326
|
}, [
|
|
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
|
|
|
62
62
|
error: string;
|
|
63
63
|
states?: undefined;
|
|
64
64
|
} | {
|
|
65
|
+
error?: undefined;
|
|
65
66
|
states: {
|
|
66
67
|
clientId: number;
|
|
67
68
|
state: string;
|
|
68
69
|
}[];
|
|
69
|
-
error?: undefined;
|
|
70
70
|
}>>;
|
|
71
71
|
/**
|
|
72
72
|
* GET /_agent-native/collab/:docId/users
|
|
@@ -77,9 +77,9 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
|
|
|
77
77
|
error: string;
|
|
78
78
|
users?: undefined;
|
|
79
79
|
} | {
|
|
80
|
+
error?: undefined;
|
|
80
81
|
users: {
|
|
81
82
|
clientId: number;
|
|
82
83
|
lastSeen: number;
|
|
83
84
|
}[];
|
|
84
|
-
error?: undefined;
|
|
85
85
|
}>>;
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
|
@@ -2,10 +2,6 @@ import type { PlatformAdapter, IncomingMessage } from "../types.js";
|
|
|
2
2
|
export interface SlackAdapterOptions {
|
|
3
3
|
/** Resolve the bot token for the exact Slack installation. */
|
|
4
4
|
resolveBotToken?: (incoming: IncomingMessage) => Promise<string | undefined>;
|
|
5
|
-
/** Override active-thread detection for hosted adapters/tests. */
|
|
6
|
-
isThreadActive?: (incoming: IncomingMessage) => Promise<boolean>;
|
|
7
|
-
/** Override one-shot clarification-window consumption for tests. */
|
|
8
|
-
consumeAwaitingInput?: (incoming: IncomingMessage) => Promise<boolean>;
|
|
9
5
|
}
|
|
10
6
|
/**
|
|
11
7
|
* Create a Slack platform adapter.
|
|
@@ -3,10 +3,8 @@ import { createError, getHeader, readRawBody } from "h3";
|
|
|
3
3
|
import { resolveSecret } from "../../server/credential-provider.js";
|
|
4
4
|
import { getRequestContext } from "../../server/request-context.js";
|
|
5
5
|
import { getIntegrationRequestContext } from "../../server/request-context.js";
|
|
6
|
-
import { consumeIntegrationAwaitingInput } from "../awaiting-input-store.js";
|
|
7
6
|
import { createIntegrationControl } from "../controls-store.js";
|
|
8
7
|
import { getActiveIntegrationInstallationByKey, listActiveIntegrationInstallationsForTenant, listIntegrationInstallations, resolveIntegrationTokenBundle, } from "../installations-store.js";
|
|
9
|
-
import { hasActivePendingTask } from "../pending-tasks-store.js";
|
|
10
8
|
import { slackInstallationKey } from "../slack-oauth.js";
|
|
11
9
|
/** Slack's max message length */
|
|
12
10
|
const SLACK_MAX_LENGTH = 4000;
|
|
@@ -195,10 +193,10 @@ export function slackAdapter(options = {}) {
|
|
|
195
193
|
// Ignore message edits and deletes
|
|
196
194
|
if (e.subtype === "message_changed" || e.subtype === "message_deleted")
|
|
197
195
|
return null;
|
|
198
|
-
// Handle DMs and explicit mentions.
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
196
|
+
// Handle DMs and explicit mentions only. A channel thread can contain
|
|
197
|
+
// many human replies after an agent mention; each new agent turn must
|
|
198
|
+
// opt in with another explicit mention instead of inheriting the
|
|
199
|
+
// parent message's invocation.
|
|
202
200
|
const text = e.text?.trim();
|
|
203
201
|
if (!text)
|
|
204
202
|
return null;
|
|
@@ -211,8 +209,7 @@ export function slackAdapter(options = {}) {
|
|
|
211
209
|
? e.channel_type === "im"
|
|
212
210
|
: typeof e.channel === "string" && e.channel.startsWith("D");
|
|
213
211
|
const isMention = e.type === "app_mention";
|
|
214
|
-
|
|
215
|
-
if (!isDm && !isMention && !isThreadReply)
|
|
212
|
+
if (!isDm && !isMention)
|
|
216
213
|
return null;
|
|
217
214
|
// Remove bot mention from text (e.g., "<@U123> do something" → "do something")
|
|
218
215
|
const cleanText = text.replace(/<@[A-Z0-9]+>/g, "").trim();
|
|
@@ -227,7 +224,7 @@ export function slackAdapter(options = {}) {
|
|
|
227
224
|
text: cleanText,
|
|
228
225
|
senderName: e.user,
|
|
229
226
|
senderId: e.user,
|
|
230
|
-
triggerKind: isDm ? "dm" :
|
|
227
|
+
triggerKind: isDm ? "dm" : "mention",
|
|
231
228
|
conversationType: isDm ? "dm" : "unknown",
|
|
232
229
|
tenantId: teamId,
|
|
233
230
|
// The signed Slack envelope authenticates the workspace, not the
|
|
@@ -256,27 +253,6 @@ export function slackAdapter(options = {}) {
|
|
|
256
253
|
replyRef: e.ts,
|
|
257
254
|
timestamp: Math.floor(parseFloat(e.ts) * 1000),
|
|
258
255
|
};
|
|
259
|
-
if (isThreadReply) {
|
|
260
|
-
// An ordinary thread reply is narrowly admitted when either work is
|
|
261
|
-
// still queued or the same Slack user is answering a fresh
|
|
262
|
-
// integration-originated clarification. Consuming the latter is a
|
|
263
|
-
// conditional SQL delete, so concurrent replies cannot both reopen
|
|
264
|
-
// the agent and unrelated channel messages remain ignored.
|
|
265
|
-
const answeredClarification = options.consumeAwaitingInput
|
|
266
|
-
? await options.consumeAwaitingInput(partialIncoming)
|
|
267
|
-
: options.isThreadActive
|
|
268
|
-
? false
|
|
269
|
-
: await consumeIntegrationAwaitingInput({
|
|
270
|
-
platform: "slack",
|
|
271
|
-
externalThreadId,
|
|
272
|
-
requesterId: e.user,
|
|
273
|
-
});
|
|
274
|
-
const active = options.isThreadActive
|
|
275
|
-
? await options.isThreadActive(partialIncoming)
|
|
276
|
-
: await hasActivePendingTask("slack", externalThreadId);
|
|
277
|
-
if (!active && !answeredClarification)
|
|
278
|
-
return null;
|
|
279
|
-
}
|
|
280
256
|
const token = await resolveBotToken(partialIncoming);
|
|
281
257
|
const threadPermalink = await resolveSlackThreadPermalink(e.channel, threadTs, token);
|
|
282
258
|
return {
|
|
@@ -36,7 +36,7 @@ const BUILT_IN_CHANNEL_CATALOG = [
|
|
|
36
36
|
"Apply the Agent Native Slack manifest to enable Agent View and writable direct messages.",
|
|
37
37
|
"Configure the OAuth client id, client secret, and signing secret.",
|
|
38
38
|
"Enable Event Subscriptions and Interactivity with the documented URLs.",
|
|
39
|
-
"Subscribe to app_home_opened, app_context_changed, app_mention, and message.im
|
|
39
|
+
"Subscribe to app_home_opened, app_context_changed, app_mention, and message.im, then use Add to Slack.",
|
|
40
40
|
],
|
|
41
41
|
},
|
|
42
42
|
credentialRequirements: [
|
|
@@ -20,14 +20,6 @@ export interface PendingTask {
|
|
|
20
20
|
updatedAt: number;
|
|
21
21
|
completedAt: number | null;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Whether a provider thread currently has queued or executing work.
|
|
25
|
-
*
|
|
26
|
-
* Messaging adapters use this to accept unmentioned replies only while an
|
|
27
|
-
* agent task is active. This prevents broad message subscriptions from turning
|
|
28
|
-
* every channel message into an agent invocation.
|
|
29
|
-
*/
|
|
30
|
-
export declare function hasActivePendingTask(platform: string, externalThreadId: string): Promise<boolean>;
|
|
31
23
|
/**
|
|
32
24
|
* Insert a new pending task. Returns the generated task id.
|
|
33
25
|
*
|
|
@@ -110,27 +110,6 @@ async function ensureDispatchColumns(client) {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Whether a provider thread currently has queued or executing work.
|
|
115
|
-
*
|
|
116
|
-
* Messaging adapters use this to accept unmentioned replies only while an
|
|
117
|
-
* agent task is active. This prevents broad message subscriptions from turning
|
|
118
|
-
* every channel message into an agent invocation.
|
|
119
|
-
*/
|
|
120
|
-
export async function hasActivePendingTask(platform, externalThreadId) {
|
|
121
|
-
await ensureTable();
|
|
122
|
-
const client = getDbExec();
|
|
123
|
-
const { rows } = await client.execute({
|
|
124
|
-
sql: `SELECT 1 AS active
|
|
125
|
-
FROM integration_pending_tasks
|
|
126
|
-
WHERE platform = ?
|
|
127
|
-
AND external_thread_id = ?
|
|
128
|
-
AND status IN ('pending', 'processing')
|
|
129
|
-
LIMIT 1`,
|
|
130
|
-
args: [platform, externalThreadId],
|
|
131
|
-
});
|
|
132
|
-
return rows.length > 0;
|
|
133
|
-
}
|
|
134
113
|
function rowToTask(row) {
|
|
135
114
|
return {
|
|
136
115
|
id: row.id,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SLACK_AGENT_BOT_EVENTS: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.
|
|
1
|
+
export declare const SLACK_AGENT_BOT_EVENTS: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.im"];
|
|
2
2
|
export interface SlackAgentManifestUrls {
|
|
3
3
|
oauthRedirectUrl: string;
|
|
4
4
|
eventsRequestUrl: string;
|
|
@@ -52,7 +52,7 @@ export declare function buildSlackAgentManifest(urls: SlackAgentManifestUrls): {
|
|
|
52
52
|
readonly settings: {
|
|
53
53
|
readonly event_subscriptions: {
|
|
54
54
|
readonly request_url: string;
|
|
55
|
-
readonly bot_events: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.
|
|
55
|
+
readonly bot_events: readonly ["app_home_opened", "app_context_changed", "app_mention", "message.im"];
|
|
56
56
|
};
|
|
57
57
|
readonly interactivity: {
|
|
58
58
|
readonly is_enabled: true;
|