mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 17:52:49 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b589599a8f | ||
|
|
9821729c75 | ||
|
|
7e599db6fe | ||
|
|
b3bfec027f | ||
|
|
6610dbdffe | ||
|
|
a27a1a07dc | ||
|
|
dcaed8008b |
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.2.2 - 2026-07-25
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Claude 5 models now use the correct context windows.
|
||||||
|
|
||||||
## 0.2.1 - 2026-07-24
|
## 0.2.1 - 2026-07-24
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
Generated
+57
-57
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "paseo",
|
"name": "paseo",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "paseo",
|
"name": "paseo",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
@@ -35211,7 +35211,7 @@
|
|||||||
},
|
},
|
||||||
"packages/app": {
|
"packages/app": {
|
||||||
"name": "@getpaseo/app",
|
"name": "@getpaseo/app",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/commands": "6.10.4",
|
"@codemirror/commands": "6.10.4",
|
||||||
"@codemirror/language": "6.12.4",
|
"@codemirror/language": "6.12.4",
|
||||||
@@ -36236,12 +36236,12 @@
|
|||||||
},
|
},
|
||||||
"packages/cli": {
|
"packages/cli": {
|
||||||
"name": "@getpaseo/cli",
|
"name": "@getpaseo/cli",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "^1.0.0",
|
"@clack/prompts": "^1.0.0",
|
||||||
"@getpaseo/client": "0.2.1",
|
"@getpaseo/client": "0.2.2",
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/server": "0.2.1",
|
"@getpaseo/server": "0.2.2",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
@@ -36487,10 +36487,10 @@
|
|||||||
},
|
},
|
||||||
"packages/client": {
|
"packages/client": {
|
||||||
"name": "@getpaseo/client",
|
"name": "@getpaseo/client",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/relay": "0.2.1",
|
"@getpaseo/relay": "0.2.2",
|
||||||
"zod": "^4.4.3"
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -36501,7 +36501,7 @@
|
|||||||
},
|
},
|
||||||
"packages/desktop": {
|
"packages/desktop": {
|
||||||
"name": "@getpaseo/desktop",
|
"name": "@getpaseo/desktop",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/cli": "*",
|
"@getpaseo/cli": "*",
|
||||||
@@ -36744,7 +36744,7 @@
|
|||||||
},
|
},
|
||||||
"packages/expo-two-way-audio": {
|
"packages/expo-two-way-audio": {
|
||||||
"name": "@getpaseo/expo-two-way-audio",
|
"name": "@getpaseo/expo-two-way-audio",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
@@ -37640,7 +37640,7 @@
|
|||||||
},
|
},
|
||||||
"packages/highlight": {
|
"packages/highlight": {
|
||||||
"name": "@getpaseo/highlight",
|
"name": "@getpaseo/highlight",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "6.12.4",
|
"@codemirror/language": "6.12.4",
|
||||||
"@codemirror/legacy-modes": "^6.5.3",
|
"@codemirror/legacy-modes": "^6.5.3",
|
||||||
@@ -37872,7 +37872,7 @@
|
|||||||
},
|
},
|
||||||
"packages/protocol": {
|
"packages/protocol": {
|
||||||
"name": "@getpaseo/protocol",
|
"name": "@getpaseo/protocol",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zod": "^4.4.3"
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
@@ -37885,7 +37885,7 @@
|
|||||||
},
|
},
|
||||||
"packages/relay": {
|
"packages/relay": {
|
||||||
"name": "@getpaseo/relay",
|
"name": "@getpaseo/relay",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
@@ -38103,15 +38103,15 @@
|
|||||||
},
|
},
|
||||||
"packages/server": {
|
"packages/server": {
|
||||||
"name": "@getpaseo/server",
|
"name": "@getpaseo/server",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@agentclientprotocol/sdk": "^0.17.1",
|
"@agentclientprotocol/sdk": "^0.17.1",
|
||||||
"@anthropic-ai/claude-agent-sdk": "^0.3.214",
|
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
|
||||||
"@anthropic-ai/sdk": "^0.104.2",
|
"@anthropic-ai/sdk": "^0.104.2",
|
||||||
"@getpaseo/client": "0.2.1",
|
"@getpaseo/client": "0.2.2",
|
||||||
"@getpaseo/highlight": "0.2.1",
|
"@getpaseo/highlight": "0.2.2",
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/relay": "0.2.1",
|
"@getpaseo/relay": "0.2.2",
|
||||||
"@isaacs/ttlcache": "^2.1.4",
|
"@isaacs/ttlcache": "^2.1.4",
|
||||||
"@modelcontextprotocol/sdk": "^1.20.1",
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
||||||
"@opencode-ai/sdk": "1.14.46",
|
"@opencode-ai/sdk": "1.14.46",
|
||||||
@@ -38155,22 +38155,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.220.tgz",
|
||||||
"integrity": "sha512-wt5ImwhU+p259Zt4K/Q9v5xVi6ruxYO5+KFICyJxnjs/QFEClAeSRqhcXx1J8jgGfatPW1faw09hkm66680UjA==",
|
"integrity": "sha512-glc7SdwPkOkLw8oxwLo9PKTdLJGqW/PIR4urWXFoRtX9YllwozsEVc5Tc1+EvLSkfrsxPJqQWqOgpjUOQXf1oA==",
|
||||||
"license": "SEE LICENSE IN README.md",
|
"license": "SEE LICENSE IN README.md",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-darwin-arm64": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-darwin-x64": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-linux-arm64": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-linux-x64": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-linux-x64-musl": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.214",
|
"@anthropic-ai/claude-agent-sdk-win32-arm64": "0.3.220",
|
||||||
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.214"
|
"@anthropic-ai/claude-agent-sdk-win32-x64": "0.3.220"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@anthropic-ai/sdk": ">=0.93.0",
|
"@anthropic-ai/sdk": ">=0.93.0",
|
||||||
@@ -38179,9 +38179,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-darwin-arm64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.220.tgz",
|
||||||
"integrity": "sha512-vAAOeVtlXs3p7MpFVfvfu9ja32eaKtB+MDZnPxCbdzxJk5nofCHlNsHa1UJwXHOsP9lOnFYNIccYztsZ4DNaJA==",
|
"integrity": "sha512-7VxlbEosK7DODiOnsjoVd0DSJzbnaPrM2jelMHI0y8zx1UnLS3WC6EFUXbvy74F2sXqEznh2tzn7EKWInaRN6Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -38192,9 +38192,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-darwin-x64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.220.tgz",
|
||||||
"integrity": "sha512-NTbV8U2yucxCWqEiDC7L0MUehNmd8x3Op8OGzLZRhMF3xmQBy2DxpXiNZgSwwKWNDC3HdgKmJM5ZBbT7XrF/0g==",
|
"integrity": "sha512-X9RwDsSmbF6ultKZroaip+DL8WRgC64gHbrAwrRlAFSPNZV7zmJyP2ur8rW7KrxqmtuehdMMkw8+SAC/6hD2PA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -38205,9 +38205,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.220.tgz",
|
||||||
"integrity": "sha512-KBCf+BlusG0ZcgvpjjHwv1kh+6WiR8vJbPjpR2udwkrtcQgKLN+24l+FeaQEzO2TL+ExCmM1KC4tNPvnPpy+tw==",
|
"integrity": "sha512-WkROPwWskqhKR9XgnmseHQ6rLi9zM9qt57IWoToIjL/eXOqDWipp7JXZ1L5ud+LrA42dunHPZfBwD/vXZ+A7LA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -38218,9 +38218,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-arm64-musl": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64-musl/-/claude-agent-sdk-linux-arm64-musl-0.3.220.tgz",
|
||||||
"integrity": "sha512-i06wQRsmevE7spY1ryYfs+NP+xdZ1FwAyTjDaF0k/xG+cgtzZYghTFUemdYF3GVwgWgpcava9GiCFDT3DoHI6w==",
|
"integrity": "sha512-OHoZOZ8Cf2TBr6oXIXPwyvUxj9jrq2w8E4poA8dMpacXszcPSPiCQCMuuOh4aWJzfeJE1+TtWxhKMVb2csXyZQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -38231,9 +38231,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.220.tgz",
|
||||||
"integrity": "sha512-vqadSceJkBKHaTUszxI35uTuECGWtsHWK/mOwIJ4b9DUtYYySz6EJEk4gHg4ccutisJ/oRVCpFXHIKFb+osrKw==",
|
"integrity": "sha512-tkTJFnpR9VifvWX2fmkCAPkT6+8Wk/gVu8B5jsVekKZPiZoWRHmMXO30BnZn+f0TZhgYP+82PSX3S8crH1kn+w==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -38244,9 +38244,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-linux-x64-musl": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64-musl/-/claude-agent-sdk-linux-x64-musl-0.3.220.tgz",
|
||||||
"integrity": "sha512-948RstHDhs0E69h+2dKYWIAL1kcwEme4zvtgNUwP8XpKXzWOhrTKmd6MAokHn25zwfuSx5d+HE0XHfFH6R4hLg==",
|
"integrity": "sha512-K+FWj+LcGhC1Z7wqeWoLxm1iemcba5xKpLLFVwYm4V6HyMx3ruYd/2r2TiQtjT+JWeNFWIys0ScHiItR6vWAiA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -38257,9 +38257,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-win32-arm64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-arm64/-/claude-agent-sdk-win32-arm64-0.3.220.tgz",
|
||||||
"integrity": "sha512-CEKlPFCPv+ee79utQMEDSsgeo2f27ulhNHpjrKIt1jXz5G04J7lAWN/QwvPDv9XaLBkWpyfqZWiPXlRcwuaO/w==",
|
"integrity": "sha512-rIwgq0UwQExWl6KrHUyC4w5KwpL9l6nd95aUTx6RitexaAuEw//xtfTVLnuE4hDDQZFkzEwpdKc3nxDWoGcUbA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -38270,9 +38270,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": {
|
"packages/server/node_modules/@anthropic-ai/claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-win32-x64": {
|
||||||
"version": "0.3.214",
|
"version": "0.3.220",
|
||||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.214.tgz",
|
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-win32-x64/-/claude-agent-sdk-win32-x64-0.3.220.tgz",
|
||||||
"integrity": "sha512-cJMJfFoR9IWBZWnTtt9PnEm89hGOsZjoDNjOCEOF3+x+g/ANIXAjMJTcaQYv2HKh6MylWZ0AkxBASI+twkukaQ==",
|
"integrity": "sha512-MuOuXhbr66HlGaWXD2f3w0k2PsvmnbkwcUZ0dAe2poFLdl72GC2dapwwOBefxm9QmoNqk9+jmv/dSKGOVWyvLw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -38648,7 +38648,7 @@
|
|||||||
},
|
},
|
||||||
"packages/website": {
|
"packages/website": {
|
||||||
"name": "@getpaseo/website",
|
"name": "@getpaseo/website",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cloudflare/vite-plugin": "^1.29.1",
|
"@cloudflare/vite-plugin": "^1.29.1",
|
||||||
"@cloudflare/workers-types": "^4.20260317.1",
|
"@cloudflare/workers-types": "^4.20260317.1",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "paseo",
|
"name": "paseo",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Paseo: voice-controlled development environment for local AI coding agents",
|
"description": "Paseo: voice-controlled development environment for local AI coding agents",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/app",
|
"name": "@getpaseo/app",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/cli",
|
"name": "@getpaseo/cli",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Paseo CLI - control your AI coding agents from the command line",
|
"description": "Paseo CLI - control your AI coding agents from the command line",
|
||||||
"bin": {
|
"bin": {
|
||||||
"paseo": "bin/paseo"
|
"paseo": "bin/paseo"
|
||||||
@@ -27,9 +27,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "^1.0.0",
|
"@clack/prompts": "^1.0.0",
|
||||||
"@getpaseo/client": "0.2.1",
|
"@getpaseo/client": "0.2.2",
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/server": "0.2.1",
|
"@getpaseo/server": "0.2.2",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
|
|||||||
@@ -102,6 +102,38 @@ const EXPECTED_CLAUDE_MODELS = [
|
|||||||
},
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
const EXPECTED_CLAUDE_CONTEXT_MODELS = [
|
||||||
|
{
|
||||||
|
id: "claude-opus-5[1m]",
|
||||||
|
model: "Opus 5 1M",
|
||||||
|
descriptionFragment: "1M context window",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "claude-opus-5",
|
||||||
|
model: "Opus 5",
|
||||||
|
descriptionFragment: "200K context window",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "claude-fable-5[1m]",
|
||||||
|
model: "Fable 5 1M",
|
||||||
|
descriptionFragment: "1M context window",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "claude-sonnet-5[1m]",
|
||||||
|
model: "Sonnet 5 1M",
|
||||||
|
descriptionFragment: "1M context window",
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const EXPECTED_CLAUDE_CATALOG_MODELS = [
|
||||||
|
...new Map(
|
||||||
|
[...EXPECTED_CLAUDE_MODELS, ...EXPECTED_CLAUDE_CONTEXT_MODELS].map((model) => [
|
||||||
|
model.id,
|
||||||
|
model,
|
||||||
|
]),
|
||||||
|
).values(),
|
||||||
|
];
|
||||||
|
|
||||||
let claudeModelIdsFromJson: string[] = [];
|
let claudeModelIdsFromJson: string[] = [];
|
||||||
let claudeModelsFromJson: ProviderModel[] = [];
|
let claudeModelsFromJson: ProviderModel[] = [];
|
||||||
|
|
||||||
@@ -134,18 +166,18 @@ async function runProviderModelsJson(provider: string): Promise<ProviderModel[]>
|
|||||||
function assertClaudeModels(data: ProviderModel[]): void {
|
function assertClaudeModels(data: ProviderModel[]): void {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
data.length,
|
data.length,
|
||||||
EXPECTED_CLAUDE_MODELS.length,
|
EXPECTED_CLAUDE_CATALOG_MODELS.length,
|
||||||
"claude output should match the current catalog size",
|
"claude output should match the current catalog size",
|
||||||
);
|
);
|
||||||
|
|
||||||
const byId = new Map(data.map((model) => [model.id, model]));
|
const byId = new Map(data.map((model) => [model.id, model]));
|
||||||
const ids = [...byId.keys()].sort();
|
const ids = [...byId.keys()].sort();
|
||||||
const expectedIds = EXPECTED_CLAUDE_MODELS.map((model) => model.id).sort();
|
const expectedIds = EXPECTED_CLAUDE_CATALOG_MODELS.map((model) => model.id).sort();
|
||||||
|
|
||||||
assert.strictEqual(byId.size, data.length, "claude model IDs should be unique");
|
assert.strictEqual(byId.size, data.length, "claude model IDs should be unique");
|
||||||
assert.deepStrictEqual(ids, expectedIds, "claude IDs should match the current catalog");
|
assert.deepStrictEqual(ids, expectedIds, "claude IDs should match the current catalog");
|
||||||
|
|
||||||
for (const expectedModel of EXPECTED_CLAUDE_MODELS) {
|
for (const expectedModel of EXPECTED_CLAUDE_CATALOG_MODELS) {
|
||||||
const actualModel = byId.get(expectedModel.id);
|
const actualModel = byId.get(expectedModel.id);
|
||||||
assert(actualModel, `claude output should include ${expectedModel.id}`);
|
assert(actualModel, `claude output should include ${expectedModel.id}`);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
@@ -383,7 +415,7 @@ try {
|
|||||||
const lines = result.stdout.trim().split("\n").filter(Boolean);
|
const lines = result.stdout.trim().split("\n").filter(Boolean);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
lines.length,
|
lines.length,
|
||||||
EXPECTED_CLAUDE_MODELS.length,
|
EXPECTED_CLAUDE_CATALOG_MODELS.length,
|
||||||
"should have one line per Claude catalog model",
|
"should have one line per Claude catalog model",
|
||||||
);
|
);
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
@@ -393,7 +425,7 @@ try {
|
|||||||
);
|
);
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
[...lines].sort(),
|
[...lines].sort(),
|
||||||
EXPECTED_CLAUDE_MODELS.map((model) => model.id).sort(),
|
EXPECTED_CLAUDE_CATALOG_MODELS.map((model) => model.id).sort(),
|
||||||
"--quiet should print the current Claude catalog IDs",
|
"--quiet should print the current Claude catalog IDs",
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/client",
|
"name": "@getpaseo/client",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Paseo client SDK package",
|
"description": "Paseo client SDK package",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
"test": "vitest run"
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/relay": "0.2.1",
|
"@getpaseo/relay": "0.2.2",
|
||||||
"zod": "^4.4.3"
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/desktop",
|
"name": "@getpaseo/desktop",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Paseo desktop app (Electron wrapper)",
|
"description": "Paseo desktop app (Electron wrapper)",
|
||||||
"homepage": "https://paseo.sh",
|
"homepage": "https://paseo.sh",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/expo-two-way-audio",
|
"name": "@getpaseo/expo-two-way-audio",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Native module for two way audio streaming",
|
"description": "Native module for two way audio streaming",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ExpoTwoWayAudio",
|
"ExpoTwoWayAudio",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/highlight",
|
"name": "@getpaseo/highlight",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"!dist/**/*.map"
|
"!dist/**/*.map"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/protocol",
|
"name": "@getpaseo/protocol",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Paseo shared protocol schemas and wire types",
|
"description": "Paseo shared protocol schemas and wire types",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/relay",
|
"name": "@getpaseo/relay",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Paseo relay for bridging daemon and client connections",
|
"description": "Paseo relay for bridging daemon and client connections",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/server",
|
"name": "@getpaseo/server",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "Paseo backend server",
|
"description": "Paseo backend server",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/server",
|
"dist/server",
|
||||||
@@ -65,12 +65,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@agentclientprotocol/sdk": "^0.17.1",
|
"@agentclientprotocol/sdk": "^0.17.1",
|
||||||
"@anthropic-ai/claude-agent-sdk": "^0.3.214",
|
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
|
||||||
"@anthropic-ai/sdk": "^0.104.2",
|
"@anthropic-ai/sdk": "^0.104.2",
|
||||||
"@getpaseo/client": "0.2.1",
|
"@getpaseo/client": "0.2.2",
|
||||||
"@getpaseo/highlight": "0.2.1",
|
"@getpaseo/highlight": "0.2.2",
|
||||||
"@getpaseo/protocol": "0.2.1",
|
"@getpaseo/protocol": "0.2.2",
|
||||||
"@getpaseo/relay": "0.2.1",
|
"@getpaseo/relay": "0.2.2",
|
||||||
"@isaacs/ttlcache": "^2.1.4",
|
"@isaacs/ttlcache": "^2.1.4",
|
||||||
"@modelcontextprotocol/sdk": "^1.20.1",
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
||||||
"@opencode-ai/sdk": "1.14.46",
|
"@opencode-ai/sdk": "1.14.46",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
convertClaudeHistoryEntry,
|
convertClaudeHistoryEntry,
|
||||||
normalizeClaudeAskUserQuestionRequestInput,
|
normalizeClaudeAskUserQuestionRequestInput,
|
||||||
normalizeClaudeAskUserQuestionUpdatedInput,
|
normalizeClaudeAskUserQuestionUpdatedInput,
|
||||||
|
resolveClaudeCodeVersion,
|
||||||
toClaudeSdkMcpConfig,
|
toClaudeSdkMcpConfig,
|
||||||
} from "./agent.js";
|
} from "./agent.js";
|
||||||
import { claudeProjectDirSync } from "./project-dir.js";
|
import { claudeProjectDirSync } from "./project-dir.js";
|
||||||
@@ -405,6 +406,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
const client = new ClaudeAgentClient({
|
const client = new ClaudeAgentClient({
|
||||||
logger,
|
logger,
|
||||||
resolveBinary: async () => "/test/claude/bin",
|
resolveBinary: async () => "/test/claude/bin",
|
||||||
|
resolveVersion: async () => "2.1.219",
|
||||||
configDir: emptyConfigDir,
|
configDir: emptyConfigDir,
|
||||||
});
|
});
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
@@ -414,11 +416,14 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(models.map((m) => m.id)).toEqual([
|
expect(models.map((m) => m.id)).toEqual([
|
||||||
|
"claude-opus-5[1m]",
|
||||||
"claude-opus-5",
|
"claude-opus-5",
|
||||||
|
"claude-fable-5[1m]",
|
||||||
"claude-fable-5",
|
"claude-fable-5",
|
||||||
"claude-opus-4-8[1m]",
|
"claude-opus-4-8[1m]",
|
||||||
"claude-opus-4-8",
|
"claude-opus-4-8",
|
||||||
"claude-sonnet-5",
|
"claude-sonnet-5",
|
||||||
|
"claude-sonnet-5[1m]",
|
||||||
"claude-opus-4-7[1m]",
|
"claude-opus-4-7[1m]",
|
||||||
"claude-opus-4-7",
|
"claude-opus-4-7",
|
||||||
"claude-opus-4-6[1m]",
|
"claude-opus-4-6[1m]",
|
||||||
@@ -434,7 +439,30 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultModel = models.find((m) => m.isDefault);
|
const defaultModel = models.find((m) => m.isDefault);
|
||||||
expect(defaultModel?.id).toBe("claude-opus-5");
|
expect(defaultModel?.id).toBe("claude-opus-5[1m]");
|
||||||
|
} finally {
|
||||||
|
await fs.rm(emptyConfigDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("preserves the catalog when Claude Code version detection fails", async () => {
|
||||||
|
const emptyConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), "paseo-claude-models-empty-"));
|
||||||
|
try {
|
||||||
|
const client = new ClaudeAgentClient({
|
||||||
|
logger,
|
||||||
|
resolveVersion: async () => {
|
||||||
|
throw new Error("unrecognized version output");
|
||||||
|
},
|
||||||
|
configDir: emptyConfigDir,
|
||||||
|
});
|
||||||
|
const { models } = await client.fetchCatalog({
|
||||||
|
scope: "workspace",
|
||||||
|
cwd: "/tmp/claude-models",
|
||||||
|
force: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(models.find((model) => model.isDefault)?.id).toBe("claude-opus-5[1m]");
|
||||||
|
expect(models.map((model) => model.id)).toContain("claude-fable-5[1m]");
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(emptyConfigDir, { recursive: true, force: true });
|
await fs.rm(emptyConfigDir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
@@ -446,6 +474,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
const client = new ClaudeAgentClient({
|
const client = new ClaudeAgentClient({
|
||||||
logger,
|
logger,
|
||||||
resolveBinary: async () => "/test/claude/bin",
|
resolveBinary: async () => "/test/claude/bin",
|
||||||
|
resolveVersion: async () => "2.1.219",
|
||||||
configDir: emptyConfigDir,
|
configDir: emptyConfigDir,
|
||||||
});
|
});
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
@@ -475,6 +504,10 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
describe("ClaudeAgentClient binary resolution", () => {
|
describe("ClaudeAgentClient binary resolution", () => {
|
||||||
const logger = createTestLogger();
|
const logger = createTestLogger();
|
||||||
|
|
||||||
|
test("resolves the installed Claude Code version", async () => {
|
||||||
|
await expect(resolveClaudeCodeVersion()).resolves.toMatch(/^\d+\.\d+\.\d+$/);
|
||||||
|
});
|
||||||
|
|
||||||
test("loads user, project, and local Claude settings", async () => {
|
test("loads user, project, and local Claude settings", async () => {
|
||||||
const queryReturn = vi.fn();
|
const queryReturn = vi.fn();
|
||||||
queryReturn.mockResolvedValue(undefined);
|
queryReturn.mockResolvedValue(undefined);
|
||||||
@@ -2083,10 +2116,10 @@ describe("ClaudeAgentSession context window usage", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test("native 1M Claude models seed active context window usage from the catalog", async () => {
|
test("selected 1M Claude models seed active context window usage from the catalog", async () => {
|
||||||
const session = await createSessionForTurns(
|
const session = await createSessionForTurns(
|
||||||
[[createInitMessage(), createMessageStartEvent(), createSuccessResult()]],
|
[[createInitMessage(), createMessageStartEvent(), createSuccessResult()]],
|
||||||
{ model: "claude-sonnet-5" },
|
{ model: "claude-sonnet-5[1m]" },
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
||||||
CLAUDE_ULTRACODE_THINKING_OPTION_ID,
|
CLAUDE_ULTRACODE_THINKING_OPTION_ID,
|
||||||
|
parseClaudeCodeVersion,
|
||||||
resolveClaudeDisabledThinkingForModel,
|
resolveClaudeDisabledThinkingForModel,
|
||||||
} from "./model-manifest.js";
|
} from "./model-manifest.js";
|
||||||
import { parsePartialJsonObject } from "./partial-json.js";
|
import { parsePartialJsonObject } from "./partial-json.js";
|
||||||
@@ -363,6 +364,7 @@ interface ClaudeAgentClientOptions {
|
|||||||
runtimeSettings?: ProviderRuntimeSettings;
|
runtimeSettings?: ProviderRuntimeSettings;
|
||||||
queryFactory?: ClaudeQueryFactory;
|
queryFactory?: ClaudeQueryFactory;
|
||||||
resolveBinary?: () => Promise<string>;
|
resolveBinary?: () => Promise<string>;
|
||||||
|
resolveVersion?: () => Promise<string>;
|
||||||
configDir?: string;
|
configDir?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1439,6 +1441,7 @@ export class ClaudeAgentClient implements AgentClient {
|
|||||||
private readonly runtimeSettings?: ProviderRuntimeSettings;
|
private readonly runtimeSettings?: ProviderRuntimeSettings;
|
||||||
private readonly queryFactory?: ClaudeQueryFactory;
|
private readonly queryFactory?: ClaudeQueryFactory;
|
||||||
private readonly resolveBinary: () => Promise<string>;
|
private readonly resolveBinary: () => Promise<string>;
|
||||||
|
private readonly resolveVersion: () => Promise<string>;
|
||||||
private readonly configDir?: string;
|
private readonly configDir?: string;
|
||||||
|
|
||||||
constructor(options: ClaudeAgentClientOptions) {
|
constructor(options: ClaudeAgentClientOptions) {
|
||||||
@@ -1447,6 +1450,8 @@ export class ClaudeAgentClient implements AgentClient {
|
|||||||
this.runtimeSettings = options.runtimeSettings;
|
this.runtimeSettings = options.runtimeSettings;
|
||||||
this.queryFactory = options.queryFactory;
|
this.queryFactory = options.queryFactory;
|
||||||
this.resolveBinary = options.resolveBinary ?? (() => resolveClaudeBinary(this.runtimeSettings));
|
this.resolveBinary = options.resolveBinary ?? (() => resolveClaudeBinary(this.runtimeSettings));
|
||||||
|
this.resolveVersion =
|
||||||
|
options.resolveVersion ?? (() => resolveClaudeCodeVersion(this.runtimeSettings));
|
||||||
this.configDir = options.configDir;
|
this.configDir = options.configDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1498,7 +1503,17 @@ export class ClaudeAgentClient implements AgentClient {
|
|||||||
|
|
||||||
async fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog> {
|
async fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog> {
|
||||||
// Claude exposes a global catalog here; cwd/force are intentionally irrelevant.
|
// Claude exposes a global catalog here; cwd/force are intentionally irrelevant.
|
||||||
const models = await getClaudeModelsWithSettings(this.logger, this.configDir);
|
let claudeCodeVersion: string | undefined;
|
||||||
|
try {
|
||||||
|
claudeCodeVersion = await this.resolveVersion();
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.warn({ err: error }, "Failed to resolve Claude Code version for model catalog");
|
||||||
|
}
|
||||||
|
const models = await getClaudeModelsWithSettings(
|
||||||
|
this.logger,
|
||||||
|
this.configDir,
|
||||||
|
claudeCodeVersion,
|
||||||
|
);
|
||||||
const modes = detectIneligibleAutoModeTransport(
|
const modes = detectIneligibleAutoModeTransport(
|
||||||
createProviderEnv({ baseEnv: process.env, runtimeSettings: this.runtimeSettings }),
|
createProviderEnv({ baseEnv: process.env, runtimeSettings: this.runtimeSettings }),
|
||||||
)
|
)
|
||||||
@@ -1620,6 +1635,29 @@ async function resolveClaudeBinary(runtimeSettings?: ProviderRuntimeSettings): P
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function resolveClaudeCodeVersion(
|
||||||
|
runtimeSettings?: ProviderRuntimeSettings,
|
||||||
|
): Promise<string> {
|
||||||
|
const launch = await resolveProviderLaunch({
|
||||||
|
commandConfig: runtimeSettings?.command,
|
||||||
|
defaultBinary: "claude",
|
||||||
|
});
|
||||||
|
const availability = await checkProviderLaunchAvailable(launch);
|
||||||
|
if (!availability.available) {
|
||||||
|
throw new Error("Claude binary not found while resolving Claude Code version");
|
||||||
|
}
|
||||||
|
const executable = availability.resolvedPath ?? launch.command;
|
||||||
|
const { stdout, stderr } = await execCommand(executable, [...launch.args, "--version"], {
|
||||||
|
...createProviderEnvSpec({ runtimeSettings }),
|
||||||
|
timeout: 5_000,
|
||||||
|
});
|
||||||
|
const version = parseClaudeCodeVersion(`${stdout}\n${stderr}`);
|
||||||
|
if (!version) {
|
||||||
|
throw new Error("Unable to parse Claude Code version from --version output");
|
||||||
|
}
|
||||||
|
return version.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
async function resolveClaudeAuth(
|
async function resolveClaudeAuth(
|
||||||
launch: ResolvedProviderLaunch,
|
launch: ResolvedProviderLaunch,
|
||||||
availability: { resolvedPath: string | null },
|
availability: { resolvedPath: string | null },
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ interface ClaudeModelManifestEntry {
|
|||||||
id: string;
|
id: string;
|
||||||
label: string;
|
label: string;
|
||||||
description: string;
|
description: string;
|
||||||
isDefault?: boolean;
|
defaultPriority?: number;
|
||||||
|
minimumClaudeCodeVersion?: string;
|
||||||
contextWindowMaxTokens?: number;
|
contextWindowMaxTokens?: number;
|
||||||
effortLevels?: readonly ClaudeEffortLevel[];
|
effortLevels?: readonly ClaudeEffortLevel[];
|
||||||
supportsThinkingDisabled?: boolean;
|
supportsThinkingDisabled?: boolean;
|
||||||
@@ -31,19 +32,38 @@ export const CLAUDE_ULTRACODE_THINKING_OPTION_ID = "ultracode";
|
|||||||
|
|
||||||
export const CLAUDE_MODEL_MANIFEST = [
|
export const CLAUDE_MODEL_MANIFEST = [
|
||||||
{
|
{
|
||||||
id: "claude-opus-5",
|
id: "claude-opus-5[1m]",
|
||||||
label: "Opus 5",
|
label: "Opus 5 1M",
|
||||||
description: "Opus 5 · Latest release",
|
description: "Opus 5 with 1M context window",
|
||||||
isDefault: true,
|
defaultPriority: 2,
|
||||||
|
minimumClaudeCodeVersion: "2.1.219",
|
||||||
contextWindowMaxTokens: 1_000_000,
|
contextWindowMaxTokens: 1_000_000,
|
||||||
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
supportsThinkingDisabled: true,
|
supportsThinkingDisabled: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "claude-opus-5",
|
||||||
|
label: "Opus 5",
|
||||||
|
description: "Opus 5 · 200K context window",
|
||||||
|
minimumClaudeCodeVersion: "2.1.219",
|
||||||
|
contextWindowMaxTokens: 200_000,
|
||||||
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
|
supportsThinkingDisabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "claude-fable-5[1m]",
|
||||||
|
label: "Fable 5 1M",
|
||||||
|
description: "Fable 5 with 1M context window",
|
||||||
|
minimumClaudeCodeVersion: "2.1.169",
|
||||||
|
contextWindowMaxTokens: 1_000_000,
|
||||||
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "claude-fable-5",
|
id: "claude-fable-5",
|
||||||
label: "Fable 5",
|
label: "Fable 5",
|
||||||
description: "Fable 5 · Most powerful model",
|
description: "Fable 5 · Most powerful model",
|
||||||
contextWindowMaxTokens: 1_000_000,
|
minimumClaudeCodeVersion: "2.1.169",
|
||||||
|
contextWindowMaxTokens: 200_000,
|
||||||
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -59,6 +79,7 @@ export const CLAUDE_MODEL_MANIFEST = [
|
|||||||
id: "claude-opus-4-8",
|
id: "claude-opus-4-8",
|
||||||
label: "Opus 4.8",
|
label: "Opus 4.8",
|
||||||
description: "Opus 4.8 · Previous release",
|
description: "Opus 4.8 · Previous release",
|
||||||
|
defaultPriority: 1,
|
||||||
contextWindowMaxTokens: 200_000,
|
contextWindowMaxTokens: 200_000,
|
||||||
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
supportsThinkingDisabled: true,
|
supportsThinkingDisabled: true,
|
||||||
@@ -68,6 +89,14 @@ export const CLAUDE_MODEL_MANIFEST = [
|
|||||||
id: "claude-sonnet-5",
|
id: "claude-sonnet-5",
|
||||||
label: "Sonnet 5",
|
label: "Sonnet 5",
|
||||||
description: "Sonnet 5 · Best for everyday tasks",
|
description: "Sonnet 5 · Best for everyday tasks",
|
||||||
|
contextWindowMaxTokens: 200_000,
|
||||||
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
|
supportsThinkingDisabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "claude-sonnet-5[1m]",
|
||||||
|
label: "Sonnet 5 1M",
|
||||||
|
description: "Sonnet 5 with 1M context window",
|
||||||
contextWindowMaxTokens: 1_000_000,
|
contextWindowMaxTokens: 1_000_000,
|
||||||
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
effortLevels: CLAUDE_EFFORT_LEVELS.xhigh,
|
||||||
supportsThinkingDisabled: true,
|
supportsThinkingDisabled: true,
|
||||||
@@ -155,31 +184,73 @@ function buildThinkingOptions(
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getClaudeManifestModels(): AgentModelDefinition[] {
|
export function getClaudeManifestModels(claudeCodeVersion?: string): AgentModelDefinition[] {
|
||||||
return CLAUDE_MODEL_MANIFEST.map((model) => {
|
const availableModels: readonly ClaudeModelManifestEntry[] = CLAUDE_MODEL_MANIFEST.filter(
|
||||||
|
(model) => isModelAvailableInClaudeCode(model, claudeCodeVersion),
|
||||||
|
);
|
||||||
|
const defaultModel = availableModels.reduce<ClaudeModelManifestEntry | undefined>(
|
||||||
|
(selected, candidate) =>
|
||||||
|
(candidate.defaultPriority ?? 0) > (selected?.defaultPriority ?? 0) ? candidate : selected,
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
|
||||||
|
return availableModels.map((model) => {
|
||||||
const thinkingOptions = buildThinkingOptions(
|
const thinkingOptions = buildThinkingOptions(
|
||||||
"effortLevels" in model ? model.effortLevels : undefined,
|
model.effortLevels,
|
||||||
"supportsThinkingDisabled" in model && model.supportsThinkingDisabled,
|
model.supportsThinkingDisabled === true,
|
||||||
);
|
);
|
||||||
return {
|
const definition: AgentModelDefinition = {
|
||||||
provider: "claude",
|
provider: "claude",
|
||||||
id: model.id,
|
id: model.id,
|
||||||
label: model.label,
|
label: model.label,
|
||||||
description: model.description,
|
description: model.description,
|
||||||
...("isDefault" in model && model.isDefault ? { isDefault: true } : {}),
|
|
||||||
...(model.contextWindowMaxTokens !== undefined
|
|
||||||
? { contextWindowMaxTokens: model.contextWindowMaxTokens }
|
|
||||||
: {}),
|
|
||||||
...(thinkingOptions
|
|
||||||
? {
|
|
||||||
thinkingOptions,
|
|
||||||
defaultThinkingOptionId: "effortLevels" in model ? model.effortLevels?.[0] : undefined,
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
};
|
};
|
||||||
|
if (model === defaultModel) {
|
||||||
|
definition.isDefault = true;
|
||||||
|
}
|
||||||
|
if (model.contextWindowMaxTokens !== undefined) {
|
||||||
|
definition.contextWindowMaxTokens = model.contextWindowMaxTokens;
|
||||||
|
}
|
||||||
|
if (thinkingOptions) {
|
||||||
|
definition.thinkingOptions = thinkingOptions;
|
||||||
|
definition.defaultThinkingOptionId = model.effortLevels?.[0];
|
||||||
|
}
|
||||||
|
return definition;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isModelAvailableInClaudeCode(
|
||||||
|
model: ClaudeModelManifestEntry,
|
||||||
|
claudeCodeVersion: string | undefined,
|
||||||
|
): boolean {
|
||||||
|
if (!model.minimumClaudeCodeVersion || claudeCodeVersion === undefined) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return compareVersions(claudeCodeVersion, model.minimumClaudeCodeVersion) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareVersions(left: string, right: string): number {
|
||||||
|
const leftParts = parseClaudeCodeVersion(left);
|
||||||
|
const rightParts = parseClaudeCodeVersion(right);
|
||||||
|
if (!leftParts || !rightParts) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (let index = 0; index < leftParts.length; index += 1) {
|
||||||
|
const difference = leftParts[index] - rightParts[index];
|
||||||
|
if (difference !== 0) {
|
||||||
|
return difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseClaudeCodeVersion(value: string): [number, number, number] | null {
|
||||||
|
const match =
|
||||||
|
value.match(/\b(\d+)\.(\d+)\.(\d+)\s+\(Claude Code\)/i) ??
|
||||||
|
value.match(/\b(\d+)\.(\d+)\.(\d+)\b/);
|
||||||
|
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ClaudeDisabledThinkingResolution {
|
export interface ClaudeDisabledThinkingResolution {
|
||||||
supported: boolean;
|
supported: boolean;
|
||||||
fallbackThinkingOptionId: string | undefined;
|
fallbackThinkingOptionId: string | undefined;
|
||||||
@@ -236,7 +307,7 @@ export function normalizeClaudeManifestModelId(value: string | null | undefined)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const singleSegmentMatch = trimmed.match(
|
const singleSegmentMatch = trimmed.match(
|
||||||
/^(?:claude[-_ ])?(fable|opus|sonnet|haiku)[-_ ]+(\d+)(\[1m\])?(?:[-_ ]+\d{8})?$/i,
|
/^(?:claude[-_ ])?(fable|opus|sonnet|haiku)[-_ ]+(\d+)(?:\[1m\])?(?:[-_ ]+\d{8})?(?:\[1m\])?$/i,
|
||||||
);
|
);
|
||||||
if (singleSegmentMatch) {
|
if (singleSegmentMatch) {
|
||||||
return normalizeSingleSegmentClaudeModelId(
|
return normalizeSingleSegmentClaudeModelId(
|
||||||
@@ -247,7 +318,7 @@ export function normalizeClaudeManifestModelId(value: string | null | undefined)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const runtimeMatch = trimmed.match(
|
const runtimeMatch = trimmed.match(
|
||||||
/^(?:claude[-_ ])?(opus|sonnet|haiku)[-_ ]+(\d+)[-.](\d+)(\[1m\])?(?:[-_ ]+\d{8})?$/i,
|
/^(?:claude[-_ ])?(opus|sonnet|haiku)[-_ ]+(\d+)[-.](\d+)(?:\[1m\])?(?:[-_ ]+\d{8})?(?:\[1m\])?$/i,
|
||||||
);
|
);
|
||||||
if (!runtimeMatch) {
|
if (!runtimeMatch) {
|
||||||
return null;
|
return null;
|
||||||
@@ -257,7 +328,7 @@ export function normalizeClaudeManifestModelId(value: string | null | undefined)
|
|||||||
runtimeMatch[1],
|
runtimeMatch[1],
|
||||||
runtimeMatch[2],
|
runtimeMatch[2],
|
||||||
runtimeMatch[3],
|
runtimeMatch[3],
|
||||||
Boolean(runtimeMatch[4]),
|
trimmed.toLowerCase().includes("[1m]"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +355,7 @@ export function normalizeClaudeRuntimeModelId(value: string | null | undefined):
|
|||||||
const normalizedModelId = normalizeSingleSegmentClaudeModelId(
|
const normalizedModelId = normalizeSingleSegmentClaudeModelId(
|
||||||
singleSegmentMatch[1],
|
singleSegmentMatch[1],
|
||||||
singleSegmentMatch[2],
|
singleSegmentMatch[2],
|
||||||
Boolean(singleSegmentMatch[3]),
|
trimmed.toLowerCase().includes("[1m]"),
|
||||||
);
|
);
|
||||||
if (normalizedModelId) {
|
if (normalizedModelId) {
|
||||||
return normalizedModelId;
|
return normalizedModelId;
|
||||||
@@ -302,7 +373,7 @@ export function normalizeClaudeRuntimeModelId(value: string | null | undefined):
|
|||||||
runtimeMatch[1],
|
runtimeMatch[1],
|
||||||
runtimeMatch[2],
|
runtimeMatch[2],
|
||||||
runtimeMatch[3],
|
runtimeMatch[3],
|
||||||
Boolean(runtimeMatch[4]),
|
trimmed.toLowerCase().includes("[1m]"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
CLAUDE_ULTRACODE_THINKING_OPTION_ID,
|
CLAUDE_ULTRACODE_THINKING_OPTION_ID,
|
||||||
claudeManifestModelSupportsFastMode,
|
claudeManifestModelSupportsFastMode,
|
||||||
normalizeClaudeManifestModelId,
|
normalizeClaudeManifestModelId,
|
||||||
|
parseClaudeCodeVersion,
|
||||||
resolveClaudeDisabledThinkingForModel,
|
resolveClaudeDisabledThinkingForModel,
|
||||||
} from "./model-manifest.js";
|
} from "./model-manifest.js";
|
||||||
import { findClaudeModel, getClaudeModels, normalizeClaudeRuntimeModelId } from "./models.js";
|
import { findClaudeModel, getClaudeModels, normalizeClaudeRuntimeModelId } from "./models.js";
|
||||||
@@ -38,15 +39,25 @@ async function createClaudeConfigDirWithRawSettings(settings: string): Promise<s
|
|||||||
return configDir;
|
return configDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createCatalogClient(claudeCodeVersion = "2.1.219"): ClaudeAgentClient {
|
||||||
|
return new ClaudeAgentClient({
|
||||||
|
logger: createTestLogger(),
|
||||||
|
resolveVersion: async () => claudeCodeVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("getClaudeModels", () => {
|
describe("getClaudeModels", () => {
|
||||||
it("returns all claude models", () => {
|
it("returns all claude models", () => {
|
||||||
const models = getClaudeModels();
|
const models = getClaudeModels();
|
||||||
expect(models.map((m) => m.id)).toEqual([
|
expect(models.map((m) => m.id)).toEqual([
|
||||||
|
"claude-opus-5[1m]",
|
||||||
"claude-opus-5",
|
"claude-opus-5",
|
||||||
|
"claude-fable-5[1m]",
|
||||||
"claude-fable-5",
|
"claude-fable-5",
|
||||||
"claude-opus-4-8[1m]",
|
"claude-opus-4-8[1m]",
|
||||||
"claude-opus-4-8",
|
"claude-opus-4-8",
|
||||||
"claude-sonnet-5",
|
"claude-sonnet-5",
|
||||||
|
"claude-sonnet-5[1m]",
|
||||||
"claude-opus-4-7[1m]",
|
"claude-opus-4-7[1m]",
|
||||||
"claude-opus-4-7",
|
"claude-opus-4-7",
|
||||||
"claude-opus-4-6[1m]",
|
"claude-opus-4-6[1m]",
|
||||||
@@ -61,7 +72,7 @@ describe("getClaudeModels", () => {
|
|||||||
const models = getClaudeModels();
|
const models = getClaudeModels();
|
||||||
const defaults = models.filter((m) => m.isDefault);
|
const defaults = models.filter((m) => m.isDefault);
|
||||||
expect(defaults).toHaveLength(1);
|
expect(defaults).toHaveLength(1);
|
||||||
expect(defaults[0].id).toBe("claude-opus-5");
|
expect(defaults[0].id).toBe("claude-opus-5[1m]");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("defines context window sizes in the catalog", () => {
|
it("defines context window sizes in the catalog", () => {
|
||||||
@@ -71,11 +82,14 @@ describe("getClaudeModels", () => {
|
|||||||
|
|
||||||
expect(contextWindows).toEqual(
|
expect(contextWindows).toEqual(
|
||||||
new Map([
|
new Map([
|
||||||
["claude-opus-5", 1_000_000],
|
["claude-opus-5[1m]", 1_000_000],
|
||||||
["claude-fable-5", 1_000_000],
|
["claude-opus-5", 200_000],
|
||||||
|
["claude-fable-5[1m]", 1_000_000],
|
||||||
|
["claude-fable-5", 200_000],
|
||||||
["claude-opus-4-8[1m]", 1_000_000],
|
["claude-opus-4-8[1m]", 1_000_000],
|
||||||
["claude-opus-4-8", 200_000],
|
["claude-opus-4-8", 200_000],
|
||||||
["claude-sonnet-5", 1_000_000],
|
["claude-sonnet-5", 200_000],
|
||||||
|
["claude-sonnet-5[1m]", 1_000_000],
|
||||||
["claude-opus-4-7[1m]", 1_000_000],
|
["claude-opus-4-7[1m]", 1_000_000],
|
||||||
["claude-opus-4-7", 200_000],
|
["claude-opus-4-7", 200_000],
|
||||||
["claude-opus-4-6[1m]", 1_000_000],
|
["claude-opus-4-6[1m]", 1_000_000],
|
||||||
@@ -87,6 +101,20 @@ describe("getClaudeModels", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("filters models by their minimum Claude Code version", () => {
|
||||||
|
const oldVersionModels = getClaudeModels("2.1.218");
|
||||||
|
expect(oldVersionModels.map((model) => model.id)).not.toContain("claude-opus-5[1m]");
|
||||||
|
expect(oldVersionModels.map((model) => model.id)).not.toContain("claude-opus-5");
|
||||||
|
expect(oldVersionModels.find((model) => model.isDefault)?.id).toBe("claude-opus-4-8");
|
||||||
|
expect(getClaudeModels("2.1.219").map((model) => model.id)).toContain("claude-opus-5[1m]");
|
||||||
|
expect(getClaudeModels("2.1.219").map((model) => model.id)).toContain("claude-opus-5");
|
||||||
|
|
||||||
|
expect(getClaudeModels("2.1.168").map((model) => model.id)).not.toContain("claude-fable-5[1m]");
|
||||||
|
expect(getClaudeModels("2.1.168").map((model) => model.id)).not.toContain("claude-fable-5");
|
||||||
|
expect(getClaudeModels("2.1.169").map((model) => model.id)).toContain("claude-fable-5[1m]");
|
||||||
|
expect(getClaudeModels("2.1.169").map((model) => model.id)).toContain("claude-fable-5");
|
||||||
|
});
|
||||||
|
|
||||||
it("derives thinking options from model effort capabilities", () => {
|
it("derives thinking options from model effort capabilities", () => {
|
||||||
const models = new Map(getClaudeModels().map((model) => [model.id, model]));
|
const models = new Map(getClaudeModels().map((model) => [model.id, model]));
|
||||||
|
|
||||||
@@ -115,6 +143,9 @@ describe("getClaudeModels", () => {
|
|||||||
?.label,
|
?.label,
|
||||||
).toBe("Ultra Code");
|
).toBe("Ultra Code");
|
||||||
expect(models.get("claude-sonnet-5")?.defaultThinkingOptionId).toBe("low");
|
expect(models.get("claude-sonnet-5")?.defaultThinkingOptionId).toBe("low");
|
||||||
|
expect(models.get("claude-sonnet-5[1m]")?.thinkingOptions).toEqual(
|
||||||
|
models.get("claude-sonnet-5")?.thinkingOptions,
|
||||||
|
);
|
||||||
|
|
||||||
expect(models.get("claude-opus-4-7")?.thinkingOptions?.map((option) => option.id)).toEqual([
|
expect(models.get("claude-opus-4-7")?.thinkingOptions?.map((option) => option.id)).toEqual([
|
||||||
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
||||||
@@ -135,6 +166,9 @@ describe("getClaudeModels", () => {
|
|||||||
expect(models.get("claude-fable-5")?.thinkingOptions?.map((option) => option.id)).not.toContain(
|
expect(models.get("claude-fable-5")?.thinkingOptions?.map((option) => option.id)).not.toContain(
|
||||||
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
CLAUDE_DISABLED_THINKING_OPTION_ID,
|
||||||
);
|
);
|
||||||
|
expect(models.get("claude-fable-5[1m]")?.thinkingOptions).toEqual(
|
||||||
|
models.get("claude-fable-5")?.thinkingOptions,
|
||||||
|
);
|
||||||
expect(models.get("claude-haiku-4-5")?.thinkingOptions).toBeUndefined();
|
expect(models.get("claude-haiku-4-5")?.thinkingOptions).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -142,6 +176,7 @@ describe("getClaudeModels", () => {
|
|||||||
["claude-opus-5", true, "low"],
|
["claude-opus-5", true, "low"],
|
||||||
["claude-opus-5-20260724", true, "low"],
|
["claude-opus-5-20260724", true, "low"],
|
||||||
["claude-sonnet-5", true, "low"],
|
["claude-sonnet-5", true, "low"],
|
||||||
|
["claude-sonnet-5[1m]", true, "low"],
|
||||||
["claude-sonnet-5-20260101", true, "low"],
|
["claude-sonnet-5-20260101", true, "low"],
|
||||||
["claude-fable-5", false, "low"],
|
["claude-fable-5", false, "low"],
|
||||||
["claude-haiku-4-5", false, undefined],
|
["claude-haiku-4-5", false, undefined],
|
||||||
@@ -175,7 +210,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
||||||
const client = new ClaudeAgentClient({ logger: createTestLogger() });
|
const client = createCatalogClient();
|
||||||
|
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
scope: "workspace",
|
scope: "workspace",
|
||||||
@@ -228,7 +263,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
const configDir = await fs.mkdtemp(path.join(os.tmpdir(), "paseo-claude-models-"));
|
const configDir = await fs.mkdtemp(path.join(os.tmpdir(), "paseo-claude-models-"));
|
||||||
createdClaudeConfigDirs.push(configDir);
|
createdClaudeConfigDirs.push(configDir);
|
||||||
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
||||||
const client = new ClaudeAgentClient({ logger: createTestLogger() });
|
const client = createCatalogClient();
|
||||||
|
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
scope: "workspace",
|
scope: "workspace",
|
||||||
@@ -242,7 +277,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
it("falls back to hardcoded models when settings.json is malformed", async () => {
|
it("falls back to hardcoded models when settings.json is malformed", async () => {
|
||||||
const configDir = await createClaudeConfigDirWithRawSettings("{ nope");
|
const configDir = await createClaudeConfigDirWithRawSettings("{ nope");
|
||||||
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
||||||
const client = new ClaudeAgentClient({ logger: createTestLogger() });
|
const client = createCatalogClient();
|
||||||
|
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
scope: "workspace",
|
scope: "workspace",
|
||||||
@@ -262,7 +297,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
||||||
const client = new ClaudeAgentClient({ logger: createTestLogger() });
|
const client = createCatalogClient();
|
||||||
|
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
scope: "workspace",
|
scope: "workspace",
|
||||||
@@ -282,7 +317,7 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
vi.stubEnv("CLAUDE_CONFIG_DIR", configDir);
|
||||||
const client = new ClaudeAgentClient({ logger: createTestLogger() });
|
const client = createCatalogClient();
|
||||||
|
|
||||||
const { models } = await client.fetchCatalog({
|
const { models } = await client.fetchCatalog({
|
||||||
scope: "workspace",
|
scope: "workspace",
|
||||||
@@ -295,13 +330,29 @@ describe("ClaudeAgentClient.fetchCatalog", () => {
|
|||||||
"glm-5.1",
|
"glm-5.1",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("omits models that require a newer Claude Code version", async () => {
|
||||||
|
const client = createCatalogClient("2.1.218");
|
||||||
|
|
||||||
|
const { models } = await client.fetchCatalog({
|
||||||
|
scope: "workspace",
|
||||||
|
cwd: os.tmpdir(),
|
||||||
|
force: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(models.map((model) => model.id)).not.toContain("claude-opus-5[1m]");
|
||||||
|
expect(models.map((model) => model.id)).not.toContain("claude-opus-5");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("normalizeClaudeRuntimeModelId", () => {
|
describe("normalizeClaudeRuntimeModelId", () => {
|
||||||
it("returns exact match for known model IDs", () => {
|
it("returns exact match for known model IDs", () => {
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-opus-5[1m]")).toBe("claude-opus-5[1m]");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-opus-5")).toBe("claude-opus-5");
|
expect(normalizeClaudeRuntimeModelId("claude-opus-5")).toBe("claude-opus-5");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-fable-5")).toBe("claude-fable-5");
|
expect(normalizeClaudeRuntimeModelId("claude-fable-5")).toBe("claude-fable-5");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-fable-5[1m]")).toBe("claude-fable-5[1m]");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-sonnet-5")).toBe("claude-sonnet-5");
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-5")).toBe("claude-sonnet-5");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-5[1m]")).toBe("claude-sonnet-5[1m]");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6")).toBe("claude-opus-4-6");
|
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6")).toBe("claude-opus-4-6");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6[1m]")).toBe("claude-opus-4-6[1m]");
|
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6[1m]")).toBe("claude-opus-4-6[1m]");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-sonnet-4-6")).toBe("claude-sonnet-4-6");
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-4-6")).toBe("claude-sonnet-4-6");
|
||||||
@@ -315,9 +366,17 @@ describe("normalizeClaudeRuntimeModelId", () => {
|
|||||||
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6-20260101")).toBe("claude-opus-4-6");
|
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6-20260101")).toBe("claude-opus-4-6");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-sonnet-4-6-20260101")).toBe("claude-sonnet-4-6");
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-4-6-20260101")).toBe("claude-sonnet-4-6");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-haiku-4-5-20251001")).toBe("claude-haiku-4-5");
|
expect(normalizeClaudeRuntimeModelId("claude-haiku-4-5-20251001")).toBe("claude-haiku-4-5");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-opus-5-20260724[1m]")).toBe("claude-opus-5[1m]");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-fable-5-20260301[1m]")).toBe("claude-fable-5[1m]");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-5-20260101[1m]")).toBe(
|
||||||
|
"claude-sonnet-5[1m]",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("preserves [1m] suffix from runtime model strings", () => {
|
it("preserves [1m] suffix from runtime model strings", () => {
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-opus-5[1m]")).toBe("claude-opus-5[1m]");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-fable-5[1m]")).toBe("claude-fable-5[1m]");
|
||||||
|
expect(normalizeClaudeRuntimeModelId("claude-sonnet-5[1m]")).toBe("claude-sonnet-5[1m]");
|
||||||
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6[1m]")).toBe("claude-opus-4-6[1m]");
|
expect(normalizeClaudeRuntimeModelId("claude-opus-4-6[1m]")).toBe("claude-opus-4-6[1m]");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -346,6 +405,12 @@ describe("normalizeClaudeRuntimeModelId", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("parseClaudeCodeVersion", () => {
|
||||||
|
it("prefers the Claude Code version over a wrapper banner", () => {
|
||||||
|
expect(parseClaudeCodeVersion("wrapper 1.0.0\n2.1.219 (Claude Code)")).toEqual([2, 1, 219]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("findClaudeModel", () => {
|
describe("findClaudeModel", () => {
|
||||||
it("resolves runtime model IDs to catalog entries", () => {
|
it("resolves runtime model IDs to catalog entries", () => {
|
||||||
expect(findClaudeModel("claude-sonnet-5-20260101")?.id).toBe("claude-sonnet-5");
|
expect(findClaudeModel("claude-sonnet-5-20260101")?.id).toBe("claude-sonnet-5");
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ const CLAUDE_SETTINGS_MODEL_ENV_KEYS = [
|
|||||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export function getClaudeModels(): AgentModelDefinition[] {
|
export function getClaudeModels(claudeCodeVersion?: string): AgentModelDefinition[] {
|
||||||
return getClaudeManifestModels();
|
return getClaudeManifestModels(claudeCodeVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findClaudeModel(
|
export function findClaudeModel(
|
||||||
@@ -34,8 +34,9 @@ export function findClaudeModel(
|
|||||||
export async function getClaudeModelsWithSettings(
|
export async function getClaudeModelsWithSettings(
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
configDir?: string,
|
configDir?: string,
|
||||||
|
claudeCodeVersion?: string,
|
||||||
): Promise<AgentModelDefinition[]> {
|
): Promise<AgentModelDefinition[]> {
|
||||||
const hardcodedModels = getClaudeModels();
|
const hardcodedModels = getClaudeModels(claudeCodeVersion);
|
||||||
const settingsModels = await readClaudeSettingsModels(logger, configDir);
|
const settingsModels = await readClaudeSettingsModels(logger, configDir);
|
||||||
if (settingsModels.length === 0) {
|
if (settingsModels.length === 0) {
|
||||||
return hardcodedModels;
|
return hardcodedModels;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@getpaseo/website",
|
"name": "@getpaseo/website",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user