@agent-native/core 0.7.14 → 0.7.15
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 +56 -6
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +149 -24
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +166 -51
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/task-store.d.ts +10 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +36 -2
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/agent/default-model.d.ts +21 -0
- package/dist/agent/default-model.d.ts.map +1 -0
- package/dist/agent/default-model.js +21 -0
- package/dist/agent/default-model.js.map +1 -0
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +7 -4
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts +1 -1
- package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
- package/dist/agent/engine/anthropic-engine.js +10 -4
- package/dist/agent/engine/anthropic-engine.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +4 -1
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/builtin.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +27 -7
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +101 -20
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/production-agent.d.ts +25 -3
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +227 -36
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/application-state/handlers.d.ts.map +1 -1
- package/dist/application-state/handlers.js +10 -6
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/application-state/script-helpers.d.ts +1 -1
- package/dist/application-state/script-helpers.d.ts.map +1 -1
- package/dist/application-state/script-helpers.js +12 -8
- package/dist/application-state/script-helpers.js.map +1 -1
- package/dist/application-state/store.d.ts.map +1 -1
- package/dist/application-state/store.js +19 -10
- package/dist/application-state/store.js.map +1 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +4 -1
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +79 -13
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +97 -39
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +4 -0
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +56 -12
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/workspacify.d.ts +2 -0
- package/dist/cli/workspacify.d.ts.map +1 -1
- package/dist/cli/workspacify.js +5 -4
- package/dist/cli/workspacify.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +5 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +61 -23
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AgentTaskCard.d.ts.map +1 -1
- package/dist/client/AgentTaskCard.js +3 -2
- package/dist/client/AgentTaskCard.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +79 -16
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +2 -1
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/DefaultSpinner.d.ts +1 -1
- package/dist/client/DefaultSpinner.d.ts.map +1 -1
- package/dist/client/DefaultSpinner.js +2 -9
- package/dist/client/DefaultSpinner.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +20 -19
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +2 -1
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +3 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +70 -1
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/api-path.d.ts +5 -0
- package/dist/client/api-path.d.ts.map +1 -0
- package/dist/client/api-path.js +48 -0
- package/dist/client/api-path.js.map +1 -0
- package/dist/client/components/ApiKeySettings.d.ts.map +1 -1
- package/dist/client/components/ApiKeySettings.js +3 -2
- package/dist/client/components/ApiKeySettings.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +3 -2
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +9 -8
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/draft-key.d.ts +2 -0
- package/dist/client/composer/draft-key.d.ts.map +1 -0
- package/dist/client/composer/draft-key.js +8 -0
- package/dist/client/composer/draft-key.js.map +1 -0
- package/dist/client/composer/use-file-search.d.ts.map +1 -1
- package/dist/client/composer/use-file-search.js +2 -1
- package/dist/client/composer/use-file-search.js.map +1 -1
- package/dist/client/composer/use-mention-search.d.ts.map +1 -1
- package/dist/client/composer/use-mention-search.js +2 -1
- package/dist/client/composer/use-mention-search.js.map +1 -1
- package/dist/client/composer/use-skills.d.ts.map +1 -1
- package/dist/client/composer/use-skills.js +2 -1
- package/dist/client/composer/use-skills.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +16 -8
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/dev-mode.d.ts +14 -0
- package/dist/client/dev-mode.d.ts.map +1 -0
- package/dist/client/dev-mode.js +14 -0
- package/dist/client/dev-mode.js.map +1 -0
- package/dist/client/dev-overlay/DevOverlay.d.ts +26 -0
- package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -0
- package/dist/client/dev-overlay/DevOverlay.js +315 -0
- package/dist/client/dev-overlay/DevOverlay.js.map +1 -0
- package/dist/client/dev-overlay/builtins.d.ts +6 -0
- package/dist/client/dev-overlay/builtins.d.ts.map +1 -0
- package/dist/client/dev-overlay/builtins.js +35 -0
- package/dist/client/dev-overlay/builtins.js.map +1 -0
- package/dist/client/dev-overlay/index.d.ts +6 -0
- package/dist/client/dev-overlay/index.d.ts.map +1 -0
- package/dist/client/dev-overlay/index.js +5 -0
- package/dist/client/dev-overlay/index.js.map +1 -0
- package/dist/client/dev-overlay/registry.d.ts +13 -0
- package/dist/client/dev-overlay/registry.d.ts.map +1 -0
- package/dist/client/dev-overlay/registry.js +63 -0
- package/dist/client/dev-overlay/registry.js.map +1 -0
- package/dist/client/dev-overlay/types.d.ts +56 -0
- package/dist/client/dev-overlay/types.d.ts.map +1 -0
- package/dist/client/dev-overlay/types.js +9 -0
- package/dist/client/dev-overlay/types.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts +12 -0
- package/dist/client/dev-overlay/use-dev-option.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-option.js +73 -0
- package/dist/client/dev-overlay/use-dev-option.js.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts +6 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts.map +1 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js +29 -0
- package/dist/client/dev-overlay/use-dev-overlay-shortcut.js.map +1 -0
- package/dist/client/frame.d.ts +1 -0
- package/dist/client/frame.d.ts.map +1 -1
- package/dist/client/frame.js +32 -11
- package/dist/client/frame.js.map +1 -1
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationCard.js +3 -2
- package/dist/client/integrations/IntegrationCard.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -1
- package/dist/client/integrations/useIntegrationStatus.js +2 -1
- package/dist/client/integrations/useIntegrationStatus.js.map +1 -1
- package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
- package/dist/client/notifications/NotificationsBell.js +26 -8
- package/dist/client/notifications/NotificationsBell.js.map +1 -1
- package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -1
- package/dist/client/observability/ThumbsFeedback.js +2 -1
- package/dist/client/observability/ThumbsFeedback.js.map +1 -1
- package/dist/client/observability/useObservability.d.ts.map +1 -1
- package/dist/client/observability/useObservability.js +2 -1
- package/dist/client/observability/useObservability.js.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.d.ts +0 -7
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/client/onboarding/OnboardingPanel.js +20 -10
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/client/onboarding/index.d.ts +1 -0
- package/dist/client/onboarding/index.d.ts.map +1 -1
- package/dist/client/onboarding/index.js +1 -0
- package/dist/client/onboarding/index.js.map +1 -1
- package/dist/client/onboarding/use-onboarding.d.ts +1 -7
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -1
- package/dist/client/onboarding/use-onboarding.js +27 -13
- package/dist/client/onboarding/use-onboarding.js.map +1 -1
- package/dist/client/onboarding/use-preview-mode.d.ts +10 -0
- package/dist/client/onboarding/use-preview-mode.d.ts.map +1 -0
- package/dist/client/onboarding/use-preview-mode.js +35 -0
- package/dist/client/onboarding/use-preview-mode.js.map +1 -0
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +2 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +7 -5
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/org/hooks.d.ts.map +1 -1
- package/dist/client/org/hooks.js +2 -1
- package/dist/client/org/hooks.js.map +1 -1
- package/dist/client/progress/RunsTray.d.ts.map +1 -1
- package/dist/client/progress/RunsTray.js +2 -1
- package/dist/client/progress/RunsTray.js.map +1 -1
- package/dist/client/resources/McpServerDetail.d.ts +0 -8
- package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
- package/dist/client/resources/McpServerDetail.js +6 -1
- package/dist/client/resources/McpServerDetail.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +2 -1
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +2 -1
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
- package/dist/client/resources/use-mcp-servers.js +7 -2
- package/dist/client/resources/use-mcp-servers.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js +9 -7
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +7 -5
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
- package/dist/client/settings/AutomationsSection.js +9 -5
- package/dist/client/settings/AutomationsSection.js.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
- package/dist/client/settings/BackgroundAgentSection.js +2 -1
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +12 -4
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +15 -23
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/UsageSection.d.ts.map +1 -1
- package/dist/client/settings/UsageSection.js +2 -1
- package/dist/client/settings/UsageSection.js.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.d.ts +2 -4
- package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js +66 -23
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +9 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +31 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -2
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/client/sharing/ShareDialog.js +4 -3
- package/dist/client/sharing/ShareDialog.js.map +1 -1
- package/dist/client/terminal/AgentTerminal.d.ts +1 -0
- package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
- package/dist/client/terminal/AgentTerminal.js +12 -8
- package/dist/client/terminal/AgentTerminal.js.map +1 -1
- package/dist/client/tools/EmbeddedTool.d.ts +20 -0
- package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
- package/dist/client/tools/EmbeddedTool.js +113 -0
- package/dist/client/tools/EmbeddedTool.js.map +1 -0
- package/dist/client/tools/ExtensionSlot.d.ts +27 -0
- package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
- package/dist/client/tools/ExtensionSlot.js +96 -0
- package/dist/client/tools/ExtensionSlot.js.map +1 -0
- package/dist/client/tools/ToolEditor.d.ts.map +1 -1
- package/dist/client/tools/ToolEditor.js +5 -4
- package/dist/client/tools/ToolEditor.js.map +1 -1
- package/dist/client/tools/ToolViewer.d.ts.map +1 -1
- package/dist/client/tools/ToolViewer.js +10 -44
- package/dist/client/tools/ToolViewer.js.map +1 -1
- package/dist/client/tools/ToolViewerPage.d.ts.map +1 -1
- package/dist/client/tools/ToolViewerPage.js +2 -1
- package/dist/client/tools/ToolViewerPage.js.map +1 -1
- package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
- package/dist/client/tools/ToolsListPage.js +3 -2
- package/dist/client/tools/ToolsListPage.js.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
- package/dist/client/tools/ToolsSidebarSection.js +4 -3
- package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
- package/dist/client/tools/iframe-bridge.d.ts +16 -0
- package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
- package/dist/client/tools/iframe-bridge.js +118 -0
- package/dist/client/tools/iframe-bridge.js.map +1 -0
- package/dist/client/tools/index.d.ts +2 -0
- package/dist/client/tools/index.d.ts.map +1 -1
- package/dist/client/tools/index.js +2 -0
- package/dist/client/tools/index.js.map +1 -1
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +2 -1
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-avatar.d.ts.map +1 -1
- package/dist/client/use-avatar.js +3 -2
- package/dist/client/use-avatar.js.map +1 -1
- package/dist/client/use-builder-enabled.d.ts.map +1 -1
- package/dist/client/use-builder-enabled.js +2 -1
- package/dist/client/use-builder-enabled.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +2 -1
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +3 -2
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-dev-mode.d.ts.map +1 -1
- package/dist/client/use-dev-mode.js +2 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
- package/dist/client/use-send-to-agent-chat.js +3 -1
- package/dist/client/use-send-to-agent-chat.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +2 -1
- package/dist/client/use-session.js.map +1 -1
- package/dist/client/useProductionAgent.d.ts.map +1 -1
- package/dist/client/useProductionAgent.js +2 -1
- package/dist/client/useProductionAgent.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +3 -2
- package/dist/collab/client.js.map +1 -1
- package/dist/credentials/index.d.ts +27 -10
- package/dist/credentials/index.d.ts.map +1 -1
- package/dist/credentials/index.js +61 -19
- package/dist/credentials/index.js.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +10 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations.d.ts +13 -5
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +9 -2
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.d.ts +12 -1
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +195 -23
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/registry.d.ts.map +1 -1
- package/dist/file-upload/registry.js +25 -1
- package/dist/file-upload/registry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts.map +1 -1
- package/dist/integrations/adapters/email.js +152 -32
- package/dist/integrations/adapters/email.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +190 -32
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +37 -2
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +91 -12
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts.map +1 -1
- package/dist/integrations/google-docs-poller.js +5 -2
- package/dist/integrations/google-docs-poller.js.map +1 -1
- package/dist/integrations/internal-token.d.ts.map +1 -1
- package/dist/integrations/internal-token.js +17 -1
- package/dist/integrations/internal-token.js.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-retry-job.js +18 -7
- package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
- package/dist/integrations/pending-tasks-store.d.ts +16 -0
- package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
- package/dist/integrations/pending-tasks-store.js +58 -5
- package/dist/integrations/pending-tasks-store.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +198 -15
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +33 -2
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +6 -0
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +141 -61
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +12 -4
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +141 -16
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +94 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +128 -62
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp-client/hub-routes.d.ts +14 -0
- package/dist/mcp-client/hub-routes.d.ts.map +1 -1
- package/dist/mcp-client/hub-routes.js +42 -2
- package/dist/mcp-client/hub-routes.js.map +1 -1
- package/dist/mcp-client/index.d.ts +1 -1
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +1 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +28 -3
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/remote-store.d.ts +49 -1
- package/dist/mcp-client/remote-store.d.ts.map +1 -1
- package/dist/mcp-client/remote-store.js +253 -6
- package/dist/mcp-client/remote-store.js.map +1 -1
- package/dist/mcp-client/routes.d.ts.map +1 -1
- package/dist/mcp-client/routes.js +11 -9
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/mcp-client/visibility.d.ts +7 -3
- package/dist/mcp-client/visibility.d.ts.map +1 -1
- package/dist/mcp-client/visibility.js +16 -7
- package/dist/mcp-client/visibility.js.map +1 -1
- package/dist/notifications/actions.d.ts.map +1 -1
- package/dist/notifications/actions.js +7 -1
- package/dist/notifications/actions.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts.map +1 -1
- package/dist/notifications/routes.js +20 -3
- package/dist/notifications/routes.js.map +1 -1
- package/dist/notifications/store.d.ts.map +1 -1
- package/dist/notifications/store.js +6 -1
- package/dist/notifications/store.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts +43 -2
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +83 -14
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/observability/experiments.js +5 -5
- package/dist/observability/experiments.js.map +1 -1
- package/dist/observability/routes.d.ts.map +1 -1
- package/dist/observability/routes.js +37 -8
- package/dist/observability/routes.js.map +1 -1
- package/dist/observability/store.d.ts.map +1 -1
- package/dist/observability/store.js +19 -3
- package/dist/observability/store.js.map +1 -1
- package/dist/observability/types.d.ts +7 -0
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts.map +1 -1
- package/dist/onboarding/default-steps.js +1 -2
- package/dist/onboarding/default-steps.js.map +1 -1
- package/dist/onboarding/plugin.d.ts.map +1 -1
- package/dist/onboarding/plugin.js +63 -32
- package/dist/onboarding/plugin.js.map +1 -1
- package/dist/onboarding/types.d.ts +6 -1
- package/dist/onboarding/types.d.ts.map +1 -1
- package/dist/org/accept-pending.d.ts.map +1 -1
- package/dist/org/accept-pending.js +2 -1
- package/dist/org/accept-pending.js.map +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +10 -1
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts.map +1 -1
- package/dist/progress/routes.js +20 -3
- package/dist/progress/routes.js.map +1 -1
- package/dist/progress/store.d.ts.map +1 -1
- package/dist/progress/store.js +6 -1
- package/dist/progress/store.js.map +1 -1
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +35 -7
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +15 -3
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +12 -4
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts +1 -0
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +78 -40
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/chat/search-chats.d.ts.map +1 -1
- package/dist/scripts/chat/search-chats.js +3 -2
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/db/exec.d.ts +1 -1
- package/dist/scripts/db/exec.d.ts.map +1 -1
- package/dist/scripts/db/exec.js +22 -3
- package/dist/scripts/db/exec.js.map +1 -1
- package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -1
- package/dist/scripts/db/migrate-user-api-keys.js +10 -0
- package/dist/scripts/db/migrate-user-api-keys.js.map +1 -1
- package/dist/scripts/db/query.d.ts +1 -1
- package/dist/scripts/db/query.d.ts.map +1 -1
- package/dist/scripts/db/query.js +22 -3
- package/dist/scripts/db/query.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +15 -9
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/dev/shell.d.ts.map +1 -1
- package/dist/scripts/dev/shell.js +3 -1
- package/dist/scripts/dev/shell.js.map +1 -1
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
- package/dist/scripts/resources/delete-memory.js +2 -1
- package/dist/scripts/resources/delete-memory.js.map +1 -1
- 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/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.map +1 -1
- package/dist/scripts/resources/save-memory.js +2 -1
- package/dist/scripts/resources/save-memory.js.map +1 -1
- 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/secrets/onboarding.d.ts.map +1 -1
- package/dist/secrets/onboarding.js +24 -16
- package/dist/secrets/onboarding.js.map +1 -1
- package/dist/secrets/routes.d.ts.map +1 -1
- package/dist/secrets/routes.js +139 -37
- package/dist/secrets/routes.js.map +1 -1
- package/dist/secrets/storage.d.ts.map +1 -1
- package/dist/secrets/storage.js +23 -12
- package/dist/secrets/storage.js.map +1 -1
- package/dist/secrets/substitution.d.ts +24 -2
- package/dist/secrets/substitution.d.ts.map +1 -1
- package/dist/secrets/substitution.js +44 -6
- package/dist/secrets/substitution.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +15 -51
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +42 -15
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +447 -335
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +8 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +39 -12
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-teams.d.ts.map +1 -1
- package/dist/server/agent-teams.js +4 -1
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/analytics.d.ts +0 -1
- package/dist/server/analytics.d.ts.map +1 -1
- package/dist/server/analytics.js +0 -1
- package/dist/server/analytics.js.map +1 -1
- package/dist/server/app-base-path.d.ts +4 -0
- package/dist/server/app-base-path.d.ts.map +1 -0
- package/dist/server/app-base-path.js +33 -0
- package/dist/server/app-base-path.js.map +1 -0
- package/dist/server/auth.d.ts +15 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +400 -68
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +67 -15
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +15 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +90 -4
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/cli-capture.d.ts +31 -0
- package/dist/server/cli-capture.d.ts.map +1 -0
- package/dist/server/cli-capture.js +120 -0
- package/dist/server/cli-capture.js.map +1 -0
- package/dist/server/collab-plugin.d.ts +12 -0
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +63 -21
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +435 -106
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/create-server.d.ts +2 -0
- package/dist/server/create-server.d.ts.map +1 -1
- package/dist/server/create-server.js +82 -11
- package/dist/server/create-server.js.map +1 -1
- package/dist/server/credential-provider.d.ts +11 -0
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +51 -2
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/csrf.d.ts +58 -0
- package/dist/server/csrf.d.ts.map +1 -0
- package/dist/server/csrf.js +165 -0
- package/dist/server/csrf.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts +20 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +115 -34
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.d.ts.map +1 -1
- package/dist/server/google-auth-plugin.js +10 -2
- package/dist/server/google-auth-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts +84 -2
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +248 -45
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +8 -3
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +12 -8
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +37 -9
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts +33 -0
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +43 -2
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +102 -3
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +100 -7
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/security-headers.d.ts +51 -0
- package/dist/server/security-headers.d.ts.map +1 -0
- package/dist/server/security-headers.js +90 -0
- package/dist/server/security-headers.js.map +1 -0
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +96 -2
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +307 -56
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/server/voice-providers-status.d.ts +12 -0
- package/dist/server/voice-providers-status.d.ts.map +1 -0
- package/dist/server/voice-providers-status.js +71 -0
- package/dist/server/voice-providers-status.js.map +1 -0
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +16 -13
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts +1 -0
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +45 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/dist/templates/default/app/root.tsx +1 -1
- package/dist/templates/default/app/routes/_index.tsx +6 -1
- package/dist/templates/default/public/favicon.svg +13 -0
- package/dist/templates/default/public/icon-180.svg +12 -3
- package/dist/templates/default/public/icon-192.svg +12 -3
- package/dist/templates/default/public/icon-512.svg +12 -3
- package/dist/templates/workspace-core/package.json +22 -4
- package/dist/templates/workspace-core/src/credentials.ts +32 -5
- package/dist/templates/workspace-core/tsconfig.json +4 -1
- package/dist/terminal/pty-server.d.ts.map +1 -1
- package/dist/terminal/pty-server.js +7 -1
- package/dist/terminal/pty-server.js.map +1 -1
- package/dist/terminal/terminal-plugin.js +3 -3
- package/dist/terminal/terminal-plugin.js.map +1 -1
- package/dist/tools/actions.d.ts.map +1 -1
- package/dist/tools/actions.js +130 -0
- package/dist/tools/actions.js.map +1 -1
- package/dist/tools/fetch-tool.d.ts +1 -0
- package/dist/tools/fetch-tool.d.ts.map +1 -1
- package/dist/tools/fetch-tool.js +38 -16
- package/dist/tools/fetch-tool.js.map +1 -1
- package/dist/tools/html-shell.d.ts +43 -1
- package/dist/tools/html-shell.d.ts.map +1 -1
- package/dist/tools/html-shell.js +102 -4
- package/dist/tools/html-shell.js.map +1 -1
- package/dist/tools/proxy-security.d.ts +12 -0
- package/dist/tools/proxy-security.d.ts.map +1 -0
- package/dist/tools/proxy-security.js +158 -0
- package/dist/tools/proxy-security.js.map +1 -0
- package/dist/tools/routes.d.ts.map +1 -1
- package/dist/tools/routes.js +158 -105
- package/dist/tools/routes.js.map +1 -1
- package/dist/tools/schema.d.ts +3 -0
- package/dist/tools/schema.d.ts.map +1 -1
- package/dist/tools/schema.js +3 -0
- package/dist/tools/schema.js.map +1 -1
- package/dist/tools/slots/routes.d.ts +15 -0
- package/dist/tools/slots/routes.d.ts.map +1 -0
- package/dist/tools/slots/routes.js +94 -0
- package/dist/tools/slots/routes.js.map +1 -0
- package/dist/tools/slots/schema.d.ts +303 -0
- package/dist/tools/slots/schema.d.ts.map +1 -0
- package/dist/tools/slots/schema.js +76 -0
- package/dist/tools/slots/schema.js.map +1 -0
- package/dist/tools/slots/store.d.ts +66 -0
- package/dist/tools/slots/store.d.ts.map +1 -0
- package/dist/tools/slots/store.js +227 -0
- package/dist/tools/slots/store.js.map +1 -0
- package/dist/tools/store.d.ts.map +1 -1
- package/dist/tools/store.js +28 -37
- package/dist/tools/store.js.map +1 -1
- package/dist/tools/url-safety.d.ts +24 -0
- package/dist/tools/url-safety.d.ts.map +1 -0
- package/dist/tools/url-safety.js +224 -0
- package/dist/tools/url-safety.js.map +1 -0
- package/dist/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +28 -11
- package/dist/tracking/providers.js.map +1 -1
- package/dist/tracking/registry.d.ts.map +1 -1
- package/dist/tracking/registry.js +7 -3
- package/dist/tracking/registry.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +11 -6
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/condition-evaluator.d.ts +8 -0
- package/dist/triggers/condition-evaluator.d.ts.map +1 -1
- package/dist/triggers/condition-evaluator.js +39 -4
- package/dist/triggers/condition-evaluator.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +67 -4
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +8 -5
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +2 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +216 -4
- package/dist/vite/client.js.map +1 -1
- package/docs/content/authentication.md +27 -12
- package/docs/content/drop-in-agent.md +2 -2
- package/docs/content/messaging.md +195 -155
- package/docs/content/onboarding.md +82 -12
- package/docs/content/template-analytics.md +65 -59
- package/docs/content/template-clips.md +7 -9
- package/docs/content/template-design.md +55 -0
- package/docs/content/template-dispatch.md +13 -0
- package/docs/content/template-forms.md +7 -6
- package/docs/content/template-mail.md +78 -80
- package/package.json +2 -1
- package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
- package/src/templates/default/app/root.tsx +1 -1
- package/src/templates/default/app/routes/_index.tsx +6 -1
- package/src/templates/default/public/favicon.svg +13 -0
- package/src/templates/default/public/icon-180.svg +12 -3
- package/src/templates/default/public/icon-192.svg +12 -3
- package/src/templates/default/public/icon-512.svg +12 -3
- package/src/templates/workspace-core/package.json +22 -4
- package/src/templates/workspace-core/src/credentials.ts +32 -5
- package/src/templates/workspace-core/tsconfig.json +4 -1
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { runWithRequestContext, getRequestOrgId } from "./request-context.js";
|
|
1
|
+
import { runWithRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
|
|
2
2
|
import { getSetting, putSetting } from "../settings/store.js";
|
|
3
3
|
import { getH3App, trackPluginInit } from "./framework-request-handler.js";
|
|
4
4
|
import { createProductionAgentHandler, runAgentLoop, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, } from "../agent/production-agent.js";
|
|
5
5
|
import { resolveEngine, createAnthropicEngine } from "../agent/engine/index.js";
|
|
6
|
+
import { DEFAULT_MODEL } from "../agent/default-model.js";
|
|
6
7
|
import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, syncMcpActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, buildMergedConfig, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
|
|
7
8
|
import { discoverAgents } from "./agent-discovery.js";
|
|
8
9
|
import { loadSchemaPromptBlock } from "./schema-prompt.js";
|
|
9
10
|
import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-builder.js";
|
|
10
11
|
import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
|
|
11
|
-
import { getSession } from "./auth.js";
|
|
12
|
+
import { getSession, DEV_MODE_USER_EMAIL } from "./auth.js";
|
|
12
13
|
import { getOrigin } from "./google-oauth.js";
|
|
13
14
|
import { createThread, forkThread, getThread, listThreads, searchThreads, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
|
|
14
15
|
import { resourceListAccessible, resourceList, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, } from "../resources/store.js";
|
|
15
16
|
import nodePath from "node:path";
|
|
16
17
|
import { readBody } from "./h3-helpers.js";
|
|
17
18
|
import { getBuilderBrowserConnectUrl } from "./builder-browser.js";
|
|
19
|
+
import { captureCliOutput } from "./cli-capture.js";
|
|
18
20
|
// Lazy fs — loaded via dynamic import() on first use.
|
|
19
21
|
// This avoids require() which bundlers convert to createRequire(import.meta.url)
|
|
20
22
|
// that crashes on CF Workers where import.meta.url is undefined.
|
|
@@ -27,7 +29,9 @@ async function lazyFs() {
|
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* Wraps a core CLI script (that writes to console.log) as a ActionEntry
|
|
30
|
-
* by capturing stdout.
|
|
32
|
+
* by capturing stdout. Uses an AsyncLocalStorage-backed capture so
|
|
33
|
+
* concurrent tool calls do not corrupt the global console/stdout pointers
|
|
34
|
+
* (see `cli-capture.ts`).
|
|
31
35
|
*/
|
|
32
36
|
function wrapCliScript(tool, cliDefault, opts) {
|
|
33
37
|
return {
|
|
@@ -38,39 +42,7 @@ function wrapCliScript(tool, cliDefault, opts) {
|
|
|
38
42
|
for (const [k, v] of Object.entries(args)) {
|
|
39
43
|
cliArgs.push(`--${k}`, v);
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
const origLog = console.log;
|
|
43
|
-
const origError = console.error;
|
|
44
|
-
const origStdoutWrite = process.stdout.write;
|
|
45
|
-
console.log = (...a) => {
|
|
46
|
-
logs.push(a.map(String).join(" "));
|
|
47
|
-
};
|
|
48
|
-
console.error = (...a) => {
|
|
49
|
-
logs.push(a.map(String).join(" "));
|
|
50
|
-
};
|
|
51
|
-
// Intercept process.stdout.write so scripts that write directly
|
|
52
|
-
// (e.g. resource-read) have their output captured
|
|
53
|
-
process.stdout.write = ((chunk, ...rest) => {
|
|
54
|
-
if (typeof chunk === "string") {
|
|
55
|
-
logs.push(chunk);
|
|
56
|
-
}
|
|
57
|
-
else if (Buffer.isBuffer(chunk)) {
|
|
58
|
-
logs.push(chunk.toString());
|
|
59
|
-
}
|
|
60
|
-
return true;
|
|
61
|
-
});
|
|
62
|
-
try {
|
|
63
|
-
await cliDefault(cliArgs);
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
logs.push(`Error: ${err?.message ?? String(err)}`);
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
console.log = origLog;
|
|
70
|
-
console.error = origError;
|
|
71
|
-
process.stdout.write = origStdoutWrite;
|
|
72
|
-
}
|
|
73
|
-
return logs.join("\n") || "(no output)";
|
|
45
|
+
return captureCliOutput(() => cliDefault(cliArgs));
|
|
74
46
|
},
|
|
75
47
|
};
|
|
76
48
|
}
|
|
@@ -156,6 +128,12 @@ function createRefreshScreenEntry() {
|
|
|
156
128
|
}
|
|
157
129
|
/** Well-known application-state key used by the refresh-screen tool. */
|
|
158
130
|
const SCREEN_REFRESH_KEY = "__screen_refresh__";
|
|
131
|
+
/**
|
|
132
|
+
* In-memory rate-limit tracker for `/generate-title`. Keyed by user email,
|
|
133
|
+
* value is recent invocation timestamps within the rolling window. Stale
|
|
134
|
+
* entries are pruned on read.
|
|
135
|
+
*/
|
|
136
|
+
const generateTitleRateLimit = new Map();
|
|
159
137
|
/**
|
|
160
138
|
* Creates the `set-search-params` / `set-url-path` tools. Writes a one-shot
|
|
161
139
|
* URL command to application_state; the client's URLSync component applies
|
|
@@ -953,6 +931,8 @@ const FRAMEWORK_CORE_COMPACT = `
|
|
|
953
931
|
6. **Memory** — Use \`save-memory\` proactively when you learn preferences, corrections, or project context.
|
|
954
932
|
7. **Security** — Always use parameterized queries. Never \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`.
|
|
955
933
|
8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
|
|
934
|
+
9. **Never fabricate data** — Do NOT invent numbers, metrics, records, or query results. Do NOT present estimated or example data as if it were real. If a data source is unavailable (missing credentials, connection error, tool failure), say so clearly, note the gap, and work with whatever data you do have. If no data can be retrieved at all, say "I can't retrieve this data right now" and explain why. Presenting made-up data as real is a critical failure — it is worse than admitting the limitation.
|
|
935
|
+
10. **Never fabricate success from tool errors** — When any tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED. Do NOT synthesize a success narrative or describe what the action "would have" produced. Report the failure verbatim from the tool output. This applies especially to \`shell(command="pnpm action ...")\` calls: if the action threw, it did NOT succeed.
|
|
956
936
|
|
|
957
937
|
### Resources
|
|
958
938
|
|
|
@@ -1117,6 +1097,8 @@ const FRAMEWORK_CORE = `
|
|
|
1117
1097
|
6. **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.
|
|
1118
1098
|
7. **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\`.
|
|
1119
1099
|
8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
|
|
1100
|
+
9. **Never fabricate data** — Do NOT invent numbers, metrics, records, or query results. Do NOT present estimated or example data as if it were real. If a data source is unavailable (missing credentials, connection error, tool failure), say so clearly, note the gap, and work with whatever data you do have. If no data can be retrieved at all, say "I can't retrieve this data right now" and explain why. Presenting made-up data as real is a critical failure — it is worse than admitting the limitation.
|
|
1101
|
+
10. **Never fabricate success from tool errors** — When any tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED. Do NOT synthesize a success narrative, format a result table, or describe what the action "would have" produced. Report the failure verbatim from the tool output. This applies especially to \`shell(command="pnpm action ...")\` calls: if the underlying action threw (visible in the error text), the action did NOT succeed — report the error, do not describe a successful outcome.
|
|
1120
1102
|
|
|
1121
1103
|
### Resources
|
|
1122
1104
|
|
|
@@ -1274,8 +1256,16 @@ The agent and the UI are equal partners — everything the UI can do, you can do
|
|
|
1274
1256
|
|
|
1275
1257
|
**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.
|
|
1276
1258
|
|
|
1259
|
+
### Tools (Mini-Apps) — Use \`create-tool\` for tools / widgets / dashboards
|
|
1260
|
+
|
|
1261
|
+
If the user asks you to create, build, or make a **tool**, **widget**, **dashboard**, **calculator**, **mini-app**, or any small self-contained interactive utility — call \`create-tool\` immediately with a self-contained Alpine.js HTML body. This is **NOT** a code change and does **NOT** go through \`connect-builder\`. Tools are sandboxed mini-apps stored in the database — no source files are touched, no PR is opened, no build is required. The tool appears in the Tools view and can be edited later via \`update-tool\`.
|
|
1262
|
+
|
|
1263
|
+
When in doubt — if the request mentions "tool", "widget", "dashboard", "calculator", or asks for a small interactive utility — choose \`create-tool\`. Do **not** preface the call with planning text like "let me build the dashboard…" — just call \`create-tool\` directly. One tool call, one response.
|
|
1264
|
+
|
|
1277
1265
|
### Code Changes Not Available — Call \`connect-builder\` Immediately
|
|
1278
1266
|
|
|
1267
|
+
If the request matches the Tools section above (tool / widget / dashboard / calculator / mini-app), use \`create-tool\` instead — do NOT route it to \`connect-builder\`.
|
|
1268
|
+
|
|
1279
1269
|
When the user asks you to change the UI, modify code, add a feature, fix a bug in the app itself, change styles, add a hook, create a component, add a route, add an integration, or anything else that requires editing source files — you MUST take exactly these steps, in order:
|
|
1280
1270
|
|
|
1281
1271
|
1. Call the \`connect-builder\` tool, passing the user's full request verbatim as the \`prompt\` argument. This renders an inline card. If Builder is connected, the card hands the prompt off to Builder's cloud agent on one click and returns a branch URL; otherwise it shows a connect / waitlist flow. Either way, Builder writes the code — no local setup, no clone, no install.
|
|
@@ -1323,9 +1313,13 @@ The agent and the UI are equal partners — everything the UI can do, you can do
|
|
|
1323
1313
|
|
|
1324
1314
|
**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.
|
|
1325
1315
|
|
|
1316
|
+
### Tools (Mini-Apps) — Use \`create-tool\`
|
|
1317
|
+
|
|
1318
|
+
If the user asks for a **tool**, **widget**, **dashboard**, **calculator**, or **mini-app**, call \`create-tool\` immediately with a self-contained Alpine.js HTML body. This is NOT a code change — tools are sandboxed mini-apps stored in the database. Do not preface with "let me build…" — just call \`create-tool\`.
|
|
1319
|
+
|
|
1326
1320
|
### Code Changes — Call \`connect-builder\`
|
|
1327
1321
|
|
|
1328
|
-
When the user asks to change the UI, modify code, add a feature, or fix a bug in the app itself — call \`connect-builder\` immediately, passing the user's request as the \`prompt\`. Do NOT write code, list files, make plans, or spawn sub-agents for code changes. Builder handles it in the cloud. Mention \`npx agent-native create <app-name>\` as an offline fallback.
|
|
1322
|
+
When the user asks to change the UI, modify code, add a feature, or fix a bug in the app itself — call \`connect-builder\` immediately, passing the user's request as the \`prompt\`. (Tool / widget / dashboard requests use \`create-tool\` instead — see above.) Do NOT write code, list files, make plans, or spawn sub-agents for code changes. Builder handles it in the cloud. Mention \`npx agent-native create <app-name>\` as an offline fallback.
|
|
1329
1323
|
${FRAMEWORK_CORE_COMPACT}`;
|
|
1330
1324
|
const DEV_FRAMEWORK_PROMPT_COMPACT = `## Agent-Native Framework — Development Mode
|
|
1331
1325
|
|
|
@@ -1760,9 +1754,8 @@ export function createAgentChatPlugin(options) {
|
|
|
1760
1754
|
...engineScripts,
|
|
1761
1755
|
};
|
|
1762
1756
|
const callAgentScript = await createCallAgentScriptEntry(options?.appId);
|
|
1763
|
-
let _currentRequestOrigin = "http://localhost:3000";
|
|
1764
1757
|
const browserTools = createBuilderBrowserTool({
|
|
1765
|
-
getOrigin: () =>
|
|
1758
|
+
getOrigin: () => getRequestRunContext()?.requestOrigin ?? "http://localhost:3000",
|
|
1766
1759
|
});
|
|
1767
1760
|
// Auto-mount A2A protocol endpoints so every app is discoverable
|
|
1768
1761
|
// and callable by other agents via the standard protocol.
|
|
@@ -1893,27 +1886,57 @@ export function createAgentChatPlugin(options) {
|
|
|
1893
1886
|
}
|
|
1894
1887
|
catch { }
|
|
1895
1888
|
}
|
|
1896
|
-
//
|
|
1897
|
-
//
|
|
1898
|
-
//
|
|
1899
|
-
|
|
1900
|
-
//
|
|
1889
|
+
// Per-request owner is read from the AsyncLocalStorage run context
|
|
1890
|
+
// (populated by prepareRun). Module-scope `let` would race across
|
|
1891
|
+
// concurrent requests on a long-lived Node process — overlapping
|
|
1892
|
+
// tool calls would observe whichever request wrote last. ALS gives
|
|
1893
|
+
// each async call-chain its own view of the owner.
|
|
1894
|
+
//
|
|
1895
|
+
// Falls back to `getRequestUserEmail()` so callers that wrap work
|
|
1896
|
+
// in `runWithRequestContext({ userEmail }, …)` without going through
|
|
1897
|
+
// `prepareRun` (recurring jobs, trigger dispatcher) still see the
|
|
1898
|
+
// correct owner.
|
|
1899
|
+
//
|
|
1900
|
+
// SECURITY: returns `null` when neither the run context nor the
|
|
1901
|
+
// request user-email is populated. Consumers MUST short-circuit
|
|
1902
|
+
// with an explicit error rather than fall back to a sentinel
|
|
1903
|
+
// identity (e.g. DEV_MODE_USER_EMAIL). The previous fallback to
|
|
1904
|
+
// `local@localhost` slipped past `guard-no-localhost-fallback`
|
|
1905
|
+
// because the literal was hidden behind a symbolic alias —
|
|
1906
|
+
// any agent loop that reached this code without a populated
|
|
1907
|
+
// session would resolve `${keys.NAME}` against the dev-shim's
|
|
1908
|
+
// `app_secrets WHERE scope_id='local@localhost'` rows. See
|
|
1909
|
+
// audit 02 (HIGH: getCurrentRunOwner) and the
|
|
1910
|
+
// 2026-04-29 credentials-leak incident for the prior shape.
|
|
1911
|
+
const getCurrentRunOwner = () => getRequestRunContext()?.owner ?? getRequestUserEmail() ?? null;
|
|
1912
|
+
const requireCurrentRunOwner = (operation) => {
|
|
1913
|
+
const owner = getCurrentRunOwner();
|
|
1914
|
+
if (!owner) {
|
|
1915
|
+
throw new Error(`[agent-chat] No authenticated owner in run context — ` +
|
|
1916
|
+
`refusing to ${operation}. Ensure the request goes through ` +
|
|
1917
|
+
`prepareRun() or is wrapped in runWithRequestContext({ userEmail, ... }).`);
|
|
1918
|
+
}
|
|
1919
|
+
return owner;
|
|
1920
|
+
};
|
|
1921
|
+
// Automation tools + fetch tool — depend on owner via callback.
|
|
1922
|
+
// Each callback short-circuits with a clear error when the run context
|
|
1923
|
+
// has no authenticated owner (see SECURITY note on getCurrentRunOwner).
|
|
1901
1924
|
let automationTools = {};
|
|
1902
1925
|
try {
|
|
1903
1926
|
const { createAutomationToolEntries } = await import("../triggers/actions.js");
|
|
1904
|
-
automationTools = createAutomationToolEntries(() =>
|
|
1927
|
+
automationTools = createAutomationToolEntries(() => requireCurrentRunOwner("manage automations"));
|
|
1905
1928
|
}
|
|
1906
1929
|
catch { }
|
|
1907
1930
|
let notificationTools = {};
|
|
1908
1931
|
try {
|
|
1909
1932
|
const { createNotificationToolEntries } = await import("../notifications/actions.js");
|
|
1910
|
-
notificationTools = createNotificationToolEntries(() =>
|
|
1933
|
+
notificationTools = createNotificationToolEntries(() => requireCurrentRunOwner("manage notifications"));
|
|
1911
1934
|
}
|
|
1912
1935
|
catch { }
|
|
1913
1936
|
let progressTools = {};
|
|
1914
1937
|
try {
|
|
1915
1938
|
const { createProgressToolEntries } = await import("../progress/actions.js");
|
|
1916
|
-
progressTools = createProgressToolEntries(() =>
|
|
1939
|
+
progressTools = createProgressToolEntries(() => requireCurrentRunOwner("manage progress"));
|
|
1917
1940
|
}
|
|
1918
1941
|
catch { }
|
|
1919
1942
|
let fetchTool = {};
|
|
@@ -1921,10 +1944,10 @@ export function createAgentChatPlugin(options) {
|
|
|
1921
1944
|
const { createFetchToolEntry } = await import("../tools/fetch-tool.js");
|
|
1922
1945
|
const { resolveKeyReferences, validateUrlAllowlist, getKeyAllowlist } = await import("../secrets/substitution.js");
|
|
1923
1946
|
fetchTool = createFetchToolEntry({
|
|
1924
|
-
resolveKeys: async (text) => resolveKeyReferences(text, "user",
|
|
1947
|
+
resolveKeys: async (text) => resolveKeyReferences(text, "user", requireCurrentRunOwner("resolve key references")),
|
|
1925
1948
|
validateUrl: async (url, usedKeys) => {
|
|
1926
1949
|
for (const keyName of usedKeys) {
|
|
1927
|
-
const allowlist = await getKeyAllowlist(keyName, "user",
|
|
1950
|
+
const allowlist = await getKeyAllowlist(keyName, "user", requireCurrentRunOwner("validate URL allowlist"));
|
|
1928
1951
|
if (allowlist && !validateUrlAllowlist(url, allowlist)) {
|
|
1929
1952
|
return false;
|
|
1930
1953
|
}
|
|
@@ -1994,11 +2017,80 @@ export function createAgentChatPlugin(options) {
|
|
|
1994
2017
|
streaming: true,
|
|
1995
2018
|
handler: async function* (message, context) {
|
|
1996
2019
|
// Resolve the caller's identity for user-scoped data access.
|
|
2020
|
+
// Priority: A2A-JWT verified email (set by the A2A handler in
|
|
2021
|
+
// request-context) > dev session DB (dev only) > Google OAuth
|
|
2022
|
+
// tokeninfo (prod only). Without the JWT-verified-email path,
|
|
2023
|
+
// cross-app A2A calls landed owned by `local@localhost` (dev) or
|
|
2024
|
+
// `dispatch@shared`, which made resources invisible to the actual
|
|
2025
|
+
// signed-in user.
|
|
2026
|
+
//
|
|
2027
|
+
// SECURITY: we deliberately do NOT trust `context.metadata.userEmail`
|
|
2028
|
+
// as a fallback. The A2A endpoint runs in three modes — JWT-signed
|
|
2029
|
+
// (verified email lands in request context), API-key (caller is
|
|
2030
|
+
// app-authenticated but NOT user-authenticated), and unsigned
|
|
2031
|
+
// (no auth at all). Trusting caller-supplied metadata on the latter
|
|
2032
|
+
// two paths would let any reachable caller forge `metadata.userEmail`
|
|
2033
|
+
// and impersonate an arbitrary user. The JWT path already populates
|
|
2034
|
+
// the request context, so the metadata fallback was only ever used
|
|
2035
|
+
// on the unauthenticated paths — exactly where it's unsafe.
|
|
1997
2036
|
const isDev = process.env.NODE_ENV !== "production";
|
|
1998
2037
|
let userEmail;
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2038
|
+
// 1. JWT-verified email from A2A receiver (auth boundary already
|
|
2039
|
+
// enforced upstream). Works in dev AND prod.
|
|
2040
|
+
try {
|
|
2041
|
+
const { getRequestUserEmail } = await import("./request-context.js");
|
|
2042
|
+
userEmail = getRequestUserEmail();
|
|
2043
|
+
}
|
|
2044
|
+
catch { }
|
|
2045
|
+
// Dev-mode-only: when no JWT-verified email is present, fall back
|
|
2046
|
+
// to the most recently logged-in session. This is convenient for a
|
|
2047
|
+
// single-developer dev box but is a silent-impersonation hole if
|
|
2048
|
+
// it ever fires in production or on an exposed dev environment
|
|
2049
|
+
// (preview deploys, ngrok tunnels, etc.).
|
|
2050
|
+
//
|
|
2051
|
+
// SECURITY: gate this fallback narrowly:
|
|
2052
|
+
// - NODE_ENV strictly === "development" (not "test", not unset).
|
|
2053
|
+
// - AUTH_MODE === "local" (the dev-only auth shim).
|
|
2054
|
+
// - Request host is localhost / 127.0.0.1 (best-effort: when the
|
|
2055
|
+
// A2A handler doesn't have direct H3 event access, we rely on
|
|
2056
|
+
// env-based shape checks).
|
|
2057
|
+
//
|
|
2058
|
+
// In production this MUST never fire — the runtime assertion
|
|
2059
|
+
// below crashes loud if NODE_ENV === "production" somehow reaches
|
|
2060
|
+
// this block.
|
|
2061
|
+
if (!userEmail && isDev) {
|
|
2062
|
+
if (process.env.NODE_ENV === "production") {
|
|
2063
|
+
throw new Error("[agent-chat] Dev-mode 'latest session' fallback reached in production — refusing.");
|
|
2064
|
+
}
|
|
2065
|
+
const strictlyDev = process.env.NODE_ENV === "development";
|
|
2066
|
+
const localAuthMode = process.env.AUTH_MODE === "local";
|
|
2067
|
+
// Request host check: rely on the request-context request origin
|
|
2068
|
+
// which prepareRun() / mountActionRoutes populate. The A2A
|
|
2069
|
+
// handler doesn't have direct H3 event access, but on a
|
|
2070
|
+
// misconfigured non-localhost dev box we still want to refuse.
|
|
2071
|
+
let isLocalHost = false;
|
|
2072
|
+
try {
|
|
2073
|
+
const origin = getRequestRunContext()?.requestOrigin;
|
|
2074
|
+
if (origin) {
|
|
2075
|
+
const url = new URL(origin);
|
|
2076
|
+
isLocalHost =
|
|
2077
|
+
url.hostname === "localhost" ||
|
|
2078
|
+
url.hostname === "127.0.0.1" ||
|
|
2079
|
+
url.hostname === "::1";
|
|
2080
|
+
}
|
|
2081
|
+
else {
|
|
2082
|
+
// No origin in context — the A2A handler runs without an
|
|
2083
|
+
// explicit request origin. Treat absence as permissive only
|
|
2084
|
+
// when we're confident the process is dev-only (NODE_ENV
|
|
2085
|
+
// strictly "development" + AUTH_MODE=local). Otherwise
|
|
2086
|
+
// refuse.
|
|
2087
|
+
isLocalHost = strictlyDev && localAuthMode;
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
catch {
|
|
2091
|
+
isLocalHost = false;
|
|
2092
|
+
}
|
|
2093
|
+
if (strictlyDev && localAuthMode && isLocalHost) {
|
|
2002
2094
|
try {
|
|
2003
2095
|
const { getDbExec } = await import("../db/client.js");
|
|
2004
2096
|
const db = getDbExec();
|
|
@@ -2012,7 +2104,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2012
2104
|
catch { }
|
|
2013
2105
|
}
|
|
2014
2106
|
}
|
|
2015
|
-
|
|
2107
|
+
if (!userEmail && !isDev) {
|
|
2016
2108
|
const googleToken = context.metadata?.googleToken;
|
|
2017
2109
|
if (googleToken) {
|
|
2018
2110
|
try {
|
|
@@ -2027,9 +2119,6 @@ export function createAgentChatPlugin(options) {
|
|
|
2027
2119
|
catch { }
|
|
2028
2120
|
}
|
|
2029
2121
|
}
|
|
2030
|
-
if (userEmail) {
|
|
2031
|
-
process.env.AGENT_USER_EMAIL = userEmail;
|
|
2032
|
-
}
|
|
2033
2122
|
const text = message.parts
|
|
2034
2123
|
.filter((p) => p.type === "text")
|
|
2035
2124
|
.map((p) => p.text)
|
|
@@ -2053,7 +2142,9 @@ export function createAgentChatPlugin(options) {
|
|
|
2053
2142
|
const devActive = isDevMode();
|
|
2054
2143
|
const handler = devActive && devHandler ? devHandler : prodHandler;
|
|
2055
2144
|
// Build the same system prompt the interactive agent uses
|
|
2056
|
-
|
|
2145
|
+
if (!userEmail)
|
|
2146
|
+
throw new Error("no authenticated user");
|
|
2147
|
+
const owner = userEmail;
|
|
2057
2148
|
const resources = await loadResourcesForPrompt(owner, lazyContext);
|
|
2058
2149
|
const schemaBlock = lazyContext
|
|
2059
2150
|
? ""
|
|
@@ -2061,7 +2152,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2061
2152
|
const systemPrompt = devActive
|
|
2062
2153
|
? devPrompt + resources + schemaBlock
|
|
2063
2154
|
: basePrompt + resources + schemaBlock;
|
|
2064
|
-
const model = options?.model ??
|
|
2155
|
+
const model = options?.model ?? DEFAULT_MODEL;
|
|
2065
2156
|
// Build tools — same as interactive handler but WITHOUT call-agent
|
|
2066
2157
|
// to prevent infinite recursive A2A loops (agent calling itself).
|
|
2067
2158
|
// In dev mode, template actions are invoked via shell (not native tools),
|
|
@@ -2181,7 +2272,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2181
2272
|
engineOption: options?.engine,
|
|
2182
2273
|
apiKey: options?.apiKey,
|
|
2183
2274
|
});
|
|
2184
|
-
const model = options?.model ??
|
|
2275
|
+
const model = options?.model ?? DEFAULT_MODEL;
|
|
2185
2276
|
// Same actions as A2A — without call-agent to prevent loops.
|
|
2186
2277
|
// In dev mode, template actions go through shell, not native tools.
|
|
2187
2278
|
const devActiveMcp = isDevMode();
|
|
@@ -2207,10 +2298,10 @@ export function createAgentChatPlugin(options) {
|
|
|
2207
2298
|
...toolActions,
|
|
2208
2299
|
};
|
|
2209
2300
|
const mcpTools = actionsToEngineTools(mcpActions);
|
|
2210
|
-
const resources = await loadResourcesForPrompt(
|
|
2301
|
+
const resources = await loadResourcesForPrompt(DEV_MODE_USER_EMAIL, lazyContext);
|
|
2211
2302
|
const schemaBlock = lazyContext
|
|
2212
2303
|
? ""
|
|
2213
|
-
: await buildSchemaBlock(
|
|
2304
|
+
: await buildSchemaBlock(DEV_MODE_USER_EMAIL, devActiveMcp);
|
|
2214
2305
|
// Build the MCP handler's own prompt — always use the shell-based
|
|
2215
2306
|
// dev prompt in dev mode because mcpActions routes template actions
|
|
2216
2307
|
// through shell (`devScriptsForA2A`), regardless of `nativeActionsInDev`.
|
|
@@ -2248,13 +2339,15 @@ export function createAgentChatPlugin(options) {
|
|
|
2248
2339
|
});
|
|
2249
2340
|
// Resolve owner from the H3 event's session — matches how resources are created
|
|
2250
2341
|
const getOwnerFromEvent = async (event) => {
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2342
|
+
const session = await getSession(event);
|
|
2343
|
+
if (!session?.email) {
|
|
2344
|
+
const { createError } = await import("h3");
|
|
2345
|
+
throw createError({
|
|
2346
|
+
statusCode: 401,
|
|
2347
|
+
statusMessage: "Unauthenticated",
|
|
2348
|
+
});
|
|
2257
2349
|
}
|
|
2350
|
+
return session.email;
|
|
2258
2351
|
};
|
|
2259
2352
|
// Auto-mount template actions as HTTP endpoints under /_agent-native/actions/
|
|
2260
2353
|
// Include engine management script so the UI can call manage-agent-engine.
|
|
@@ -2348,10 +2441,11 @@ export function createAgentChatPlugin(options) {
|
|
|
2348
2441
|
}
|
|
2349
2442
|
// Store debug metadata so we can inspect what the LLM actually
|
|
2350
2443
|
// received (system prompt, model, engine) when diagnosing issues.
|
|
2444
|
+
const runCtx = getRequestRunContext();
|
|
2351
2445
|
repo._debug = {
|
|
2352
|
-
systemPrompt:
|
|
2353
|
-
model:
|
|
2354
|
-
engine:
|
|
2446
|
+
systemPrompt: runCtx?.systemPrompt,
|
|
2447
|
+
model: runCtx?.model ?? resolvedModel,
|
|
2448
|
+
engine: runCtx?.engine?.name ?? "unknown",
|
|
2355
2449
|
timestamp: Date.now(),
|
|
2356
2450
|
};
|
|
2357
2451
|
const meta = extractThreadMeta(repo);
|
|
@@ -2361,13 +2455,32 @@ export function createAgentChatPlugin(options) {
|
|
|
2361
2455
|
// Best-effort — don't break cleanup
|
|
2362
2456
|
}
|
|
2363
2457
|
});
|
|
2364
|
-
// Emit agent.turn.completed for automation triggers
|
|
2458
|
+
// Emit agent.turn.completed for automation triggers.
|
|
2459
|
+
//
|
|
2460
|
+
// SECURITY: include `owner` so the trigger dispatcher's tenant-scope
|
|
2461
|
+
// check engages (see triggers/dispatcher.ts:212-218). Without an
|
|
2462
|
+
// owner, every user's matching `agent.turn.completed` trigger
|
|
2463
|
+
// would fire when ANY user's chat turn completes — cross-tenant
|
|
2464
|
+
// fan-out (audit 12 #9). Owner comes from the thread row when
|
|
2465
|
+
// available (most reliable; persisted at thread create time),
|
|
2466
|
+
// falling back to the current run context's owner. If neither
|
|
2467
|
+
// resolves we skip emission entirely rather than emit unowned.
|
|
2365
2468
|
try {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
threadId
|
|
2369
|
-
|
|
2370
|
-
}
|
|
2469
|
+
let ownerEmail;
|
|
2470
|
+
try {
|
|
2471
|
+
const ownerThread = await getThread(threadId);
|
|
2472
|
+
ownerEmail = ownerThread?.ownerEmail;
|
|
2473
|
+
}
|
|
2474
|
+
catch {
|
|
2475
|
+
// ignore — fall through to run-context owner
|
|
2476
|
+
}
|
|
2477
|
+
if (!ownerEmail) {
|
|
2478
|
+
ownerEmail = getRequestRunContext()?.owner;
|
|
2479
|
+
}
|
|
2480
|
+
if (ownerEmail) {
|
|
2481
|
+
const { emit } = await import("../event-bus/index.js");
|
|
2482
|
+
emit("agent.turn.completed", { threadId, model: resolvedModel }, { owner: ownerEmail });
|
|
2483
|
+
}
|
|
2371
2484
|
}
|
|
2372
2485
|
catch {
|
|
2373
2486
|
// Event bus not available — skip
|
|
@@ -2428,18 +2541,10 @@ export function createAgentChatPlugin(options) {
|
|
|
2428
2541
|
// Each run gets its own send function, keyed by threadId so concurrent
|
|
2429
2542
|
// requests for different threads don't clobber each other.
|
|
2430
2543
|
const _runSendByThread = new Map();
|
|
2431
|
-
|
|
2432
|
-
let _currentRunThreadId = "";
|
|
2433
|
-
let _currentRunSystemPrompt = basePrompt;
|
|
2434
|
-
// Populated by onEngineResolved per request so sub-agents inherit
|
|
2435
|
-
// whichever provider + model the user configured (OpenRouter, Groq, …)
|
|
2436
|
-
// instead of silently falling back to Anthropic + Claude.
|
|
2437
|
-
let _currentRunEngine;
|
|
2438
|
-
let _currentRunModel;
|
|
2439
|
-
const resolvedModel = options?.model ?? "claude-sonnet-4-6";
|
|
2544
|
+
const resolvedModel = options?.model ?? DEFAULT_MODEL;
|
|
2440
2545
|
const teamTools = createTeamTools({
|
|
2441
|
-
getOwner: () =>
|
|
2442
|
-
getSystemPrompt: () =>
|
|
2546
|
+
getOwner: () => requireCurrentRunOwner("spawn or manage sub-agents"),
|
|
2547
|
+
getSystemPrompt: () => getRequestRunContext()?.systemPrompt ?? basePrompt,
|
|
2443
2548
|
getActions: () => isDevMode()
|
|
2444
2549
|
? {
|
|
2445
2550
|
// Sub-agents spawned in dev mode also invoke template actions
|
|
@@ -2460,20 +2565,24 @@ export function createAgentChatPlugin(options) {
|
|
|
2460
2565
|
...urlTools,
|
|
2461
2566
|
...chatScripts,
|
|
2462
2567
|
},
|
|
2463
|
-
getEngine: () =>
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2568
|
+
getEngine: () => {
|
|
2569
|
+
const runCtx = getRequestRunContext();
|
|
2570
|
+
return (runCtx?.engine ??
|
|
2571
|
+
createAnthropicEngine({
|
|
2572
|
+
// Sub-agents must inherit the parent run's resolved key so a
|
|
2573
|
+
// BYO-key user can't bypass the free-tier check on the parent
|
|
2574
|
+
// run and then have agent-teams spawn delegations bill the platform key.
|
|
2575
|
+
apiKey: runCtx?.userApiKey ??
|
|
2576
|
+
options?.apiKey ??
|
|
2577
|
+
process.env.ANTHROPIC_API_KEY,
|
|
2578
|
+
}));
|
|
2579
|
+
},
|
|
2580
|
+
getModel: () => getRequestRunContext()?.model ?? resolvedModel,
|
|
2581
|
+
getParentThreadId: () => getRequestRunContext()?.threadId ?? "",
|
|
2474
2582
|
getSend: () => {
|
|
2475
2583
|
// Return the send for the current run's thread
|
|
2476
|
-
const
|
|
2584
|
+
const threadId = getRequestRunContext()?.threadId ?? "";
|
|
2585
|
+
const send = _runSendByThread.get(threadId);
|
|
2477
2586
|
return send ?? null;
|
|
2478
2587
|
},
|
|
2479
2588
|
});
|
|
@@ -2545,27 +2654,37 @@ export function createAgentChatPlugin(options) {
|
|
|
2545
2654
|
// and tokens that minimal/voice apps don't need.
|
|
2546
2655
|
const leanBasePrompt = (options?.systemPrompt ?? "") + prodActionsPrompt;
|
|
2547
2656
|
// Per-request preamble shared by both prod and dev handlers. Resolves
|
|
2548
|
-
// owner + user API key
|
|
2549
|
-
//
|
|
2550
|
-
//
|
|
2551
|
-
//
|
|
2552
|
-
//
|
|
2657
|
+
// owner + user API key onto the AsyncLocalStorage run context so
|
|
2658
|
+
// downstream tool closures (automation, fetch, team) read the
|
|
2659
|
+
// current request's identity without racing against concurrent
|
|
2660
|
+
// requests. `extraContext` runs in every prompt variant (lean, lazy,
|
|
2661
|
+
// full) — if a template defined it, they opted in; framework-provided
|
|
2662
|
+
// content is what the token-saving modes strip.
|
|
2553
2663
|
const prepareRun = async (event) => {
|
|
2554
|
-
_currentRequestOrigin = getOrigin(event);
|
|
2555
2664
|
const owner = await getOwnerFromEvent(event);
|
|
2556
|
-
_currentRunOwner = owner;
|
|
2557
2665
|
const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
|
|
2558
|
-
|
|
2666
|
+
const userApiKey = await getOwnerActiveApiKey(owner);
|
|
2667
|
+
const runCtx = ensureRequestRunContext();
|
|
2668
|
+
if (runCtx) {
|
|
2669
|
+
runCtx.requestOrigin = getOrigin(event);
|
|
2670
|
+
runCtx.owner = owner;
|
|
2671
|
+
runCtx.userApiKey = userApiKey;
|
|
2672
|
+
}
|
|
2559
2673
|
const extra = await resolveExtraContext(event, owner);
|
|
2560
2674
|
return { owner, extra };
|
|
2561
2675
|
};
|
|
2676
|
+
const setSystemPromptOnContext = (prompt) => {
|
|
2677
|
+
const runCtx = ensureRequestRunContext();
|
|
2678
|
+
if (runCtx)
|
|
2679
|
+
runCtx.systemPrompt = prompt;
|
|
2680
|
+
return prompt;
|
|
2681
|
+
};
|
|
2562
2682
|
const prodHandler = createProductionAgentHandler({
|
|
2563
2683
|
actions: leanPrompt ? leanActions : prodActions,
|
|
2564
2684
|
systemPrompt: async (event) => {
|
|
2565
2685
|
const { owner, extra } = await prepareRun(event);
|
|
2566
2686
|
if (leanPrompt) {
|
|
2567
|
-
|
|
2568
|
-
return _currentRunSystemPrompt;
|
|
2687
|
+
return setSystemPromptOnContext(leanBasePrompt + extra);
|
|
2569
2688
|
}
|
|
2570
2689
|
const resources = await loadResourcesForPrompt(owner, lazyContext);
|
|
2571
2690
|
// In lazy context mode, skip embedding the full schema — the agent
|
|
@@ -2573,20 +2692,23 @@ export function createAgentChatPlugin(options) {
|
|
|
2573
2692
|
const schemaBlock = lazyContext
|
|
2574
2693
|
? ""
|
|
2575
2694
|
: await buildSchemaBlock(owner, false);
|
|
2576
|
-
|
|
2577
|
-
basePrompt + resources + schemaBlock + extra;
|
|
2578
|
-
return _currentRunSystemPrompt;
|
|
2695
|
+
return setSystemPromptOnContext(basePrompt + resources + schemaBlock + extra);
|
|
2579
2696
|
},
|
|
2580
|
-
model: options?.model ??
|
|
2697
|
+
model: options?.model ?? DEFAULT_MODEL,
|
|
2581
2698
|
apiKey: options?.apiKey,
|
|
2582
2699
|
skipFilesContext: leanPrompt,
|
|
2583
2700
|
onEngineResolved: (engine, model) => {
|
|
2584
|
-
|
|
2585
|
-
|
|
2701
|
+
const runCtx = ensureRequestRunContext();
|
|
2702
|
+
if (runCtx) {
|
|
2703
|
+
runCtx.engine = engine;
|
|
2704
|
+
runCtx.model = model;
|
|
2705
|
+
}
|
|
2586
2706
|
},
|
|
2587
2707
|
onRunStart: (send, threadId) => {
|
|
2588
2708
|
_runSendByThread.set(threadId, send);
|
|
2589
|
-
|
|
2709
|
+
const runCtx = ensureRequestRunContext();
|
|
2710
|
+
if (runCtx)
|
|
2711
|
+
runCtx.threadId = threadId;
|
|
2590
2712
|
},
|
|
2591
2713
|
onRunComplete: async (run, threadId) => {
|
|
2592
2714
|
if (threadId)
|
|
@@ -2645,27 +2767,29 @@ export function createAgentChatPlugin(options) {
|
|
|
2645
2767
|
systemPrompt: async (event) => {
|
|
2646
2768
|
const { owner, extra } = await prepareRun(event);
|
|
2647
2769
|
if (leanPrompt) {
|
|
2648
|
-
|
|
2649
|
-
return _currentRunSystemPrompt;
|
|
2770
|
+
return setSystemPromptOnContext(leanBasePrompt + extra);
|
|
2650
2771
|
}
|
|
2651
2772
|
const resources = await loadResourcesForPrompt(owner, lazyContext);
|
|
2652
2773
|
const schemaBlock = lazyContext
|
|
2653
2774
|
? ""
|
|
2654
2775
|
: await buildSchemaBlock(owner, true);
|
|
2655
|
-
|
|
2656
|
-
devPrompt + resources + schemaBlock + extra;
|
|
2657
|
-
return _currentRunSystemPrompt;
|
|
2776
|
+
return setSystemPromptOnContext(devPrompt + resources + schemaBlock + extra);
|
|
2658
2777
|
},
|
|
2659
2778
|
model: options?.model,
|
|
2660
2779
|
apiKey: options?.apiKey,
|
|
2661
2780
|
skipFilesContext: leanPrompt,
|
|
2662
2781
|
onEngineResolved: (engine, model) => {
|
|
2663
|
-
|
|
2664
|
-
|
|
2782
|
+
const runCtx = ensureRequestRunContext();
|
|
2783
|
+
if (runCtx) {
|
|
2784
|
+
runCtx.engine = engine;
|
|
2785
|
+
runCtx.model = model;
|
|
2786
|
+
}
|
|
2665
2787
|
},
|
|
2666
2788
|
onRunStart: (send, threadId) => {
|
|
2667
2789
|
_runSendByThread.set(threadId, send);
|
|
2668
|
-
|
|
2790
|
+
const runCtx = ensureRequestRunContext();
|
|
2791
|
+
if (runCtx)
|
|
2792
|
+
runCtx.threadId = threadId;
|
|
2669
2793
|
},
|
|
2670
2794
|
onRunComplete: async (run, threadId) => {
|
|
2671
2795
|
if (threadId)
|
|
@@ -2713,10 +2837,11 @@ export function createAgentChatPlugin(options) {
|
|
|
2713
2837
|
return { devMode: currentDevMode, canToggle };
|
|
2714
2838
|
}));
|
|
2715
2839
|
// Mount save-key BEFORE the prefix handler so it isn't shadowed.
|
|
2716
|
-
// Persists the user's key
|
|
2717
|
-
//
|
|
2718
|
-
//
|
|
2719
|
-
//
|
|
2840
|
+
// Persists the user's API key in `app_secrets` (encrypted, scope=user,
|
|
2841
|
+
// scopeId=email). Hard rule: never mutates process.env, never writes
|
|
2842
|
+
// .env. User-pasted secrets must not become deploy-level identity —
|
|
2843
|
+
// that's the cross-tenant leak class (KVesta Space, 2026-04).
|
|
2844
|
+
// Consumers read these values per-request via `resolveSecret(key)`.
|
|
2720
2845
|
getH3App(nitroApp).use(`${routePath}/save-key`, defineEventHandler(async (event) => {
|
|
2721
2846
|
if (getMethod(event) !== "POST") {
|
|
2722
2847
|
setResponseStatus(event, 405);
|
|
@@ -2730,75 +2855,35 @@ export function createAgentChatPlugin(options) {
|
|
|
2730
2855
|
return { error: "API key is required" };
|
|
2731
2856
|
}
|
|
2732
2857
|
const trimmedKey = key.trim();
|
|
2733
|
-
// Persist per-owner so the key survives cold starts in serverless
|
|
2734
|
-
// and so the user's key isn't shared across users on multi-tenant
|
|
2735
|
-
// hosted deployments. We require a real authenticated owner here —
|
|
2736
|
-
// `local@localhost` is the unauthenticated fallback and must never
|
|
2737
|
-
// become the shared key bucket on hosted deployments.
|
|
2738
2858
|
const ownerEmail = await getOwnerFromEvent(event);
|
|
2739
|
-
if (
|
|
2740
|
-
(!ownerEmail || ownerEmail === "local@localhost")) {
|
|
2859
|
+
if (!ownerEmail || ownerEmail === DEV_MODE_USER_EMAIL) {
|
|
2741
2860
|
setResponseStatus(event, 401);
|
|
2742
2861
|
return { error: "Authentication required" };
|
|
2743
2862
|
}
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
}
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
};
|
|
2768
|
-
}
|
|
2769
|
-
// Local dev falls through to the env-file path below.
|
|
2770
|
-
}
|
|
2771
|
-
}
|
|
2772
|
-
// In hosted/multi-tenant mode we deliberately do NOT touch
|
|
2773
|
-
// process.env or .env: the per-owner SQL lookup above is the
|
|
2774
|
-
// single source of truth, and overwriting the shared env key
|
|
2775
|
-
// would leak one tenant's credentials into every subsequent
|
|
2776
|
-
// request that hit the same warm instance without its own key.
|
|
2777
|
-
if (!isHostedProd) {
|
|
2778
|
-
const providerToEnv = {
|
|
2779
|
-
anthropic: "ANTHROPIC_API_KEY",
|
|
2780
|
-
openai: "OPENAI_API_KEY",
|
|
2781
|
-
google: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
2782
|
-
groq: "GROQ_API_KEY",
|
|
2783
|
-
mistral: "MISTRAL_API_KEY",
|
|
2784
|
-
cohere: "COHERE_API_KEY",
|
|
2863
|
+
const providerToEnv = {
|
|
2864
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
2865
|
+
openai: "OPENAI_API_KEY",
|
|
2866
|
+
google: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
2867
|
+
groq: "GROQ_API_KEY",
|
|
2868
|
+
mistral: "MISTRAL_API_KEY",
|
|
2869
|
+
cohere: "COHERE_API_KEY",
|
|
2870
|
+
};
|
|
2871
|
+
const secretKey = providerToEnv[provider] ?? `${provider.toUpperCase()}_API_KEY`;
|
|
2872
|
+
try {
|
|
2873
|
+
const { writeAppSecret } = await import("../secrets/storage.js");
|
|
2874
|
+
await writeAppSecret({
|
|
2875
|
+
key: secretKey,
|
|
2876
|
+
value: trimmedKey,
|
|
2877
|
+
scope: "user",
|
|
2878
|
+
scopeId: ownerEmail,
|
|
2879
|
+
});
|
|
2880
|
+
}
|
|
2881
|
+
catch (err) {
|
|
2882
|
+
console.error("[agent-chat] save-key persistence failed:", err instanceof Error ? err.message : err);
|
|
2883
|
+
setResponseStatus(event, 500);
|
|
2884
|
+
return {
|
|
2885
|
+
error: "Failed to persist API key. Please try again or contact support.",
|
|
2785
2886
|
};
|
|
2786
|
-
const envVar = providerToEnv[provider] ?? `${provider.toUpperCase()}_API_KEY`;
|
|
2787
|
-
try {
|
|
2788
|
-
const path = await import("path");
|
|
2789
|
-
const { upsertEnvFile } = await import("./create-server.js");
|
|
2790
|
-
const envPath = path.join(process.cwd(), ".env");
|
|
2791
|
-
await upsertEnvFile(envPath, [
|
|
2792
|
-
{ key: envVar, value: trimmedKey },
|
|
2793
|
-
]);
|
|
2794
|
-
}
|
|
2795
|
-
catch {
|
|
2796
|
-
// Edge runtime — can't write .env, but can still update process.env
|
|
2797
|
-
}
|
|
2798
|
-
// Update process.env so the agent works immediately in the
|
|
2799
|
-
// current local-dev invocation; the SQL persist above covers
|
|
2800
|
-
// future invocations.
|
|
2801
|
-
process.env[envVar] = trimmedKey;
|
|
2802
2887
|
}
|
|
2803
2888
|
return { ok: true };
|
|
2804
2889
|
}));
|
|
@@ -2836,7 +2921,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2836
2921
|
// Query resources
|
|
2837
2922
|
try {
|
|
2838
2923
|
const resources = currentDevMode
|
|
2839
|
-
? await resourceListAccessible(
|
|
2924
|
+
? await resourceListAccessible(DEV_MODE_USER_EMAIL)
|
|
2840
2925
|
: await resourceList(SHARED_OWNER);
|
|
2841
2926
|
for (const r of resources) {
|
|
2842
2927
|
if (!seen.has(r.path)) {
|
|
@@ -2921,7 +3006,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2921
3006
|
// Query resources with skills/ prefix
|
|
2922
3007
|
try {
|
|
2923
3008
|
const resourceSkills = currentDevMode
|
|
2924
|
-
? await resourceListAccessible(
|
|
3009
|
+
? await resourceListAccessible(DEV_MODE_USER_EMAIL, "skills/")
|
|
2925
3010
|
: await resourceList(SHARED_OWNER, "skills/");
|
|
2926
3011
|
for (const r of resourceSkills) {
|
|
2927
3012
|
// Try to get content to parse frontmatter
|
|
@@ -2966,6 +3051,22 @@ export function createAgentChatPlugin(options) {
|
|
|
2966
3051
|
setResponseStatus(event, 405);
|
|
2967
3052
|
return { error: "Method not allowed" };
|
|
2968
3053
|
}
|
|
3054
|
+
// Resolve the caller and run the entire stream inside a request
|
|
3055
|
+
// context so custom mention providers can use `accessFilter` /
|
|
3056
|
+
// `resolveAccess` when querying ownable tables. Without this,
|
|
3057
|
+
// a provider that searches `decks` (or any sharable resource)
|
|
3058
|
+
// would see every row regardless of ownership.
|
|
3059
|
+
const mentionsOwner = await getOwnerFromEvent(event).catch(() => undefined);
|
|
3060
|
+
let mentionsOrgId;
|
|
3061
|
+
if (options?.resolveOrgId) {
|
|
3062
|
+
try {
|
|
3063
|
+
const resolved = await options.resolveOrgId(event);
|
|
3064
|
+
mentionsOrgId = resolved ?? undefined;
|
|
3065
|
+
}
|
|
3066
|
+
catch {
|
|
3067
|
+
mentionsOrgId = undefined;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
2969
3070
|
const query = getQuery(event);
|
|
2970
3071
|
const q = typeof query.q === "string" ? query.q.toLowerCase() : "";
|
|
2971
3072
|
const matchesQuery = (item) => !q ||
|
|
@@ -2976,148 +3077,154 @@ export function createAgentChatPlugin(options) {
|
|
|
2976
3077
|
setResponseHeader(event, "Content-Type", "application/x-ndjson");
|
|
2977
3078
|
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
2978
3079
|
const stream = new ReadableStream({
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
// 1. Resources from SQL (fast — flush first)
|
|
3005
|
-
sources.push((async () => {
|
|
3080
|
+
start(controller) {
|
|
3081
|
+
return runWithRequestContext({
|
|
3082
|
+
userEmail: mentionsOwner,
|
|
3083
|
+
orgId: mentionsOrgId,
|
|
3084
|
+
}, () => mentionsStreamWork(controller));
|
|
3085
|
+
},
|
|
3086
|
+
cancel() {
|
|
3087
|
+
// Client disconnected — stop enqueuing
|
|
3088
|
+
},
|
|
3089
|
+
});
|
|
3090
|
+
return stream;
|
|
3091
|
+
async function mentionsStreamWork(controller) {
|
|
3092
|
+
const MAX_RESULTS = 50;
|
|
3093
|
+
let totalSent = 0;
|
|
3094
|
+
let cancelled = false;
|
|
3095
|
+
const flush = (batch) => {
|
|
3096
|
+
if (cancelled)
|
|
3097
|
+
return;
|
|
3098
|
+
const filtered = batch.filter(matchesQuery);
|
|
3099
|
+
if (filtered.length === 0)
|
|
3100
|
+
return;
|
|
3101
|
+
const remaining = MAX_RESULTS - totalSent;
|
|
3102
|
+
const toSend = filtered.slice(0, remaining);
|
|
3103
|
+
if (toSend.length > 0) {
|
|
3104
|
+
totalSent += toSend.length;
|
|
3006
3105
|
try {
|
|
3007
|
-
|
|
3008
|
-
? await resourceListAccessible("local@localhost")
|
|
3009
|
-
: await resourceList(SHARED_OWNER);
|
|
3010
|
-
flush(resources.map((r) => {
|
|
3011
|
-
const isShared = r.owner === SHARED_OWNER;
|
|
3012
|
-
return {
|
|
3013
|
-
id: `resource:${r.path}`,
|
|
3014
|
-
label: r.path.split("/").pop() || r.path,
|
|
3015
|
-
description: r.path,
|
|
3016
|
-
icon: "file",
|
|
3017
|
-
source: isShared
|
|
3018
|
-
? "resource:shared"
|
|
3019
|
-
: "resource:private",
|
|
3020
|
-
refType: "file",
|
|
3021
|
-
refPath: r.path,
|
|
3022
|
-
section: "Files",
|
|
3023
|
-
};
|
|
3024
|
-
}));
|
|
3106
|
+
controller.enqueue(enc.encode(JSON.stringify({ items: toSend }) + "\n"));
|
|
3025
3107
|
}
|
|
3026
|
-
catch {
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3108
|
+
catch {
|
|
3109
|
+
// Stream was closed by client
|
|
3110
|
+
cancelled = true;
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
};
|
|
3114
|
+
// All sources run in parallel; each flushes independently.
|
|
3115
|
+
const sources = [];
|
|
3116
|
+
// 1. Resources from SQL (fast — flush first)
|
|
3117
|
+
sources.push((async () => {
|
|
3118
|
+
try {
|
|
3119
|
+
const resources = currentDevMode
|
|
3120
|
+
? await resourceListAccessible(DEV_MODE_USER_EMAIL)
|
|
3121
|
+
: await resourceList(SHARED_OWNER);
|
|
3122
|
+
flush(resources.map((r) => {
|
|
3123
|
+
const isShared = r.owner === SHARED_OWNER;
|
|
3124
|
+
return {
|
|
3125
|
+
id: `resource:${r.path}`,
|
|
3126
|
+
label: r.path.split("/").pop() || r.path,
|
|
3127
|
+
description: r.path,
|
|
3128
|
+
icon: "file",
|
|
3129
|
+
source: isShared
|
|
3130
|
+
? "resource:shared"
|
|
3131
|
+
: "resource:private",
|
|
3042
3132
|
refType: "file",
|
|
3043
|
-
refPath:
|
|
3133
|
+
refPath: r.path,
|
|
3044
3134
|
section: "Files",
|
|
3045
|
-
}
|
|
3046
|
-
})
|
|
3047
|
-
}
|
|
3048
|
-
// 3. Custom mention providers (each flushes independently)
|
|
3049
|
-
for (const [key, provider] of Object.entries(mentionProviders)) {
|
|
3050
|
-
sources.push((async () => {
|
|
3051
|
-
try {
|
|
3052
|
-
const providerItems = await provider.search(q, event);
|
|
3053
|
-
flush(providerItems.map((item) => ({
|
|
3054
|
-
id: item.id,
|
|
3055
|
-
label: item.label,
|
|
3056
|
-
description: item.description,
|
|
3057
|
-
icon: item.icon || provider.icon || "file",
|
|
3058
|
-
source: key,
|
|
3059
|
-
refType: item.refType,
|
|
3060
|
-
refPath: item.refPath,
|
|
3061
|
-
refId: item.refId,
|
|
3062
|
-
section: provider.label,
|
|
3063
|
-
})));
|
|
3064
|
-
}
|
|
3065
|
-
catch (e) {
|
|
3066
|
-
console.error(`[agent-native] Mention provider "${key}" failed:`, e);
|
|
3067
|
-
}
|
|
3068
|
-
})());
|
|
3135
|
+
};
|
|
3136
|
+
}));
|
|
3069
3137
|
}
|
|
3070
|
-
|
|
3138
|
+
catch { }
|
|
3139
|
+
})());
|
|
3140
|
+
// 2. Codebase files (dev mode only — can be slow on large repos)
|
|
3141
|
+
if (currentDevMode) {
|
|
3071
3142
|
sources.push((async () => {
|
|
3143
|
+
const codebaseFiles = [];
|
|
3072
3144
|
try {
|
|
3073
|
-
|
|
3074
|
-
const { listAccessibleCustomAgents } = await import("../resources/agents.js");
|
|
3075
|
-
const agents = await listAccessibleCustomAgents(owner);
|
|
3076
|
-
flush(agents.map((agent) => ({
|
|
3077
|
-
id: `custom-agent:${agent.id}`,
|
|
3078
|
-
label: agent.name,
|
|
3079
|
-
description: agent.description || agent.path,
|
|
3080
|
-
icon: "agent",
|
|
3081
|
-
source: "agent:custom",
|
|
3082
|
-
refType: "custom-agent",
|
|
3083
|
-
refPath: agent.path,
|
|
3084
|
-
refId: agent.id,
|
|
3085
|
-
section: "Agents",
|
|
3086
|
-
})));
|
|
3087
|
-
}
|
|
3088
|
-
catch (e) {
|
|
3089
|
-
console.error("[agent-native] Custom agent discovery failed:", e);
|
|
3145
|
+
await collectFiles(process.cwd(), "", 0, codebaseFiles);
|
|
3090
3146
|
}
|
|
3147
|
+
catch { }
|
|
3148
|
+
flush(codebaseFiles.map((f) => ({
|
|
3149
|
+
id: `codebase:${f.path}`,
|
|
3150
|
+
label: f.name,
|
|
3151
|
+
description: f.path !== f.name ? f.path : undefined,
|
|
3152
|
+
icon: f.type,
|
|
3153
|
+
source: "codebase",
|
|
3154
|
+
refType: "file",
|
|
3155
|
+
refPath: f.path,
|
|
3156
|
+
section: "Files",
|
|
3157
|
+
})));
|
|
3091
3158
|
})());
|
|
3092
|
-
|
|
3159
|
+
}
|
|
3160
|
+
// 3. Custom mention providers (each flushes independently)
|
|
3161
|
+
for (const [key, provider] of Object.entries(mentionProviders)) {
|
|
3093
3162
|
sources.push((async () => {
|
|
3094
3163
|
try {
|
|
3095
|
-
const
|
|
3096
|
-
flush(
|
|
3097
|
-
id:
|
|
3098
|
-
label:
|
|
3099
|
-
description:
|
|
3100
|
-
icon: "
|
|
3101
|
-
source:
|
|
3102
|
-
refType:
|
|
3103
|
-
refPath:
|
|
3104
|
-
refId:
|
|
3105
|
-
section:
|
|
3164
|
+
const providerItems = await provider.search(q, event);
|
|
3165
|
+
flush(providerItems.map((item) => ({
|
|
3166
|
+
id: item.id,
|
|
3167
|
+
label: item.label,
|
|
3168
|
+
description: item.description,
|
|
3169
|
+
icon: item.icon || provider.icon || "file",
|
|
3170
|
+
source: key,
|
|
3171
|
+
refType: item.refType,
|
|
3172
|
+
refPath: item.refPath,
|
|
3173
|
+
refId: item.refId,
|
|
3174
|
+
section: provider.label,
|
|
3106
3175
|
})));
|
|
3107
3176
|
}
|
|
3108
3177
|
catch (e) {
|
|
3109
|
-
console.error(
|
|
3178
|
+
console.error(`[agent-native] Mention provider "${key}" failed:`, e);
|
|
3110
3179
|
}
|
|
3111
3180
|
})());
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3181
|
+
}
|
|
3182
|
+
// 4. Custom workspace agents
|
|
3183
|
+
sources.push((async () => {
|
|
3184
|
+
try {
|
|
3185
|
+
const owner = await getOwnerFromEvent(event);
|
|
3186
|
+
const { listAccessibleCustomAgents } = await import("../resources/agents.js");
|
|
3187
|
+
const agents = await listAccessibleCustomAgents(owner);
|
|
3188
|
+
flush(agents.map((agent) => ({
|
|
3189
|
+
id: `custom-agent:${agent.id}`,
|
|
3190
|
+
label: agent.name,
|
|
3191
|
+
description: agent.description || agent.path,
|
|
3192
|
+
icon: "agent",
|
|
3193
|
+
source: "agent:custom",
|
|
3194
|
+
refType: "custom-agent",
|
|
3195
|
+
refPath: agent.path,
|
|
3196
|
+
refId: agent.id,
|
|
3197
|
+
section: "Agents",
|
|
3198
|
+
})));
|
|
3199
|
+
}
|
|
3200
|
+
catch (e) {
|
|
3201
|
+
console.error("[agent-native] Custom agent discovery failed:", e);
|
|
3202
|
+
}
|
|
3203
|
+
})());
|
|
3204
|
+
// 5. Peer agent discovery (network call — often slowest)
|
|
3205
|
+
sources.push((async () => {
|
|
3206
|
+
try {
|
|
3207
|
+
const agents = await discoverAgents(options?.appId);
|
|
3208
|
+
flush(agents.map((agent) => ({
|
|
3209
|
+
id: `agent:${agent.id}`,
|
|
3210
|
+
label: agent.name,
|
|
3211
|
+
description: agent.description,
|
|
3212
|
+
icon: "agent",
|
|
3213
|
+
source: "agent",
|
|
3214
|
+
refType: "agent",
|
|
3215
|
+
refPath: agent.url,
|
|
3216
|
+
refId: agent.id,
|
|
3217
|
+
section: "Connected Agents",
|
|
3218
|
+
})));
|
|
3219
|
+
}
|
|
3220
|
+
catch (e) {
|
|
3221
|
+
console.error("[agent-native] Agent discovery failed:", e);
|
|
3222
|
+
}
|
|
3223
|
+
})());
|
|
3224
|
+
await Promise.all(sources);
|
|
3225
|
+
if (!cancelled)
|
|
3226
|
+
controller.close();
|
|
3227
|
+
}
|
|
3121
3228
|
}));
|
|
3122
3229
|
// ─── Generate thread title ──────────────────────────────────────────
|
|
3123
3230
|
getH3App(nitroApp).use(`${routePath}/generate-title`, defineEventHandler(async (event) => {
|
|
@@ -3126,6 +3233,19 @@ export function createAgentChatPlugin(options) {
|
|
|
3126
3233
|
return { error: "Method not allowed" };
|
|
3127
3234
|
}
|
|
3128
3235
|
const ownerEmail = await getOwnerFromEvent(event);
|
|
3236
|
+
// Per-user rate limit: 10 calls / 60s. Prevents an authenticated
|
|
3237
|
+
// user from spamming the endpoint to exhaust shared Anthropic
|
|
3238
|
+
// credits on platform-key deployments.
|
|
3239
|
+
const now = Date.now();
|
|
3240
|
+
const limitWindowMs = 60_000;
|
|
3241
|
+
const limitMax = 10;
|
|
3242
|
+
const recent = (generateTitleRateLimit.get(ownerEmail) ?? []).filter((t) => now - t < limitWindowMs);
|
|
3243
|
+
if (recent.length >= limitMax) {
|
|
3244
|
+
setResponseStatus(event, 429);
|
|
3245
|
+
return { error: "Rate limit exceeded" };
|
|
3246
|
+
}
|
|
3247
|
+
recent.push(now);
|
|
3248
|
+
generateTitleRateLimit.set(ownerEmail, recent);
|
|
3129
3249
|
const body = await readBody(event);
|
|
3130
3250
|
const message = body?.message;
|
|
3131
3251
|
if (!message || typeof message !== "string") {
|
|
@@ -3498,14 +3618,6 @@ export function createAgentChatPlugin(options) {
|
|
|
3498
3618
|
// Session not available
|
|
3499
3619
|
}
|
|
3500
3620
|
}
|
|
3501
|
-
// Also set process.env for backwards compat (CLI scripts, legacy readers)
|
|
3502
|
-
process.env.AGENT_USER_EMAIL = owner;
|
|
3503
|
-
if (resolvedOrgId) {
|
|
3504
|
-
process.env.AGENT_ORG_ID = resolvedOrgId;
|
|
3505
|
-
}
|
|
3506
|
-
else {
|
|
3507
|
-
delete process.env.AGENT_ORG_ID;
|
|
3508
|
-
}
|
|
3509
3621
|
// Propagate the caller's IANA timezone from `x-user-timezone` so that
|
|
3510
3622
|
// tool calls made by the agent (e.g. log-meal with no explicit date)
|
|
3511
3623
|
// resolve "today" in the user's local timezone instead of server UTC.
|
|
@@ -3515,8 +3627,6 @@ export function createAgentChatPlugin(options) {
|
|
|
3515
3627
|
tzRaw.trim().length < 64
|
|
3516
3628
|
? tzRaw.trim()
|
|
3517
3629
|
: undefined;
|
|
3518
|
-
if (timezone)
|
|
3519
|
-
process.env.AGENT_USER_TIMEZONE = timezone;
|
|
3520
3630
|
return runWithRequestContext({ userEmail: owner, orgId: resolvedOrgId, timezone }, () => {
|
|
3521
3631
|
const handler = currentDevMode && devHandler ? devHandler : prodHandler;
|
|
3522
3632
|
return handler(event);
|
|
@@ -3635,9 +3745,10 @@ export function getGlobalMcpManager() {
|
|
|
3635
3745
|
return _globalMcpManager;
|
|
3636
3746
|
}
|
|
3637
3747
|
function mountMcpHubStatusRoute(nitroApp) {
|
|
3638
|
-
|
|
3748
|
+
const mountedApps = (globalThis.__agentNativeMcpHubStatusMountedApps ??= new WeakSet());
|
|
3749
|
+
if (mountedApps.has(nitroApp))
|
|
3639
3750
|
return;
|
|
3640
|
-
|
|
3751
|
+
mountedApps.add(nitroApp);
|
|
3641
3752
|
try {
|
|
3642
3753
|
getH3App(nitroApp).use("/_agent-native/mcp/hub/status", defineEventHandler(async (event) => {
|
|
3643
3754
|
if (getMethod(event) !== "GET") {
|
|
@@ -3653,10 +3764,11 @@ function mountMcpHubStatusRoute(nitroApp) {
|
|
|
3653
3764
|
}
|
|
3654
3765
|
}
|
|
3655
3766
|
function mountMcpStatusRoute(nitroApp, manager) {
|
|
3656
|
-
// Idempotent
|
|
3657
|
-
|
|
3767
|
+
// Idempotent per Nitro app; dev-all may host multiple templates in one process.
|
|
3768
|
+
const mountedApps = (globalThis.__agentNativeMcpStatusMountedApps ??= new WeakSet());
|
|
3769
|
+
if (mountedApps.has(nitroApp))
|
|
3658
3770
|
return;
|
|
3659
|
-
|
|
3771
|
+
mountedApps.add(nitroApp);
|
|
3660
3772
|
try {
|
|
3661
3773
|
getH3App(nitroApp).use("/_agent-native/mcp/status", defineEventHandler(async (event) => {
|
|
3662
3774
|
if (getMethod(event) !== "GET") {
|