@agent-native/core 0.5.0-dev.b51eaae → 0.7.1
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/README.md +49 -37
- package/dist/a2a/agent-card.d.ts.map +1 -1
- package/dist/a2a/agent-card.js +12 -1
- package/dist/a2a/agent-card.js.map +1 -1
- package/dist/a2a/client.d.ts +11 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +38 -1
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/index.d.ts +1 -1
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/server.d.ts +4 -0
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +53 -8
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +1 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/action.d.ts +64 -30
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +224 -27
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts +24 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +302 -0
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -0
- package/dist/agent/engine/anthropic-engine.d.ts +24 -0
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -0
- package/dist/agent/engine/anthropic-engine.js +169 -0
- package/dist/agent/engine/anthropic-engine.js.map +1 -0
- package/dist/agent/engine/builtin.d.ts +12 -0
- package/dist/agent/engine/builtin.d.ts.map +1 -0
- package/dist/agent/engine/builtin.js +72 -0
- package/dist/agent/engine/builtin.js.map +1 -0
- package/dist/agent/engine/index.d.ts +9 -0
- package/dist/agent/engine/index.d.ts.map +1 -0
- package/dist/agent/engine/index.js +8 -0
- package/dist/agent/engine/index.js.map +1 -0
- package/dist/agent/engine/registry.d.ts +61 -0
- package/dist/agent/engine/registry.d.ts.map +1 -0
- package/dist/agent/engine/registry.js +101 -0
- package/dist/agent/engine/registry.js.map +1 -0
- package/dist/agent/engine/translate-ai-sdk.d.ts +20 -0
- package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -0
- package/dist/agent/engine/translate-ai-sdk.js +174 -0
- package/dist/agent/engine/translate-ai-sdk.js.map +1 -0
- package/dist/agent/engine/translate-anthropic.d.ts +23 -0
- package/dist/agent/engine/translate-anthropic.d.ts.map +1 -0
- package/dist/agent/engine/translate-anthropic.js +140 -0
- package/dist/agent/engine/translate-anthropic.js.map +1 -0
- package/dist/agent/engine/types.d.ts +168 -0
- package/dist/agent/engine/types.d.ts.map +1 -0
- package/dist/agent/engine/types.js +13 -0
- package/dist/agent/engine/types.js.map +1 -0
- package/dist/agent/production-agent.d.ts +48 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +369 -79
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +15 -9
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +5 -5
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +1 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +4 -1
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/agent/types.d.ts +23 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/application-state/handlers.d.ts +8 -8
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +3 -2
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +47 -9
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/chat-threads/store.d.ts +14 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +32 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/create-workspace.js +18 -0
- package/dist/cli/create-workspace.js.map +1 -0
- package/dist/cli/create.d.ts +36 -2
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +509 -61
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +73 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/workspacify.d.ts +18 -0
- package/dist/cli/workspacify.d.ts.map +1 -0
- package/dist/cli/workspacify.js +74 -0
- package/dist/cli/workspacify.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +6 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +314 -180
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts +12 -0
- package/dist/client/AgentTaskCard.d.ts.map +1 -0
- package/dist/client/AgentTaskCard.js +146 -0
- package/dist/client/AgentTaskCard.js.map +1 -0
- package/dist/client/AssistantChat.d.ts +13 -2
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +344 -122
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts +7 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +345 -63
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/PoweredByBadge.js +2 -2
- package/dist/client/PoweredByBadge.js.map +1 -1
- package/dist/client/Turnstile.d.ts.map +1 -1
- package/dist/client/Turnstile.js +2 -3
- package/dist/client/Turnstile.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +63 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +14 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +4 -2
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/components/CodeAgentIndicator.d.ts +14 -0
- package/dist/client/components/CodeAgentIndicator.d.ts.map +1 -0
- package/dist/client/components/CodeAgentIndicator.js +29 -0
- package/dist/client/components/CodeAgentIndicator.js.map +1 -0
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +86 -5
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts +4 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +51 -8
- package/dist/client/composer/MentionPopover.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +8 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +149 -17
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/index.d.ts +1 -1
- package/dist/client/composer/index.d.ts.map +1 -1
- package/dist/client/composer/types.d.ts +6 -1
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.js +46 -13
- package/dist/client/composer/use-mention-search.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +54 -0
- package/dist/client/frame-protocol.d.ts.map +1 -0
- package/dist/client/frame-protocol.js +9 -0
- package/dist/client/frame-protocol.js.map +1 -0
- package/dist/client/frame.d.ts +56 -0
- package/dist/client/frame.d.ts.map +1 -0
- package/dist/client/{harness.js → frame.js} +49 -26
- package/dist/client/frame.js.map +1 -0
- package/dist/client/index.d.ts +7 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts +6 -0
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -0
- package/dist/client/integrations/IntegrationCard.js +45 -0
- package/dist/client/integrations/IntegrationCard.js.map +1 -0
- package/dist/client/integrations/IntegrationsPanel.d.ts +2 -0
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -0
- package/dist/client/integrations/IntegrationsPanel.js +162 -0
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -0
- package/dist/client/integrations/index.d.ts +4 -0
- package/dist/client/integrations/index.d.ts.map +1 -0
- package/dist/client/integrations/index.js +3 -0
- package/dist/client/integrations/index.js.map +1 -0
- package/dist/client/integrations/useIntegrationStatus.d.ts +15 -0
- package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -0
- package/dist/client/integrations/useIntegrationStatus.js +37 -0
- package/dist/client/integrations/useIntegrationStatus.js.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.js +36 -0
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +360 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
- package/dist/client/onboarding/SetupButton.d.ts +10 -0
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
- package/dist/client/onboarding/SetupButton.js +26 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -0
- package/dist/client/onboarding/index.d.ts +12 -0
- package/dist/client/onboarding/index.d.ts.map +1 -0
- package/dist/client/onboarding/index.js +11 -0
- package/dist/client/onboarding/index.js.map +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +34 -0
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
- package/dist/client/onboarding/use-onboarding.js +101 -0
- package/dist/client/onboarding/use-onboarding.js.map +1 -0
- package/dist/client/org/InvitationBanner.d.ts +9 -0
- package/dist/client/org/InvitationBanner.d.ts.map +1 -0
- package/dist/client/org/InvitationBanner.js +17 -0
- package/dist/client/org/InvitationBanner.js.map +1 -0
- package/dist/client/org/OrgSwitcher.d.ts +14 -0
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -0
- package/dist/client/org/OrgSwitcher.js +51 -0
- package/dist/client/org/OrgSwitcher.js.map +1 -0
- package/dist/client/org/TeamPage.d.ts +28 -0
- package/dist/client/org/TeamPage.d.ts.map +1 -0
- package/dist/client/org/TeamPage.js +216 -0
- package/dist/client/org/TeamPage.js.map +1 -0
- package/dist/client/org/hooks.d.ts +14 -0
- package/dist/client/org/hooks.d.ts.map +1 -0
- package/dist/client/org/hooks.js +101 -0
- package/dist/client/org/hooks.js.map +1 -0
- package/dist/client/org/index.d.ts +6 -0
- package/dist/client/org/index.d.ts.map +1 -0
- package/dist/client/org/index.js +6 -0
- package/dist/client/org/index.js.map +1 -0
- package/dist/client/resources/ResourceEditor.d.ts +8 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +141 -89
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +33 -5
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +260 -109
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +15 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +2 -2
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts +2 -0
- package/dist/client/settings/AgentsSection.d.ts.map +1 -0
- package/dist/client/settings/AgentsSection.js +198 -0
- package/dist/client/settings/AgentsSection.js.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.js +46 -0
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
- package/dist/client/settings/BrowserSection.d.ts +2 -0
- package/dist/client/settings/BrowserSection.d.ts.map +1 -0
- package/dist/client/settings/BrowserSection.js +10 -0
- package/dist/client/settings/BrowserSection.js.map +1 -0
- package/dist/client/settings/ComingSoonSection.d.ts +13 -0
- package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
- package/dist/client/settings/ComingSoonSection.js +9 -0
- package/dist/client/settings/ComingSoonSection.js.map +1 -0
- package/dist/client/settings/LLMSection.d.ts +2 -0
- package/dist/client/settings/LLMSection.d.ts.map +1 -0
- package/dist/client/settings/LLMSection.js +64 -0
- package/dist/client/settings/LLMSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
- package/dist/client/settings/SettingsPanel.js +118 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -0
- package/dist/client/settings/SettingsSection.d.ts +19 -0
- package/dist/client/settings/SettingsSection.d.ts.map +1 -0
- package/dist/client/settings/SettingsSection.js +10 -0
- package/dist/client/settings/SettingsSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.d.ts.map +1 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/client/settings/index.js.map +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +22 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.js +41 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -0
- package/dist/client/sse-event-processor.d.ts +9 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +36 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +4 -4
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +14 -14
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/use-action.d.ts +51 -0
- package/dist/client/use-action.d.ts.map +1 -0
- package/dist/client/use-action.js +102 -0
- package/dist/client/use-action.js.map +1 -0
- package/dist/client/use-avatar.d.ts +15 -0
- package/dist/client/use-avatar.d.ts.map +1 -0
- package/dist/client/use-avatar.js +116 -0
- package/dist/client/use-avatar.js.map +1 -0
- package/dist/client/use-chat-threads.d.ts +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +34 -18
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +2 -0
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts +7 -4
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +31 -10
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/collab/awareness.d.ts +41 -0
- package/dist/collab/awareness.d.ts.map +1 -0
- package/dist/collab/awareness.js +82 -0
- package/dist/collab/awareness.js.map +1 -0
- package/dist/collab/client.d.ts +49 -0
- package/dist/collab/client.d.ts.map +1 -0
- package/dist/collab/client.js +250 -0
- package/dist/collab/client.js.map +1 -0
- package/dist/collab/emitter.d.ts +12 -0
- package/dist/collab/emitter.d.ts.map +1 -0
- package/dist/collab/emitter.js +16 -0
- package/dist/collab/emitter.js.map +1 -0
- package/dist/collab/index.d.ts +7 -0
- package/dist/collab/index.d.ts.map +1 -0
- package/dist/collab/index.js +14 -0
- package/dist/collab/index.js.map +1 -0
- package/dist/collab/routes.d.ts +69 -0
- package/dist/collab/routes.d.ts.map +1 -0
- package/dist/collab/routes.js +98 -0
- package/dist/collab/routes.js.map +1 -0
- package/dist/collab/storage.d.ts +18 -0
- package/dist/collab/storage.d.ts.map +1 -0
- package/dist/collab/storage.js +94 -0
- package/dist/collab/storage.js.map +1 -0
- package/dist/collab/text-to-yjs.d.ts +23 -0
- package/dist/collab/text-to-yjs.d.ts.map +1 -0
- package/dist/collab/text-to-yjs.js +63 -0
- package/dist/collab/text-to-yjs.js.map +1 -0
- package/dist/collab/xml-ops.d.ts +20 -0
- package/dist/collab/xml-ops.d.ts.map +1 -0
- package/dist/collab/xml-ops.js +59 -0
- package/dist/collab/xml-ops.js.map +1 -0
- package/dist/collab/ydoc-manager.d.ts +52 -0
- package/dist/collab/ydoc-manager.d.ts.map +1 -0
- package/dist/collab/ydoc-manager.js +154 -0
- package/dist/collab/ydoc-manager.js.map +1 -0
- package/dist/db/client.d.ts +10 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +43 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +9 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +45 -20
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/schema.d.ts +8 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +13 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/deploy/build.js +795 -86
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +22 -4
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +148 -35
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +28 -0
- package/dist/deploy/workspace-core.d.ts.map +1 -0
- package/dist/deploy/workspace-core.js +223 -0
- package/dist/deploy/workspace-core.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts +11 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -0
- package/dist/deploy/workspace-deploy.js +148 -0
- package/dist/deploy/workspace-deploy.js.map +1 -0
- package/dist/file-upload/builder.d.ts +11 -0
- package/dist/file-upload/builder.d.ts.map +1 -0
- package/dist/file-upload/builder.js +53 -0
- package/dist/file-upload/builder.js.map +1 -0
- package/dist/file-upload/index.d.ts +4 -0
- package/dist/file-upload/index.d.ts.map +1 -0
- package/dist/file-upload/index.js +3 -0
- package/dist/file-upload/index.js.map +1 -0
- package/dist/file-upload/registry.d.ts +23 -0
- package/dist/file-upload/registry.d.ts.map +1 -0
- package/dist/file-upload/registry.js +52 -0
- package/dist/file-upload/registry.js.map +1 -0
- package/dist/file-upload/types.d.ts +37 -0
- package/dist/file-upload/types.d.ts.map +1 -0
- package/dist/file-upload/types.js +10 -0
- package/dist/file-upload/types.js.map +1 -0
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +4 -0
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/google-docs.d.ts +89 -0
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
- package/dist/integrations/adapters/google-docs.js +261 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts +10 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -0
- package/dist/integrations/adapters/slack.js +249 -0
- package/dist/integrations/adapters/slack.js.map +1 -0
- package/dist/integrations/adapters/telegram.d.ts +12 -0
- package/dist/integrations/adapters/telegram.d.ts.map +1 -0
- package/dist/integrations/adapters/telegram.js +216 -0
- package/dist/integrations/adapters/telegram.js.map +1 -0
- package/dist/integrations/adapters/whatsapp.d.ts +14 -0
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -0
- package/dist/integrations/adapters/whatsapp.js +205 -0
- package/dist/integrations/adapters/whatsapp.js.map +1 -0
- package/dist/integrations/config-store.d.ts +24 -0
- package/dist/integrations/config-store.d.ts.map +1 -0
- package/dist/integrations/config-store.js +92 -0
- package/dist/integrations/config-store.js.map +1 -0
- package/dist/integrations/google-docs-poller.d.ts +54 -0
- package/dist/integrations/google-docs-poller.d.ts.map +1 -0
- package/dist/integrations/google-docs-poller.js +442 -0
- package/dist/integrations/google-docs-poller.js.map +1 -0
- package/dist/integrations/index.d.ts +10 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +13 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/plugin.d.ts +20 -0
- package/dist/integrations/plugin.d.ts.map +1 -0
- package/dist/integrations/plugin.js +260 -0
- package/dist/integrations/plugin.js.map +1 -0
- package/dist/integrations/thread-mapping-store.d.ts +25 -0
- package/dist/integrations/thread-mapping-store.d.ts.map +1 -0
- package/dist/integrations/thread-mapping-store.js +95 -0
- package/dist/integrations/thread-mapping-store.js.map +1 -0
- package/dist/integrations/types.d.ts +144 -0
- package/dist/integrations/types.d.ts.map +1 -0
- package/dist/integrations/types.js +2 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/integrations/webhook-handler.d.ts +40 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -0
- package/dist/integrations/webhook-handler.js +220 -0
- package/dist/integrations/webhook-handler.js.map +1 -0
- package/dist/jobs/cron.d.ts +14 -0
- package/dist/jobs/cron.d.ts.map +1 -0
- package/dist/jobs/cron.js +100 -0
- package/dist/jobs/cron.js.map +1 -0
- package/dist/jobs/index.d.ts +4 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +4 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/scheduler.d.ts +32 -0
- package/dist/jobs/scheduler.d.ts.map +1 -0
- package/dist/jobs/scheduler.js +226 -0
- package/dist/jobs/scheduler.js.map +1 -0
- package/dist/jobs/tools.d.ts +3 -0
- package/dist/jobs/tools.d.ts.map +1 -0
- package/dist/jobs/tools.js +209 -0
- package/dist/jobs/tools.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +26 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +182 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp-client/config.d.ts +46 -0
- package/dist/mcp-client/config.d.ts.map +1 -0
- package/dist/mcp-client/config.js +152 -0
- package/dist/mcp-client/config.js.map +1 -0
- package/dist/mcp-client/index.d.ts +17 -0
- package/dist/mcp-client/index.d.ts.map +1 -0
- package/dist/mcp-client/index.js +53 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/manager.d.ts +76 -0
- package/dist/mcp-client/manager.d.ts.map +1 -0
- package/dist/mcp-client/manager.js +212 -0
- package/dist/mcp-client/manager.js.map +1 -0
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +5 -0
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +33 -8
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts +10 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -0
- package/dist/onboarding/default-steps.js +164 -0
- package/dist/onboarding/default-steps.js.map +1 -0
- package/dist/onboarding/index.d.ts +12 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +11 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/plugin.d.ts +19 -0
- package/dist/onboarding/plugin.d.ts.map +1 -0
- package/dist/onboarding/plugin.js +147 -0
- package/dist/onboarding/plugin.js.map +1 -0
- package/dist/onboarding/registry.d.ts +24 -0
- package/dist/onboarding/registry.d.ts.map +1 -0
- package/dist/onboarding/registry.js +40 -0
- package/dist/onboarding/registry.js.map +1 -0
- package/dist/onboarding/types.d.ts +71 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +10 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/org/context.d.ts +11 -0
- package/dist/org/context.d.ts.map +1 -0
- package/dist/org/context.js +61 -0
- package/dist/org/context.js.map +1 -0
- package/dist/org/handlers.d.ts +66 -0
- package/dist/org/handlers.d.ts.map +1 -0
- package/dist/org/handlers.js +306 -0
- package/dist/org/handlers.js.map +1 -0
- package/dist/org/index.d.ts +7 -0
- package/dist/org/index.d.ts.map +1 -0
- package/dist/org/index.js +11 -0
- package/dist/org/index.js.map +1 -0
- package/dist/org/migrations.d.ts +10 -0
- package/dist/org/migrations.d.ts.map +1 -0
- package/dist/org/migrations.js +39 -0
- package/dist/org/migrations.js.map +1 -0
- package/dist/org/plugin.d.ts +26 -0
- package/dist/org/plugin.d.ts.map +1 -0
- package/dist/org/plugin.js +94 -0
- package/dist/org/plugin.js.map +1 -0
- package/dist/org/schema.d.ts +301 -0
- package/dist/org/schema.d.ts.map +1 -0
- package/dist/org/schema.js +23 -0
- package/dist/org/schema.js.map +1 -0
- package/dist/org/types.d.ts +42 -0
- package/dist/org/types.d.ts.map +1 -0
- package/dist/org/types.js +5 -0
- package/dist/org/types.js.map +1 -0
- package/dist/resources/agents.d.ts +4 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +44 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/handlers.d.ts +27 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +121 -11
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts +48 -0
- package/dist/resources/metadata.d.ts.map +1 -0
- package/dist/resources/metadata.js +150 -0
- package/dist/resources/metadata.js.map +1 -0
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +3 -2
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts +5 -0
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +76 -17
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/agent-engines/list-agent-engines.d.ts +7 -0
- package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -0
- package/dist/scripts/agent-engines/list-agent-engines.js +42 -0
- package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -0
- package/dist/scripts/agent-engines/set-agent-engine.d.ts +7 -0
- package/dist/scripts/agent-engines/set-agent-engine.d.ts.map +1 -0
- package/dist/scripts/agent-engines/set-agent-engine.js +57 -0
- package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -0
- package/dist/scripts/agent-engines/test-agent-engine.d.ts +7 -0
- package/dist/scripts/agent-engines/test-agent-engine.d.ts.map +1 -0
- package/dist/scripts/agent-engines/test-agent-engine.js +102 -0
- package/dist/scripts/agent-engines/test-agent-engine.js.map +1 -0
- package/dist/scripts/call-agent.d.ts +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +13 -8
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/index.d.ts +2 -0
- package/dist/scripts/chat/index.d.ts.map +1 -0
- package/dist/scripts/chat/index.js +5 -0
- package/dist/scripts/chat/index.js.map +1 -0
- package/dist/scripts/chat/open-chat.d.ts +11 -0
- package/dist/scripts/chat/open-chat.d.ts.map +1 -0
- package/dist/scripts/chat/open-chat.js +48 -0
- package/dist/scripts/chat/open-chat.js.map +1 -0
- package/dist/scripts/chat/search-chats.d.ts +10 -0
- package/dist/scripts/chat/search-chats.d.ts.map +1 -0
- package/dist/scripts/chat/search-chats.js +90 -0
- package/dist/scripts/chat/search-chats.js.map +1 -0
- package/dist/scripts/core-scripts.d.ts.map +1 -1
- package/dist/scripts/core-scripts.js +4 -0
- package/dist/scripts/core-scripts.js.map +1 -1
- package/dist/scripts/db/check-scoping.d.ts +14 -0
- package/dist/scripts/db/check-scoping.d.ts.map +1 -0
- package/dist/scripts/db/check-scoping.js +174 -0
- package/dist/scripts/db/check-scoping.js.map +1 -0
- package/dist/scripts/db/exec.d.ts +3 -2
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +35 -19
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/index.d.ts.map +1 -1
- package/dist/scripts/db/index.js +2 -0
- package/dist/scripts/db/index.js.map +1 -1
- package/dist/scripts/db/patch.d.ts +50 -0
- package/dist/scripts/db/patch.d.ts.map +1 -0
- package/dist/scripts/db/patch.js +392 -0
- package/dist/scripts/db/patch.js.map +1 -0
- package/dist/scripts/db/scoping.d.ts +8 -2
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +66 -47
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/dev/index.d.ts.map +1 -1
- package/dist/scripts/dev/index.js +64 -1
- package/dist/scripts/dev/index.js.map +1 -1
- package/dist/scripts/docs/index.d.ts +2 -0
- package/dist/scripts/docs/index.d.ts.map +1 -0
- package/dist/scripts/docs/index.js +4 -0
- package/dist/scripts/docs/index.js.map +1 -0
- package/dist/scripts/docs/search.d.ts +13 -0
- package/dist/scripts/docs/search.d.ts.map +1 -0
- package/dist/scripts/docs/search.js +130 -0
- package/dist/scripts/docs/search.js.map +1 -0
- package/dist/scripts/parse-args.d.ts +14 -0
- package/dist/scripts/parse-args.d.ts.map +1 -0
- package/dist/scripts/parse-args.js +45 -0
- package/dist/scripts/parse-args.js.map +1 -0
- package/dist/scripts/resources/delete-memory.d.ts +7 -0
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
- package/dist/scripts/resources/delete-memory.js +49 -0
- package/dist/scripts/resources/delete-memory.js.map +1 -0
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/index.d.ts.map +1 -1
- package/dist/scripts/resources/index.js +2 -0
- package/dist/scripts/resources/index.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts +9 -0
- package/dist/scripts/resources/save-memory.d.ts.map +1 -0
- package/dist/scripts/resources/save-memory.js +78 -0
- package/dist/scripts/resources/save-memory.js.map +1 -0
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/scripts/runner.d.ts.map +1 -1
- package/dist/scripts/runner.js +10 -2
- package/dist/scripts/runner.js.map +1 -1
- package/dist/scripts/utils.d.ts +9 -8
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +40 -35
- package/dist/scripts/utils.js.map +1 -1
- package/dist/server/action-discovery.d.ts +5 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +132 -33
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts +15 -0
- package/dist/server/action-routes.d.ts.map +1 -0
- package/dist/server/action-routes.js +111 -0
- package/dist/server/action-routes.js.map +1 -0
- package/dist/server/agent-chat-plugin.d.ts +23 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +1474 -266
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +8 -3
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +57 -8
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts +70 -0
- package/dist/server/agent-teams.d.ts.map +1 -0
- package/dist/server/agent-teams.js +368 -0
- package/dist/server/agent-teams.js.map +1 -0
- package/dist/server/agents-bundle.d.ts +115 -0
- package/dist/server/agents-bundle.d.ts.map +1 -0
- package/dist/server/agents-bundle.js +275 -0
- package/dist/server/agents-bundle.js.map +1 -0
- package/dist/server/auth-plugin.d.ts +3 -3
- package/dist/server/auth-plugin.d.ts.map +1 -1
- package/dist/server/auth-plugin.js +9 -10
- package/dist/server/auth-plugin.js.map +1 -1
- package/dist/server/auth.d.ts +55 -33
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +640 -610
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +72 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -0
- package/dist/server/better-auth-instance.js +340 -0
- package/dist/server/better-auth-instance.js.map +1 -0
- package/dist/server/builder-browser.d.ts +40 -0
- package/dist/server/builder-browser.d.ts.map +1 -0
- package/dist/server/builder-browser.js +166 -0
- package/dist/server/builder-browser.js.map +1 -0
- package/dist/server/collab-plugin.d.ts +29 -0
- package/dist/server/collab-plugin.d.ts.map +1 -0
- package/dist/server/collab-plugin.js +85 -0
- package/dist/server/collab-plugin.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts +0 -3
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +248 -32
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +1 -1
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +39 -16
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts +37 -0
- package/dist/server/credential-provider.d.ts.map +1 -0
- package/dist/server/credential-provider.js +49 -0
- package/dist/server/credential-provider.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts +47 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -0
- package/dist/server/framework-request-handler.js +207 -0
- package/dist/server/framework-request-handler.js.map +1 -0
- package/dist/server/google-auth-plugin.d.ts +4 -0
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +14 -13
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts +3 -3
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +51 -24
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/h3-helpers.d.ts +23 -0
- package/dist/server/h3-helpers.d.ts.map +1 -0
- package/dist/server/h3-helpers.js +37 -0
- package/dist/server/h3-helpers.js.map +1 -0
- package/dist/server/index.d.ts +12 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +15 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/local-migration.d.ts +32 -0
- package/dist/server/local-migration.d.ts.map +1 -0
- package/dist/server/local-migration.js +205 -0
- package/dist/server/local-migration.js.map +1 -0
- package/dist/server/oauth-helpers.d.ts +5 -6
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +10 -11
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +24 -0
- package/dist/server/onboarding-html.d.ts.map +1 -0
- package/dist/server/onboarding-html.js +438 -0
- package/dist/server/onboarding-html.js.map +1 -0
- package/dist/server/poll.d.ts +7 -2
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +48 -1
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +20 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +41 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/resources-plugin.d.ts.map +1 -1
- package/dist/server/resources-plugin.js +4 -3
- package/dist/server/resources-plugin.js.map +1 -1
- package/dist/server/schema-prompt.d.ts +16 -0
- package/dist/server/schema-prompt.d.ts.map +1 -0
- package/dist/server/schema-prompt.js +275 -0
- package/dist/server/schema-prompt.js.map +1 -0
- package/dist/server/sse.d.ts +3 -20
- package/dist/server/sse.d.ts.map +1 -1
- package/dist/server/sse.js +1 -29
- package/dist/server/sse.js.map +1 -1
- package/dist/server/ssr-handler.d.ts +6 -0
- package/dist/server/ssr-handler.d.ts.map +1 -0
- package/dist/server/ssr-handler.js +55 -0
- package/dist/server/ssr-handler.js.map +1 -0
- package/dist/settings/handlers.d.ts +3 -3
- package/dist/settings/handlers.d.ts.map +1 -1
- package/dist/settings/handlers.js +2 -1
- package/dist/settings/handlers.js.map +1 -1
- package/dist/settings/index.d.ts +1 -0
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +2 -0
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/org-settings.d.ts +22 -0
- package/dist/settings/org-settings.d.ts.map +1 -0
- package/dist/settings/org-settings.js +45 -0
- package/dist/settings/org-settings.js.map +1 -0
- package/dist/shared/agent-chat.d.ts +5 -5
- package/dist/shared/agent-chat.d.ts.map +1 -1
- package/dist/shared/agent-chat.js +8 -8
- package/dist/shared/agent-chat.js.map +1 -1
- package/dist/shared/agent-env.d.ts +1 -1
- package/dist/shared/agent-env.js +1 -1
- package/dist/shared/runtime.d.ts +14 -0
- package/dist/shared/runtime.d.ts.map +1 -0
- package/dist/shared/runtime.js +25 -0
- package/dist/shared/runtime.js.map +1 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +143 -0
- package/dist/templates/default/.agents/skills/agent-engines/SKILL.md +127 -0
- package/dist/templates/default/.agents/skills/capture-learnings/SKILL.md +50 -0
- package/dist/templates/default/.agents/skills/create-skill/SKILL.md +167 -0
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +90 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +69 -0
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +183 -0
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/security/SKILL.md +213 -0
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +79 -0
- package/{src/templates/default/.agents/skills/files-as-database → dist/templates/default/.agents/skills/storing-data}/SKILL.md +7 -1
- package/dist/templates/default/.claude/settings.json +100 -0
- package/dist/templates/default/.env.example +5 -0
- package/dist/templates/default/.prettierrc +5 -0
- package/dist/templates/default/AGENTS.md +110 -0
- package/dist/templates/default/DEVELOPING.md +117 -0
- package/dist/templates/default/_gitignore +38 -0
- package/dist/templates/default/actions/hello.ts +20 -0
- package/dist/templates/default/actions/navigate.ts +53 -0
- package/dist/templates/default/actions/run.ts +2 -0
- package/dist/templates/default/actions/view-screen.ts +39 -0
- package/dist/templates/default/app/entry.client.tsx +4 -0
- package/dist/templates/default/app/entry.server.tsx +56 -0
- package/dist/templates/default/app/global.css +95 -0
- package/dist/templates/default/app/lib/utils.ts +1 -0
- package/dist/templates/default/app/root.tsx +110 -0
- package/dist/templates/default/app/routes/_index.tsx +62 -0
- package/dist/templates/default/app/routes.ts +4 -0
- package/dist/templates/default/app/vite-env.d.ts +6 -0
- package/dist/templates/default/components.json +20 -0
- package/dist/templates/default/data/.gitkeep +0 -0
- package/dist/templates/default/data/sync-config.json +1 -0
- package/dist/templates/default/learnings.defaults.md +5 -0
- package/dist/templates/default/learnings.md +0 -0
- package/dist/templates/default/package.json +46 -0
- package/dist/templates/default/postcss.config.js +6 -0
- package/dist/templates/default/public/icon-180.svg +4 -0
- package/dist/templates/default/public/icon-192.svg +4 -0
- package/dist/templates/default/public/icon-512.svg +4 -0
- package/dist/templates/default/public/manifest.json +13 -0
- package/dist/templates/default/react-router.config.ts +6 -0
- package/dist/templates/default/server/middleware/auth.ts +15 -0
- package/dist/templates/default/server/plugins/.gitkeep +0 -0
- package/dist/templates/default/server/routes/[...page].get.ts +5 -0
- package/dist/templates/default/server/routes/api/hello.get.ts +5 -0
- package/dist/templates/default/shared/api.ts +6 -0
- package/dist/templates/default/ssr-entry.ts +20 -0
- package/dist/templates/default/tailwind.config.ts +7 -0
- package/dist/templates/default/tsconfig.json +11 -0
- package/dist/templates/default/vite.config.ts +6 -0
- package/dist/templates/workspace-core/AGENTS.md +62 -0
- package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
- package/dist/templates/workspace-core/package.json +39 -0
- package/dist/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/dist/templates/workspace-core/src/client/index.ts +26 -0
- package/dist/templates/workspace-core/src/credentials.ts +29 -0
- package/dist/templates/workspace-core/src/index.ts +21 -0
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/dist/templates/workspace-core/src/server/index.ts +22 -0
- package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
- package/dist/templates/workspace-core/tsconfig.json +9 -0
- package/dist/templates/workspace-root/.env.example +37 -0
- package/dist/templates/workspace-root/README.md +62 -0
- package/dist/templates/workspace-root/_gitignore +23 -0
- package/dist/templates/workspace-root/package.json +18 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/dist/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/terminal/cli-registry.d.ts +1 -1
- package/dist/terminal/cli-registry.d.ts.map +1 -1
- package/dist/terminal/cli-registry.js +7 -7
- package/dist/terminal/cli-registry.js.map +1 -1
- package/dist/terminal/pty-server.d.ts +1 -1
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +34 -12
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/terminal/terminal-plugin.d.ts +0 -9
- package/dist/terminal/terminal-plugin.d.ts.map +1 -1
- package/dist/terminal/terminal-plugin.js +57 -14
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/dist/usage/store.d.ts +29 -0
- package/dist/usage/store.d.ts.map +1 -0
- package/dist/usage/store.js +102 -0
- package/dist/usage/store.js.map +1 -0
- package/dist/vite/action-types-plugin.d.ts +13 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -0
- package/dist/vite/action-types-plugin.js +132 -0
- package/dist/vite/action-types-plugin.js.map +1 -0
- package/dist/vite/agents-bundle-plugin.d.ts +3 -0
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -0
- package/dist/vite/agents-bundle-plugin.js +137 -0
- package/dist/vite/agents-bundle-plugin.js.map +1 -0
- package/dist/vite/client.d.ts +21 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +297 -37
- package/dist/vite/client.js.map +1 -1
- package/dist/vite/index.d.ts +2 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +2 -1
- package/dist/vite/index.js.map +1 -1
- package/docs/content/a2a-protocol.md +223 -0
- package/docs/content/actions.md +129 -0
- package/docs/content/agent-mentions.md +171 -0
- package/docs/content/authentication.md +155 -0
- package/docs/content/cli-adapters.md +244 -0
- package/docs/content/client.md +175 -0
- package/docs/content/context-awareness.md +168 -0
- package/docs/content/creating-templates.md +311 -0
- package/docs/content/database.md +82 -0
- package/docs/content/deployment.md +180 -0
- package/docs/content/enterprise-workspace.md +235 -0
- package/docs/content/faq.md +101 -0
- package/docs/content/file-uploads.md +102 -0
- package/docs/content/frames.md +47 -0
- package/docs/content/getting-started.md +104 -0
- package/docs/content/integrations.md +198 -0
- package/docs/content/key-concepts.md +246 -0
- package/docs/content/mcp-clients.md +110 -0
- package/docs/content/mcp-protocol.md +168 -0
- package/docs/content/onboarding.md +107 -0
- package/docs/content/real-time-collaboration.md +185 -0
- package/docs/content/resources.md +277 -0
- package/docs/content/security.md +158 -0
- package/docs/content/server.md +200 -0
- package/docs/content/skills-guide.md +107 -0
- package/docs/content/what-is-agent-native.md +100 -0
- package/docs/content/workspace-management.md +224 -0
- package/package.json +78 -20
- package/src/templates/default/.agents/skills/actions/SKILL.md +14 -7
- package/src/templates/default/.agents/skills/agent-engines/SKILL.md +127 -0
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +183 -0
- package/src/templates/default/.agents/skills/security/SKILL.md +213 -0
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +116 -0
- package/src/templates/default/.claude/settings.json +13 -0
- package/src/templates/default/AGENTS.md +25 -9
- package/src/templates/default/_gitignore +1 -0
- package/src/templates/default/actions/view-screen.ts +1 -1
- package/src/templates/default/app/root.tsx +4 -1
- package/src/templates/default/package.json +2 -2
- package/src/templates/default/server/middleware/auth.ts +15 -0
- package/src/templates/default/server/routes/[...page].get.ts +2 -9
- package/src/templates/default/ssr-entry.ts +20 -0
- package/src/templates/workspace-core/AGENTS.md +62 -0
- package/src/templates/workspace-core/actions/company-directory.ts +38 -0
- package/src/templates/workspace-core/package.json +39 -0
- package/src/templates/workspace-core/skills/company-policies/SKILL.md +42 -0
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/src/templates/workspace-core/src/client/index.ts +26 -0
- package/src/templates/workspace-core/src/credentials.ts +29 -0
- package/src/templates/workspace-core/src/index.ts +21 -0
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/src/templates/workspace-core/src/server/index.ts +22 -0
- package/src/templates/workspace-core/tailwind.preset.ts +34 -0
- package/src/templates/workspace-core/tsconfig.json +9 -0
- package/src/templates/workspace-root/.env.example +37 -0
- package/src/templates/workspace-root/README.md +62 -0
- package/src/templates/workspace-root/_gitignore +23 -0
- package/src/templates/workspace-root/package.json +18 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/src/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/adapters/convex/adapter.d.ts +0 -24
- package/dist/adapters/convex/adapter.d.ts.map +0 -1
- package/dist/adapters/convex/adapter.js +0 -125
- package/dist/adapters/convex/adapter.js.map +0 -1
- package/dist/adapters/convex/index.d.ts +0 -4
- package/dist/adapters/convex/index.d.ts.map +0 -1
- package/dist/adapters/convex/index.js +0 -3
- package/dist/adapters/convex/index.js.map +0 -1
- package/dist/adapters/drizzle/adapter.d.ts +0 -36
- package/dist/adapters/drizzle/adapter.d.ts.map +0 -1
- package/dist/adapters/drizzle/adapter.js +0 -210
- package/dist/adapters/drizzle/adapter.js.map +0 -1
- package/dist/adapters/drizzle/index.d.ts +0 -3
- package/dist/adapters/drizzle/index.d.ts.map +0 -1
- package/dist/adapters/drizzle/index.js +0 -3
- package/dist/adapters/drizzle/index.js.map +0 -1
- package/dist/adapters/drizzle/schema.d.ts +0 -146
- package/dist/adapters/drizzle/schema.d.ts.map +0 -1
- package/dist/adapters/drizzle/schema.js +0 -20
- package/dist/adapters/drizzle/schema.js.map +0 -1
- package/dist/adapters/firestore/adapter.d.ts +0 -48
- package/dist/adapters/firestore/adapter.d.ts.map +0 -1
- package/dist/adapters/firestore/adapter.js +0 -62
- package/dist/adapters/firestore/adapter.js.map +0 -1
- package/dist/adapters/firestore/index.d.ts +0 -4
- package/dist/adapters/firestore/index.d.ts.map +0 -1
- package/dist/adapters/firestore/index.js +0 -3
- package/dist/adapters/firestore/index.js.map +0 -1
- package/dist/adapters/supabase/adapter.d.ts +0 -43
- package/dist/adapters/supabase/adapter.d.ts.map +0 -1
- package/dist/adapters/supabase/adapter.js +0 -137
- package/dist/adapters/supabase/adapter.js.map +0 -1
- package/dist/adapters/supabase/index.d.ts +0 -3
- package/dist/adapters/supabase/index.d.ts.map +0 -1
- package/dist/adapters/supabase/index.js +0 -3
- package/dist/adapters/supabase/index.js.map +0 -1
- package/dist/adapters/sync/config.d.ts +0 -40
- package/dist/adapters/sync/config.d.ts.map +0 -1
- package/dist/adapters/sync/config.js +0 -209
- package/dist/adapters/sync/config.js.map +0 -1
- package/dist/adapters/sync/create-file-sync.d.ts +0 -32
- package/dist/adapters/sync/create-file-sync.d.ts.map +0 -1
- package/dist/adapters/sync/create-file-sync.js +0 -218
- package/dist/adapters/sync/create-file-sync.js.map +0 -1
- package/dist/adapters/sync/file-sync.d.ts +0 -94
- package/dist/adapters/sync/file-sync.d.ts.map +0 -1
- package/dist/adapters/sync/file-sync.js +0 -671
- package/dist/adapters/sync/file-sync.js.map +0 -1
- package/dist/adapters/sync/index.d.ts +0 -6
- package/dist/adapters/sync/index.d.ts.map +0 -1
- package/dist/adapters/sync/index.js +0 -6
- package/dist/adapters/sync/index.js.map +0 -1
- package/dist/adapters/sync/merge.d.ts +0 -21
- package/dist/adapters/sync/merge.d.ts.map +0 -1
- package/dist/adapters/sync/merge.js +0 -132
- package/dist/adapters/sync/merge.js.map +0 -1
- package/dist/adapters/sync/types.d.ts +0 -62
- package/dist/adapters/sync/types.d.ts.map +0 -1
- package/dist/adapters/sync/types.js +0 -23
- package/dist/adapters/sync/types.js.map +0 -1
- package/dist/client/harness.d.ts +0 -48
- package/dist/client/harness.d.ts.map +0 -1
- package/dist/client/harness.js.map +0 -1
- package/dist/client/use-file-sync-status.d.ts +0 -21
- package/dist/client/use-file-sync-status.d.ts.map +0 -1
- package/dist/client/use-file-sync-status.js +0 -65
- package/dist/client/use-file-sync-status.js.map +0 -1
- package/dist/server/default-watcher.d.ts +0 -23
- package/dist/server/default-watcher.d.ts.map +0 -1
- package/dist/server/default-watcher.js +0 -57
- package/dist/server/default-watcher.js.map +0 -1
- package/dist/server/file-sync-plugin.d.ts +0 -7
- package/dist/server/file-sync-plugin.d.ts.map +0 -1
- package/dist/server/file-sync-plugin.js +0 -38
- package/dist/server/file-sync-plugin.js.map +0 -1
- package/dist/vite/dev-api-server.d.ts +0 -10
- package/dist/vite/dev-api-server.d.ts.map +0 -1
- package/dist/vite/dev-api-server.js +0 -243
- package/dist/vite/dev-api-server.js.map +0 -1
- /package/{src/templates/default/application-state/.gitkeep → dist/templates/default/.ignore} +0 -0
|
@@ -1,11 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runWithRequestContext, getRequestOrgId } from "./request-context.js";
|
|
2
|
+
import { getH3App } from "./framework-request-handler.js";
|
|
3
|
+
import { createProductionAgentHandler, runAgentLoop, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, } from "../agent/production-agent.js";
|
|
4
|
+
import { resolveEngine, createAnthropicEngine } from "../agent/engine/index.js";
|
|
5
|
+
import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, } from "../mcp-client/index.js";
|
|
6
|
+
import { discoverAgents } from "./agent-discovery.js";
|
|
7
|
+
import { loadSchemaPromptBlock } from "./schema-prompt.js";
|
|
2
8
|
import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-builder.js";
|
|
3
|
-
import { defineEventHandler,
|
|
9
|
+
import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, } from "h3";
|
|
4
10
|
import { getSession } from "./auth.js";
|
|
11
|
+
import { getOrigin } from "./google-oauth.js";
|
|
5
12
|
import { createThread, getThread, listThreads, searchThreads, updateThreadData, deleteThread, } from "../chat-threads/store.js";
|
|
6
13
|
import { resourceListAccessible, resourceList, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, } from "../resources/store.js";
|
|
7
|
-
import fs from "node:fs";
|
|
8
14
|
import nodePath from "node:path";
|
|
15
|
+
import { readBody } from "./h3-helpers.js";
|
|
16
|
+
import { getBuilderBrowserConnectUrl, requestBuilderBrowserConnection, } from "./builder-browser.js";
|
|
17
|
+
// Lazy fs — loaded via dynamic import() on first use.
|
|
18
|
+
// This avoids require() which bundlers convert to createRequire(import.meta.url)
|
|
19
|
+
// that crashes on CF Workers where import.meta.url is undefined.
|
|
20
|
+
let _fs;
|
|
21
|
+
async function lazyFs() {
|
|
22
|
+
if (!_fs) {
|
|
23
|
+
_fs = await import("node:fs");
|
|
24
|
+
}
|
|
25
|
+
return _fs;
|
|
26
|
+
}
|
|
9
27
|
/**
|
|
10
28
|
* Wraps a core CLI script (that writes to console.log) as a ActionEntry
|
|
11
29
|
* by capturing stdout.
|
|
@@ -54,16 +72,53 @@ function wrapCliScript(tool, cliDefault) {
|
|
|
54
72
|
},
|
|
55
73
|
};
|
|
56
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates the docs-search tool so agents can look up framework documentation.
|
|
77
|
+
* Docs are bundled in @agent-native/core and read via fs at runtime.
|
|
78
|
+
*/
|
|
79
|
+
async function createDocsScriptEntries() {
|
|
80
|
+
try {
|
|
81
|
+
const mod = await import("../scripts/docs/search.js");
|
|
82
|
+
return {
|
|
83
|
+
"docs-search": wrapCliScript({
|
|
84
|
+
description: "Search and read agent-native framework documentation. Use --list to see all pages, --query to search, --slug to read a specific page.",
|
|
85
|
+
parameters: {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
query: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Search term to find relevant docs (e.g. 'actions', 'authentication', 'database')",
|
|
91
|
+
},
|
|
92
|
+
slug: {
|
|
93
|
+
type: "string",
|
|
94
|
+
description: "Read a specific doc page by slug (e.g. 'actions', 'authentication', 'database')",
|
|
95
|
+
},
|
|
96
|
+
list: {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: 'Set to "true" to list all available doc pages',
|
|
99
|
+
enum: ["true"],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
}, mod.default),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
57
110
|
/**
|
|
58
111
|
* Creates resource ScriptEntries available in both prod and dev modes.
|
|
59
112
|
*/
|
|
60
113
|
async function createResourceScriptEntries() {
|
|
61
114
|
try {
|
|
62
|
-
const [list, read, write, del] = await Promise.all([
|
|
115
|
+
const [list, read, write, del, saveMem, delMem] = await Promise.all([
|
|
63
116
|
import("../scripts/resources/list.js"),
|
|
64
117
|
import("../scripts/resources/read.js"),
|
|
65
118
|
import("../scripts/resources/write.js"),
|
|
66
119
|
import("../scripts/resources/delete.js"),
|
|
120
|
+
import("../scripts/resources/save-memory.js"),
|
|
121
|
+
import("../scripts/resources/delete-memory.js"),
|
|
67
122
|
]);
|
|
68
123
|
return {
|
|
69
124
|
"resource-list": wrapCliScript({
|
|
@@ -150,6 +205,45 @@ async function createResourceScriptEntries() {
|
|
|
150
205
|
required: ["path"],
|
|
151
206
|
},
|
|
152
207
|
}, del.default),
|
|
208
|
+
"save-memory": wrapCliScript({
|
|
209
|
+
description: "Save a memory for future conversations. Creates or updates a memory file and its index entry. Use proactively when you learn preferences, corrections, project context, or references.",
|
|
210
|
+
parameters: {
|
|
211
|
+
type: "object",
|
|
212
|
+
properties: {
|
|
213
|
+
name: {
|
|
214
|
+
type: "string",
|
|
215
|
+
description: "Short kebab-case identifier (e.g. 'coding-style', 'deploy-process'). Used as the filename.",
|
|
216
|
+
},
|
|
217
|
+
type: {
|
|
218
|
+
type: "string",
|
|
219
|
+
description: "Memory category",
|
|
220
|
+
enum: ["user", "feedback", "project", "reference"],
|
|
221
|
+
},
|
|
222
|
+
description: {
|
|
223
|
+
type: "string",
|
|
224
|
+
description: "One-line summary shown in the memory index (keep under 80 chars)",
|
|
225
|
+
},
|
|
226
|
+
content: {
|
|
227
|
+
type: "string",
|
|
228
|
+
description: "The memory content in markdown. For updates, read first and provide full updated content.",
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
required: ["name", "type", "description", "content"],
|
|
232
|
+
},
|
|
233
|
+
}, saveMem.default),
|
|
234
|
+
"delete-memory": wrapCliScript({
|
|
235
|
+
description: "Delete a memory entry and remove it from the memory index.",
|
|
236
|
+
parameters: {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
name: {
|
|
240
|
+
type: "string",
|
|
241
|
+
description: "The memory name to delete (e.g. 'coding-style')",
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
required: ["name"],
|
|
245
|
+
},
|
|
246
|
+
}, delMem.default),
|
|
153
247
|
};
|
|
154
248
|
}
|
|
155
249
|
catch {
|
|
@@ -157,16 +251,88 @@ async function createResourceScriptEntries() {
|
|
|
157
251
|
return {};
|
|
158
252
|
}
|
|
159
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Creates chat management ActionEntries (search-chats, open-chat).
|
|
256
|
+
*/
|
|
257
|
+
async function createChatScriptEntries() {
|
|
258
|
+
try {
|
|
259
|
+
const [searchMod, openMod] = await Promise.all([
|
|
260
|
+
import("../scripts/chat/search-chats.js"),
|
|
261
|
+
import("../scripts/chat/open-chat.js"),
|
|
262
|
+
]);
|
|
263
|
+
return {
|
|
264
|
+
"search-chats": wrapCliScript({
|
|
265
|
+
description: "Search or list past agent chat threads. Use this to find previous conversations by keyword.",
|
|
266
|
+
parameters: {
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: {
|
|
269
|
+
query: {
|
|
270
|
+
type: "string",
|
|
271
|
+
description: "Search term to find chats by title, preview, or content",
|
|
272
|
+
},
|
|
273
|
+
limit: {
|
|
274
|
+
type: "string",
|
|
275
|
+
description: "Max number of results (default: 20)",
|
|
276
|
+
},
|
|
277
|
+
format: {
|
|
278
|
+
type: "string",
|
|
279
|
+
description: "Output format",
|
|
280
|
+
enum: ["json", "text"],
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
}, searchMod.default),
|
|
285
|
+
"open-chat": wrapCliScript({
|
|
286
|
+
description: "Open a chat thread in the UI as a new tab and focus it. Use search-chats first to find the thread ID.",
|
|
287
|
+
parameters: {
|
|
288
|
+
type: "object",
|
|
289
|
+
properties: {
|
|
290
|
+
id: {
|
|
291
|
+
type: "string",
|
|
292
|
+
description: "The chat thread ID to open",
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
required: ["id"],
|
|
296
|
+
},
|
|
297
|
+
}, openMod.default),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return {};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Creates agent engine management tools (list-agent-engines, set-agent-engine,
|
|
306
|
+
* test-agent-engine). Let the agent inspect and configure the active LLM engine.
|
|
307
|
+
*/
|
|
308
|
+
async function createAgentEngineScriptEntries() {
|
|
309
|
+
try {
|
|
310
|
+
const [listMod, setMod, testMod] = await Promise.all([
|
|
311
|
+
import("../scripts/agent-engines/list-agent-engines.js"),
|
|
312
|
+
import("../scripts/agent-engines/set-agent-engine.js"),
|
|
313
|
+
import("../scripts/agent-engines/test-agent-engine.js"),
|
|
314
|
+
]);
|
|
315
|
+
return {
|
|
316
|
+
"list-agent-engines": { tool: listMod.tool, run: listMod.run },
|
|
317
|
+
"set-agent-engine": { tool: setMod.tool, run: setMod.run },
|
|
318
|
+
"test-agent-engine": { tool: testMod.tool, run: testMod.run },
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
return {};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
160
325
|
/**
|
|
161
326
|
* Creates the call-agent ActionEntry for cross-agent A2A communication.
|
|
327
|
+
* Binds selfAppId so the agent cannot call itself via call-agent.
|
|
162
328
|
*/
|
|
163
|
-
async function createCallAgentScriptEntry() {
|
|
329
|
+
async function createCallAgentScriptEntry(selfAppId) {
|
|
164
330
|
try {
|
|
165
331
|
const mod = await import("../scripts/call-agent.js");
|
|
166
332
|
return {
|
|
167
333
|
"call-agent": {
|
|
168
334
|
tool: mod.tool,
|
|
169
|
-
run: mod.run,
|
|
335
|
+
run: (args, context) => mod.run(args, context, selfAppId),
|
|
170
336
|
},
|
|
171
337
|
};
|
|
172
338
|
}
|
|
@@ -174,6 +340,269 @@ async function createCallAgentScriptEntry() {
|
|
|
174
340
|
return {};
|
|
175
341
|
}
|
|
176
342
|
}
|
|
343
|
+
function createBuilderBrowserTool(deps) {
|
|
344
|
+
return {
|
|
345
|
+
"get-browser-connection": {
|
|
346
|
+
tool: {
|
|
347
|
+
description: "Provision a Builder-backed browser session and return browser websocket connection details. If Builder browser access is not configured yet, this returns setup guidance instead.",
|
|
348
|
+
parameters: {
|
|
349
|
+
type: "object",
|
|
350
|
+
properties: {
|
|
351
|
+
sessionId: {
|
|
352
|
+
type: "string",
|
|
353
|
+
description: "Stable browser session identifier. Reuse it to reconnect to the same browser session.",
|
|
354
|
+
},
|
|
355
|
+
projectId: {
|
|
356
|
+
type: "string",
|
|
357
|
+
description: "Optional Builder project or space identifier to scope the session.",
|
|
358
|
+
},
|
|
359
|
+
branchName: {
|
|
360
|
+
type: "string",
|
|
361
|
+
description: "Optional branch name for Builder preview sessions.",
|
|
362
|
+
},
|
|
363
|
+
proxyOrigin: {
|
|
364
|
+
type: "string",
|
|
365
|
+
description: "Optional source origin to proxy from when browsing a local app.",
|
|
366
|
+
},
|
|
367
|
+
proxyDefaultOrigin: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "Optional default origin that the browser should use for proxied requests.",
|
|
370
|
+
},
|
|
371
|
+
proxyDestination: {
|
|
372
|
+
type: "string",
|
|
373
|
+
description: "Optional destination origin for proxying local development traffic.",
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
required: ["sessionId"],
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
run: async (args) => {
|
|
380
|
+
if (!process.env.BUILDER_PRIVATE_KEY ||
|
|
381
|
+
!process.env.BUILDER_PUBLIC_KEY) {
|
|
382
|
+
return JSON.stringify({
|
|
383
|
+
configured: false,
|
|
384
|
+
message: "Builder browser access is not configured. Connect Builder from the workspace Resources panel before requesting a browser session.",
|
|
385
|
+
connectUrl: getBuilderBrowserConnectUrl(deps.getOrigin()),
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
const connection = await requestBuilderBrowserConnection({
|
|
389
|
+
sessionId: args.sessionId,
|
|
390
|
+
projectId: args.projectId,
|
|
391
|
+
branchName: args.branchName,
|
|
392
|
+
proxyOrigin: args.proxyOrigin,
|
|
393
|
+
proxyDefaultOrigin: args.proxyDefaultOrigin,
|
|
394
|
+
proxyDestination: args.proxyDestination,
|
|
395
|
+
});
|
|
396
|
+
return JSON.stringify({
|
|
397
|
+
configured: true,
|
|
398
|
+
sessionId: args.sessionId,
|
|
399
|
+
...connection,
|
|
400
|
+
});
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Creates agent team orchestration tools (spawn-task, task-status, read-task-result).
|
|
407
|
+
* These let the main agent spawn sub-agents and coordinate work.
|
|
408
|
+
*/
|
|
409
|
+
function createTeamTools(deps) {
|
|
410
|
+
return {
|
|
411
|
+
"spawn-task": {
|
|
412
|
+
tool: {
|
|
413
|
+
description: "Spawn a sub-agent to handle a task in the background. The sub-agent runs independently with its own conversation thread. Use this to delegate work so the main chat stays free for new requests. A live preview card will appear in the chat showing the sub-agent's progress.",
|
|
414
|
+
parameters: {
|
|
415
|
+
type: "object",
|
|
416
|
+
properties: {
|
|
417
|
+
task: {
|
|
418
|
+
type: "string",
|
|
419
|
+
description: "Clear description of what the sub-agent should accomplish",
|
|
420
|
+
},
|
|
421
|
+
instructions: {
|
|
422
|
+
type: "string",
|
|
423
|
+
description: "Optional additional instructions or context for the sub-agent",
|
|
424
|
+
},
|
|
425
|
+
name: {
|
|
426
|
+
type: "string",
|
|
427
|
+
description: "Short name for the sub-agent tab (e.g. 'Research', 'Draft email'). If omitted, derived from the task.",
|
|
428
|
+
},
|
|
429
|
+
agent: {
|
|
430
|
+
type: "string",
|
|
431
|
+
description: "Optional custom agent profile from agents/*.md to use for this task.",
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
required: ["task"],
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
run: async (args) => {
|
|
438
|
+
// Capture the send function NOW (at spawn time) so that
|
|
439
|
+
// concurrent runs don't clobber each other's send reference.
|
|
440
|
+
const capturedSend = deps.getSend();
|
|
441
|
+
const { spawnTask } = await import("./agent-teams.js");
|
|
442
|
+
// Filter out team orchestration tools so sub-agents can't spawn sub-agents
|
|
443
|
+
const teamToolNames = new Set([
|
|
444
|
+
"spawn-task",
|
|
445
|
+
"task-status",
|
|
446
|
+
"read-task-result",
|
|
447
|
+
"send-to-task",
|
|
448
|
+
"list-tasks",
|
|
449
|
+
]);
|
|
450
|
+
const subAgentActions = Object.fromEntries(Object.entries(deps.getActions()).filter(([name]) => !teamToolNames.has(name)));
|
|
451
|
+
let instructions = args.instructions;
|
|
452
|
+
let selectedModel = deps.getModel();
|
|
453
|
+
let selectedName = args.name || "";
|
|
454
|
+
if (args.agent) {
|
|
455
|
+
const { findAccessibleCustomAgent } = await import("../resources/agents.js");
|
|
456
|
+
const profile = await findAccessibleCustomAgent(deps.getOwner(), args.agent);
|
|
457
|
+
if (!profile) {
|
|
458
|
+
throw new Error(`Custom agent not found: ${args.agent}`);
|
|
459
|
+
}
|
|
460
|
+
const profileInstructions = `## Custom Agent Profile: ${profile.name}\n\n` +
|
|
461
|
+
(profile.description ? `${profile.description}\n\n` : "") +
|
|
462
|
+
profile.instructions;
|
|
463
|
+
instructions = instructions
|
|
464
|
+
? `${profileInstructions}\n\n## Extra Task Context\n\n${instructions}`
|
|
465
|
+
: profileInstructions;
|
|
466
|
+
selectedModel = profile.model ?? selectedModel;
|
|
467
|
+
selectedName = selectedName || profile.name;
|
|
468
|
+
}
|
|
469
|
+
const task = await spawnTask({
|
|
470
|
+
description: args.task,
|
|
471
|
+
instructions,
|
|
472
|
+
ownerEmail: deps.getOwner(),
|
|
473
|
+
systemPrompt: deps.getSystemPrompt(),
|
|
474
|
+
actions: subAgentActions,
|
|
475
|
+
engine: deps.getEngine(),
|
|
476
|
+
model: selectedModel,
|
|
477
|
+
parentThreadId: deps.getParentThreadId(),
|
|
478
|
+
parentSend: (event) => {
|
|
479
|
+
if (capturedSend)
|
|
480
|
+
capturedSend(event);
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
return JSON.stringify({
|
|
484
|
+
taskId: task.taskId,
|
|
485
|
+
threadId: task.threadId,
|
|
486
|
+
status: task.status,
|
|
487
|
+
description: task.description,
|
|
488
|
+
name: selectedName,
|
|
489
|
+
});
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
"task-status": {
|
|
493
|
+
tool: {
|
|
494
|
+
description: "Check the status of a sub-agent task. Returns current status, preview of output, and current step.",
|
|
495
|
+
parameters: {
|
|
496
|
+
type: "object",
|
|
497
|
+
properties: {
|
|
498
|
+
taskId: {
|
|
499
|
+
type: "string",
|
|
500
|
+
description: "The task ID returned by spawn-task",
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
required: ["taskId"],
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
run: async (args) => {
|
|
507
|
+
const { getTask } = await import("./agent-teams.js");
|
|
508
|
+
const task = await getTask(args.taskId);
|
|
509
|
+
if (!task)
|
|
510
|
+
return JSON.stringify({ error: "Task not found" });
|
|
511
|
+
return JSON.stringify({
|
|
512
|
+
taskId: task.taskId,
|
|
513
|
+
threadId: task.threadId,
|
|
514
|
+
status: task.status,
|
|
515
|
+
description: task.description,
|
|
516
|
+
preview: task.preview,
|
|
517
|
+
currentStep: task.currentStep,
|
|
518
|
+
summary: task.summary,
|
|
519
|
+
});
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
"read-task-result": {
|
|
523
|
+
tool: {
|
|
524
|
+
description: "Read the result of a completed sub-agent task. Returns the full output summary.",
|
|
525
|
+
parameters: {
|
|
526
|
+
type: "object",
|
|
527
|
+
properties: {
|
|
528
|
+
taskId: {
|
|
529
|
+
type: "string",
|
|
530
|
+
description: "The task ID returned by spawn-task",
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
required: ["taskId"],
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
run: async (args) => {
|
|
537
|
+
const { getTask } = await import("./agent-teams.js");
|
|
538
|
+
const task = await getTask(args.taskId);
|
|
539
|
+
if (!task)
|
|
540
|
+
return JSON.stringify({ error: "Task not found" });
|
|
541
|
+
if (task.status === "running") {
|
|
542
|
+
return JSON.stringify({
|
|
543
|
+
status: "running",
|
|
544
|
+
preview: task.preview,
|
|
545
|
+
message: "Task is still running. Check back later.",
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
return JSON.stringify({
|
|
549
|
+
taskId: task.taskId,
|
|
550
|
+
status: task.status,
|
|
551
|
+
summary: task.summary,
|
|
552
|
+
preview: task.preview,
|
|
553
|
+
});
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
"send-to-task": {
|
|
557
|
+
tool: {
|
|
558
|
+
description: "Send a message or update to a running sub-agent. Use this to redirect, add context, or give feedback to a sub-agent while it's working.",
|
|
559
|
+
parameters: {
|
|
560
|
+
type: "object",
|
|
561
|
+
properties: {
|
|
562
|
+
taskId: {
|
|
563
|
+
type: "string",
|
|
564
|
+
description: "The task ID returned by spawn-task",
|
|
565
|
+
},
|
|
566
|
+
message: {
|
|
567
|
+
type: "string",
|
|
568
|
+
description: "Message to send to the sub-agent",
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
required: ["taskId", "message"],
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
run: async (args) => {
|
|
575
|
+
const { sendToTask } = await import("./agent-teams.js");
|
|
576
|
+
const result = await sendToTask(args.taskId, args.message);
|
|
577
|
+
return JSON.stringify(result);
|
|
578
|
+
},
|
|
579
|
+
},
|
|
580
|
+
"list-tasks": {
|
|
581
|
+
tool: {
|
|
582
|
+
description: "List all sub-agent tasks and their current status. Use this to see what's running, completed, or failed.",
|
|
583
|
+
parameters: {
|
|
584
|
+
type: "object",
|
|
585
|
+
properties: {},
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
run: async () => {
|
|
589
|
+
const { listTasks } = await import("./agent-teams.js");
|
|
590
|
+
const tasks = await listTasks();
|
|
591
|
+
if (tasks.length === 0) {
|
|
592
|
+
return "No sub-agent tasks.";
|
|
593
|
+
}
|
|
594
|
+
return JSON.stringify(tasks.map((t) => ({
|
|
595
|
+
taskId: t.taskId,
|
|
596
|
+
threadId: t.threadId,
|
|
597
|
+
description: t.description,
|
|
598
|
+
status: t.status,
|
|
599
|
+
currentStep: t.currentStep,
|
|
600
|
+
hasResult: t.summary.length > 0,
|
|
601
|
+
})), null, 2);
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
};
|
|
605
|
+
}
|
|
177
606
|
/**
|
|
178
607
|
* Framework-level instructions injected into every agent's system prompt.
|
|
179
608
|
* This is the single source of truth for the core philosophy, rules, and patterns.
|
|
@@ -187,23 +616,124 @@ const FRAMEWORK_CORE = `
|
|
|
187
616
|
### Core Rules
|
|
188
617
|
|
|
189
618
|
1. **Data lives in SQL** — All app state is in a SQL database (could be SQLite, Postgres, Turso, or Cloudflare D1 — never assume which). Use the available database tools.
|
|
190
|
-
2. **Context awareness** —
|
|
619
|
+
2. **Context awareness** — The user's current screen state is automatically included in each message as a \`<current-screen>\` block. Use it to understand what the user is looking at. You can still call \`view-screen\` for a more detailed snapshot if needed, but you should NOT need to call it before every action.
|
|
191
620
|
3. **Navigate the UI** — Use the \`navigate\` tool to switch views, open items, or focus elements for the user.
|
|
192
621
|
4. **Application state** — Ephemeral UI state (drafts, selections, navigation) lives in \`application_state\`. Use \`readAppState\`/\`writeAppState\` to read and write it. When you write state, the UI updates automatically.
|
|
193
|
-
5. **
|
|
622
|
+
5. **Memory** — Use the structured memory system to persist knowledge across sessions. Use \`save-memory\` proactively when you learn preferences, corrections, or project context. Update shared AGENTS.md for instructions that should apply to all users.
|
|
623
|
+
6. **Security** — Always use \`defineAction\` with a Zod \`schema:\` for input validation. Never construct SQL with string concatenation — use parameterized queries via db-query/db-exec. Never use \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`. Never expose secrets in responses or source code. Every table with user data must have \`owner_email\`.
|
|
194
624
|
|
|
195
625
|
### Resources
|
|
196
626
|
|
|
197
|
-
You have access to a Resources system for persistent notes
|
|
627
|
+
You have access to a Resources system for persistent notes and context files.
|
|
198
628
|
Use resource-list, resource-read, resource-write, and resource-delete to manage resources.
|
|
199
629
|
Resources can be personal (per-user) or shared (team-wide). By default, resources are personal.
|
|
200
630
|
|
|
201
|
-
When
|
|
202
|
-
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource instead.
|
|
631
|
+
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource.
|
|
203
632
|
|
|
204
633
|
### Navigation Rule
|
|
205
634
|
|
|
206
635
|
When the user says "show me", "go to", "open", "switch to", or similar navigation language, ALWAYS use the \`navigate\` action to update the UI. The user expects to SEE the result in the main app, not just read it in chat. Navigate first, then fetch/display data.
|
|
636
|
+
|
|
637
|
+
### Chat History
|
|
638
|
+
|
|
639
|
+
You can search and restore previous chat conversations:
|
|
640
|
+
- \`search-chats\` — Search or list past chat threads by keyword
|
|
641
|
+
- \`open-chat\` — Open a chat thread in the UI as a new tab and focus it
|
|
642
|
+
|
|
643
|
+
When the user asks to find a previous conversation, use \`search-chats\` first to find matching threads, then \`open-chat\` to restore the one they want.
|
|
644
|
+
|
|
645
|
+
### Agent Teams — Orchestration
|
|
646
|
+
|
|
647
|
+
You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents:
|
|
648
|
+
- \`spawn-task\` — Spawn a sub-agent for a task. It runs in its own thread while you stay available. A live preview card appears in the chat. You can optionally choose a custom agent profile from \`agents/*.md\`.
|
|
649
|
+
- \`task-status\` — Check the progress of a running sub-agent.
|
|
650
|
+
- \`read-task-result\` — Read the result when a sub-agent finishes.
|
|
651
|
+
|
|
652
|
+
**When to delegate vs do directly:**
|
|
653
|
+
- **Delegate** when the task involves multiple tool calls, research, content generation, or anything that takes more than a few seconds. Examples: "create a deck about X", "analyze the data and write a report", "look up Y and draft an email about it".
|
|
654
|
+
- **Do directly** for quick single-step tasks like navigation, reading state, or answering simple questions.
|
|
655
|
+
- **Spawn multiple sub-agents** when the user asks for multiple independent things — they'll run in parallel.
|
|
656
|
+
|
|
657
|
+
**How to orchestrate:**
|
|
658
|
+
1. When the user asks for something complex, spawn a sub-agent with a clear task description.
|
|
659
|
+
2. Tell the user what you've started ("I'm having a sub-agent research that for you").
|
|
660
|
+
3. You can keep chatting — sub-agents run independently.
|
|
661
|
+
4. Use \`read-task-result\` to check results when needed, or the user can see live progress in the card.
|
|
662
|
+
5. If the user's request has multiple steps, you can spawn one sub-agent per step, or chain them.
|
|
663
|
+
|
|
664
|
+
Sub-agents have access to all template tools but **cannot spawn sub-agents themselves** — only you (the orchestrator) can do that. Give the sub-agent a specific, actionable task description — it will figure out which tools to use. If a matching custom agent profile exists, pass it via the \`agent\` parameter on \`spawn-task\`.
|
|
665
|
+
|
|
666
|
+
### Recurring Jobs
|
|
667
|
+
|
|
668
|
+
You can create recurring jobs that run on a cron schedule. Jobs are resource files under \`jobs/\`. Each job has a cron schedule and instructions that the agent executes automatically.
|
|
669
|
+
|
|
670
|
+
- \`create-job\` — Create a new recurring job with a cron schedule and instructions
|
|
671
|
+
- \`list-jobs\` — List all recurring jobs and their status (schedule, last run, next run, errors)
|
|
672
|
+
- \`update-job\` — Update a job's schedule, instructions, or toggle enabled/disabled
|
|
673
|
+
- Delete a job with \`resource-delete --path jobs/<name>.md\`
|
|
674
|
+
|
|
675
|
+
When the user asks for something recurring ("every morning", "daily at 9am", "weekly on Mondays"), create a job. Convert natural language to 5-field cron format:
|
|
676
|
+
- "every morning" / "daily at 9am" → \`0 9 * * *\`
|
|
677
|
+
- "every weekday at 9am" → \`0 9 * * 1-5\`
|
|
678
|
+
- "every hour" → \`0 * * * *\`
|
|
679
|
+
- "every 30 minutes" → \`*/30 * * * *\`
|
|
680
|
+
- "every monday at 9am" → \`0 9 * * 1\`
|
|
681
|
+
- "twice a day" / "morning and evening" → \`0 9,17 * * *\`
|
|
682
|
+
|
|
683
|
+
Job instructions should be self-contained — include which actions to call, what conditions to check, and what to do with results. The agent executing the job has access to all the same tools you do.
|
|
684
|
+
|
|
685
|
+
### Browser Access
|
|
686
|
+
|
|
687
|
+
Use \`get-browser-connection\` when you need a real browser session backed by Builder. It returns websocket connection details for a provisioned browser session.
|
|
688
|
+
|
|
689
|
+
- If the tool says Builder is not configured, tell the user to connect Builder from the workspace Resources panel.
|
|
690
|
+
- Reuse a stable \`sessionId\` when you want to reconnect to the same browser session.
|
|
691
|
+
- Include proxy parameters when you need the browser to reach a local dev server through Builder's browser connection flow.
|
|
692
|
+
|
|
693
|
+
### call-agent — External Apps Only
|
|
694
|
+
|
|
695
|
+
The \`call-agent\` tool sends a message to a DIFFERENT, separately-deployed app's agent (A2A protocol). It is **not** for calling actions within the current app.
|
|
696
|
+
|
|
697
|
+
**NEVER use \`call-agent\` to:**
|
|
698
|
+
- Call your own app by name (if you are the "macros" agent, never do \`call-agent(agent="macros")\`)
|
|
699
|
+
- Perform tasks you can accomplish with your own registered tools
|
|
700
|
+
- Wrap your own actions in an A2A round-trip
|
|
701
|
+
|
|
702
|
+
**ONLY use \`call-agent\` when:**
|
|
703
|
+
- The user explicitly asks you to communicate with a different app (e.g., "ask the mail agent to...")
|
|
704
|
+
- You need data that only another deployed app can provide
|
|
705
|
+
- You are coordinating across genuinely separate apps
|
|
706
|
+
|
|
707
|
+
If \`call-agent\` returns an error saying the agent is yourself — stop and use your own tools instead.
|
|
708
|
+
|
|
709
|
+
### Structured Memory
|
|
710
|
+
|
|
711
|
+
You have a structured memory system. Your memory index (\`memory/MEMORY.md\`) is loaded at the start of every conversation (shown above). Individual memories are stored as separate files under \`memory/\`.
|
|
712
|
+
|
|
713
|
+
**Tools:**
|
|
714
|
+
- \`save-memory\` — Create or update a memory. Provide name, type, description, and content. Atomically updates both the memory file and the index.
|
|
715
|
+
- \`delete-memory\` — Remove a memory and its index entry.
|
|
716
|
+
- \`resource-read --path memory/<name>.md\` — Read the full content of a specific memory when you need details beyond the index.
|
|
717
|
+
|
|
718
|
+
**Memory types:**
|
|
719
|
+
- \`user\` — Preferences, role, personal context, contacts
|
|
720
|
+
- \`feedback\` — Corrections ("don't do X, do Y instead"), confirmed approaches
|
|
721
|
+
- \`project\` — Ongoing work context, decisions, status
|
|
722
|
+
- \`reference\` — Pointers to external systems, URLs, API details
|
|
723
|
+
|
|
724
|
+
**When to save (do it proactively, don't ask permission):**
|
|
725
|
+
- User corrects your approach → save as \`feedback\`
|
|
726
|
+
- User shares preferences (tone, style, workflow) → save as \`user\`
|
|
727
|
+
- You discover a non-obvious pattern or gotcha → save as \`feedback\`
|
|
728
|
+
- User provides personal context (contacts, team, domain) → save as \`user\`
|
|
729
|
+
- A project gains enough context to track → save as \`project\`
|
|
730
|
+
|
|
731
|
+
**Rules:**
|
|
732
|
+
- Don't save things obvious from the code or standard framework behavior
|
|
733
|
+
- When updating an existing memory, read it first and merge — don't overwrite blindly
|
|
734
|
+
- Keep descriptions concise — the index is loaded every message
|
|
735
|
+
- One memory per logical topic (e.g. 'coding-style', 'project-alpha')
|
|
736
|
+
- Don't save temporary debugging notes or ephemeral task details
|
|
207
737
|
`;
|
|
208
738
|
const PROD_FRAMEWORK_PROMPT = `## Agent-Native Framework — Production Mode
|
|
209
739
|
|
|
@@ -212,6 +742,21 @@ You are an AI agent in an agent-native application, running in **production mode
|
|
|
212
742
|
The agent and the UI are equal partners — everything the UI can do, you can do via your tools, and vice versa. They share the same SQL database and stay in sync automatically.
|
|
213
743
|
|
|
214
744
|
**In production mode, you operate through registered actions exposed as tools.** These are your capabilities — use them to read data, take actions, and help the user. You cannot edit source code or access the filesystem directly. Your tools are the app's API.
|
|
745
|
+
|
|
746
|
+
### Code Changes Not Available
|
|
747
|
+
|
|
748
|
+
When the user asks you to change the UI, modify code, add features, fix bugs in the app itself, change styles, or do anything that requires editing source files — you MUST respond with this exact message (replacing APP_NAME with the current app name from the URL hostname):
|
|
749
|
+
|
|
750
|
+
> This app is running in hosted mode and I can't make code changes here. To customize this app:
|
|
751
|
+
>
|
|
752
|
+
> **Option 1:** Connect to [Builder.io](https://www.builder.io/m/agent-native) for a full development environment
|
|
753
|
+
>
|
|
754
|
+
> **Option 2:** Clone and run locally:
|
|
755
|
+
> \`\`\`
|
|
756
|
+
> npx agent-native create APP_NAME
|
|
757
|
+
> \`\`\`
|
|
758
|
+
|
|
759
|
+
Do NOT attempt to work around this limitation. Do NOT say "I can't do that" without providing the options above. Always include both the Builder.io link and the CLI command.
|
|
215
760
|
${FRAMEWORK_CORE}`;
|
|
216
761
|
const DEV_FRAMEWORK_PROMPT = `## Agent-Native Framework — Development Mode
|
|
217
762
|
|
|
@@ -219,7 +764,17 @@ You are an AI agent in an agent-native application, running in **development mod
|
|
|
219
764
|
|
|
220
765
|
The agent and the UI are equal partners — everything the UI can do, you can do via tools/scripts, and vice versa. They share the same SQL database and stay in sync automatically.
|
|
221
766
|
|
|
222
|
-
**In development mode, you have
|
|
767
|
+
**In development mode, you have UNRESTRICTED access.** You can:
|
|
768
|
+
- Run ANY shell command via the \`shell\` tool (bash, node, curl, pnpm, etc.)
|
|
769
|
+
- Execute arbitrary code: \`shell({ command: 'node -e "console.log(1+1)"' })\`
|
|
770
|
+
- Read/write any file on the filesystem
|
|
771
|
+
- Query and modify the database
|
|
772
|
+
- Call external APIs (via shell with curl, or via scripts)
|
|
773
|
+
- Edit source code, install packages, modify the app
|
|
774
|
+
|
|
775
|
+
**There are NO restrictions in dev mode.** If a dedicated tool/action doesn't exist for what you need, use \`shell\` to run any command. For example: \`shell({ command: 'curl -s https://api.example.com/data' })\`
|
|
776
|
+
|
|
777
|
+
**Template-specific actions are invoked via shell, NOT as direct tools.** In dev mode, the only tools registered as native tool calls are framework-level utilities (shell, file ops, resources, chat, teams, jobs). Anything from the template's \`actions/\` directory must be run through shell: \`shell({ command: 'pnpm action <name> --arg value' })\`. The "Available Actions" section below shows the exact CLI syntax for each one — copy that command verbatim and pass it to \`shell\`. Do not try to call template actions by name as if they were tools; they will not appear in your tool list.
|
|
223
778
|
|
|
224
779
|
When editing code, follow the agent-native architecture:
|
|
225
780
|
- Every feature needs all four areas: UI + scripts + skills/instructions + application-state sync
|
|
@@ -229,59 +784,180 @@ When editing code, follow the agent-native architecture:
|
|
|
229
784
|
${FRAMEWORK_CORE}`;
|
|
230
785
|
const DEFAULT_SYSTEM_PROMPT = PROD_FRAMEWORK_PROMPT;
|
|
231
786
|
/**
|
|
232
|
-
* Pre-load
|
|
233
|
-
*
|
|
787
|
+
* Pre-load the agent's context: AGENTS.md (template instructions), the skills
|
|
788
|
+
* index, shared LEARNINGS.md (team notes), and memory/MEMORY.md (personal
|
|
789
|
+
* structured memory index). These all get appended to the system prompt so
|
|
790
|
+
* the agent has everything it needs from the first turn.
|
|
791
|
+
*
|
|
792
|
+
* Four sources are layered:
|
|
793
|
+
*
|
|
794
|
+
* 1. `<workspace>` — AGENTS.md from the enterprise workspace core.
|
|
795
|
+
* 2. `<template>` — AGENTS.md + skills index from the Vite plugin bundle.
|
|
796
|
+
* 3. `<shared>` — LEARNINGS.md from the SQL shared scope. Team-level notes.
|
|
797
|
+
* 4. `<personal>` — memory/MEMORY.md from the SQL personal scope. The
|
|
798
|
+
* current user's structured memory index.
|
|
799
|
+
*
|
|
800
|
+
* Each source is read independently — no copying between them. Editing
|
|
801
|
+
* AGENTS.md and restarting the server is all it takes; Vite HMR invalidates
|
|
802
|
+
* the bundle in dev so changes land instantly.
|
|
234
803
|
*/
|
|
235
804
|
async function loadResourcesForPrompt(owner) {
|
|
236
805
|
await ensurePersonalDefaults(owner);
|
|
237
|
-
const resourceNames = ["AGENTS.md", "LEARNINGS.md"];
|
|
238
806
|
const sections = [];
|
|
239
|
-
|
|
240
|
-
|
|
807
|
+
// 1. Workspace AGENTS.md + skills merged into the template bundle.
|
|
808
|
+
try {
|
|
809
|
+
const { loadAgentsBundle, generateSkillsPromptBlock } = await import("./agents-bundle.js");
|
|
810
|
+
const bundle = await loadAgentsBundle();
|
|
811
|
+
// Workspace-core AGENTS.md (enterprise-wide instructions), if present.
|
|
812
|
+
if (bundle.workspaceAgentsMd && bundle.workspaceAgentsMd.trim()) {
|
|
813
|
+
sections.push(`<resource name="AGENTS.md" scope="workspace">\n${bundle.workspaceAgentsMd.trim()}\n</resource>`);
|
|
814
|
+
}
|
|
815
|
+
// 2. Template AGENTS.md.
|
|
816
|
+
if (bundle.agentsMd.trim()) {
|
|
817
|
+
sections.push(`<resource name="AGENTS.md" scope="template">\n${bundle.agentsMd.trim()}\n</resource>`);
|
|
818
|
+
}
|
|
819
|
+
const skillsBlock = generateSkillsPromptBlock(bundle);
|
|
820
|
+
if (skillsBlock)
|
|
821
|
+
sections.push(skillsBlock);
|
|
822
|
+
}
|
|
823
|
+
catch { }
|
|
824
|
+
// LEARNINGS.md from SQL (template-level instructions are in AGENTS.md above).
|
|
825
|
+
// 2. Shared SQL scope
|
|
826
|
+
try {
|
|
827
|
+
const shared = await resourceGetByPath(SHARED_OWNER, "LEARNINGS.md");
|
|
828
|
+
if (shared?.content?.trim()) {
|
|
829
|
+
sections.push(`<resource name="LEARNINGS.md" scope="shared">\n${shared.content.trim()}\n</resource>`);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
catch { }
|
|
833
|
+
// 3. Personal memory index (skip if owner is the shared sentinel)
|
|
834
|
+
if (owner !== SHARED_OWNER) {
|
|
241
835
|
try {
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
244
|
-
sections.push(`<resource name="
|
|
836
|
+
const memoryIndex = await resourceGetByPath(owner, "memory/MEMORY.md");
|
|
837
|
+
if (memoryIndex?.content?.trim()) {
|
|
838
|
+
sections.push(`<resource name="memory/MEMORY.md" scope="personal">\n${memoryIndex.content.trim()}\n</resource>`);
|
|
245
839
|
}
|
|
246
840
|
}
|
|
247
841
|
catch { }
|
|
248
|
-
// Read personal (skip if owner is the shared sentinel)
|
|
249
|
-
if (owner !== SHARED_OWNER) {
|
|
250
|
-
try {
|
|
251
|
-
const personal = await resourceGetByPath(owner, name);
|
|
252
|
-
if (personal?.content?.trim()) {
|
|
253
|
-
sections.push(`<resource name="${name}" scope="personal">\n${personal.content.trim()}\n</resource>`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
catch { }
|
|
257
|
-
}
|
|
258
842
|
}
|
|
259
843
|
if (sections.length === 0)
|
|
260
844
|
return "";
|
|
261
845
|
return ("\n\nThe following resources contain template-specific instructions and user context. Use the information in them to help the user.\n\n" +
|
|
262
846
|
sections.join("\n\n"));
|
|
263
847
|
}
|
|
848
|
+
/**
|
|
849
|
+
* Build the per-request SQL-schema context block. Reads AGENT_ORG_ID live
|
|
850
|
+
* from the environment so scheduler/A2A/HTTP call sites all see whatever
|
|
851
|
+
* org was just resolved for this request.
|
|
852
|
+
*/
|
|
853
|
+
async function buildSchemaBlock(owner, hasRawDbTools) {
|
|
854
|
+
try {
|
|
855
|
+
return await loadSchemaPromptBlock({
|
|
856
|
+
owner,
|
|
857
|
+
orgId: getRequestOrgId() ?? null,
|
|
858
|
+
hasRawDbTools,
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
catch {
|
|
862
|
+
return "";
|
|
863
|
+
}
|
|
864
|
+
}
|
|
264
865
|
/** @deprecated Kept for backward compat — dev prompt is now part of DEV_FRAMEWORK_PROMPT */
|
|
265
866
|
const DEFAULT_DEV_PROMPT = "";
|
|
266
867
|
/**
|
|
267
868
|
* Generates a system prompt section describing registered template actions.
|
|
268
869
|
* This helps the agent prefer template-specific actions over raw db-query/db-exec.
|
|
870
|
+
*
|
|
871
|
+
* Two output modes:
|
|
872
|
+
*
|
|
873
|
+
* - `"tool"` — used in production, where template actions are registered
|
|
874
|
+
* as native Anthropic tools. Output reads `name(arg*: type; ...) — desc`.
|
|
875
|
+
* - `"cli"` — used in dev, where template actions are NOT registered as
|
|
876
|
+
* native tools and must be invoked via `shell(command="pnpm action ...")`.
|
|
877
|
+
* Output reads `pnpm action name --arg <type> [--opt <type>] — desc`.
|
|
269
878
|
*/
|
|
270
|
-
function generateActionsPrompt(registry) {
|
|
879
|
+
function generateActionsPrompt(registry, mode = "tool") {
|
|
271
880
|
if (!registry || Object.keys(registry).length === 0)
|
|
272
881
|
return "";
|
|
273
882
|
const lines = Object.entries(registry).map(([name, entry]) => {
|
|
274
883
|
const desc = entry.tool.description;
|
|
275
884
|
const params = entry.tool.parameters?.properties;
|
|
885
|
+
const requiredFields = new Set(entry.tool.parameters?.required ?? []);
|
|
886
|
+
if (mode === "cli") {
|
|
887
|
+
// CLI mode: emit `pnpm action <name> --required <type> [--optional <type>]`
|
|
888
|
+
if (!params || Object.keys(params).length === 0) {
|
|
889
|
+
return `- \`pnpm action ${name}\` — ${desc}`;
|
|
890
|
+
}
|
|
891
|
+
const entries = Object.entries(params);
|
|
892
|
+
// Required first (alphabetical), then optional (alphabetical)
|
|
893
|
+
entries.sort(([a], [b]) => {
|
|
894
|
+
const ar = requiredFields.has(a) ? 0 : 1;
|
|
895
|
+
const br = requiredFields.has(b) ? 0 : 1;
|
|
896
|
+
if (ar !== br)
|
|
897
|
+
return ar - br;
|
|
898
|
+
return a.localeCompare(b);
|
|
899
|
+
});
|
|
900
|
+
const required = [];
|
|
901
|
+
const optional = [];
|
|
902
|
+
const requiredNames = [];
|
|
903
|
+
for (const [k, v] of entries) {
|
|
904
|
+
const type = v.type ?? "any";
|
|
905
|
+
const flag = `--${k} <${type}>`;
|
|
906
|
+
if (requiredFields.has(k)) {
|
|
907
|
+
required.push(flag);
|
|
908
|
+
requiredNames.push(`--${k}`);
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
optional.push(`[${flag}]`);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const cmd = ["pnpm action " + name, ...required, ...optional].join(" ");
|
|
915
|
+
const requiredNote = requiredNames.length > 0
|
|
916
|
+
? ` Required: ${requiredNames.join(", ")}.`
|
|
917
|
+
: "";
|
|
918
|
+
return `- \`${cmd}\` — ${desc}.${requiredNote}`;
|
|
919
|
+
}
|
|
920
|
+
// tool mode (production / native tool calls)
|
|
276
921
|
if (params) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
922
|
+
// Order required params first, then optional. Mark required with "*"
|
|
923
|
+
// and include type + description so the agent knows exactly how to call.
|
|
924
|
+
const entries = Object.entries(params);
|
|
925
|
+
entries.sort(([a], [b]) => {
|
|
926
|
+
const ar = requiredFields.has(a) ? 0 : 1;
|
|
927
|
+
const br = requiredFields.has(b) ? 0 : 1;
|
|
928
|
+
if (ar !== br)
|
|
929
|
+
return ar - br;
|
|
930
|
+
return a.localeCompare(b);
|
|
931
|
+
});
|
|
932
|
+
const paramList = entries
|
|
933
|
+
.map(([k, v]) => {
|
|
934
|
+
const isRequired = requiredFields.has(k);
|
|
935
|
+
const type = v.type ?? "any";
|
|
936
|
+
const marker = isRequired ? "*" : "?";
|
|
937
|
+
const descPart = v.description ? ` — ${v.description}` : "";
|
|
938
|
+
return `${k}${marker}: ${type}${descPart}`;
|
|
939
|
+
})
|
|
940
|
+
.join("; ");
|
|
941
|
+
return `- \`${name}\`(${paramList}) — ${desc}`;
|
|
281
942
|
}
|
|
282
|
-
return `- \`${name}\` — ${desc}`;
|
|
943
|
+
return `- \`${name}\`() — ${desc}`;
|
|
283
944
|
});
|
|
284
|
-
|
|
945
|
+
if (mode === "cli") {
|
|
946
|
+
return `\n\n## Available Actions
|
|
947
|
+
|
|
948
|
+
**These template actions are NOT exposed as direct tools in dev mode. To run any of them, use the \`shell\` tool with the exact command shown below.** Example: \`shell(command="pnpm action add-slide --deckId abc --content 'Hello'")\`.
|
|
949
|
+
|
|
950
|
+
Do NOT try to call these by name as if they were tools — they will not exist in your tool list. Always go through \`shell\`.
|
|
951
|
+
|
|
952
|
+
${lines.join("\n")}`;
|
|
953
|
+
}
|
|
954
|
+
return `\n\n## Available Actions
|
|
955
|
+
|
|
956
|
+
**Use these actions directly to accomplish tasks. Do NOT use \`db-schema\`, \`search-files\`, or \`shell\` to explore the app — these actions already connect to the correct database and services.**
|
|
957
|
+
|
|
958
|
+
Parameter notation: \`name*\` = required, \`name?\` = optional. Always pass the tool's parameters as a JSON object to the tool_use call — never via shell or string-concatenated CLI flags.
|
|
959
|
+
|
|
960
|
+
${lines.join("\n")}`;
|
|
285
961
|
}
|
|
286
962
|
/**
|
|
287
963
|
* Creates a Nitro plugin that mounts the agent chat endpoint.
|
|
@@ -292,7 +968,7 @@ function generateActionsPrompt(registry) {
|
|
|
292
968
|
* Usage in templates:
|
|
293
969
|
* ```ts
|
|
294
970
|
* // server/plugins/agent-chat.ts
|
|
295
|
-
* import { createAgentChatPlugin } from "@agent-native/core/server";
|
|
971
|
+
* import { readBody, createAgentChatPlugin } from "@agent-native/core/server";
|
|
296
972
|
* import { scriptRegistry } from "../../scripts/registry.js";
|
|
297
973
|
*
|
|
298
974
|
* export default createAgentChatPlugin({
|
|
@@ -301,7 +977,7 @@ function generateActionsPrompt(registry) {
|
|
|
301
977
|
* });
|
|
302
978
|
* ```
|
|
303
979
|
*/
|
|
304
|
-
function collectFiles(dir, prefix, depth, results) {
|
|
980
|
+
async function collectFiles(dir, prefix, depth, results) {
|
|
305
981
|
if (depth > 4 || results.length >= 500)
|
|
306
982
|
return;
|
|
307
983
|
const skip = new Set([
|
|
@@ -316,6 +992,7 @@ function collectFiles(dir, prefix, depth, results) {
|
|
|
316
992
|
]);
|
|
317
993
|
let entries;
|
|
318
994
|
try {
|
|
995
|
+
const fs = await lazyFs();
|
|
319
996
|
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
320
997
|
}
|
|
321
998
|
catch {
|
|
@@ -334,7 +1011,7 @@ function collectFiles(dir, prefix, depth, results) {
|
|
|
334
1011
|
type: isDir ? "folder" : "file",
|
|
335
1012
|
});
|
|
336
1013
|
if (isDir)
|
|
337
|
-
collectFiles(nodePath.join(dir, entry.name), relPath, depth + 1, results);
|
|
1014
|
+
await collectFiles(nodePath.join(dir, entry.name), relPath, depth + 1, results);
|
|
338
1015
|
}
|
|
339
1016
|
}
|
|
340
1017
|
function parseSkillFrontmatter(content) {
|
|
@@ -358,28 +1035,229 @@ function isLocalhost(event) {
|
|
|
358
1035
|
}
|
|
359
1036
|
export function createAgentChatPlugin(options) {
|
|
360
1037
|
return async (nitroApp) => {
|
|
1038
|
+
// Wait for default framework plugins (auth, core-routes, integrations, ...)
|
|
1039
|
+
// to finish mounting their middleware before we register our own. Without
|
|
1040
|
+
// this, requests can race ahead of the bootstrap and hit the SSR catch-all.
|
|
1041
|
+
const { awaitBootstrap } = await import("./framework-request-handler.js");
|
|
1042
|
+
await awaitBootstrap(nitroApp);
|
|
361
1043
|
const env = process.env.NODE_ENV;
|
|
362
1044
|
// AGENT_MODE=production forces production agent constraints even in dev
|
|
363
1045
|
const canToggle = (env === "development" || env === "test") &&
|
|
364
1046
|
process.env.AGENT_MODE !== "production";
|
|
365
1047
|
const routePath = options?.path ?? "/_agent-native/agent-chat";
|
|
1048
|
+
// Initialize MCP client (connects to user-configured local MCP servers).
|
|
1049
|
+
// Graceful-degrade: any failure yields zero MCP tools and agent-chat keeps
|
|
1050
|
+
// working as before. No-op outside Node runtimes.
|
|
1051
|
+
let mcpConfig = loadMcpConfig();
|
|
1052
|
+
if (!mcpConfig) {
|
|
1053
|
+
mcpConfig = autoDetectMcpConfig();
|
|
1054
|
+
if (mcpConfig) {
|
|
1055
|
+
const detected = Object.keys(mcpConfig.servers).join(", ");
|
|
1056
|
+
console.log(`[mcp-client] auto-detected ${detected}, registering as MCP server — set AGENT_NATIVE_DISABLE_MCP_AUTODETECT=1 to opt out`);
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
console.log("[mcp-client] no mcp.config.json and no auto-detectable servers — skipping MCP tools");
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
else if (mcpConfig.source) {
|
|
1063
|
+
console.log(`[mcp-client] loaded config from ${mcpConfig.source} (${Object.keys(mcpConfig.servers).length} server(s))`);
|
|
1064
|
+
}
|
|
1065
|
+
const mcpManager = new McpClientManager(mcpConfig);
|
|
1066
|
+
try {
|
|
1067
|
+
await mcpManager.start();
|
|
1068
|
+
}
|
|
1069
|
+
catch (err) {
|
|
1070
|
+
console.warn(`[mcp-client] start() failed: ${err?.message ?? err}. Continuing without MCP tools.`);
|
|
1071
|
+
}
|
|
1072
|
+
setGlobalMcpManager(mcpManager);
|
|
1073
|
+
const mcpActionEntries = mcpToolsToActionEntries(mcpManager);
|
|
1074
|
+
// Mount status route so tooling/onboarding can inspect MCP state.
|
|
1075
|
+
mountMcpStatusRoute(nitroApp, mcpManager);
|
|
1076
|
+
// Ensure we tear down child processes if the host shuts down cleanly.
|
|
1077
|
+
if (typeof process !== "undefined" &&
|
|
1078
|
+
typeof process.once === "function" &&
|
|
1079
|
+
!globalThis.__agentNativeMcpExitHooked) {
|
|
1080
|
+
globalThis.__agentNativeMcpExitHooked = true;
|
|
1081
|
+
const stop = () => {
|
|
1082
|
+
const mgr = getGlobalMcpManager();
|
|
1083
|
+
if (mgr)
|
|
1084
|
+
void mgr.stop();
|
|
1085
|
+
};
|
|
1086
|
+
process.once("exit", stop);
|
|
1087
|
+
process.once("SIGTERM", stop);
|
|
1088
|
+
process.once("SIGINT", stop);
|
|
1089
|
+
}
|
|
366
1090
|
// Resolve actions — prefer `actions`, fall back to deprecated `scripts`
|
|
367
1091
|
const rawActions = options?.actions ?? options?.scripts;
|
|
368
1092
|
const templateScripts = typeof rawActions === "function"
|
|
369
1093
|
? await rawActions()
|
|
370
1094
|
: (rawActions ?? {});
|
|
371
|
-
// Resource and cross-agent scripts are available in both prod and dev modes
|
|
1095
|
+
// Resource, chat, docs, and cross-agent scripts are available in both prod and dev modes
|
|
372
1096
|
const resourceScripts = await createResourceScriptEntries();
|
|
373
|
-
const
|
|
1097
|
+
const docsScripts = await createDocsScriptEntries();
|
|
1098
|
+
const engineScripts = await createAgentEngineScriptEntries();
|
|
1099
|
+
const chatScripts = {
|
|
1100
|
+
...(await createChatScriptEntries()),
|
|
1101
|
+
...engineScripts,
|
|
1102
|
+
};
|
|
1103
|
+
const callAgentScript = await createCallAgentScriptEntry(options?.appId);
|
|
1104
|
+
let _currentRequestOrigin = "http://localhost:3000";
|
|
1105
|
+
const browserTools = createBuilderBrowserTool({
|
|
1106
|
+
getOrigin: () => _currentRequestOrigin,
|
|
1107
|
+
});
|
|
374
1108
|
// Auto-mount A2A protocol endpoints so every app is discoverable
|
|
375
1109
|
// and callable by other agents via the standard protocol.
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
1110
|
+
// In dev mode, include dev scripts (filesystem-discovered) so the A2A agent
|
|
1111
|
+
// has access to the same tools as the interactive agent.
|
|
1112
|
+
let devScriptsForA2A = {};
|
|
1113
|
+
let discoveredActions = {};
|
|
1114
|
+
if (canToggle) {
|
|
1115
|
+
try {
|
|
1116
|
+
const { createDevScriptRegistry } = await import("../scripts/dev/index.js");
|
|
1117
|
+
devScriptsForA2A = await createDevScriptRegistry();
|
|
1118
|
+
}
|
|
1119
|
+
catch { }
|
|
1120
|
+
// Auto-discover template action files and register as shell-based tools.
|
|
1121
|
+
// This ensures templates without a custom agent-chat plugin (e.g., analytics)
|
|
1122
|
+
// still have their domain actions available as tools.
|
|
1123
|
+
try {
|
|
1124
|
+
const fs = await import("fs");
|
|
1125
|
+
const pathMod = await import("path");
|
|
1126
|
+
const cwd = process.cwd();
|
|
1127
|
+
const skipFiles = new Set([
|
|
1128
|
+
"helpers",
|
|
1129
|
+
"run",
|
|
1130
|
+
"registry",
|
|
1131
|
+
"_utils",
|
|
1132
|
+
"db-connect",
|
|
1133
|
+
"db-status",
|
|
1134
|
+
]);
|
|
1135
|
+
for (const dir of ["actions", "scripts"]) {
|
|
1136
|
+
const actionsDir = pathMod.join(cwd, dir);
|
|
1137
|
+
const _fs = await lazyFs();
|
|
1138
|
+
if (!_fs.existsSync(actionsDir))
|
|
1139
|
+
continue;
|
|
1140
|
+
const files = _fs
|
|
1141
|
+
.readdirSync(actionsDir)
|
|
1142
|
+
.filter((f) => f.endsWith(".ts") &&
|
|
1143
|
+
!f.startsWith("_") &&
|
|
1144
|
+
!skipFiles.has(f.replace(/\.ts$/, "")));
|
|
1145
|
+
for (const file of files) {
|
|
1146
|
+
const name = file.replace(/\.ts$/, "");
|
|
1147
|
+
if (templateScripts[name] || devScriptsForA2A[name])
|
|
1148
|
+
continue;
|
|
1149
|
+
// Try to load the action module directly so we get the real
|
|
1150
|
+
// run function (not a shell wrapper). This makes HTTP endpoints
|
|
1151
|
+
// work correctly. Only fall back to shell wrapper if the import
|
|
1152
|
+
// fails (e.g., CLI-style scripts that throw at top level).
|
|
1153
|
+
const filePath = pathMod.join(actionsDir, file);
|
|
1154
|
+
try {
|
|
1155
|
+
const mod = await import(/* @vite-ignore */ filePath);
|
|
1156
|
+
const def = mod.default && typeof mod.default === "object"
|
|
1157
|
+
? mod.default
|
|
1158
|
+
: mod;
|
|
1159
|
+
if (def?.tool && typeof def.run === "function") {
|
|
1160
|
+
discoveredActions[name] = {
|
|
1161
|
+
tool: def.tool,
|
|
1162
|
+
run: def.run,
|
|
1163
|
+
...(def.http !== undefined ? { http: def.http } : {}),
|
|
1164
|
+
};
|
|
1165
|
+
continue;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
catch {
|
|
1169
|
+
// Fall through to shell wrapper for CLI-style scripts
|
|
1170
|
+
// (and .ts files Node can't parse natively).
|
|
1171
|
+
}
|
|
1172
|
+
// Static-parse the source for `http: false` or
|
|
1173
|
+
// `http: { method: "GET" }` so the shell-wrapper fallback still
|
|
1174
|
+
// mounts HTTP routes with the correct method. We can't load the
|
|
1175
|
+
// .ts module to read the real defineAction object in this Node
|
|
1176
|
+
// context, so this regex sniff is the best we can do until the
|
|
1177
|
+
// discovery is moved into a Vite-aware codepath.
|
|
1178
|
+
let httpConfig;
|
|
1179
|
+
try {
|
|
1180
|
+
const src = _fs.readFileSync(filePath, "utf-8");
|
|
1181
|
+
if (/\bhttp\s*:\s*false\b/.test(src)) {
|
|
1182
|
+
httpConfig = false;
|
|
1183
|
+
}
|
|
1184
|
+
else {
|
|
1185
|
+
const httpStart = src.search(/\bhttp\s*:\s*\{/);
|
|
1186
|
+
if (httpStart >= 0) {
|
|
1187
|
+
const window = src.slice(httpStart, httpStart + 200);
|
|
1188
|
+
const m = window.match(/method\s*:\s*['"`](GET|POST|PUT|DELETE)['"`]/);
|
|
1189
|
+
const p = window.match(/path\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
1190
|
+
if (m || p) {
|
|
1191
|
+
httpConfig = {
|
|
1192
|
+
...(m
|
|
1193
|
+
? {
|
|
1194
|
+
method: m[1],
|
|
1195
|
+
}
|
|
1196
|
+
: {}),
|
|
1197
|
+
...(p ? { path: p[1] } : {}),
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
catch {
|
|
1204
|
+
// File read failed — leave httpConfig undefined (default POST)
|
|
1205
|
+
}
|
|
1206
|
+
// Fallback: shell-based wrapper for CLI-style scripts
|
|
1207
|
+
discoveredActions[name] = {
|
|
1208
|
+
tool: {
|
|
1209
|
+
description: `Run the ${name} action. Use: pnpm action ${name} --arg=value`,
|
|
1210
|
+
parameters: {
|
|
1211
|
+
type: "object",
|
|
1212
|
+
properties: {
|
|
1213
|
+
args: {
|
|
1214
|
+
type: "string",
|
|
1215
|
+
description: "CLI arguments as a string (e.g., --metrics=sessions --days=7)",
|
|
1216
|
+
},
|
|
1217
|
+
},
|
|
1218
|
+
},
|
|
1219
|
+
},
|
|
1220
|
+
run: async (input) => {
|
|
1221
|
+
const shellEntry = devScriptsForA2A["shell"];
|
|
1222
|
+
if (!shellEntry)
|
|
1223
|
+
return "Error: shell not available";
|
|
1224
|
+
return shellEntry.run({
|
|
1225
|
+
command: `pnpm action ${name} ${input.args || ""}`.trim(),
|
|
1226
|
+
});
|
|
1227
|
+
},
|
|
1228
|
+
...(httpConfig !== undefined ? { http: httpConfig } : {}),
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
if (Object.keys(discoveredActions).length > 0 && process.env.DEBUG)
|
|
1233
|
+
console.log(`[agent-chat] Auto-discovered ${Object.keys(discoveredActions).length} action(s): ${Object.keys(discoveredActions).join(", ")}`);
|
|
1234
|
+
}
|
|
1235
|
+
catch { }
|
|
1236
|
+
}
|
|
1237
|
+
// In dev mode, template actions (templateScripts and discoveredActions) are
|
|
1238
|
+
// NOT registered as native tools — the agent invokes them via shell instead.
|
|
1239
|
+
// This avoids degenerate empty-object tool calls that Anthropic models
|
|
1240
|
+
// sometimes emit for actions with complex schemas. Production keeps the
|
|
1241
|
+
// native registration since it has no shell access.
|
|
1242
|
+
const allScripts = canToggle
|
|
1243
|
+
? {
|
|
1244
|
+
...resourceScripts,
|
|
1245
|
+
...docsScripts,
|
|
1246
|
+
...chatScripts,
|
|
1247
|
+
...callAgentScript,
|
|
1248
|
+
...browserTools,
|
|
1249
|
+
...devScriptsForA2A,
|
|
1250
|
+
}
|
|
1251
|
+
: {
|
|
1252
|
+
...discoveredActions,
|
|
1253
|
+
...templateScripts,
|
|
1254
|
+
...resourceScripts,
|
|
1255
|
+
...docsScripts,
|
|
1256
|
+
...chatScripts,
|
|
1257
|
+
...callAgentScript,
|
|
1258
|
+
...browserTools,
|
|
1259
|
+
...devScriptsForA2A,
|
|
1260
|
+
};
|
|
383
1261
|
const { mountA2A } = await import("../a2a/server.js");
|
|
384
1262
|
mountA2A(nitroApp, {
|
|
385
1263
|
name: options?.appId
|
|
@@ -394,12 +1272,9 @@ export function createAgentChatPlugin(options) {
|
|
|
394
1272
|
streaming: true,
|
|
395
1273
|
handler: async function* (message, context) {
|
|
396
1274
|
// Resolve the caller's identity for user-scoped data access.
|
|
397
|
-
// Dev: use most recent session from local DB (single user, no verification).
|
|
398
|
-
// Prod: verify Google OAuth token from caller, check email domain.
|
|
399
1275
|
const isDev = process.env.NODE_ENV !== "production";
|
|
400
1276
|
let userEmail;
|
|
401
1277
|
if (isDev) {
|
|
402
|
-
// Dev mode: trust the caller's claimed email, or auto-detect from local sessions
|
|
403
1278
|
userEmail = context.metadata?.userEmail || undefined;
|
|
404
1279
|
if (!userEmail) {
|
|
405
1280
|
try {
|
|
@@ -416,7 +1291,6 @@ export function createAgentChatPlugin(options) {
|
|
|
416
1291
|
}
|
|
417
1292
|
}
|
|
418
1293
|
else {
|
|
419
|
-
// Prod mode: verify identity via Google OAuth token
|
|
420
1294
|
const googleToken = context.metadata?.googleToken;
|
|
421
1295
|
if (googleToken) {
|
|
422
1296
|
try {
|
|
@@ -447,109 +1321,162 @@ export function createAgentChatPlugin(options) {
|
|
|
447
1321
|
};
|
|
448
1322
|
return;
|
|
449
1323
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
},
|
|
460
|
-
],
|
|
461
|
-
};
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
const client = new Anthropic({ apiKey });
|
|
465
|
-
const model = options?.model ?? "claude-sonnet-4-6";
|
|
466
|
-
// Load shared AGENTS.md resource so the agent knows how to use its tools
|
|
1324
|
+
// Use the SAME agent setup as the interactive chat — identical tools,
|
|
1325
|
+
// prompt, and capabilities. The A2A agent IS the app's agent.
|
|
1326
|
+
const a2aEngine = await resolveEngine({
|
|
1327
|
+
engineOption: options?.engine,
|
|
1328
|
+
apiKey: options?.apiKey,
|
|
1329
|
+
});
|
|
1330
|
+
// Use the same handler (dev or prod) that the interactive chat uses
|
|
1331
|
+
const handler = canToggle && devHandler ? devHandler : prodHandler;
|
|
1332
|
+
// Build the same system prompt the interactive agent uses
|
|
467
1333
|
const owner = userEmail || "local@localhost";
|
|
468
1334
|
const resources = await loadResourcesForPrompt(owner);
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
const
|
|
1335
|
+
const schemaBlock = await buildSchemaBlock(owner, canToggle);
|
|
1336
|
+
const systemPrompt = canToggle
|
|
1337
|
+
? devPrompt + resources + schemaBlock
|
|
1338
|
+
: basePrompt + resources + schemaBlock;
|
|
1339
|
+
const model = options?.model ??
|
|
1340
|
+
(canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
|
|
1341
|
+
// Build tools — same as interactive handler but WITHOUT call-agent
|
|
1342
|
+
// to prevent infinite recursive A2A loops (agent calling itself).
|
|
1343
|
+
// In dev mode, template actions are invoked via shell (not native tools),
|
|
1344
|
+
// so they're omitted from the tool registry — see allScripts comment.
|
|
1345
|
+
const a2aActions = canToggle
|
|
1346
|
+
? {
|
|
1347
|
+
...resourceScripts,
|
|
1348
|
+
...docsScripts,
|
|
1349
|
+
...chatScripts,
|
|
1350
|
+
...browserTools,
|
|
1351
|
+
...devScriptsForA2A,
|
|
1352
|
+
}
|
|
1353
|
+
: {
|
|
1354
|
+
...templateScripts,
|
|
1355
|
+
...resourceScripts,
|
|
1356
|
+
...docsScripts,
|
|
1357
|
+
...chatScripts,
|
|
1358
|
+
...browserTools,
|
|
1359
|
+
};
|
|
1360
|
+
const a2aTools = actionsToEngineTools(a2aActions);
|
|
1361
|
+
const a2aMessages = [
|
|
1362
|
+
{ role: "user", content: [{ type: "text", text }] },
|
|
1363
|
+
];
|
|
1364
|
+
// Run the SAME agent loop, collect text events, yield as A2A messages
|
|
480
1365
|
let accumulatedText = "";
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
event.delta?.type === "text_delta") {
|
|
494
|
-
accumulatedText += event.delta.text;
|
|
495
|
-
yield {
|
|
496
|
-
role: "agent",
|
|
497
|
-
parts: [{ type: "text", text: accumulatedText }],
|
|
498
|
-
};
|
|
1366
|
+
const controller = new AbortController();
|
|
1367
|
+
console.log(`[A2A] Starting agent loop: ${a2aTools.length} tools, prompt ${systemPrompt.length} chars`);
|
|
1368
|
+
await runAgentLoop({
|
|
1369
|
+
engine: a2aEngine,
|
|
1370
|
+
model,
|
|
1371
|
+
systemPrompt,
|
|
1372
|
+
tools: a2aTools,
|
|
1373
|
+
messages: a2aMessages,
|
|
1374
|
+
actions: a2aActions,
|
|
1375
|
+
send: (event) => {
|
|
1376
|
+
if (event.type === "text") {
|
|
1377
|
+
accumulatedText += event.text;
|
|
499
1378
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
const finalMessage = await apiStream.finalMessage();
|
|
503
|
-
const toolUseBlocks = finalMessage.content.filter((b) => b.type === "tool_use");
|
|
504
|
-
if (toolUseBlocks.length === 0 ||
|
|
505
|
-
finalMessage.stop_reason !== "tool_use") {
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
// Execute tools and continue the loop
|
|
509
|
-
msgs.push({ role: "assistant", content: finalMessage.content });
|
|
510
|
-
const toolResults = [];
|
|
511
|
-
for (const tb of toolUseBlocks) {
|
|
512
|
-
const script = allScripts[tb.name];
|
|
513
|
-
let result = `Unknown tool: ${tb.name}`;
|
|
514
|
-
if (script) {
|
|
515
|
-
try {
|
|
516
|
-
result = await script.run(tb.input);
|
|
517
|
-
}
|
|
518
|
-
catch (err) {
|
|
519
|
-
result = `Error: ${err?.message}`;
|
|
520
|
-
}
|
|
1379
|
+
else if (event.type === "tool_start") {
|
|
1380
|
+
console.log(`[A2A] Tool call: ${event.tool}`);
|
|
521
1381
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
1382
|
+
else if (event.type === "error") {
|
|
1383
|
+
console.error(`[A2A] Error: ${event.error}`);
|
|
1384
|
+
}
|
|
1385
|
+
else if (event.type === "done") {
|
|
1386
|
+
console.log(`[A2A] Done. Response: ${accumulatedText.length} chars`);
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1389
|
+
signal: controller.signal,
|
|
1390
|
+
});
|
|
1391
|
+
console.log(`[A2A] Loop complete. Text: ${accumulatedText.slice(0, 100)}...`);
|
|
1392
|
+
// Yield the final accumulated text
|
|
1393
|
+
yield {
|
|
1394
|
+
role: "agent",
|
|
1395
|
+
parts: [
|
|
1396
|
+
{
|
|
1397
|
+
type: "text",
|
|
1398
|
+
text: accumulatedText || "(no response)",
|
|
1399
|
+
},
|
|
1400
|
+
],
|
|
1401
|
+
};
|
|
537
1402
|
},
|
|
538
1403
|
});
|
|
539
1404
|
// Generate an "Available Actions" section from template-specific actions
|
|
540
|
-
// so the agent knows to use them instead of raw SQL
|
|
541
|
-
|
|
1405
|
+
// so the agent knows to use them instead of raw SQL.
|
|
1406
|
+
//
|
|
1407
|
+
// Production: actions are native tools — emit `name(arg*: type) — desc`
|
|
1408
|
+
// Dev: actions are invoked via shell — emit `pnpm action name --arg <type>`
|
|
1409
|
+
// and include discoveredActions too, since those are also missing
|
|
1410
|
+
// from the dev tool registry.
|
|
1411
|
+
const prodActionsPrompt = generateActionsPrompt(templateScripts, "tool");
|
|
1412
|
+
const devActionsPrompt = generateActionsPrompt({ ...discoveredActions, ...templateScripts }, "cli");
|
|
542
1413
|
// Build system prompts — dynamic functions that pre-load resources per-request.
|
|
543
1414
|
// Production gets PROD_FRAMEWORK_PROMPT, dev gets DEV_FRAMEWORK_PROMPT.
|
|
544
1415
|
// Custom systemPrompt from options overrides the framework default entirely.
|
|
545
|
-
const prodPrompt = (options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT) +
|
|
1416
|
+
const prodPrompt = (options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT) + prodActionsPrompt;
|
|
546
1417
|
const devPrompt = (options?.devSystemPrompt
|
|
547
1418
|
? options.devSystemPrompt +
|
|
548
1419
|
(options?.systemPrompt ?? PROD_FRAMEWORK_PROMPT)
|
|
549
|
-
: DEV_FRAMEWORK_PROMPT) +
|
|
1420
|
+
: DEV_FRAMEWORK_PROMPT) + devActionsPrompt;
|
|
550
1421
|
// Keep legacy names for the composition below
|
|
551
1422
|
const basePrompt = prodPrompt;
|
|
552
1423
|
const devPrefix = options?.devSystemPrompt ?? DEFAULT_DEV_PROMPT;
|
|
1424
|
+
// Mount MCP remote server — same action registry as A2A + agent chat
|
|
1425
|
+
const { mountMCP } = await import("../mcp/server.js");
|
|
1426
|
+
mountMCP(nitroApp, {
|
|
1427
|
+
name: options?.appId
|
|
1428
|
+
? options.appId.charAt(0).toUpperCase() + options.appId.slice(1)
|
|
1429
|
+
: "Agent",
|
|
1430
|
+
description: `Agent-native ${options?.appId ?? "app"} agent`,
|
|
1431
|
+
actions: allScripts,
|
|
1432
|
+
askAgent: async (message) => {
|
|
1433
|
+
const mcpEngine = await resolveEngine({
|
|
1434
|
+
engineOption: options?.engine,
|
|
1435
|
+
apiKey: options?.apiKey,
|
|
1436
|
+
});
|
|
1437
|
+
const model = options?.model ??
|
|
1438
|
+
(canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
|
|
1439
|
+
// Same actions as A2A — without call-agent to prevent loops.
|
|
1440
|
+
// In dev mode, template actions go through shell, not native tools.
|
|
1441
|
+
const mcpActions = canToggle
|
|
1442
|
+
? {
|
|
1443
|
+
...resourceScripts,
|
|
1444
|
+
...docsScripts,
|
|
1445
|
+
...chatScripts,
|
|
1446
|
+
...devScriptsForA2A,
|
|
1447
|
+
}
|
|
1448
|
+
: {
|
|
1449
|
+
...templateScripts,
|
|
1450
|
+
...resourceScripts,
|
|
1451
|
+
...docsScripts,
|
|
1452
|
+
...chatScripts,
|
|
1453
|
+
};
|
|
1454
|
+
const mcpTools = actionsToEngineTools(mcpActions);
|
|
1455
|
+
const resources = await loadResourcesForPrompt("local@localhost");
|
|
1456
|
+
const schemaBlock = await buildSchemaBlock("local@localhost", canToggle);
|
|
1457
|
+
const systemPrompt = canToggle
|
|
1458
|
+
? devPrompt + resources + schemaBlock
|
|
1459
|
+
: basePrompt + resources + schemaBlock;
|
|
1460
|
+
let accumulatedText = "";
|
|
1461
|
+
const controller = new AbortController();
|
|
1462
|
+
await runAgentLoop({
|
|
1463
|
+
engine: mcpEngine,
|
|
1464
|
+
model,
|
|
1465
|
+
systemPrompt,
|
|
1466
|
+
tools: mcpTools,
|
|
1467
|
+
messages: [
|
|
1468
|
+
{ role: "user", content: [{ type: "text", text: message }] },
|
|
1469
|
+
],
|
|
1470
|
+
actions: mcpActions,
|
|
1471
|
+
send: (event) => {
|
|
1472
|
+
if (event.type === "text")
|
|
1473
|
+
accumulatedText += event.text;
|
|
1474
|
+
},
|
|
1475
|
+
signal: controller.signal,
|
|
1476
|
+
});
|
|
1477
|
+
return accumulatedText || "(no response)";
|
|
1478
|
+
},
|
|
1479
|
+
});
|
|
553
1480
|
// Resolve owner from the H3 event's session — matches how resources are created
|
|
554
1481
|
const getOwnerFromEvent = async (event) => {
|
|
555
1482
|
try {
|
|
@@ -560,6 +1487,20 @@ export function createAgentChatPlugin(options) {
|
|
|
560
1487
|
return "local@localhost";
|
|
561
1488
|
}
|
|
562
1489
|
};
|
|
1490
|
+
// Auto-mount template actions as HTTP endpoints under /_agent-native/actions/
|
|
1491
|
+
// Include engine management scripts so the UI can call list/set/test-agent-engine.
|
|
1492
|
+
const httpActions = {
|
|
1493
|
+
...discoveredActions,
|
|
1494
|
+
...templateScripts,
|
|
1495
|
+
...engineScripts,
|
|
1496
|
+
};
|
|
1497
|
+
if (Object.keys(httpActions).length > 0) {
|
|
1498
|
+
const { mountActionRoutes } = await import("./action-routes.js");
|
|
1499
|
+
mountActionRoutes(nitroApp, httpActions, {
|
|
1500
|
+
getOwnerFromEvent,
|
|
1501
|
+
resolveOrgId: options?.resolveOrgId,
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
563
1504
|
// Callback to persist agent response when run finishes (even if client disconnected).
|
|
564
1505
|
// Reconstructs the assistant message from buffered events and appends to thread_data.
|
|
565
1506
|
const onRunComplete = async (run, threadId) => {
|
|
@@ -588,12 +1529,24 @@ export function createAgentChatPlugin(options) {
|
|
|
588
1529
|
if (!Array.isArray(repo.messages))
|
|
589
1530
|
repo.messages = [];
|
|
590
1531
|
const lastMsg = repo.messages[repo.messages.length - 1];
|
|
591
|
-
|
|
1532
|
+
// Check both wrapped ({ message: { role } }) and unwrapped ({ role }) formats
|
|
1533
|
+
const lastRole = lastMsg?.message?.role ?? lastMsg?.role;
|
|
1534
|
+
if (lastRole === "assistant") {
|
|
592
1535
|
// Frontend already saved the assistant response — just bump timestamp
|
|
593
1536
|
await updateThreadData(threadId, thread.threadData, thread.title, thread.preview, thread.messageCount);
|
|
594
1537
|
return;
|
|
595
1538
|
}
|
|
596
|
-
repo
|
|
1539
|
+
// Determine if repo uses wrapped format ({ message, parentId }) or flat format
|
|
1540
|
+
const isWrapped = lastMsg && "message" in lastMsg;
|
|
1541
|
+
if (isWrapped) {
|
|
1542
|
+
const parentId = repo.messages.length > 0
|
|
1543
|
+
? (repo.messages[repo.messages.length - 1].message?.id ?? null)
|
|
1544
|
+
: null;
|
|
1545
|
+
repo.messages.push({ message: assistantMsg, parentId });
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
repo.messages.push(assistantMsg);
|
|
1549
|
+
}
|
|
597
1550
|
const meta = extractThreadMeta(repo);
|
|
598
1551
|
await updateThreadData(threadId, JSON.stringify(repo), meta.title || thread.title, meta.preview || thread.preview, repo.messages.length);
|
|
599
1552
|
}
|
|
@@ -601,38 +1554,138 @@ export function createAgentChatPlugin(options) {
|
|
|
601
1554
|
// Best-effort — don't break cleanup
|
|
602
1555
|
}
|
|
603
1556
|
};
|
|
604
|
-
//
|
|
1557
|
+
// ─── Agent Teams: per-run send reference ─────────────────────────
|
|
1558
|
+
// Team tools need to emit events to the parent chat's SSE stream.
|
|
1559
|
+
// Each run gets its own send function, keyed by threadId so concurrent
|
|
1560
|
+
// requests for different threads don't clobber each other.
|
|
1561
|
+
const _runSendByThread = new Map();
|
|
1562
|
+
let _currentRunOwner = "local@localhost";
|
|
1563
|
+
let _currentRunThreadId = "";
|
|
1564
|
+
let _currentRunSystemPrompt = basePrompt;
|
|
1565
|
+
// Default to Haiku in production mode to manage costs for hosted apps
|
|
1566
|
+
const resolvedModel = options?.model ??
|
|
1567
|
+
(canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
|
|
1568
|
+
const teamTools = createTeamTools({
|
|
1569
|
+
getOwner: () => _currentRunOwner,
|
|
1570
|
+
getSystemPrompt: () => _currentRunSystemPrompt,
|
|
1571
|
+
getActions: () => canToggle
|
|
1572
|
+
? {
|
|
1573
|
+
// Sub-agents spawned in dev mode also invoke template actions
|
|
1574
|
+
// via shell, so omit them from the native tool registry.
|
|
1575
|
+
...resourceScripts,
|
|
1576
|
+
...docsScripts,
|
|
1577
|
+
...chatScripts,
|
|
1578
|
+
...devScriptsForA2A,
|
|
1579
|
+
}
|
|
1580
|
+
: {
|
|
1581
|
+
...templateScripts,
|
|
1582
|
+
...resourceScripts,
|
|
1583
|
+
...docsScripts,
|
|
1584
|
+
...chatScripts,
|
|
1585
|
+
},
|
|
1586
|
+
getEngine: () => createAnthropicEngine({
|
|
1587
|
+
apiKey: options?.apiKey ?? process.env.ANTHROPIC_API_KEY,
|
|
1588
|
+
}),
|
|
1589
|
+
getModel: () => resolvedModel,
|
|
1590
|
+
getParentThreadId: () => _currentRunThreadId,
|
|
1591
|
+
getSend: () => {
|
|
1592
|
+
// Return the send for the current run's thread
|
|
1593
|
+
const send = _runSendByThread.get(_currentRunThreadId);
|
|
1594
|
+
return send ?? null;
|
|
1595
|
+
},
|
|
1596
|
+
});
|
|
1597
|
+
// Hook into the run lifecycle to set/clear the send reference.
|
|
1598
|
+
// Job management tools (create-job, list-jobs, update-job)
|
|
1599
|
+
let jobTools = {};
|
|
1600
|
+
try {
|
|
1601
|
+
const { createJobTools } = await import("../jobs/tools.js");
|
|
1602
|
+
jobTools = createJobTools();
|
|
1603
|
+
}
|
|
1604
|
+
catch { }
|
|
1605
|
+
const prodActions = {
|
|
1606
|
+
...templateScripts,
|
|
1607
|
+
...resourceScripts,
|
|
1608
|
+
...docsScripts,
|
|
1609
|
+
...chatScripts,
|
|
1610
|
+
...callAgentScript,
|
|
1611
|
+
...teamTools,
|
|
1612
|
+
...jobTools,
|
|
1613
|
+
...browserTools,
|
|
1614
|
+
...mcpActionEntries,
|
|
1615
|
+
};
|
|
1616
|
+
// Always build the production handler (includes resource tools + call-agent + team tools)
|
|
1617
|
+
// In production mode (!canToggle), enable usage tracking and limits
|
|
1618
|
+
const isHostedProd = !canToggle;
|
|
605
1619
|
const prodHandler = createProductionAgentHandler({
|
|
606
|
-
actions:
|
|
1620
|
+
actions: prodActions,
|
|
607
1621
|
systemPrompt: async (event) => {
|
|
1622
|
+
_currentRequestOrigin = getOrigin(event);
|
|
608
1623
|
const owner = await getOwnerFromEvent(event);
|
|
1624
|
+
_currentRunOwner = owner;
|
|
609
1625
|
const resources = await loadResourcesForPrompt(owner);
|
|
610
|
-
|
|
1626
|
+
const schemaBlock = await buildSchemaBlock(owner, false);
|
|
1627
|
+
_currentRunSystemPrompt = basePrompt + resources + schemaBlock;
|
|
1628
|
+
return _currentRunSystemPrompt;
|
|
611
1629
|
},
|
|
612
|
-
model: options?.model
|
|
1630
|
+
model: options?.model ??
|
|
1631
|
+
(isHostedProd ? "claude-haiku-4-5-20251001" : undefined),
|
|
613
1632
|
apiKey: options?.apiKey,
|
|
614
|
-
|
|
1633
|
+
onRunStart: (send, threadId) => {
|
|
1634
|
+
_runSendByThread.set(threadId, send);
|
|
1635
|
+
_currentRunThreadId = threadId;
|
|
1636
|
+
},
|
|
1637
|
+
onRunComplete: async (run, threadId) => {
|
|
1638
|
+
if (threadId)
|
|
1639
|
+
_runSendByThread.delete(threadId);
|
|
1640
|
+
await onRunComplete(run, threadId);
|
|
1641
|
+
},
|
|
1642
|
+
// Usage tracking for hosted production deployments
|
|
1643
|
+
trackUsage: isHostedProd,
|
|
1644
|
+
resolveOwnerEmail: isHostedProd ? getOwnerFromEvent : undefined,
|
|
615
1645
|
});
|
|
616
1646
|
// Build the dev handler (with filesystem/shell/db tools) if environment allows toggling
|
|
617
1647
|
let devHandler = null;
|
|
618
1648
|
if (canToggle) {
|
|
619
1649
|
const { createDevScriptRegistry } = await import("../scripts/dev/index.js");
|
|
1650
|
+
// Dev mode: template actions (templateScripts and discoveredActions) are
|
|
1651
|
+
// intentionally OMITTED from the native tool registry. The agent invokes
|
|
1652
|
+
// them via `shell(command="pnpm action <name> ...")` instead. This mirrors
|
|
1653
|
+
// how Claude Code works locally and dramatically reduces the rate of
|
|
1654
|
+
// degenerate empty-object tool calls. The CLI syntax for each action is
|
|
1655
|
+
// listed in the dev system prompt's "Available Actions" section.
|
|
620
1656
|
const devActions = {
|
|
621
|
-
...templateScripts,
|
|
622
1657
|
...resourceScripts,
|
|
1658
|
+
...docsScripts,
|
|
1659
|
+
...chatScripts,
|
|
623
1660
|
...callAgentScript,
|
|
1661
|
+
...teamTools,
|
|
1662
|
+
...jobTools,
|
|
1663
|
+
...browserTools,
|
|
1664
|
+
...mcpActionEntries,
|
|
624
1665
|
...(await createDevScriptRegistry()),
|
|
625
1666
|
};
|
|
626
1667
|
devHandler = createProductionAgentHandler({
|
|
627
1668
|
actions: devActions,
|
|
628
1669
|
systemPrompt: async (event) => {
|
|
1670
|
+
_currentRequestOrigin = getOrigin(event);
|
|
629
1671
|
const owner = await getOwnerFromEvent(event);
|
|
1672
|
+
_currentRunOwner = owner;
|
|
630
1673
|
const resources = await loadResourcesForPrompt(owner);
|
|
631
|
-
|
|
1674
|
+
const schemaBlock = await buildSchemaBlock(owner, true);
|
|
1675
|
+
_currentRunSystemPrompt = devPrompt + resources + schemaBlock;
|
|
1676
|
+
return _currentRunSystemPrompt;
|
|
632
1677
|
},
|
|
633
1678
|
model: options?.model,
|
|
634
1679
|
apiKey: options?.apiKey,
|
|
635
|
-
|
|
1680
|
+
onRunStart: (send, threadId) => {
|
|
1681
|
+
_runSendByThread.set(threadId, send);
|
|
1682
|
+
_currentRunThreadId = threadId;
|
|
1683
|
+
},
|
|
1684
|
+
onRunComplete: async (run, threadId) => {
|
|
1685
|
+
if (threadId)
|
|
1686
|
+
_runSendByThread.delete(threadId);
|
|
1687
|
+
await onRunComplete(run, threadId);
|
|
1688
|
+
},
|
|
636
1689
|
});
|
|
637
1690
|
}
|
|
638
1691
|
// Resolve mention providers
|
|
@@ -643,7 +1696,7 @@ export function createAgentChatPlugin(options) {
|
|
|
643
1696
|
// Mutable mode flag — starts in dev if environment allows
|
|
644
1697
|
let currentDevMode = canToggle;
|
|
645
1698
|
// Mount mode endpoint — GET returns current mode, POST toggles it (localhost only)
|
|
646
|
-
nitroApp.
|
|
1699
|
+
getH3App(nitroApp).use(`${routePath}/mode`, defineEventHandler(async (event) => {
|
|
647
1700
|
if (getMethod(event) === "POST") {
|
|
648
1701
|
if (!canToggle) {
|
|
649
1702
|
setResponseStatus(event, 403);
|
|
@@ -666,7 +1719,7 @@ export function createAgentChatPlugin(options) {
|
|
|
666
1719
|
}));
|
|
667
1720
|
// Mount save-key BEFORE the prefix handler so it isn't shadowed
|
|
668
1721
|
// Only functional in Node.js environments (writes to .env file)
|
|
669
|
-
nitroApp.
|
|
1722
|
+
getH3App(nitroApp).use(`${routePath}/save-key`, defineEventHandler(async (event) => {
|
|
670
1723
|
if (getMethod(event) !== "POST") {
|
|
671
1724
|
setResponseStatus(event, 405);
|
|
672
1725
|
return { error: "Method not allowed" };
|
|
@@ -682,7 +1735,7 @@ export function createAgentChatPlugin(options) {
|
|
|
682
1735
|
const path = await import("path");
|
|
683
1736
|
const { upsertEnvFile } = await import("./create-server.js");
|
|
684
1737
|
const envPath = path.join(process.cwd(), ".env");
|
|
685
|
-
upsertEnvFile(envPath, [
|
|
1738
|
+
await upsertEnvFile(envPath, [
|
|
686
1739
|
{ key: "ANTHROPIC_API_KEY", value: trimmedKey },
|
|
687
1740
|
]);
|
|
688
1741
|
}
|
|
@@ -694,7 +1747,7 @@ export function createAgentChatPlugin(options) {
|
|
|
694
1747
|
return { ok: true };
|
|
695
1748
|
}));
|
|
696
1749
|
// Mount file search endpoint
|
|
697
|
-
nitroApp.
|
|
1750
|
+
getH3App(nitroApp).use(`${routePath}/files`, defineEventHandler(async (event) => {
|
|
698
1751
|
if (getMethod(event) !== "GET") {
|
|
699
1752
|
setResponseStatus(event, 405);
|
|
700
1753
|
return { error: "Method not allowed" };
|
|
@@ -707,7 +1760,7 @@ export function createAgentChatPlugin(options) {
|
|
|
707
1760
|
if (currentDevMode) {
|
|
708
1761
|
const codebaseFiles = [];
|
|
709
1762
|
try {
|
|
710
|
-
collectFiles(process.cwd(), "", 0, codebaseFiles);
|
|
1763
|
+
await collectFiles(process.cwd(), "", 0, codebaseFiles);
|
|
711
1764
|
}
|
|
712
1765
|
catch {
|
|
713
1766
|
// Filesystem access failed — skip
|
|
@@ -751,7 +1804,7 @@ export function createAgentChatPlugin(options) {
|
|
|
751
1804
|
return { files: filtered.slice(0, 30) };
|
|
752
1805
|
}));
|
|
753
1806
|
// Mount skills listing endpoint
|
|
754
|
-
nitroApp.
|
|
1807
|
+
getH3App(nitroApp).use(`${routePath}/skills`, defineEventHandler(async (event) => {
|
|
755
1808
|
if (getMethod(event) !== "GET") {
|
|
756
1809
|
setResponseStatus(event, 405);
|
|
757
1810
|
return { error: "Method not allowed" };
|
|
@@ -761,8 +1814,9 @@ export function createAgentChatPlugin(options) {
|
|
|
761
1814
|
// In dev mode, scan .agents/skills/ directory
|
|
762
1815
|
if (currentDevMode) {
|
|
763
1816
|
try {
|
|
1817
|
+
const _fs = await lazyFs();
|
|
764
1818
|
const skillsDir = nodePath.join(process.cwd(), ".agents", "skills");
|
|
765
|
-
const entries =
|
|
1819
|
+
const entries = _fs.readdirSync(skillsDir, {
|
|
766
1820
|
withFileTypes: true,
|
|
767
1821
|
});
|
|
768
1822
|
for (const entry of entries) {
|
|
@@ -772,7 +1826,7 @@ export function createAgentChatPlugin(options) {
|
|
|
772
1826
|
if (entry.isDirectory()) {
|
|
773
1827
|
// Subdirectory layout: .agents/skills/<name>/SKILL.md
|
|
774
1828
|
const candidate = nodePath.join(skillsDir, entry.name, "SKILL.md");
|
|
775
|
-
if (!
|
|
1829
|
+
if (!_fs.existsSync(candidate))
|
|
776
1830
|
continue;
|
|
777
1831
|
skillFilePath = candidate;
|
|
778
1832
|
skillRelPath = `.agents/skills/${entry.name}/SKILL.md`;
|
|
@@ -786,7 +1840,7 @@ export function createAgentChatPlugin(options) {
|
|
|
786
1840
|
continue;
|
|
787
1841
|
}
|
|
788
1842
|
try {
|
|
789
|
-
const content =
|
|
1843
|
+
const content = _fs.readFileSync(skillFilePath, "utf-8");
|
|
790
1844
|
const fm = parseSkillFrontmatter(content);
|
|
791
1845
|
const skillName = fm.name || entry.name.replace(/\.md$/, "");
|
|
792
1846
|
if (!seenNames.has(skillName)) {
|
|
@@ -851,107 +1905,166 @@ export function createAgentChatPlugin(options) {
|
|
|
851
1905
|
return result;
|
|
852
1906
|
}));
|
|
853
1907
|
// Mount unified mentions endpoint (files + resources + custom providers)
|
|
854
|
-
nitroApp.
|
|
1908
|
+
getH3App(nitroApp).use(`${routePath}/mentions`, defineEventHandler(async (event) => {
|
|
855
1909
|
if (getMethod(event) !== "GET") {
|
|
856
1910
|
setResponseStatus(event, 405);
|
|
857
1911
|
return { error: "Method not allowed" };
|
|
858
1912
|
}
|
|
859
1913
|
const query = getQuery(event);
|
|
860
1914
|
const q = typeof query.q === "string" ? query.q.toLowerCase() : "";
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1915
|
+
const matchesQuery = (item) => !q ||
|
|
1916
|
+
item.label.toLowerCase().includes(q) ||
|
|
1917
|
+
(item.description?.toLowerCase().includes(q) ?? false);
|
|
1918
|
+
const enc = new TextEncoder();
|
|
1919
|
+
// Stream NDJSON — each source flushes its batch as soon as it's ready.
|
|
1920
|
+
setResponseHeader(event, "Content-Type", "application/x-ndjson");
|
|
1921
|
+
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
1922
|
+
const stream = new ReadableStream({
|
|
1923
|
+
async start(controller) {
|
|
1924
|
+
const MAX_RESULTS = 50;
|
|
1925
|
+
let totalSent = 0;
|
|
1926
|
+
let cancelled = false;
|
|
1927
|
+
const flush = (batch) => {
|
|
1928
|
+
if (cancelled)
|
|
1929
|
+
return;
|
|
1930
|
+
const filtered = batch.filter(matchesQuery);
|
|
1931
|
+
if (filtered.length === 0)
|
|
1932
|
+
return;
|
|
1933
|
+
const remaining = MAX_RESULTS - totalSent;
|
|
1934
|
+
const toSend = filtered.slice(0, remaining);
|
|
1935
|
+
if (toSend.length > 0) {
|
|
1936
|
+
totalSent += toSend.length;
|
|
1937
|
+
try {
|
|
1938
|
+
controller.enqueue(enc.encode(JSON.stringify({ items: toSend }) + "\n"));
|
|
1939
|
+
}
|
|
1940
|
+
catch {
|
|
1941
|
+
// Stream was closed by client
|
|
1942
|
+
cancelled = true;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
};
|
|
1946
|
+
// All sources run in parallel; each flushes independently.
|
|
1947
|
+
const sources = [];
|
|
1948
|
+
// 1. Resources from SQL (fast — flush first)
|
|
1949
|
+
sources.push((async () => {
|
|
1950
|
+
try {
|
|
1951
|
+
const resources = currentDevMode
|
|
1952
|
+
? await resourceListAccessible("local@localhost")
|
|
1953
|
+
: await resourceList(SHARED_OWNER);
|
|
1954
|
+
flush(resources.map((r) => {
|
|
1955
|
+
const isShared = r.owner === SHARED_OWNER;
|
|
1956
|
+
return {
|
|
1957
|
+
id: `resource:${r.path}`,
|
|
1958
|
+
label: r.path.split("/").pop() || r.path,
|
|
1959
|
+
description: r.path,
|
|
1960
|
+
icon: "file",
|
|
1961
|
+
source: isShared
|
|
1962
|
+
? "resource:shared"
|
|
1963
|
+
: "resource:private",
|
|
1964
|
+
refType: "file",
|
|
1965
|
+
refPath: r.path,
|
|
1966
|
+
section: "Files",
|
|
1967
|
+
};
|
|
1968
|
+
}));
|
|
1969
|
+
}
|
|
1970
|
+
catch { }
|
|
1971
|
+
})());
|
|
1972
|
+
// 2. Codebase files (dev mode only — can be slow on large repos)
|
|
1973
|
+
if (currentDevMode) {
|
|
1974
|
+
sources.push((async () => {
|
|
1975
|
+
const codebaseFiles = [];
|
|
1976
|
+
try {
|
|
1977
|
+
await collectFiles(process.cwd(), "", 0, codebaseFiles);
|
|
1978
|
+
}
|
|
1979
|
+
catch { }
|
|
1980
|
+
flush(codebaseFiles.map((f) => ({
|
|
1981
|
+
id: `codebase:${f.path}`,
|
|
1982
|
+
label: f.name,
|
|
1983
|
+
description: f.path !== f.name ? f.path : undefined,
|
|
1984
|
+
icon: f.type,
|
|
1985
|
+
source: "codebase",
|
|
1986
|
+
refType: "file",
|
|
1987
|
+
refPath: f.path,
|
|
1988
|
+
section: "Files",
|
|
1989
|
+
})));
|
|
1990
|
+
})());
|
|
1991
|
+
}
|
|
1992
|
+
// 3. Custom mention providers (each flushes independently)
|
|
1993
|
+
for (const [key, provider] of Object.entries(mentionProviders)) {
|
|
1994
|
+
sources.push((async () => {
|
|
1995
|
+
try {
|
|
1996
|
+
const providerItems = await provider.search(q, event);
|
|
1997
|
+
flush(providerItems.map((item) => ({
|
|
1998
|
+
id: item.id,
|
|
1999
|
+
label: item.label,
|
|
2000
|
+
description: item.description,
|
|
2001
|
+
icon: item.icon || provider.icon || "file",
|
|
2002
|
+
source: key,
|
|
2003
|
+
refType: item.refType,
|
|
2004
|
+
refPath: item.refPath,
|
|
2005
|
+
refId: item.refId,
|
|
2006
|
+
section: provider.label,
|
|
2007
|
+
})));
|
|
2008
|
+
}
|
|
2009
|
+
catch (e) {
|
|
2010
|
+
console.error(`[agent-native] Mention provider "${key}" failed:`, e);
|
|
2011
|
+
}
|
|
2012
|
+
})());
|
|
2013
|
+
}
|
|
2014
|
+
// 4. Custom workspace agents
|
|
2015
|
+
sources.push((async () => {
|
|
2016
|
+
try {
|
|
2017
|
+
const owner = await getOwnerFromEvent(event);
|
|
2018
|
+
const { listAccessibleCustomAgents } = await import("../resources/agents.js");
|
|
2019
|
+
const agents = await listAccessibleCustomAgents(owner);
|
|
2020
|
+
flush(agents.map((agent) => ({
|
|
2021
|
+
id: `custom-agent:${agent.id}`,
|
|
2022
|
+
label: agent.name,
|
|
2023
|
+
description: agent.description || agent.path,
|
|
2024
|
+
icon: "agent",
|
|
2025
|
+
source: "agent:custom",
|
|
2026
|
+
refType: "custom-agent",
|
|
2027
|
+
refPath: agent.path,
|
|
2028
|
+
refId: agent.id,
|
|
2029
|
+
section: "Agents",
|
|
2030
|
+
})));
|
|
2031
|
+
}
|
|
2032
|
+
catch (e) {
|
|
2033
|
+
console.error("[agent-native] Custom agent discovery failed:", e);
|
|
2034
|
+
}
|
|
2035
|
+
})());
|
|
2036
|
+
// 5. Peer agent discovery (network call — often slowest)
|
|
2037
|
+
sources.push((async () => {
|
|
2038
|
+
try {
|
|
2039
|
+
const agents = await discoverAgents(options?.appId);
|
|
2040
|
+
flush(agents.map((agent) => ({
|
|
2041
|
+
id: `agent:${agent.id}`,
|
|
2042
|
+
label: agent.name,
|
|
2043
|
+
description: agent.description,
|
|
2044
|
+
icon: "agent",
|
|
2045
|
+
source: "agent",
|
|
2046
|
+
refType: "agent",
|
|
2047
|
+
refPath: agent.url,
|
|
2048
|
+
refId: agent.id,
|
|
2049
|
+
section: "Connected Agents",
|
|
2050
|
+
})));
|
|
2051
|
+
}
|
|
2052
|
+
catch (e) {
|
|
2053
|
+
console.error("[agent-native] Agent discovery failed:", e);
|
|
2054
|
+
}
|
|
2055
|
+
})());
|
|
2056
|
+
await Promise.all(sources);
|
|
2057
|
+
if (!cancelled)
|
|
2058
|
+
controller.close();
|
|
2059
|
+
},
|
|
2060
|
+
cancel() {
|
|
2061
|
+
// Client disconnected — stop enqueuing
|
|
2062
|
+
},
|
|
2063
|
+
});
|
|
2064
|
+
return stream;
|
|
952
2065
|
}));
|
|
953
2066
|
// ─── Generate thread title ──────────────────────────────────────────
|
|
954
|
-
nitroApp.
|
|
2067
|
+
getH3App(nitroApp).use(`${routePath}/generate-title`, defineEventHandler(async (event) => {
|
|
955
2068
|
if (getMethod(event) !== "POST") {
|
|
956
2069
|
setResponseStatus(event, 405);
|
|
957
2070
|
return { error: "Method not allowed" };
|
|
@@ -963,10 +2076,12 @@ export function createAgentChatPlugin(options) {
|
|
|
963
2076
|
setResponseStatus(event, 400);
|
|
964
2077
|
return { error: "message is required" };
|
|
965
2078
|
}
|
|
2079
|
+
// Strip mention markup: @[Name|type] → @Name
|
|
2080
|
+
const cleanMessage = message.replace(/@\[([^\]|]+)\|[^\]]*\]/g, "@$1");
|
|
966
2081
|
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
967
2082
|
if (!apiKey) {
|
|
968
2083
|
// Fallback: truncate the message
|
|
969
|
-
return { title:
|
|
2084
|
+
return { title: cleanMessage.trim().slice(0, 60) };
|
|
970
2085
|
}
|
|
971
2086
|
try {
|
|
972
2087
|
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
@@ -982,38 +2097,42 @@ export function createAgentChatPlugin(options) {
|
|
|
982
2097
|
messages: [
|
|
983
2098
|
{
|
|
984
2099
|
role: "user",
|
|
985
|
-
content: `Generate a very short title (3-6 words, no quotes) for a chat that starts with this message:\n\n${
|
|
2100
|
+
content: `Generate a very short title (3-6 words, no quotes) for a chat that starts with this message:\n\n${cleanMessage.slice(0, 500)}`,
|
|
986
2101
|
},
|
|
987
2102
|
],
|
|
988
2103
|
}),
|
|
989
2104
|
});
|
|
990
2105
|
if (!res.ok) {
|
|
991
|
-
return { title:
|
|
2106
|
+
return { title: cleanMessage.trim().slice(0, 60) };
|
|
992
2107
|
}
|
|
993
2108
|
const data = (await res.json());
|
|
994
2109
|
const text = data.content?.[0]?.text?.trim();
|
|
995
|
-
return { title: text ||
|
|
2110
|
+
return { title: text || cleanMessage.trim().slice(0, 60) };
|
|
996
2111
|
}
|
|
997
2112
|
catch {
|
|
998
|
-
return { title:
|
|
2113
|
+
return { title: cleanMessage.trim().slice(0, 60) };
|
|
999
2114
|
}
|
|
1000
2115
|
}));
|
|
1001
2116
|
// ─── Run management endpoints (for hot-reload resilience) ─────────────
|
|
1002
2117
|
// GET /runs/active?threadId=X — check if there's an active run for a thread
|
|
1003
|
-
nitroApp.
|
|
2118
|
+
getH3App(nitroApp).use(`${routePath}/runs`, defineEventHandler(async (event) => {
|
|
1004
2119
|
// Auth check — ensure the user is authenticated
|
|
1005
2120
|
await getOwnerFromEvent(event);
|
|
1006
2121
|
const method = getMethod(event);
|
|
1007
2122
|
const url = event.node?.req?.url || event.path || "";
|
|
1008
2123
|
// Route: POST /runs/:id/abort
|
|
1009
|
-
|
|
2124
|
+
// Match both full URL (/runs/{id}/abort) and h3 prefix-stripped (/{id}/abort)
|
|
2125
|
+
const abortMatch = url.match(/\/runs\/([^/?]+)\/abort/) ||
|
|
2126
|
+
url.match(/^\/([^/?]+)\/abort/);
|
|
1010
2127
|
if (abortMatch && method === "POST") {
|
|
1011
2128
|
const runId = decodeURIComponent(abortMatch[1]);
|
|
1012
2129
|
abortRun(runId); // Aborts in-memory + marks aborted in SQL
|
|
1013
2130
|
return { ok: true };
|
|
1014
2131
|
}
|
|
1015
2132
|
// Route: GET /runs/:id/events?after=N
|
|
1016
|
-
|
|
2133
|
+
// Match both full URL (/runs/{id}/events) and h3 prefix-stripped (/{id}/events)
|
|
2134
|
+
const eventsMatch = url.match(/\/runs\/([^/?]+)\/events/) ||
|
|
2135
|
+
url.match(/^\/([^/?]+)\/events/);
|
|
1017
2136
|
if (eventsMatch && method === "GET") {
|
|
1018
2137
|
const runId = decodeURIComponent(eventsMatch[1]);
|
|
1019
2138
|
const query = getQuery(event);
|
|
@@ -1054,7 +2173,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1054
2173
|
// ─── Thread management endpoints ──────────────────────────────────────
|
|
1055
2174
|
// Single handler for /threads and /threads/:id — h3's use() does prefix
|
|
1056
2175
|
// matching so we can't reliably split them into separate handlers.
|
|
1057
|
-
nitroApp.
|
|
2176
|
+
getH3App(nitroApp).use(`${routePath}/threads`, defineEventHandler(async (event) => {
|
|
1058
2177
|
const owner = await getOwnerFromEvent(event);
|
|
1059
2178
|
const method = getMethod(event);
|
|
1060
2179
|
// Determine if this is a specific-thread request.
|
|
@@ -1116,6 +2235,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1116
2235
|
if (method === "POST") {
|
|
1117
2236
|
const body = await readBody(event);
|
|
1118
2237
|
const thread = await createThread(owner, {
|
|
2238
|
+
id: body?.id,
|
|
1119
2239
|
title: body?.title ?? "",
|
|
1120
2240
|
});
|
|
1121
2241
|
return thread;
|
|
@@ -1127,7 +2247,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1127
2247
|
// This is mounted last because h3's use() is prefix-based, meaning /_agent-native/agent-chat
|
|
1128
2248
|
// also matches /_agent-native/agent-chat/threads/... — we skip sub-path requests here so the
|
|
1129
2249
|
// earlier-mounted handlers (mode, save-key, files, skills, mentions, threads) handle them.
|
|
1130
|
-
nitroApp.
|
|
2250
|
+
getH3App(nitroApp).use(routePath, defineEventHandler(async (event) => {
|
|
1131
2251
|
// Skip sub-path requests — they're handled by earlier-mounted handlers
|
|
1132
2252
|
const url = event.node?.req?.url || event.path || "";
|
|
1133
2253
|
const afterBase = url.slice(url.indexOf(routePath) + routePath.length);
|
|
@@ -1136,14 +2256,71 @@ export function createAgentChatPlugin(options) {
|
|
|
1136
2256
|
setResponseStatus(event, 404);
|
|
1137
2257
|
return { error: "Not found" };
|
|
1138
2258
|
}
|
|
1139
|
-
//
|
|
1140
|
-
// Without this, scripts default to "local@localhost" and miss resources
|
|
1141
|
-
// created by users who authenticated via OAuth (e.g., Gmail).
|
|
2259
|
+
// Resolve per-request auth context
|
|
1142
2260
|
const owner = await getOwnerFromEvent(event);
|
|
2261
|
+
// Resolve org ID: explicit callback > session.orgId from Better Auth
|
|
2262
|
+
let resolvedOrgId;
|
|
2263
|
+
if (options?.resolveOrgId) {
|
|
2264
|
+
resolvedOrgId = (await options.resolveOrgId(event)) ?? undefined;
|
|
2265
|
+
}
|
|
2266
|
+
else {
|
|
2267
|
+
try {
|
|
2268
|
+
const session = await getSession(event);
|
|
2269
|
+
resolvedOrgId = session?.orgId ?? undefined;
|
|
2270
|
+
}
|
|
2271
|
+
catch {
|
|
2272
|
+
// Session not available
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
// Also set process.env for backwards compat (CLI scripts, legacy readers)
|
|
1143
2276
|
process.env.AGENT_USER_EMAIL = owner;
|
|
1144
|
-
|
|
1145
|
-
|
|
2277
|
+
if (resolvedOrgId) {
|
|
2278
|
+
process.env.AGENT_ORG_ID = resolvedOrgId;
|
|
2279
|
+
}
|
|
2280
|
+
else {
|
|
2281
|
+
delete process.env.AGENT_ORG_ID;
|
|
2282
|
+
}
|
|
2283
|
+
return runWithRequestContext({ userEmail: owner, orgId: resolvedOrgId }, () => {
|
|
2284
|
+
const handler = currentDevMode && devHandler ? devHandler : prodHandler;
|
|
2285
|
+
return handler(event);
|
|
2286
|
+
});
|
|
1146
2287
|
}));
|
|
2288
|
+
// ─── Recurring Jobs Scheduler ──────────────────────────────────────
|
|
2289
|
+
// Poll every 60 seconds for due recurring jobs and execute them.
|
|
2290
|
+
// Uses setInterval so it works in all deployment environments without
|
|
2291
|
+
// requiring Nitro experimental tasks configuration.
|
|
2292
|
+
try {
|
|
2293
|
+
const { processRecurringJobs } = await import("../jobs/scheduler.js");
|
|
2294
|
+
const schedulerDeps = {
|
|
2295
|
+
getActions: () => ({
|
|
2296
|
+
...templateScripts,
|
|
2297
|
+
...resourceScripts,
|
|
2298
|
+
...docsScripts,
|
|
2299
|
+
...chatScripts,
|
|
2300
|
+
...jobTools,
|
|
2301
|
+
}),
|
|
2302
|
+
getSystemPrompt: async (owner) => {
|
|
2303
|
+
const resources = await loadResourcesForPrompt(owner);
|
|
2304
|
+
const schemaBlock = await buildSchemaBlock(owner, false);
|
|
2305
|
+
return basePrompt + resources + schemaBlock;
|
|
2306
|
+
},
|
|
2307
|
+
apiKey: options?.apiKey ?? process.env.ANTHROPIC_API_KEY,
|
|
2308
|
+
model: resolvedModel,
|
|
2309
|
+
};
|
|
2310
|
+
// Start after a 10-second delay to let the server fully initialize
|
|
2311
|
+
setTimeout(() => {
|
|
2312
|
+
setInterval(() => {
|
|
2313
|
+
processRecurringJobs(schedulerDeps).catch((err) => {
|
|
2314
|
+
console.error("[recurring-jobs] Scheduler error:", err?.message);
|
|
2315
|
+
});
|
|
2316
|
+
}, 60_000);
|
|
2317
|
+
if (process.env.DEBUG)
|
|
2318
|
+
console.log("[recurring-jobs] Scheduler started (60s interval)");
|
|
2319
|
+
}, 10_000);
|
|
2320
|
+
}
|
|
2321
|
+
catch (err) {
|
|
2322
|
+
// Jobs module not available — skip silently
|
|
2323
|
+
}
|
|
1147
2324
|
};
|
|
1148
2325
|
}
|
|
1149
2326
|
/**
|
|
@@ -1152,4 +2329,35 @@ export function createAgentChatPlugin(options) {
|
|
|
1152
2329
|
* In production, provides only the default system prompt.
|
|
1153
2330
|
*/
|
|
1154
2331
|
export const defaultAgentChatPlugin = createAgentChatPlugin();
|
|
2332
|
+
// ---------------------------------------------------------------------------
|
|
2333
|
+
// MCP client glue — a shared manager reference + a /_agent-native/mcp/status
|
|
2334
|
+
// route so onboarding / settings UIs can see which MCP servers are live.
|
|
2335
|
+
// ---------------------------------------------------------------------------
|
|
2336
|
+
let _globalMcpManager = null;
|
|
2337
|
+
function setGlobalMcpManager(manager) {
|
|
2338
|
+
_globalMcpManager = manager;
|
|
2339
|
+
}
|
|
2340
|
+
/** Internal: access the current process's MCP client manager, if any. */
|
|
2341
|
+
export function getGlobalMcpManager() {
|
|
2342
|
+
return _globalMcpManager;
|
|
2343
|
+
}
|
|
2344
|
+
function mountMcpStatusRoute(nitroApp, manager) {
|
|
2345
|
+
// Idempotent — agent-chat-plugin can be invoked once per process; guard anyway.
|
|
2346
|
+
if (globalThis.__agentNativeMcpStatusMounted)
|
|
2347
|
+
return;
|
|
2348
|
+
globalThis.__agentNativeMcpStatusMounted = true;
|
|
2349
|
+
try {
|
|
2350
|
+
getH3App(nitroApp).use("/_agent-native/mcp/status", defineEventHandler(async (event) => {
|
|
2351
|
+
if (getMethod(event) !== "GET") {
|
|
2352
|
+
setResponseStatus(event, 405);
|
|
2353
|
+
return { error: "Method not allowed" };
|
|
2354
|
+
}
|
|
2355
|
+
setResponseHeader(event, "Content-Type", "application/json");
|
|
2356
|
+
return manager.getStatus();
|
|
2357
|
+
}));
|
|
2358
|
+
}
|
|
2359
|
+
catch (err) {
|
|
2360
|
+
console.warn(`[mcp-client] Failed to mount /_agent-native/mcp/status: ${err?.message ?? err}`);
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
1155
2363
|
//# sourceMappingURL=agent-chat-plugin.js.map
|