@cloudcli-ai/cloudcli 1.36.3 → 1.37.0
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/dist/assets/index-DSlds633.css +32 -0
- package/dist/assets/{index-CcCsKitq.js → index-eGqPeIEu.js} +375 -267
- package/dist/index.html +2 -2
- package/dist-server/server/constants/config.js.map +1 -1
- package/dist-server/server/index.js +73 -1224
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/load-env.js +17 -4
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/agent/agent.module.js +37 -0
- package/dist-server/server/modules/agent/agent.module.js.map +1 -0
- package/dist-server/server/modules/agent/agent.routes.js +1161 -0
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
- package/dist-server/server/modules/agent/index.js +3 -0
- package/dist-server/server/modules/agent/index.js.map +1 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
- package/dist-server/server/modules/assets/assets.routes.js +56 -15
- package/dist-server/server/modules/assets/assets.routes.js.map +1 -1
- package/dist-server/server/modules/assets/index.js +2 -2
- package/dist-server/server/modules/assets/index.js.map +1 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js +39 -1
- package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js +21 -1
- package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -1
- package/dist-server/server/{middleware/auth.js → modules/auth/auth.middleware.js} +30 -8
- package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
- package/dist-server/server/modules/auth/auth.module.js +29 -0
- package/dist-server/server/modules/auth/auth.module.js.map +1 -0
- package/dist-server/server/modules/auth/auth.routes.js +45 -0
- package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
- package/dist-server/server/modules/auth/auth.service.js +113 -0
- package/dist-server/server/modules/auth/auth.service.js.map +1 -0
- package/dist-server/server/modules/auth/index.js +9 -0
- package/dist-server/server/modules/auth/index.js.map +1 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
- package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
- package/dist-server/server/{browser-use-mcp.js → modules/browser-use/browser-use-mcp.js} +3 -1
- package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
- package/dist-server/server/modules/browser-use/browser-use.service.js +3 -4
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +9 -0
- package/dist-server/server/modules/browser-use/index.js.map +1 -0
- package/dist-server/server/modules/cli/cli.js +11 -0
- package/dist-server/server/modules/cli/cli.js.map +1 -0
- package/dist-server/server/modules/cli/cli.module.js +86 -0
- package/dist-server/server/modules/cli/cli.module.js.map +1 -0
- package/dist-server/server/modules/cli/cli.service.js +244 -0
- package/dist-server/server/modules/cli/cli.service.js.map +1 -0
- package/dist-server/server/modules/cli/index.js +3 -0
- package/dist-server/server/modules/cli/index.js.map +1 -0
- package/dist-server/server/modules/cli/sandbox.service.js +332 -0
- package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js +78 -0
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
- package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
- package/dist-server/server/modules/commands/commands.module.js +20 -0
- package/dist-server/server/modules/commands/commands.module.js.map +1 -0
- package/dist-server/server/modules/commands/commands.routes.js +497 -0
- package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
- package/dist-server/server/modules/commands/index.js +3 -0
- package/dist-server/server/modules/commands/index.js.map +1 -0
- package/dist-server/server/modules/commands/tests/commands.test.js +96 -0
- package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
- package/dist-server/server/modules/database/index.js +1 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +13 -0
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js +14 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/schema.js +4 -0
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/file-tree/file-tree.module.js +91 -0
- package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
- package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js +544 -0
- package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
- package/dist-server/server/modules/file-tree/index.js +3 -0
- package/dist-server/server/modules/file-tree/index.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +184 -0
- package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
- package/dist-server/server/modules/git/git-parsing.service.js +61 -0
- package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
- package/dist-server/server/modules/git/git.module.js +14 -0
- package/dist-server/server/modules/git/git.module.js.map +1 -0
- package/dist-server/server/modules/git/git.routes.js +1339 -0
- package/dist-server/server/modules/git/git.routes.js.map +1 -0
- package/dist-server/server/modules/git/index.js +3 -0
- package/dist-server/server/modules/git/index.js.map +1 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js +48 -0
- package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
- package/dist-server/server/{routes → modules/git/tests}/git.test.js +1 -1
- package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
- package/dist-server/server/modules/notifications/index.js +15 -1
- package/dist-server/server/modules/notifications/index.js.map +1 -1
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
- package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
- package/dist-server/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.js} +3 -2
- package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
- package/dist-server/server/modules/plugins/index.js +9 -0
- package/dist-server/server/modules/plugins/index.js.map +1 -0
- package/dist-server/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.js} +3 -2
- package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
- package/dist-server/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.js} +2 -1
- package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.module.js +30 -0
- package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
- package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
- package/dist-server/server/modules/plugins/plugins.service.js +123 -0
- package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
- package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
- package/dist-server/server/modules/projects/index.js +5 -0
- package/dist-server/server/modules/projects/index.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +3 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +6 -0
- package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -1
- package/dist-server/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +62 -41
- package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +6 -4
- package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +23 -4
- package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +48 -34
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +290 -6
- package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +5 -0
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
- package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -4
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
- package/dist-server/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +40 -28
- package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +21 -14
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +7 -5
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -1
- package/dist-server/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +38 -25
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
- package/dist-server/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +27 -4
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +11 -5
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +2 -0
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +33 -9
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +5 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +110 -15
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js +268 -0
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +2 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions.service.js +54 -0
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js +2 -3
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-auth.test.js +122 -0
- package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js +44 -0
- package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +36 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/{provider-image-history.test.js → provider-attachment-history.test.js} +60 -2
- package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +148 -61
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +130 -0
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +165 -0
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
- package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/skills.test.js +4 -2
- package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
- package/dist-server/server/modules/settings/index.js +3 -0
- package/dist-server/server/modules/settings/index.js.map +1 -0
- package/dist-server/server/modules/settings/settings.module.js +35 -0
- package/dist-server/server/modules/settings/settings.module.js.map +1 -0
- package/dist-server/server/modules/settings/settings.routes.js +34 -0
- package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
- package/dist-server/server/modules/settings/settings.service.js +116 -0
- package/dist-server/server/modules/settings/settings.service.js.map +1 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
- package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
- package/dist-server/server/modules/system/index.js +3 -0
- package/dist-server/server/modules/system/index.js.map +1 -0
- package/dist-server/server/modules/system/system.module.js +44 -0
- package/dist-server/server/modules/system/system.module.js.map +1 -0
- package/dist-server/server/modules/system/system.routes.js +16 -0
- package/dist-server/server/modules/system/system.routes.js.map +1 -0
- package/dist-server/server/modules/system/system.service.js +45 -0
- package/dist-server/server/modules/system/system.service.js.map +1 -0
- package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
- package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/index.js +3 -0
- package/dist-server/server/modules/taskmaster/index.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
- package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
- package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +132 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
- package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
- package/dist-server/server/modules/user/index.js +3 -0
- package/dist-server/server/modules/user/index.js.map +1 -0
- package/dist-server/server/modules/user/tests/user.service.test.js +53 -0
- package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
- package/dist-server/server/modules/user/user.module.js +47 -0
- package/dist-server/server/modules/user/user.module.js.map +1 -0
- package/dist-server/server/modules/user/user.routes.js +44 -0
- package/dist-server/server/modules/user/user.routes.js.map +1 -0
- package/dist-server/server/modules/user/user.service.js +59 -0
- package/dist-server/server/modules/user/user.service.js.map +1 -0
- package/dist-server/server/modules/voice/index.js +3 -0
- package/dist-server/server/modules/voice/index.js.map +1 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js +86 -0
- package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
- package/dist-server/server/modules/voice/voice.module.js +44 -0
- package/dist-server/server/modules/voice/voice.module.js.map +1 -0
- package/dist-server/server/modules/voice/voice.routes.js +87 -0
- package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
- package/dist-server/server/modules/voice/voice.service.js +148 -0
- package/dist-server/server/modules/voice/voice.service.js.map +1 -0
- package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +2 -2
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +40 -29
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +76 -8
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/websocket-server.service.js +51 -20
- package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/{chat-image-filter.test.js → chat-attachment-filter.test.js} +10 -3
- package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +97 -0
- package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
- package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/index.js +3 -0
- package/dist-server/server/modules/worktrees/index.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
- package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
- package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
- package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
- package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
- package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
- package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
- package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
- package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
- package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
- package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
- package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
- package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
- package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
- package/dist-server/server/shared/image-attachments.js +90 -17
- package/dist-server/server/shared/image-attachments.js.map +1 -1
- package/dist-server/server/shared/tests/image-attachments.test.js +43 -1
- package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -1
- package/dist-server/server/shared/utils.js +66 -142
- package/dist-server/server/shared/utils.js.map +1 -1
- package/package.json +8 -4
- package/server/index.ts +401 -0
- package/server/{load-env.js → load-env.ts} +18 -5
- package/server/modules/agent/agent.module.ts +51 -0
- package/server/modules/agent/agent.routes.ts +1287 -0
- package/server/modules/agent/index.ts +2 -0
- package/server/modules/agent/tests/agent.routes.test.ts +205 -0
- package/server/modules/assets/assets.routes.ts +63 -16
- package/server/modules/assets/index.ts +2 -2
- package/server/modules/assets/services/image-assets.service.ts +46 -1
- package/server/modules/assets/tests/image-assets.service.test.ts +28 -0
- package/server/{middleware/auth.js → modules/auth/auth.middleware.ts} +38 -7
- package/server/modules/auth/auth.module.ts +38 -0
- package/server/modules/auth/auth.routes.ts +57 -0
- package/server/modules/auth/auth.service.ts +155 -0
- package/server/modules/auth/index.ts +9 -0
- package/server/modules/auth/tests/auth.service.test.ts +95 -0
- package/server/{browser-use-mcp.ts → modules/browser-use/browser-use-mcp.ts} +3 -1
- package/server/modules/browser-use/browser-use.service.ts +3 -4
- package/server/modules/browser-use/index.ts +8 -0
- package/server/modules/cli/cli.module.ts +96 -0
- package/server/modules/cli/cli.service.ts +281 -0
- package/server/modules/cli/cli.ts +13 -0
- package/server/modules/cli/index.ts +2 -0
- package/server/modules/cli/sandbox.service.ts +413 -0
- package/server/modules/cli/tests/cli.service.test.ts +91 -0
- package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
- package/server/modules/commands/commands.module.ts +22 -0
- package/server/{routes/commands.js → modules/commands/commands.routes.ts} +44 -36
- package/server/modules/commands/index.ts +2 -0
- package/server/modules/commands/tests/commands.test.ts +119 -0
- package/server/modules/database/index.ts +1 -0
- package/server/modules/database/migrations.ts +15 -0
- package/server/modules/database/repositories/sessions.db.ts +19 -1
- package/server/modules/database/schema.ts +4 -0
- package/server/modules/file-tree/file-tree.module.ts +112 -0
- package/server/modules/file-tree/file-tree.routes.ts +258 -0
- package/server/modules/file-tree/file-tree.service.ts +616 -0
- package/server/modules/file-tree/index.ts +2 -0
- package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
- package/server/modules/file-tree/tests/file-tree.service.test.ts +220 -0
- package/server/modules/git/git-parsing.service.ts +66 -0
- package/server/modules/git/git.module.ts +22 -0
- package/server/{routes/git.js → modules/git/git.routes.ts} +91 -132
- package/server/modules/git/index.ts +2 -0
- package/server/modules/git/tests/git-init.routes.test.ts +52 -0
- package/server/{routes/git.test.js → modules/git/tests/git.test.ts} +3 -3
- package/server/modules/notifications/index.ts +9 -0
- package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
- package/server/{services/vapid-keys.js → modules/notifications/vapid-keys.service.ts} +3 -1
- package/server/modules/plugins/index.ts +9 -0
- package/server/{utils/plugin-process-manager.js → modules/plugins/plugin-process.service.ts} +3 -1
- package/server/{utils/plugin-loader.js → modules/plugins/plugin-registry.service.ts} +1 -0
- package/server/modules/plugins/plugins.module.ts +33 -0
- package/server/modules/plugins/plugins.routes.ts +66 -0
- package/server/modules/plugins/plugins.service.ts +147 -0
- package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
- package/server/modules/projects/index.ts +5 -0
- package/server/modules/providers/README.md +41 -9
- package/server/modules/providers/index.ts +4 -0
- package/server/modules/providers/list/claude/claude-auth.provider.ts +8 -0
- package/server/modules/providers/list/claude/claude-models.provider.ts +1 -12
- package/server/{claude-sdk.js → modules/providers/list/claude/claude-runtime.provider.js} +66 -44
- package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +6 -4
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +27 -4
- package/server/modules/providers/list/claude/claude.provider.ts +3 -0
- package/server/modules/providers/list/codex/codex-models.provider.ts +0 -9
- package/server/{openai-codex.js → modules/providers/list/codex/codex-runtime.provider.js} +54 -36
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +331 -7
- package/server/modules/providers/list/codex/codex-skills.provider.ts +5 -0
- package/server/modules/providers/list/codex/codex.provider.ts +3 -0
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +0 -9
- package/server/{cursor-cli.js → modules/providers/list/cursor/cursor-runtime.provider.js} +58 -27
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +26 -15
- package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +7 -10
- package/server/{opencode-cli.js → modules/providers/list/opencode/opencode-runtime.provider.js} +56 -28
- package/server/{opencode-cli.test.js → modules/providers/list/opencode/opencode-runtime.provider.test.js} +41 -3
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +13 -5
- package/server/modules/providers/list/opencode/opencode.provider.ts +3 -0
- package/server/modules/providers/provider.routes.ts +47 -10
- package/server/modules/providers/services/provider-capabilities.service.ts +7 -1
- package/server/modules/providers/services/provider-models.service.ts +131 -23
- package/server/modules/providers/services/provider-runtime.service.ts +109 -0
- package/server/modules/providers/services/provider-token-usage.service.ts +357 -0
- package/server/modules/providers/services/sessions-watcher.service.ts +2 -0
- package/server/modules/providers/services/sessions.service.ts +79 -0
- package/server/modules/providers/shared/base/abstract.provider.ts +4 -3
- package/server/modules/providers/tests/claude-auth.test.ts +150 -0
- package/server/modules/providers/tests/claude-sessions.test.ts +61 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +40 -0
- package/server/modules/providers/tests/{provider-image-history.test.ts → provider-attachment-history.test.ts} +68 -1
- package/server/modules/providers/tests/provider-models.service.test.ts +450 -349
- package/server/modules/providers/tests/provider-runtime.service.test.ts +142 -0
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +185 -0
- package/server/modules/providers/tests/sessions-details.test.ts +73 -0
- package/server/modules/providers/tests/skills.test.ts +9 -2
- package/server/modules/settings/index.ts +2 -0
- package/server/modules/settings/settings.module.ts +50 -0
- package/server/modules/settings/settings.routes.ts +51 -0
- package/server/modules/settings/settings.service.ts +186 -0
- package/server/modules/settings/tests/settings.service.test.ts +54 -0
- package/server/modules/system/index.ts +2 -0
- package/server/modules/system/system.module.ts +62 -0
- package/server/modules/system/system.routes.ts +21 -0
- package/server/modules/system/system.service.ts +76 -0
- package/server/modules/system/tests/system.service.test.ts +118 -0
- package/server/modules/taskmaster/index.ts +2 -0
- package/server/modules/taskmaster/taskmaster.module.ts +24 -0
- package/server/modules/taskmaster/taskmaster.routes.ts +1482 -0
- package/server/modules/taskmaster/taskmaster.service.ts +132 -0
- package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -0
- package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
- package/server/modules/user/index.ts +2 -0
- package/server/modules/user/tests/user.service.test.ts +61 -0
- package/server/modules/user/user.module.ts +58 -0
- package/server/modules/user/user.routes.ts +50 -0
- package/server/modules/user/user.service.ts +85 -0
- package/server/modules/voice/index.ts +2 -0
- package/server/modules/voice/tests/voice.service.test.ts +98 -0
- package/server/modules/voice/voice.module.ts +47 -0
- package/server/modules/voice/voice.routes.ts +113 -0
- package/server/modules/voice/voice.service.ts +192 -0
- package/server/modules/websocket/README.md +7 -7
- package/server/modules/websocket/services/chat-session-writer.service.ts +2 -2
- package/server/modules/websocket/services/chat-websocket.service.ts +73 -61
- package/server/modules/websocket/services/shell-websocket.service.ts +88 -12
- package/server/modules/websocket/services/websocket-server.service.ts +63 -19
- package/server/modules/websocket/tests/{chat-image-filter.test.ts → chat-attachment-filter.test.ts} +17 -2
- package/server/modules/websocket/tests/shell-websocket.service.test.ts +119 -0
- package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
- package/server/modules/worktrees/index.ts +2 -0
- package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
- package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
- package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
- package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
- package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
- package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
- package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
- package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
- package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
- package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
- package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
- package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
- package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
- package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
- package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
- package/server/modules/worktrees/worktrees.module.ts +113 -0
- package/server/modules/worktrees/worktrees.routes.ts +116 -0
- package/server/shared/image-attachments.ts +112 -18
- package/server/shared/interfaces.ts +29 -19
- package/server/shared/tests/image-attachments.test.ts +55 -0
- package/server/shared/types.ts +658 -21
- package/server/shared/utils.ts +77 -212
- package/dist/assets/index-DLmhQ15L.css +0 -32
- package/dist-server/server/browser-use-mcp.js.map +0 -1
- package/dist-server/server/claude-sdk.js.map +0 -1
- package/dist-server/server/cli.js +0 -647
- package/dist-server/server/cli.js.map +0 -1
- package/dist-server/server/cursor-cli.js.map +0 -1
- package/dist-server/server/middleware/auth.js.map +0 -1
- package/dist-server/server/modules/providers/tests/provider-image-history.test.js.map +0 -1
- package/dist-server/server/modules/websocket/tests/chat-image-filter.test.js.map +0 -1
- package/dist-server/server/openai-codex.js.map +0 -1
- package/dist-server/server/opencode-cli.js.map +0 -1
- package/dist-server/server/opencode-cli.test.js.map +0 -1
- package/dist-server/server/routes/agent.js +0 -1155
- package/dist-server/server/routes/agent.js.map +0 -1
- package/dist-server/server/routes/auth.js +0 -119
- package/dist-server/server/routes/auth.js.map +0 -1
- package/dist-server/server/routes/commands.js +0 -492
- package/dist-server/server/routes/commands.js.map +0 -1
- package/dist-server/server/routes/cursor.js +0 -49
- package/dist-server/server/routes/cursor.js.map +0 -1
- package/dist-server/server/routes/git.js +0 -1389
- package/dist-server/server/routes/git.js.map +0 -1
- package/dist-server/server/routes/git.test.js.map +0 -1
- package/dist-server/server/routes/mcp-utils.js +0 -29
- package/dist-server/server/routes/mcp-utils.js.map +0 -1
- package/dist-server/server/routes/plugins.js +0 -266
- package/dist-server/server/routes/plugins.js.map +0 -1
- package/dist-server/server/routes/settings.js +0 -249
- package/dist-server/server/routes/settings.js.map +0 -1
- package/dist-server/server/routes/taskmaster.js +0 -1362
- package/dist-server/server/routes/taskmaster.js.map +0 -1
- package/dist-server/server/routes/tests/commands.test.js +0 -76
- package/dist-server/server/routes/tests/commands.test.js.map +0 -1
- package/dist-server/server/routes/user.js +0 -116
- package/dist-server/server/routes/user.js.map +0 -1
- package/dist-server/server/services/notification-orchestrator.js +0 -2
- package/dist-server/server/services/notification-orchestrator.js.map +0 -1
- package/dist-server/server/services/tests/notification-orchestrator.test.js +0 -64
- package/dist-server/server/services/tests/notification-orchestrator.test.js.map +0 -1
- package/dist-server/server/services/vapid-keys.js.map +0 -1
- package/dist-server/server/utils/colors.js +0 -20
- package/dist-server/server/utils/colors.js.map +0 -1
- package/dist-server/server/utils/commandParser.js +0 -255
- package/dist-server/server/utils/commandParser.js.map +0 -1
- package/dist-server/server/utils/gitConfig.js +0 -37
- package/dist-server/server/utils/gitConfig.js.map +0 -1
- package/dist-server/server/utils/mcp-detector.js +0 -134
- package/dist-server/server/utils/mcp-detector.js.map +0 -1
- package/dist-server/server/utils/plugin-loader.js.map +0 -1
- package/dist-server/server/utils/plugin-process-manager.js.map +0 -1
- package/dist-server/server/utils/runtime-paths.js +0 -30
- package/dist-server/server/utils/runtime-paths.js.map +0 -1
- package/dist-server/server/utils/taskmaster-websocket.js +0 -124
- package/dist-server/server/utils/taskmaster-websocket.js.map +0 -1
- package/dist-server/server/utils/url-detection.js +0 -58
- package/dist-server/server/utils/url-detection.js.map +0 -1
- package/dist-server/server/voice-proxy.js +0 -226
- package/dist-server/server/voice-proxy.js.map +0 -1
- package/server/cli.js +0 -695
- package/server/index.js +0 -1651
- package/server/routes/agent.js +0 -1257
- package/server/routes/auth.js +0 -137
- package/server/routes/cursor.js +0 -52
- package/server/routes/mcp-utils.js +0 -31
- package/server/routes/plugins.js +0 -307
- package/server/routes/settings.js +0 -282
- package/server/routes/taskmaster.js +0 -1470
- package/server/routes/tests/commands.test.js +0 -82
- package/server/routes/user.js +0 -124
- package/server/services/notification-orchestrator.js +0 -7
- package/server/services/tests/notification-orchestrator.test.js +0 -80
- package/server/utils/colors.js +0 -21
- package/server/utils/commandParser.js +0 -305
- package/server/utils/gitConfig.js +0 -35
- package/server/utils/mcp-detector.js +0 -147
- package/server/utils/runtime-paths.js +0 -37
- package/server/utils/taskmaster-websocket.js +0 -135
- package/server/utils/url-detection.js +0 -71
- package/server/voice-proxy.js +0 -224
- /package/server/constants/{config.js → config.ts} +0 -0
|
@@ -4,7 +4,20 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
opencodeRuntime,
|
|
9
|
+
resolveOpenCodePermissionOptions,
|
|
10
|
+
} from './opencode-runtime.provider.js';
|
|
11
|
+
import { OpenCodeSessionsProvider } from './opencode-sessions.provider.js';
|
|
12
|
+
|
|
13
|
+
const sessionsProvider = new OpenCodeSessionsProvider();
|
|
14
|
+
const runtimeContext = {
|
|
15
|
+
resolveProviderSessionId: (sessionId) => sessionId || null,
|
|
16
|
+
resolveResumeModel: async (_sessionId, requestedModel) => requestedModel || undefined,
|
|
17
|
+
getProviderModels: async () => ({ OPTIONS: [], DEFAULT: '' }),
|
|
18
|
+
normalizeMessage: (raw, sessionId) => sessionsProvider.normalizeMessage(raw, sessionId),
|
|
19
|
+
isProviderInstalled: async () => true,
|
|
20
|
+
};
|
|
8
21
|
|
|
9
22
|
const findEnvKey = (name) =>
|
|
10
23
|
Object.keys(process.env).find((key) => key.toLowerCase() === name.toLowerCase()) || name;
|
|
@@ -71,7 +84,7 @@ test('spawnOpenCode emits session_created before normalized live messages for ne
|
|
|
71
84
|
: `.COM;.EXE;.BAT;.CMD${previousPathExt ? `;${previousPathExt}` : ''}`;
|
|
72
85
|
}
|
|
73
86
|
|
|
74
|
-
await
|
|
87
|
+
await opencodeRuntime.run('Hi', { cwd: tempRoot }, writer, runtimeContext);
|
|
75
88
|
|
|
76
89
|
const sessionCreatedIndex = messages.findIndex((message) => message.kind === 'session_created');
|
|
77
90
|
const assistantDeltaIndex = messages.findIndex((message) =>
|
|
@@ -98,6 +111,26 @@ test('spawnOpenCode emits session_created before normalized live messages for ne
|
|
|
98
111
|
assert.equal(launchedArgs.includes('--auto'), false);
|
|
99
112
|
assert.equal(launchedArgs.includes('--agent'), false);
|
|
100
113
|
assert.equal(capture.permissionEnv, null);
|
|
114
|
+
|
|
115
|
+
const attachmentOnlyCapturePath = path.join(tempRoot, 'opencode-attachment-only.json');
|
|
116
|
+
process.env.OPENCODE_ARGS_CAPTURE = attachmentOnlyCapturePath;
|
|
117
|
+
await opencodeRuntime.run(
|
|
118
|
+
'',
|
|
119
|
+
{
|
|
120
|
+
cwd: tempRoot,
|
|
121
|
+
files: [{
|
|
122
|
+
path: path.join(tempRoot, 'brief.pdf'),
|
|
123
|
+
name: 'brief.pdf',
|
|
124
|
+
mimeType: 'application/pdf',
|
|
125
|
+
}],
|
|
126
|
+
},
|
|
127
|
+
writer,
|
|
128
|
+
runtimeContext,
|
|
129
|
+
);
|
|
130
|
+
const attachmentOnlyCapture = JSON.parse(await readFile(attachmentOnlyCapturePath, 'utf8'));
|
|
131
|
+
const attachmentPrompt = attachmentOnlyCapture.args[attachmentOnlyCapture.args.length - 1];
|
|
132
|
+
assert.match(attachmentPrompt, /<files_input>/);
|
|
133
|
+
assert.match(attachmentPrompt, /brief\.pdf/);
|
|
101
134
|
} finally {
|
|
102
135
|
if (previousPath === undefined) {
|
|
103
136
|
delete process.env[pathKey];
|
|
@@ -186,7 +219,12 @@ test('spawnOpenCode passes permission mode flags and env to the CLI', async () =
|
|
|
186
219
|
const argsCapturePath = path.join(tempRoot, `opencode-args-${scenario.permissionMode}.json`);
|
|
187
220
|
process.env.OPENCODE_ARGS_CAPTURE = argsCapturePath;
|
|
188
221
|
|
|
189
|
-
await
|
|
222
|
+
await opencodeRuntime.run(
|
|
223
|
+
'Hi',
|
|
224
|
+
{ cwd: tempRoot, permissionMode: scenario.permissionMode },
|
|
225
|
+
writer,
|
|
226
|
+
runtimeContext,
|
|
227
|
+
);
|
|
190
228
|
|
|
191
229
|
const capture = JSON.parse(await readFile(argsCapturePath, 'utf8'));
|
|
192
230
|
for (const expectedArg of scenario.expectArgs) {
|
|
@@ -2,7 +2,7 @@ import fsSync from 'node:fs';
|
|
|
2
2
|
|
|
3
3
|
import Database from 'better-sqlite3';
|
|
4
4
|
|
|
5
|
-
import { parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
5
|
+
import { parseFilesInputTag, parseImagesInputTag } from '@/shared/image-attachments.js';
|
|
6
6
|
import type { IProviderSessions } from '@/shared/interfaces.js';
|
|
7
7
|
import type { AnyRecord, FetchHistoryOptions, FetchHistoryResult, NormalizedMessage } from '@/shared/types.js';
|
|
8
8
|
import {
|
|
@@ -404,10 +404,17 @@ export class OpenCodeSessionsProvider implements IProviderSessions {
|
|
|
404
404
|
const rawContent = extractText(partData);
|
|
405
405
|
// User prompts sent with attachments carry an <images_input> path
|
|
406
406
|
// list; strip it for display and surface the paths as images.
|
|
407
|
-
const
|
|
407
|
+
const parsedImages = messageRole === 'user'
|
|
408
408
|
? parseImagesInputTag(rawContent)
|
|
409
409
|
: { text: rawContent, attachments: [] };
|
|
410
|
-
|
|
410
|
+
const parsedFiles = messageRole === 'user'
|
|
411
|
+
? parseFilesInputTag(parsedImages.text)
|
|
412
|
+
: { text: rawContent, attachments: [] };
|
|
413
|
+
if (
|
|
414
|
+
parsedFiles.text.trim()
|
|
415
|
+
|| parsedImages.attachments.length > 0
|
|
416
|
+
|| parsedFiles.attachments.length > 0
|
|
417
|
+
) {
|
|
411
418
|
normalized.push(createNormalizedMessage({
|
|
412
419
|
id: baseId,
|
|
413
420
|
sessionId,
|
|
@@ -415,8 +422,9 @@ export class OpenCodeSessionsProvider implements IProviderSessions {
|
|
|
415
422
|
provider: PROVIDER,
|
|
416
423
|
kind: 'text',
|
|
417
424
|
role: messageRole === 'user' ? 'user' : 'assistant',
|
|
418
|
-
content,
|
|
419
|
-
images: attachments.length > 0 ? attachments : undefined,
|
|
425
|
+
content: parsedFiles.text,
|
|
426
|
+
images: parsedImages.attachments.length > 0 ? parsedImages.attachments : undefined,
|
|
427
|
+
files: parsedFiles.attachments.length > 0 ? parsedFiles.attachments : undefined,
|
|
420
428
|
}));
|
|
421
429
|
}
|
|
422
430
|
continue;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenCodeProviderAuth } from '@/modules/providers/list/opencode/opencode-auth.provider.js';
|
|
2
2
|
import { OpenCodeProviderModels } from '@/modules/providers/list/opencode/opencode-models.provider.js';
|
|
3
|
+
import { opencodeRuntime } from '@/modules/providers/list/opencode/opencode-runtime.provider.js';
|
|
3
4
|
import { OpenCodeMcpProvider } from '@/modules/providers/list/opencode/opencode-mcp.provider.js';
|
|
4
5
|
import { OpenCodeSessionSynchronizer } from '@/modules/providers/list/opencode/opencode-session-synchronizer.provider.js';
|
|
5
6
|
import { OpenCodeSessionsProvider } from '@/modules/providers/list/opencode/opencode-sessions.provider.js';
|
|
@@ -8,12 +9,14 @@ import { AbstractProvider } from '@/modules/providers/shared/base/abstract.provi
|
|
|
8
9
|
import type {
|
|
9
10
|
IProviderAuth,
|
|
10
11
|
IProviderModels,
|
|
12
|
+
IProviderRuntime,
|
|
11
13
|
IProviderSessionSynchronizer,
|
|
12
14
|
IProviderSkills,
|
|
13
15
|
IProviderSessions,
|
|
14
16
|
} from '@/shared/interfaces.js';
|
|
15
17
|
|
|
16
18
|
export class OpenCodeProvider extends AbstractProvider {
|
|
19
|
+
readonly runtime: IProviderRuntime = opencodeRuntime;
|
|
17
20
|
readonly models: IProviderModels = new OpenCodeProviderModels();
|
|
18
21
|
readonly mcp = new OpenCodeMcpProvider();
|
|
19
22
|
readonly auth: IProviderAuth = new OpenCodeProviderAuth();
|
|
@@ -4,6 +4,7 @@ import { providerAuthService } from '@/modules/providers/services/provider-auth.
|
|
|
4
4
|
import { providerCapabilitiesService } from '@/modules/providers/services/provider-capabilities.service.js';
|
|
5
5
|
import { providerMcpService } from '@/modules/providers/services/mcp.service.js';
|
|
6
6
|
import { providerModelsService } from '@/modules/providers/services/provider-models.service.js';
|
|
7
|
+
import { providerTokenUsageService } from '@/modules/providers/services/provider-token-usage.service.js';
|
|
7
8
|
import { providerSkillsService } from '@/modules/providers/services/skills.service.js';
|
|
8
9
|
import { sessionConversationsSearchService } from '@/modules/providers/services/session-conversations-search.service.js';
|
|
9
10
|
import { sessionsService } from '@/modules/providers/services/sessions.service.js';
|
|
@@ -11,7 +12,6 @@ import type {
|
|
|
11
12
|
LLMProvider,
|
|
12
13
|
McpScope,
|
|
13
14
|
McpTransport,
|
|
14
|
-
ProviderChangeActiveModelInput,
|
|
15
15
|
ProviderSkillCreateFile,
|
|
16
16
|
ProviderSkillCreateInput,
|
|
17
17
|
UpsertProviderMcpServerInput,
|
|
@@ -352,7 +352,7 @@ const parseSessionSearchLimit = (value: unknown): number => {
|
|
|
352
352
|
return Math.max(1, Math.min(parsed, 100));
|
|
353
353
|
};
|
|
354
354
|
|
|
355
|
-
const
|
|
355
|
+
const parseSessionModelPayload = (payload: unknown): string => {
|
|
356
356
|
if (!payload || typeof payload !== 'object') {
|
|
357
357
|
throw new AppError('Request body must be an object.', {
|
|
358
358
|
code: 'INVALID_REQUEST_BODY',
|
|
@@ -369,10 +369,7 @@ const parseChangeActiveModelPayload = (payload: unknown): ProviderChangeActiveMo
|
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
return
|
|
373
|
-
sessionId: '',
|
|
374
|
-
model,
|
|
375
|
-
};
|
|
372
|
+
return model;
|
|
376
373
|
};
|
|
377
374
|
|
|
378
375
|
router.get(
|
|
@@ -394,20 +391,40 @@ router.get(
|
|
|
394
391
|
}),
|
|
395
392
|
);
|
|
396
393
|
|
|
397
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Reports which model one session is using. `requestedModel` lets the client
|
|
396
|
+
* pass the default it would otherwise send, so a session that has not been
|
|
397
|
+
* sent on yet resolves to that instead of the catalog default.
|
|
398
|
+
*/
|
|
399
|
+
router.get(
|
|
398
400
|
'/:provider/sessions/:sessionId/active-model',
|
|
399
401
|
asyncHandler(async (req: Request, res: Response) => {
|
|
400
402
|
const provider = parseProvider(req.params.provider);
|
|
401
403
|
const sessionId = parseSessionId(req.params.sessionId);
|
|
402
|
-
const
|
|
403
|
-
const result = await providerModelsService.
|
|
404
|
-
...payload,
|
|
404
|
+
const requestedModel = readOptionalQueryString(req.query.requestedModel);
|
|
405
|
+
const result = await providerModelsService.resolveSessionModel(provider, {
|
|
405
406
|
sessionId,
|
|
407
|
+
requestedModel,
|
|
406
408
|
});
|
|
407
409
|
res.json(createApiSuccessResponse(result));
|
|
408
410
|
}),
|
|
409
411
|
);
|
|
410
412
|
|
|
413
|
+
router.post(
|
|
414
|
+
'/:provider/sessions/:sessionId/active-model',
|
|
415
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
416
|
+
const provider = parseProvider(req.params.provider);
|
|
417
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
418
|
+
const model = parseSessionModelPayload(req.body);
|
|
419
|
+
const stored = providerModelsService.setSessionModel(provider, sessionId, model);
|
|
420
|
+
// A session row only exists once the gateway has allocated one. Report the
|
|
421
|
+
// selection back either way so the client can hold it until the first send.
|
|
422
|
+
res.json(createApiSuccessResponse(
|
|
423
|
+
stored ?? { provider, sessionId, model, source: 'session' as const },
|
|
424
|
+
));
|
|
425
|
+
}),
|
|
426
|
+
);
|
|
427
|
+
|
|
411
428
|
// ----------------- Skills routes -----------------
|
|
412
429
|
router.get(
|
|
413
430
|
'/:provider/skills',
|
|
@@ -556,6 +573,26 @@ router.get(
|
|
|
556
573
|
}),
|
|
557
574
|
);
|
|
558
575
|
|
|
576
|
+
router.get(
|
|
577
|
+
'/sessions/:sessionId/token-usage',
|
|
578
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
579
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
580
|
+
const result = await providerTokenUsageService.getSessionTokenUsage(sessionId);
|
|
581
|
+
res.json(createApiSuccessResponse(result));
|
|
582
|
+
}),
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
// Must stay registered after the static `/sessions/running` and
|
|
586
|
+
// `/sessions/archived` routes so those literals never match `:sessionId`.
|
|
587
|
+
router.get(
|
|
588
|
+
'/sessions/:sessionId',
|
|
589
|
+
asyncHandler(async (req: Request, res: Response) => {
|
|
590
|
+
const sessionId = parseSessionId(req.params.sessionId);
|
|
591
|
+
const result = sessionsService.getSessionDetailsById(sessionId);
|
|
592
|
+
res.json(createApiSuccessResponse(result));
|
|
593
|
+
}),
|
|
594
|
+
);
|
|
595
|
+
|
|
559
596
|
router.delete(
|
|
560
597
|
'/sessions/:sessionId',
|
|
561
598
|
asyncHandler(async (req: Request, res: Response) => {
|
|
@@ -15,6 +15,8 @@ type ProviderCapabilities = {
|
|
|
15
15
|
defaultPermissionMode: string;
|
|
16
16
|
/** Whether image attachments can be included in a chat.send. */
|
|
17
17
|
supportsImages: boolean;
|
|
18
|
+
/** Whether general file attachments can be included in a chat.send. */
|
|
19
|
+
supportsFiles: boolean;
|
|
18
20
|
/** Whether an in-flight run can be cancelled via chat.abort. */
|
|
19
21
|
supportsAbort: boolean;
|
|
20
22
|
/** Whether interactive tool permission prompts can reach the UI. */
|
|
@@ -37,6 +39,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
37
39
|
permissionModes: ['default', 'auto', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
38
40
|
defaultPermissionMode: 'default',
|
|
39
41
|
supportsImages: true,
|
|
42
|
+
supportsFiles: true,
|
|
40
43
|
supportsAbort: true,
|
|
41
44
|
supportsPermissionRequests: true,
|
|
42
45
|
supportsTokenUsage: true,
|
|
@@ -47,6 +50,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
47
50
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
48
51
|
defaultPermissionMode: 'default',
|
|
49
52
|
supportsImages: true,
|
|
53
|
+
supportsFiles: true,
|
|
50
54
|
supportsAbort: true,
|
|
51
55
|
supportsPermissionRequests: false,
|
|
52
56
|
supportsTokenUsage: false,
|
|
@@ -57,6 +61,7 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
57
61
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions'],
|
|
58
62
|
defaultPermissionMode: 'default',
|
|
59
63
|
supportsImages: true,
|
|
64
|
+
supportsFiles: true,
|
|
60
65
|
supportsAbort: true,
|
|
61
66
|
supportsPermissionRequests: false,
|
|
62
67
|
supportsTokenUsage: true,
|
|
@@ -66,10 +71,11 @@ const PROVIDER_CAPABILITIES: Record<LLMProvider, ProviderCapabilities> = {
|
|
|
66
71
|
provider: 'opencode',
|
|
67
72
|
// Mapped by the runtime onto OpenCode's controls: `--agent plan` (plan),
|
|
68
73
|
// `--auto` (bypassPermissions) and the OPENCODE_PERMISSION env var
|
|
69
|
-
// (acceptEdits). See resolveOpenCodePermissionOptions in
|
|
74
|
+
// (acceptEdits). See resolveOpenCodePermissionOptions in the OpenCode runtime adapter.
|
|
70
75
|
permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan'],
|
|
71
76
|
defaultPermissionMode: 'default',
|
|
72
77
|
supportsImages: true,
|
|
78
|
+
supportsFiles: true,
|
|
73
79
|
supportsAbort: true,
|
|
74
80
|
supportsPermissionRequests: false,
|
|
75
81
|
supportsTokenUsage: true,
|
|
@@ -2,27 +2,32 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
+
import { sessionsDb } from '@/modules/database/index.js';
|
|
5
6
|
import { providerRegistry } from '@/modules/providers/provider.registry.js';
|
|
6
7
|
import type { IProvider } from '@/shared/interfaces.js';
|
|
7
8
|
import type {
|
|
8
9
|
LLMProvider,
|
|
9
|
-
ProviderChangeActiveModelInput,
|
|
10
10
|
ProviderCurrentActiveModel,
|
|
11
11
|
ProviderModelsCacheInfo,
|
|
12
12
|
ProviderModelsDefinition,
|
|
13
13
|
ProviderModelsResult,
|
|
14
|
-
|
|
14
|
+
ProviderSessionModel,
|
|
15
15
|
} from '@/shared/types.js';
|
|
16
|
-
import { readProviderSessionActiveModelChange } from '@/shared/utils.js';
|
|
17
16
|
|
|
18
17
|
export const PROVIDER_MODELS_CACHE_TTL_MS = 3 * 24 * 60 * 60 * 1000;
|
|
19
18
|
const PROVIDER_MODELS_CACHE_VERSION = 2;
|
|
20
19
|
const UNCACHED_PROVIDERS = new Set<LLMProvider>(['claude']);
|
|
21
20
|
|
|
21
|
+
/** Session-row access the service needs, narrowed so tests can stub it. */
|
|
22
|
+
type ProviderModelsSessionStore = {
|
|
23
|
+
getSessionById(sessionId: string): { model: string | null } | null;
|
|
24
|
+
setSessionModel(sessionId: string, model: string): void;
|
|
25
|
+
};
|
|
26
|
+
|
|
22
27
|
type ProviderModelsServiceDependencies = {
|
|
23
28
|
resolveProvider?: (provider: LLMProvider) => Pick<IProvider, 'models'>;
|
|
24
29
|
cachePath?: string;
|
|
25
|
-
|
|
30
|
+
sessions?: ProviderModelsSessionStore;
|
|
26
31
|
now?: () => number;
|
|
27
32
|
};
|
|
28
33
|
|
|
@@ -137,7 +142,7 @@ const writeProviderModelsCacheFile = async (
|
|
|
137
142
|
export const createProviderModelsService = (dependencies: ProviderModelsServiceDependencies = {}) => {
|
|
138
143
|
const resolveProvider = dependencies.resolveProvider ?? providerRegistry.resolveProvider;
|
|
139
144
|
const cachePath = dependencies.cachePath ?? getProviderModelsCachePath();
|
|
140
|
-
const
|
|
145
|
+
const sessions = dependencies.sessions ?? sessionsDb;
|
|
141
146
|
const now = dependencies.now ?? (() => Date.now());
|
|
142
147
|
const memoryCache = new Map<LLMProvider, ProviderModelsCacheEntry>();
|
|
143
148
|
const pendingRequests = new Map<LLMProvider, Promise<ProviderModelsResult>>();
|
|
@@ -308,34 +313,138 @@ export const createProviderModelsService = (dependencies: ProviderModelsServiceD
|
|
|
308
313
|
sessionId?: string,
|
|
309
314
|
): Promise<ProviderCurrentActiveModel> => resolveProvider(provider).models.getCurrentActiveModel(sessionId);
|
|
310
315
|
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
316
|
+
const readRecordedSessionModel = (sessionId: string): string | null => {
|
|
317
|
+
const session = sessions.getSessionById(sessionId);
|
|
318
|
+
return session?.model?.trim() || null;
|
|
319
|
+
};
|
|
315
320
|
|
|
316
|
-
|
|
321
|
+
/**
|
|
322
|
+
* Records the model one session runs with.
|
|
323
|
+
*
|
|
324
|
+
* Called from the active-model route when the user picks a model and from
|
|
325
|
+
* `chat.send` on every turn, so the row always matches what the session last
|
|
326
|
+
* ran with. Sessions the app has not created yet (no row) are ignored rather
|
|
327
|
+
* than treated as an error: the client keeps its own pending selection and
|
|
328
|
+
* the value lands on the row with the first send.
|
|
329
|
+
*/
|
|
330
|
+
const setSessionModel = (
|
|
317
331
|
provider: LLMProvider,
|
|
318
332
|
sessionId: string,
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
333
|
+
model: string,
|
|
334
|
+
): ProviderSessionModel | null => {
|
|
335
|
+
const normalizedSessionId = sessionId.trim();
|
|
336
|
+
const normalizedModel = model.trim();
|
|
337
|
+
if (!normalizedSessionId || !normalizedModel) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (!sessions.getSessionById(normalizedSessionId)) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
sessions.setSessionModel(normalizedSessionId, normalizedModel);
|
|
346
|
+
return {
|
|
347
|
+
provider,
|
|
348
|
+
sessionId: normalizedSessionId,
|
|
349
|
+
model: normalizedModel,
|
|
350
|
+
source: 'session',
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Answers "which model is this session using?" for every display surface.
|
|
356
|
+
*
|
|
357
|
+
* Precedence, highest first:
|
|
358
|
+
* 1. the model recorded on the session row — the user's pick, or whatever
|
|
359
|
+
* the last send used;
|
|
360
|
+
* 2. the provider's own session state, for sessions started outside the app
|
|
361
|
+
* that we have never recorded a model for;
|
|
362
|
+
* 3. `requestedModel`, the client's current default, for a chat that has no
|
|
363
|
+
* session yet;
|
|
364
|
+
* 4. the provider catalog default.
|
|
365
|
+
*/
|
|
366
|
+
const resolveSessionModel = async (
|
|
367
|
+
provider: LLMProvider,
|
|
368
|
+
options: { sessionId?: string | null; requestedModel?: string | null } = {},
|
|
369
|
+
): Promise<ProviderSessionModel> => {
|
|
370
|
+
const normalizedSessionId = typeof options.sessionId === 'string' ? options.sessionId.trim() : '';
|
|
371
|
+
const normalizedRequestedModel = typeof options.requestedModel === 'string'
|
|
372
|
+
? options.requestedModel.trim()
|
|
373
|
+
: '';
|
|
374
|
+
|
|
375
|
+
if (normalizedSessionId) {
|
|
376
|
+
const recordedModel = readRecordedSessionModel(normalizedSessionId);
|
|
377
|
+
if (recordedModel) {
|
|
378
|
+
return {
|
|
379
|
+
provider,
|
|
380
|
+
sessionId: normalizedSessionId,
|
|
381
|
+
model: recordedModel,
|
|
382
|
+
source: 'session',
|
|
383
|
+
};
|
|
384
|
+
}
|
|
322
385
|
|
|
386
|
+
// Never sent on through the app. Ask the provider what its own session
|
|
387
|
+
// state says before falling back to anything client-supplied.
|
|
388
|
+
const catalog = (await getProviderModels(provider)).models;
|
|
389
|
+
const providerModel = await getCurrentActiveModel(provider, normalizedSessionId);
|
|
390
|
+
const resolvedProviderModel = providerModel.model?.trim();
|
|
391
|
+
if (resolvedProviderModel && resolvedProviderModel !== catalog.DEFAULT) {
|
|
392
|
+
return {
|
|
393
|
+
provider,
|
|
394
|
+
sessionId: normalizedSessionId,
|
|
395
|
+
model: resolvedProviderModel,
|
|
396
|
+
source: 'provider',
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return {
|
|
401
|
+
provider,
|
|
402
|
+
sessionId: normalizedSessionId,
|
|
403
|
+
model: normalizedRequestedModel || catalog.DEFAULT,
|
|
404
|
+
source: normalizedRequestedModel ? 'session' : 'default',
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (normalizedRequestedModel) {
|
|
409
|
+
return {
|
|
410
|
+
provider,
|
|
411
|
+
sessionId: null,
|
|
412
|
+
model: normalizedRequestedModel,
|
|
413
|
+
source: 'session',
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const catalog = (await getProviderModels(provider)).models;
|
|
418
|
+
return {
|
|
419
|
+
provider,
|
|
420
|
+
sessionId: null,
|
|
421
|
+
model: catalog.DEFAULT,
|
|
422
|
+
source: 'default',
|
|
423
|
+
};
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Picks the model one run should use, for provider runtime adapters.
|
|
428
|
+
*
|
|
429
|
+
* Deliberately narrower than `resolveSessionModel`: the provider's own
|
|
430
|
+
* session state is not consulted here. Codex reports a global config value
|
|
431
|
+
* from `getCurrentActiveModel`, which would silently override the model the
|
|
432
|
+
* user picked in the composer on every single run.
|
|
433
|
+
*/
|
|
323
434
|
const resolveResumeModel = async (
|
|
324
435
|
provider: LLMProvider,
|
|
325
436
|
sessionId: string | undefined,
|
|
326
437
|
requestedModel?: string | null,
|
|
327
438
|
): Promise<string | undefined> => {
|
|
439
|
+
void provider;
|
|
328
440
|
const normalizedRequestedModel = typeof requestedModel === 'string' ? requestedModel.trim() : '';
|
|
329
|
-
|
|
441
|
+
const normalizedSessionId = sessionId?.trim();
|
|
442
|
+
if (!normalizedSessionId) {
|
|
330
443
|
return normalizedRequestedModel || undefined;
|
|
331
444
|
}
|
|
332
445
|
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
return changedModel.model.trim();
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return normalizedRequestedModel || undefined;
|
|
446
|
+
const recordedModel = readRecordedSessionModel(normalizedSessionId);
|
|
447
|
+
return recordedModel || normalizedRequestedModel || undefined;
|
|
339
448
|
};
|
|
340
449
|
|
|
341
450
|
const clearCache = (): void => {
|
|
@@ -347,9 +456,8 @@ export const createProviderModelsService = (dependencies: ProviderModelsServiceD
|
|
|
347
456
|
|
|
348
457
|
return {
|
|
349
458
|
getProviderModels,
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
changeActiveModel,
|
|
459
|
+
setSessionModel,
|
|
460
|
+
resolveSessionModel,
|
|
353
461
|
resolveResumeModel,
|
|
354
462
|
clearCache,
|
|
355
463
|
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { providerRegistry } from '@/modules/providers/provider.registry.js';
|
|
2
|
+
import { providerModelsService } from '@/modules/providers/services/provider-models.service.js';
|
|
3
|
+
import { sessionsService } from '@/modules/providers/services/sessions.service.js';
|
|
4
|
+
import type { IProvider } from '@/shared/interfaces.js';
|
|
5
|
+
import type {
|
|
6
|
+
AnyRecord,
|
|
7
|
+
LLMProvider,
|
|
8
|
+
ProviderPermissionDecision,
|
|
9
|
+
ProviderRunFunction,
|
|
10
|
+
ProviderRuntimeContext,
|
|
11
|
+
ProviderRuntimeWriter,
|
|
12
|
+
} from '@/shared/types.js';
|
|
13
|
+
|
|
14
|
+
type ProviderRuntimeServiceDependencies = {
|
|
15
|
+
listProviders(): IProvider[];
|
|
16
|
+
resolveProvider(provider: string): IProvider;
|
|
17
|
+
resolveProviderSessionId(sessionId: string | null | undefined): string | null;
|
|
18
|
+
resolveResumeModel(
|
|
19
|
+
provider: LLMProvider,
|
|
20
|
+
sessionId: string | undefined,
|
|
21
|
+
requestedModel?: string | null,
|
|
22
|
+
): Promise<string | undefined>;
|
|
23
|
+
getProviderModels: typeof providerModelsService.getProviderModels;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const defaultDependencies: ProviderRuntimeServiceDependencies = {
|
|
27
|
+
listProviders: () => providerRegistry.listProviders(),
|
|
28
|
+
resolveProvider: (provider) => providerRegistry.resolveProvider(provider),
|
|
29
|
+
resolveProviderSessionId: (sessionId) => sessionsService.resolveProviderSessionId(sessionId),
|
|
30
|
+
resolveResumeModel: (provider, sessionId, requestedModel) =>
|
|
31
|
+
providerModelsService.resolveResumeModel(provider, sessionId, requestedModel),
|
|
32
|
+
getProviderModels: (provider, options) => providerModelsService.getProviderModels(provider, options),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates the application-facing provider runtime dispatcher.
|
|
37
|
+
*
|
|
38
|
+
* The provider registry owns each concrete runtime. This service supplies the
|
|
39
|
+
* registry-backed model/session lookups at execution time so runtime adapters
|
|
40
|
+
* never import services that resolve back through the registry.
|
|
41
|
+
*/
|
|
42
|
+
export function createProviderRuntimeService(
|
|
43
|
+
dependencyOverrides: Partial<ProviderRuntimeServiceDependencies> = {},
|
|
44
|
+
) {
|
|
45
|
+
const dependencies = { ...defaultDependencies, ...dependencyOverrides };
|
|
46
|
+
|
|
47
|
+
const createRuntimeContext = (
|
|
48
|
+
provider: IProvider,
|
|
49
|
+
): ProviderRuntimeContext => ({
|
|
50
|
+
resolveProviderSessionId: dependencies.resolveProviderSessionId,
|
|
51
|
+
resolveResumeModel: (sessionId, requestedModel) =>
|
|
52
|
+
dependencies.resolveResumeModel(provider.id, sessionId, requestedModel),
|
|
53
|
+
getProviderModels: async () =>
|
|
54
|
+
(await dependencies.getProviderModels(provider.id)).models,
|
|
55
|
+
normalizeMessage: (raw, sessionId) => provider.sessions.normalizeMessage(raw, sessionId),
|
|
56
|
+
async isProviderInstalled() {
|
|
57
|
+
try {
|
|
58
|
+
return (await provider.auth.getStatus()).installed;
|
|
59
|
+
} catch {
|
|
60
|
+
// Preserve the runtime's original error when installation probing fails.
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const run = (
|
|
67
|
+
providerName: LLMProvider,
|
|
68
|
+
command: string,
|
|
69
|
+
options: AnyRecord,
|
|
70
|
+
writer: ProviderRuntimeWriter,
|
|
71
|
+
): Promise<unknown> => {
|
|
72
|
+
const provider = dependencies.resolveProvider(providerName);
|
|
73
|
+
return provider.runtime.run(command, options, writer, createRuntimeContext(provider));
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
run,
|
|
78
|
+
|
|
79
|
+
hasRuntime(providerName: string): boolean {
|
|
80
|
+
try {
|
|
81
|
+
return Boolean(dependencies.resolveProvider(providerName).runtime);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
getRunner(provider: LLMProvider): ProviderRunFunction {
|
|
88
|
+
return (command, options, writer) => run(provider, command, options, writer);
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
async abort(providerName: LLMProvider, sessionId: string): Promise<boolean> {
|
|
92
|
+
return Boolean(await dependencies.resolveProvider(providerName).runtime.abort(sessionId));
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
resolveToolApproval(requestId: string, decision: ProviderPermissionDecision): void {
|
|
96
|
+
for (const provider of dependencies.listProviders()) {
|
|
97
|
+
provider.runtime.permissions?.resolve(requestId, decision);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
getPendingApprovalsForSession(sessionId: string): unknown[] {
|
|
102
|
+
return dependencies.listProviders().flatMap(
|
|
103
|
+
(provider) => provider.runtime.permissions?.listPending(sessionId) ?? [],
|
|
104
|
+
);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const providerRuntimeService = createProviderRuntimeService();
|