@agent-native/core 0.6.1 → 0.7.2
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 +43 -3
- package/dist/action.d.ts +8 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +18 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +9 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +301 -39
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +20 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +14 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +63 -6
- package/dist/agent/run-store.js.map +1 -1
- package/dist/agent/types.d.ts +3 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/cli/create-workspace.d.ts +8 -0
- package/dist/cli/create-workspace.d.ts.map +1 -0
- package/dist/cli/create-workspace.js +18 -0
- package/dist/cli/create-workspace.js.map +1 -0
- package/dist/cli/create.d.ts +35 -7
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +444 -251
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/index.js +59 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup-agents.d.ts.map +1 -1
- package/dist/cli/setup-agents.js +0 -2
- package/dist/cli/setup-agents.js.map +1 -1
- package/dist/cli/templates-meta.d.ts +52 -0
- package/dist/cli/templates-meta.d.ts.map +1 -0
- package/dist/cli/templates-meta.js +165 -0
- package/dist/cli/templates-meta.js.map +1 -0
- package/dist/cli/workspacify.d.ts +18 -0
- package/dist/cli/workspacify.d.ts.map +1 -0
- package/dist/cli/workspacify.js +74 -0
- package/dist/cli/workspacify.js.map +1 -0
- package/dist/client/AgentPanel.d.ts +6 -2
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +328 -241
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +172 -40
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts +21 -0
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -0
- package/dist/client/ConnectBuilderCard.js +196 -0
- package/dist/client/ConnectBuilderCard.js.map +1 -0
- package/dist/client/FeedbackButton.d.ts +15 -0
- package/dist/client/FeedbackButton.d.ts.map +1 -0
- package/dist/client/FeedbackButton.js +72 -0
- package/dist/client/FeedbackButton.js.map +1 -0
- package/dist/client/IframeEmbed.d.ts +17 -0
- package/dist/client/IframeEmbed.d.ts.map +1 -0
- package/dist/client/IframeEmbed.js +108 -0
- package/dist/client/IframeEmbed.js.map +1 -0
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +34 -7
- 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 +34 -15
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +7 -0
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
- package/dist/client/components/CodeRequiredDialog.js +86 -5
- package/dist/client/components/CodeRequiredDialog.js.map +1 -1
- package/dist/client/composer/MentionPopover.d.ts.map +1 -1
- package/dist/client/composer/MentionPopover.js +42 -26
- package/dist/client/composer/MentionPopover.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 +24 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/types.d.ts +1 -1
- package/dist/client/composer/types.d.ts.map +1 -1
- package/dist/client/embed.d.ts +28 -0
- package/dist/client/embed.d.ts.map +1 -0
- package/dist/client/embed.js +50 -0
- package/dist/client/embed.js.map +1 -0
- package/dist/client/index.d.ts +4 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +4 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +22 -9
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/onboarding/OnboardingBanner.d.ts +13 -0
- package/dist/client/onboarding/OnboardingBanner.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingBanner.js +36 -0
- package/dist/client/onboarding/OnboardingBanner.js.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts +16 -0
- package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/client/onboarding/OnboardingPanel.js +447 -0
- package/dist/client/onboarding/OnboardingPanel.js.map +1 -0
- package/dist/client/onboarding/SetupButton.d.ts +10 -0
- package/dist/client/onboarding/SetupButton.d.ts.map +1 -0
- package/dist/client/onboarding/SetupButton.js +36 -0
- package/dist/client/onboarding/SetupButton.js.map +1 -0
- package/dist/client/onboarding/index.d.ts +12 -0
- package/dist/client/onboarding/index.d.ts.map +1 -0
- package/dist/client/onboarding/index.js +11 -0
- package/dist/client/onboarding/index.js.map +1 -0
- package/dist/client/onboarding/use-onboarding.d.ts +34 -0
- package/dist/client/onboarding/use-onboarding.d.ts.map +1 -0
- package/dist/client/onboarding/use-onboarding.js +101 -0
- package/dist/client/onboarding/use-onboarding.js.map +1 -0
- package/dist/client/org/TeamPage.d.ts +6 -1
- package/dist/client/org/TeamPage.d.ts.map +1 -1
- package/dist/client/org/TeamPage.js +97 -21
- package/dist/client/org/TeamPage.js.map +1 -1
- package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/client/resources/ResourceEditor.js +104 -78
- package/dist/client/resources/ResourceEditor.js.map +1 -1
- package/dist/client/resources/ResourceTree.d.ts +5 -1
- package/dist/client/resources/ResourceTree.d.ts.map +1 -1
- package/dist/client/resources/ResourceTree.js +31 -11
- package/dist/client/resources/ResourceTree.js.map +1 -1
- package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/client/resources/ResourcesPanel.js +142 -14
- package/dist/client/resources/ResourcesPanel.js.map +1 -1
- package/dist/client/resources/use-resources.d.ts +5 -0
- package/dist/client/resources/use-resources.d.ts.map +1 -1
- package/dist/client/resources/use-resources.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts +2 -0
- package/dist/client/settings/AgentsSection.d.ts.map +1 -0
- package/dist/client/settings/AgentsSection.js +201 -0
- package/dist/client/settings/AgentsSection.js.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts +2 -0
- package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -0
- package/dist/client/settings/BackgroundAgentSection.js +46 -0
- package/dist/client/settings/BackgroundAgentSection.js.map +1 -0
- package/dist/client/settings/BrowserSection.d.ts +2 -0
- package/dist/client/settings/BrowserSection.d.ts.map +1 -0
- package/dist/client/settings/BrowserSection.js +10 -0
- package/dist/client/settings/BrowserSection.js.map +1 -0
- package/dist/client/settings/ComingSoonSection.d.ts +13 -0
- package/dist/client/settings/ComingSoonSection.d.ts.map +1 -0
- package/dist/client/settings/ComingSoonSection.js +9 -0
- package/dist/client/settings/ComingSoonSection.js.map +1 -0
- package/dist/client/settings/LLMSection.d.ts +2 -0
- package/dist/client/settings/LLMSection.d.ts.map +1 -0
- package/dist/client/settings/LLMSection.js +64 -0
- package/dist/client/settings/LLMSection.js.map +1 -0
- package/dist/client/settings/SettingsPanel.d.ts +8 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -0
- package/dist/client/settings/SettingsPanel.js +111 -0
- package/dist/client/settings/SettingsPanel.js.map +1 -0
- package/dist/client/settings/SettingsSection.d.ts +19 -0
- package/dist/client/settings/SettingsSection.d.ts.map +1 -0
- package/dist/client/settings/SettingsSection.js +10 -0
- package/dist/client/settings/SettingsSection.js.map +1 -0
- package/dist/client/settings/UsageSection.d.ts +2 -0
- package/dist/client/settings/UsageSection.d.ts.map +1 -0
- package/dist/client/settings/UsageSection.js +70 -0
- package/dist/client/settings/UsageSection.js.map +1 -0
- package/dist/client/settings/index.d.ts +3 -0
- package/dist/client/settings/index.d.ts.map +1 -0
- package/dist/client/settings/index.js +3 -0
- package/dist/client/settings/index.js.map +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +22 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -0
- package/dist/client/settings/useBuilderStatus.js +41 -0
- package/dist/client/settings/useBuilderStatus.js.map +1 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +67 -4
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +25 -2
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +62 -1
- 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 +16 -1
- package/dist/client/use-dev-mode.js.map +1 -1
- package/dist/db/client.d.ts +12 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +89 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/create-get-db.d.ts +11 -0
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +47 -3
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +62 -5
- package/dist/db/migrations.js.map +1 -1
- package/dist/deploy/build.js +198 -54
- package/dist/deploy/build.js.map +1 -1
- package/dist/deploy/route-discovery.d.ts +5 -0
- package/dist/deploy/route-discovery.d.ts.map +1 -1
- package/dist/deploy/route-discovery.js +38 -7
- package/dist/deploy/route-discovery.js.map +1 -1
- package/dist/deploy/workspace-core.d.ts +28 -0
- package/dist/deploy/workspace-core.d.ts.map +1 -0
- package/dist/deploy/workspace-core.js +223 -0
- package/dist/deploy/workspace-core.js.map +1 -0
- package/dist/deploy/workspace-deploy.d.ts +11 -0
- package/dist/deploy/workspace-deploy.d.ts.map +1 -0
- package/dist/deploy/workspace-deploy.js +148 -0
- package/dist/deploy/workspace-deploy.js.map +1 -0
- package/dist/file-upload/builder.d.ts +11 -0
- package/dist/file-upload/builder.d.ts.map +1 -0
- package/dist/file-upload/builder.js +53 -0
- package/dist/file-upload/builder.js.map +1 -0
- package/dist/file-upload/index.d.ts +4 -0
- package/dist/file-upload/index.d.ts.map +1 -0
- package/dist/file-upload/index.js +3 -0
- package/dist/file-upload/index.js.map +1 -0
- package/dist/file-upload/registry.d.ts +23 -0
- package/dist/file-upload/registry.d.ts.map +1 -0
- package/dist/file-upload/registry.js +52 -0
- package/dist/file-upload/registry.js.map +1 -0
- package/dist/file-upload/types.d.ts +37 -0
- package/dist/file-upload/types.d.ts.map +1 -0
- package/dist/file-upload/types.js +10 -0
- package/dist/file-upload/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/adapters/google-docs.d.ts +89 -0
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -0
- package/dist/integrations/adapters/google-docs.js +261 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -0
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +34 -0
- 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 +32 -0
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/google-docs-poller.d.ts +54 -0
- package/dist/integrations/google-docs-poller.d.ts.map +1 -0
- package/dist/integrations/google-docs-poller.js +442 -0
- package/dist/integrations/google-docs-poller.js.map +1 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +3 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +49 -2
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +33 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.d.ts +10 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +13 -3
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +3 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +87 -61
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +20 -3
- package/dist/jobs/tools.js.map +1 -1
- package/dist/mcp-client/config.d.ts +46 -0
- package/dist/mcp-client/config.d.ts.map +1 -0
- package/dist/mcp-client/config.js +152 -0
- package/dist/mcp-client/config.js.map +1 -0
- package/dist/mcp-client/index.d.ts +17 -0
- package/dist/mcp-client/index.d.ts.map +1 -0
- package/dist/mcp-client/index.js +53 -0
- package/dist/mcp-client/index.js.map +1 -0
- package/dist/mcp-client/manager.d.ts +76 -0
- package/dist/mcp-client/manager.d.ts.map +1 -0
- package/dist/mcp-client/manager.js +212 -0
- package/dist/mcp-client/manager.js.map +1 -0
- package/dist/oauth-tokens/google-refresh.d.ts +31 -0
- package/dist/oauth-tokens/google-refresh.d.ts.map +1 -0
- package/dist/oauth-tokens/google-refresh.js +115 -0
- package/dist/oauth-tokens/google-refresh.js.map +1 -0
- package/dist/oauth-tokens/index.d.ts +1 -0
- package/dist/oauth-tokens/index.d.ts.map +1 -1
- package/dist/oauth-tokens/index.js +1 -0
- package/dist/oauth-tokens/index.js.map +1 -1
- package/dist/oauth-tokens/store.d.ts.map +1 -1
- package/dist/oauth-tokens/store.js +3 -1
- package/dist/oauth-tokens/store.js.map +1 -1
- package/dist/onboarding/default-steps.d.ts +10 -0
- package/dist/onboarding/default-steps.d.ts.map +1 -0
- package/dist/onboarding/default-steps.js +203 -0
- package/dist/onboarding/default-steps.js.map +1 -0
- package/dist/onboarding/index.d.ts +12 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +11 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/plugin.d.ts +19 -0
- package/dist/onboarding/plugin.d.ts.map +1 -0
- package/dist/onboarding/plugin.js +147 -0
- package/dist/onboarding/plugin.js.map +1 -0
- package/dist/onboarding/registry.d.ts +24 -0
- package/dist/onboarding/registry.d.ts.map +1 -0
- package/dist/onboarding/registry.js +40 -0
- package/dist/onboarding/registry.js.map +1 -0
- package/dist/onboarding/types.d.ts +71 -0
- package/dist/onboarding/types.d.ts.map +1 -0
- package/dist/onboarding/types.js +10 -0
- package/dist/onboarding/types.js.map +1 -0
- package/dist/org/context.js +1 -1
- package/dist/org/handlers.d.ts.map +1 -1
- package/dist/org/handlers.js +35 -10
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/plugin.d.ts.map +1 -1
- package/dist/org/plugin.js +37 -22
- package/dist/org/plugin.js.map +1 -1
- package/dist/resources/agents.d.ts +4 -0
- package/dist/resources/agents.d.ts.map +1 -0
- package/dist/resources/agents.js +44 -0
- package/dist/resources/agents.js.map +1 -0
- package/dist/resources/handlers.d.ts +17 -0
- package/dist/resources/handlers.d.ts.map +1 -1
- package/dist/resources/handlers.js +49 -12
- package/dist/resources/handlers.js.map +1 -1
- package/dist/resources/metadata.d.ts +48 -0
- package/dist/resources/metadata.d.ts.map +1 -0
- package/dist/resources/metadata.js +150 -0
- package/dist/resources/metadata.js.map +1 -0
- package/dist/resources/script-helpers.d.ts.map +1 -1
- package/dist/resources/script-helpers.js +3 -2
- package/dist/resources/script-helpers.js.map +1 -1
- package/dist/resources/store.d.ts.map +1 -1
- package/dist/resources/store.js +59 -18
- package/dist/resources/store.js.map +1 -1
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +3 -2
- 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 +2 -1
- package/dist/scripts/chat/search-chats.js.map +1 -1
- package/dist/scripts/core-scripts.d.ts.map +1 -1
- package/dist/scripts/core-scripts.js +2 -0
- package/dist/scripts/core-scripts.js.map +1 -1
- package/dist/scripts/db/patch.d.ts.map +1 -1
- package/dist/scripts/db/patch.js +273 -11
- package/dist/scripts/db/patch.js.map +1 -1
- package/dist/scripts/db/scoping.d.ts.map +1 -1
- package/dist/scripts/db/scoping.js +3 -2
- package/dist/scripts/db/scoping.js.map +1 -1
- package/dist/scripts/docs/index.d.ts +2 -0
- package/dist/scripts/docs/index.d.ts.map +1 -0
- package/dist/scripts/docs/index.js +4 -0
- package/dist/scripts/docs/index.js.map +1 -0
- package/dist/scripts/docs/search.d.ts +13 -0
- package/dist/scripts/docs/search.d.ts.map +1 -0
- package/dist/scripts/docs/search.js +130 -0
- package/dist/scripts/docs/search.js.map +1 -0
- package/dist/scripts/resources/delete-memory.d.ts +7 -0
- package/dist/scripts/resources/delete-memory.d.ts.map +1 -0
- package/dist/scripts/resources/delete-memory.js +49 -0
- package/dist/scripts/resources/delete-memory.js.map +1 -0
- package/dist/scripts/resources/delete.d.ts.map +1 -1
- package/dist/scripts/resources/delete.js +2 -1
- package/dist/scripts/resources/delete.js.map +1 -1
- package/dist/scripts/resources/index.d.ts.map +1 -1
- package/dist/scripts/resources/index.js +2 -0
- package/dist/scripts/resources/index.js.map +1 -1
- package/dist/scripts/resources/list.d.ts.map +1 -1
- package/dist/scripts/resources/list.js +2 -1
- package/dist/scripts/resources/list.js.map +1 -1
- package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
- package/dist/scripts/resources/migrate-learnings.js +2 -1
- package/dist/scripts/resources/migrate-learnings.js.map +1 -1
- package/dist/scripts/resources/read.d.ts.map +1 -1
- package/dist/scripts/resources/read.js +2 -1
- package/dist/scripts/resources/read.js.map +1 -1
- package/dist/scripts/resources/save-memory.d.ts +9 -0
- package/dist/scripts/resources/save-memory.d.ts.map +1 -0
- package/dist/scripts/resources/save-memory.js +78 -0
- package/dist/scripts/resources/save-memory.js.map +1 -0
- package/dist/scripts/resources/write.d.ts.map +1 -1
- package/dist/scripts/resources/write.js +2 -1
- package/dist/scripts/resources/write.js.map +1 -1
- package/dist/scripts/utils.d.ts +10 -1
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +45 -2
- package/dist/scripts/utils.js.map +1 -1
- package/dist/server/action-discovery.d.ts +5 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +53 -20
- 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 +88 -56
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +15 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +853 -91
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +13 -25
- 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 +23 -59
- package/dist/server/agent-teams.js.map +1 -1
- package/dist/server/agents-bundle.d.ts +33 -5
- package/dist/server/agents-bundle.d.ts.map +1 -1
- package/dist/server/agents-bundle.js +108 -64
- package/dist/server/agents-bundle.js.map +1 -1
- package/dist/server/auth.d.ts +7 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +448 -93
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +1 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +272 -10
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +61 -0
- package/dist/server/builder-browser.d.ts.map +1 -0
- package/dist/server/builder-browser.js +229 -0
- package/dist/server/builder-browser.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +273 -9
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +37 -0
- package/dist/server/credential-provider.d.ts.map +1 -0
- package/dist/server/credential-provider.js +49 -0
- package/dist/server/credential-provider.js.map +1 -0
- package/dist/server/desktop-sso.d.ts +30 -0
- package/dist/server/desktop-sso.d.ts.map +1 -0
- package/dist/server/desktop-sso.js +74 -0
- package/dist/server/desktop-sso.js.map +1 -0
- package/dist/server/email.d.ts +23 -0
- package/dist/server/email.d.ts.map +1 -0
- package/dist/server/email.js +105 -0
- package/dist/server/email.js.map +1 -0
- package/dist/server/framework-request-handler.d.ts.map +1 -1
- package/dist/server/framework-request-handler.js +71 -3
- package/dist/server/framework-request-handler.js.map +1 -1
- package/dist/server/google-auth-plugin.js +1 -1
- package/dist/server/google-oauth.d.ts +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +34 -13
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/local-migration.d.ts +9 -0
- package/dist/server/local-migration.d.ts.map +1 -1
- package/dist/server/local-migration.js +44 -14
- package/dist/server/local-migration.js.map +1 -1
- package/dist/server/oauth-helpers.d.ts +3 -0
- package/dist/server/oauth-helpers.d.ts.map +1 -1
- package/dist/server/oauth-helpers.js +7 -4
- package/dist/server/oauth-helpers.js.map +1 -1
- package/dist/server/onboarding-html.d.ts +6 -0
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +323 -28
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +48 -0
- package/dist/server/poll.js.map +1 -1
- package/dist/server/request-context.d.ts +20 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +41 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/dist/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- package/dist/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/dist/templates/default/_gitignore +1 -0
- package/dist/templates/default/app/root.tsx +4 -1
- package/dist/templates/workspace-core/.agents/skills/company-policies/SKILL.md +42 -0
- package/dist/templates/workspace-core/AGENTS.md +62 -0
- package/dist/templates/workspace-core/actions/company-directory.ts +38 -0
- package/dist/templates/workspace-core/package.json +39 -0
- package/dist/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/dist/templates/workspace-core/src/client/index.ts +26 -0
- package/dist/templates/workspace-core/src/credentials.ts +29 -0
- package/dist/templates/workspace-core/src/index.ts +21 -0
- package/dist/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/dist/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/dist/templates/workspace-core/src/server/index.ts +22 -0
- package/dist/templates/workspace-core/tailwind.preset.ts +34 -0
- package/dist/templates/workspace-core/tsconfig.json +9 -0
- package/dist/templates/workspace-root/.env.example +37 -0
- package/dist/templates/workspace-root/README.md +62 -0
- package/dist/templates/workspace-root/_gitignore +23 -0
- package/dist/templates/workspace-root/package.json +18 -0
- package/dist/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/dist/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/usage/store.d.ts +74 -12
- package/dist/usage/store.d.ts.map +1 -1
- package/dist/usage/store.js +210 -44
- package/dist/usage/store.js.map +1 -1
- package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
- package/dist/vite/agents-bundle-plugin.js +65 -15
- package/dist/vite/agents-bundle-plugin.js.map +1 -1
- package/dist/vite/client.d.ts +16 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +130 -0
- package/dist/vite/client.js.map +1 -1
- package/docs/content/a2a-protocol.md +223 -0
- package/docs/content/actions.md +129 -0
- package/docs/content/agent-mentions.md +171 -0
- package/docs/content/authentication.md +155 -0
- package/docs/content/cli-adapters.md +244 -0
- package/docs/content/client.md +175 -0
- package/docs/content/context-awareness.md +168 -0
- package/docs/content/creating-templates.md +311 -0
- package/docs/content/database.md +82 -0
- package/docs/content/deployment.md +237 -0
- package/docs/content/enterprise-workspace.md +235 -0
- package/docs/content/faq.md +101 -0
- package/docs/content/file-uploads.md +102 -0
- package/docs/content/frames.md +47 -0
- package/docs/content/getting-started.md +104 -0
- package/docs/content/integrations.md +198 -0
- package/docs/content/key-concepts.md +246 -0
- package/docs/content/mcp-clients.md +110 -0
- package/docs/content/mcp-protocol.md +168 -0
- package/docs/content/onboarding.md +107 -0
- package/docs/content/real-time-collaboration.md +185 -0
- package/docs/content/resources.md +277 -0
- package/docs/content/security.md +158 -0
- package/docs/content/server.md +200 -0
- package/docs/content/skills-guide.md +107 -0
- package/docs/content/what-is-agent-native.md +100 -0
- package/docs/content/workspace-management.md +224 -0
- package/package.json +13 -3
- package/src/templates/default/.agents/skills/actions/SKILL.md +2 -1
- package/src/templates/default/.agents/skills/inline-embeds/SKILL.md +88 -0
- package/src/templates/default/.agents/skills/security/SKILL.md +145 -40
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +7 -1
- package/src/templates/default/_gitignore +1 -0
- package/src/templates/default/app/root.tsx +4 -1
- package/src/templates/workspace-core/.agents/skills/company-policies/SKILL.md +42 -0
- package/src/templates/workspace-core/AGENTS.md +62 -0
- package/src/templates/workspace-core/actions/company-directory.ts +38 -0
- package/src/templates/workspace-core/package.json +39 -0
- package/src/templates/workspace-core/src/client/AuthenticatedLayout.tsx +37 -0
- package/src/templates/workspace-core/src/client/index.ts +26 -0
- package/src/templates/workspace-core/src/credentials.ts +29 -0
- package/src/templates/workspace-core/src/index.ts +21 -0
- package/src/templates/workspace-core/src/server/agent-chat-plugin.ts +30 -0
- package/src/templates/workspace-core/src/server/auth-plugin.ts +35 -0
- package/src/templates/workspace-core/src/server/index.ts +22 -0
- package/src/templates/workspace-core/tailwind.preset.ts +34 -0
- package/src/templates/workspace-core/tsconfig.json +9 -0
- package/src/templates/workspace-root/.env.example +37 -0
- package/src/templates/workspace-root/README.md +62 -0
- package/src/templates/workspace-root/_gitignore +23 -0
- package/src/templates/workspace-root/package.json +18 -0
- package/src/templates/workspace-root/pnpm-workspace.yaml +3 -0
- package/src/templates/workspace-root/tsconfig.base.json +21 -0
- package/dist/templates/templates/default/.agents/skills/actions/SKILL.md +0 -142
- package/dist/templates/templates/default/.agents/skills/agent-engines/SKILL.md +0 -127
- package/dist/templates/templates/default/.agents/skills/capture-learnings/SKILL.md +0 -50
- package/dist/templates/templates/default/.agents/skills/create-skill/SKILL.md +0 -167
- package/dist/templates/templates/default/.agents/skills/delegate-to-agent/SKILL.md +0 -90
- package/dist/templates/templates/default/.agents/skills/frontend-design/SKILL.md +0 -69
- package/dist/templates/templates/default/.agents/skills/real-time-collab/SKILL.md +0 -183
- package/dist/templates/templates/default/.agents/skills/real-time-sync/SKILL.md +0 -112
- package/dist/templates/templates/default/.agents/skills/security/SKILL.md +0 -108
- package/dist/templates/templates/default/.agents/skills/self-modifying-code/SKILL.md +0 -79
- package/dist/templates/templates/default/.agents/skills/storing-data/SKILL.md +0 -110
- package/dist/templates/templates/default/.claude/settings.json +0 -100
- package/dist/templates/templates/default/.env.example +0 -5
- package/dist/templates/templates/default/.ignore +0 -0
- package/dist/templates/templates/default/.prettierrc +0 -5
- package/dist/templates/templates/default/AGENTS.md +0 -110
- package/dist/templates/templates/default/DEVELOPING.md +0 -117
- package/dist/templates/templates/default/_gitignore +0 -37
- package/dist/templates/templates/default/actions/hello.ts +0 -20
- package/dist/templates/templates/default/actions/navigate.ts +0 -53
- package/dist/templates/templates/default/actions/run.ts +0 -2
- package/dist/templates/templates/default/actions/view-screen.ts +0 -39
- package/dist/templates/templates/default/app/entry.client.tsx +0 -4
- package/dist/templates/templates/default/app/entry.server.tsx +0 -56
- package/dist/templates/templates/default/app/global.css +0 -95
- package/dist/templates/templates/default/app/lib/utils.ts +0 -1
- package/dist/templates/templates/default/app/root.tsx +0 -107
- package/dist/templates/templates/default/app/routes/_index.tsx +0 -62
- package/dist/templates/templates/default/app/routes.ts +0 -4
- package/dist/templates/templates/default/app/vite-env.d.ts +0 -6
- package/dist/templates/templates/default/components.json +0 -20
- package/dist/templates/templates/default/data/.gitkeep +0 -0
- package/dist/templates/templates/default/data/sync-config.json +0 -1
- package/dist/templates/templates/default/learnings.defaults.md +0 -5
- package/dist/templates/templates/default/learnings.md +0 -0
- package/dist/templates/templates/default/package.json +0 -46
- package/dist/templates/templates/default/postcss.config.js +0 -6
- package/dist/templates/templates/default/public/icon-180.svg +0 -4
- package/dist/templates/templates/default/public/icon-192.svg +0 -4
- package/dist/templates/templates/default/public/icon-512.svg +0 -4
- package/dist/templates/templates/default/public/manifest.json +0 -13
- package/dist/templates/templates/default/react-router.config.ts +0 -6
- package/dist/templates/templates/default/server/middleware/auth.ts +0 -15
- package/dist/templates/templates/default/server/plugins/.gitkeep +0 -0
- package/dist/templates/templates/default/server/routes/[...page].get.ts +0 -5
- package/dist/templates/templates/default/server/routes/api/hello.get.ts +0 -5
- package/dist/templates/templates/default/shared/api.ts +0 -6
- package/dist/templates/templates/default/ssr-entry.ts +0 -20
- package/dist/templates/templates/default/tailwind.config.ts +0 -7
- package/dist/templates/templates/default/tsconfig.json +0 -11
- package/dist/templates/templates/default/vite.config.ts +0 -6
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import { runWithRequestContext, getRequestOrgId } from "./request-context.js";
|
|
2
|
+
import { getSetting, putSetting } from "../settings/store.js";
|
|
1
3
|
import { getH3App } from "./framework-request-handler.js";
|
|
2
4
|
import { createProductionAgentHandler, runAgentLoop, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, } from "../agent/production-agent.js";
|
|
3
5
|
import { resolveEngine, createAnthropicEngine } from "../agent/engine/index.js";
|
|
6
|
+
import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, } from "../mcp-client/index.js";
|
|
4
7
|
import { discoverAgents } from "./agent-discovery.js";
|
|
5
8
|
import { loadSchemaPromptBlock } from "./schema-prompt.js";
|
|
6
9
|
import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-builder.js";
|
|
7
10
|
import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, } from "h3";
|
|
8
11
|
import { getSession } from "./auth.js";
|
|
12
|
+
import { getOrigin } from "./google-oauth.js";
|
|
9
13
|
import { createThread, getThread, listThreads, searchThreads, updateThreadData, deleteThread, } from "../chat-threads/store.js";
|
|
10
14
|
import { resourceListAccessible, resourceList, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, } from "../resources/store.js";
|
|
11
15
|
import nodePath from "node:path";
|
|
12
16
|
import { readBody } from "./h3-helpers.js";
|
|
17
|
+
import { getBuilderBrowserConnectUrl, requestBuilderBrowserConnection, } from "./builder-browser.js";
|
|
13
18
|
// Lazy fs — loaded via dynamic import() on first use.
|
|
14
19
|
// This avoids require() which bundlers convert to createRequire(import.meta.url)
|
|
15
20
|
// that crashes on CF Workers where import.meta.url is undefined.
|
|
@@ -24,9 +29,10 @@ async function lazyFs() {
|
|
|
24
29
|
* Wraps a core CLI script (that writes to console.log) as a ActionEntry
|
|
25
30
|
* by capturing stdout.
|
|
26
31
|
*/
|
|
27
|
-
function wrapCliScript(tool, cliDefault) {
|
|
32
|
+
function wrapCliScript(tool, cliDefault, opts) {
|
|
28
33
|
return {
|
|
29
34
|
tool,
|
|
35
|
+
...(opts?.readOnly ? { readOnly: true } : {}),
|
|
30
36
|
run: async (args) => {
|
|
31
37
|
const cliArgs = [];
|
|
32
38
|
for (const [k, v] of Object.entries(args)) {
|
|
@@ -68,16 +74,301 @@ function wrapCliScript(tool, cliDefault) {
|
|
|
68
74
|
},
|
|
69
75
|
};
|
|
70
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Creates the `refresh-screen` tool. Writes a bump to `application_state`
|
|
79
|
+
* under a well-known key; the client's `useDbSync` watches for this and
|
|
80
|
+
* invalidates react-query caches so the on-screen UI re-fetches its data
|
|
81
|
+
* without a full page reload.
|
|
82
|
+
*
|
|
83
|
+
* This is the standard way for the agent to say "the data on the screen
|
|
84
|
+
* just changed, please refresh it" — e.g. after editing a dashboard config,
|
|
85
|
+
* updating a form schema, or mutating a row that the current view renders.
|
|
86
|
+
*/
|
|
87
|
+
function createRefreshScreenEntry() {
|
|
88
|
+
return {
|
|
89
|
+
"refresh-screen": {
|
|
90
|
+
// Writes __screen_refresh__ to application_state, which emits its own
|
|
91
|
+
// distinct `screen-refresh` poll event. Don't double-emit a generic
|
|
92
|
+
// `action` event on top of that.
|
|
93
|
+
readOnly: true,
|
|
94
|
+
tool: {
|
|
95
|
+
description: "Manually refresh the user's current screen. The framework ALREADY auto-refreshes after any successful mutating action tool call (template actions, db-exec, db-patch) — you do NOT need to call this after a normal action. Use it only when (a) you mutated data via a path the framework can't detect (e.g. a direct write to an external system the app mirrors), or (b) you want to pass a `scope` hint so the UI narrows which queries to refetch. The UI re-fetches its queries without a full page reload.",
|
|
96
|
+
parameters: {
|
|
97
|
+
type: "object",
|
|
98
|
+
properties: {
|
|
99
|
+
scope: {
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "Optional hint describing what changed (e.g. 'dashboard', 'form', 'settings'). Templates may use it to narrow which queries to invalidate; if omitted, all queries are invalidated.",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
run: async (args) => {
|
|
107
|
+
const { writeAppState } = await import("../application-state/script-helpers.js");
|
|
108
|
+
const nonce = Date.now();
|
|
109
|
+
const scope = typeof args?.scope === "string" ? args.scope : undefined;
|
|
110
|
+
await writeAppState(SCREEN_REFRESH_KEY, {
|
|
111
|
+
nonce,
|
|
112
|
+
...(scope ? { scope } : {}),
|
|
113
|
+
});
|
|
114
|
+
return `refreshed${scope ? ` (scope: ${scope})` : ""}`;
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Well-known application-state key used by the refresh-screen tool. */
|
|
120
|
+
const SCREEN_REFRESH_KEY = "__screen_refresh__";
|
|
121
|
+
/**
|
|
122
|
+
* Creates the `set-search-params` / `set-url-path` tools. Writes a one-shot
|
|
123
|
+
* URL command to application_state; the client's URLSync component applies
|
|
124
|
+
* it via react-router (no full page reload) and then deletes the command.
|
|
125
|
+
*
|
|
126
|
+
* This is how the agent edits URL state — filter query params, route
|
|
127
|
+
* changes, hash — without needing a per-template navigate action. The
|
|
128
|
+
* current URL is visible to the agent via the auto-injected `<current-url>`
|
|
129
|
+
* block, which includes parsed search params.
|
|
130
|
+
*/
|
|
131
|
+
function createUrlTools() {
|
|
132
|
+
return {
|
|
133
|
+
"set-search-params": {
|
|
134
|
+
// Writes __set_url__ to application_state, which the app-state watcher
|
|
135
|
+
// already surfaces as a poll event. No need to double-emit.
|
|
136
|
+
readOnly: true,
|
|
137
|
+
tool: {
|
|
138
|
+
description: "Update the URL query string on the user's current page. Use this to change dashboard/list filters, search terms, or any other state the app stores in `?foo=bar` style query params. One-shot — the UI applies it in ~1s without a page reload. See the current URL + parsed search params in the auto-injected `<current-url>` block. Keys are the exact query param names as they appear in the URL (e.g. `f_pubDateStart`, not just `pubDateStart`). Set a value to null or empty string to clear that param. By default merges over existing params — pass `merge: false` to replace them all.",
|
|
139
|
+
parameters: {
|
|
140
|
+
type: "object",
|
|
141
|
+
properties: {
|
|
142
|
+
params: {
|
|
143
|
+
type: "object",
|
|
144
|
+
description: 'Map of query param → value. Each value is a string, or null/"" to clear. Example: {"f_pubDateStart": null, "f_cadence": "MONTH"}.',
|
|
145
|
+
},
|
|
146
|
+
merge: {
|
|
147
|
+
type: "string",
|
|
148
|
+
description: '"true" (default) merges over existing params; "false" replaces them entirely.',
|
|
149
|
+
enum: ["true", "false"],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: ["params"],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
run: async (args) => {
|
|
156
|
+
const params = (args?.params ?? {});
|
|
157
|
+
const merge = args?.merge !== "false";
|
|
158
|
+
const { writeAppState } = await import("../application-state/script-helpers.js");
|
|
159
|
+
await writeAppState("__set_url__", {
|
|
160
|
+
searchParams: params,
|
|
161
|
+
mergeSearchParams: merge,
|
|
162
|
+
});
|
|
163
|
+
const keys = Object.keys(params);
|
|
164
|
+
return `set-search-params: ${keys.length} key${keys.length === 1 ? "" : "s"}${merge ? "" : " (replace)"}`;
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
"set-url-path": {
|
|
168
|
+
// Same as set-search-params — writes application_state, already emits
|
|
169
|
+
// via the app-state watcher.
|
|
170
|
+
readOnly: true,
|
|
171
|
+
tool: {
|
|
172
|
+
description: "Navigate the user to a different pathname, optionally also setting search params. For most template-specific routing prefer the template's `navigate` action if it exists — this is the generic fallback. One-shot, applied by the client without a page reload.",
|
|
173
|
+
parameters: {
|
|
174
|
+
type: "object",
|
|
175
|
+
properties: {
|
|
176
|
+
pathname: {
|
|
177
|
+
type: "string",
|
|
178
|
+
description: "New URL pathname (e.g. '/adhoc/weekly').",
|
|
179
|
+
},
|
|
180
|
+
params: {
|
|
181
|
+
type: "object",
|
|
182
|
+
description: 'Optional query params to set alongside the path change. String values set, null/"" clears.',
|
|
183
|
+
},
|
|
184
|
+
merge: {
|
|
185
|
+
type: "string",
|
|
186
|
+
description: '"true" (default) merges over existing params; "false" starts fresh.',
|
|
187
|
+
enum: ["true", "false"],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
required: ["pathname"],
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
run: async (args) => {
|
|
194
|
+
const pathname = String(args?.pathname ?? "");
|
|
195
|
+
if (!pathname.startsWith("/")) {
|
|
196
|
+
return "Error: pathname must start with '/'.";
|
|
197
|
+
}
|
|
198
|
+
const params = (args?.params ?? {});
|
|
199
|
+
const merge = args?.merge !== "false";
|
|
200
|
+
const { writeAppState } = await import("../application-state/script-helpers.js");
|
|
201
|
+
await writeAppState("__set_url__", {
|
|
202
|
+
pathname,
|
|
203
|
+
searchParams: params,
|
|
204
|
+
mergeSearchParams: merge,
|
|
205
|
+
});
|
|
206
|
+
return `set-url-path: ${pathname}`;
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Creates db-* tools (db-query, db-exec, db-patch, db-schema) as native tools.
|
|
213
|
+
* These let the agent read and write the app's own SQL database. Scoping to
|
|
214
|
+
* the current user/org is enforced automatically in production via temp views.
|
|
215
|
+
*
|
|
216
|
+
* In dev mode template actions are invoked via shell and the agent can call
|
|
217
|
+
* `pnpm action db-query ...` — but in production there is no shell, so these
|
|
218
|
+
* must be registered as native tools for the agent to reach the app DB at all.
|
|
219
|
+
*/
|
|
220
|
+
async function createDbScriptEntries() {
|
|
221
|
+
try {
|
|
222
|
+
const [schemaMod, queryMod, execMod, patchMod] = await Promise.all([
|
|
223
|
+
import("../scripts/db/schema.js"),
|
|
224
|
+
import("../scripts/db/query.js"),
|
|
225
|
+
import("../scripts/db/exec.js"),
|
|
226
|
+
import("../scripts/db/patch.js"),
|
|
227
|
+
]);
|
|
228
|
+
return {
|
|
229
|
+
"db-schema": wrapCliScript({
|
|
230
|
+
description: "Show the app's SQL schema — all tables, columns, types, indexes, and foreign keys. Use this to understand the data model before querying.",
|
|
231
|
+
parameters: {
|
|
232
|
+
type: "object",
|
|
233
|
+
properties: {
|
|
234
|
+
format: {
|
|
235
|
+
type: "string",
|
|
236
|
+
description: 'Output format: "json" or "text" (default: text)',
|
|
237
|
+
enum: ["json", "text"],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
}, schemaMod.default, { readOnly: true }),
|
|
242
|
+
"db-query": wrapCliScript({
|
|
243
|
+
description: "Read from the app's SQL database. Runs a SELECT (or WITH/EXPLAIN/PRAGMA) against the app's own tables — settings, application_state, and all template tables. Results are automatically scoped to the current user/org; DO NOT add `WHERE owner_email = ...` yourself. This queries the APP DATABASE — not any external data source.",
|
|
244
|
+
parameters: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
sql: {
|
|
248
|
+
type: "string",
|
|
249
|
+
description: "SELECT query to run, e.g. \"SELECT key, value FROM settings WHERE key LIKE 'sql-dashboard-%'\"",
|
|
250
|
+
},
|
|
251
|
+
format: {
|
|
252
|
+
type: "string",
|
|
253
|
+
description: 'Output format: "json" or "text" (default: text)',
|
|
254
|
+
enum: ["json", "text"],
|
|
255
|
+
},
|
|
256
|
+
limit: {
|
|
257
|
+
type: "string",
|
|
258
|
+
description: "Append LIMIT N if the query doesn't already have one",
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
required: ["sql"],
|
|
262
|
+
},
|
|
263
|
+
}, queryMod.default, { readOnly: true }),
|
|
264
|
+
"db-exec": wrapCliScript({
|
|
265
|
+
description: "Write to the app's SQL database. Runs INSERT / UPDATE / DELETE against the app's own tables. Writes are automatically scoped to the current user/org, and `owner_email` / `org_id` are auto-injected on INSERT. Use this to update rows in the settings table (e.g. edit a dashboard config stored under `o:<orgId>:sql-dashboard-<id>`). This writes to the APP DATABASE — not any external data source.",
|
|
266
|
+
parameters: {
|
|
267
|
+
type: "object",
|
|
268
|
+
properties: {
|
|
269
|
+
sql: {
|
|
270
|
+
type: "string",
|
|
271
|
+
description: "INSERT / UPDATE / DELETE statement. Use parameterized placeholders (?) if possible.",
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
required: ["sql"],
|
|
275
|
+
},
|
|
276
|
+
}, execMod.default),
|
|
277
|
+
"db-patch": wrapCliScript({
|
|
278
|
+
description: "Surgical patch on a large text/JSON column in the app's SQL database. Two modes: (1) text find/replace via `find`/`replace`/`edits` — best for small edits to documents, slide HTML, etc. (2) structural JSON ops via `json-ops` — STRONGLY PREFERRED when the column is JSON (dashboard configs, form schemas, slide decks) because it avoids all the brace/quote/comma surgery that text find/replace requires. Use `json-ops` to set/remove values at a JSON Pointer path, or to move/insert array items — e.g. reorder dashboard panels, add a filter, rename a field. Targets exactly one row (narrow `where` by primary key). Same per-user/org scoping as db-exec.",
|
|
279
|
+
parameters: {
|
|
280
|
+
type: "object",
|
|
281
|
+
properties: {
|
|
282
|
+
table: {
|
|
283
|
+
type: "string",
|
|
284
|
+
description: "Table name (e.g. 'settings')",
|
|
285
|
+
},
|
|
286
|
+
column: {
|
|
287
|
+
type: "string",
|
|
288
|
+
description: "Text/JSON column to patch (e.g. 'value' for settings)",
|
|
289
|
+
},
|
|
290
|
+
where: {
|
|
291
|
+
type: "string",
|
|
292
|
+
description: "WHERE clause that matches exactly one row (e.g. \"key = 'o:org1:sql-dashboard-foo'\")",
|
|
293
|
+
},
|
|
294
|
+
find: {
|
|
295
|
+
type: "string",
|
|
296
|
+
description: "Text mode: substring to find. Must match EXACTLY ONE occurrence by default (like Claude Code's Edit tool). If 0 matches, you get 'NOT FOUND'. If >1 matches, you get surrounding context for each match — widen `find` with unique context and retry. Use `all: \"true\"` to replace every occurrence.",
|
|
297
|
+
},
|
|
298
|
+
replace: {
|
|
299
|
+
type: "string",
|
|
300
|
+
description: "Text mode: replacement substring",
|
|
301
|
+
},
|
|
302
|
+
edits: {
|
|
303
|
+
type: "string",
|
|
304
|
+
description: 'Text mode batch: JSON array of {find, replace} pairs. Same uniqueness rule applies to each `find`. Example: \'[{"find":"a","replace":"b"}]\'',
|
|
305
|
+
},
|
|
306
|
+
"json-ops": {
|
|
307
|
+
type: "string",
|
|
308
|
+
description: 'JSON mode: JSON array of structural ops. Each op is {op, path, value?, from?}. `op` is one of "set", "remove", "insert", "move", "move-before". `path` / `from` use JSON Pointer ("/panels/3/title"). Examples — reorder: \'[{"op":"move","from":"/panels/7","path":"/panels/1"}]\'; edit field: \'[{"op":"set","path":"/panels/0/title","value":"New"}]\'; delete filter: \'[{"op":"remove","path":"/filters/2"}]\'; add panel: \'[{"op":"insert","path":"/panels/0","value":{"id":"p","title":"..."}}]\'. Much safer than text find/replace for JSON columns.',
|
|
309
|
+
},
|
|
310
|
+
all: {
|
|
311
|
+
type: "string",
|
|
312
|
+
description: 'Text mode: set to "true" to replace every occurrence of each `find` (default requires exactly one match)',
|
|
313
|
+
enum: ["true"],
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
required: ["table", "column", "where"],
|
|
317
|
+
},
|
|
318
|
+
}, patchMod.default),
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
return {};
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Creates the docs-search tool so agents can look up framework documentation.
|
|
327
|
+
* Docs are bundled in @agent-native/core and read via fs at runtime.
|
|
328
|
+
*/
|
|
329
|
+
async function createDocsScriptEntries() {
|
|
330
|
+
try {
|
|
331
|
+
const mod = await import("../scripts/docs/search.js");
|
|
332
|
+
return {
|
|
333
|
+
"docs-search": wrapCliScript({
|
|
334
|
+
description: "Search and read agent-native framework documentation. Use --list to see all pages, --query to search, --slug to read a specific page.",
|
|
335
|
+
parameters: {
|
|
336
|
+
type: "object",
|
|
337
|
+
properties: {
|
|
338
|
+
query: {
|
|
339
|
+
type: "string",
|
|
340
|
+
description: "Search term to find relevant docs (e.g. 'actions', 'authentication', 'database')",
|
|
341
|
+
},
|
|
342
|
+
slug: {
|
|
343
|
+
type: "string",
|
|
344
|
+
description: "Read a specific doc page by slug (e.g. 'actions', 'authentication', 'database')",
|
|
345
|
+
},
|
|
346
|
+
list: {
|
|
347
|
+
type: "string",
|
|
348
|
+
description: 'Set to "true" to list all available doc pages',
|
|
349
|
+
enum: ["true"],
|
|
350
|
+
},
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
}, mod.default, { readOnly: true }),
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return {};
|
|
358
|
+
}
|
|
359
|
+
}
|
|
71
360
|
/**
|
|
72
361
|
* Creates resource ScriptEntries available in both prod and dev modes.
|
|
73
362
|
*/
|
|
74
363
|
async function createResourceScriptEntries() {
|
|
75
364
|
try {
|
|
76
|
-
const [list, read, write, del] = await Promise.all([
|
|
365
|
+
const [list, read, write, del, saveMem, delMem] = await Promise.all([
|
|
77
366
|
import("../scripts/resources/list.js"),
|
|
78
367
|
import("../scripts/resources/read.js"),
|
|
79
368
|
import("../scripts/resources/write.js"),
|
|
80
369
|
import("../scripts/resources/delete.js"),
|
|
370
|
+
import("../scripts/resources/save-memory.js"),
|
|
371
|
+
import("../scripts/resources/delete-memory.js"),
|
|
81
372
|
]);
|
|
82
373
|
return {
|
|
83
374
|
"resource-list": wrapCliScript({
|
|
@@ -164,6 +455,45 @@ async function createResourceScriptEntries() {
|
|
|
164
455
|
required: ["path"],
|
|
165
456
|
},
|
|
166
457
|
}, del.default),
|
|
458
|
+
"save-memory": wrapCliScript({
|
|
459
|
+
description: "Save a memory for future conversations. Creates or updates a memory file and its index entry. Use proactively when you learn preferences, corrections, project context, or references.",
|
|
460
|
+
parameters: {
|
|
461
|
+
type: "object",
|
|
462
|
+
properties: {
|
|
463
|
+
name: {
|
|
464
|
+
type: "string",
|
|
465
|
+
description: "Short kebab-case identifier (e.g. 'coding-style', 'deploy-process'). Used as the filename.",
|
|
466
|
+
},
|
|
467
|
+
type: {
|
|
468
|
+
type: "string",
|
|
469
|
+
description: "Memory category",
|
|
470
|
+
enum: ["user", "feedback", "project", "reference"],
|
|
471
|
+
},
|
|
472
|
+
description: {
|
|
473
|
+
type: "string",
|
|
474
|
+
description: "One-line summary shown in the memory index (keep under 80 chars)",
|
|
475
|
+
},
|
|
476
|
+
content: {
|
|
477
|
+
type: "string",
|
|
478
|
+
description: "The memory content in markdown. For updates, read first and provide full updated content.",
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
required: ["name", "type", "description", "content"],
|
|
482
|
+
},
|
|
483
|
+
}, saveMem.default),
|
|
484
|
+
"delete-memory": wrapCliScript({
|
|
485
|
+
description: "Delete a memory entry and remove it from the memory index.",
|
|
486
|
+
parameters: {
|
|
487
|
+
type: "object",
|
|
488
|
+
properties: {
|
|
489
|
+
name: {
|
|
490
|
+
type: "string",
|
|
491
|
+
description: "The memory name to delete (e.g. 'coding-style')",
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
required: ["name"],
|
|
495
|
+
},
|
|
496
|
+
}, delMem.default),
|
|
167
497
|
};
|
|
168
498
|
}
|
|
169
499
|
catch {
|
|
@@ -260,6 +590,94 @@ async function createCallAgentScriptEntry(selfAppId) {
|
|
|
260
590
|
return {};
|
|
261
591
|
}
|
|
262
592
|
}
|
|
593
|
+
function createBuilderBrowserTool(deps) {
|
|
594
|
+
return {
|
|
595
|
+
"connect-builder": {
|
|
596
|
+
tool: {
|
|
597
|
+
description: "Render a Builder.io card inline in the chat. Call this IMMEDIATELY — no exploration, no planning — whenever (a) the user asks to add a feature, change the UI, edit code, create a component, add a route, add an integration, fix a bug in the app itself, or anything else that requires source-file edits while in hosted/production mode, OR (b) the user needs Builder for LLM access, browser automation, or any other Builder-gated capability. If Builder is already connected, the card shows a 'Send to Builder' button that hands the work off to Builder's cloud agent and returns a branch URL. When you call this for a code-change request, pass the user's request verbatim as the `prompt` arg so the card can forward it to Builder unchanged.",
|
|
598
|
+
parameters: {
|
|
599
|
+
type: "object",
|
|
600
|
+
properties: {
|
|
601
|
+
prompt: {
|
|
602
|
+
type: "string",
|
|
603
|
+
description: "The user's feature / change request, verbatim. Forwarded to Builder's cloud agent when the user clicks Send. Omit only for generic 'connect Builder' requests that aren't tied to a specific code change.",
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
run: async (args) => {
|
|
609
|
+
const configured = !!(process.env.BUILDER_PRIVATE_KEY && process.env.BUILDER_PUBLIC_KEY);
|
|
610
|
+
const prompt = typeof args?.prompt === "string" ? args.prompt : "";
|
|
611
|
+
return JSON.stringify({
|
|
612
|
+
kind: "connect-builder-card",
|
|
613
|
+
configured,
|
|
614
|
+
builderEnabled: !!process.env.ENABLE_BUILDER,
|
|
615
|
+
connectUrl: getBuilderBrowserConnectUrl(deps.getOrigin()),
|
|
616
|
+
orgName: process.env.BUILDER_ORG_NAME || null,
|
|
617
|
+
prompt,
|
|
618
|
+
});
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
"get-browser-connection": {
|
|
622
|
+
tool: {
|
|
623
|
+
description: "Provision a Builder-backed browser session and return browser websocket connection details. If Builder browser access is not configured yet, this returns setup guidance instead.",
|
|
624
|
+
parameters: {
|
|
625
|
+
type: "object",
|
|
626
|
+
properties: {
|
|
627
|
+
sessionId: {
|
|
628
|
+
type: "string",
|
|
629
|
+
description: "Stable browser session identifier. Reuse it to reconnect to the same browser session.",
|
|
630
|
+
},
|
|
631
|
+
projectId: {
|
|
632
|
+
type: "string",
|
|
633
|
+
description: "Optional Builder project or space identifier to scope the session.",
|
|
634
|
+
},
|
|
635
|
+
branchName: {
|
|
636
|
+
type: "string",
|
|
637
|
+
description: "Optional branch name for Builder preview sessions.",
|
|
638
|
+
},
|
|
639
|
+
proxyOrigin: {
|
|
640
|
+
type: "string",
|
|
641
|
+
description: "Optional source origin to proxy from when browsing a local app.",
|
|
642
|
+
},
|
|
643
|
+
proxyDefaultOrigin: {
|
|
644
|
+
type: "string",
|
|
645
|
+
description: "Optional default origin that the browser should use for proxied requests.",
|
|
646
|
+
},
|
|
647
|
+
proxyDestination: {
|
|
648
|
+
type: "string",
|
|
649
|
+
description: "Optional destination origin for proxying local development traffic.",
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
required: ["sessionId"],
|
|
653
|
+
},
|
|
654
|
+
},
|
|
655
|
+
run: async (args) => {
|
|
656
|
+
if (!process.env.BUILDER_PRIVATE_KEY ||
|
|
657
|
+
!process.env.BUILDER_PUBLIC_KEY) {
|
|
658
|
+
return JSON.stringify({
|
|
659
|
+
configured: false,
|
|
660
|
+
message: "Builder browser access is not configured. Connect Builder from the workspace Resources panel before requesting a browser session.",
|
|
661
|
+
connectUrl: getBuilderBrowserConnectUrl(deps.getOrigin()),
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
const connection = await requestBuilderBrowserConnection({
|
|
665
|
+
sessionId: args.sessionId,
|
|
666
|
+
projectId: args.projectId,
|
|
667
|
+
branchName: args.branchName,
|
|
668
|
+
proxyOrigin: args.proxyOrigin,
|
|
669
|
+
proxyDefaultOrigin: args.proxyDefaultOrigin,
|
|
670
|
+
proxyDestination: args.proxyDestination,
|
|
671
|
+
});
|
|
672
|
+
return JSON.stringify({
|
|
673
|
+
configured: true,
|
|
674
|
+
sessionId: args.sessionId,
|
|
675
|
+
...connection,
|
|
676
|
+
});
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
};
|
|
680
|
+
}
|
|
263
681
|
/**
|
|
264
682
|
* Creates agent team orchestration tools (spawn-task, task-status, read-task-result).
|
|
265
683
|
* These let the main agent spawn sub-agents and coordinate work.
|
|
@@ -284,6 +702,10 @@ function createTeamTools(deps) {
|
|
|
284
702
|
type: "string",
|
|
285
703
|
description: "Short name for the sub-agent tab (e.g. 'Research', 'Draft email'). If omitted, derived from the task.",
|
|
286
704
|
},
|
|
705
|
+
agent: {
|
|
706
|
+
type: "string",
|
|
707
|
+
description: "Optional custom agent profile from agents/*.md to use for this task.",
|
|
708
|
+
},
|
|
287
709
|
},
|
|
288
710
|
required: ["task"],
|
|
289
711
|
},
|
|
@@ -302,14 +724,32 @@ function createTeamTools(deps) {
|
|
|
302
724
|
"list-tasks",
|
|
303
725
|
]);
|
|
304
726
|
const subAgentActions = Object.fromEntries(Object.entries(deps.getActions()).filter(([name]) => !teamToolNames.has(name)));
|
|
727
|
+
let instructions = args.instructions;
|
|
728
|
+
let selectedModel = deps.getModel();
|
|
729
|
+
let selectedName = args.name || "";
|
|
730
|
+
if (args.agent) {
|
|
731
|
+
const { findAccessibleCustomAgent } = await import("../resources/agents.js");
|
|
732
|
+
const profile = await findAccessibleCustomAgent(deps.getOwner(), args.agent);
|
|
733
|
+
if (!profile) {
|
|
734
|
+
throw new Error(`Custom agent not found: ${args.agent}`);
|
|
735
|
+
}
|
|
736
|
+
const profileInstructions = `## Custom Agent Profile: ${profile.name}\n\n` +
|
|
737
|
+
(profile.description ? `${profile.description}\n\n` : "") +
|
|
738
|
+
profile.instructions;
|
|
739
|
+
instructions = instructions
|
|
740
|
+
? `${profileInstructions}\n\n## Extra Task Context\n\n${instructions}`
|
|
741
|
+
: profileInstructions;
|
|
742
|
+
selectedModel = profile.model ?? selectedModel;
|
|
743
|
+
selectedName = selectedName || profile.name;
|
|
744
|
+
}
|
|
305
745
|
const task = await spawnTask({
|
|
306
746
|
description: args.task,
|
|
307
|
-
instructions
|
|
747
|
+
instructions,
|
|
308
748
|
ownerEmail: deps.getOwner(),
|
|
309
749
|
systemPrompt: deps.getSystemPrompt(),
|
|
310
750
|
actions: subAgentActions,
|
|
311
751
|
engine: deps.getEngine(),
|
|
312
|
-
model:
|
|
752
|
+
model: selectedModel,
|
|
313
753
|
parentThreadId: deps.getParentThreadId(),
|
|
314
754
|
parentSend: (event) => {
|
|
315
755
|
if (capturedSend)
|
|
@@ -321,7 +761,7 @@ function createTeamTools(deps) {
|
|
|
321
761
|
threadId: task.threadId,
|
|
322
762
|
status: task.status,
|
|
323
763
|
description: task.description,
|
|
324
|
-
name:
|
|
764
|
+
name: selectedName,
|
|
325
765
|
});
|
|
326
766
|
},
|
|
327
767
|
},
|
|
@@ -452,24 +892,56 @@ const FRAMEWORK_CORE = `
|
|
|
452
892
|
### Core Rules
|
|
453
893
|
|
|
454
894
|
1. **Data lives in SQL** — All app state is in a SQL database (could be SQLite, Postgres, Turso, or Cloudflare D1 — never assume which). Use the available database tools.
|
|
455
|
-
2. **Context awareness** — The user's current screen state is automatically included in each message as a \`<current-screen>\` block. Use
|
|
895
|
+
2. **Context awareness** — The user's current screen state is automatically included in each message as a \`<current-screen>\` block, and the current URL (path + search params) as a \`<current-url>\` block. Use both to understand what the user is looking at — filters, search terms, and other URL-driven state live in \`<current-url>\`'s \`searchParams\`, NOT in the settings table. To change URL state (e.g. toggle a filter, clear a query string), use the \`set-search-params\` or \`set-url-path\` tools — never try to edit URL state by writing to settings or application_state directly.
|
|
456
896
|
3. **Navigate the UI** — Use the \`navigate\` tool to switch views, open items, or focus elements for the user.
|
|
457
897
|
4. **Application state** — Ephemeral UI state (drafts, selections, navigation) lives in \`application_state\`. Use \`readAppState\`/\`writeAppState\` to read and write it. When you write state, the UI updates automatically.
|
|
458
|
-
5. **
|
|
898
|
+
5. **Screen refresh is automatic after action calls** — The framework auto-emits a refresh event after any successful mutating tool call (template actions like \`log-meal\`, \`update-form\`, \`edit-document\`, and the \`db-exec\` / \`db-patch\` tools). The UI re-fetches its queries without a full page reload. You do NOT need to call \`refresh-screen\` after an action — it's already handled. Only call \`refresh-screen\` explicitly when (a) you mutated data via a path the framework can't detect (e.g. writing directly to an external system whose results the app mirrors), or (b) you want to pass a \`scope\` hint so the UI narrows which queries to refetch. Do NOT tell the user to reload the page.
|
|
899
|
+
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.
|
|
900
|
+
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\`.
|
|
459
901
|
|
|
460
902
|
### Resources
|
|
461
903
|
|
|
462
|
-
You have access to a Resources system for persistent notes
|
|
904
|
+
You have access to a Resources system for persistent notes and context files.
|
|
463
905
|
Use resource-list, resource-read, resource-write, and resource-delete to manage resources.
|
|
464
906
|
Resources can be personal (per-user) or shared (team-wide). By default, resources are personal.
|
|
465
907
|
|
|
466
|
-
When
|
|
467
|
-
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource instead.
|
|
908
|
+
When the user gives instructions that should apply to all users/sessions, update the shared "AGENTS.md" resource.
|
|
468
909
|
|
|
469
910
|
### Navigation Rule
|
|
470
911
|
|
|
471
912
|
When the user says "show me", "go to", "open", "switch to", or similar navigation language, ALWAYS use the \`navigate\` action to update the UI. The user expects to SEE the result in the main app, not just read it in chat. Navigate first, then fetch/display data.
|
|
472
913
|
|
|
914
|
+
### Inline Embeds
|
|
915
|
+
|
|
916
|
+
You can embed an interactive view inline in your chat reply by writing an \`embed\` fenced code block. The chat renderer swaps the fence for a sandboxed iframe pointing at a route inside this app.
|
|
917
|
+
|
|
918
|
+
Syntax:
|
|
919
|
+
|
|
920
|
+
\`\`\`\`
|
|
921
|
+
\`\`\`embed
|
|
922
|
+
src: /some/path?param=value
|
|
923
|
+
aspect: 16/9
|
|
924
|
+
title: Optional label
|
|
925
|
+
\`\`\`
|
|
926
|
+
\`\`\`\`
|
|
927
|
+
|
|
928
|
+
Keys:
|
|
929
|
+
- \`src\` (required) — **must be a same-origin path starting with \`/\`**. Cross-origin URLs are blocked by the renderer. No \`javascript:\` or \`data:\` URLs.
|
|
930
|
+
- \`aspect\` (optional) — one of \`16/9\` (default), \`4/3\`, \`3/2\`, \`2/1\`, \`21/9\`, \`1/1\`.
|
|
931
|
+
- \`title\` (optional) — accessible label / hover tooltip.
|
|
932
|
+
- \`height\` (optional) — fixed pixel height when aspect ratio isn't a good fit.
|
|
933
|
+
|
|
934
|
+
**When to reach for it:**
|
|
935
|
+
- Showing a chart, visualization, or map that benefits from being live/interactive.
|
|
936
|
+
- Previewing a specific item (a thread, a doc, a record) inline with your explanation.
|
|
937
|
+
- Anything where a screenshot-sized static image would undersell the result.
|
|
938
|
+
|
|
939
|
+
**When NOT to use it:**
|
|
940
|
+
- For simple prose answers, tables, or plain data — those should stay as markdown.
|
|
941
|
+
- For external sites — the renderer blocks cross-origin iframes.
|
|
942
|
+
|
|
943
|
+
Which routes are renderable as embeds is template-specific — the app's \`AGENTS.md\` will list them. If no embeddable routes exist in this template, don't emit \`embed\` fences.
|
|
944
|
+
|
|
473
945
|
### Chat History
|
|
474
946
|
|
|
475
947
|
You can search and restore previous chat conversations:
|
|
@@ -481,7 +953,7 @@ When the user asks to find a previous conversation, use \`search-chats\` first t
|
|
|
481
953
|
### Agent Teams — Orchestration
|
|
482
954
|
|
|
483
955
|
You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents:
|
|
484
|
-
- \`spawn-task\` — Spawn a sub-agent for a task. It runs in its own thread while you stay available. A live preview card appears in the chat.
|
|
956
|
+
- \`spawn-task\` — Spawn a sub-agent for a task. It runs in its own thread while you stay available. A live preview card appears in the chat. You can optionally choose a custom agent profile from \`agents/*.md\`.
|
|
485
957
|
- \`task-status\` — Check the progress of a running sub-agent.
|
|
486
958
|
- \`read-task-result\` — Read the result when a sub-agent finishes.
|
|
487
959
|
|
|
@@ -497,7 +969,7 @@ You are an orchestrator. For complex or multi-step tasks, delegate to sub-agents
|
|
|
497
969
|
4. Use \`read-task-result\` to check results when needed, or the user can see live progress in the card.
|
|
498
970
|
5. If the user's request has multiple steps, you can spawn one sub-agent per step, or chain them.
|
|
499
971
|
|
|
500
|
-
Sub-agents have access to all template tools but **cannot spawn sub-agents themselves** — only you (the orchestrator) can do that. Give the sub-agent a specific, actionable task description — it will figure out which tools to use.
|
|
972
|
+
Sub-agents have access to all template tools but **cannot spawn sub-agents themselves** — only you (the orchestrator) can do that. Give the sub-agent a specific, actionable task description — it will figure out which tools to use. If a matching custom agent profile exists, pass it via the \`agent\` parameter on \`spawn-task\`.
|
|
501
973
|
|
|
502
974
|
### Recurring Jobs
|
|
503
975
|
|
|
@@ -518,6 +990,18 @@ When the user asks for something recurring ("every morning", "daily at 9am", "we
|
|
|
518
990
|
|
|
519
991
|
Job instructions should be self-contained — include which actions to call, what conditions to check, and what to do with results. The agent executing the job has access to all the same tools you do.
|
|
520
992
|
|
|
993
|
+
### Connecting Builder.io
|
|
994
|
+
|
|
995
|
+
When the user asks to connect Builder.io, needs Builder for LLM access / browser automation, or you hit a "Builder not configured" error, call the \`connect-builder\` tool. It renders a one-click Connect card inline in the chat — do NOT write out multi-step setup instructions yourself (no "Option 1 / Option 2", no terminal commands). Just call the tool and let the card handle the rest.
|
|
996
|
+
|
|
997
|
+
### Browser Access
|
|
998
|
+
|
|
999
|
+
Use \`get-browser-connection\` when you need a real browser session backed by Builder. It returns websocket connection details for a provisioned browser session.
|
|
1000
|
+
|
|
1001
|
+
- If the tool says Builder is not configured, call \`connect-builder\` to show the user a Connect card.
|
|
1002
|
+
- Reuse a stable \`sessionId\` when you want to reconnect to the same browser session.
|
|
1003
|
+
- Include proxy parameters when you need the browser to reach a local dev server through Builder's browser connection flow.
|
|
1004
|
+
|
|
521
1005
|
### call-agent — External Apps Only
|
|
522
1006
|
|
|
523
1007
|
The \`call-agent\` tool sends a message to a DIFFERENT, separately-deployed app's agent (A2A protocol). It is **not** for calling actions within the current app.
|
|
@@ -534,15 +1018,34 @@ The \`call-agent\` tool sends a message to a DIFFERENT, separately-deployed app'
|
|
|
534
1018
|
|
|
535
1019
|
If \`call-agent\` returns an error saying the agent is yourself — stop and use your own tools instead.
|
|
536
1020
|
|
|
537
|
-
###
|
|
1021
|
+
### Structured Memory
|
|
538
1022
|
|
|
539
|
-
|
|
540
|
-
- User corrects your approach → capture the correct way
|
|
541
|
-
- User shares preferences (tone, style, workflow) → capture them
|
|
542
|
-
- You discover a non-obvious pattern or gotcha → capture it
|
|
543
|
-
- User provides personal context (contacts, team info, domain knowledge) → capture it
|
|
1023
|
+
You have a structured memory system. Your memory index (\`memory/MEMORY.md\`) is loaded at the start of every conversation (shown above). Individual memories are stored as separate files under \`memory/\`.
|
|
544
1024
|
|
|
545
|
-
**
|
|
1025
|
+
**Tools:**
|
|
1026
|
+
- \`save-memory\` — Create or update a memory. Provide name, type, description, and content. Atomically updates both the memory file and the index.
|
|
1027
|
+
- \`delete-memory\` — Remove a memory and its index entry.
|
|
1028
|
+
- \`resource-read --path memory/<name>.md\` — Read the full content of a specific memory when you need details beyond the index.
|
|
1029
|
+
|
|
1030
|
+
**Memory types:**
|
|
1031
|
+
- \`user\` — Preferences, role, personal context, contacts
|
|
1032
|
+
- \`feedback\` — Corrections ("don't do X, do Y instead"), confirmed approaches
|
|
1033
|
+
- \`project\` — Ongoing work context, decisions, status
|
|
1034
|
+
- \`reference\` — Pointers to external systems, URLs, API details
|
|
1035
|
+
|
|
1036
|
+
**When to save (do it proactively, don't ask permission):**
|
|
1037
|
+
- User corrects your approach → save as \`feedback\`
|
|
1038
|
+
- User shares preferences (tone, style, workflow) → save as \`user\`
|
|
1039
|
+
- You discover a non-obvious pattern or gotcha → save as \`feedback\`
|
|
1040
|
+
- User provides personal context (contacts, team, domain) → save as \`user\`
|
|
1041
|
+
- A project gains enough context to track → save as \`project\`
|
|
1042
|
+
|
|
1043
|
+
**Rules:**
|
|
1044
|
+
- Don't save things obvious from the code or standard framework behavior
|
|
1045
|
+
- When updating an existing memory, read it first and merge — don't overwrite blindly
|
|
1046
|
+
- Keep descriptions concise — the index is loaded every message
|
|
1047
|
+
- One memory per logical topic (e.g. 'coding-style', 'project-alpha')
|
|
1048
|
+
- Don't save temporary debugging notes or ephemeral task details
|
|
546
1049
|
`;
|
|
547
1050
|
const PROD_FRAMEWORK_PROMPT = `## Agent-Native Framework — Production Mode
|
|
548
1051
|
|
|
@@ -552,20 +1055,22 @@ The agent and the UI are equal partners — everything the UI can do, you can do
|
|
|
552
1055
|
|
|
553
1056
|
**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.
|
|
554
1057
|
|
|
555
|
-
### Code Changes Not Available
|
|
1058
|
+
### Code Changes Not Available — Call \`connect-builder\` Immediately
|
|
1059
|
+
|
|
1060
|
+
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:
|
|
556
1061
|
|
|
557
|
-
|
|
1062
|
+
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.
|
|
1063
|
+
2. After the card renders, write a single short sentence telling the user to click Connect Builder to have this built for them in the cloud, and mention they can also clone the app locally with \`npx agent-native create <app-name>\` if they'd rather work offline.
|
|
558
1064
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
> \`\`\`
|
|
1065
|
+
**Hard rules — do NOT break these:**
|
|
1066
|
+
- Do NOT read source files, list directories, or explore the codebase. You have no filesystem tools and don't need to look at code to recommend Builder.
|
|
1067
|
+
- Do NOT write an implementation plan. Do NOT write code in your response. Do NOT describe which files to create or modify. Builder will figure that out in its sandbox.
|
|
1068
|
+
- Do NOT save plans, specs, or code to \`resource-write\`. Resources are for app data, not implementation plans the user didn't ask for.
|
|
1069
|
+
- Do NOT spawn sub-agents (\`spawn-task\`) to design, plan, or research the feature. The answer is always: call \`connect-builder\`, say one sentence, stop. Sub-agents inherit these same rules and have no code-editing tools either.
|
|
1070
|
+
- Do NOT say "I don't have a request-code-change tool" or list what tools you lack. Just call \`connect-builder\`.
|
|
1071
|
+
- Do NOT wait for the user to ask "how" — call \`connect-builder\` the moment a code change is requested.
|
|
567
1072
|
|
|
568
|
-
|
|
1073
|
+
Builder.io is the recommended path because it's one-click and runs in the cloud. Local dev is a fallback for users who want to work offline.
|
|
569
1074
|
${FRAMEWORK_CORE}`;
|
|
570
1075
|
const DEV_FRAMEWORK_PROMPT = `## Agent-Native Framework — Development Mode
|
|
571
1076
|
|
|
@@ -594,19 +1099,17 @@ ${FRAMEWORK_CORE}`;
|
|
|
594
1099
|
const DEFAULT_SYSTEM_PROMPT = PROD_FRAMEWORK_PROMPT;
|
|
595
1100
|
/**
|
|
596
1101
|
* Pre-load the agent's context: AGENTS.md (template instructions), the skills
|
|
597
|
-
* index,
|
|
598
|
-
*
|
|
599
|
-
*
|
|
1102
|
+
* index, shared LEARNINGS.md (team notes), and memory/MEMORY.md (personal
|
|
1103
|
+
* structured memory index). These all get appended to the system prompt so
|
|
1104
|
+
* the agent has everything it needs from the first turn.
|
|
600
1105
|
*
|
|
601
|
-
*
|
|
1106
|
+
* Four sources are layered:
|
|
602
1107
|
*
|
|
603
|
-
* 1. `<
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
* 3. `<personal>` — LEARNINGS.md from the SQL personal scope. The current
|
|
609
|
-
* user's own notes.
|
|
1108
|
+
* 1. `<workspace>` — AGENTS.md from the enterprise workspace core.
|
|
1109
|
+
* 2. `<template>` — AGENTS.md + skills index from the Vite plugin bundle.
|
|
1110
|
+
* 3. `<shared>` — LEARNINGS.md from the SQL shared scope. Team-level notes.
|
|
1111
|
+
* 4. `<personal>` — memory/MEMORY.md from the SQL personal scope. The
|
|
1112
|
+
* current user's structured memory index.
|
|
610
1113
|
*
|
|
611
1114
|
* Each source is read independently — no copying between them. Editing
|
|
612
1115
|
* AGENTS.md and restarting the server is all it takes; Vite HMR invalidates
|
|
@@ -615,10 +1118,15 @@ const DEFAULT_SYSTEM_PROMPT = PROD_FRAMEWORK_PROMPT;
|
|
|
615
1118
|
async function loadResourcesForPrompt(owner) {
|
|
616
1119
|
await ensurePersonalDefaults(owner);
|
|
617
1120
|
const sections = [];
|
|
618
|
-
// 1.
|
|
1121
|
+
// 1. Workspace AGENTS.md + skills merged into the template bundle.
|
|
619
1122
|
try {
|
|
620
1123
|
const { loadAgentsBundle, generateSkillsPromptBlock } = await import("./agents-bundle.js");
|
|
621
1124
|
const bundle = await loadAgentsBundle();
|
|
1125
|
+
// Workspace-core AGENTS.md (enterprise-wide instructions), if present.
|
|
1126
|
+
if (bundle.workspaceAgentsMd && bundle.workspaceAgentsMd.trim()) {
|
|
1127
|
+
sections.push(`<resource name="AGENTS.md" scope="workspace">\n${bundle.workspaceAgentsMd.trim()}\n</resource>`);
|
|
1128
|
+
}
|
|
1129
|
+
// 2. Template AGENTS.md.
|
|
622
1130
|
if (bundle.agentsMd.trim()) {
|
|
623
1131
|
sections.push(`<resource name="AGENTS.md" scope="template">\n${bundle.agentsMd.trim()}\n</resource>`);
|
|
624
1132
|
}
|
|
@@ -636,12 +1144,12 @@ async function loadResourcesForPrompt(owner) {
|
|
|
636
1144
|
}
|
|
637
1145
|
}
|
|
638
1146
|
catch { }
|
|
639
|
-
// 3. Personal
|
|
1147
|
+
// 3. Personal memory index (skip if owner is the shared sentinel)
|
|
640
1148
|
if (owner !== SHARED_OWNER) {
|
|
641
1149
|
try {
|
|
642
|
-
const
|
|
643
|
-
if (
|
|
644
|
-
sections.push(`<resource name="
|
|
1150
|
+
const memoryIndex = await resourceGetByPath(owner, "memory/MEMORY.md");
|
|
1151
|
+
if (memoryIndex?.content?.trim()) {
|
|
1152
|
+
sections.push(`<resource name="memory/MEMORY.md" scope="personal">\n${memoryIndex.content.trim()}\n</resource>`);
|
|
645
1153
|
}
|
|
646
1154
|
}
|
|
647
1155
|
catch { }
|
|
@@ -656,12 +1164,15 @@ async function loadResourcesForPrompt(owner) {
|
|
|
656
1164
|
* from the environment so scheduler/A2A/HTTP call sites all see whatever
|
|
657
1165
|
* org was just resolved for this request.
|
|
658
1166
|
*/
|
|
659
|
-
async function buildSchemaBlock(owner,
|
|
1167
|
+
async function buildSchemaBlock(owner, _legacyHasRawDbTools) {
|
|
1168
|
+
// db-* tools are always registered (see createDbScriptEntries), in both dev
|
|
1169
|
+
// and prod. The legacy boolean is kept for call-site compatibility but
|
|
1170
|
+
// ignored — always advertise the tools to the agent.
|
|
660
1171
|
try {
|
|
661
1172
|
return await loadSchemaPromptBlock({
|
|
662
1173
|
owner,
|
|
663
|
-
orgId:
|
|
664
|
-
hasRawDbTools,
|
|
1174
|
+
orgId: getRequestOrgId() ?? null,
|
|
1175
|
+
hasRawDbTools: true,
|
|
665
1176
|
});
|
|
666
1177
|
}
|
|
667
1178
|
catch {
|
|
@@ -851,19 +1362,92 @@ export function createAgentChatPlugin(options) {
|
|
|
851
1362
|
const canToggle = (env === "development" || env === "test") &&
|
|
852
1363
|
process.env.AGENT_MODE !== "production";
|
|
853
1364
|
const routePath = options?.path ?? "/_agent-native/agent-chat";
|
|
1365
|
+
// Mutable mode flag — persisted to the `settings` table so a user who
|
|
1366
|
+
// toggles to "Production" stays in prod mode across server restarts.
|
|
1367
|
+
// Hoisted here (before any tool-registry / handler closures are built)
|
|
1368
|
+
// so every runtime decision point can close over it and see live changes
|
|
1369
|
+
// when the user toggles the Environment dropdown.
|
|
1370
|
+
const AGENT_MODE_SETTING_KEY = "agent-chat.mode";
|
|
1371
|
+
let currentDevMode = canToggle;
|
|
1372
|
+
if (canToggle) {
|
|
1373
|
+
try {
|
|
1374
|
+
const persisted = await getSetting(AGENT_MODE_SETTING_KEY);
|
|
1375
|
+
if (persisted && typeof persisted.devMode === "boolean") {
|
|
1376
|
+
currentDevMode = persisted.devMode;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
catch {
|
|
1380
|
+
// Settings table may not be ready yet — fall back to default.
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
// Every closure that picks between dev/prod tools, prompts, or handlers
|
|
1384
|
+
// at request time should call this getter instead of reading `canToggle`.
|
|
1385
|
+
// `canToggle` means "this environment allows toggling" (static); this
|
|
1386
|
+
// function means "the user currently has dev mode ON" (live).
|
|
1387
|
+
const isDevMode = () => currentDevMode;
|
|
1388
|
+
// Initialize MCP client (connects to user-configured local MCP servers).
|
|
1389
|
+
// Graceful-degrade: any failure yields zero MCP tools and agent-chat keeps
|
|
1390
|
+
// working as before. No-op outside Node runtimes.
|
|
1391
|
+
let mcpConfig = loadMcpConfig();
|
|
1392
|
+
if (!mcpConfig) {
|
|
1393
|
+
mcpConfig = autoDetectMcpConfig();
|
|
1394
|
+
if (mcpConfig) {
|
|
1395
|
+
const detected = Object.keys(mcpConfig.servers).join(", ");
|
|
1396
|
+
console.log(`[mcp-client] auto-detected ${detected}, registering as MCP server — set AGENT_NATIVE_DISABLE_MCP_AUTODETECT=1 to opt out`);
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
console.log("[mcp-client] no mcp.config.json and no auto-detectable servers — skipping MCP tools");
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
else if (mcpConfig.source) {
|
|
1403
|
+
console.log(`[mcp-client] loaded config from ${mcpConfig.source} (${Object.keys(mcpConfig.servers).length} server(s))`);
|
|
1404
|
+
}
|
|
1405
|
+
const mcpManager = new McpClientManager(mcpConfig);
|
|
1406
|
+
try {
|
|
1407
|
+
await mcpManager.start();
|
|
1408
|
+
}
|
|
1409
|
+
catch (err) {
|
|
1410
|
+
console.warn(`[mcp-client] start() failed: ${err?.message ?? err}. Continuing without MCP tools.`);
|
|
1411
|
+
}
|
|
1412
|
+
setGlobalMcpManager(mcpManager);
|
|
1413
|
+
const mcpActionEntries = mcpToolsToActionEntries(mcpManager);
|
|
1414
|
+
// Mount status route so tooling/onboarding can inspect MCP state.
|
|
1415
|
+
mountMcpStatusRoute(nitroApp, mcpManager);
|
|
1416
|
+
// Ensure we tear down child processes if the host shuts down cleanly.
|
|
1417
|
+
if (typeof process !== "undefined" &&
|
|
1418
|
+
typeof process.once === "function" &&
|
|
1419
|
+
!globalThis.__agentNativeMcpExitHooked) {
|
|
1420
|
+
globalThis.__agentNativeMcpExitHooked = true;
|
|
1421
|
+
const stop = () => {
|
|
1422
|
+
const mgr = getGlobalMcpManager();
|
|
1423
|
+
if (mgr)
|
|
1424
|
+
void mgr.stop();
|
|
1425
|
+
};
|
|
1426
|
+
process.once("exit", stop);
|
|
1427
|
+
process.once("SIGTERM", stop);
|
|
1428
|
+
process.once("SIGINT", stop);
|
|
1429
|
+
}
|
|
854
1430
|
// Resolve actions — prefer `actions`, fall back to deprecated `scripts`
|
|
855
1431
|
const rawActions = options?.actions ?? options?.scripts;
|
|
856
1432
|
const templateScripts = typeof rawActions === "function"
|
|
857
1433
|
? await rawActions()
|
|
858
1434
|
: (rawActions ?? {});
|
|
859
|
-
// Resource, chat, and cross-agent scripts are available in both prod and dev modes
|
|
1435
|
+
// Resource, chat, docs, db, and cross-agent scripts are available in both prod and dev modes
|
|
860
1436
|
const resourceScripts = await createResourceScriptEntries();
|
|
1437
|
+
const docsScripts = await createDocsScriptEntries();
|
|
1438
|
+
const dbScripts = await createDbScriptEntries();
|
|
1439
|
+
const refreshScreenTool = createRefreshScreenEntry();
|
|
1440
|
+
const urlTools = createUrlTools();
|
|
861
1441
|
const engineScripts = await createAgentEngineScriptEntries();
|
|
862
1442
|
const chatScripts = {
|
|
863
1443
|
...(await createChatScriptEntries()),
|
|
864
1444
|
...engineScripts,
|
|
865
1445
|
};
|
|
866
1446
|
const callAgentScript = await createCallAgentScriptEntry(options?.appId);
|
|
1447
|
+
let _currentRequestOrigin = "http://localhost:3000";
|
|
1448
|
+
const browserTools = createBuilderBrowserTool({
|
|
1449
|
+
getOrigin: () => _currentRequestOrigin,
|
|
1450
|
+
});
|
|
867
1451
|
// Auto-mount A2A protocol endpoints so every app is discoverable
|
|
868
1452
|
// and callable by other agents via the standard protocol.
|
|
869
1453
|
// In dev mode, include dev scripts (filesystem-discovered) so the A2A agent
|
|
@@ -1001,16 +1585,23 @@ export function createAgentChatPlugin(options) {
|
|
|
1001
1585
|
const allScripts = canToggle
|
|
1002
1586
|
? {
|
|
1003
1587
|
...resourceScripts,
|
|
1588
|
+
...docsScripts,
|
|
1004
1589
|
...chatScripts,
|
|
1005
1590
|
...callAgentScript,
|
|
1591
|
+
...browserTools,
|
|
1006
1592
|
...devScriptsForA2A,
|
|
1007
1593
|
}
|
|
1008
1594
|
: {
|
|
1009
1595
|
...discoveredActions,
|
|
1010
1596
|
...templateScripts,
|
|
1011
1597
|
...resourceScripts,
|
|
1598
|
+
...docsScripts,
|
|
1599
|
+
...dbScripts,
|
|
1600
|
+
...refreshScreenTool,
|
|
1601
|
+
...urlTools,
|
|
1012
1602
|
...chatScripts,
|
|
1013
1603
|
...callAgentScript,
|
|
1604
|
+
...browserTools,
|
|
1014
1605
|
...devScriptsForA2A,
|
|
1015
1606
|
};
|
|
1016
1607
|
const { mountA2A } = await import("../a2a/server.js");
|
|
@@ -1083,12 +1674,13 @@ export function createAgentChatPlugin(options) {
|
|
|
1083
1674
|
apiKey: options?.apiKey,
|
|
1084
1675
|
});
|
|
1085
1676
|
// Use the same handler (dev or prod) that the interactive chat uses
|
|
1086
|
-
const
|
|
1677
|
+
const devActive = isDevMode();
|
|
1678
|
+
const handler = devActive && devHandler ? devHandler : prodHandler;
|
|
1087
1679
|
// Build the same system prompt the interactive agent uses
|
|
1088
1680
|
const owner = userEmail || "local@localhost";
|
|
1089
1681
|
const resources = await loadResourcesForPrompt(owner);
|
|
1090
|
-
const schemaBlock = await buildSchemaBlock(owner,
|
|
1091
|
-
const systemPrompt =
|
|
1682
|
+
const schemaBlock = await buildSchemaBlock(owner, devActive);
|
|
1683
|
+
const systemPrompt = devActive
|
|
1092
1684
|
? devPrompt + resources + schemaBlock
|
|
1093
1685
|
: basePrompt + resources + schemaBlock;
|
|
1094
1686
|
const model = options?.model ??
|
|
@@ -1097,16 +1689,23 @@ export function createAgentChatPlugin(options) {
|
|
|
1097
1689
|
// to prevent infinite recursive A2A loops (agent calling itself).
|
|
1098
1690
|
// In dev mode, template actions are invoked via shell (not native tools),
|
|
1099
1691
|
// so they're omitted from the tool registry — see allScripts comment.
|
|
1100
|
-
const a2aActions =
|
|
1692
|
+
const a2aActions = devActive
|
|
1101
1693
|
? {
|
|
1102
1694
|
...resourceScripts,
|
|
1695
|
+
...docsScripts,
|
|
1103
1696
|
...chatScripts,
|
|
1697
|
+
...browserTools,
|
|
1104
1698
|
...devScriptsForA2A,
|
|
1105
1699
|
}
|
|
1106
1700
|
: {
|
|
1107
1701
|
...templateScripts,
|
|
1108
1702
|
...resourceScripts,
|
|
1703
|
+
...docsScripts,
|
|
1704
|
+
...dbScripts,
|
|
1705
|
+
...refreshScreenTool,
|
|
1706
|
+
...urlTools,
|
|
1109
1707
|
...chatScripts,
|
|
1708
|
+
...browserTools,
|
|
1110
1709
|
};
|
|
1111
1710
|
const a2aTools = actionsToEngineTools(a2aActions);
|
|
1112
1711
|
const a2aMessages = [
|
|
@@ -1189,21 +1788,27 @@ export function createAgentChatPlugin(options) {
|
|
|
1189
1788
|
(canToggle ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001");
|
|
1190
1789
|
// Same actions as A2A — without call-agent to prevent loops.
|
|
1191
1790
|
// In dev mode, template actions go through shell, not native tools.
|
|
1192
|
-
const
|
|
1791
|
+
const devActiveMcp = isDevMode();
|
|
1792
|
+
const mcpActions = devActiveMcp
|
|
1193
1793
|
? {
|
|
1194
1794
|
...resourceScripts,
|
|
1795
|
+
...docsScripts,
|
|
1195
1796
|
...chatScripts,
|
|
1196
1797
|
...devScriptsForA2A,
|
|
1197
1798
|
}
|
|
1198
1799
|
: {
|
|
1199
1800
|
...templateScripts,
|
|
1200
1801
|
...resourceScripts,
|
|
1802
|
+
...docsScripts,
|
|
1803
|
+
...dbScripts,
|
|
1804
|
+
...refreshScreenTool,
|
|
1805
|
+
...urlTools,
|
|
1201
1806
|
...chatScripts,
|
|
1202
1807
|
};
|
|
1203
1808
|
const mcpTools = actionsToEngineTools(mcpActions);
|
|
1204
1809
|
const resources = await loadResourcesForPrompt("local@localhost");
|
|
1205
|
-
const schemaBlock = await buildSchemaBlock("local@localhost",
|
|
1206
|
-
const systemPrompt =
|
|
1810
|
+
const schemaBlock = await buildSchemaBlock("local@localhost", devActiveMcp);
|
|
1811
|
+
const systemPrompt = devActiveMcp
|
|
1207
1812
|
? devPrompt + resources + schemaBlock
|
|
1208
1813
|
: basePrompt + resources + schemaBlock;
|
|
1209
1814
|
let accumulatedText = "";
|
|
@@ -1309,6 +1914,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1309
1914
|
// requests for different threads don't clobber each other.
|
|
1310
1915
|
const _runSendByThread = new Map();
|
|
1311
1916
|
let _currentRunOwner = "local@localhost";
|
|
1917
|
+
let _currentRunUserApiKey;
|
|
1312
1918
|
let _currentRunThreadId = "";
|
|
1313
1919
|
let _currentRunSystemPrompt = basePrompt;
|
|
1314
1920
|
// Default to Haiku in production mode to manage costs for hosted apps
|
|
@@ -1317,21 +1923,31 @@ export function createAgentChatPlugin(options) {
|
|
|
1317
1923
|
const teamTools = createTeamTools({
|
|
1318
1924
|
getOwner: () => _currentRunOwner,
|
|
1319
1925
|
getSystemPrompt: () => _currentRunSystemPrompt,
|
|
1320
|
-
getActions: () =>
|
|
1926
|
+
getActions: () => isDevMode()
|
|
1321
1927
|
? {
|
|
1322
1928
|
// Sub-agents spawned in dev mode also invoke template actions
|
|
1323
1929
|
// via shell, so omit them from the native tool registry.
|
|
1324
1930
|
...resourceScripts,
|
|
1931
|
+
...docsScripts,
|
|
1325
1932
|
...chatScripts,
|
|
1326
1933
|
...devScriptsForA2A,
|
|
1327
1934
|
}
|
|
1328
1935
|
: {
|
|
1329
1936
|
...templateScripts,
|
|
1330
1937
|
...resourceScripts,
|
|
1938
|
+
...docsScripts,
|
|
1939
|
+
...dbScripts,
|
|
1940
|
+
...refreshScreenTool,
|
|
1941
|
+
...urlTools,
|
|
1331
1942
|
...chatScripts,
|
|
1332
1943
|
},
|
|
1333
1944
|
getEngine: () => createAnthropicEngine({
|
|
1334
|
-
|
|
1945
|
+
// Sub-agents must inherit the parent run's resolved key so a
|
|
1946
|
+
// BYO-key user can't bypass the free-tier check on the parent
|
|
1947
|
+
// run and then have spawn-task delegations bill the platform key.
|
|
1948
|
+
apiKey: _currentRunUserApiKey ??
|
|
1949
|
+
options?.apiKey ??
|
|
1950
|
+
process.env.ANTHROPIC_API_KEY,
|
|
1335
1951
|
}),
|
|
1336
1952
|
getModel: () => resolvedModel,
|
|
1337
1953
|
getParentThreadId: () => _currentRunThreadId,
|
|
@@ -1352,22 +1968,44 @@ export function createAgentChatPlugin(options) {
|
|
|
1352
1968
|
const prodActions = {
|
|
1353
1969
|
...templateScripts,
|
|
1354
1970
|
...resourceScripts,
|
|
1971
|
+
...docsScripts,
|
|
1972
|
+
...dbScripts,
|
|
1973
|
+
...refreshScreenTool,
|
|
1974
|
+
...urlTools,
|
|
1355
1975
|
...chatScripts,
|
|
1356
1976
|
...callAgentScript,
|
|
1357
1977
|
...teamTools,
|
|
1358
1978
|
...jobTools,
|
|
1979
|
+
...browserTools,
|
|
1980
|
+
...mcpActionEntries,
|
|
1359
1981
|
};
|
|
1360
1982
|
// Always build the production handler (includes resource tools + call-agent + team tools)
|
|
1361
1983
|
// In production mode (!canToggle), enable usage tracking and limits
|
|
1362
1984
|
const isHostedProd = !canToggle;
|
|
1985
|
+
const resolveExtraContext = async (event, owner) => {
|
|
1986
|
+
if (!options?.extraContext)
|
|
1987
|
+
return "";
|
|
1988
|
+
try {
|
|
1989
|
+
const extra = await options.extraContext(event, owner);
|
|
1990
|
+
return extra ? `\n\n${extra}` : "";
|
|
1991
|
+
}
|
|
1992
|
+
catch (err) {
|
|
1993
|
+
console.warn("[agent-chat] extraContext threw:", err instanceof Error ? err.message : err);
|
|
1994
|
+
return "";
|
|
1995
|
+
}
|
|
1996
|
+
};
|
|
1363
1997
|
const prodHandler = createProductionAgentHandler({
|
|
1364
1998
|
actions: prodActions,
|
|
1365
1999
|
systemPrompt: async (event) => {
|
|
2000
|
+
_currentRequestOrigin = getOrigin(event);
|
|
1366
2001
|
const owner = await getOwnerFromEvent(event);
|
|
1367
2002
|
_currentRunOwner = owner;
|
|
2003
|
+
const { getOwnerAnthropicApiKey } = await import("../agent/production-agent.js");
|
|
2004
|
+
_currentRunUserApiKey = await getOwnerAnthropicApiKey(owner);
|
|
1368
2005
|
const resources = await loadResourcesForPrompt(owner);
|
|
1369
2006
|
const schemaBlock = await buildSchemaBlock(owner, false);
|
|
1370
|
-
|
|
2007
|
+
const extra = await resolveExtraContext(event, owner);
|
|
2008
|
+
_currentRunSystemPrompt = basePrompt + resources + schemaBlock + extra;
|
|
1371
2009
|
return _currentRunSystemPrompt;
|
|
1372
2010
|
},
|
|
1373
2011
|
model: options?.model ??
|
|
@@ -1398,20 +2036,27 @@ export function createAgentChatPlugin(options) {
|
|
|
1398
2036
|
// listed in the dev system prompt's "Available Actions" section.
|
|
1399
2037
|
const devActions = {
|
|
1400
2038
|
...resourceScripts,
|
|
2039
|
+
...docsScripts,
|
|
1401
2040
|
...chatScripts,
|
|
1402
2041
|
...callAgentScript,
|
|
1403
2042
|
...teamTools,
|
|
1404
2043
|
...jobTools,
|
|
2044
|
+
...browserTools,
|
|
2045
|
+
...mcpActionEntries,
|
|
1405
2046
|
...(await createDevScriptRegistry()),
|
|
1406
2047
|
};
|
|
1407
2048
|
devHandler = createProductionAgentHandler({
|
|
1408
2049
|
actions: devActions,
|
|
1409
2050
|
systemPrompt: async (event) => {
|
|
2051
|
+
_currentRequestOrigin = getOrigin(event);
|
|
1410
2052
|
const owner = await getOwnerFromEvent(event);
|
|
1411
2053
|
_currentRunOwner = owner;
|
|
2054
|
+
const { getOwnerAnthropicApiKey } = await import("../agent/production-agent.js");
|
|
2055
|
+
_currentRunUserApiKey = await getOwnerAnthropicApiKey(owner);
|
|
1412
2056
|
const resources = await loadResourcesForPrompt(owner);
|
|
1413
2057
|
const schemaBlock = await buildSchemaBlock(owner, true);
|
|
1414
|
-
|
|
2058
|
+
const extra = await resolveExtraContext(event, owner);
|
|
2059
|
+
_currentRunSystemPrompt = devPrompt + resources + schemaBlock + extra;
|
|
1415
2060
|
return _currentRunSystemPrompt;
|
|
1416
2061
|
},
|
|
1417
2062
|
model: options?.model,
|
|
@@ -1432,8 +2077,8 @@ export function createAgentChatPlugin(options) {
|
|
|
1432
2077
|
const mentionProviders = typeof rawProviders === "function"
|
|
1433
2078
|
? await rawProviders()
|
|
1434
2079
|
: (rawProviders ?? {});
|
|
1435
|
-
//
|
|
1436
|
-
|
|
2080
|
+
// currentDevMode + persistence were hoisted to the top of this function
|
|
2081
|
+
// so every closure built below can close over the live flag.
|
|
1437
2082
|
// Mount mode endpoint — GET returns current mode, POST toggles it (localhost only)
|
|
1438
2083
|
getH3App(nitroApp).use(`${routePath}/mode`, defineEventHandler(async (event) => {
|
|
1439
2084
|
if (getMethod(event) === "POST") {
|
|
@@ -1452,12 +2097,24 @@ export function createAgentChatPlugin(options) {
|
|
|
1452
2097
|
else {
|
|
1453
2098
|
currentDevMode = !currentDevMode;
|
|
1454
2099
|
}
|
|
2100
|
+
try {
|
|
2101
|
+
await putSetting(AGENT_MODE_SETTING_KEY, {
|
|
2102
|
+
devMode: currentDevMode,
|
|
2103
|
+
});
|
|
2104
|
+
}
|
|
2105
|
+
catch {
|
|
2106
|
+
// Persistence is best-effort — in-memory flag still applies for
|
|
2107
|
+
// the lifetime of this process even if the settings write fails.
|
|
2108
|
+
}
|
|
1455
2109
|
return { devMode: currentDevMode, canToggle };
|
|
1456
2110
|
}
|
|
1457
2111
|
return { devMode: currentDevMode, canToggle };
|
|
1458
2112
|
}));
|
|
1459
|
-
// Mount save-key BEFORE the prefix handler so it isn't shadowed
|
|
1460
|
-
//
|
|
2113
|
+
// Mount save-key BEFORE the prefix handler so it isn't shadowed.
|
|
2114
|
+
// Persists the user's key per-owner in the SQL settings table so it
|
|
2115
|
+
// survives across serverless invocations (where mutating process.env
|
|
2116
|
+
// and writing .env are both no-ops). Also updates process.env and
|
|
2117
|
+
// .env when running locally for fast pickup by other handlers.
|
|
1461
2118
|
getH3App(nitroApp).use(`${routePath}/save-key`, defineEventHandler(async (event) => {
|
|
1462
2119
|
if (getMethod(event) !== "POST") {
|
|
1463
2120
|
setResponseStatus(event, 405);
|
|
@@ -1470,19 +2127,66 @@ export function createAgentChatPlugin(options) {
|
|
|
1470
2127
|
return { error: "API key is required" };
|
|
1471
2128
|
}
|
|
1472
2129
|
const trimmedKey = key.trim();
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
2130
|
+
// Persist per-owner so the key survives cold starts in serverless
|
|
2131
|
+
// and so the user's key isn't shared across users on multi-tenant
|
|
2132
|
+
// hosted deployments. We require a real authenticated owner here —
|
|
2133
|
+
// `local@localhost` is the unauthenticated fallback and must never
|
|
2134
|
+
// become the shared key bucket on hosted deployments.
|
|
2135
|
+
const ownerEmail = await getOwnerFromEvent(event);
|
|
2136
|
+
if (isHostedProd && (!ownerEmail || ownerEmail === "local@localhost")) {
|
|
2137
|
+
setResponseStatus(event, 401);
|
|
2138
|
+
return { error: "Authentication required" };
|
|
1480
2139
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
2140
|
+
if (ownerEmail && ownerEmail !== "local@localhost") {
|
|
2141
|
+
try {
|
|
2142
|
+
await putSetting(`user-anthropic-api-key:${ownerEmail}`, {
|
|
2143
|
+
key: trimmedKey,
|
|
2144
|
+
});
|
|
2145
|
+
// Verify the write actually landed — some managed DB drivers
|
|
2146
|
+
// swallow errors on degraded connections. Without this the
|
|
2147
|
+
// client sees "saved", reloads, and the usage-limit card
|
|
2148
|
+
// re-appears on the next message because the key isn't
|
|
2149
|
+
// really persisted.
|
|
2150
|
+
const check = await getSetting(`user-anthropic-api-key:${ownerEmail}`);
|
|
2151
|
+
if (!check ||
|
|
2152
|
+
typeof check.key !== "string" ||
|
|
2153
|
+
check.key !== trimmedKey) {
|
|
2154
|
+
throw new Error("settings write did not persist");
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
catch (err) {
|
|
2158
|
+
if (isHostedProd) {
|
|
2159
|
+
console.error("[agent-chat] save-key persistence failed:", err instanceof Error ? err.message : err);
|
|
2160
|
+
setResponseStatus(event, 500);
|
|
2161
|
+
return {
|
|
2162
|
+
error: "Failed to persist API key. Please try again or contact support.",
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
// Local dev falls through to the env-file path below.
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
// In hosted/multi-tenant mode we deliberately do NOT touch
|
|
2169
|
+
// process.env or .env: the per-owner SQL lookup above is the
|
|
2170
|
+
// single source of truth, and overwriting the shared env key
|
|
2171
|
+
// would leak one tenant's credentials into every subsequent
|
|
2172
|
+
// request that hit the same warm instance without its own key.
|
|
2173
|
+
if (!isHostedProd) {
|
|
2174
|
+
try {
|
|
2175
|
+
const path = await import("path");
|
|
2176
|
+
const { upsertEnvFile } = await import("./create-server.js");
|
|
2177
|
+
const envPath = path.join(process.cwd(), ".env");
|
|
2178
|
+
await upsertEnvFile(envPath, [
|
|
2179
|
+
{ key: "ANTHROPIC_API_KEY", value: trimmedKey },
|
|
2180
|
+
]);
|
|
2181
|
+
}
|
|
2182
|
+
catch {
|
|
2183
|
+
// Edge runtime — can't write .env, but can still update process.env
|
|
2184
|
+
}
|
|
2185
|
+
// Update process.env so the agent works immediately in the
|
|
2186
|
+
// current local-dev invocation; the SQL persist above covers
|
|
2187
|
+
// future invocations.
|
|
2188
|
+
process.env.ANTHROPIC_API_KEY = trimmedKey;
|
|
1483
2189
|
}
|
|
1484
|
-
// Update process.env so the agent works immediately
|
|
1485
|
-
process.env.ANTHROPIC_API_KEY = trimmedKey;
|
|
1486
2190
|
return { ok: true };
|
|
1487
2191
|
}));
|
|
1488
2192
|
// Mount file search endpoint
|
|
@@ -1750,7 +2454,29 @@ export function createAgentChatPlugin(options) {
|
|
|
1750
2454
|
}
|
|
1751
2455
|
})());
|
|
1752
2456
|
}
|
|
1753
|
-
// 4.
|
|
2457
|
+
// 4. Custom workspace agents
|
|
2458
|
+
sources.push((async () => {
|
|
2459
|
+
try {
|
|
2460
|
+
const owner = await getOwnerFromEvent(event);
|
|
2461
|
+
const { listAccessibleCustomAgents } = await import("../resources/agents.js");
|
|
2462
|
+
const agents = await listAccessibleCustomAgents(owner);
|
|
2463
|
+
flush(agents.map((agent) => ({
|
|
2464
|
+
id: `custom-agent:${agent.id}`,
|
|
2465
|
+
label: agent.name,
|
|
2466
|
+
description: agent.description || agent.path,
|
|
2467
|
+
icon: "agent",
|
|
2468
|
+
source: "agent:custom",
|
|
2469
|
+
refType: "custom-agent",
|
|
2470
|
+
refPath: agent.path,
|
|
2471
|
+
refId: agent.id,
|
|
2472
|
+
section: "Agents",
|
|
2473
|
+
})));
|
|
2474
|
+
}
|
|
2475
|
+
catch (e) {
|
|
2476
|
+
console.error("[agent-native] Custom agent discovery failed:", e);
|
|
2477
|
+
}
|
|
2478
|
+
})());
|
|
2479
|
+
// 5. Peer agent discovery (network call — often slowest)
|
|
1754
2480
|
sources.push((async () => {
|
|
1755
2481
|
try {
|
|
1756
2482
|
const agents = await discoverAgents(options?.appId);
|
|
@@ -1763,7 +2489,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1763
2489
|
refType: "agent",
|
|
1764
2490
|
refPath: agent.url,
|
|
1765
2491
|
refId: agent.id,
|
|
1766
|
-
section: "Agents",
|
|
2492
|
+
section: "Connected Agents",
|
|
1767
2493
|
})));
|
|
1768
2494
|
}
|
|
1769
2495
|
catch (e) {
|
|
@@ -1786,7 +2512,7 @@ export function createAgentChatPlugin(options) {
|
|
|
1786
2512
|
setResponseStatus(event, 405);
|
|
1787
2513
|
return { error: "Method not allowed" };
|
|
1788
2514
|
}
|
|
1789
|
-
await getOwnerFromEvent(event);
|
|
2515
|
+
const ownerEmail = await getOwnerFromEvent(event);
|
|
1790
2516
|
const body = await readBody(event);
|
|
1791
2517
|
const message = body?.message;
|
|
1792
2518
|
if (!message || typeof message !== "string") {
|
|
@@ -1795,7 +2521,11 @@ export function createAgentChatPlugin(options) {
|
|
|
1795
2521
|
}
|
|
1796
2522
|
// Strip mention markup: @[Name|type] → @Name
|
|
1797
2523
|
const cleanMessage = message.replace(/@\[([^\]|]+)\|[^\]]*\]/g, "@$1");
|
|
1798
|
-
|
|
2524
|
+
// Mirror the chat-run resolution so BYO-key users have title
|
|
2525
|
+
// generation billed to their own key instead of the platform key.
|
|
2526
|
+
const { getOwnerAnthropicApiKey } = await import("../agent/production-agent.js");
|
|
2527
|
+
const userApiKey = await getOwnerAnthropicApiKey(ownerEmail);
|
|
2528
|
+
const apiKey = userApiKey ?? process.env.ANTHROPIC_API_KEY;
|
|
1799
2529
|
if (!apiKey) {
|
|
1800
2530
|
// Fallback: truncate the message
|
|
1801
2531
|
return { title: cleanMessage.trim().slice(0, 60) };
|
|
@@ -1973,34 +2703,34 @@ export function createAgentChatPlugin(options) {
|
|
|
1973
2703
|
setResponseStatus(event, 404);
|
|
1974
2704
|
return { error: "Not found" };
|
|
1975
2705
|
}
|
|
1976
|
-
//
|
|
1977
|
-
// Without this, scripts default to "local@localhost" and miss resources
|
|
1978
|
-
// created by users who authenticated via OAuth (e.g., Gmail).
|
|
2706
|
+
// Resolve per-request auth context
|
|
1979
2707
|
const owner = await getOwnerFromEvent(event);
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
// Priority: explicit resolveOrgId callback > session.orgId from Better Auth
|
|
1983
|
-
let resolvedOrgId = null;
|
|
2708
|
+
// Resolve org ID: explicit callback > session.orgId from Better Auth
|
|
2709
|
+
let resolvedOrgId;
|
|
1984
2710
|
if (options?.resolveOrgId) {
|
|
1985
|
-
resolvedOrgId = await options.resolveOrgId(event);
|
|
2711
|
+
resolvedOrgId = (await options.resolveOrgId(event)) ?? undefined;
|
|
1986
2712
|
}
|
|
1987
2713
|
else {
|
|
1988
2714
|
try {
|
|
1989
2715
|
const session = await getSession(event);
|
|
1990
|
-
resolvedOrgId = session?.orgId ??
|
|
2716
|
+
resolvedOrgId = session?.orgId ?? undefined;
|
|
1991
2717
|
}
|
|
1992
2718
|
catch {
|
|
1993
2719
|
// Session not available
|
|
1994
2720
|
}
|
|
1995
2721
|
}
|
|
2722
|
+
// Also set process.env for backwards compat (CLI scripts, legacy readers)
|
|
2723
|
+
process.env.AGENT_USER_EMAIL = owner;
|
|
1996
2724
|
if (resolvedOrgId) {
|
|
1997
2725
|
process.env.AGENT_ORG_ID = resolvedOrgId;
|
|
1998
2726
|
}
|
|
1999
2727
|
else {
|
|
2000
2728
|
delete process.env.AGENT_ORG_ID;
|
|
2001
2729
|
}
|
|
2002
|
-
|
|
2003
|
-
|
|
2730
|
+
return runWithRequestContext({ userEmail: owner, orgId: resolvedOrgId }, () => {
|
|
2731
|
+
const handler = currentDevMode && devHandler ? devHandler : prodHandler;
|
|
2732
|
+
return handler(event);
|
|
2733
|
+
});
|
|
2004
2734
|
}));
|
|
2005
2735
|
// ─── Recurring Jobs Scheduler ──────────────────────────────────────
|
|
2006
2736
|
// Poll every 60 seconds for due recurring jobs and execute them.
|
|
@@ -2012,6 +2742,7 @@ export function createAgentChatPlugin(options) {
|
|
|
2012
2742
|
getActions: () => ({
|
|
2013
2743
|
...templateScripts,
|
|
2014
2744
|
...resourceScripts,
|
|
2745
|
+
...docsScripts,
|
|
2015
2746
|
...chatScripts,
|
|
2016
2747
|
...jobTools,
|
|
2017
2748
|
}),
|
|
@@ -2045,4 +2776,35 @@ export function createAgentChatPlugin(options) {
|
|
|
2045
2776
|
* In production, provides only the default system prompt.
|
|
2046
2777
|
*/
|
|
2047
2778
|
export const defaultAgentChatPlugin = createAgentChatPlugin();
|
|
2779
|
+
// ---------------------------------------------------------------------------
|
|
2780
|
+
// MCP client glue — a shared manager reference + a /_agent-native/mcp/status
|
|
2781
|
+
// route so onboarding / settings UIs can see which MCP servers are live.
|
|
2782
|
+
// ---------------------------------------------------------------------------
|
|
2783
|
+
let _globalMcpManager = null;
|
|
2784
|
+
function setGlobalMcpManager(manager) {
|
|
2785
|
+
_globalMcpManager = manager;
|
|
2786
|
+
}
|
|
2787
|
+
/** Internal: access the current process's MCP client manager, if any. */
|
|
2788
|
+
export function getGlobalMcpManager() {
|
|
2789
|
+
return _globalMcpManager;
|
|
2790
|
+
}
|
|
2791
|
+
function mountMcpStatusRoute(nitroApp, manager) {
|
|
2792
|
+
// Idempotent — agent-chat-plugin can be invoked once per process; guard anyway.
|
|
2793
|
+
if (globalThis.__agentNativeMcpStatusMounted)
|
|
2794
|
+
return;
|
|
2795
|
+
globalThis.__agentNativeMcpStatusMounted = true;
|
|
2796
|
+
try {
|
|
2797
|
+
getH3App(nitroApp).use("/_agent-native/mcp/status", defineEventHandler(async (event) => {
|
|
2798
|
+
if (getMethod(event) !== "GET") {
|
|
2799
|
+
setResponseStatus(event, 405);
|
|
2800
|
+
return { error: "Method not allowed" };
|
|
2801
|
+
}
|
|
2802
|
+
setResponseHeader(event, "Content-Type", "application/json");
|
|
2803
|
+
return manager.getStatus();
|
|
2804
|
+
}));
|
|
2805
|
+
}
|
|
2806
|
+
catch (err) {
|
|
2807
|
+
console.warn(`[mcp-client] Failed to mount /_agent-native/mcp/status: ${err?.message ?? err}`);
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2048
2810
|
//# sourceMappingURL=agent-chat-plugin.js.map
|