@xenosystem/agent-interface-ui 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +67 -0
- package/dist/adapters/agentHostPlatformBridge.d.ts +24 -0
- package/dist/adapters/agentHostPlatformBridge.d.ts.map +1 -0
- package/dist/adapters/agentHostPlatformBridge.js +1244 -0
- package/dist/adapters/agentHostPlatformBridge.js.map +1 -0
- package/dist/adapters/hubAgentPlatformBridge.d.ts +17 -0
- package/dist/adapters/hubAgentPlatformBridge.d.ts.map +1 -0
- package/dist/adapters/hubAgentPlatformBridge.js +109 -0
- package/dist/adapters/hubAgentPlatformBridge.js.map +1 -0
- package/dist/adapters/xenoAgentCompatibilityBridge.d.ts +14 -0
- package/dist/adapters/xenoAgentCompatibilityBridge.d.ts.map +1 -0
- package/dist/adapters/xenoAgentCompatibilityBridge.js +237 -0
- package/dist/adapters/xenoAgentCompatibilityBridge.js.map +1 -0
- package/dist/adapters/xenoAgentHostCatalog.d.ts +40 -0
- package/dist/adapters/xenoAgentHostCatalog.d.ts.map +1 -0
- package/dist/adapters/xenoAgentHostCatalog.js +228 -0
- package/dist/adapters/xenoAgentHostCatalog.js.map +1 -0
- package/dist/components/agent/AIStatusIndicator.d.ts +25 -0
- package/dist/components/agent/AIStatusIndicator.d.ts.map +1 -0
- package/dist/components/agent/AIStatusIndicator.js +85 -0
- package/dist/components/agent/AIStatusIndicator.js.map +1 -0
- package/dist/components/agent/AgentInterface.d.ts +21 -0
- package/dist/components/agent/AgentInterface.d.ts.map +1 -0
- package/dist/components/agent/AgentInterface.js +7586 -0
- package/dist/components/agent/AgentInterface.js.map +1 -0
- package/dist/components/agent/AgentOnboarding.d.ts +16 -0
- package/dist/components/agent/AgentOnboarding.d.ts.map +1 -0
- package/dist/components/agent/AgentOnboarding.js +423 -0
- package/dist/components/agent/AgentOnboarding.js.map +1 -0
- package/dist/components/agent/AgentPtyTerminalPanel.d.ts +13 -0
- package/dist/components/agent/AgentPtyTerminalPanel.d.ts.map +1 -0
- package/dist/components/agent/AgentPtyTerminalPanel.js +129 -0
- package/dist/components/agent/AgentPtyTerminalPanel.js.map +1 -0
- package/dist/components/agent/AgentView.d.ts +143 -0
- package/dist/components/agent/AgentView.d.ts.map +1 -0
- package/dist/components/agent/AgentView.js +7250 -0
- package/dist/components/agent/AgentView.js.map +1 -0
- package/dist/components/agent/AgentWorkbenchCliPanel.d.ts +15 -0
- package/dist/components/agent/AgentWorkbenchCliPanel.d.ts.map +1 -0
- package/dist/components/agent/AgentWorkbenchCliPanel.js +275 -0
- package/dist/components/agent/AgentWorkbenchCliPanel.js.map +1 -0
- package/dist/components/agent/AgentWorkbenchPanel.d.ts +791 -0
- package/dist/components/agent/AgentWorkbenchPanel.d.ts.map +1 -0
- package/dist/components/agent/AgentWorkbenchPanel.js +584 -0
- package/dist/components/agent/AgentWorkbenchPanel.js.map +1 -0
- package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts +11 -0
- package/dist/components/agent/AgentWorkspaceBrowserPanel.d.ts.map +1 -0
- package/dist/components/agent/AgentWorkspaceBrowserPanel.js +198 -0
- package/dist/components/agent/AgentWorkspaceBrowserPanel.js.map +1 -0
- package/dist/components/agent/AssistantTurnStatusNotice.d.ts +16 -0
- package/dist/components/agent/AssistantTurnStatusNotice.d.ts.map +1 -0
- package/dist/components/agent/AssistantTurnStatusNotice.js +54 -0
- package/dist/components/agent/AssistantTurnStatusNotice.js.map +1 -0
- package/dist/components/agent/CommandToolCard.d.ts +11 -0
- package/dist/components/agent/CommandToolCard.d.ts.map +1 -0
- package/dist/components/agent/CommandToolCard.js +29 -0
- package/dist/components/agent/CommandToolCard.js.map +1 -0
- package/dist/components/agent/FleetPanel.d.ts +28 -0
- package/dist/components/agent/FleetPanel.d.ts.map +1 -0
- package/dist/components/agent/FleetPanel.js +175 -0
- package/dist/components/agent/FleetPanel.js.map +1 -0
- package/dist/components/agent/GhostTextArea.d.ts +13 -0
- package/dist/components/agent/GhostTextArea.d.ts.map +1 -0
- package/dist/components/agent/GhostTextArea.js +21 -0
- package/dist/components/agent/GhostTextArea.js.map +1 -0
- package/dist/components/agent/IntakePanel.d.ts +29 -0
- package/dist/components/agent/IntakePanel.d.ts.map +1 -0
- package/dist/components/agent/IntakePanel.js +81 -0
- package/dist/components/agent/IntakePanel.js.map +1 -0
- package/dist/components/agent/KnowledgePanel.d.ts +25 -0
- package/dist/components/agent/KnowledgePanel.d.ts.map +1 -0
- package/dist/components/agent/KnowledgePanel.js +99 -0
- package/dist/components/agent/KnowledgePanel.js.map +1 -0
- package/dist/components/agent/MonacoDiffWorkbenchEditor.d.ts +9 -0
- package/dist/components/agent/MonacoDiffWorkbenchEditor.d.ts.map +1 -0
- package/dist/components/agent/MonacoDiffWorkbenchEditor.js +204 -0
- package/dist/components/agent/MonacoDiffWorkbenchEditor.js.map +1 -0
- package/dist/components/agent/MonacoWorkbenchEditor.d.ts +15 -0
- package/dist/components/agent/MonacoWorkbenchEditor.d.ts.map +1 -0
- package/dist/components/agent/MonacoWorkbenchEditor.js +380 -0
- package/dist/components/agent/MonacoWorkbenchEditor.js.map +1 -0
- package/dist/components/agent/PermissionDialog.d.ts +34 -0
- package/dist/components/agent/PermissionDialog.d.ts.map +1 -0
- package/dist/components/agent/PermissionDialog.js +67 -0
- package/dist/components/agent/PermissionDialog.js.map +1 -0
- package/dist/components/agent/PluginManager.d.ts +20 -0
- package/dist/components/agent/PluginManager.d.ts.map +1 -0
- package/dist/components/agent/PluginManager.js +506 -0
- package/dist/components/agent/PluginManager.js.map +1 -0
- package/dist/components/agent/RunReviewPanel.d.ts +52 -0
- package/dist/components/agent/RunReviewPanel.d.ts.map +1 -0
- package/dist/components/agent/RunReviewPanel.js +236 -0
- package/dist/components/agent/RunReviewPanel.js.map +1 -0
- package/dist/components/agent/SessionsPanel.d.ts +30 -0
- package/dist/components/agent/SessionsPanel.d.ts.map +1 -0
- package/dist/components/agent/SessionsPanel.js +247 -0
- package/dist/components/agent/SessionsPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpAgentConfigForm.d.ts +19 -0
- package/dist/components/agent/acp/AcpAgentConfigForm.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpAgentConfigForm.js +85 -0
- package/dist/components/agent/acp/AcpAgentConfigForm.js.map +1 -0
- package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.d.ts +10 -0
- package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js +80 -0
- package/dist/components/agent/acp/AcpAgentDiagnosticsPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpAgentManager.d.ts +3 -0
- package/dist/components/agent/acp/AcpAgentManager.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpAgentManager.js +152 -0
- package/dist/components/agent/acp/AcpAgentManager.js.map +1 -0
- package/dist/components/agent/acp/AcpAgentTestResultPanel.d.ts +9 -0
- package/dist/components/agent/acp/AcpAgentTestResultPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpAgentTestResultPanel.js +24 -0
- package/dist/components/agent/acp/AcpAgentTestResultPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpApprovalPanel.d.ts +29 -0
- package/dist/components/agent/acp/AcpApprovalPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpApprovalPanel.js +37 -0
- package/dist/components/agent/acp/AcpApprovalPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpCertificationPanel.d.ts +10 -0
- package/dist/components/agent/acp/AcpCertificationPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpCertificationPanel.js +41 -0
- package/dist/components/agent/acp/AcpCertificationPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.d.ts +11 -0
- package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js +32 -0
- package/dist/components/agent/acp/AcpLiveProviderWorkflowPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpProviderManagerPanel.d.ts +7 -0
- package/dist/components/agent/acp/AcpProviderManagerPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpProviderManagerPanel.js +69 -0
- package/dist/components/agent/acp/AcpProviderManagerPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpProviderModelsPanel.d.ts +7 -0
- package/dist/components/agent/acp/AcpProviderModelsPanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpProviderModelsPanel.js +108 -0
- package/dist/components/agent/acp/AcpProviderModelsPanel.js.map +1 -0
- package/dist/components/agent/acp/AcpSupportBundlePanel.d.ts +8 -0
- package/dist/components/agent/acp/AcpSupportBundlePanel.d.ts.map +1 -0
- package/dist/components/agent/acp/AcpSupportBundlePanel.js +56 -0
- package/dist/components/agent/acp/AcpSupportBundlePanel.js.map +1 -0
- package/dist/components/agent/compactionSummary.d.ts +28 -0
- package/dist/components/agent/compactionSummary.d.ts.map +1 -0
- package/dist/components/agent/compactionSummary.js +41 -0
- package/dist/components/agent/compactionSummary.js.map +1 -0
- package/dist/components/agent/monacoWorkbenchShared.d.ts +13 -0
- package/dist/components/agent/monacoWorkbenchShared.d.ts.map +1 -0
- package/dist/components/agent/monacoWorkbenchShared.js +226 -0
- package/dist/components/agent/monacoWorkbenchShared.js.map +1 -0
- package/dist/components/agent/settings/EntitySettingsLayout.d.ts +61 -0
- package/dist/components/agent/settings/EntitySettingsLayout.d.ts.map +1 -0
- package/dist/components/agent/settings/EntitySettingsLayout.js +72 -0
- package/dist/components/agent/settings/EntitySettingsLayout.js.map +1 -0
- package/dist/components/agent/settings/SettingsNavigation.d.ts +8 -0
- package/dist/components/agent/settings/SettingsNavigation.d.ts.map +1 -0
- package/dist/components/agent/settings/SettingsNavigation.js +39 -0
- package/dist/components/agent/settings/SettingsNavigation.js.map +1 -0
- package/dist/components/agent/settings/sections/AccessMembersSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/AccessMembersSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/AccessMembersSection.js +31 -0
- package/dist/components/agent/settings/sections/AccessMembersSection.js.map +1 -0
- package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.d.ts +25 -0
- package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js +56 -0
- package/dist/components/agent/settings/sections/AgentPermissionRulesPanel.js.map +1 -0
- package/dist/components/agent/settings/sections/DangerZoneSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/DangerZoneSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/DangerZoneSection.js +19 -0
- package/dist/components/agent/settings/sections/DangerZoneSection.js.map +1 -0
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js +66 -0
- package/dist/components/agent/settings/sections/DefaultAgentConfigSection.js.map +1 -0
- package/dist/components/agent/settings/sections/EnvironmentSecretsSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/EnvironmentSecretsSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js +87 -0
- package/dist/components/agent/settings/sections/EnvironmentSecretsSection.js.map +1 -0
- package/dist/components/agent/settings/sections/ExportBackupSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/ExportBackupSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/ExportBackupSection.js +23 -0
- package/dist/components/agent/settings/sections/ExportBackupSection.js.map +1 -0
- package/dist/components/agent/settings/sections/GeneralSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/GeneralSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/GeneralSection.js +15 -0
- package/dist/components/agent/settings/sections/GeneralSection.js.map +1 -0
- package/dist/components/agent/settings/sections/IntegrationsSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/IntegrationsSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/IntegrationsSection.js +40 -0
- package/dist/components/agent/settings/sections/IntegrationsSection.js.map +1 -0
- package/dist/components/agent/settings/sections/NotificationsSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/NotificationsSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/NotificationsSection.js +28 -0
- package/dist/components/agent/settings/sections/NotificationsSection.js.map +1 -0
- package/dist/components/agent/settings/sections/ResourceLimitsSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/ResourceLimitsSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/ResourceLimitsSection.js +17 -0
- package/dist/components/agent/settings/sections/ResourceLimitsSection.js.map +1 -0
- package/dist/components/agent/settings/sections/SecurityComplianceSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/SecurityComplianceSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/SecurityComplianceSection.js +28 -0
- package/dist/components/agent/settings/sections/SecurityComplianceSection.js.map +1 -0
- package/dist/components/agent/settings/sections/UsageAnalyticsSection.d.ts +3 -0
- package/dist/components/agent/settings/sections/UsageAnalyticsSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/UsageAnalyticsSection.js +17 -0
- package/dist/components/agent/settings/sections/UsageAnalyticsSection.js.map +1 -0
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.d.ts +54 -0
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.d.ts.map +1 -0
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js +333 -0
- package/dist/components/agent/settings/sections/WorkspaceDirectoryAccessSection.js.map +1 -0
- package/dist/components/agent/settings/shared/CheckboxField.d.ts +13 -0
- package/dist/components/agent/settings/shared/CheckboxField.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/CheckboxField.js +8 -0
- package/dist/components/agent/settings/shared/CheckboxField.js.map +1 -0
- package/dist/components/agent/settings/shared/InputField.d.ts +15 -0
- package/dist/components/agent/settings/shared/InputField.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/InputField.js +7 -0
- package/dist/components/agent/settings/shared/InputField.js.map +1 -0
- package/dist/components/agent/settings/shared/MembersTable.d.ts +11 -0
- package/dist/components/agent/settings/shared/MembersTable.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/MembersTable.js +7 -0
- package/dist/components/agent/settings/shared/MembersTable.js.map +1 -0
- package/dist/components/agent/settings/shared/SettingRow.d.ts +11 -0
- package/dist/components/agent/settings/shared/SettingRow.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/SettingRow.js +6 -0
- package/dist/components/agent/settings/shared/SettingRow.js.map +1 -0
- package/dist/components/agent/settings/shared/SettingsCard.d.ts +11 -0
- package/dist/components/agent/settings/shared/SettingsCard.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/SettingsCard.js +8 -0
- package/dist/components/agent/settings/shared/SettingsCard.js.map +1 -0
- package/dist/components/agent/settings/shared/ToggleSwitch.d.ts +8 -0
- package/dist/components/agent/settings/shared/ToggleSwitch.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/ToggleSwitch.js +6 -0
- package/dist/components/agent/settings/shared/ToggleSwitch.js.map +1 -0
- package/dist/components/agent/settings/shared/UsageChart.d.ts +12 -0
- package/dist/components/agent/settings/shared/UsageChart.d.ts.map +1 -0
- package/dist/components/agent/settings/shared/UsageChart.js +16 -0
- package/dist/components/agent/settings/shared/UsageChart.js.map +1 -0
- package/dist/components/agent/toolCardDisplay.d.ts +24 -0
- package/dist/components/agent/toolCardDisplay.d.ts.map +1 -0
- package/dist/components/agent/toolCardDisplay.js +85 -0
- package/dist/components/agent/toolCardDisplay.js.map +1 -0
- package/dist/components/product/XenoAgentProductHeader.d.ts +18 -0
- package/dist/components/product/XenoAgentProductHeader.d.ts.map +1 -0
- package/dist/components/product/XenoAgentProductHeader.js +25 -0
- package/dist/components/product/XenoAgentProductHeader.js.map +1 -0
- package/dist/components/product/XenoAgentSessionTabs.d.ts +18 -0
- package/dist/components/product/XenoAgentSessionTabs.d.ts.map +1 -0
- package/dist/components/product/XenoAgentSessionTabs.js +103 -0
- package/dist/components/product/XenoAgentSessionTabs.js.map +1 -0
- package/dist/components/ui/CodeBlock.d.ts +8 -0
- package/dist/components/ui/CodeBlock.d.ts.map +1 -0
- package/dist/components/ui/CodeBlock.js +89 -0
- package/dist/components/ui/CodeBlock.js.map +1 -0
- package/dist/components/ui/XenoLogo.d.ts +11 -0
- package/dist/components/ui/XenoLogo.d.ts.map +1 -0
- package/dist/components/ui/XenoLogo.js +9 -0
- package/dist/components/ui/XenoLogo.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +127 -0
- package/dist/index.js.map +1 -0
- package/dist/platformApiTypes.d.ts +3992 -0
- package/dist/platformApiTypes.d.ts.map +1 -0
- package/dist/platformApiTypes.js +2 -0
- package/dist/platformApiTypes.js.map +1 -0
- package/dist/platformBridge.d.ts +9 -0
- package/dist/platformBridge.d.ts.map +1 -0
- package/dist/platformBridge.js +19 -0
- package/dist/platformBridge.js.map +1 -0
- package/dist/providerSelector.d.ts +28 -0
- package/dist/providerSelector.d.ts.map +1 -0
- package/dist/providerSelector.js +104 -0
- package/dist/providerSelector.js.map +1 -0
- package/dist/services/connectionMode.d.ts +13 -0
- package/dist/services/connectionMode.d.ts.map +1 -0
- package/dist/services/connectionMode.js +31 -0
- package/dist/services/connectionMode.js.map +1 -0
- package/dist/sessionTabs.d.ts +48 -0
- package/dist/sessionTabs.d.ts.map +1 -0
- package/dist/sessionTabs.js +106 -0
- package/dist/sessionTabs.js.map +1 -0
- package/dist/stores/acpAgentStore.d.ts +264 -0
- package/dist/stores/acpAgentStore.d.ts.map +1 -0
- package/dist/stores/acpAgentStore.js +825 -0
- package/dist/stores/acpAgentStore.js.map +1 -0
- package/dist/stores/agentChatStore.d.ts +529 -0
- package/dist/stores/agentChatStore.d.ts.map +1 -0
- package/dist/stores/agentChatStore.js +5309 -0
- package/dist/stores/agentChatStore.js.map +1 -0
- package/dist/stores/agentIdeStore.d.ts +9 -0
- package/dist/stores/agentIdeStore.d.ts.map +1 -0
- package/dist/stores/agentIdeStore.js +8 -0
- package/dist/stores/agentIdeStore.js.map +1 -0
- package/dist/stores/agentSearchStore.d.ts +174 -0
- package/dist/stores/agentSearchStore.d.ts.map +1 -0
- package/dist/stores/agentSearchStore.js +305 -0
- package/dist/stores/agentSearchStore.js.map +1 -0
- package/dist/stores/authStore.d.ts +26 -0
- package/dist/stores/authStore.d.ts.map +1 -0
- package/dist/stores/authStore.js +163 -0
- package/dist/stores/authStore.js.map +1 -0
- package/dist/stores/entitySettingsStore.d.ts +236 -0
- package/dist/stores/entitySettingsStore.d.ts.map +1 -0
- package/dist/stores/entitySettingsStore.js +916 -0
- package/dist/stores/entitySettingsStore.js.map +1 -0
- package/dist/stores/permissionStore.d.ts +25 -0
- package/dist/stores/permissionStore.d.ts.map +1 -0
- package/dist/stores/permissionStore.js +58 -0
- package/dist/stores/permissionStore.js.map +1 -0
- package/dist/stores/suggestionStore.d.ts +29 -0
- package/dist/stores/suggestionStore.d.ts.map +1 -0
- package/dist/stores/suggestionStore.js +160 -0
- package/dist/stores/suggestionStore.js.map +1 -0
- package/dist/stores/tabStore.d.ts +30 -0
- package/dist/stores/tabStore.d.ts.map +1 -0
- package/dist/stores/tabStore.js +252 -0
- package/dist/stores/tabStore.js.map +1 -0
- package/dist/stores/themeStore.d.ts +13 -0
- package/dist/stores/themeStore.d.ts.map +1 -0
- package/dist/stores/themeStore.js +77 -0
- package/dist/stores/themeStore.js.map +1 -0
- package/dist/stores/workspaceStore.d.ts +175 -0
- package/dist/stores/workspaceStore.d.ts.map +1 -0
- package/dist/stores/workspaceStore.js +694 -0
- package/dist/stores/workspaceStore.js.map +1 -0
- package/dist/stores/xenoChatStore.d.ts +88 -0
- package/dist/stores/xenoChatStore.d.ts.map +1 -0
- package/dist/stores/xenoChatStore.js +572 -0
- package/dist/stores/xenoChatStore.js.map +1 -0
- package/dist/toolCardProjection.d.ts +33 -0
- package/dist/toolCardProjection.d.ts.map +1 -0
- package/dist/toolCardProjection.js +62 -0
- package/dist/toolCardProjection.js.map +1 -0
- package/dist/types/agentEditor.d.ts +39 -0
- package/dist/types/agentEditor.d.ts.map +1 -0
- package/dist/types/agentEditor.js +2 -0
- package/dist/types/agentEditor.js.map +1 -0
- package/dist/types/agentRuntimeProvider.d.ts +2 -0
- package/dist/types/agentRuntimeProvider.d.ts.map +1 -0
- package/dist/types/agentRuntimeProvider.js +2 -0
- package/dist/types/agentRuntimeProvider.js.map +1 -0
- package/dist/utils/acpExecutionAuthority.d.ts +18 -0
- package/dist/utils/acpExecutionAuthority.d.ts.map +1 -0
- package/dist/utils/acpExecutionAuthority.js +22 -0
- package/dist/utils/acpExecutionAuthority.js.map +1 -0
- package/dist/utils/agentAttachedContextPrompt.d.ts +2 -0
- package/dist/utils/agentAttachedContextPrompt.d.ts.map +1 -0
- package/dist/utils/agentAttachedContextPrompt.js +2 -0
- package/dist/utils/agentAttachedContextPrompt.js.map +1 -0
- package/dist/utils/agentModelContext.d.ts +2 -0
- package/dist/utils/agentModelContext.d.ts.map +1 -0
- package/dist/utils/agentModelContext.js +2 -0
- package/dist/utils/agentModelContext.js.map +1 -0
- package/dist/utils/agentReasoningEffort.d.ts +3 -0
- package/dist/utils/agentReasoningEffort.d.ts.map +1 -0
- package/dist/utils/agentReasoningEffort.js +2 -0
- package/dist/utils/agentReasoningEffort.js.map +1 -0
- package/dist/utils/agentRuntimeProvider.d.ts +3 -0
- package/dist/utils/agentRuntimeProvider.d.ts.map +1 -0
- package/dist/utils/agentRuntimeProvider.js +2 -0
- package/dist/utils/agentRuntimeProvider.js.map +1 -0
- package/dist/utils/cloudModels.d.ts +3 -0
- package/dist/utils/cloudModels.d.ts.map +1 -0
- package/dist/utils/cloudModels.js +181 -0
- package/dist/utils/cloudModels.js.map +1 -0
- package/dist/utils/conversationRuntime.d.ts +3 -0
- package/dist/utils/conversationRuntime.d.ts.map +1 -0
- package/dist/utils/conversationRuntime.js +2 -0
- package/dist/utils/conversationRuntime.js.map +1 -0
- package/dist/utils/fileCreateIntent.d.ts +16 -0
- package/dist/utils/fileCreateIntent.d.ts.map +1 -0
- package/dist/utils/fileCreateIntent.js +123 -0
- package/dist/utils/fileCreateIntent.js.map +1 -0
- package/dist/utils/legacyAgentRuntimeEvents.d.ts +2 -0
- package/dist/utils/legacyAgentRuntimeEvents.d.ts.map +1 -0
- package/dist/utils/legacyAgentRuntimeEvents.js +2 -0
- package/dist/utils/legacyAgentRuntimeEvents.js.map +1 -0
- package/dist/utils/markdownWindowsPaths.d.ts +2 -0
- package/dist/utils/markdownWindowsPaths.d.ts.map +1 -0
- package/dist/utils/markdownWindowsPaths.js +2 -0
- package/dist/utils/markdownWindowsPaths.js.map +1 -0
- package/dist/utils/workspaceSelectionContinuation.d.ts +2 -0
- package/dist/utils/workspaceSelectionContinuation.d.ts.map +1 -0
- package/dist/utils/workspaceSelectionContinuation.js +2 -0
- package/dist/utils/workspaceSelectionContinuation.js.map +1 -0
- package/package.json +53 -0
- package/src/agent.css +1156 -0
- package/src/foundation.css +62 -0
|
@@ -0,0 +1,1244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapts the versioned Agent host client to the temporary legacy-shaped UI
|
|
3
|
+
* bridge. Only host-backed features are exposed; unsupported Hub-only
|
|
4
|
+
* namespaces remain absent so the shared UI renders an honest degraded state.
|
|
5
|
+
*/
|
|
6
|
+
export function createAgentHostPlatformBridge(client, options = {}) {
|
|
7
|
+
const runtimeListeners = new Set();
|
|
8
|
+
const errorListeners = new Set();
|
|
9
|
+
const chooseDirectoryListeners = new Set();
|
|
10
|
+
const workspacePlacementListeners = new Set();
|
|
11
|
+
const permissionListeners = new Set();
|
|
12
|
+
const askUserListeners = new Set();
|
|
13
|
+
const taskListeners = new Set();
|
|
14
|
+
const terminalDataListeners = new Set();
|
|
15
|
+
const terminalExitListeners = new Set();
|
|
16
|
+
const ptyDataListeners = new Set();
|
|
17
|
+
const ptyExitListeners = new Set();
|
|
18
|
+
const runtimeSubscriptions = new Map();
|
|
19
|
+
const chooseDirectorySubscriptions = new Map();
|
|
20
|
+
const workspacePlacementSubscriptions = new Map();
|
|
21
|
+
const sessionListeners = new Set();
|
|
22
|
+
const fleetListeners = new Set();
|
|
23
|
+
const observationListeners = new Set();
|
|
24
|
+
const catalogListeners = new Set();
|
|
25
|
+
const activeConversations = new Map();
|
|
26
|
+
const pendingCancellations = new Set();
|
|
27
|
+
let subscriptionSequence = 0;
|
|
28
|
+
const unsubscribe = client.subscribe((event) => {
|
|
29
|
+
routeHostEvent(event, {
|
|
30
|
+
runtimeListeners,
|
|
31
|
+
errorListeners,
|
|
32
|
+
chooseDirectoryListeners,
|
|
33
|
+
workspacePlacementListeners,
|
|
34
|
+
permissionListeners,
|
|
35
|
+
askUserListeners,
|
|
36
|
+
taskListeners,
|
|
37
|
+
runtimeSubscriptions,
|
|
38
|
+
chooseDirectorySubscriptions,
|
|
39
|
+
workspacePlacementSubscriptions,
|
|
40
|
+
activeConversations,
|
|
41
|
+
terminalDataListeners,
|
|
42
|
+
terminalExitListeners,
|
|
43
|
+
ptyDataListeners,
|
|
44
|
+
ptyExitListeners,
|
|
45
|
+
sessionListeners,
|
|
46
|
+
fleetListeners,
|
|
47
|
+
observationListeners,
|
|
48
|
+
catalogListeners,
|
|
49
|
+
clientInstanceId: client.instanceId,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const unsupported = (feature) => ({ success: false, error: `${feature} is not available on this host yet.` });
|
|
53
|
+
const agent = {
|
|
54
|
+
run: async (params) => runHostPrompt(client, activeConversations, pendingCancellations, params),
|
|
55
|
+
cancel: async (requestId) => cancelByRequestId(client, activeConversations, pendingCancellations, requestId),
|
|
56
|
+
// The legacy per-chunk callback stream (onTextChunk/onToolStart/onToolEnd/onDone)
|
|
57
|
+
// is deliberately ABSENT here: this host publishes the same information as native
|
|
58
|
+
// `runtime.event.appended` envelopes through `onRuntimeEvent`. Registering an
|
|
59
|
+
// inert no-op would make the missing stream indistinguishable from a working one,
|
|
60
|
+
// so callers must feature-detect these methods instead.
|
|
61
|
+
onRuntimeEvent: (callback) => { runtimeListeners.add(callback); },
|
|
62
|
+
offRuntimeEvent: () => { runtimeListeners.clear(); },
|
|
63
|
+
onTaskEvent: (callback) => { taskListeners.add(callback); },
|
|
64
|
+
offTaskEvent: () => { taskListeners.clear(); },
|
|
65
|
+
onError: (callback) => { errorListeners.add(callback); },
|
|
66
|
+
offError: () => { errorListeners.clear(); },
|
|
67
|
+
onPermissionRequest: (callback) => { permissionListeners.add(callback); },
|
|
68
|
+
offPermissionRequest: () => { permissionListeners.clear(); },
|
|
69
|
+
onAskUserRequest: (callback) => { askUserListeners.add(callback); },
|
|
70
|
+
offAskUserRequest: () => { askUserListeners.clear(); },
|
|
71
|
+
onChooseDirectoryRequest: (callback) => { chooseDirectoryListeners.add(callback); },
|
|
72
|
+
offChooseDirectoryRequest: () => { chooseDirectoryListeners.clear(); },
|
|
73
|
+
subscribeChooseDirectoryRequested: (callback) => (addSubscription(chooseDirectorySubscriptions, callback, () => ++subscriptionSequence, 'choose-directory')),
|
|
74
|
+
unsubscribeChooseDirectoryRequested: (id) => chooseDirectorySubscriptions.delete(id),
|
|
75
|
+
onWorkspacePlacementRequest: (callback) => {
|
|
76
|
+
workspacePlacementListeners.add(callback);
|
|
77
|
+
},
|
|
78
|
+
offWorkspacePlacementRequest: () => { workspacePlacementListeners.clear(); },
|
|
79
|
+
subscribeWorkspacePlacementRequested: (callback) => (addSubscription(workspacePlacementSubscriptions, callback, () => ++subscriptionSequence, 'workspace-placement')),
|
|
80
|
+
unsubscribeWorkspacePlacementRequested: (id) => workspacePlacementSubscriptions.delete(id),
|
|
81
|
+
grantAccess: async (input) => client.answerPermission({
|
|
82
|
+
permissionId: input.permissionId,
|
|
83
|
+
granted: true,
|
|
84
|
+
directory: input.directory,
|
|
85
|
+
...(input.selectedOptionId ? { selectedOptionId: input.selectedOptionId } : {}),
|
|
86
|
+
}),
|
|
87
|
+
steerTurn: async (input) => {
|
|
88
|
+
const result = await client.steerTurn(input);
|
|
89
|
+
// A provider that cannot be steered refuses BY NAME. The caller leaves the
|
|
90
|
+
// message queued rather than pretending it was delivered.
|
|
91
|
+
return result.success
|
|
92
|
+
? { success: true }
|
|
93
|
+
: { success: false, error: result.safeError };
|
|
94
|
+
},
|
|
95
|
+
resumeTurn: async (input) => {
|
|
96
|
+
const result = await client.resumeTurn(input);
|
|
97
|
+
return result.success
|
|
98
|
+
? { success: true }
|
|
99
|
+
: { success: false, error: result.safeError };
|
|
100
|
+
},
|
|
101
|
+
/**
|
|
102
|
+
* 🔴 The queue, bound. Both halves, because a read with no undo is
|
|
103
|
+
* a list of things a person can watch and not change.
|
|
104
|
+
*
|
|
105
|
+
* `drop` goes through the client wrapper rather than the transport: its
|
|
106
|
+
* request carries a host-minted command context, and a caller must never
|
|
107
|
+
* forge one.
|
|
108
|
+
*/
|
|
109
|
+
/**
|
|
110
|
+
* 🔴 Coordination §6's human half, bound. Both calls, because a list of
|
|
111
|
+
* withheld messages with no way to approve one is a list of things a
|
|
112
|
+
* person can read and not act on.
|
|
113
|
+
*
|
|
114
|
+
* `release` goes through the client wrapper: its request carries a
|
|
115
|
+
* host-minted command context, and approving another agent's message is
|
|
116
|
+
* exactly the act that should be attributable.
|
|
117
|
+
*/
|
|
118
|
+
listHeldMessages: (input) => client.listHeldMessages(input),
|
|
119
|
+
releaseHeldMessage: (input) => client.releaseHeldMessage(input),
|
|
120
|
+
setInboundPolicy: (input) => client.setInboundPolicy(input),
|
|
121
|
+
listQueuedInstructions: (input) => client.listQueuedInstructions(input),
|
|
122
|
+
dropQueuedInstruction: async (input) => {
|
|
123
|
+
const result = await client.dropQueuedInstruction(input);
|
|
124
|
+
return result.success
|
|
125
|
+
? { success: true }
|
|
126
|
+
: { success: false, safeError: result.safeError };
|
|
127
|
+
},
|
|
128
|
+
listPermissionRules: async () => client.listPermissionRules(),
|
|
129
|
+
revokePermissionRule: async (input) => client.revokePermissionRule(input.ruleId),
|
|
130
|
+
denyAccess: async (input) => client.answerPermission({
|
|
131
|
+
permissionId: input.permissionId,
|
|
132
|
+
granted: false,
|
|
133
|
+
// Present only for "never allow this". The host verifies the id was
|
|
134
|
+
// offered AND that its kind agrees with granted:false before honouring it.
|
|
135
|
+
...(input.selectedOptionId ? { selectedOptionId: input.selectedOptionId } : {}),
|
|
136
|
+
}),
|
|
137
|
+
answerAskUser: async (input) => (client.answerAskUser(input)),
|
|
138
|
+
answerChooseDirectory: async (input) => (client.answerChooseDirectory(input)),
|
|
139
|
+
answerWorkspacePlacement: async (input) => (client.answerWorkspacePlacement(input)),
|
|
140
|
+
listSdkSessions: async (input = {}) => (client.listSdkSessions(input)),
|
|
141
|
+
showSdkSession: async (input) => (client.showSdkSession(input)),
|
|
142
|
+
attachSdkSession: async (input) => (client.attachSdkSession(input)),
|
|
143
|
+
detachSdkSession: async (input) => (client.detachSdkSession(input)),
|
|
144
|
+
deleteSdkSession: async (input) => (client.deleteSdkSession(input)),
|
|
145
|
+
cleanSdkSessions: async (input) => (client.cleanSdkSessions(input)),
|
|
146
|
+
listSdkCheckpoints: async (input) => (client.listSdkCheckpoints(input)),
|
|
147
|
+
restoreSdkCheckpoint: async (input) => (client.restoreSdkCheckpoint(input)),
|
|
148
|
+
deleteSdkCheckpoint: async (input) => (client.deleteSdkCheckpoint(input)),
|
|
149
|
+
readSdkTaskOutput: async (input) => (client.readSdkTaskOutput(input)),
|
|
150
|
+
stopSdkTask: async (input) => (client.stopSdkTask(input)),
|
|
151
|
+
};
|
|
152
|
+
const acp = {
|
|
153
|
+
listAgents: async () => ({ success: true, agents: (await acpProviders(client)).map(toLegacyAgentView) }),
|
|
154
|
+
/**
|
|
155
|
+
* The provider catalog changed — by ANY surface, or by the host itself.
|
|
156
|
+
*
|
|
157
|
+
* A surface reloads after its own edits already; this is for everyone
|
|
158
|
+
* else's, which is the case a multi-surface product has and a single-window
|
|
159
|
+
* one does not.
|
|
160
|
+
*/
|
|
161
|
+
subscribeCatalogChanged: (listener) => {
|
|
162
|
+
catalogListeners.add(listener);
|
|
163
|
+
return () => { catalogListeners.delete(listener); };
|
|
164
|
+
},
|
|
165
|
+
getAgent: async (id) => {
|
|
166
|
+
const provider = (await acpProviders(client)).find((entry) => acpConfigId(entry.id) === id);
|
|
167
|
+
return provider
|
|
168
|
+
? { success: true, agent: toLegacyAgentView(provider) }
|
|
169
|
+
: { success: false, error: 'ACP provider was not found.' };
|
|
170
|
+
},
|
|
171
|
+
getProviderModels: async (id) => {
|
|
172
|
+
const provider = (await acpProviders(client)).find((entry) => acpConfigId(entry.id) === id);
|
|
173
|
+
if (!provider)
|
|
174
|
+
return { success: false, error: 'ACP provider was not found.' };
|
|
175
|
+
return {
|
|
176
|
+
success: true,
|
|
177
|
+
result: {
|
|
178
|
+
success: true,
|
|
179
|
+
modelDiscovery: {
|
|
180
|
+
models: provider.models.map(toLegacyModel),
|
|
181
|
+
defaultModelId: provider.defaultModelId,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
runAgentPrompt: async (params) => runAcpPrompt(client, activeConversations, pendingCancellations, params),
|
|
187
|
+
cancelAgentPrompt: async (params) => cancelAcpPrompt(client, activeConversations, pendingCancellations, params),
|
|
188
|
+
// `acp.closeConversation` is deliberately ABSENT: the versioned host protocol has
|
|
189
|
+
// no command that reaches `AcpSessionService.closeConversation`, so this surface
|
|
190
|
+
// genuinely cannot terminate a conversation's ACP sessions. A stub returning
|
|
191
|
+
// `{ success: true, closedSessionCount: 0 }` told callers the sessions had been
|
|
192
|
+
// closed while the agent processes kept running. Callers feature-detect instead.
|
|
193
|
+
listProviderCatalog: async () => ({
|
|
194
|
+
success: true,
|
|
195
|
+
catalog: {
|
|
196
|
+
acpEnabled: true,
|
|
197
|
+
source: 'fallback',
|
|
198
|
+
refreshedAt: new Date().toISOString(),
|
|
199
|
+
entries: (await acpProviders(client)).map(toLegacyCatalogEntry),
|
|
200
|
+
syncErrors: [],
|
|
201
|
+
},
|
|
202
|
+
}),
|
|
203
|
+
syncProviderCatalog: async () => unsupported('ACP catalog mutation'),
|
|
204
|
+
setProviderCatalogEnabled: async () => unsupported('ACP catalog mutation'),
|
|
205
|
+
setCatalogProviderEnabled: async () => unsupported('ACP catalog mutation'),
|
|
206
|
+
updateCatalogProvider: async () => unsupported('ACP catalog mutation'),
|
|
207
|
+
setPreferredCatalogProvider: async () => unsupported('ACP catalog mutation'),
|
|
208
|
+
saveAgent: async () => unsupported('ACP registry mutation'),
|
|
209
|
+
createFixtureAgent: async () => unsupported('ACP registry mutation'),
|
|
210
|
+
createLocalProviderAgent: async () => unsupported('ACP registry mutation'),
|
|
211
|
+
removeAgent: async () => ({ ...unsupported('ACP registry mutation'), removed: false }),
|
|
212
|
+
testAgent: async () => ({ ...unsupported('ACP diagnostics'), updateCount: 0, diagnostics: {} }),
|
|
213
|
+
certifyAgent: async () => unsupported('ACP certification'),
|
|
214
|
+
approveProvider: async (id, providerId) => approveAcpProvider(client, id, providerId, 'approve'),
|
|
215
|
+
revokeProvider: async (id, providerId) => approveAcpProvider(client, id, providerId, 'revoke'),
|
|
216
|
+
getDiagnostics: async () => unsupported('ACP diagnostics'),
|
|
217
|
+
};
|
|
218
|
+
const workspaceError = 'Workspace tools are not available on this host yet.';
|
|
219
|
+
const workspace = {
|
|
220
|
+
pickDirectory: options.shell?.pickDirectory
|
|
221
|
+
|| (async () => ({ success: false, path: null, error: workspaceError })),
|
|
222
|
+
pickExecutable: options.shell?.pickExecutable
|
|
223
|
+
|| (async () => ({ success: false, path: null, error: workspaceError })),
|
|
224
|
+
listDirectory: async (input) => client.listWorkspaceDirectory({
|
|
225
|
+
...workspaceAccessInput(input),
|
|
226
|
+
dirPath: input.dirPath,
|
|
227
|
+
}),
|
|
228
|
+
readFile: async (input) => client.readWorkspaceFile({
|
|
229
|
+
...workspaceAccessInput(input),
|
|
230
|
+
path: input.path,
|
|
231
|
+
}),
|
|
232
|
+
getFileOpenOptions: options.shell?.getFileOpenOptions || (async () => ({
|
|
233
|
+
success: false,
|
|
234
|
+
path: null,
|
|
235
|
+
defaultApp: null,
|
|
236
|
+
options: [],
|
|
237
|
+
revealLabel: 'Open in Explorer',
|
|
238
|
+
error: workspaceError,
|
|
239
|
+
})),
|
|
240
|
+
openFileWith: options.shell?.openFileWith
|
|
241
|
+
|| (async () => ({ success: false, path: null, target: null, error: workspaceError })),
|
|
242
|
+
runCommand: async (input) => client.runWorkspaceCommand({
|
|
243
|
+
...workspaceAccessInput(input),
|
|
244
|
+
command: input.command,
|
|
245
|
+
...(input.cwd ? { cwd: input.cwd } : {}),
|
|
246
|
+
...(input.timeoutMs ? { timeoutMs: input.timeoutMs } : {}),
|
|
247
|
+
}),
|
|
248
|
+
terminalStart: async (input) => client.startWorkspaceTerminal({
|
|
249
|
+
...workspaceAccessInput(input),
|
|
250
|
+
command: input.command,
|
|
251
|
+
...(input.cwd ? { cwd: input.cwd } : {}),
|
|
252
|
+
...(input.timeoutMs ? { timeoutMs: input.timeoutMs } : {}),
|
|
253
|
+
}),
|
|
254
|
+
terminalStop: async (input) => client.stopWorkspaceTerminal({
|
|
255
|
+
...workspaceAccessInput(input),
|
|
256
|
+
terminalId: input.terminalId,
|
|
257
|
+
}),
|
|
258
|
+
ptyStart: async (input) => client.startWorkspacePty({
|
|
259
|
+
...workspaceAccessInput(input),
|
|
260
|
+
...(input.cwd ? { cwd: input.cwd } : {}),
|
|
261
|
+
...(input.cols ? { cols: input.cols } : {}),
|
|
262
|
+
...(input.rows ? { rows: input.rows } : {}),
|
|
263
|
+
}),
|
|
264
|
+
ptySnapshot: async (input) => client.snapshotWorkspacePty({
|
|
265
|
+
...workspaceAccessInput(input),
|
|
266
|
+
terminalId: input.terminalId,
|
|
267
|
+
}),
|
|
268
|
+
ptyInput: async (input) => client.inputWorkspacePty({
|
|
269
|
+
...workspaceAccessInput(input),
|
|
270
|
+
terminalId: input.terminalId,
|
|
271
|
+
data: input.data,
|
|
272
|
+
}),
|
|
273
|
+
ptyResize: async (input) => client.resizeWorkspacePty({
|
|
274
|
+
...workspaceAccessInput(input),
|
|
275
|
+
terminalId: input.terminalId,
|
|
276
|
+
cols: input.cols,
|
|
277
|
+
rows: input.rows,
|
|
278
|
+
}),
|
|
279
|
+
ptyClear: async (input) => client.clearWorkspacePty({
|
|
280
|
+
...workspaceAccessInput(input),
|
|
281
|
+
terminalId: input.terminalId,
|
|
282
|
+
}),
|
|
283
|
+
ptyStop: async (input) => client.stopWorkspacePty({
|
|
284
|
+
...workspaceAccessInput(input),
|
|
285
|
+
terminalId: input.terminalId,
|
|
286
|
+
}),
|
|
287
|
+
browserRegister: async () => ({ success: false, error: workspaceError }),
|
|
288
|
+
browserUnregister: async () => ({ success: false, error: workspaceError }),
|
|
289
|
+
browserList: async () => ({ success: false, tabs: [], error: workspaceError }),
|
|
290
|
+
browserSnapshot: async () => ({ success: false, snapshot: null, error: workspaceError }),
|
|
291
|
+
browserGoto: async () => ({ success: false, error: workspaceError }),
|
|
292
|
+
browserClick: async () => ({ success: false, error: workspaceError }),
|
|
293
|
+
browserType: async () => ({ success: false, error: workspaceError }),
|
|
294
|
+
browserKey: async () => ({ success: false, error: workspaceError }),
|
|
295
|
+
onPtyData: (callback) => { ptyDataListeners.add(callback); },
|
|
296
|
+
offPtyData: () => { ptyDataListeners.clear(); },
|
|
297
|
+
onPtyExit: (callback) => { ptyExitListeners.add(callback); },
|
|
298
|
+
offPtyExit: () => { ptyExitListeners.clear(); },
|
|
299
|
+
onTerminalData: (callback) => { terminalDataListeners.add(callback); },
|
|
300
|
+
offTerminalData: () => { terminalDataListeners.clear(); },
|
|
301
|
+
onTerminalExit: (callback) => { terminalExitListeners.add(callback); },
|
|
302
|
+
offTerminalExit: () => { terminalExitListeners.clear(); },
|
|
303
|
+
writeFile: async (input) => client.writeWorkspaceFile({
|
|
304
|
+
...workspaceAccessInput(input),
|
|
305
|
+
path: input.path,
|
|
306
|
+
content: input.content,
|
|
307
|
+
}),
|
|
308
|
+
openApp: options.shell?.openApp
|
|
309
|
+
|| (async () => ({ success: false, appPath: null, error: workspaceError })),
|
|
310
|
+
};
|
|
311
|
+
const engineering = {
|
|
312
|
+
gitStatus: (input) => client.requestEngineering('engineering.git.status', input),
|
|
313
|
+
gitDiff: (input) => client.requestEngineering('engineering.git.diff', input),
|
|
314
|
+
gitStage: (input) => client.requestEngineering('engineering.git.stage', input),
|
|
315
|
+
gitUnstage: (input) => client.requestEngineering('engineering.git.unstage', input),
|
|
316
|
+
gitCommit: (input) => client.requestEngineering('engineering.git.commit', input),
|
|
317
|
+
gitBranch: (input) => client.requestEngineering('engineering.git.branch', input),
|
|
318
|
+
gitPush: (input) => client.requestEngineering('engineering.git.push', input),
|
|
319
|
+
gitCreatePullRequest: (input) => client.requestEngineering('engineering.git.pr.create', input),
|
|
320
|
+
landingEnqueue: (input) => client.requestEngineering('engineering.landing.enqueue', input),
|
|
321
|
+
landingRemove: (input) => client.requestEngineering('engineering.landing.remove', input),
|
|
322
|
+
landingStatus: (input) => client.requestEngineering('engineering.landing.status', input),
|
|
323
|
+
landingVerify: (input) => client.requestEngineering('engineering.landing.verify', input),
|
|
324
|
+
landingLand: (input) => client.requestEngineering('engineering.landing.land', input),
|
|
325
|
+
discoverChecks: (input) => client.requestEngineering('engineering.checks.discover', input),
|
|
326
|
+
runCheck: (input) => client.requestEngineering('engineering.checks.run', input),
|
|
327
|
+
startBackgroundCheck: (input) => client.requestEngineering('engineering.background.start', input),
|
|
328
|
+
listBackgroundRuns: (input) => client.requestEngineering('engineering.background.list', input),
|
|
329
|
+
readBackgroundRunOutput: (input) => client.requestEngineering('engineering.background.output', input),
|
|
330
|
+
stopBackgroundRun: (input) => client.requestEngineering('engineering.background.stop', input),
|
|
331
|
+
listRuns: (input) => client.requestEngineering('engineering.runs.list', input),
|
|
332
|
+
diagnostics: (input) => client.requestEngineering('engineering.diagnostics', input),
|
|
333
|
+
listPatchReviews: (input) => client.requestEngineering('engineering.patches.list', input),
|
|
334
|
+
enqueuePatchReview: (input) => client.requestEngineering('engineering.patches.enqueue', input),
|
|
335
|
+
updatePatchReview: (input) => client.requestEngineering('engineering.patches.update', input),
|
|
336
|
+
reviewPatchSelection: (input) => client.requestEngineering('engineering.patches.review', input),
|
|
337
|
+
listCheckpoints: (input) => client.requestEngineering('engineering.checkpoints.list', input),
|
|
338
|
+
compareCheckpoints: (input) => client.requestEngineering('engineering.checkpoints.compare', input),
|
|
339
|
+
restoreCheckpoint: (input) => client.requestEngineering('engineering.checkpoints.restore', input),
|
|
340
|
+
listSessions: (input) => client.requestEngineering('engineering.sessions.list', input),
|
|
341
|
+
runtimeTimeline: (input) => client.requestEngineering('engineering.runtime.timeline', input),
|
|
342
|
+
};
|
|
343
|
+
const knowledge = {
|
|
344
|
+
list: (input) => client.requestKnowledge('knowledge.list', input),
|
|
345
|
+
record: (input) => client.requestKnowledge('knowledge.record', input),
|
|
346
|
+
forget: (input) => client.requestKnowledge('knowledge.forget', input),
|
|
347
|
+
context: (input) => client.requestKnowledge('knowledge.context', input),
|
|
348
|
+
};
|
|
349
|
+
const intake = {
|
|
350
|
+
sources: (input) => client.requestIntake('intake.sources.list', input),
|
|
351
|
+
list: (input) => client.requestIntake('intake.items.list', input),
|
|
352
|
+
claim: (input) => client.requestIntake('intake.item.claim', input),
|
|
353
|
+
release: (input) => client.requestIntake('intake.item.release', input),
|
|
354
|
+
dispatch: (input) => client.requestIntake('intake.item.dispatch', input),
|
|
355
|
+
};
|
|
356
|
+
const session = {
|
|
357
|
+
list: (input) => client.requestSession('session.list', input),
|
|
358
|
+
attach: (input) => client.requestSession('session.attach', input),
|
|
359
|
+
detach: (input) => client.requestSession('session.detach', input),
|
|
360
|
+
snapshot: (input) => client.requestSession('session.snapshot', input),
|
|
361
|
+
/**
|
|
362
|
+
* 🔴 The ORDINARY typing path, and it was bound nowhere.
|
|
363
|
+
*
|
|
364
|
+
* Six of the seven session methods were on this bridge and this one was
|
|
365
|
+
* not, so the only way a surface could type was `takeover` — which seizes
|
|
366
|
+
* the write lease and records an intervention, because §5.5 is explicit
|
|
367
|
+
* that typing IS the takeover. Every keystroke read as "this agent is going
|
|
368
|
+
* wrong now".
|
|
369
|
+
*/
|
|
370
|
+
/**
|
|
371
|
+
* 🔴 The command context is minted HERE, not asked of the caller.
|
|
372
|
+
*
|
|
373
|
+
* A fresh id per send, because two identical keystrokes are two inputs and
|
|
374
|
+
* a shared idempotency key would make the second one a replay of the first.
|
|
375
|
+
* Minting it in the transport also means no surface can forget the field —
|
|
376
|
+
* the reason this method sat unbound is that its request was hard to
|
|
377
|
+
* satisfy from a panel.
|
|
378
|
+
*/
|
|
379
|
+
input: (input) => client.requestSession('session.input', {
|
|
380
|
+
...input,
|
|
381
|
+
command: {
|
|
382
|
+
schemaVersion: 1,
|
|
383
|
+
commandId: `session-input-${++subscriptionSequence}-${client.instanceId}`,
|
|
384
|
+
idempotencyKey: `session-input-${subscriptionSequence}-${client.instanceId}`,
|
|
385
|
+
client: client.clientIdentity,
|
|
386
|
+
},
|
|
387
|
+
}),
|
|
388
|
+
takeover: (input) => client.requestSession('session.takeover', input),
|
|
389
|
+
/**
|
|
390
|
+
* Fires when a session opens, closes, or gains or loses a viewer.
|
|
391
|
+
*
|
|
392
|
+
* Returns its own unsubscribe rather than taking an id, because there is
|
|
393
|
+
* exactly one caller shape — a panel that mounts and unmounts — and an id
|
|
394
|
+
* table would be a second thing to keep in sync with it.
|
|
395
|
+
*/
|
|
396
|
+
subscribeChanged: (listener) => {
|
|
397
|
+
sessionListeners.add(listener);
|
|
398
|
+
return () => { sessionListeners.delete(listener); };
|
|
399
|
+
},
|
|
400
|
+
release: (input) => client.requestSession('session.release', input),
|
|
401
|
+
};
|
|
402
|
+
const fleet = {
|
|
403
|
+
view: (input) => client.requestFleet('fleet.view', input),
|
|
404
|
+
/** Fires when anything a board row is composed from moves. See the router. */
|
|
405
|
+
subscribeChanged: (listener) => {
|
|
406
|
+
fleetListeners.add(listener);
|
|
407
|
+
return () => { fleetListeners.delete(listener); };
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
const review = {
|
|
411
|
+
snapshot: (input) => client.requestRunObservation('run.observation.snapshot', input),
|
|
412
|
+
change: (input) => client.requestRunObservation('run.observation.change', input),
|
|
413
|
+
overlaps: (input) => client.requestRunObservation('run.observation.overlaps', input),
|
|
414
|
+
/**
|
|
415
|
+
* A run's tier-1 change set moved — §2.9.
|
|
416
|
+
*
|
|
417
|
+
* The payload carries the run it belongs to; a subscriber watching ONE run
|
|
418
|
+
* filters for itself, because a review pane must not re-read a diff because
|
|
419
|
+
* some other run wrote a file.
|
|
420
|
+
*/
|
|
421
|
+
subscribeChanged: (listener) => {
|
|
422
|
+
observationListeners.add(listener);
|
|
423
|
+
return () => { observationListeners.delete(listener); };
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
const bridge = {
|
|
427
|
+
debug: {
|
|
428
|
+
log: options.log || ((scope, message, meta) => {
|
|
429
|
+
console.debug(`[${scope}] ${message}`, meta || '');
|
|
430
|
+
}),
|
|
431
|
+
},
|
|
432
|
+
updater: {
|
|
433
|
+
// Only `check` and `getVersion` exist here. `download`/`install` and the update
|
|
434
|
+
// lifecycle listeners are deliberately ABSENT: this host runs no update pipeline,
|
|
435
|
+
// and no-op implementations would have accepted a download request or an update
|
|
436
|
+
// listener that could never resolve or fire.
|
|
437
|
+
check: async () => unsupported('Updater'),
|
|
438
|
+
getVersion: async () => options.appVersion || '0.0.0',
|
|
439
|
+
},
|
|
440
|
+
agentContext: {
|
|
441
|
+
// No host command reports installed apps or the signed-in user, so this
|
|
442
|
+
// reports failure rather than an authoritative-looking empty machine.
|
|
443
|
+
get: async () => ({ ...unsupported('Agent runtime context'), context: null }),
|
|
444
|
+
},
|
|
445
|
+
workspaceStorage: {
|
|
446
|
+
save: async (workspaces) => client.saveWorkspaces(Array.isArray(workspaces) ? workspaces : []),
|
|
447
|
+
load: async () => client.loadWorkspaces(),
|
|
448
|
+
// `onChanged`/`offChanged` are deliberately ABSENT: the host emits no
|
|
449
|
+
// workspace-state change event, so cross-surface workspace reload cannot work
|
|
450
|
+
// here. No-op registrars satisfied every existence check while guaranteeing the
|
|
451
|
+
// callback would never fire; callers feature-detect instead.
|
|
452
|
+
},
|
|
453
|
+
agentStorage: {
|
|
454
|
+
saveConversation: async (conversation) => client.saveConversation(conversation),
|
|
455
|
+
loadConversations: async () => client.loadConversations(),
|
|
456
|
+
deleteConversation: async (id) => client.deleteConversation(id),
|
|
457
|
+
},
|
|
458
|
+
runtimeEvents: {
|
|
459
|
+
append: async () => unsupported('Renderer-authored runtime events'),
|
|
460
|
+
list: async (params) => {
|
|
461
|
+
try {
|
|
462
|
+
const result = await client.listRuntimeEvents(toRuntimeEventListRequest(params));
|
|
463
|
+
return { success: true, events: result.events };
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
return { success: false, events: [], error: safeError(error) };
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
listSubagentTrace: async (params) => {
|
|
470
|
+
try {
|
|
471
|
+
const result = await client.listRuntimeEvents(toRuntimeEventListRequest(params));
|
|
472
|
+
return { success: true, events: result.events };
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
return { success: false, events: [], error: safeError(error) };
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
project: async () => unsupported('Host runtime projection'),
|
|
479
|
+
repair: async () => unsupported('Runtime-event repair'),
|
|
480
|
+
subscribeAppended: (callback) => (addSubscription(runtimeSubscriptions, callback, () => ++subscriptionSequence, 'runtime')),
|
|
481
|
+
unsubscribeAppended: (id) => runtimeSubscriptions.delete(id),
|
|
482
|
+
},
|
|
483
|
+
workspace,
|
|
484
|
+
engineering,
|
|
485
|
+
review,
|
|
486
|
+
fleet,
|
|
487
|
+
session,
|
|
488
|
+
intake,
|
|
489
|
+
knowledge,
|
|
490
|
+
agent,
|
|
491
|
+
acp,
|
|
492
|
+
};
|
|
493
|
+
return {
|
|
494
|
+
bridge,
|
|
495
|
+
dispose() {
|
|
496
|
+
unsubscribe();
|
|
497
|
+
runtimeListeners.clear();
|
|
498
|
+
errorListeners.clear();
|
|
499
|
+
chooseDirectoryListeners.clear();
|
|
500
|
+
workspacePlacementListeners.clear();
|
|
501
|
+
permissionListeners.clear();
|
|
502
|
+
askUserListeners.clear();
|
|
503
|
+
taskListeners.clear();
|
|
504
|
+
runtimeSubscriptions.clear();
|
|
505
|
+
chooseDirectorySubscriptions.clear();
|
|
506
|
+
workspacePlacementSubscriptions.clear();
|
|
507
|
+
terminalDataListeners.clear();
|
|
508
|
+
terminalExitListeners.clear();
|
|
509
|
+
ptyDataListeners.clear();
|
|
510
|
+
ptyExitListeners.clear();
|
|
511
|
+
activeConversations.clear();
|
|
512
|
+
pendingCancellations.clear();
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
function routeHostEvent(event, state) {
|
|
517
|
+
/**
|
|
518
|
+
* Sessions changed — ADE §2.8.
|
|
519
|
+
*
|
|
520
|
+
* 🔴 The host has always published these and NOTHING listened, so a panel
|
|
521
|
+
* that read `session.list` once on mount never learned about a session opened
|
|
522
|
+
* afterwards. Since a run gets its session at turn start, that is every
|
|
523
|
+
* session but the ones that already existed — the list was correct only for
|
|
524
|
+
* an instant.
|
|
525
|
+
*
|
|
526
|
+
* IDS AND COUNTS ONLY, which is why this is safe to broadcast. Terminal bytes
|
|
527
|
+
* are per-viewer and large, and the substrate deliberately keeps them off the
|
|
528
|
+
* event feed; `session.snapshot` is the read path for output and stays a poll.
|
|
529
|
+
*/
|
|
530
|
+
/**
|
|
531
|
+
* The provider catalog changed — a provider was registered, removed, or the
|
|
532
|
+
* catalog reloaded.
|
|
533
|
+
*
|
|
534
|
+
* 🔴 Published since the host existed and routed NOWHERE, which matters
|
|
535
|
+
* because this repo is explicitly multi-surface: standalone, Hub, and Shell
|
|
536
|
+
* next. A list of agents is self-consistent only for the surface that changed
|
|
537
|
+
* it — the store reloads after its OWN mutations — so another window adding
|
|
538
|
+
* an ACP agent left every other window showing a catalog that no longer
|
|
539
|
+
* exists. That is a designed scenario here, not a hypothetical one.
|
|
540
|
+
*/
|
|
541
|
+
if (event.type === 'provider.catalog.changed') {
|
|
542
|
+
for (const listener of [...state.catalogListeners])
|
|
543
|
+
listener(event.payload);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (event.type === 'session.event') {
|
|
547
|
+
for (const listener of [...state.sessionListeners])
|
|
548
|
+
listener(event.payload);
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* The fleet board changed — ADE §5.2/§5.4.
|
|
553
|
+
*
|
|
554
|
+
* 🔴 TWO event types, ONE subscription, because a board row is composed from
|
|
555
|
+
* both: `coordination.event` moves claims, collisions and run state;
|
|
556
|
+
* `run.observation` moves the change counts and whether the diff can be
|
|
557
|
+
* trusted. A surface subscribing to only one would be right about half of
|
|
558
|
+
* each row.
|
|
559
|
+
*
|
|
560
|
+
* ⚠️ This corrects a note left last iteration, which said a live
|
|
561
|
+
* coordination feed was unnecessary "because the fleet board polls
|
|
562
|
+
* `fleet.view`". It does not poll. It read once on mount, so the board was
|
|
563
|
+
* accurate for an instant and then silently stale — the same defect the
|
|
564
|
+
* sessions panel had, in the surface a person uses to decide whether work is
|
|
565
|
+
* safe to land.
|
|
566
|
+
*/
|
|
567
|
+
if (event.type === 'coordination.event' || event.type === 'run.observation') {
|
|
568
|
+
for (const listener of [...state.fleetListeners])
|
|
569
|
+
listener(event.payload);
|
|
570
|
+
/**
|
|
571
|
+
* 🔴 `run.observation` reaches TWO surfaces, and they want different
|
|
572
|
+
* slices of it. The board wants every run's counts; a review pane wants one
|
|
573
|
+
* run's diff. Both read the same event and each filters for itself, rather
|
|
574
|
+
* than the router deciding — it does not know which run anyone is looking
|
|
575
|
+
* at.
|
|
576
|
+
*/
|
|
577
|
+
if (event.type === 'run.observation') {
|
|
578
|
+
for (const listener of [...state.observationListeners])
|
|
579
|
+
listener(event.payload);
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
if (event.type === 'runtime.event.appended') {
|
|
584
|
+
const payload = asRecord(event.payload);
|
|
585
|
+
const envelope = asRecord(payload.event);
|
|
586
|
+
const requestId = cleanString(payload.requestId) || cleanString(envelope.requestId);
|
|
587
|
+
if (!requestId || !isRecord(envelope.event))
|
|
588
|
+
return;
|
|
589
|
+
const legacyPayload = { requestId, event: structuredClone(envelope.event) };
|
|
590
|
+
for (const listener of [...state.runtimeListeners])
|
|
591
|
+
listener(legacyPayload);
|
|
592
|
+
for (const listener of [...state.runtimeSubscriptions.values()]) {
|
|
593
|
+
listener({ requestId, event: structuredClone(envelope) });
|
|
594
|
+
}
|
|
595
|
+
if (isTerminalEvent(envelope.event))
|
|
596
|
+
state.activeConversations.delete(requestId);
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
if (event.type === 'turn.execution.completed') {
|
|
600
|
+
// The host's own terminal signal. `isTerminalEvent` below still clears on provider-specific
|
|
601
|
+
// strings, and deliberately stays: it is the fine-grained stream. This is the coarse fact
|
|
602
|
+
// that does not depend on knowing which provider ran, so a turn whose adapter emits a
|
|
603
|
+
// terminal type this bridge has never heard of no longer appears to run forever.
|
|
604
|
+
const requestId = cleanString(asRecord(event.payload).requestId);
|
|
605
|
+
if (requestId)
|
|
606
|
+
state.activeConversations.delete(requestId);
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (event.type === 'turn.execution.abandoned') {
|
|
610
|
+
// 🔴 Surfaced as an ERROR, not a quiet clear. The host stopped tracking the turn and
|
|
611
|
+
// released its capacity, but the adapter may still be running — so silently dropping it
|
|
612
|
+
// would show the user a finished turn while work continues behind them. Saying so is the
|
|
613
|
+
// whole point of the event existing.
|
|
614
|
+
const payload = asRecord(event.payload);
|
|
615
|
+
const requestId = cleanString(payload.requestId);
|
|
616
|
+
if (!requestId)
|
|
617
|
+
return;
|
|
618
|
+
const failure = {
|
|
619
|
+
requestId,
|
|
620
|
+
error: cleanString(payload.safeError)
|
|
621
|
+
|| 'The Agent host stopped tracking this turn. The runtime may still be running.',
|
|
622
|
+
context: 'host',
|
|
623
|
+
};
|
|
624
|
+
for (const listener of [...state.errorListeners])
|
|
625
|
+
listener(failure);
|
|
626
|
+
state.activeConversations.delete(requestId);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (event.type === 'turn.execution.failed') {
|
|
630
|
+
const payload = asRecord(event.payload);
|
|
631
|
+
const requestId = cleanString(payload.requestId);
|
|
632
|
+
if (!requestId)
|
|
633
|
+
return;
|
|
634
|
+
const failure = {
|
|
635
|
+
requestId,
|
|
636
|
+
error: cleanString(payload.safeError) || 'The Agent host could not execute this turn.',
|
|
637
|
+
context: 'host',
|
|
638
|
+
};
|
|
639
|
+
for (const listener of [...state.errorListeners])
|
|
640
|
+
listener(failure);
|
|
641
|
+
state.activeConversations.delete(requestId);
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
if (event.type === 'elicitation.choose-directory.requested') {
|
|
645
|
+
const payload = asRecord(event.payload);
|
|
646
|
+
const requestId = cleanString(payload.requestId);
|
|
647
|
+
const chooseDirectoryId = cleanString(payload.chooseDirectoryId);
|
|
648
|
+
if (!requestId || !chooseDirectoryId)
|
|
649
|
+
return;
|
|
650
|
+
const normalized = {
|
|
651
|
+
requestId,
|
|
652
|
+
chooseDirectoryId,
|
|
653
|
+
...(cleanString(payload.title) ? { title: cleanString(payload.title) } : {}),
|
|
654
|
+
};
|
|
655
|
+
for (const listener of [...state.chooseDirectoryListeners])
|
|
656
|
+
listener(normalized);
|
|
657
|
+
for (const listener of [...state.chooseDirectorySubscriptions.values()])
|
|
658
|
+
listener(normalized);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (event.type === 'elicitation.workspace-placement.requested') {
|
|
662
|
+
const payload = asRecord(event.payload);
|
|
663
|
+
const requestId = cleanString(payload.requestId);
|
|
664
|
+
const workspacePlacementId = cleanString(payload.workspacePlacementId);
|
|
665
|
+
const directory = cleanString(payload.directory);
|
|
666
|
+
if (!requestId || !workspacePlacementId || !directory)
|
|
667
|
+
return;
|
|
668
|
+
const normalized = {
|
|
669
|
+
requestId,
|
|
670
|
+
workspacePlacementId,
|
|
671
|
+
directory,
|
|
672
|
+
...(cleanString(payload.title) ? { title: cleanString(payload.title) } : {}),
|
|
673
|
+
};
|
|
674
|
+
for (const listener of [...state.workspacePlacementListeners])
|
|
675
|
+
listener(normalized);
|
|
676
|
+
for (const listener of [...state.workspacePlacementSubscriptions.values()])
|
|
677
|
+
listener(normalized);
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
if (event.type === 'elicitation.permission.requested') {
|
|
681
|
+
const payload = asRecord(event.payload);
|
|
682
|
+
const requestId = cleanString(payload.requestId);
|
|
683
|
+
const permissionId = cleanString(payload.permissionId);
|
|
684
|
+
const toolName = cleanString(payload.toolName);
|
|
685
|
+
const path = cleanString(payload.path, 100_000);
|
|
686
|
+
const directory = cleanString(payload.directory, 2_000);
|
|
687
|
+
// Identity is required — without a requestId the surface cannot attach the
|
|
688
|
+
// prompt to a conversation, and without a permissionId it cannot be
|
|
689
|
+
// answered. `path` and `directory` are NOT required: an ACP `execute` call
|
|
690
|
+
// legitimately names no file, and dropping those events silently is how a
|
|
691
|
+
// permission prompt goes missing rather than being refused.
|
|
692
|
+
if (!requestId || !permissionId || !toolName)
|
|
693
|
+
return;
|
|
694
|
+
const normalized = {
|
|
695
|
+
requestId,
|
|
696
|
+
permissionId,
|
|
697
|
+
toolName,
|
|
698
|
+
// Empty is a truthful "none" here. Inventing a directory would be worse
|
|
699
|
+
// than an empty one: the SDK-native lane widens a real grant from this
|
|
700
|
+
// field, so a fabricated value could authorise a directory nobody chose.
|
|
701
|
+
path: path || '',
|
|
702
|
+
directory: directory || '',
|
|
703
|
+
...(cleanString(payload.allowAlwaysOptionId, 500)
|
|
704
|
+
? { allowAlwaysOptionId: cleanString(payload.allowAlwaysOptionId, 500) }
|
|
705
|
+
: {}),
|
|
706
|
+
...(cleanString(payload.rejectAlwaysOptionId, 500)
|
|
707
|
+
? { rejectAlwaysOptionId: cleanString(payload.rejectAlwaysOptionId, 500) }
|
|
708
|
+
: {}),
|
|
709
|
+
...(cleanString(payload.browserOrigin, 2_000)
|
|
710
|
+
? { browserOrigin: cleanString(payload.browserOrigin, 2_000) }
|
|
711
|
+
: {}),
|
|
712
|
+
};
|
|
713
|
+
for (const listener of [...state.permissionListeners])
|
|
714
|
+
listener(normalized);
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
if (event.type === 'elicitation.ask-user.requested') {
|
|
718
|
+
const payload = asRecord(event.payload);
|
|
719
|
+
const requestId = cleanString(payload.requestId);
|
|
720
|
+
const askUserId = cleanString(payload.askUserId);
|
|
721
|
+
const question = cleanString(payload.question, 100_000);
|
|
722
|
+
if (!requestId || !askUserId || !question)
|
|
723
|
+
return;
|
|
724
|
+
const options = stringArray(payload.options, 100, 10_000);
|
|
725
|
+
const normalized = {
|
|
726
|
+
requestId,
|
|
727
|
+
askUserId,
|
|
728
|
+
question,
|
|
729
|
+
...(options.length > 0 ? { options } : {}),
|
|
730
|
+
...(cleanString(payload.context, 100_000) ? { context: cleanString(payload.context, 100_000) } : {}),
|
|
731
|
+
};
|
|
732
|
+
for (const listener of [...state.askUserListeners])
|
|
733
|
+
listener(normalized);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
if (event.type === 'task.changed') {
|
|
737
|
+
const payload = asRecord(event.payload);
|
|
738
|
+
const requestId = cleanString(payload.requestId);
|
|
739
|
+
const action = payload.action === 'create' || payload.action === 'update' || payload.action === 'clear'
|
|
740
|
+
? payload.action
|
|
741
|
+
: undefined;
|
|
742
|
+
if (!requestId || !action)
|
|
743
|
+
return;
|
|
744
|
+
const normalized = {
|
|
745
|
+
requestId,
|
|
746
|
+
action,
|
|
747
|
+
...(isRecord(payload.task) ? { task: structuredClone(payload.task) } : {}),
|
|
748
|
+
...(cleanString(payload.taskId) ? { taskId: cleanString(payload.taskId) } : {}),
|
|
749
|
+
...(isRecord(payload.patch) ? { patch: structuredClone(payload.patch) } : {}),
|
|
750
|
+
};
|
|
751
|
+
for (const listener of [...state.taskListeners])
|
|
752
|
+
listener(normalized);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
const payload = asRecord(event.payload);
|
|
756
|
+
const ownerInstanceId = cleanString(payload.ownerInstanceId);
|
|
757
|
+
if (ownerInstanceId && ownerInstanceId !== state.clientInstanceId)
|
|
758
|
+
return;
|
|
759
|
+
if (event.type === 'workspace.terminal.data') {
|
|
760
|
+
const terminalId = cleanString(payload.terminalId);
|
|
761
|
+
const stream = payload.stream === 'stderr' ? 'stderr' : payload.stream === 'stdout' ? 'stdout' : undefined;
|
|
762
|
+
if (!terminalId || !stream || typeof payload.chunk !== 'string')
|
|
763
|
+
return;
|
|
764
|
+
for (const listener of [...state.terminalDataListeners]) {
|
|
765
|
+
listener({ terminalId, stream, chunk: payload.chunk });
|
|
766
|
+
}
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
if (event.type === 'workspace.terminal.exit') {
|
|
770
|
+
const terminalId = cleanString(payload.terminalId);
|
|
771
|
+
const command = cleanString(payload.command, 100_000);
|
|
772
|
+
const cwd = cleanString(payload.cwd, 2_000);
|
|
773
|
+
if (!terminalId || !command || !cwd)
|
|
774
|
+
return;
|
|
775
|
+
const normalized = {
|
|
776
|
+
terminalId,
|
|
777
|
+
command,
|
|
778
|
+
cwd,
|
|
779
|
+
success: payload.success === true,
|
|
780
|
+
exitCode: typeof payload.exitCode === 'number' ? payload.exitCode : null,
|
|
781
|
+
error: typeof payload.error === 'string' ? payload.error : null,
|
|
782
|
+
};
|
|
783
|
+
for (const listener of [...state.terminalExitListeners])
|
|
784
|
+
listener(normalized);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
if (event.type === 'workspace.pty.data') {
|
|
788
|
+
const terminalId = cleanString(payload.terminalId);
|
|
789
|
+
if (!terminalId || typeof payload.data !== 'string')
|
|
790
|
+
return;
|
|
791
|
+
for (const listener of [...state.ptyDataListeners])
|
|
792
|
+
listener({ terminalId, data: payload.data });
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
if (event.type === 'workspace.pty.exit') {
|
|
796
|
+
const terminalId = cleanString(payload.terminalId);
|
|
797
|
+
if (!terminalId || typeof payload.exitCode !== 'number')
|
|
798
|
+
return;
|
|
799
|
+
const normalized = {
|
|
800
|
+
terminalId,
|
|
801
|
+
exitCode: payload.exitCode,
|
|
802
|
+
...(typeof payload.signal === 'number' ? { signal: payload.signal } : {}),
|
|
803
|
+
};
|
|
804
|
+
for (const listener of [...state.ptyExitListeners])
|
|
805
|
+
listener(normalized);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
function workspaceAccessInput(value) {
|
|
809
|
+
const input = asRecord(value);
|
|
810
|
+
const caller = asRecord(input.caller);
|
|
811
|
+
return {
|
|
812
|
+
allowedDirectories: stringArray(input.allowedDirs ?? input.allowedDirectories ?? caller.allowedDirectories, 100, 2_000),
|
|
813
|
+
...(cleanString(input.conversationId, 500) ? { conversationId: cleanString(input.conversationId, 500) } : {}),
|
|
814
|
+
...(cleanString(input.workspaceId, 500) || cleanString(caller.workspaceId, 500)
|
|
815
|
+
? { workspaceId: cleanString(input.workspaceId, 500) || cleanString(caller.workspaceId, 500) }
|
|
816
|
+
: {}),
|
|
817
|
+
...(cleanString(input.teamId, 500) || cleanString(caller.teamId, 500)
|
|
818
|
+
? { teamId: cleanString(input.teamId, 500) || cleanString(caller.teamId, 500) }
|
|
819
|
+
: {}),
|
|
820
|
+
...(cleanString(input.agentId, 500) || cleanString(caller.agentId, 500)
|
|
821
|
+
? { agentId: cleanString(input.agentId, 500) || cleanString(caller.agentId, 500) }
|
|
822
|
+
: {}),
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
async function runAcpPrompt(client, activeConversations, pendingCancellations, value) {
|
|
826
|
+
const params = asRecord(value);
|
|
827
|
+
const requestId = cleanString(params.requestId);
|
|
828
|
+
const conversationId = cleanString(params.conversationId);
|
|
829
|
+
const configId = cleanString(params.acpAgentConfigId) || cleanString(params.id);
|
|
830
|
+
const prompt = cleanString(params.prompt, 2_000_000);
|
|
831
|
+
if (!requestId || !conversationId || !configId || !prompt) {
|
|
832
|
+
return { success: false, error: 'ACP turn requires requestId, conversationId, provider, and prompt.' };
|
|
833
|
+
}
|
|
834
|
+
activeConversations.set(requestId, conversationId);
|
|
835
|
+
try {
|
|
836
|
+
const providers = await acpProviders(client);
|
|
837
|
+
const provider = providers.find((entry) => acpConfigId(entry.id) === configId);
|
|
838
|
+
if (!provider) {
|
|
839
|
+
activeConversations.delete(requestId);
|
|
840
|
+
return { success: false, error: 'The selected ACP provider is no longer available.' };
|
|
841
|
+
}
|
|
842
|
+
const selection = selectProviderRuntime(provider, cleanString(params.providerModel, 240));
|
|
843
|
+
if (pendingCancellations.has(requestId)) {
|
|
844
|
+
activeConversations.delete(requestId);
|
|
845
|
+
return { success: true, status: 'cancelled', events: [] };
|
|
846
|
+
}
|
|
847
|
+
const workspace = toWorkspace(params);
|
|
848
|
+
const continuation = toContinuation(params, provider.id);
|
|
849
|
+
const contextCompaction = isRecord(params.contextCompaction)
|
|
850
|
+
? params.contextCompaction
|
|
851
|
+
: undefined;
|
|
852
|
+
const result = await client.startTurn({
|
|
853
|
+
conversationId,
|
|
854
|
+
requestId,
|
|
855
|
+
...(cleanString(params.workspaceId, 500) ? { workspaceId: cleanString(params.workspaceId, 500) } : {}),
|
|
856
|
+
...(cleanString(params.teamId, 500) ? { teamId: cleanString(params.teamId, 500) } : {}),
|
|
857
|
+
...(cleanString(params.agentId, 500) ? { agentId: cleanString(params.agentId, 500) } : {}),
|
|
858
|
+
mode: workspace.primaryDirectory ? 'development' : 'chat',
|
|
859
|
+
selection,
|
|
860
|
+
prompt,
|
|
861
|
+
history: toTurnHistory(params.history),
|
|
862
|
+
...(cleanString(params.systemPrompt, 2_000_000) ? { systemPrompt: cleanString(params.systemPrompt, 2_000_000) } : {}),
|
|
863
|
+
...(Object.keys(workspace).length > 0 ? { workspace } : {}),
|
|
864
|
+
...(continuation ? { continuation } : {}),
|
|
865
|
+
...(contextCompaction ? { contextCompaction } : {}),
|
|
866
|
+
...(positiveInteger(params.timeoutMs) ? { timeoutMs: positiveInteger(params.timeoutMs) } : {}),
|
|
867
|
+
});
|
|
868
|
+
if (!result.success) {
|
|
869
|
+
activeConversations.delete(requestId);
|
|
870
|
+
return { success: false, status: 'failed', error: result.safeError, events: [] };
|
|
871
|
+
}
|
|
872
|
+
return { success: true, status: result.status, events: [] };
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
activeConversations.delete(requestId);
|
|
876
|
+
return { success: false, status: 'failed', error: safeError(error), events: [] };
|
|
877
|
+
}
|
|
878
|
+
finally {
|
|
879
|
+
pendingCancellations.delete(requestId);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
async function runHostPrompt(client, activeConversations, pendingCancellations, value) {
|
|
883
|
+
const params = asRecord(value);
|
|
884
|
+
const requestId = cleanString(params.requestId);
|
|
885
|
+
const conversationId = cleanString(params.conversationId);
|
|
886
|
+
const requestedModel = cleanString(params.model, 240);
|
|
887
|
+
const requestedProviderId = cleanString(params.providerId, 240);
|
|
888
|
+
const providerKind = params.providerKind === 'xeno-cloud' ? 'xeno-cloud' : 'sdk-native';
|
|
889
|
+
const mode = params.mode === 'chat' || params.mode === 'development'
|
|
890
|
+
? params.mode
|
|
891
|
+
: (providerKind === 'xeno-cloud' ? 'chat' : 'development');
|
|
892
|
+
const messages = toTurnHistory(params.messages) || [];
|
|
893
|
+
let lastUserIndex = -1;
|
|
894
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
895
|
+
if (messages[index]?.role === 'user') {
|
|
896
|
+
lastUserIndex = index;
|
|
897
|
+
break;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
const prompt = lastUserIndex >= 0 ? messages[lastUserIndex]?.content : undefined;
|
|
901
|
+
if (!requestId || !conversationId || !requestedModel || !prompt) {
|
|
902
|
+
return {
|
|
903
|
+
success: false,
|
|
904
|
+
error: 'Host execution requires requestId, conversationId, model, and a user message.',
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
activeConversations.set(requestId, conversationId);
|
|
908
|
+
try {
|
|
909
|
+
const catalog = await client.listProviders({ includeUnavailable: true });
|
|
910
|
+
const provider = catalog.providers.find((entry) => (requestedProviderId ? entry.id === requestedProviderId : entry.kind === providerKind));
|
|
911
|
+
if (!provider) {
|
|
912
|
+
activeConversations.delete(requestId);
|
|
913
|
+
return { success: false, error: `The ${providerKind} runtime is not available from the owning Agent host.` };
|
|
914
|
+
}
|
|
915
|
+
const selection = selectProviderRuntime(provider, requestedModel);
|
|
916
|
+
if (pendingCancellations.has(requestId)) {
|
|
917
|
+
activeConversations.delete(requestId);
|
|
918
|
+
return { success: true, requestId };
|
|
919
|
+
}
|
|
920
|
+
const allowedDirectories = stringArray(params.allowedDirectories, 500, 2_000);
|
|
921
|
+
const permissionProfile = cleanString(params.permissionProfile, 80);
|
|
922
|
+
const capabilities = booleanRecord(params.capabilities);
|
|
923
|
+
const approvalRules = recordArray(params.approvalRules, 500);
|
|
924
|
+
const contextCompaction = isRecord(params.contextCompaction)
|
|
925
|
+
? params.contextCompaction
|
|
926
|
+
: undefined;
|
|
927
|
+
const providerSessionId = providerKind === 'xeno-cloud'
|
|
928
|
+
? cleanString(params.previousRunId, 500)
|
|
929
|
+
: cleanString(params.sdkSessionId, 500);
|
|
930
|
+
const result = await client.startTurn({
|
|
931
|
+
conversationId,
|
|
932
|
+
requestId,
|
|
933
|
+
...(cleanString(params.workspaceId, 500) ? { workspaceId: cleanString(params.workspaceId, 500) } : {}),
|
|
934
|
+
...(cleanString(params.teamId, 500) ? { teamId: cleanString(params.teamId, 500) } : {}),
|
|
935
|
+
...(cleanString(params.agentId, 500) ? { agentId: cleanString(params.agentId, 500) } : {}),
|
|
936
|
+
...(cleanString(params.subagentRunId, 500) ? { subagentRunId: cleanString(params.subagentRunId, 500) } : {}),
|
|
937
|
+
mode,
|
|
938
|
+
selection,
|
|
939
|
+
prompt,
|
|
940
|
+
...(lastUserIndex > 0 ? { history: messages.slice(0, lastUserIndex) } : {}),
|
|
941
|
+
...(cleanString(params.systemPrompt, 2_000_000) ? { systemPrompt: cleanString(params.systemPrompt, 2_000_000) } : {}),
|
|
942
|
+
workspace: {
|
|
943
|
+
...(allowedDirectories[0] ? { primaryDirectory: allowedDirectories[0] } : {}),
|
|
944
|
+
...(allowedDirectories.length > 1 ? { additionalDirectories: allowedDirectories.slice(1) } : {}),
|
|
945
|
+
...(permissionProfile ? { permissionProfile } : {}),
|
|
946
|
+
filesystem: permissionProfile === 'read-only'
|
|
947
|
+
|| permissionProfile === 'plan'
|
|
948
|
+
|| capabilities?.fileWrite === false
|
|
949
|
+
? 'read-only'
|
|
950
|
+
: 'workspace-write',
|
|
951
|
+
},
|
|
952
|
+
execution: {
|
|
953
|
+
...(positiveInteger(params.maxIterations) ? { maxIterations: positiveInteger(params.maxIterations) } : {}),
|
|
954
|
+
enableThinking: params.enableThinking === true,
|
|
955
|
+
...(capabilities ? { capabilities } : {}),
|
|
956
|
+
...(approvalRules.length > 0 ? { approvalRules } : {}),
|
|
957
|
+
},
|
|
958
|
+
...(contextCompaction ? { contextCompaction } : {}),
|
|
959
|
+
...(providerSessionId
|
|
960
|
+
? {
|
|
961
|
+
continuation: {
|
|
962
|
+
providerId: provider.id,
|
|
963
|
+
providerSessionId,
|
|
964
|
+
},
|
|
965
|
+
}
|
|
966
|
+
: {}),
|
|
967
|
+
});
|
|
968
|
+
if (!result.success) {
|
|
969
|
+
activeConversations.delete(requestId);
|
|
970
|
+
return { success: false, error: result.safeError };
|
|
971
|
+
}
|
|
972
|
+
return { success: true, requestId };
|
|
973
|
+
}
|
|
974
|
+
catch (error) {
|
|
975
|
+
activeConversations.delete(requestId);
|
|
976
|
+
return { success: false, error: safeError(error) };
|
|
977
|
+
}
|
|
978
|
+
finally {
|
|
979
|
+
pendingCancellations.delete(requestId);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
async function cancelAcpPrompt(client, activeConversations, pendingCancellations, value) {
|
|
983
|
+
const params = asRecord(value);
|
|
984
|
+
const requestId = cleanString(params.requestId);
|
|
985
|
+
const conversationId = cleanString(params.conversationId) || (requestId ? activeConversations.get(requestId) : undefined);
|
|
986
|
+
if (!requestId || !conversationId) {
|
|
987
|
+
return { success: false, cancelled: false, error: 'ACP cancellation requires an active request and conversation.' };
|
|
988
|
+
}
|
|
989
|
+
pendingCancellations.add(requestId);
|
|
990
|
+
try {
|
|
991
|
+
const result = await client.cancelTurn({ conversationId, requestId, reason: cleanString(params.reason) });
|
|
992
|
+
if (result.success || (result.code === 'turn_not_active' && activeConversations.has(requestId))) {
|
|
993
|
+
return { success: true, cancelled: true };
|
|
994
|
+
}
|
|
995
|
+
pendingCancellations.delete(requestId);
|
|
996
|
+
return { success: false, cancelled: false, error: result.safeError };
|
|
997
|
+
}
|
|
998
|
+
catch (error) {
|
|
999
|
+
if (activeConversations.has(requestId))
|
|
1000
|
+
return { success: true, cancelled: true };
|
|
1001
|
+
pendingCancellations.delete(requestId);
|
|
1002
|
+
return { success: false, cancelled: false, error: safeError(error) };
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
async function cancelByRequestId(client, activeConversations, pendingCancellations, requestId) {
|
|
1006
|
+
const conversationId = activeConversations.get(requestId);
|
|
1007
|
+
if (!conversationId)
|
|
1008
|
+
return { success: false, error: 'The requested turn is not active.' };
|
|
1009
|
+
pendingCancellations.add(requestId);
|
|
1010
|
+
const result = await client.cancelTurn({ conversationId, requestId, reason: 'Cancelled from the Agent interface.' });
|
|
1011
|
+
if (result.success || result.code === 'turn_not_active')
|
|
1012
|
+
return { success: true };
|
|
1013
|
+
pendingCancellations.delete(requestId);
|
|
1014
|
+
return { success: false, error: result.safeError };
|
|
1015
|
+
}
|
|
1016
|
+
async function acpProviders(client) {
|
|
1017
|
+
const result = await client.listProviders({ includeUnavailable: true });
|
|
1018
|
+
return result.providers.filter((provider) => provider.kind === 'acp');
|
|
1019
|
+
}
|
|
1020
|
+
function selectProviderRuntime(provider, requestedModel) {
|
|
1021
|
+
const direct = requestedModel ? provider.models.find((model) => model.id === requestedModel) : undefined;
|
|
1022
|
+
const reasoning = requestedModel
|
|
1023
|
+
? provider.models.flatMap((model) => (model.reasoningOptions || []).map((option) => ({ model, option })))
|
|
1024
|
+
.find(({ option }) => option.runtimeModelId === requestedModel || option.id === requestedModel)
|
|
1025
|
+
: undefined;
|
|
1026
|
+
const model = direct || reasoning?.model
|
|
1027
|
+
|| provider.models.find((entry) => entry.id === provider.defaultModelId)
|
|
1028
|
+
|| provider.models.find((entry) => entry.isDefault)
|
|
1029
|
+
|| provider.models.find((entry) => entry.availability === 'available');
|
|
1030
|
+
return {
|
|
1031
|
+
providerId: provider.id,
|
|
1032
|
+
catalogRevision: provider.catalogRevision,
|
|
1033
|
+
...(model ? { modelId: model.id } : {}),
|
|
1034
|
+
...(reasoning ? { reasoningOptionId: reasoning.option.id } : {}),
|
|
1035
|
+
...(reasoning?.option.runtimeModelId ? { runtimeModelId: reasoning.option.runtimeModelId } : {}),
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
function toWorkspace(params) {
|
|
1039
|
+
const execution = asRecord(params.execution);
|
|
1040
|
+
const primaryDirectory = cleanString(params.cwd, 2_000);
|
|
1041
|
+
const additionalDirectories = stringArray(params.additionalDirectories, 500, 2_000);
|
|
1042
|
+
const permissionProfile = cleanString(execution.permissionProfile, 80);
|
|
1043
|
+
const filesystem = execution.filesystem === 'workspace-write' ? 'workspace-write' : 'read-only';
|
|
1044
|
+
return {
|
|
1045
|
+
...(primaryDirectory ? { primaryDirectory } : {}),
|
|
1046
|
+
...(additionalDirectories.length > 0 ? { additionalDirectories } : {}),
|
|
1047
|
+
...(permissionProfile ? { permissionProfile } : {}),
|
|
1048
|
+
filesystem,
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
function toContinuation(params, providerId) {
|
|
1052
|
+
const providerSessionId = cleanString(params.resumeSessionId, 500);
|
|
1053
|
+
if (!providerSessionId)
|
|
1054
|
+
return undefined;
|
|
1055
|
+
const state = isRecord(params.resumeState) ? structuredClone(params.resumeState) : undefined;
|
|
1056
|
+
return {
|
|
1057
|
+
providerId,
|
|
1058
|
+
providerSessionId,
|
|
1059
|
+
...(state ? { state } : {}),
|
|
1060
|
+
...(cleanString(params.resumeAgentConfigFingerprint, 500)
|
|
1061
|
+
? { providerConfigFingerprint: cleanString(params.resumeAgentConfigFingerprint, 500) }
|
|
1062
|
+
: {}),
|
|
1063
|
+
...(cleanString(params.resumeWorkspaceFingerprint, 500)
|
|
1064
|
+
? { workspaceFingerprint: cleanString(params.resumeWorkspaceFingerprint, 500) }
|
|
1065
|
+
: {}),
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
function toTurnHistory(value) {
|
|
1069
|
+
if (!Array.isArray(value))
|
|
1070
|
+
return undefined;
|
|
1071
|
+
const messages = value.flatMap((entry) => {
|
|
1072
|
+
const record = asRecord(entry);
|
|
1073
|
+
if ((record.role !== 'user' && record.role !== 'assistant') || typeof record.content !== 'string')
|
|
1074
|
+
return [];
|
|
1075
|
+
return [{ role: record.role, content: record.content }];
|
|
1076
|
+
});
|
|
1077
|
+
return messages.length > 0 ? messages : undefined;
|
|
1078
|
+
}
|
|
1079
|
+
function toRuntimeEventListRequest(value) {
|
|
1080
|
+
const params = asRecord(value);
|
|
1081
|
+
const conversationId = cleanString(params.conversationId);
|
|
1082
|
+
if (!conversationId)
|
|
1083
|
+
throw new Error('conversationId is required to list runtime events.');
|
|
1084
|
+
return {
|
|
1085
|
+
conversationId,
|
|
1086
|
+
...(cleanString(params.requestId) ? { requestId: cleanString(params.requestId) } : {}),
|
|
1087
|
+
...(cleanString(params.subagentRunId) ? { subagentRunId: cleanString(params.subagentRunId) } : {}),
|
|
1088
|
+
...(cleanString(params.type) ? { type: cleanString(params.type) } : {}),
|
|
1089
|
+
...(nonNegativeInteger(params.afterSequence) !== undefined
|
|
1090
|
+
? { afterSequence: nonNegativeInteger(params.afterSequence) }
|
|
1091
|
+
: {}),
|
|
1092
|
+
...(positiveInteger(params.limit) ? { limit: positiveInteger(params.limit) } : {}),
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
function toLegacyAgentView(provider) {
|
|
1096
|
+
const id = acpConfigId(provider.id);
|
|
1097
|
+
const now = new Date(0).toISOString();
|
|
1098
|
+
return {
|
|
1099
|
+
id,
|
|
1100
|
+
name: provider.displayName,
|
|
1101
|
+
command: 'host-managed',
|
|
1102
|
+
args: [],
|
|
1103
|
+
envKeys: [],
|
|
1104
|
+
enabled: provider.availability !== 'blocked' && provider.availability !== 'unavailable',
|
|
1105
|
+
trustLevel: 'restricted',
|
|
1106
|
+
endpointKind: 'native-acp',
|
|
1107
|
+
certification: {
|
|
1108
|
+
status: provider.availability === 'available' ? 'certified' : 'not_certified',
|
|
1109
|
+
notes: provider.safeUnavailableReason,
|
|
1110
|
+
},
|
|
1111
|
+
providerReview: {
|
|
1112
|
+
providerId: id,
|
|
1113
|
+
displayName: provider.displayName,
|
|
1114
|
+
runnable: provider.availability === 'available',
|
|
1115
|
+
approvalState: provider.availability === 'available' ? 'approved' : 'blocked',
|
|
1116
|
+
runtimeEnvKeys: [],
|
|
1117
|
+
requiredAuthRefs: [],
|
|
1118
|
+
optionalAuthRefs: [],
|
|
1119
|
+
},
|
|
1120
|
+
createdAt: now,
|
|
1121
|
+
updatedAt: now,
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
function toLegacyModel(model) {
|
|
1125
|
+
return {
|
|
1126
|
+
id: model.id,
|
|
1127
|
+
label: model.displayName,
|
|
1128
|
+
available: model.availability === 'available',
|
|
1129
|
+
default: model.isDefault === true,
|
|
1130
|
+
reason: model.safeUnavailableReason,
|
|
1131
|
+
reasoningOptions: model.reasoningOptions?.map((option) => ({
|
|
1132
|
+
id: option.id,
|
|
1133
|
+
label: option.label,
|
|
1134
|
+
modelId: option.runtimeModelId,
|
|
1135
|
+
default: option.isDefault === true,
|
|
1136
|
+
})),
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
function toLegacyCatalogEntry(provider) {
|
|
1140
|
+
const id = acpConfigId(provider.id);
|
|
1141
|
+
const ready = provider.availability === 'available';
|
|
1142
|
+
return {
|
|
1143
|
+
id,
|
|
1144
|
+
name: provider.displayName,
|
|
1145
|
+
description: provider.safeUnavailableReason || 'Host-managed ACP provider.',
|
|
1146
|
+
authors: [],
|
|
1147
|
+
distributionKind: 'custom',
|
|
1148
|
+
installed: true,
|
|
1149
|
+
configured: true,
|
|
1150
|
+
enabled: ready,
|
|
1151
|
+
preferred: false,
|
|
1152
|
+
canAutoSetup: false,
|
|
1153
|
+
availableActions: [],
|
|
1154
|
+
agentConfigId: id,
|
|
1155
|
+
status: ready ? 'ready' : 'needs_attention',
|
|
1156
|
+
statusMessage: ready ? 'Ready' : (provider.safeUnavailableReason || 'Unavailable'),
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
function addSubscription(subscriptions, listener, nextSequence, prefix) {
|
|
1160
|
+
const id = `${prefix}-${nextSequence()}`;
|
|
1161
|
+
subscriptions.set(id, listener);
|
|
1162
|
+
return id;
|
|
1163
|
+
}
|
|
1164
|
+
function acpConfigId(providerId) {
|
|
1165
|
+
return providerId.startsWith('acp:') ? providerId.slice(4) : providerId;
|
|
1166
|
+
}
|
|
1167
|
+
function isTerminalEvent(event) {
|
|
1168
|
+
return event.type === 'acp.session.completed'
|
|
1169
|
+
|| event.type === 'acp.session.failed'
|
|
1170
|
+
|| event.type === 'acp.session.cancelled'
|
|
1171
|
+
|| event.type === 'turn.completed'
|
|
1172
|
+
|| event.type === 'turn.failed'
|
|
1173
|
+
|| event.type === 'turn.cancelled';
|
|
1174
|
+
}
|
|
1175
|
+
function positiveInteger(value) {
|
|
1176
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : undefined;
|
|
1177
|
+
}
|
|
1178
|
+
function nonNegativeInteger(value) {
|
|
1179
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 0 ? value : undefined;
|
|
1180
|
+
}
|
|
1181
|
+
function stringArray(value, limit, maxLength) {
|
|
1182
|
+
if (!Array.isArray(value))
|
|
1183
|
+
return [];
|
|
1184
|
+
return value.flatMap((entry) => {
|
|
1185
|
+
const normalized = cleanString(entry, maxLength);
|
|
1186
|
+
return normalized ? [normalized] : [];
|
|
1187
|
+
}).slice(0, limit);
|
|
1188
|
+
}
|
|
1189
|
+
function booleanRecord(value) {
|
|
1190
|
+
if (!isRecord(value))
|
|
1191
|
+
return undefined;
|
|
1192
|
+
const entries = Object.entries(value).filter((entry) => (typeof entry[1] === 'boolean'));
|
|
1193
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
1194
|
+
}
|
|
1195
|
+
function recordArray(value, limit) {
|
|
1196
|
+
if (!Array.isArray(value))
|
|
1197
|
+
return [];
|
|
1198
|
+
return value.filter(isRecord).slice(0, limit).map((entry) => structuredClone(entry));
|
|
1199
|
+
}
|
|
1200
|
+
function cleanString(value, maxLength = 500) {
|
|
1201
|
+
if (typeof value !== 'string')
|
|
1202
|
+
return undefined;
|
|
1203
|
+
const trimmed = value.trim();
|
|
1204
|
+
return trimmed ? trimmed.slice(0, maxLength) : undefined;
|
|
1205
|
+
}
|
|
1206
|
+
function safeError(error) {
|
|
1207
|
+
return error instanceof Error && error.message.trim()
|
|
1208
|
+
? error.message.slice(0, 500)
|
|
1209
|
+
: 'The XENO Agent host request failed.';
|
|
1210
|
+
}
|
|
1211
|
+
function asRecord(value) {
|
|
1212
|
+
return isRecord(value) ? value : {};
|
|
1213
|
+
}
|
|
1214
|
+
function isRecord(value) {
|
|
1215
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Routes provider approval to the host, which is the only place that may make
|
|
1219
|
+
* this trust decision.
|
|
1220
|
+
*
|
|
1221
|
+
* Normalises a HOST-LEVEL failure (transport down, handshake missing) into the
|
|
1222
|
+
* same `{success:false,error}` shape the store already handles, so a surface
|
|
1223
|
+
* cannot tell "the host refused" from "the host was unreachable" by crashing.
|
|
1224
|
+
*/
|
|
1225
|
+
async function approveAcpProvider(client, agentId, providerId, action) {
|
|
1226
|
+
try {
|
|
1227
|
+
const result = await client.requestAcp('acp.provider.approve', {
|
|
1228
|
+
agentId,
|
|
1229
|
+
...(providerId ? { providerId } : {}),
|
|
1230
|
+
action,
|
|
1231
|
+
});
|
|
1232
|
+
if (!result.success) {
|
|
1233
|
+
return { success: false, result, error: result.safeError ?? 'Provider approval failed.' };
|
|
1234
|
+
}
|
|
1235
|
+
return { success: true, result };
|
|
1236
|
+
}
|
|
1237
|
+
catch (error) {
|
|
1238
|
+
return {
|
|
1239
|
+
success: false,
|
|
1240
|
+
error: error instanceof Error ? error.message : 'Provider approval could not reach the host.',
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
//# sourceMappingURL=agentHostPlatformBridge.js.map
|