mirror of
https://fastgit.cc/https://github.com/anomalyco/opencode
synced 2026-05-02 23:04:07 +08:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4954edf8ae | ||
|
|
c1b4e1f19d | ||
|
|
89d820b1c4 | ||
|
|
e3e459fc50 | ||
|
|
4bf0541bd6 | ||
|
|
c81624aef7 | ||
|
|
df61aa801b | ||
|
|
6af0c2ec21 | ||
|
|
ce9d2ee04f | ||
|
|
4b30705c42 | ||
|
|
1f8d396b76 | ||
|
|
3752bb9717 | ||
|
|
16d66c209d | ||
|
|
6506e48c54 | ||
|
|
f0e8b7c29b | ||
|
|
a00b49d65b | ||
|
|
b1589be4ba | ||
|
|
eb24d2f847 | ||
|
|
9bb25a9260 | ||
|
|
535230dce4 | ||
|
|
555fb53505 | ||
|
|
b1e0a23351 | ||
|
|
2b69bcccdf | ||
|
|
e03f27381f | ||
|
|
aebd50da7e | ||
|
|
c02f58c2af | ||
|
|
c8f4d54f7f | ||
|
|
4983d255dd | ||
|
|
f2b4891ff0 | ||
|
|
efcb5abbf7 | ||
|
|
d37e58719e | ||
|
|
c6c153de95 | ||
|
|
417e8f619c | ||
|
|
f2094b7bb3 | ||
|
|
176dc51b2e | ||
|
|
f7d9a031e6 | ||
|
|
3e2478ebf9 | ||
|
|
1f4e8b4954 | ||
|
|
9a346a00fb | ||
|
|
0a13820927 | ||
|
|
c5fa3ee9f8 | ||
|
|
c294a18155 | ||
|
|
c3dc6d6df6 | ||
|
|
ef3425a177 | ||
|
|
0290b4aaf0 | ||
|
|
4ceee53480 | ||
|
|
469dc9095f | ||
|
|
1bd198eb34 |
4
.github/workflows/format.yml
vendored
4
.github/workflows/format.yml
vendored
@@ -2,7 +2,11 @@ name: Format
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- production
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- production
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
format:
|
||||
|
||||
3
STATS.md
3
STATS.md
@@ -76,3 +76,6 @@
|
||||
| 2025-09-09 | 300,036 (+6,695) | 229,788 (+2,715) | 529,824 (+9,410) |
|
||||
| 2025-09-10 | 307,287 (+7,251) | 233,435 (+3,647) | 540,722 (+10,898) |
|
||||
| 2025-09-11 | 314,083 (+6,796) | 237,356 (+3,921) | 551,439 (+10,717) |
|
||||
| 2025-09-12 | 321,046 (+6,963) | 240,728 (+3,372) | 561,774 (+10,335) |
|
||||
| 2025-09-13 | 324,894 (+3,848) | 245,539 (+4,811) | 570,433 (+8,659) |
|
||||
| 2025-09-14 | 328,876 (+3,982) | 248,245 (+2,706) | 577,121 (+6,688) |
|
||||
|
||||
62
bun.lock
62
bun.lock
@@ -7,8 +7,8 @@
|
||||
"pulumi-stripe": "0.0.24",
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "3.5.3",
|
||||
"sst": "3.17.12",
|
||||
"prettier": "3.6.2",
|
||||
"sst": "3.17.13",
|
||||
},
|
||||
},
|
||||
"cloud/app": {
|
||||
@@ -26,7 +26,7 @@
|
||||
},
|
||||
"cloud/core": {
|
||||
"name": "@opencode/cloud-core",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sts": "3.782.0",
|
||||
"@opencode/cloud-resource": "workspace:*",
|
||||
@@ -43,7 +43,7 @@
|
||||
},
|
||||
"cloud/function": {
|
||||
"name": "@opencode/cloud-function",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "2.0.0",
|
||||
"@ai-sdk/openai": "2.0.2",
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"cloud/scripts": {
|
||||
"name": "@opencode/cloud-scripts",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@opencode/cloud-core": "workspace:*",
|
||||
"tsx": "4.20.5",
|
||||
@@ -81,7 +81,7 @@
|
||||
},
|
||||
"packages/function": {
|
||||
"name": "@opencode/function",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@octokit/auth-app": "8.0.1",
|
||||
"@octokit/rest": "22.0.0",
|
||||
@@ -96,12 +96,13 @@
|
||||
},
|
||||
"packages/opencode": {
|
||||
"name": "opencode",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
"dependencies": {
|
||||
"@clack/prompts": "1.0.0-alpha.1",
|
||||
"@hono/standard-validator": "0.1.5",
|
||||
"@hono/zod-validator": "catalog:",
|
||||
"@modelcontextprotocol/sdk": "1.15.1",
|
||||
"@openauthjs/openauth": "0.4.3",
|
||||
@@ -114,7 +115,7 @@
|
||||
"diff": "8.0.2",
|
||||
"gray-matter": "4.0.3",
|
||||
"hono": "catalog:",
|
||||
"hono-openapi": "0.4.8",
|
||||
"hono-openapi": "1.0.7",
|
||||
"ignore": "7.0.5",
|
||||
"jsonc-parser": "3.3.1",
|
||||
"minimatch": "10.0.3",
|
||||
@@ -129,7 +130,6 @@
|
||||
"xdg-basedir": "5.1.0",
|
||||
"yargs": "18.0.0",
|
||||
"zod": "catalog:",
|
||||
"zod-openapi": "4.1.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ai-sdk/amazon-bedrock": "2.2.10",
|
||||
@@ -146,7 +146,7 @@
|
||||
},
|
||||
"packages/plugin": {
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
},
|
||||
@@ -157,7 +157,7 @@
|
||||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@hey-api/openapi-ts": "0.81.0",
|
||||
},
|
||||
@@ -169,7 +169,7 @@
|
||||
},
|
||||
"packages/web": {
|
||||
"name": "@opencode/web",
|
||||
"version": "0.6.10",
|
||||
"version": "0.8.0",
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "12.6.3",
|
||||
"@astrojs/markdown-remark": "6.3.1",
|
||||
@@ -212,7 +212,7 @@
|
||||
"@solidjs/start@1.1.7": "patches/@solidjs%2Fstart@1.1.7.patch",
|
||||
},
|
||||
"overrides": {
|
||||
"zod": "3.25.76",
|
||||
"zod": "4.1.8",
|
||||
},
|
||||
"catalog": {
|
||||
"@hono/zod-validator": "0.4.2",
|
||||
@@ -224,7 +224,7 @@
|
||||
"remeda": "2.26.0",
|
||||
"solid-js": "1.9.9",
|
||||
"typescript": "5.8.2",
|
||||
"zod": "3.25.76",
|
||||
"zod": "4.1.8",
|
||||
},
|
||||
"packages": {
|
||||
"@ai-sdk/amazon-bedrock": ["@ai-sdk/amazon-bedrock@2.2.10", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8", "@smithy/eventstream-codec": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "aws4fetch": "^1.0.20" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-icLGO7Q0NinnHIPgT+y1QjHVwH4HwV+brWbvM+FfCG2Afpa89PyKa3Ret91kGjZpBgM/xnj1B7K5eM+rRlsXQA=="],
|
||||
@@ -243,8 +243,6 @@
|
||||
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
"@apidevtools/json-schema-ref-parser": ["@apidevtools/json-schema-ref-parser@11.9.3", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0" } }, "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ=="],
|
||||
|
||||
"@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.1", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20250507.0", "tinyglobby": "^0.2.13", "vite": "^6.3.5", "wrangler": "^4.14.1" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-xhJptF5tU2k5eo70nIMyL1Udma0CqmUEnGSlGyFflLqSY82CRQI6nWZ/xZt0ZvmXuErUjIx0YYQNfZsz5CNjLQ=="],
|
||||
|
||||
"@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="],
|
||||
@@ -495,6 +493,8 @@
|
||||
|
||||
"@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.81.0", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "js-yaml": "4.1.0", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-PoJukNBkUfHOoMDpN33bBETX49TUhy7Hu8Sa0jslOvFndvZ5VjQr4Nl/Dzjb9LG1Lp5HjybyTJMA6a1zYk/q6A=="],
|
||||
|
||||
"@hono/standard-validator": ["@hono/standard-validator@0.1.5", "", { "peerDependencies": { "@standard-schema/spec": "1.0.0", "hono": ">=3.9.0" } }, "sha512-EIyZPPwkyLn6XKwFj5NBEWHXhXbgmnVh2ceIFo5GO7gKI9WmzTjPDKnppQB0KrqKeAkq3kpoW4SIbu5X1dgx3w=="],
|
||||
|
||||
"@hono/zod-validator": ["@hono/zod-validator@0.4.2", "", { "peerDependencies": { "hono": ">=3.9.0", "zod": "^3.19.1" } }, "sha512-1rrlBg+EpDPhzOV4hT9pxr5+xDVmKuz6YJl+la7VCwK6ass5ldyKm5fD+umJdV2zhHD6jROoCCv8NbTwyfhT0g=="],
|
||||
|
||||
"@ibm/plex": ["@ibm/plex@6.4.1", "", { "dependencies": { "@ibm/telemetry-js": "^1.5.1" } }, "sha512-fnsipQywHt3zWvsnlyYKMikcVI7E2fEwpiPnIHFqlbByXVfQfANAAeJk1IV4mNnxhppUIDlhU0TzwYwL++Rn2g=="],
|
||||
@@ -973,6 +973,10 @@
|
||||
|
||||
"@speed-highlight/core": ["@speed-highlight/core@1.2.7", "", {}, "sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g=="],
|
||||
|
||||
"@standard-community/standard-json": ["@standard-community/standard-json@0.3.1", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "@types/json-schema": "^7.0.15", "@valibot/to-json-schema": "^1.3.0", "arktype": "^2.1.20", "effect": "^3.16.8", "quansync": "^0.2.11", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.5" }, "optionalPeers": ["@valibot/to-json-schema", "arktype", "effect", "valibot", "zod", "zod-to-json-schema"] }, "sha512-QYW1sZWWheij2CZnUL8LAFK5oECJe7cQUqtao1dY4Pjp/RPidOmpgS4L3pm9rR2gzFoyjpS5Q0MhF3c0Bxzevg=="],
|
||||
|
||||
"@standard-community/standard-openapi": ["@standard-community/standard-openapi@0.2.4", "", { "peerDependencies": { "@standard-community/standard-json": "^0.3.1", "@standard-schema/spec": "^1.0.0", "arktype": "^2.1.20", "openapi-types": "^12.1.3", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-openapi": "^4" }, "optionalPeers": ["arktype", "valibot", "zod", "zod-openapi"] }, "sha512-guPU+9Y+Y9JN0gpBQbZMlIYzRSaRyTe7f+g6JCV3d0rrMQ5JFngLQKRyg3MP07xIts8nGim167Y9ePfdlkJp0Q=="],
|
||||
|
||||
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
||||
@@ -1759,7 +1763,7 @@
|
||||
|
||||
"hono": ["hono@4.7.10", "", {}, "sha512-QkACju9MiN59CKSY5JsGZCYmPZkA6sIW6OFCUp7qDjZu6S6KHtJHhAc9Uy9mV9F8PJ1/HQ3ybZF2yjCa/73fvQ=="],
|
||||
|
||||
"hono-openapi": ["hono-openapi@0.4.8", "", { "dependencies": { "json-schema-walker": "^2.0.0" }, "peerDependencies": { "@hono/arktype-validator": "^2.0.0", "@hono/effect-validator": "^1.2.0", "@hono/typebox-validator": "^0.2.0 || ^0.3.0", "@hono/valibot-validator": "^0.5.1", "@hono/zod-validator": "^0.4.1", "@sinclair/typebox": "^0.34.9", "@valibot/to-json-schema": "^1.0.0-beta.3", "arktype": "^2.0.0", "effect": "^3.11.3", "hono": "^4.6.13", "openapi-types": "^12.1.3", "valibot": "^1.0.0-beta.9", "zod": "^3.23.8", "zod-openapi": "^4.0.0" }, "optionalPeers": ["@hono/arktype-validator", "@hono/effect-validator", "@hono/typebox-validator", "@hono/valibot-validator", "@hono/zod-validator", "@sinclair/typebox", "@valibot/to-json-schema", "arktype", "effect", "hono", "valibot", "zod", "zod-openapi"] }, "sha512-LYr5xdtD49M7hEAduV1PftOMzuT8ZNvkyWfh1DThkLsIr4RkvDb12UxgIiFbwrJB6FLtFXLoOZL9x4IeDk2+VA=="],
|
||||
"hono-openapi": ["hono-openapi@1.0.7", "", { "peerDependencies": { "@hono/standard-validator": "^0.1.2", "@standard-community/standard-json": "^0.3.1", "@standard-community/standard-openapi": "^0.2.4", "@types/json-schema": "^7.0.15", "hono": "^4.8.3", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-rMn+nn4/HMisyi549L3zT7WCmVvmpiKsyt790GcGfqvJf9mJfhq6txw09l0IhSBxpJpA0pXVKxFijcsnGfshUA=="],
|
||||
|
||||
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
||||
|
||||
@@ -1919,8 +1923,6 @@
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-schema-walker": ["json-schema-walker@2.0.0", "", { "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.1.0", "clone": "^2.1.2" } }, "sha512-nXN2cMky0Iw7Af28w061hmxaPDaML5/bQD9nwm1lOoIKEGjHcRGxqWe4MfrkYThYAPjSUhmsp4bJNoLAyVn9Xw=="],
|
||||
|
||||
"json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="],
|
||||
|
||||
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||
@@ -2365,7 +2367,7 @@
|
||||
|
||||
"precinct": ["precinct@12.2.0", "", { "dependencies": { "@dependents/detective-less": "^5.0.1", "commander": "^12.1.0", "detective-amd": "^6.0.1", "detective-cjs": "^6.0.1", "detective-es6": "^5.0.1", "detective-postcss": "^7.0.1", "detective-sass": "^6.0.1", "detective-scss": "^5.0.1", "detective-stylus": "^5.0.1", "detective-typescript": "^14.0.0", "detective-vue2": "^2.2.0", "module-definition": "^6.0.1", "node-source-walk": "^7.0.1", "postcss": "^8.5.1", "typescript": "^5.7.3" }, "bin": { "precinct": "bin/cli.js" } }, "sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w=="],
|
||||
|
||||
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
||||
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"pretty-bytes": ["pretty-bytes@6.1.1", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="],
|
||||
|
||||
@@ -2647,23 +2649,23 @@
|
||||
|
||||
"ssri": ["ssri@10.0.6", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ=="],
|
||||
|
||||
"sst": ["sst@3.17.12", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.17.12", "sst-darwin-x64": "3.17.12", "sst-linux-arm64": "3.17.12", "sst-linux-x64": "3.17.12", "sst-linux-x86": "3.17.12", "sst-win32-arm64": "3.17.12", "sst-win32-x64": "3.17.12", "sst-win32-x86": "3.17.12" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-UwUbucNZRLp9GHgPAwkat1sBsNGaJfHsLXZHCMKsolCW7CEuugJfvBl2vOyJrhKP4N+Xnv1QFh0BGsOmN0kQeA=="],
|
||||
"sst": ["sst@3.17.13", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.17.13", "sst-darwin-x64": "3.17.13", "sst-linux-arm64": "3.17.13", "sst-linux-x64": "3.17.13", "sst-linux-x86": "3.17.13", "sst-win32-arm64": "3.17.13", "sst-win32-x64": "3.17.13", "sst-win32-x86": "3.17.13" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-NaNTZL7uk2AsXzPBySQy7aqXlStXorR+bA785NxvCbskwkc44nVSQcEsvX5tdsD6/jrWpw9tDy4sStv2ycLAng=="],
|
||||
|
||||
"sst-darwin-arm64": ["sst-darwin-arm64@3.17.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9Oky2ZmJoeEN97ALWtFRt3kvSIZLjYoQoOtJvTaNQJTFi/9OsUE/6I5zdedf5GhMKCT1JvY+Ngpv3U3Y6SEYOg=="],
|
||||
"sst-darwin-arm64": ["sst-darwin-arm64@3.17.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HZaDReT/c+2CcEnFkYjMty63II2ckQrUniiSdoEH6eAWyU1Iy7UwKK4I2GYm+5dy9xeSBaOKga6FMdLqFxIiUg=="],
|
||||
|
||||
"sst-darwin-x64": ["sst-darwin-x64@3.17.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-n6tWCjFF9Pb+QzxXJmuTGfQ4GW96Nf6ATtb7Wpa+9RDLRHrEBdOjXAp7osr7MB9djPRkt4942nwUZ7wX/EULpg=="],
|
||||
"sst-darwin-x64": ["sst-darwin-x64@3.17.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-1DlYMrmrI5RY3/Ob039JatgvDKZ5QNtyRkVu0WcnsOvcxFE4dzrCiYKYHg2A+FMDl+H1qcwy2gGA3BTwC9in1w=="],
|
||||
|
||||
"sst-linux-arm64": ["sst-linux-arm64@3.17.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-iMflBzQWhF5kmRdXu402dwVpQI9LfFR3yFok3HUTV0ema5Pq2kPphEatEEw1dyG2ZXCBLeKN+T3Ujjfer+ddRA=="],
|
||||
"sst-linux-arm64": ["sst-linux-arm64@3.17.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-A4+ZamchUdaX0pqvYWZ+r7OP1bruwEj9qgWT5kU7Q5pqaotIsEitYQi0q9nZFKH+5mXYesUwSy5FA+Q8T3X/Rg=="],
|
||||
|
||||
"sst-linux-x64": ["sst-linux-x64@3.17.12", "", { "os": "linux", "cpu": "x64" }, "sha512-89rZXs3IfGrY9yiDNuLfcJvHnAUX1gRVeB+lqQ1M2sbJD2iMpN+fx93owcApAndtZYzYNfQYEZ/xYwI6HFfu4w=="],
|
||||
"sst-linux-x64": ["sst-linux-x64@3.17.13", "", { "os": "linux", "cpu": "x64" }, "sha512-yhKZc5CojqjB2DnyeVka5jeRb4oc3lBx8Qf6or0w4cs47SBIqyvO0iR/3IeKvRRL1hiEUeUF8r/q83rQo9jZMw=="],
|
||||
|
||||
"sst-linux-x86": ["sst-linux-x86@3.17.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zc2nd2syaq/DfNxtDcn4NOh8RBCaCZ1qsjLFpvGGfMMRnGiWjofuE6eFX3fhchGL3uvaqwlENvtzj4UC/MF5wQ=="],
|
||||
"sst-linux-x86": ["sst-linux-x86@3.17.13", "", { "os": "linux", "cpu": "none" }, "sha512-G1FIUmpUaECB/3CV5EO/y1QmV5mQ8RUkFeZq64oyILEEaMzSWWKz0glHzQ3+p316VE74MzbktiWRqsCKQy8GeA=="],
|
||||
|
||||
"sst-win32-arm64": ["sst-win32-arm64@3.17.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-Bb7M6PoImmGeyzJu75QbNHBs0mDp21DsKFyMucn2dwxYwahuFPjjMbG+tlziWtxcNgdZMdEcy9jR8ot1jAIh0Q=="],
|
||||
"sst-win32-arm64": ["sst-win32-arm64@3.17.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-9uCiIXmsGoxGeNWgM81x/d6V/vecjoiHXhBUPDGlQ1Dct1SbtHAgaf/g2ec5XwSQb9B/tne4qk81eMlTl83Z1A=="],
|
||||
|
||||
"sst-win32-x64": ["sst-win32-x64@3.17.12", "", { "os": "win32", "cpu": "x64" }, "sha512-7f41o1WhxdcuLhHijoavkX5O3L/Pnma6zCoL3kG6f9Njc6Zyj8Oha2fQz6Tesb/Qt8deG04WU4bL3FmxgNHU6g=="],
|
||||
"sst-win32-x64": ["sst-win32-x64@3.17.13", "", { "os": "win32", "cpu": "x64" }, "sha512-hTuj4rFSCI/9tX4NMUpNJ69Q9td/giekELDRNv03ys8TpJGoGvPT8D6VD1eX7j1CQnOZIgeEphfW9WmCXkLaIA=="],
|
||||
|
||||
"sst-win32-x86": ["sst-win32-x86@3.17.12", "", { "os": "win32", "cpu": "none" }, "sha512-AfsNJQMTlefHitaVRWh5Uf3AaICIaomFbSo5qDbibgkvhbppCxgMFpW0IxiWySjWrCN5hMMkxdxlZP9IHqqxjQ=="],
|
||||
"sst-win32-x86": ["sst-win32-x86@3.17.13", "", { "os": "win32", "cpu": "none" }, "sha512-AuMDGux+H1kPckKJ7Szgi04EpBoOKh/v5zFNAPjvWSkcWcGZ+hsBUx3h/FO/AkGK3RnlLMRj4CQQLoa10RSSIg=="],
|
||||
|
||||
"stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="],
|
||||
|
||||
@@ -2977,7 +2979,7 @@
|
||||
|
||||
"zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
|
||||
|
||||
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
"zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="],
|
||||
|
||||
"zod-openapi": ["zod-openapi@4.1.0", "", { "peerDependencies": { "zod": "^3.21.4" } }, "sha512-bRCwRYhEO9CmFLyKgJX8h6j1dRtRiwOe+TLzMVPyV0pRW5vRIgb1rLgIGcuRZ5z3MmSVrZqbv3yva4IJrtZK4g=="],
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev",
|
||||
"build": "vinxi build && ../../packages/opencode/script/schema.ts ./.output/public/config.json",
|
||||
"start": "vinxi start",
|
||||
"version": "0.7.5"
|
||||
"version": "0.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ibm/plex": "6.4.1",
|
||||
|
||||
@@ -115,11 +115,18 @@
|
||||
[data-component="api-keys-section"] {
|
||||
[data-slot="create-form"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-4);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
|
||||
[data-slot="input-container"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
gap: var(--space-2);
|
||||
}
|
||||
@@ -148,6 +155,13 @@
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
[data-slot="form-error"] {
|
||||
color: var(--color-danger);
|
||||
font-size: var(--font-size-sm);
|
||||
margin-top: var(--space-1);
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="api-keys-table"] {
|
||||
@@ -453,10 +467,15 @@
|
||||
[data-slot="new-user-sections"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-16);
|
||||
gap: var(--space-8);
|
||||
padding: var(--space-6);
|
||||
background-color: var(--color-bg-surface);
|
||||
border: 1px dashed var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
gap: var(--space-8);
|
||||
padding: var(--space-4);
|
||||
}
|
||||
|
||||
[data-component="feature-grid"] {
|
||||
@@ -476,7 +495,6 @@
|
||||
padding: var(--space-4);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
background-color: var(--color-bg-surface);
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-sm);
|
||||
@@ -532,7 +550,6 @@
|
||||
padding: var(--space-4);
|
||||
border: 2px solid var(--color-accent);
|
||||
border-radius: var(--border-radius-sm);
|
||||
background-color: var(--color-bg-surface);
|
||||
align-items: center;
|
||||
|
||||
@media (max-width: 40rem) {
|
||||
@@ -585,26 +602,6 @@
|
||||
flex-direction: column;
|
||||
gap: var(--space-6);
|
||||
|
||||
[data-slot="section-title"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-1);
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.03125rem;
|
||||
margin: 0;
|
||||
color: var(--color-text-secondary);
|
||||
text-transform: uppercase;
|
||||
|
||||
@media (max-width: 30rem) {
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ol {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
@@ -614,15 +611,14 @@
|
||||
list-style-position: inside;
|
||||
|
||||
li {
|
||||
font-size: var(--font-size-sm);
|
||||
font-size: var(--font-size-md);
|
||||
line-height: 1.5;
|
||||
color: var(--color-text-muted);
|
||||
color: var(--color-text-secondary);
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-xs);
|
||||
font-size: var(--font-size-sm);
|
||||
padding: var(--space-1) var(--space-2);
|
||||
background-color: var(--color-bg-surface);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius-sm);
|
||||
color: var(--color-text);
|
||||
|
||||
@@ -49,7 +49,13 @@ const createKey = action(async (form: FormData) => {
|
||||
const workspaceID = form.get("workspaceID")?.toString()
|
||||
if (!workspaceID) return { error: "Workspace ID is required" }
|
||||
return json(
|
||||
withActor(() => Key.create({ name }), workspaceID),
|
||||
await withActor(
|
||||
() =>
|
||||
Key.create({ name })
|
||||
.then((data) => ({ error: undefined, data }))
|
||||
.catch((e) => ({ error: e.message as string })),
|
||||
workspaceID,
|
||||
),
|
||||
{ revalidate: listKeys.key },
|
||||
)
|
||||
}, "key.create")
|
||||
@@ -60,10 +66,7 @@ const removeKey = action(async (form: FormData) => {
|
||||
if (!id) return { error: "ID is required" }
|
||||
const workspaceID = form.get("workspaceID")?.toString()
|
||||
if (!workspaceID) return { error: "Workspace ID is required" }
|
||||
return json(
|
||||
withActor(() => Key.remove({ id }), workspaceID),
|
||||
{ revalidate: listKeys.key },
|
||||
)
|
||||
return json(await withActor(() => Key.remove({ id }), workspaceID), { revalidate: listKeys.key })
|
||||
}, "key.remove")
|
||||
|
||||
/////////////////////////////////////
|
||||
@@ -185,19 +188,26 @@ function KeySection() {
|
||||
function KeyCreateForm() {
|
||||
const params = useParams()
|
||||
const submission = useSubmission(createKey)
|
||||
const [store, setStore] = createStore({
|
||||
show: false,
|
||||
})
|
||||
const [store, setStore] = createStore({ show: false })
|
||||
|
||||
let input: HTMLInputElement
|
||||
|
||||
createEffect(() => {
|
||||
if (!submission.pending && submission.result) {
|
||||
if (!submission.pending && submission.result && !submission.result.error) {
|
||||
hide()
|
||||
}
|
||||
})
|
||||
|
||||
function show() {
|
||||
// submission.clear() does not clear the result in some cases, ie.
|
||||
// 1. Create key with empty name => error shows
|
||||
// 2. Put in a key name and creates the key => form hides
|
||||
// 3. Click add key button again => form shows with the same error if
|
||||
// submission.clear() is called only once
|
||||
while (true) {
|
||||
submission.clear()
|
||||
if (!submission.result) break
|
||||
}
|
||||
setStore("show", true)
|
||||
input.focus()
|
||||
}
|
||||
@@ -216,7 +226,12 @@ function KeyCreateForm() {
|
||||
}
|
||||
>
|
||||
<form action={createKey} method="post" data-slot="create-form">
|
||||
<input ref={(r) => (input = r)} data-component="input" name="name" type="text" placeholder="Enter key name" />
|
||||
<div data-slot="input-container">
|
||||
<input ref={(r) => (input = r)} data-component="input" name="name" type="text" placeholder="Enter key name" />
|
||||
<Show when={submission.result && submission.result.error}>
|
||||
{(err) => <div data-slot="form-error">{err()}</div>}
|
||||
</Show>
|
||||
</div>
|
||||
<input type="hidden" name="workspaceID" value={params.id} />
|
||||
<div data-slot="form-actions">
|
||||
<button type="reset" data-color="ghost" onClick={() => hide()}>
|
||||
@@ -406,10 +421,6 @@ function NewUserSection() {
|
||||
</div>
|
||||
|
||||
<div data-component="api-key-highlight">
|
||||
<div data-slot="section-title">
|
||||
<h2>Your API Key</h2>
|
||||
</div>
|
||||
|
||||
<Show when={defaultKey()}>
|
||||
<div data-slot="key-display">
|
||||
<div data-slot="key-container">
|
||||
@@ -441,15 +452,12 @@ function NewUserSection() {
|
||||
</div>
|
||||
|
||||
<div data-component="next-steps">
|
||||
<div data-slot="section-title">
|
||||
<h2>Next Steps</h2>
|
||||
</div>
|
||||
<ol>
|
||||
<li>Copy your API key above</li>
|
||||
<li>
|
||||
Run <code>opencode auth login</code> and select opencode
|
||||
</li>
|
||||
<li>Paste your API key when prompted</li>
|
||||
<li>Paste your API key</li>
|
||||
<li>Start opencode</li>
|
||||
<li>
|
||||
Run <code>/models</code> to see available models
|
||||
</li>
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
import type { APIEvent } from "@solidjs/start/server"
|
||||
import { handler } from "~/util/zen"
|
||||
|
||||
type Usage = {
|
||||
prompt_tokens?: number
|
||||
completion_tokens?: number
|
||||
total_tokens?: number
|
||||
prompt_tokens_details?: {
|
||||
text_tokens?: number
|
||||
audio_tokens?: number
|
||||
image_tokens?: number
|
||||
cached_tokens?: number
|
||||
}
|
||||
completion_tokens_details?: {
|
||||
reasoning_tokens?: number
|
||||
audio_tokens?: number
|
||||
accepted_prediction_tokens?: number
|
||||
rejected_prediction_tokens?: number
|
||||
}
|
||||
}
|
||||
|
||||
export function POST(input: APIEvent) {
|
||||
let usage: any
|
||||
let usage: Usage
|
||||
return handler(input, {
|
||||
modifyBody: (body: any) => ({
|
||||
...body,
|
||||
@@ -17,7 +35,7 @@ export function POST(input: APIEvent) {
|
||||
|
||||
let json
|
||||
try {
|
||||
json = JSON.parse(chunk.slice(6))
|
||||
json = JSON.parse(chunk.slice(6)) as { usage?: Usage }
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
@@ -26,11 +44,11 @@ export function POST(input: APIEvent) {
|
||||
usage = json.usage
|
||||
},
|
||||
getStreamUsage: () => usage,
|
||||
normalizeUsage: (usage: any) => ({
|
||||
normalizeUsage: (usage: Usage) => ({
|
||||
inputTokens: usage.prompt_tokens ?? 0,
|
||||
outputTokens: usage.completion_tokens ?? 0,
|
||||
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
||||
cacheReadTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,
|
||||
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? undefined,
|
||||
cacheReadTokens: usage.prompt_tokens_details?.cached_tokens ?? undefined,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,9 +53,9 @@ export function POST(input: APIEvent) {
|
||||
normalizeUsage: (usage: Usage) => ({
|
||||
inputTokens: usage.input_tokens ?? 0,
|
||||
outputTokens: usage.output_tokens ?? 0,
|
||||
cacheReadTokens: usage.cache_read_input_tokens ?? 0,
|
||||
cacheWrite5mTokens: usage.cache_creation?.ephemeral_5m_input_tokens,
|
||||
cacheWrite1hTokens: usage.cache_creation?.ephemeral_1h_input_tokens,
|
||||
cacheReadTokens: usage.cache_read_input_tokens ?? undefined,
|
||||
cacheWrite5mTokens: usage.cache_creation?.ephemeral_5m_input_tokens ?? undefined,
|
||||
cacheWrite1hTokens: usage.cache_creation?.ephemeral_1h_input_tokens ?? undefined,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
import type { APIEvent } from "@solidjs/start/server"
|
||||
import { handler } from "~/util/zen"
|
||||
|
||||
type Usage = {
|
||||
input_tokens?: number
|
||||
input_tokens_details?: {
|
||||
cached_tokens?: number
|
||||
}
|
||||
output_tokens?: number
|
||||
output_tokens_details?: {
|
||||
reasoning_tokens?: number
|
||||
}
|
||||
total_tokens?: number
|
||||
}
|
||||
|
||||
export function POST(input: APIEvent) {
|
||||
let usage: any
|
||||
let usage: Usage
|
||||
return handler(input, {
|
||||
setAuthHeader: (headers: Headers, apiKey: string) => {
|
||||
headers.set("authorization", `Bearer ${apiKey}`)
|
||||
@@ -15,7 +27,7 @@ export function POST(input: APIEvent) {
|
||||
|
||||
let json
|
||||
try {
|
||||
json = JSON.parse(data.slice(6))
|
||||
json = JSON.parse(data.slice(6)) as { response?: { usage?: Usage } }
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
@@ -24,14 +36,14 @@ export function POST(input: APIEvent) {
|
||||
usage = json.response.usage
|
||||
},
|
||||
getStreamUsage: () => usage,
|
||||
normalizeUsage: (usage: any) => {
|
||||
normalizeUsage: (usage: Usage) => {
|
||||
const inputTokens = usage.input_tokens ?? 0
|
||||
const outputTokens = usage.output_tokens ?? 0
|
||||
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0
|
||||
const cacheReadTokens = usage.input_tokens_details?.cached_tokens ?? 0
|
||||
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? undefined
|
||||
const cacheReadTokens = usage.input_tokens_details?.cached_tokens ?? undefined
|
||||
return {
|
||||
inputTokens: inputTokens - cacheReadTokens,
|
||||
outputTokens: outputTokens - reasoningTokens,
|
||||
inputTokens: inputTokens - (cacheReadTokens ?? 0),
|
||||
outputTokens: outputTokens - (reasoningTokens ?? 0),
|
||||
reasoningTokens,
|
||||
cacheReadTokens,
|
||||
}
|
||||
|
||||
@@ -10,10 +10,11 @@ import { Resource } from "@opencode/cloud-resource"
|
||||
type ModelCost = {
|
||||
input: number
|
||||
output: number
|
||||
cacheRead: number
|
||||
cacheWrite5m: number
|
||||
cacheWrite1h: number
|
||||
cacheRead?: number
|
||||
cacheWrite5m?: number
|
||||
cacheWrite1h?: number
|
||||
}
|
||||
|
||||
type Model = {
|
||||
id: string
|
||||
auth: boolean
|
||||
@@ -42,7 +43,7 @@ export async function handler(
|
||||
inputTokens: number
|
||||
outputTokens: number
|
||||
reasoningTokens?: number
|
||||
cacheReadTokens: number
|
||||
cacheReadTokens?: number
|
||||
cacheWrite5mTokens?: number
|
||||
cacheWrite1hTokens?: number
|
||||
}
|
||||
@@ -129,8 +130,6 @@ export async function handler(
|
||||
input: 0.00000125,
|
||||
output: 0.00001,
|
||||
cacheRead: 0.000000125,
|
||||
cacheWrite5m: 0,
|
||||
cacheWrite1h: 0,
|
||||
},
|
||||
headerMappings: {},
|
||||
providers: {
|
||||
@@ -147,9 +146,6 @@ export async function handler(
|
||||
cost: {
|
||||
input: 0.00000045,
|
||||
output: 0.0000018,
|
||||
cacheRead: 0,
|
||||
cacheWrite5m: 0,
|
||||
cacheWrite1h: 0,
|
||||
},
|
||||
headerMappings: {},
|
||||
providers: {
|
||||
@@ -173,9 +169,6 @@ export async function handler(
|
||||
cost: {
|
||||
input: 0.0000006,
|
||||
output: 0.0000025,
|
||||
cacheRead: 0,
|
||||
cacheWrite5m: 0,
|
||||
cacheWrite1h: 0,
|
||||
},
|
||||
headerMappings: {},
|
||||
providers: {
|
||||
@@ -200,8 +193,6 @@ export async function handler(
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite5m: 0,
|
||||
cacheWrite1h: 0,
|
||||
},
|
||||
headerMappings: {
|
||||
"x-grok-conv-id": "x-opencode-session",
|
||||
@@ -222,9 +213,6 @@ export async function handler(
|
||||
cost: {
|
||||
input: 0.00000038,
|
||||
output: 0.00000153,
|
||||
cacheRead: 0,
|
||||
cacheWrite5m: 0,
|
||||
cacheWrite1h: 0,
|
||||
},
|
||||
headerMappings: {},
|
||||
providers: {
|
||||
@@ -438,15 +426,30 @@ export async function handler(
|
||||
|
||||
const inputCost = modelCost.input * inputTokens * 100
|
||||
const outputCost = modelCost.output * outputTokens * 100
|
||||
const reasoningCost = reasoningTokens ? modelCost.output * reasoningTokens * 100 : undefined
|
||||
const cacheReadCost = modelCost.cacheRead * cacheReadTokens * 100
|
||||
const cacheWrite5mCost = cacheWrite5mTokens ? modelCost.cacheWrite5m * cacheWrite5mTokens * 100 : undefined
|
||||
const cacheWrite1hCost = cacheWrite1hTokens ? modelCost.cacheWrite1h * cacheWrite1hTokens * 100 : undefined
|
||||
const reasoningCost = (() => {
|
||||
if (!reasoningTokens) return undefined
|
||||
return modelCost.output * reasoningTokens * 100
|
||||
})()
|
||||
const cacheReadCost = (() => {
|
||||
if (!cacheReadTokens) return undefined
|
||||
if (!modelCost.cacheRead) return undefined
|
||||
return modelCost.cacheRead * cacheReadTokens * 100
|
||||
})()
|
||||
const cacheWrite5mCost = (() => {
|
||||
if (!cacheWrite5mTokens) return undefined
|
||||
if (!modelCost.cacheWrite5m) return undefined
|
||||
return modelCost.cacheWrite5m * cacheWrite5mTokens * 100
|
||||
})()
|
||||
const cacheWrite1hCost = (() => {
|
||||
if (!cacheWrite1hTokens) return undefined
|
||||
if (!modelCost.cacheWrite1h) return undefined
|
||||
return modelCost.cacheWrite1h * cacheWrite1hTokens * 100
|
||||
})()
|
||||
const totalCostInCent =
|
||||
inputCost +
|
||||
outputCost +
|
||||
(reasoningCost ?? 0) +
|
||||
cacheReadCost +
|
||||
(cacheReadCost ?? 0) +
|
||||
(cacheWrite5mCost ?? 0) +
|
||||
(cacheWrite1hCost ?? 0)
|
||||
|
||||
@@ -460,7 +463,7 @@ export async function handler(
|
||||
"cost.input": Math.round(inputCost),
|
||||
"cost.output": Math.round(outputCost),
|
||||
"cost.reasoning": reasoningCost ? Math.round(reasoningCost) : undefined,
|
||||
"cost.cache_read": Math.round(cacheReadCost),
|
||||
"cost.cache_read": cacheReadCost ? Math.round(cacheReadCost) : undefined,
|
||||
"cost.cache_write_5m": cacheWrite5mCost ? Math.round(cacheWrite5mCost) : undefined,
|
||||
"cost.cache_write_1h": cacheWrite1hCost ? Math.round(cacheWrite1hCost) : undefined,
|
||||
"cost.total": Math.round(totalCostInCent),
|
||||
@@ -479,7 +482,8 @@ export async function handler(
|
||||
outputTokens,
|
||||
reasoningTokens,
|
||||
cacheReadTokens,
|
||||
cacheWriteTokens: (cacheWrite5mTokens ?? 0) + (cacheWrite1hTokens ?? 0),
|
||||
cacheWrite5mTokens,
|
||||
cacheWrite1hTokens,
|
||||
cost,
|
||||
})
|
||||
await tx
|
||||
|
||||
1
cloud/core/migrations/0005_jazzy_skrulls.sql
Normal file
1
cloud/core/migrations/0005_jazzy_skrulls.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `usage` MODIFY COLUMN `provider` varchar(255) NOT NULL;
|
||||
2
cloud/core/migrations/0006_parallel_gauntlet.sql
Normal file
2
cloud/core/migrations/0006_parallel_gauntlet.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `usage` ADD `cache_write_5m_tokens` int;--> statement-breakpoint
|
||||
ALTER TABLE `usage` ADD `cache_write_1h_tokens` int;
|
||||
1
cloud/core/migrations/0007_familiar_nightshade.sql
Normal file
1
cloud/core/migrations/0007_familiar_nightshade.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `usage` DROP COLUMN `cache_write_tokens`;
|
||||
588
cloud/core/migrations/meta/0005_snapshot.json
Normal file
588
cloud/core/migrations/meta/0005_snapshot.json
Normal file
@@ -0,0 +1,588 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "d13af80e-3c70-4866-8f14-48e7ff6ff0ff",
|
||||
"prevId": "06dc6226-bfbb-4ccc-b4bc-f26070c3bed5",
|
||||
"tables": {
|
||||
"account": {
|
||||
"name": "account",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"columns": ["email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"billing": {
|
||||
"name": "billing",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_id": {
|
||||
"name": "payment_method_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_last4": {
|
||||
"name": "payment_method_last4",
|
||||
"type": "varchar(4)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"balance": {
|
||||
"name": "balance",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reload": {
|
||||
"name": "reload",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"billing_workspace_id_id_pk": {
|
||||
"name": "billing_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"payment": {
|
||||
"name": "payment",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_id": {
|
||||
"name": "payment_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"amount": {
|
||||
"name": "amount",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"payment_workspace_id_id_pk": {
|
||||
"name": "payment_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"usage": {
|
||||
"name": "usage",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"model": {
|
||||
"name": "model",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"provider": {
|
||||
"name": "provider",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"input_tokens": {
|
||||
"name": "input_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"output_tokens": {
|
||||
"name": "output_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reasoning_tokens": {
|
||||
"name": "reasoning_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_read_tokens": {
|
||||
"name": "cache_read_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_tokens": {
|
||||
"name": "cache_write_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cost": {
|
||||
"name": "cost",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"usage_workspace_id_id_pk": {
|
||||
"name": "usage_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor": {
|
||||
"name": "actor",
|
||||
"type": "json",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"old_name": {
|
||||
"name": "old_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_used": {
|
||||
"name": "time_used",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"global_key": {
|
||||
"name": "global_key",
|
||||
"columns": ["key"],
|
||||
"isUnique": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"columns": ["workspace_id", "name"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"key_workspace_id_id_pk": {
|
||||
"name": "key_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user": {
|
||||
"name": "user",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_seen": {
|
||||
"name": "time_seen",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"user_email": {
|
||||
"name": "user_email",
|
||||
"columns": ["workspace_id", "email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"user_workspace_id_id_pk": {
|
||||
"name": "user_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"workspace": {
|
||||
"name": "workspace",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"columns": ["slug"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"columns": ["id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
602
cloud/core/migrations/meta/0006_snapshot.json
Normal file
602
cloud/core/migrations/meta/0006_snapshot.json
Normal file
@@ -0,0 +1,602 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "b0ad4b11-b607-46c7-8e2d-3b9823cdc5f7",
|
||||
"prevId": "d13af80e-3c70-4866-8f14-48e7ff6ff0ff",
|
||||
"tables": {
|
||||
"account": {
|
||||
"name": "account",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"columns": ["email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"billing": {
|
||||
"name": "billing",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_id": {
|
||||
"name": "payment_method_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_last4": {
|
||||
"name": "payment_method_last4",
|
||||
"type": "varchar(4)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"balance": {
|
||||
"name": "balance",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reload": {
|
||||
"name": "reload",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"billing_workspace_id_id_pk": {
|
||||
"name": "billing_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"payment": {
|
||||
"name": "payment",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_id": {
|
||||
"name": "payment_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"amount": {
|
||||
"name": "amount",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"payment_workspace_id_id_pk": {
|
||||
"name": "payment_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"usage": {
|
||||
"name": "usage",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"model": {
|
||||
"name": "model",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"provider": {
|
||||
"name": "provider",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"input_tokens": {
|
||||
"name": "input_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"output_tokens": {
|
||||
"name": "output_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reasoning_tokens": {
|
||||
"name": "reasoning_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_read_tokens": {
|
||||
"name": "cache_read_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_tokens": {
|
||||
"name": "cache_write_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_5m_tokens": {
|
||||
"name": "cache_write_5m_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_1h_tokens": {
|
||||
"name": "cache_write_1h_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cost": {
|
||||
"name": "cost",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"usage_workspace_id_id_pk": {
|
||||
"name": "usage_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor": {
|
||||
"name": "actor",
|
||||
"type": "json",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"old_name": {
|
||||
"name": "old_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_used": {
|
||||
"name": "time_used",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"global_key": {
|
||||
"name": "global_key",
|
||||
"columns": ["key"],
|
||||
"isUnique": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"columns": ["workspace_id", "name"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"key_workspace_id_id_pk": {
|
||||
"name": "key_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user": {
|
||||
"name": "user",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_seen": {
|
||||
"name": "time_seen",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"user_email": {
|
||||
"name": "user_email",
|
||||
"columns": ["workspace_id", "email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"user_workspace_id_id_pk": {
|
||||
"name": "user_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"workspace": {
|
||||
"name": "workspace",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"columns": ["slug"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"columns": ["id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
595
cloud/core/migrations/meta/0007_snapshot.json
Normal file
595
cloud/core/migrations/meta/0007_snapshot.json
Normal file
@@ -0,0 +1,595 @@
|
||||
{
|
||||
"version": "5",
|
||||
"dialect": "mysql",
|
||||
"id": "91067cc9-d492-47b3-932a-42dcc0920b3c",
|
||||
"prevId": "b0ad4b11-b607-46c7-8e2d-3b9823cdc5f7",
|
||||
"tables": {
|
||||
"account": {
|
||||
"name": "account",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"columns": ["email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"billing": {
|
||||
"name": "billing",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_id": {
|
||||
"name": "payment_method_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_method_last4": {
|
||||
"name": "payment_method_last4",
|
||||
"type": "varchar(4)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"balance": {
|
||||
"name": "balance",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reload": {
|
||||
"name": "reload",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"billing_workspace_id_id_pk": {
|
||||
"name": "billing_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"payment": {
|
||||
"name": "payment",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"customer_id": {
|
||||
"name": "customer_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"payment_id": {
|
||||
"name": "payment_id",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"amount": {
|
||||
"name": "amount",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"payment_workspace_id_id_pk": {
|
||||
"name": "payment_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"usage": {
|
||||
"name": "usage",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"model": {
|
||||
"name": "model",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"provider": {
|
||||
"name": "provider",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"input_tokens": {
|
||||
"name": "input_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"output_tokens": {
|
||||
"name": "output_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reasoning_tokens": {
|
||||
"name": "reasoning_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_read_tokens": {
|
||||
"name": "cache_read_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_5m_tokens": {
|
||||
"name": "cache_write_5m_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cache_write_1h_tokens": {
|
||||
"name": "cache_write_1h_tokens",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"cost": {
|
||||
"name": "cost",
|
||||
"type": "bigint",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"usage_workspace_id_id_pk": {
|
||||
"name": "usage_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"actor": {
|
||||
"name": "actor",
|
||||
"type": "json",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"old_name": {
|
||||
"name": "old_name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_used": {
|
||||
"name": "time_used",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"global_key": {
|
||||
"name": "global_key",
|
||||
"columns": ["key"],
|
||||
"isUnique": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"columns": ["workspace_id", "name"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"key_workspace_id_id_pk": {
|
||||
"name": "key_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"user": {
|
||||
"name": "user",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_seen": {
|
||||
"name": "time_seen",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "int",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"user_email": {
|
||||
"name": "user_email",
|
||||
"columns": ["workspace_id", "email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"user_workspace_id_id_pk": {
|
||||
"name": "user_workspace_id_id_pk",
|
||||
"columns": ["workspace_id", "id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
},
|
||||
"workspace": {
|
||||
"name": "workspace",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "varchar(30)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "varchar(255)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"time_created": {
|
||||
"name": "time_created",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(now())"
|
||||
},
|
||||
"time_updated": {
|
||||
"name": "time_updated",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||
},
|
||||
"time_deleted": {
|
||||
"name": "time_deleted",
|
||||
"type": "timestamp(3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"slug": {
|
||||
"name": "slug",
|
||||
"columns": ["slug"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {
|
||||
"workspace_id": {
|
||||
"name": "workspace_id",
|
||||
"columns": ["id"]
|
||||
}
|
||||
},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraint": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {},
|
||||
"indexes": {}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,27 @@
|
||||
"when": 1757627357232,
|
||||
"tag": "0004_first_mockingbird",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "5",
|
||||
"when": 1757632304856,
|
||||
"tag": "0005_jazzy_skrulls",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "5",
|
||||
"when": 1757643108507,
|
||||
"tag": "0006_parallel_gauntlet",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "5",
|
||||
"when": 1757693869142,
|
||||
"tag": "0007_familiar_nightshade",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode/cloud-core",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -41,7 +41,11 @@ export namespace Key {
|
||||
key: secretKey,
|
||||
timeUsed: null,
|
||||
}),
|
||||
)
|
||||
).catch((e: any) => {
|
||||
if (e.message.match(/Duplicate entry '.*' for key 'key.name'/))
|
||||
throw new Error("A key with this name already exists. Please choose a different name.")
|
||||
throw e
|
||||
})
|
||||
|
||||
return keyID
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { bigint, boolean, int, mysqlTable, varchar } from "drizzle-orm/mysql-core"
|
||||
import { bigint, boolean, int, mysqlTable, varchar, json } from "drizzle-orm/mysql-core"
|
||||
import { timestamps, workspaceColumns } from "../drizzle/types"
|
||||
import { workspaceIndexes } from "./workspace.sql"
|
||||
|
||||
@@ -34,12 +34,13 @@ export const UsageTable = mysqlTable(
|
||||
...workspaceColumns,
|
||||
...timestamps,
|
||||
model: varchar("model", { length: 255 }).notNull(),
|
||||
provider: varchar("provider", { length: 255 }),
|
||||
provider: varchar("provider", { length: 255 }).notNull(),
|
||||
inputTokens: int("input_tokens").notNull(),
|
||||
outputTokens: int("output_tokens").notNull(),
|
||||
reasoningTokens: int("reasoning_tokens"),
|
||||
cacheReadTokens: int("cache_read_tokens"),
|
||||
cacheWriteTokens: int("cache_write_tokens"),
|
||||
cacheWrite5mTokens: int("cache_write_5m_tokens"),
|
||||
cacheWrite1hTokens: int("cache_write_1h_tokens"),
|
||||
cost: bigint("cost", { mode: "number" }).notNull(),
|
||||
},
|
||||
(table) => [...workspaceIndexes(table)],
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.output<T>) => Result) {
|
||||
const result = (input: z.input<T>) => {
|
||||
export function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.infer<T>) => Result) {
|
||||
const result = (input: z.infer<T>) => {
|
||||
const parsed = schema.parse(input)
|
||||
return cb(parsed)
|
||||
}
|
||||
result.force = (input: z.input<T>) => cb(input)
|
||||
result.force = (input: z.infer<T>) => cb(input)
|
||||
result.schema = schema
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode/cloud-function",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "@opencode/cloud-scripts",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "tsx",
|
||||
"shell": "sst shell"
|
||||
"shell": "sst shell -- bun tsx",
|
||||
"shell-dev": "sst shell --stage dev -- bun tsx",
|
||||
"shell-prod": "sst shell --stage production -- bun tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opencode/cloud-core": "workspace:*",
|
||||
|
||||
10
cloud/scripts/src/backfill-usage-provider.ts
Normal file
10
cloud/scripts/src/backfill-usage-provider.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Database, eq } from "@opencode/cloud-core/drizzle/index.js"
|
||||
import { UsageTable } from "@opencode/cloud-core/schema/billing.sql.js"
|
||||
|
||||
await Database.use(async (tx) => {
|
||||
await tx
|
||||
.update(UsageTable)
|
||||
.set({ model: "grok-code" })
|
||||
.where(eq(UsageTable.model, "x-ai/grok-code-fast-1"))
|
||||
.limit(90000)
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
// placeholder
|
||||
@@ -24,7 +24,7 @@
|
||||
"ai": "5.0.8",
|
||||
"hono": "4.7.10",
|
||||
"typescript": "5.8.2",
|
||||
"zod": "3.25.76",
|
||||
"zod": "4.1.8",
|
||||
"remeda": "2.26.0",
|
||||
"solid-js": "1.9.9"
|
||||
}
|
||||
@@ -33,8 +33,8 @@
|
||||
"pulumi-stripe": "0.0.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "3.5.3",
|
||||
"sst": "3.17.12"
|
||||
"prettier": "3.6.2",
|
||||
"sst": "3.17.13"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -54,7 +54,7 @@
|
||||
"web-tree-sitter"
|
||||
],
|
||||
"overrides": {
|
||||
"zod": "3.25.76"
|
||||
"zod": "4.1.8"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"@solidjs/start@1.1.7": "patches/@solidjs%2Fstart@1.1.7.patch"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode/function",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
@@ -28,6 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@clack/prompts": "1.0.0-alpha.1",
|
||||
"@hono/standard-validator": "0.1.5",
|
||||
"@hono/zod-validator": "catalog:",
|
||||
"@modelcontextprotocol/sdk": "1.15.1",
|
||||
"@openauthjs/openauth": "0.4.3",
|
||||
@@ -40,7 +41,7 @@
|
||||
"diff": "8.0.2",
|
||||
"gray-matter": "4.0.3",
|
||||
"hono": "catalog:",
|
||||
"hono-openapi": "0.4.8",
|
||||
"hono-openapi": "1.0.7",
|
||||
"ignore": "7.0.5",
|
||||
"jsonc-parser": "3.3.1",
|
||||
"minimatch": "10.0.3",
|
||||
@@ -54,7 +55,6 @@
|
||||
"web-tree-sitter": "0.22.6",
|
||||
"xdg-basedir": "5.1.0",
|
||||
"yargs": "18.0.0",
|
||||
"zod": "catalog:",
|
||||
"zod-openapi": "4.1.0"
|
||||
"zod": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import "zod-openapi/extend"
|
||||
import { z } from "zod/v4"
|
||||
import { Config } from "../src/config/config"
|
||||
import { zodToJsonSchema } from "zod-to-json-schema"
|
||||
|
||||
const file = process.argv[2]
|
||||
console.log(file)
|
||||
|
||||
const result = zodToJsonSchema(Config.Info, {
|
||||
const result = z.toJSONSchema(Config.Info, {
|
||||
/**
|
||||
* We'll use the `default` values of the field as the only value in `examples`.
|
||||
* This will ensure no docs are needed to be read, as the configuration is
|
||||
@@ -15,10 +14,8 @@ const result = zodToJsonSchema(Config.Info, {
|
||||
*
|
||||
* See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
|
||||
*/
|
||||
postProcess(jsonSchema) {
|
||||
const schema = jsonSchema as typeof jsonSchema & {
|
||||
examples?: unknown[]
|
||||
}
|
||||
override(input) {
|
||||
const schema = input.jsonSchema
|
||||
if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
|
||||
if (!schema.examples) {
|
||||
schema.examples = [schema.default]
|
||||
@@ -29,8 +26,6 @@ const result = zodToJsonSchema(Config.Info, {
|
||||
.join("\n\n")
|
||||
.trim()
|
||||
}
|
||||
|
||||
return jsonSchema
|
||||
},
|
||||
}) as Record<string, unknown> & {
|
||||
allowComments?: boolean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Config } from "../config/config"
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Provider } from "../provider/provider"
|
||||
import { generateObject, type ModelMessage } from "ai"
|
||||
import PROMPT_GENERATE from "./generate.txt"
|
||||
@@ -28,10 +28,10 @@ export namespace Agent {
|
||||
})
|
||||
.optional(),
|
||||
prompt: z.string().optional(),
|
||||
tools: z.record(z.boolean()),
|
||||
tools: z.record(z.string(), z.boolean()),
|
||||
options: z.record(z.string(), z.any()),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Agent",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Auth } from "./index"
|
||||
import { NamedError } from "../util/error"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "path"
|
||||
import { Global } from "../global"
|
||||
import fs from "fs/promises"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
|
||||
export namespace Auth {
|
||||
export const Oauth = z
|
||||
@@ -11,14 +11,14 @@ export namespace Auth {
|
||||
access: z.string(),
|
||||
expires: z.number(),
|
||||
})
|
||||
.openapi({ ref: "OAuth" })
|
||||
.meta({ ref: "OAuth" })
|
||||
|
||||
export const Api = z
|
||||
.object({
|
||||
type: z.literal("api"),
|
||||
key: z.string(),
|
||||
})
|
||||
.openapi({ ref: "ApiAuth" })
|
||||
.meta({ ref: "ApiAuth" })
|
||||
|
||||
export const WellKnown = z
|
||||
.object({
|
||||
@@ -26,9 +26,9 @@ export namespace Auth {
|
||||
key: z.string(),
|
||||
token: z.string(),
|
||||
})
|
||||
.openapi({ ref: "WellKnownAuth" })
|
||||
.meta({ ref: "WellKnownAuth" })
|
||||
|
||||
export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).openapi({ ref: "Auth" })
|
||||
export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).meta({ ref: "Auth" })
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
const filepath = path.join(Global.Path.data, "auth.json")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Global } from "../global"
|
||||
import { Log } from "../util/log"
|
||||
import path from "path"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { z, type ZodType } from "zod"
|
||||
import z from "zod/v4"
|
||||
import type { ZodType } from "zod/v4"
|
||||
import { Log } from "../util/log"
|
||||
import { Instance } from "../project/instance"
|
||||
|
||||
@@ -38,7 +39,7 @@ export namespace Bus {
|
||||
type: z.literal(type),
|
||||
properties: def.properties,
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Event" + "." + def.type,
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ import { MessageV2 } from "../../session/message-v2"
|
||||
import { Identifier } from "../../id/id"
|
||||
import { Agent } from "../../agent/agent"
|
||||
import { Command } from "../../command"
|
||||
import { SessionPrompt } from "../../session/prompt"
|
||||
|
||||
const TOOL: Record<string, [string, string]> = {
|
||||
todowrite: ["Todo", UI.Style.TEXT_WARNING_BOLD],
|
||||
@@ -144,6 +145,7 @@ export const RunCommand = cmd({
|
||||
}
|
||||
|
||||
let text = ""
|
||||
|
||||
Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
|
||||
if (evt.properties.part.sessionID !== session.id) return
|
||||
if (evt.properties.part.messageID === messageID) return
|
||||
@@ -154,7 +156,13 @@ export const RunCommand = cmd({
|
||||
const title =
|
||||
part.state.title ||
|
||||
(Object.keys(part.state.input).length > 0 ? JSON.stringify(part.state.input) : "Unknown")
|
||||
|
||||
printEvent(color, tool, title)
|
||||
|
||||
if (part.tool === "bash" && part.state.output && part.state.output.trim()) {
|
||||
UI.println()
|
||||
UI.println(part.state.output)
|
||||
}
|
||||
}
|
||||
|
||||
if (part.type === "text") {
|
||||
@@ -185,7 +193,7 @@ export const RunCommand = cmd({
|
||||
})
|
||||
|
||||
if (args.command) {
|
||||
await Session.command({
|
||||
await SessionPrompt.command({
|
||||
messageID: Identifier.ascending("message"),
|
||||
sessionID: session.id,
|
||||
agent: agent.name,
|
||||
@@ -197,7 +205,7 @@ export const RunCommand = cmd({
|
||||
}
|
||||
|
||||
const messageID = Identifier.ascending("message")
|
||||
const result = await Session.prompt({
|
||||
const result = await SessionPrompt.prompt({
|
||||
sessionID: session.id,
|
||||
messageID,
|
||||
model: {
|
||||
|
||||
@@ -123,14 +123,15 @@ export const TuiCommand = cmd({
|
||||
const file = Bun.file(binary)
|
||||
if (!(await file.exists())) {
|
||||
await Bun.write(file, tui, { mode: 0o755 })
|
||||
await fs.chmod(binary, 0o755)
|
||||
if (process.platform !== "win32") await fs.chmod(binary, 0o755)
|
||||
}
|
||||
cmd = [binary]
|
||||
}
|
||||
if (!tui) {
|
||||
const dir = Bun.fileURLToPath(new URL("../../../../tui/cmd/opencode", import.meta.url))
|
||||
await $`go build -o ./dist/tui ./main.go`.cwd(dir)
|
||||
cmd = [path.join(dir, "dist/tui")]
|
||||
let binaryName = `./dist/tui${process.platform === "win32" ? ".exe" : ""}`
|
||||
await $`go build -o ${binaryName} ./main.go`.cwd(dir)
|
||||
cmd = [path.join(dir, binaryName)]
|
||||
}
|
||||
Log.Default.info("tui", {
|
||||
cmd,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { EOL } from "os"
|
||||
import { NamedError } from "../util/error"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Config } from "../config/config"
|
||||
import { Instance } from "../project/instance"
|
||||
|
||||
@@ -10,8 +10,9 @@ export namespace Command {
|
||||
agent: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
template: z.string(),
|
||||
subtask: z.boolean().optional(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Command",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
@@ -28,6 +29,7 @@ export namespace Command {
|
||||
model: command.model,
|
||||
description: command.description,
|
||||
template: command.template,
|
||||
subtask: command.subtask,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Log } from "../util/log"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
import { ModelsDev } from "../provider/models"
|
||||
import { mergeDeep, pipe } from "remeda"
|
||||
@@ -217,7 +217,7 @@ export namespace Config {
|
||||
enabled: z.boolean().optional().describe("Enable or disable the MCP server on startup"),
|
||||
})
|
||||
.strict()
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "McpLocalConfig",
|
||||
})
|
||||
|
||||
@@ -229,7 +229,7 @@ export namespace Config {
|
||||
headers: z.record(z.string(), z.string()).optional().describe("Headers to send with the request"),
|
||||
})
|
||||
.strict()
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "McpRemoteConfig",
|
||||
})
|
||||
|
||||
@@ -244,6 +244,7 @@ export namespace Config {
|
||||
description: z.string().optional(),
|
||||
agent: z.string().optional(),
|
||||
model: z.string().optional(),
|
||||
subtask: z.boolean().optional(),
|
||||
})
|
||||
export type Command = z.infer<typeof Command>
|
||||
|
||||
@@ -266,7 +267,7 @@ export namespace Config {
|
||||
.optional(),
|
||||
})
|
||||
.catchall(z.any())
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "AgentConfig",
|
||||
})
|
||||
export type Agent = z.infer<typeof Agent>
|
||||
@@ -341,7 +342,7 @@ export namespace Config {
|
||||
messages_revert: z.string().optional().default("none").describe("@deprecated use messages_undo. Revert message"),
|
||||
})
|
||||
.strict()
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "KeybindsConfig",
|
||||
})
|
||||
|
||||
@@ -349,7 +350,7 @@ export namespace Config {
|
||||
scroll_speed: z.number().min(1).optional().default(2).describe("TUI scroll speed"),
|
||||
})
|
||||
|
||||
export const Layout = z.enum(["auto", "stretch"]).openapi({
|
||||
export const Layout = z.enum(["auto", "stretch"]).meta({
|
||||
ref: "LayoutConfig",
|
||||
})
|
||||
export type Layout = z.infer<typeof Layout>
|
||||
@@ -406,9 +407,10 @@ export namespace Config {
|
||||
.describe("Agent configuration, see https://opencode.ai/docs/agent"),
|
||||
provider: z
|
||||
.record(
|
||||
z.string(),
|
||||
ModelsDev.Provider.partial()
|
||||
.extend({
|
||||
models: z.record(ModelsDev.Model.partial()).optional(),
|
||||
models: z.record(z.string(), ModelsDev.Model.partial()).optional(),
|
||||
options: z
|
||||
.object({
|
||||
apiKey: z.string().optional(),
|
||||
@@ -504,7 +506,7 @@ export namespace Config {
|
||||
.optional(),
|
||||
})
|
||||
.strict()
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Config",
|
||||
})
|
||||
|
||||
@@ -643,7 +645,7 @@ export namespace Config {
|
||||
"ConfigInvalidError",
|
||||
z.object({
|
||||
path: z.string(),
|
||||
issues: z.custom<z.ZodIssue[]>().optional(),
|
||||
issues: z.custom<z.core.$ZodIssue[]>().optional(),
|
||||
message: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "path"
|
||||
import { Global } from "../global"
|
||||
import fs from "fs/promises"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { NamedError } from "../util/error"
|
||||
import { lazy } from "../util/lazy"
|
||||
import { Log } from "../util/log"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Bus } from "../bus"
|
||||
import { $ } from "bun"
|
||||
import { formatPatch, structuredPatch } from "diff"
|
||||
@@ -18,7 +18,7 @@ export namespace File {
|
||||
removed: z.number().int(),
|
||||
status: z.enum(["added", "deleted", "modified"]),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "File",
|
||||
})
|
||||
|
||||
@@ -32,7 +32,7 @@ export namespace File {
|
||||
type: z.enum(["file", "directory"]),
|
||||
ignored: z.boolean(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "FileNode",
|
||||
})
|
||||
export type Node = z.infer<typeof Node>
|
||||
@@ -60,7 +60,7 @@ export namespace File {
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "FileContent",
|
||||
})
|
||||
export type Content = z.infer<typeof Content>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import path from "path"
|
||||
import { Global } from "../global"
|
||||
import fs from "fs/promises"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { NamedError } from "../util/error"
|
||||
import { lazy } from "../util/lazy"
|
||||
import { $ } from "bun"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Bus } from "../bus"
|
||||
import fs from "fs"
|
||||
import { Log } from "../util/log"
|
||||
|
||||
@@ -8,6 +8,7 @@ export namespace Flag {
|
||||
export const OPENCODE_DISABLE_DEFAULT_PLUGINS = truthy("OPENCODE_DISABLE_DEFAULT_PLUGINS")
|
||||
export const OPENCODE_DISABLE_LSP_DOWNLOAD = truthy("OPENCODE_DISABLE_LSP_DOWNLOAD")
|
||||
export const OPENCODE_ENABLE_EXPERIMENTAL_MODELS = truthy("OPENCODE_ENABLE_EXPERIMENTAL_MODELS")
|
||||
export const OPENCODE_DISABLE_AUTOCOMPACT = truthy("OPENCODE_DISABLE_AUTOCOMPACT")
|
||||
|
||||
function truthy(key: string) {
|
||||
const value = process.env[key]?.toLowerCase()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { randomBytes } from "crypto"
|
||||
|
||||
export namespace Identifier {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { spawn } from "bun"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { NamedError } from "../util/error"
|
||||
import { Log } from "../util/log"
|
||||
import { Bus } from "../bus"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import "zod-openapi/extend"
|
||||
import yargs from "yargs"
|
||||
import { hideBin } from "yargs/helpers"
|
||||
import { RunCommand } from "./cli/cmd/run"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from "path"
|
||||
import { $ } from "bun"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { NamedError } from "../util/error"
|
||||
import { Bus } from "../bus"
|
||||
import { Log } from "../util/log"
|
||||
@@ -28,7 +28,7 @@ export namespace Installation {
|
||||
version: z.string(),
|
||||
latest: z.string(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "InstallationInfo",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Diagnostic as VSCodeDiagnostic } from "vscode-languageserver-types
|
||||
import { Log } from "../util/log"
|
||||
import { LANGUAGE_EXTENSIONS } from "./language"
|
||||
import { Bus } from "../bus"
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import type { LSPServer } from "./server"
|
||||
import { NamedError } from "../util/error"
|
||||
import { withTimeout } from "../util/timeout"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Log } from "../util/log"
|
||||
import { LSPClient } from "./client"
|
||||
import path from "path"
|
||||
import { LSPServer } from "./server"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Config } from "../config/config"
|
||||
import { spawn } from "child_process"
|
||||
import { Instance } from "../project/instance"
|
||||
@@ -21,7 +21,7 @@ export namespace LSP {
|
||||
character: z.number(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Range",
|
||||
})
|
||||
export type Range = z.infer<typeof Range>
|
||||
@@ -35,7 +35,7 @@ export namespace LSP {
|
||||
range: Range,
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Symbol",
|
||||
})
|
||||
export type Symbol = z.infer<typeof Symbol>
|
||||
@@ -48,7 +48,7 @@ export namespace LSP {
|
||||
range: Range,
|
||||
selectionRange: Range,
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "DocumentSymbol",
|
||||
})
|
||||
export type DocumentSymbol = z.infer<typeof DocumentSymbol>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
||||
import { Config } from "../config/config"
|
||||
import { Log } from "../util/log"
|
||||
import { NamedError } from "../util/error"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Session } from "../session"
|
||||
import { Bus } from "../bus"
|
||||
import { Instance } from "../project/instance"
|
||||
|
||||
@@ -1,28 +1,38 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Bus } from "../bus"
|
||||
import { Log } from "../util/log"
|
||||
import { Identifier } from "../id/id"
|
||||
import { Plugin } from "../plugin"
|
||||
import { Instance } from "../project/instance"
|
||||
import { Wildcard } from "../util/wildcard"
|
||||
|
||||
export namespace Permission {
|
||||
const log = Log.create({ service: "permission" })
|
||||
|
||||
function toKeys(pattern: Info["pattern"], type: string): string[] {
|
||||
return pattern === undefined ? [type] : Array.isArray(pattern) ? pattern : [pattern]
|
||||
}
|
||||
|
||||
function covered(keys: string[], approved: Record<string, boolean>): boolean {
|
||||
const pats = Object.keys(approved)
|
||||
return keys.every((k) => pats.some((p) => Wildcard.match(k, p)))
|
||||
}
|
||||
|
||||
export const Info = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
type: z.string(),
|
||||
pattern: z.string().optional(),
|
||||
pattern: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
sessionID: z.string(),
|
||||
messageID: z.string(),
|
||||
callID: z.string().optional(),
|
||||
title: z.string(),
|
||||
metadata: z.record(z.any()),
|
||||
metadata: z.record(z.string(), z.any()),
|
||||
time: z.object({
|
||||
created: z.number(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Permission",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
@@ -83,7 +93,9 @@ export namespace Permission {
|
||||
toolCallID: input.callID,
|
||||
pattern: input.pattern,
|
||||
})
|
||||
if (approved[input.sessionID]?.[input.pattern ?? input.type]) return
|
||||
const approvedForSession = approved[input.sessionID] || {}
|
||||
const keys = toKeys(input.pattern, input.type)
|
||||
if (covered(keys, approvedForSession)) return
|
||||
const info: Info = {
|
||||
id: Identifier.ascending("permission"),
|
||||
type: input.type,
|
||||
@@ -141,9 +153,15 @@ export namespace Permission {
|
||||
})
|
||||
if (input.response === "always") {
|
||||
approved[input.sessionID] = approved[input.sessionID] || {}
|
||||
approved[input.sessionID][match.info.pattern ?? match.info.type] = true
|
||||
for (const item of Object.values(pending[input.sessionID])) {
|
||||
if ((item.info.pattern ?? item.info.type) === (match.info.pattern ?? match.info.type)) {
|
||||
const approveKeys = toKeys(match.info.pattern, match.info.type)
|
||||
for (const k of approveKeys) {
|
||||
approved[input.sessionID][k] = true
|
||||
}
|
||||
const items = pending[input.sessionID]
|
||||
if (!items) return
|
||||
for (const item of Object.values(items)) {
|
||||
const itemKeys = toKeys(item.info.pattern, item.info.type)
|
||||
if (covered(itemKeys, approved[input.sessionID])) {
|
||||
respond({ sessionID: item.info.sessionID, permissionID: item.info.id, response: input.response })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Filesystem } from "../util/filesystem"
|
||||
import path from "path"
|
||||
import { $ } from "bun"
|
||||
@@ -17,7 +17,7 @@ export namespace Project {
|
||||
initialized: z.number().optional(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Project",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Global } from "../global"
|
||||
import { Log } from "../util/log"
|
||||
import path from "path"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { data } from "./models-macro" with { type: "macro" }
|
||||
import { Installation } from "../installation"
|
||||
|
||||
@@ -29,10 +29,10 @@ export namespace ModelsDev {
|
||||
output: z.number(),
|
||||
}),
|
||||
experimental: z.boolean().optional(),
|
||||
options: z.record(z.any()),
|
||||
options: z.record(z.string(), z.any()),
|
||||
provider: z.object({ npm: z.string() }).optional(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Model",
|
||||
})
|
||||
export type Model = z.infer<typeof Model>
|
||||
@@ -44,9 +44,9 @@ export namespace ModelsDev {
|
||||
env: z.array(z.string()),
|
||||
id: z.string(),
|
||||
npm: z.string().optional(),
|
||||
models: z.record(Model),
|
||||
models: z.record(z.string(), Model),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Provider",
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import path from "path"
|
||||
import { Config } from "../config/config"
|
||||
import { mergeDeep, sortBy } from "remeda"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ModelMessage } from "ai"
|
||||
import { unique } from "remeda"
|
||||
import type { JSONSchema } from "zod/v4/core"
|
||||
|
||||
export namespace ProviderTransform {
|
||||
function normalizeToolCallIds(msgs: ModelMessage[]): ModelMessage[] {
|
||||
@@ -112,4 +113,29 @@ export namespace ProviderTransform {
|
||||
}
|
||||
return outputLimit
|
||||
}
|
||||
|
||||
export function schema(_providerID: string, _modelID: string, schema: JSONSchema.BaseSchema) {
|
||||
/*
|
||||
if (["openai", "azure"].includes(providerID)) {
|
||||
if (schema.type === "object" && schema.properties) {
|
||||
for (const [key, value] of Object.entries(schema.properties)) {
|
||||
if (schema.required?.includes(key)) continue
|
||||
schema.properties[key] = {
|
||||
anyOf: [
|
||||
value as JSONSchema.JSONSchema,
|
||||
{
|
||||
type: "null",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (providerID === "google") {
|
||||
}
|
||||
*/
|
||||
|
||||
return schema
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute } from "hono-openapi"
|
||||
import { resolver } from "hono-openapi/zod"
|
||||
import { resolver } from "hono-openapi"
|
||||
import { Instance } from "../project/instance"
|
||||
import { Project } from "../project/project"
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { Log } from "../util/log"
|
||||
import { Bus } from "../bus"
|
||||
import { describeRoute, generateSpecs, openAPISpecs } from "hono-openapi"
|
||||
import { describeRoute, generateSpecs, validator, resolver, openAPIRouteHandler } from "hono-openapi"
|
||||
import { Hono } from "hono"
|
||||
import { streamSSE } from "hono/streaming"
|
||||
import { Session } from "../session"
|
||||
import { resolver, validator as zValidator } from "hono-openapi/zod"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Provider } from "../provider/provider"
|
||||
import { mapValues } from "remeda"
|
||||
import { NamedError } from "../util/error"
|
||||
@@ -25,6 +24,9 @@ import { Global } from "../global"
|
||||
import { ProjectRoute } from "./project"
|
||||
import { ToolRegistry } from "../tool/registry"
|
||||
import { zodToJsonSchema } from "zod-to-json-schema"
|
||||
import { SessionPrompt } from "../session/prompt"
|
||||
import { SessionCompaction } from "../session/compaction"
|
||||
import { SessionRevert } from "../session/revert"
|
||||
|
||||
const ERRORS = {
|
||||
400: {
|
||||
@@ -36,7 +38,7 @@ const ERRORS = {
|
||||
.object({
|
||||
data: z.record(z.string(), z.any()),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Error",
|
||||
}),
|
||||
),
|
||||
@@ -56,7 +58,7 @@ export namespace Server {
|
||||
optional: z.boolean().optional(),
|
||||
items: z.enum(["string", "number", "boolean"]).optional(),
|
||||
})
|
||||
.openapi({ ref: "HttpParamSpec" })
|
||||
.meta({ ref: "HttpParamSpec" })
|
||||
|
||||
const HttpToolRegistration = z
|
||||
.object({
|
||||
@@ -64,12 +66,12 @@ export namespace Server {
|
||||
description: z.string(),
|
||||
parameters: z.object({
|
||||
type: z.literal("object"),
|
||||
properties: z.record(HttpParamSpec),
|
||||
properties: z.record(z.string(), HttpParamSpec),
|
||||
}),
|
||||
callbackUrl: z.string(),
|
||||
headers: z.record(z.string(), z.string()).optional(),
|
||||
})
|
||||
.openapi({ ref: "HttpToolRegistration" })
|
||||
.meta({ ref: "HttpToolRegistration" })
|
||||
|
||||
export const Event = {
|
||||
Connected: Bus.event("server.connected", z.object({})),
|
||||
@@ -112,10 +114,9 @@ export namespace Server {
|
||||
return next()
|
||||
})
|
||||
})
|
||||
.use(zValidator("query", z.object({ directory: z.string().optional() })))
|
||||
.get(
|
||||
"/doc",
|
||||
openAPISpecs(app, {
|
||||
openAPIRouteHandler(app, {
|
||||
documentation: {
|
||||
info: {
|
||||
title: "opencode",
|
||||
@@ -126,6 +127,7 @@ export namespace Server {
|
||||
},
|
||||
}),
|
||||
)
|
||||
.use(validator("query", z.object({ directory: z.string().optional() })))
|
||||
.route("/project", ProjectRoute)
|
||||
.get(
|
||||
"/event",
|
||||
@@ -138,7 +140,7 @@ export namespace Server {
|
||||
content: {
|
||||
"text/event-stream": {
|
||||
schema: resolver(
|
||||
Bus.payloads().openapi({
|
||||
Bus.payloads().meta({
|
||||
ref: "Event",
|
||||
}),
|
||||
),
|
||||
@@ -208,7 +210,7 @@ export namespace Server {
|
||||
...ERRORS,
|
||||
},
|
||||
}),
|
||||
zValidator("json", HttpToolRegistration),
|
||||
validator("json", HttpToolRegistration),
|
||||
async (c) => {
|
||||
ToolRegistry.registerHTTP(c.req.valid("json"))
|
||||
return c.json(true)
|
||||
@@ -224,7 +226,7 @@ export namespace Server {
|
||||
description: "Tool IDs",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(z.array(z.string()).openapi({ ref: "ToolIDs" })),
|
||||
schema: resolver(z.array(z.string()).meta({ ref: "ToolIDs" })),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -254,9 +256,9 @@ export namespace Server {
|
||||
description: z.string(),
|
||||
parameters: z.any(),
|
||||
})
|
||||
.openapi({ ref: "ToolListItem" }),
|
||||
.meta({ ref: "ToolListItem" }),
|
||||
)
|
||||
.openapi({ ref: "ToolList" }),
|
||||
.meta({ ref: "ToolList" }),
|
||||
),
|
||||
},
|
||||
},
|
||||
@@ -264,7 +266,7 @@ export namespace Server {
|
||||
...ERRORS,
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
provider: z.string(),
|
||||
@@ -302,7 +304,7 @@ export namespace Server {
|
||||
worktree: z.string(),
|
||||
directory: z.string(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Path",
|
||||
}),
|
||||
),
|
||||
@@ -358,7 +360,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -386,7 +388,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -415,7 +417,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z
|
||||
.object({
|
||||
@@ -446,7 +448,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -473,13 +475,13 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
title: z.string().optional(),
|
||||
@@ -514,13 +516,13 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
messageID: z.string(),
|
||||
@@ -551,14 +553,14 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
return c.json(Session.abort(c.req.valid("param").id))
|
||||
return c.json(SessionPrompt.abort(c.req.valid("param").id))
|
||||
},
|
||||
)
|
||||
.post(
|
||||
@@ -577,7 +579,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -606,7 +608,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -635,13 +637,13 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
providerID: z.string(),
|
||||
@@ -651,7 +653,7 @@ export namespace Server {
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const body = c.req.valid("json")
|
||||
await Session.summarize({ ...body, sessionID: id })
|
||||
await SessionCompaction.run({ ...body, sessionID: id })
|
||||
return c.json(true)
|
||||
},
|
||||
)
|
||||
@@ -665,23 +667,16 @@ export namespace Server {
|
||||
description: "List of messages",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: resolver(
|
||||
z
|
||||
.object({
|
||||
info: MessageV2.Info,
|
||||
parts: MessageV2.Part.array(),
|
||||
})
|
||||
.array(),
|
||||
),
|
||||
schema: resolver(MessageV2.WithParts.array()),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
@@ -710,11 +705,11 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
messageID: z.string().openapi({ description: "Message ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
messageID: z.string().meta({ description: "Message ID" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
@@ -744,17 +739,17 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
zValidator("json", Session.PromptInput.omit({ sessionID: true })),
|
||||
validator("json", SessionPrompt.PromptInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const body = c.req.valid("json")
|
||||
const msg = await Session.prompt({ ...body, sessionID })
|
||||
const msg = await SessionPrompt.prompt({ ...body, sessionID })
|
||||
return c.json(msg)
|
||||
},
|
||||
)
|
||||
@@ -779,17 +774,17 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
zValidator("json", Session.CommandInput.omit({ sessionID: true })),
|
||||
validator("json", SessionPrompt.CommandInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const body = c.req.valid("json")
|
||||
const msg = await Session.command({ ...body, sessionID })
|
||||
const msg = await SessionPrompt.command({ ...body, sessionID })
|
||||
return c.json(msg)
|
||||
},
|
||||
)
|
||||
@@ -809,17 +804,17 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string().openapi({ description: "Session ID" }),
|
||||
id: z.string().meta({ description: "Session ID" }),
|
||||
}),
|
||||
),
|
||||
zValidator("json", Session.ShellInput.omit({ sessionID: true })),
|
||||
validator("json", SessionPrompt.ShellInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const sessionID = c.req.valid("param").id
|
||||
const body = c.req.valid("json")
|
||||
const msg = await Session.shell({ ...body, sessionID })
|
||||
const msg = await SessionPrompt.shell({ ...body, sessionID })
|
||||
return c.json(msg)
|
||||
},
|
||||
)
|
||||
@@ -839,17 +834,17 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
),
|
||||
zValidator("json", Session.RevertInput.omit({ sessionID: true })),
|
||||
validator("json", SessionRevert.RevertInput.omit({ sessionID: true })),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
log.info("revert", c.req.valid("json"))
|
||||
const session = await Session.revert({ sessionID: id, ...c.req.valid("json") })
|
||||
const session = await SessionRevert.revert({ sessionID: id, ...c.req.valid("json") })
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
@@ -869,7 +864,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
@@ -877,7 +872,7 @@ export namespace Server {
|
||||
),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const session = await Session.unrevert({ sessionID: id })
|
||||
const session = await SessionRevert.unrevert({ sessionID: id })
|
||||
return c.json(session)
|
||||
},
|
||||
)
|
||||
@@ -896,14 +891,14 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
permissionID: z.string(),
|
||||
}),
|
||||
),
|
||||
zValidator("json", z.object({ response: Permission.Response })),
|
||||
validator("json", z.object({ response: Permission.Response })),
|
||||
async (c) => {
|
||||
const params = c.req.valid("param")
|
||||
const id = params.id
|
||||
@@ -978,7 +973,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
pattern: z.string(),
|
||||
@@ -1010,7 +1005,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
query: z.string(),
|
||||
@@ -1042,7 +1037,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
query: z.string(),
|
||||
@@ -1070,7 +1065,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
path: z.string(),
|
||||
@@ -1098,7 +1093,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"query",
|
||||
z.object({
|
||||
path: z.string(),
|
||||
@@ -1147,16 +1142,16 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
service: z.string().openapi({ description: "Service name for the log entry" }),
|
||||
level: z.enum(["debug", "info", "error", "warn"]).openapi({ description: "Log level" }),
|
||||
message: z.string().openapi({ description: "Log message" }),
|
||||
service: z.string().meta({ description: "Service name for the log entry" }),
|
||||
level: z.enum(["debug", "info", "error", "warn"]).meta({ description: "Log level" }),
|
||||
message: z.string().meta({ description: "Log message" }),
|
||||
extra: z
|
||||
.record(z.string(), z.any())
|
||||
.optional()
|
||||
.openapi({ description: "Additional metadata for the log entry" }),
|
||||
.meta({ description: "Additional metadata for the log entry" }),
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
@@ -1218,7 +1213,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
text: z.string(),
|
||||
@@ -1350,7 +1345,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
command: z.string(),
|
||||
@@ -1374,7 +1369,7 @@ export namespace Server {
|
||||
},
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"json",
|
||||
z.object({
|
||||
title: z.string().optional(),
|
||||
@@ -1402,13 +1397,13 @@ export namespace Server {
|
||||
...ERRORS,
|
||||
},
|
||||
}),
|
||||
zValidator(
|
||||
validator(
|
||||
"param",
|
||||
z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
),
|
||||
zValidator("json", Auth.Info),
|
||||
validator("json", Auth.Info),
|
||||
async (c) => {
|
||||
const id = c.req.valid("param").id
|
||||
const info = c.req.valid("json")
|
||||
|
||||
124
packages/opencode/src/session/compaction.ts
Normal file
124
packages/opencode/src/session/compaction.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { generateText, type ModelMessage } from "ai"
|
||||
import { Session } from "."
|
||||
import { Identifier } from "../id/id"
|
||||
import { Instance } from "../project/instance"
|
||||
import { Provider } from "../provider/provider"
|
||||
import { defer } from "../util/defer"
|
||||
import { MessageV2 } from "./message-v2"
|
||||
import { SystemPrompt } from "./system"
|
||||
import { Bus } from "../bus"
|
||||
import z from "zod/v4"
|
||||
import type { ModelsDev } from "../provider/models"
|
||||
import { SessionPrompt } from "./prompt"
|
||||
import { Flag } from "../flag/flag"
|
||||
|
||||
export namespace SessionCompaction {
|
||||
export const Event = {
|
||||
Compacted: Bus.event(
|
||||
"session.compacted",
|
||||
z.object({
|
||||
sessionID: z.string(),
|
||||
}),
|
||||
),
|
||||
}
|
||||
|
||||
export function isOverflow(input: { tokens: MessageV2.Assistant["tokens"]; model: ModelsDev.Model }) {
|
||||
if (Flag.OPENCODE_DISABLE_AUTOCOMPACT) return false
|
||||
const context = input.model.limit.context
|
||||
if (context === 0) return false
|
||||
const count = input.tokens.input + input.tokens.cache.read + input.tokens.output
|
||||
const output = Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) || SessionPrompt.OUTPUT_TOKEN_MAX
|
||||
const usable = context - output
|
||||
return count > usable
|
||||
}
|
||||
|
||||
export async function run(input: { sessionID: string; providerID: string; modelID: string }) {
|
||||
await Session.update(input.sessionID, (draft) => {
|
||||
draft.time.compacting = Date.now()
|
||||
})
|
||||
await using _ = defer(async () => {
|
||||
await Session.update(input.sessionID, (draft) => {
|
||||
draft.time.compacting = undefined
|
||||
})
|
||||
})
|
||||
const toSummarize = await Session.messages(input.sessionID).then(MessageV2.filterSummarized)
|
||||
const model = await Provider.getModel(input.providerID, input.modelID)
|
||||
const system = [
|
||||
...SystemPrompt.summarize(model.providerID),
|
||||
...(await SystemPrompt.environment()),
|
||||
...(await SystemPrompt.custom()),
|
||||
]
|
||||
|
||||
const msg = (await Session.updateMessage({
|
||||
id: Identifier.ascending("message"),
|
||||
role: "assistant",
|
||||
sessionID: input.sessionID,
|
||||
system,
|
||||
mode: "build",
|
||||
path: {
|
||||
cwd: Instance.directory,
|
||||
root: Instance.worktree,
|
||||
},
|
||||
cost: 0,
|
||||
tokens: {
|
||||
output: 0,
|
||||
input: 0,
|
||||
reasoning: 0,
|
||||
cache: { read: 0, write: 0 },
|
||||
},
|
||||
modelID: input.modelID,
|
||||
providerID: model.providerID,
|
||||
time: {
|
||||
created: Date.now(),
|
||||
},
|
||||
})) as MessageV2.Assistant
|
||||
const generated = await generateText({
|
||||
maxRetries: 10,
|
||||
model: model.language,
|
||||
messages: [
|
||||
...system.map(
|
||||
(x): ModelMessage => ({
|
||||
role: "system",
|
||||
content: x,
|
||||
}),
|
||||
),
|
||||
...MessageV2.toModelMessage(toSummarize),
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Provide a detailed but concise summary of our conversation above. Focus on information that would be helpful for continuing the conversation, including what we did, what we're doing, which files we're working on, and what we're going to do next.",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
const usage = Session.getUsage(model.info, generated.usage, generated.providerMetadata)
|
||||
msg.cost += usage.cost
|
||||
msg.tokens = usage.tokens
|
||||
msg.summary = true
|
||||
msg.time.completed = Date.now()
|
||||
await Session.updateMessage(msg)
|
||||
const part = await Session.updatePart({
|
||||
type: "text",
|
||||
sessionID: input.sessionID,
|
||||
messageID: msg.id,
|
||||
id: Identifier.ascending("part"),
|
||||
text: generated.text,
|
||||
time: {
|
||||
start: Date.now(),
|
||||
end: Date.now(),
|
||||
},
|
||||
})
|
||||
|
||||
Bus.publish(Event.Compacted, {
|
||||
sessionID: input.sessionID,
|
||||
})
|
||||
|
||||
return {
|
||||
info: msg,
|
||||
parts: [part],
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Bus } from "../bus"
|
||||
import { NamedError } from "../util/error"
|
||||
import { Message } from "./message"
|
||||
@@ -8,7 +8,7 @@ import { LSP } from "../lsp"
|
||||
|
||||
export namespace MessageV2 {
|
||||
export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
|
||||
export const AbortedError = NamedError.create("MessageAbortedError", z.object({}))
|
||||
export const AbortedError = NamedError.create("MessageAbortedError", z.object({ message: z.string() }))
|
||||
export const AuthError = NamedError.create(
|
||||
"ProviderAuthError",
|
||||
z.object({
|
||||
@@ -21,7 +21,7 @@ export namespace MessageV2 {
|
||||
.object({
|
||||
status: z.literal("pending"),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolStatePending",
|
||||
})
|
||||
|
||||
@@ -32,12 +32,12 @@ export namespace MessageV2 {
|
||||
status: z.literal("running"),
|
||||
input: z.any(),
|
||||
title: z.string().optional(),
|
||||
metadata: z.record(z.any()).optional(),
|
||||
metadata: z.record(z.string(), z.any()).optional(),
|
||||
time: z.object({
|
||||
start: z.number(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolStateRunning",
|
||||
})
|
||||
export type ToolStateRunning = z.infer<typeof ToolStateRunning>
|
||||
@@ -45,16 +45,17 @@ export namespace MessageV2 {
|
||||
export const ToolStateCompleted = z
|
||||
.object({
|
||||
status: z.literal("completed"),
|
||||
input: z.record(z.any()),
|
||||
input: z.record(z.string(), z.any()),
|
||||
output: z.string(),
|
||||
title: z.string(),
|
||||
metadata: z.record(z.any()),
|
||||
metadata: z.record(z.string(), z.any()),
|
||||
time: z.object({
|
||||
start: z.number(),
|
||||
end: z.number(),
|
||||
compacted: z.number().optional(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolStateCompleted",
|
||||
})
|
||||
export type ToolStateCompleted = z.infer<typeof ToolStateCompleted>
|
||||
@@ -62,22 +63,22 @@ export namespace MessageV2 {
|
||||
export const ToolStateError = z
|
||||
.object({
|
||||
status: z.literal("error"),
|
||||
input: z.record(z.any()),
|
||||
input: z.record(z.string(), z.any()),
|
||||
error: z.string(),
|
||||
metadata: z.record(z.any()).optional(),
|
||||
metadata: z.record(z.string(), z.any()).optional(),
|
||||
time: z.object({
|
||||
start: z.number(),
|
||||
end: z.number(),
|
||||
}),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolStateError",
|
||||
})
|
||||
export type ToolStateError = z.infer<typeof ToolStateError>
|
||||
|
||||
export const ToolState = z
|
||||
.discriminatedUnion("status", [ToolStatePending, ToolStateRunning, ToolStateCompleted, ToolStateError])
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolState",
|
||||
})
|
||||
|
||||
@@ -90,7 +91,7 @@ export namespace MessageV2 {
|
||||
export const SnapshotPart = PartBase.extend({
|
||||
type: z.literal("snapshot"),
|
||||
snapshot: z.string(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "SnapshotPart",
|
||||
})
|
||||
export type SnapshotPart = z.infer<typeof SnapshotPart>
|
||||
@@ -99,7 +100,7 @@ export namespace MessageV2 {
|
||||
type: z.literal("patch"),
|
||||
hash: z.string(),
|
||||
files: z.string().array(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "PatchPart",
|
||||
})
|
||||
export type PatchPart = z.infer<typeof PatchPart>
|
||||
@@ -114,7 +115,7 @@ export namespace MessageV2 {
|
||||
end: z.number().optional(),
|
||||
})
|
||||
.optional(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "TextPart",
|
||||
})
|
||||
export type TextPart = z.infer<typeof TextPart>
|
||||
@@ -122,12 +123,12 @@ export namespace MessageV2 {
|
||||
export const ReasoningPart = PartBase.extend({
|
||||
type: z.literal("reasoning"),
|
||||
text: z.string(),
|
||||
metadata: z.record(z.any()).optional(),
|
||||
metadata: z.record(z.string(), z.any()).optional(),
|
||||
time: z.object({
|
||||
start: z.number(),
|
||||
end: z.number().optional(),
|
||||
}),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "ReasoningPart",
|
||||
})
|
||||
export type ReasoningPart = z.infer<typeof ReasoningPart>
|
||||
@@ -137,7 +138,7 @@ export namespace MessageV2 {
|
||||
callID: z.string(),
|
||||
tool: z.string(),
|
||||
state: ToolState,
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "ToolPart",
|
||||
})
|
||||
export type ToolPart = z.infer<typeof ToolPart>
|
||||
@@ -149,7 +150,7 @@ export namespace MessageV2 {
|
||||
start: z.number().int(),
|
||||
end: z.number().int(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "FilePartSourceText",
|
||||
}),
|
||||
})
|
||||
@@ -157,7 +158,7 @@ export namespace MessageV2 {
|
||||
export const FileSource = FilePartSourceBase.extend({
|
||||
type: z.literal("file"),
|
||||
path: z.string(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "FileSource",
|
||||
})
|
||||
|
||||
@@ -167,11 +168,11 @@ export namespace MessageV2 {
|
||||
range: LSP.Range,
|
||||
name: z.string(),
|
||||
kind: z.number().int(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "SymbolSource",
|
||||
})
|
||||
|
||||
export const FilePartSource = z.discriminatedUnion("type", [FileSource, SymbolSource]).openapi({
|
||||
export const FilePartSource = z.discriminatedUnion("type", [FileSource, SymbolSource]).meta({
|
||||
ref: "FilePartSource",
|
||||
})
|
||||
|
||||
@@ -181,7 +182,7 @@ export namespace MessageV2 {
|
||||
filename: z.string().optional(),
|
||||
url: z.string(),
|
||||
source: FilePartSource.optional(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "FilePart",
|
||||
})
|
||||
export type FilePart = z.infer<typeof FilePart>
|
||||
@@ -196,14 +197,14 @@ export namespace MessageV2 {
|
||||
end: z.number().int(),
|
||||
})
|
||||
.optional(),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "AgentPart",
|
||||
})
|
||||
export type AgentPart = z.infer<typeof AgentPart>
|
||||
|
||||
export const StepStartPart = PartBase.extend({
|
||||
type: z.literal("step-start"),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "StepStartPart",
|
||||
})
|
||||
export type StepStartPart = z.infer<typeof StepStartPart>
|
||||
@@ -220,7 +221,7 @@ export namespace MessageV2 {
|
||||
write: z.number(),
|
||||
}),
|
||||
}),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "StepFinishPart",
|
||||
})
|
||||
export type StepFinishPart = z.infer<typeof StepFinishPart>
|
||||
@@ -235,7 +236,7 @@ export namespace MessageV2 {
|
||||
time: z.object({
|
||||
created: z.number(),
|
||||
}),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "UserMessage",
|
||||
})
|
||||
export type User = z.infer<typeof User>
|
||||
@@ -252,7 +253,7 @@ export namespace MessageV2 {
|
||||
PatchPart,
|
||||
AgentPart,
|
||||
])
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Part",
|
||||
})
|
||||
export type Part = z.infer<typeof Part>
|
||||
@@ -290,12 +291,12 @@ export namespace MessageV2 {
|
||||
write: z.number(),
|
||||
}),
|
||||
}),
|
||||
}).openapi({
|
||||
}).meta({
|
||||
ref: "AssistantMessage",
|
||||
})
|
||||
export type Assistant = z.infer<typeof Assistant>
|
||||
|
||||
export const Info = z.discriminatedUnion("role", [User, Assistant]).openapi({
|
||||
export const Info = z.discriminatedUnion("role", [User, Assistant]).meta({
|
||||
ref: "Message",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
@@ -330,6 +331,12 @@ export namespace MessageV2 {
|
||||
),
|
||||
}
|
||||
|
||||
export const WithParts = z.object({
|
||||
info: Info,
|
||||
parts: z.array(Part),
|
||||
})
|
||||
export type WithParts = z.infer<typeof WithParts>
|
||||
|
||||
export function fromV1(v1: Message.Info) {
|
||||
if (v1.role === "assistant") {
|
||||
const info: Assistant = {
|
||||
@@ -528,7 +535,7 @@ export namespace MessageV2 {
|
||||
state: "output-available",
|
||||
toolCallId: part.callID,
|
||||
input: part.state.input,
|
||||
output: part.state.output,
|
||||
output: part.state.time.compacted ? "[Old tool result content cleared]" : part.state.output,
|
||||
},
|
||||
]
|
||||
if (part.state.status === "error")
|
||||
@@ -542,6 +549,15 @@ export namespace MessageV2 {
|
||||
},
|
||||
]
|
||||
}
|
||||
if (part.type === "reasoning") {
|
||||
return [
|
||||
{
|
||||
type: "reasoning",
|
||||
text: part.text,
|
||||
providerMetadata: part.metadata,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
return []
|
||||
}),
|
||||
@@ -551,4 +567,10 @@ export namespace MessageV2 {
|
||||
|
||||
return convertToModelMessages(result)
|
||||
}
|
||||
|
||||
export function filterSummarized(msgs: { info: MessageV2.Info; parts: MessageV2.Part[] }[]) {
|
||||
const i = msgs.findLastIndex((m) => m.info.role === "assistant" && !!m.info.summary)
|
||||
if (i === -1) return msgs.slice()
|
||||
return msgs.slice(i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { NamedError } from "../util/error"
|
||||
|
||||
export namespace Message {
|
||||
@@ -19,7 +19,7 @@ export namespace Message {
|
||||
toolName: z.string(),
|
||||
args: z.custom<Required<unknown>>(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolCall",
|
||||
})
|
||||
export type ToolCall = z.infer<typeof ToolCall>
|
||||
@@ -32,7 +32,7 @@ export namespace Message {
|
||||
toolName: z.string(),
|
||||
args: z.custom<Required<unknown>>(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolPartialCall",
|
||||
})
|
||||
export type ToolPartialCall = z.infer<typeof ToolPartialCall>
|
||||
@@ -46,12 +46,12 @@ export namespace Message {
|
||||
args: z.custom<Required<unknown>>(),
|
||||
result: z.string(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolResult",
|
||||
})
|
||||
export type ToolResult = z.infer<typeof ToolResult>
|
||||
|
||||
export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).openapi({
|
||||
export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).meta({
|
||||
ref: "ToolInvocation",
|
||||
})
|
||||
export type ToolInvocation = z.infer<typeof ToolInvocation>
|
||||
@@ -61,7 +61,7 @@ export namespace Message {
|
||||
type: z.literal("text"),
|
||||
text: z.string(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "TextPart",
|
||||
})
|
||||
export type TextPart = z.infer<typeof TextPart>
|
||||
@@ -70,9 +70,9 @@ export namespace Message {
|
||||
.object({
|
||||
type: z.literal("reasoning"),
|
||||
text: z.string(),
|
||||
providerMetadata: z.record(z.any()).optional(),
|
||||
providerMetadata: z.record(z.string(), z.any()).optional(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ReasoningPart",
|
||||
})
|
||||
export type ReasoningPart = z.infer<typeof ReasoningPart>
|
||||
@@ -82,7 +82,7 @@ export namespace Message {
|
||||
type: z.literal("tool-invocation"),
|
||||
toolInvocation: ToolInvocation,
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "ToolInvocationPart",
|
||||
})
|
||||
export type ToolInvocationPart = z.infer<typeof ToolInvocationPart>
|
||||
@@ -93,9 +93,9 @@ export namespace Message {
|
||||
sourceId: z.string(),
|
||||
url: z.string(),
|
||||
title: z.string().optional(),
|
||||
providerMetadata: z.record(z.any()).optional(),
|
||||
providerMetadata: z.record(z.string(), z.any()).optional(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "SourceUrlPart",
|
||||
})
|
||||
export type SourceUrlPart = z.infer<typeof SourceUrlPart>
|
||||
@@ -107,7 +107,7 @@ export namespace Message {
|
||||
filename: z.string().optional(),
|
||||
url: z.string(),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "FilePart",
|
||||
})
|
||||
export type FilePart = z.infer<typeof FilePart>
|
||||
@@ -116,14 +116,14 @@ export namespace Message {
|
||||
.object({
|
||||
type: z.literal("step-start"),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "StepStartPart",
|
||||
})
|
||||
export type StepStartPart = z.infer<typeof StepStartPart>
|
||||
|
||||
export const MessagePart = z
|
||||
.discriminatedUnion("type", [TextPart, ReasoningPart, ToolInvocationPart, SourceUrlPart, FilePart, StepStartPart])
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "MessagePart",
|
||||
})
|
||||
export type MessagePart = z.infer<typeof MessagePart>
|
||||
@@ -180,9 +180,9 @@ export namespace Message {
|
||||
.optional(),
|
||||
snapshot: z.string().optional(),
|
||||
})
|
||||
.openapi({ ref: "MessageMetadata" }),
|
||||
.meta({ ref: "MessageMetadata" }),
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: "Message",
|
||||
})
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
1590
packages/opencode/src/session/prompt.ts
Normal file
1590
packages/opencode/src/session/prompt.ts
Normal file
File diff suppressed because it is too large
Load Diff
105
packages/opencode/src/session/revert.ts
Normal file
105
packages/opencode/src/session/revert.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import z from "zod/v4"
|
||||
import { Identifier } from "../id/id"
|
||||
import { Snapshot } from "../snapshot"
|
||||
import { MessageV2 } from "./message-v2"
|
||||
import { Session } from "."
|
||||
import { Log } from "../util/log"
|
||||
import { splitWhen } from "remeda"
|
||||
import { Storage } from "../storage/storage"
|
||||
import { Bus } from "../bus"
|
||||
|
||||
export namespace SessionRevert {
|
||||
const log = Log.create({ service: "session.revert" })
|
||||
|
||||
export const RevertInput = z.object({
|
||||
sessionID: Identifier.schema("session"),
|
||||
messageID: Identifier.schema("message"),
|
||||
partID: Identifier.schema("part").optional(),
|
||||
})
|
||||
export type RevertInput = z.infer<typeof RevertInput>
|
||||
|
||||
export async function revert(input: RevertInput) {
|
||||
const all = await Session.messages(input.sessionID)
|
||||
let lastUser: MessageV2.User | undefined
|
||||
const session = await Session.get(input.sessionID)
|
||||
|
||||
let revert: Session.Info["revert"]
|
||||
const patches: Snapshot.Patch[] = []
|
||||
for (const msg of all) {
|
||||
if (msg.info.role === "user") lastUser = msg.info
|
||||
const remaining = []
|
||||
for (const part of msg.parts) {
|
||||
if (revert) {
|
||||
if (part.type === "patch") {
|
||||
patches.push(part)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (!revert) {
|
||||
if ((msg.info.id === input.messageID && !input.partID) || part.id === input.partID) {
|
||||
// if no useful parts left in message, same as reverting whole message
|
||||
const partID = remaining.some((item) => ["text", "tool"].includes(item.type)) ? input.partID : undefined
|
||||
revert = {
|
||||
messageID: !partID && lastUser ? lastUser.id : msg.info.id,
|
||||
partID,
|
||||
}
|
||||
}
|
||||
remaining.push(part)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (revert) {
|
||||
const session = await Session.get(input.sessionID)
|
||||
revert.snapshot = session.revert?.snapshot ?? (await Snapshot.track())
|
||||
await Snapshot.revert(patches)
|
||||
if (revert.snapshot) revert.diff = await Snapshot.diff(revert.snapshot)
|
||||
return Session.update(input.sessionID, (draft) => {
|
||||
draft.revert = revert
|
||||
})
|
||||
}
|
||||
return session
|
||||
}
|
||||
|
||||
export async function unrevert(input: { sessionID: string }) {
|
||||
log.info("unreverting", input)
|
||||
const session = await Session.get(input.sessionID)
|
||||
if (!session.revert) return session
|
||||
if (session.revert.snapshot) await Snapshot.restore(session.revert.snapshot)
|
||||
const next = await Session.update(input.sessionID, (draft) => {
|
||||
draft.revert = undefined
|
||||
})
|
||||
return next
|
||||
}
|
||||
|
||||
export async function cleanup(session: Session.Info) {
|
||||
if (!session.revert) return
|
||||
const sessionID = session.id
|
||||
let msgs = await Session.messages(sessionID)
|
||||
const messageID = session.revert.messageID
|
||||
const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
|
||||
msgs = preserve
|
||||
for (const msg of remove) {
|
||||
await Storage.remove(["message", sessionID, msg.info.id])
|
||||
await Bus.publish(MessageV2.Event.Removed, { sessionID: sessionID, messageID: msg.info.id })
|
||||
}
|
||||
const last = preserve.at(-1)
|
||||
if (session.revert.partID && last) {
|
||||
const partID = session.revert.partID
|
||||
const [preserveParts, removeParts] = splitWhen(last.parts, (x) => x.id === partID)
|
||||
last.parts = preserveParts
|
||||
for (const part of removeParts) {
|
||||
await Storage.remove(["part", last.info.id, part.id])
|
||||
await Bus.publish(MessageV2.Event.PartRemoved, {
|
||||
sessionID: sessionID,
|
||||
messageID: last.info.id,
|
||||
partID: part.id,
|
||||
})
|
||||
}
|
||||
}
|
||||
await Session.update(sessionID, (draft) => {
|
||||
draft.revert = undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { Log } from "../util/log"
|
||||
import { Global } from "../global"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Config } from "../config/config"
|
||||
import { Instance } from "../project/instance"
|
||||
|
||||
@@ -55,7 +55,15 @@ export namespace Snapshot {
|
||||
export async function patch(hash: string): Promise<Patch> {
|
||||
const git = gitdir()
|
||||
await $`git --git-dir ${git} add .`.quiet().cwd(Instance.directory).nothrow()
|
||||
const files = await $`git --git-dir ${git} diff --name-only ${hash} -- .`.cwd(Instance.directory).text()
|
||||
const result = await $`git --git-dir ${git} diff --name-only ${hash} -- .`.quiet().cwd(Instance.directory).nothrow()
|
||||
|
||||
// If git diff fails, return empty patch
|
||||
if (result.exitCode !== 0) {
|
||||
log.warn("failed to get diff", { hash, exitCode: result.exitCode })
|
||||
return { hash, files: [] }
|
||||
}
|
||||
|
||||
const files = result.text()
|
||||
return {
|
||||
hash,
|
||||
files: files
|
||||
@@ -70,9 +78,19 @@ export namespace Snapshot {
|
||||
export async function restore(snapshot: string) {
|
||||
log.info("restore", { commit: snapshot })
|
||||
const git = gitdir()
|
||||
await $`git --git-dir=${git} read-tree ${snapshot} && git --git-dir=${git} checkout-index -a -f`
|
||||
const result = await $`git --git-dir=${git} read-tree ${snapshot} && git --git-dir=${git} checkout-index -a -f`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
log.error("failed to restore snapshot", {
|
||||
snapshot,
|
||||
exitCode: result.exitCode,
|
||||
stderr: result.stderr.toString(),
|
||||
stdout: result.stdout.toString(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function revert(patches: Patch[]) {
|
||||
@@ -97,8 +115,19 @@ export namespace Snapshot {
|
||||
|
||||
export async function diff(hash: string) {
|
||||
const git = gitdir()
|
||||
const result = await $`git --git-dir=${git} diff ${hash} -- .`.quiet().cwd(Instance.worktree).text()
|
||||
return result.trim()
|
||||
const result = await $`git --git-dir=${git} diff ${hash} -- .`.quiet().cwd(Instance.worktree).nothrow()
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
log.warn("failed to get diff", {
|
||||
hash,
|
||||
exitCode: result.exitCode,
|
||||
stderr: result.stderr.toString(),
|
||||
stdout: result.stdout.toString(),
|
||||
})
|
||||
return ""
|
||||
}
|
||||
|
||||
return result.text().trim()
|
||||
}
|
||||
|
||||
function gitdir() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { exec } from "child_process"
|
||||
|
||||
import { Tool } from "./tool"
|
||||
@@ -59,7 +59,7 @@ export const BashTool = Tool.define("bash", {
|
||||
const tree = await parser().then((p) => p.parse(params.command))
|
||||
const permissions = await Agent.get(ctx.agent).then((x) => x.permission.bash)
|
||||
|
||||
let needsAsk = false
|
||||
const askPatterns = new Set<string>()
|
||||
for (const node of tree.rootNode.descendantsOfType("command")) {
|
||||
const command = []
|
||||
for (let i = 0; i < node.childCount; i++) {
|
||||
@@ -96,27 +96,52 @@ export const BashTool = Tool.define("bash", {
|
||||
}
|
||||
|
||||
// always allow cd if it passes above check
|
||||
if (!needsAsk && command[0] !== "cd") {
|
||||
if (command[0] !== "cd") {
|
||||
const action = Wildcard.all(node.text, permissions)
|
||||
if (action === "deny") {
|
||||
throw new Error(
|
||||
`The user has specifically restricted access to this command, you are not allowed to execute it. Here is the configuration: ${JSON.stringify(permissions)}`,
|
||||
)
|
||||
}
|
||||
if (action === "ask") needsAsk = true
|
||||
if (action === "ask") {
|
||||
const pattern = (() => {
|
||||
let head = ""
|
||||
let sub: string | undefined
|
||||
for (let i = 0; i < node.childCount; i++) {
|
||||
const child = node.child(i)
|
||||
if (!child) continue
|
||||
if (child.type === "command_name") {
|
||||
if (!head) {
|
||||
head = child.text
|
||||
}
|
||||
continue
|
||||
}
|
||||
if (!sub && child.type === "word") {
|
||||
if (!child.text.startsWith("-")) sub = child.text
|
||||
}
|
||||
}
|
||||
if (!head) return
|
||||
return sub ? `${head} ${sub} *` : `${head} *`
|
||||
})()
|
||||
if (pattern) {
|
||||
askPatterns.add(pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsAsk) {
|
||||
if (askPatterns.size > 0) {
|
||||
const patterns = Array.from(askPatterns)
|
||||
await Permission.ask({
|
||||
type: "bash",
|
||||
pattern: params.command,
|
||||
pattern: patterns,
|
||||
sessionID: ctx.sessionID,
|
||||
messageID: ctx.messageID,
|
||||
callID: ctx.callID,
|
||||
title: params.command,
|
||||
metadata: {
|
||||
command: params.command,
|
||||
patterns,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ Executes a given bash command in a persistent shell session with optional timeou
|
||||
Before executing the command, please follow these steps:
|
||||
|
||||
1. Directory Verification:
|
||||
- If the command will create new directories or files, first use the LS tool to verify the parent directory exists and is the correct location
|
||||
- For example, before running "mkdir foo/bar", first use LS to check that "foo" exists and is the intended parent directory
|
||||
- If the command will create new directories or files, first use the List tool to verify the parent directory exists and is the correct location
|
||||
- For example, before running "mkdir foo/bar", first use List to check that "foo" exists and is the intended parent directory
|
||||
|
||||
2. Command Execution:
|
||||
- Always quote file paths that contain spaces with double quotes (e.g., cd "path with spaces/file.txt")
|
||||
@@ -21,7 +21,7 @@ Usage notes:
|
||||
- You can specify an optional timeout in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 120000ms (2 minutes).
|
||||
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
|
||||
- If the output exceeds 30000 characters, output will be truncated before being returned to you.
|
||||
- VERY IMPORTANT: You MUST avoid using search commands like `find` and `grep`. Instead use Grep, Glob, or Task to search. You MUST avoid read tools like `cat`, `head`, `tail`, and `ls`, and use Read and LS to read files.
|
||||
- VERY IMPORTANT: You MUST avoid using search commands like `find` and `grep`. Instead use Grep, Glob, or Task to search. You MUST avoid read tools like `cat`, `head`, `tail`, and `ls`, and use Read and List to read files.
|
||||
- If you _still_ need to run `grep`, STOP. ALWAYS USE ripgrep at `rg` (or /usr/bin/rg) first, which all opencode users have pre-installed.
|
||||
- When issuing multiple commands, use the ';' or '&&' operator to separate them. DO NOT use newlines (newlines are ok in quoted strings).
|
||||
- Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of `cd`. You may use `cd` if the User explicitly requests it.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// https://github.com/google-gemini/gemini-cli/blob/main/packages/core/src/utils/editCorrector.ts
|
||||
// https://github.com/cline/cline/blob/main/evals/diff-edits/diff-apply/diff-06-26-25.ts
|
||||
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import * as path from "path"
|
||||
import { Tool } from "./tool"
|
||||
import { LSP } from "../lsp"
|
||||
@@ -82,7 +82,6 @@ export const EditTool = Tool.define("edit", {
|
||||
sessionID: ctx.sessionID,
|
||||
messageID: ctx.messageID,
|
||||
callID: ctx.callID,
|
||||
pattern: filePath,
|
||||
title: "Edit this file: " + filePath,
|
||||
metadata: {
|
||||
filePath,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import path from "path"
|
||||
import { Tool } from "./tool"
|
||||
import DESCRIPTION from "./glob.txt"
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
||||
- Returns matching file paths sorted by modification time
|
||||
- Use this tool when you need to find files by name patterns
|
||||
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead
|
||||
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Task tool instead
|
||||
- You have the capability to call multiple tools in a single response. It is always better to speculatively perform multiple searches as a batch that are potentially useful.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import { Ripgrep } from "../file/ripgrep"
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
- Returns file paths with at least one match sorted by modification time
|
||||
- Use this tool when you need to find files containing specific patterns
|
||||
- If you need to identify/count the number of matches within files, use the Bash tool with `rg` (ripgrep) directly. Do NOT use `grep`.
|
||||
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead
|
||||
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Task tool instead
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
|
||||
export const InvalidTool = Tool.define("invalid", {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import * as path from "path"
|
||||
import DESCRIPTION from "./ls.txt"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import path from "path"
|
||||
import { LSP } from "../lsp"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import path from "path"
|
||||
import { LSP } from "../lsp"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import { EditTool } from "./edit"
|
||||
import DESCRIPTION from "./multiedit.txt"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import * as path from "path"
|
||||
import * as fs from "fs/promises"
|
||||
import { Tool } from "./tool"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { Tool } from "./tool"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
import { BashTool } from "./bash"
|
||||
import { EditTool } from "./edit"
|
||||
import { GlobTool } from "./glob"
|
||||
@@ -124,35 +124,13 @@ export namespace ToolRegistry {
|
||||
return allTools().map((t) => t.id)
|
||||
}
|
||||
|
||||
export async function tools(providerID: string, _modelID: string) {
|
||||
export async function tools(_providerID: string, _modelID: string) {
|
||||
const result = await Promise.all(
|
||||
allTools().map(async (t) => ({
|
||||
id: t.id,
|
||||
...(await t.init()),
|
||||
})),
|
||||
)
|
||||
|
||||
if (providerID === "openai") {
|
||||
return result.map((t) => ({
|
||||
...t,
|
||||
parameters: optionalToNullable(t.parameters as unknown as z.ZodTypeAny),
|
||||
}))
|
||||
}
|
||||
|
||||
if (providerID === "azure") {
|
||||
return result.map((t) => ({
|
||||
...t,
|
||||
parameters: optionalToNullable(t.parameters as unknown as z.ZodTypeAny),
|
||||
}))
|
||||
}
|
||||
|
||||
if (providerID === "google") {
|
||||
return result.map((t) => ({
|
||||
...t,
|
||||
parameters: sanitizeGeminiParameters(t.parameters as unknown as z.ZodTypeAny),
|
||||
}))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -178,93 +156,4 @@ export namespace ToolRegistry {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function sanitizeGeminiParameters(schema: z.ZodTypeAny, visited = new Set()): z.ZodTypeAny {
|
||||
if (!schema || visited.has(schema)) {
|
||||
return schema
|
||||
}
|
||||
visited.add(schema)
|
||||
|
||||
if (schema instanceof z.ZodDefault) {
|
||||
const innerSchema = schema.removeDefault()
|
||||
// Handle Gemini's incompatibility with `default` on `anyOf` (unions).
|
||||
if (innerSchema instanceof z.ZodUnion) {
|
||||
// The schema was `z.union(...).default(...)`, which is not allowed.
|
||||
// We strip the default and return the sanitized union.
|
||||
return sanitizeGeminiParameters(innerSchema, visited)
|
||||
}
|
||||
// Otherwise, the default is on a regular type, which is allowed.
|
||||
// We recurse on the inner type and then re-apply the default.
|
||||
return sanitizeGeminiParameters(innerSchema, visited).default(schema._def.defaultValue())
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodOptional) {
|
||||
return z.optional(sanitizeGeminiParameters(schema.unwrap(), visited))
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodObject) {
|
||||
const newShape: Record<string, z.ZodTypeAny> = {}
|
||||
for (const [key, value] of Object.entries(schema.shape)) {
|
||||
newShape[key] = sanitizeGeminiParameters(value as z.ZodTypeAny, visited)
|
||||
}
|
||||
return z.object(newShape)
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodArray) {
|
||||
return z.array(sanitizeGeminiParameters(schema.element, visited))
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodUnion) {
|
||||
// This schema corresponds to `anyOf` in JSON Schema.
|
||||
// We recursively sanitize each option in the union.
|
||||
const sanitizedOptions = schema.options.map((option: z.ZodTypeAny) => sanitizeGeminiParameters(option, visited))
|
||||
return z.union(sanitizedOptions as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]])
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodString) {
|
||||
const newSchema = z.string({ description: schema.description })
|
||||
const safeChecks = ["min", "max", "length", "regex", "startsWith", "endsWith", "includes", "trim"]
|
||||
// rome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
;(newSchema._def as any).checks = (schema._def as z.ZodStringDef).checks.filter((check) =>
|
||||
safeChecks.includes(check.kind),
|
||||
)
|
||||
return newSchema
|
||||
}
|
||||
|
||||
return schema
|
||||
}
|
||||
|
||||
function optionalToNullable(schema: z.ZodTypeAny): z.ZodTypeAny {
|
||||
if (schema instanceof z.ZodObject) {
|
||||
const shape = schema.shape
|
||||
const newShape: Record<string, z.ZodTypeAny> = {}
|
||||
|
||||
for (const [key, value] of Object.entries(shape)) {
|
||||
const zodValue = value as z.ZodTypeAny
|
||||
if (zodValue instanceof z.ZodOptional) {
|
||||
newShape[key] = zodValue.unwrap().nullable()
|
||||
} else {
|
||||
newShape[key] = optionalToNullable(zodValue)
|
||||
}
|
||||
}
|
||||
|
||||
return z.object(newShape)
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodArray) {
|
||||
return z.array(optionalToNullable(schema.element))
|
||||
}
|
||||
|
||||
if (schema instanceof z.ZodUnion) {
|
||||
return z.union(
|
||||
schema.options.map((option: z.ZodTypeAny) => optionalToNullable(option)) as [
|
||||
z.ZodTypeAny,
|
||||
z.ZodTypeAny,
|
||||
...z.ZodTypeAny[],
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
return schema
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Tool } from "./tool"
|
||||
import DESCRIPTION from "./task.txt"
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Session } from "../session"
|
||||
import { Bus } from "../bus"
|
||||
import { MessageV2 } from "../session/message-v2"
|
||||
import { Identifier } from "../id/id"
|
||||
import { Agent } from "../agent/agent"
|
||||
import { SessionPrompt } from "../session/prompt"
|
||||
|
||||
export const TaskTool = Tool.define("task", async () => {
|
||||
const agents = await Agent.list().then((x) => x.filter((a) => a.mode !== "primary"))
|
||||
@@ -49,9 +50,9 @@ export const TaskTool = Tool.define("task", async () => {
|
||||
}
|
||||
|
||||
ctx.abort.addEventListener("abort", () => {
|
||||
Session.abort(session.id)
|
||||
SessionPrompt.abort(session.id)
|
||||
})
|
||||
const result = await Session.prompt({
|
||||
const result = await SessionPrompt.prompt({
|
||||
messageID,
|
||||
sessionID: session.id,
|
||||
model: {
|
||||
|
||||
@@ -5,13 +5,13 @@ Available agent types and the tools they have access to:
|
||||
|
||||
When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
|
||||
|
||||
When to use the Agent tool:
|
||||
- When you are instructed to execute custom slash commands. Use the Agent tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description="Check the file", prompt="/check-file path/to/file.py")
|
||||
When to use the Task tool:
|
||||
- When you are instructed to execute custom slash commands. Use the Task tool with the slash command invocation as the entire prompt. The slash command can take arguments. For example: Task(description="Check the file", prompt="/check-file path/to/file.py")
|
||||
|
||||
When NOT to use the Agent tool:
|
||||
- If you want to read a specific file path, use the Read or Glob tool instead of the Agent tool, to find the match more quickly
|
||||
When NOT to use the Task tool:
|
||||
- If you want to read a specific file path, use the Read or Glob tool instead of the Task tool, to find the match more quickly
|
||||
- If you are searching for a specific class definition like "class Foo", use the Glob tool instead, to find the match more quickly
|
||||
- If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Agent tool, to find the match more quickly
|
||||
- If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Task tool, to find the match more quickly
|
||||
- Other tasks that are not related to the agent descriptions above
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import DESCRIPTION_WRITE from "./todowrite.txt"
|
||||
import { Instance } from "../project/instance"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { StandardSchemaV1 } from "@standard-schema/spec"
|
||||
import z from "zod/v4"
|
||||
|
||||
export namespace Tool {
|
||||
interface Metadata {
|
||||
@@ -13,13 +13,13 @@ export namespace Tool {
|
||||
extra?: { [key: string]: any }
|
||||
metadata(input: { title?: string; metadata?: M }): void
|
||||
}
|
||||
export interface Info<Parameters extends StandardSchemaV1 = StandardSchemaV1, M extends Metadata = Metadata> {
|
||||
export interface Info<Parameters extends z.ZodType = z.ZodType, M extends Metadata = Metadata> {
|
||||
id: string
|
||||
init: () => Promise<{
|
||||
description: string
|
||||
parameters: Parameters
|
||||
execute(
|
||||
args: StandardSchemaV1.InferOutput<Parameters>,
|
||||
args: z.infer<Parameters>,
|
||||
ctx: Context,
|
||||
): Promise<{
|
||||
title: string
|
||||
@@ -29,7 +29,7 @@ export namespace Tool {
|
||||
}>
|
||||
}
|
||||
|
||||
export function define<Parameters extends StandardSchemaV1, Result extends Metadata>(
|
||||
export function define<Parameters extends z.ZodType, Result extends Metadata>(
|
||||
id: string,
|
||||
init: Info<Parameters, Result>["init"] | Awaited<ReturnType<Info<Parameters, Result>["init"]>>,
|
||||
): Info<Parameters, Result> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import { Tool } from "./tool"
|
||||
import TurndownService from "turndown"
|
||||
import DESCRIPTION from "./webfetch.txt"
|
||||
@@ -28,7 +28,6 @@ export const WebFetchTool = Tool.define("webfetch", {
|
||||
if (cfg.permission?.webfetch === "ask")
|
||||
await Permission.ask({
|
||||
type: "webfetch",
|
||||
pattern: params.url,
|
||||
sessionID: ctx.sessionID,
|
||||
messageID: ctx.messageID,
|
||||
callID: ctx.callID,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from "zod"
|
||||
import z from "zod/v4"
|
||||
import * as path from "path"
|
||||
import { Tool } from "./tool"
|
||||
import { LSP } from "../lsp"
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import { z, type ZodSchema } from "zod"
|
||||
import z from "zod/v4"
|
||||
// import { Log } from "./log"
|
||||
|
||||
// const log = Log.create()
|
||||
|
||||
export abstract class NamedError extends Error {
|
||||
abstract schema(): ZodSchema
|
||||
abstract schema(): z.core.$ZodType
|
||||
abstract toObject(): { name: string; data: any }
|
||||
|
||||
static create<Name extends string, Data extends ZodSchema>(name: Name, data: Data) {
|
||||
static create<Name extends string, Data extends z.core.$ZodType>(name: Name, data: Data) {
|
||||
const schema = z
|
||||
.object({
|
||||
name: z.literal(name),
|
||||
data,
|
||||
})
|
||||
.openapi({
|
||||
.meta({
|
||||
ref: name,
|
||||
})
|
||||
const result = class extends NamedError {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { Global } from "../global"
|
||||
import z from "zod"
|
||||
import z from "zod/v4"
|
||||
|
||||
export namespace Log {
|
||||
export const Level = z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).openapi({ ref: "LogLevel", description: "Log level" })
|
||||
export const Level = z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).meta({ ref: "LogLevel", description: "Log level" })
|
||||
export type Level = z.infer<typeof Level>
|
||||
|
||||
const levelPriority: Record<Level, number> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Session } from "../../src/session/index"
|
||||
import { SessionPrompt } from "../../src/session/prompt"
|
||||
|
||||
describe("fileRegex", () => {
|
||||
const template = `This is a @valid/path/to/a/file and it should also match at
|
||||
@@ -23,7 +23,7 @@ as well as @~/home-files and @~/paths/under/home.txt.
|
||||
|
||||
If the reference is \`@quoted/in/backticks\` then it shouldn't match at all.`
|
||||
|
||||
const matches = Array.from(template.matchAll(Session.fileRegex))
|
||||
const matches = Array.from(template.matchAll(SessionPrompt.fileRegex))
|
||||
|
||||
test("should extract exactly 12 file references", () => {
|
||||
expect(matches.length).toBe(12)
|
||||
@@ -79,13 +79,13 @@ If the reference is \`@quoted/in/backticks\` then it shouldn't match at all.`
|
||||
|
||||
test("should not match when preceded by backtick", () => {
|
||||
const backtickTest = "This `@should/not/match` should be ignored"
|
||||
const backtickMatches = Array.from(backtickTest.matchAll(Session.fileRegex))
|
||||
const backtickMatches = Array.from(backtickTest.matchAll(SessionPrompt.fileRegex))
|
||||
expect(backtickMatches.length).toBe(0)
|
||||
})
|
||||
|
||||
test("should not match email addresses", () => {
|
||||
const emailTest = "Contact user@example.com for help"
|
||||
const emailMatches = Array.from(emailTest.matchAll(Session.fileRegex))
|
||||
const emailMatches = Array.from(emailTest.matchAll(SessionPrompt.fileRegex))
|
||||
expect(emailMatches.length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import "zod-openapi/extend"
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "0.7.5",
|
||||
"version": "0.9.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
".": "0.9.0"
|
||||
".": "0.13.0"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
configured_endpoints: 43
|
||||
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-46826ba8640557721614b0c9a3f1860681d825ca8d8b12869652fa25aacb0b4c.yml
|
||||
openapi_spec_hash: 33b8db6fde3021579b21325ce910197d
|
||||
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-2e754dafcad0636137256cef499b2bcd72cf17de08f44ec03c3589b2a05341a2.yml
|
||||
openapi_spec_hash: 2d3cf84d3033068ce6c07386411527ef
|
||||
config_hash: 026ef000d34bf2f930e7b41e77d2d3ff
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# Changelog
|
||||
|
||||
## 0.13.0 (2025-09-14)
|
||||
|
||||
Full Changelog: [v0.12.0...v0.13.0](https://github.com/sst/opencode-sdk-go/compare/v0.12.0...v0.13.0)
|
||||
|
||||
### Features
|
||||
|
||||
- **api:** api update ([80da4fb](https://github.com/sst/opencode-sdk-go/commit/80da4fb4ea9c6afb51a7e7135d9f5560ce6f2a6c))
|
||||
|
||||
## 0.12.0 (2025-09-14)
|
||||
|
||||
Full Changelog: [v0.11.0...v0.12.0](https://github.com/sst/opencode-sdk-go/compare/v0.11.0...v0.12.0)
|
||||
|
||||
### Features
|
||||
|
||||
- **api:** api update ([7e3808b](https://github.com/sst/opencode-sdk-go/commit/7e3808ba349dc653174b32b48a1120c18d2975c2))
|
||||
|
||||
## 0.11.0 (2025-09-14)
|
||||
|
||||
Full Changelog: [v0.10.0...v0.11.0](https://github.com/sst/opencode-sdk-go/compare/v0.10.0...v0.11.0)
|
||||
|
||||
### Features
|
||||
|
||||
- **api:** api update ([a3d37f5](https://github.com/sst/opencode-sdk-go/commit/a3d37f5671545866547d351fc21b49809cc8b3c2))
|
||||
|
||||
## 0.10.0 (2025-09-11)
|
||||
|
||||
Full Changelog: [v0.9.0...v0.10.0](https://github.com/sst/opencode-sdk-go/compare/v0.9.0...v0.10.0)
|
||||
|
||||
### Features
|
||||
|
||||
- **api:** api update ([0dc01f6](https://github.com/sst/opencode-sdk-go/commit/0dc01f6695c9b8400a4dc92166c5002bb120cf50))
|
||||
|
||||
## 0.9.0 (2025-09-10)
|
||||
|
||||
Full Changelog: [v0.8.0...v0.9.0](https://github.com/sst/opencode-sdk-go/compare/v0.8.0...v0.9.0)
|
||||
|
||||
@@ -24,7 +24,7 @@ Or to pin the version:
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
```sh
|
||||
go get -u 'github.com/sst/opencode-sdk-go@v0.9.0'
|
||||
go get -u 'github.com/sst/opencode-sdk-go@v0.13.0'
|
||||
```
|
||||
|
||||
<!-- x-release-please-end -->
|
||||
|
||||
@@ -12,6 +12,9 @@ type Error = apierror.Error
|
||||
// This is an alias to an internal type.
|
||||
type MessageAbortedError = shared.MessageAbortedError
|
||||
|
||||
// This is an alias to an internal type.
|
||||
type MessageAbortedErrorData = shared.MessageAbortedErrorData
|
||||
|
||||
// This is an alias to an internal type.
|
||||
type MessageAbortedErrorName = shared.MessageAbortedErrorName
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ type Command struct {
|
||||
Agent string `json:"agent"`
|
||||
Description string `json:"description"`
|
||||
Model string `json:"model"`
|
||||
Subtask bool `json:"subtask"`
|
||||
JSON commandJSON `json:"-"`
|
||||
}
|
||||
|
||||
@@ -57,6 +58,7 @@ type commandJSON struct {
|
||||
Agent apijson.Field
|
||||
Description apijson.Field
|
||||
Model apijson.Field
|
||||
Subtask apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
@@ -676,6 +676,7 @@ type ConfigCommand struct {
|
||||
Agent string `json:"agent"`
|
||||
Description string `json:"description"`
|
||||
Model string `json:"model"`
|
||||
Subtask bool `json:"subtask"`
|
||||
JSON configCommandJSON `json:"-"`
|
||||
}
|
||||
|
||||
@@ -685,6 +686,7 @@ type configCommandJSON struct {
|
||||
Agent apijson.Field
|
||||
Description apijson.Field
|
||||
Model apijson.Field
|
||||
Subtask apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
@@ -698,18 +700,18 @@ func (r configCommandJSON) RawJSON() string {
|
||||
}
|
||||
|
||||
type ConfigExperimental struct {
|
||||
Hook ConfigExperimentalHook `json:"hook"`
|
||||
DisablePasteSummary bool `json:"disable_paste_summary"`
|
||||
Hook ConfigExperimentalHook `json:"hook"`
|
||||
JSON configExperimentalJSON `json:"-"`
|
||||
}
|
||||
|
||||
// configExperimentalJSON contains the JSON metadata for the struct
|
||||
// [ConfigExperimental]
|
||||
type configExperimentalJSON struct {
|
||||
Hook apijson.Field
|
||||
SummarizePaste apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
DisablePasteSummary apijson.Field
|
||||
Hook apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *ConfigExperimental) UnmarshalJSON(data []byte) (err error) {
|
||||
@@ -1022,16 +1024,14 @@ type ConfigMcpUnion interface {
|
||||
func init() {
|
||||
apijson.RegisterUnion(
|
||||
reflect.TypeOf((*ConfigMcpUnion)(nil)).Elem(),
|
||||
"type",
|
||||
"",
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(McpLocalConfig{}),
|
||||
DiscriminatorValue: "local",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(McpLocalConfig{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(McpRemoteConfig{}),
|
||||
DiscriminatorValue: "remote",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(McpRemoteConfig{}),
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -1753,15 +1753,15 @@ func (r ConfigShare) IsKnown() bool {
|
||||
// TUI specific settings
|
||||
type ConfigTui struct {
|
||||
// TUI scroll speed
|
||||
ScrollSpeed float64 `json:"scroll_speed,required"`
|
||||
JSON configTuiJSON `json:"-"`
|
||||
ScrollSpeed float64 `json:"scroll_speed"`
|
||||
JSON configTuiJSON `json:"-"`
|
||||
}
|
||||
|
||||
// configTuiJSON contains the JSON metadata for the struct [ConfigTui]
|
||||
type configTuiJSON struct {
|
||||
ScrollSpeed apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
ScrollSpeed apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *ConfigTui) UnmarshalJSON(data []byte) (err error) {
|
||||
@@ -1772,105 +1772,106 @@ func (r configTuiJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
// Custom keybind configurations
|
||||
type KeybindsConfig struct {
|
||||
// Next agent
|
||||
AgentCycle string `json:"agent_cycle,required"`
|
||||
AgentCycle string `json:"agent_cycle"`
|
||||
// Previous agent
|
||||
AgentCycleReverse string `json:"agent_cycle_reverse,required"`
|
||||
AgentCycleReverse string `json:"agent_cycle_reverse"`
|
||||
// List agents
|
||||
AgentList string `json:"agent_list,required"`
|
||||
AgentList string `json:"agent_list"`
|
||||
// Exit the application
|
||||
AppExit string `json:"app_exit,required"`
|
||||
AppExit string `json:"app_exit"`
|
||||
// Show help dialog
|
||||
AppHelp string `json:"app_help,required"`
|
||||
AppHelp string `json:"app_help"`
|
||||
// Open external editor
|
||||
EditorOpen string `json:"editor_open,required"`
|
||||
EditorOpen string `json:"editor_open"`
|
||||
// @deprecated Close file
|
||||
FileClose string `json:"file_close,required"`
|
||||
FileClose string `json:"file_close"`
|
||||
// @deprecated Split/unified diff
|
||||
FileDiffToggle string `json:"file_diff_toggle,required"`
|
||||
FileDiffToggle string `json:"file_diff_toggle"`
|
||||
// @deprecated Currently not available. List files
|
||||
FileList string `json:"file_list,required"`
|
||||
FileList string `json:"file_list"`
|
||||
// @deprecated Search file
|
||||
FileSearch string `json:"file_search,required"`
|
||||
FileSearch string `json:"file_search"`
|
||||
// Clear input field
|
||||
InputClear string `json:"input_clear,required"`
|
||||
InputClear string `json:"input_clear"`
|
||||
// Insert newline in input
|
||||
InputNewline string `json:"input_newline,required"`
|
||||
InputNewline string `json:"input_newline"`
|
||||
// Paste from clipboard
|
||||
InputPaste string `json:"input_paste,required"`
|
||||
InputPaste string `json:"input_paste"`
|
||||
// Submit input
|
||||
InputSubmit string `json:"input_submit,required"`
|
||||
InputSubmit string `json:"input_submit"`
|
||||
// Leader key for keybind combinations
|
||||
Leader string `json:"leader,required"`
|
||||
Leader string `json:"leader"`
|
||||
// Copy message
|
||||
MessagesCopy string `json:"messages_copy,required"`
|
||||
MessagesCopy string `json:"messages_copy"`
|
||||
// Navigate to first message
|
||||
MessagesFirst string `json:"messages_first,required"`
|
||||
MessagesFirst string `json:"messages_first"`
|
||||
// Scroll messages down by half page
|
||||
MessagesHalfPageDown string `json:"messages_half_page_down,required"`
|
||||
MessagesHalfPageDown string `json:"messages_half_page_down"`
|
||||
// Scroll messages up by half page
|
||||
MessagesHalfPageUp string `json:"messages_half_page_up,required"`
|
||||
MessagesHalfPageUp string `json:"messages_half_page_up"`
|
||||
// Navigate to last message
|
||||
MessagesLast string `json:"messages_last,required"`
|
||||
MessagesLast string `json:"messages_last"`
|
||||
// @deprecated Toggle layout
|
||||
MessagesLayoutToggle string `json:"messages_layout_toggle,required"`
|
||||
MessagesLayoutToggle string `json:"messages_layout_toggle"`
|
||||
// @deprecated Navigate to next message
|
||||
MessagesNext string `json:"messages_next,required"`
|
||||
MessagesNext string `json:"messages_next"`
|
||||
// Scroll messages down by one page
|
||||
MessagesPageDown string `json:"messages_page_down,required"`
|
||||
MessagesPageDown string `json:"messages_page_down"`
|
||||
// Scroll messages up by one page
|
||||
MessagesPageUp string `json:"messages_page_up,required"`
|
||||
MessagesPageUp string `json:"messages_page_up"`
|
||||
// @deprecated Navigate to previous message
|
||||
MessagesPrevious string `json:"messages_previous,required"`
|
||||
MessagesPrevious string `json:"messages_previous"`
|
||||
// Redo message
|
||||
MessagesRedo string `json:"messages_redo,required"`
|
||||
MessagesRedo string `json:"messages_redo"`
|
||||
// @deprecated use messages_undo. Revert message
|
||||
MessagesRevert string `json:"messages_revert,required"`
|
||||
MessagesRevert string `json:"messages_revert"`
|
||||
// Undo message
|
||||
MessagesUndo string `json:"messages_undo,required"`
|
||||
MessagesUndo string `json:"messages_undo"`
|
||||
// Next recent model
|
||||
ModelCycleRecent string `json:"model_cycle_recent,required"`
|
||||
ModelCycleRecent string `json:"model_cycle_recent"`
|
||||
// Previous recent model
|
||||
ModelCycleRecentReverse string `json:"model_cycle_recent_reverse,required"`
|
||||
ModelCycleRecentReverse string `json:"model_cycle_recent_reverse"`
|
||||
// List available models
|
||||
ModelList string `json:"model_list,required"`
|
||||
ModelList string `json:"model_list"`
|
||||
// Create/update AGENTS.md
|
||||
ProjectInit string `json:"project_init,required"`
|
||||
ProjectInit string `json:"project_init"`
|
||||
// Cycle to next child session
|
||||
SessionChildCycle string `json:"session_child_cycle,required"`
|
||||
SessionChildCycle string `json:"session_child_cycle"`
|
||||
// Cycle to previous child session
|
||||
SessionChildCycleReverse string `json:"session_child_cycle_reverse,required"`
|
||||
SessionChildCycleReverse string `json:"session_child_cycle_reverse"`
|
||||
// Compact the session
|
||||
SessionCompact string `json:"session_compact,required"`
|
||||
SessionCompact string `json:"session_compact"`
|
||||
// Export session to editor
|
||||
SessionExport string `json:"session_export,required"`
|
||||
SessionExport string `json:"session_export"`
|
||||
// Interrupt current session
|
||||
SessionInterrupt string `json:"session_interrupt,required"`
|
||||
SessionInterrupt string `json:"session_interrupt"`
|
||||
// List all sessions
|
||||
SessionList string `json:"session_list,required"`
|
||||
SessionList string `json:"session_list"`
|
||||
// Create a new session
|
||||
SessionNew string `json:"session_new,required"`
|
||||
SessionNew string `json:"session_new"`
|
||||
// Share current session
|
||||
SessionShare string `json:"session_share,required"`
|
||||
SessionShare string `json:"session_share"`
|
||||
// Show session timeline
|
||||
SessionTimeline string `json:"session_timeline,required"`
|
||||
SessionTimeline string `json:"session_timeline"`
|
||||
// Unshare current session
|
||||
SessionUnshare string `json:"session_unshare,required"`
|
||||
SessionUnshare string `json:"session_unshare"`
|
||||
// @deprecated use agent_cycle. Next agent
|
||||
SwitchAgent string `json:"switch_agent,required"`
|
||||
SwitchAgent string `json:"switch_agent"`
|
||||
// @deprecated use agent_cycle_reverse. Previous agent
|
||||
SwitchAgentReverse string `json:"switch_agent_reverse,required"`
|
||||
SwitchAgentReverse string `json:"switch_agent_reverse"`
|
||||
// @deprecated use agent_cycle. Next mode
|
||||
SwitchMode string `json:"switch_mode,required"`
|
||||
SwitchMode string `json:"switch_mode"`
|
||||
// @deprecated use agent_cycle_reverse. Previous mode
|
||||
SwitchModeReverse string `json:"switch_mode_reverse,required"`
|
||||
SwitchModeReverse string `json:"switch_mode_reverse"`
|
||||
// List available themes
|
||||
ThemeList string `json:"theme_list,required"`
|
||||
ThemeList string `json:"theme_list"`
|
||||
// Toggle thinking blocks
|
||||
ThinkingBlocks string `json:"thinking_blocks,required"`
|
||||
ThinkingBlocks string `json:"thinking_blocks"`
|
||||
// Toggle tool details
|
||||
ToolDetails string `json:"tool_details,required"`
|
||||
ToolDetails string `json:"tool_details"`
|
||||
JSON keybindsConfigJSON `json:"-"`
|
||||
}
|
||||
|
||||
|
||||
@@ -57,14 +57,14 @@ type EventListResponse struct {
|
||||
// [EventListResponseEventMessageUpdatedProperties],
|
||||
// [EventListResponseEventMessageRemovedProperties],
|
||||
// [EventListResponseEventMessagePartUpdatedProperties],
|
||||
// [EventListResponseEventMessagePartRemovedProperties], [Permission],
|
||||
// [EventListResponseEventMessagePartRemovedProperties],
|
||||
// [EventListResponseEventSessionCompactedProperties], [Permission],
|
||||
// [EventListResponseEventPermissionRepliedProperties],
|
||||
// [EventListResponseEventFileEditedProperties],
|
||||
// [EventListResponseEventSessionIdleProperties],
|
||||
// [EventListResponseEventSessionUpdatedProperties],
|
||||
// [EventListResponseEventSessionDeletedProperties],
|
||||
// [EventListResponseEventSessionIdleProperties],
|
||||
// [EventListResponseEventSessionErrorProperties],
|
||||
// [EventListResponseEventSessionCompactedProperties], [interface{}].
|
||||
// [EventListResponseEventSessionErrorProperties], [interface{}].
|
||||
Properties interface{} `json:"properties,required"`
|
||||
Type EventListResponseType `json:"type,required"`
|
||||
JSON eventListResponseJSON `json:"-"`
|
||||
@@ -102,11 +102,11 @@ func (r *EventListResponse) UnmarshalJSON(data []byte) (err error) {
|
||||
// [EventListResponseEventMessageUpdated], [EventListResponseEventMessageRemoved],
|
||||
// [EventListResponseEventMessagePartUpdated],
|
||||
// [EventListResponseEventMessagePartRemoved],
|
||||
// [EventListResponseEventSessionCompacted],
|
||||
// [EventListResponseEventPermissionUpdated],
|
||||
// [EventListResponseEventPermissionReplied], [EventListResponseEventFileEdited],
|
||||
// [EventListResponseEventSessionUpdated], [EventListResponseEventSessionDeleted],
|
||||
// [EventListResponseEventSessionIdle], [EventListResponseEventSessionError],
|
||||
// [EventListResponseEventSessionCompacted],
|
||||
// [EventListResponseEventSessionIdle], [EventListResponseEventSessionUpdated],
|
||||
// [EventListResponseEventSessionDeleted], [EventListResponseEventSessionError],
|
||||
// [EventListResponseEventServerConnected].
|
||||
func (r EventListResponse) AsUnion() EventListResponseUnion {
|
||||
return r.union
|
||||
@@ -117,11 +117,11 @@ func (r EventListResponse) AsUnion() EventListResponseUnion {
|
||||
// [EventListResponseEventMessageUpdated], [EventListResponseEventMessageRemoved],
|
||||
// [EventListResponseEventMessagePartUpdated],
|
||||
// [EventListResponseEventMessagePartRemoved],
|
||||
// [EventListResponseEventSessionCompacted],
|
||||
// [EventListResponseEventPermissionUpdated],
|
||||
// [EventListResponseEventPermissionReplied], [EventListResponseEventFileEdited],
|
||||
// [EventListResponseEventSessionUpdated], [EventListResponseEventSessionDeleted],
|
||||
// [EventListResponseEventSessionIdle], [EventListResponseEventSessionError],
|
||||
// [EventListResponseEventSessionCompacted] or
|
||||
// [EventListResponseEventSessionIdle], [EventListResponseEventSessionUpdated],
|
||||
// [EventListResponseEventSessionDeleted], [EventListResponseEventSessionError] or
|
||||
// [EventListResponseEventServerConnected].
|
||||
type EventListResponseUnion interface {
|
||||
implementsEventListResponse()
|
||||
@@ -130,81 +130,66 @@ type EventListResponseUnion interface {
|
||||
func init() {
|
||||
apijson.RegisterUnion(
|
||||
reflect.TypeOf((*EventListResponseUnion)(nil)).Elem(),
|
||||
"type",
|
||||
"",
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventInstallationUpdated{}),
|
||||
DiscriminatorValue: "installation.updated",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventInstallationUpdated{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventLspClientDiagnostics{}),
|
||||
DiscriminatorValue: "lsp.client.diagnostics",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventLspClientDiagnostics{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessageUpdated{}),
|
||||
DiscriminatorValue: "message.updated",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessageUpdated{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessageRemoved{}),
|
||||
DiscriminatorValue: "message.removed",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessageRemoved{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessagePartUpdated{}),
|
||||
DiscriminatorValue: "message.part.updated",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessagePartUpdated{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessagePartRemoved{}),
|
||||
DiscriminatorValue: "message.part.removed",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventMessagePartRemoved{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventPermissionUpdated{}),
|
||||
DiscriminatorValue: "permission.updated",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionCompacted{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventPermissionReplied{}),
|
||||
DiscriminatorValue: "permission.replied",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventPermissionUpdated{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventFileEdited{}),
|
||||
DiscriminatorValue: "file.edited",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventPermissionReplied{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionUpdated{}),
|
||||
DiscriminatorValue: "session.updated",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventFileEdited{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionDeleted{}),
|
||||
DiscriminatorValue: "session.deleted",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionIdle{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionIdle{}),
|
||||
DiscriminatorValue: "session.idle",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionUpdated{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionError{}),
|
||||
DiscriminatorValue: "session.error",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionDeleted{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionCompacted{}),
|
||||
DiscriminatorValue: "session.compacted",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionError{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventServerConnected{}),
|
||||
DiscriminatorValue: "server.connected",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventServerConnected{}),
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -577,6 +562,66 @@ func (r EventListResponseEventMessagePartRemovedType) IsKnown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionCompacted struct {
|
||||
Properties EventListResponseEventSessionCompactedProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionCompactedType `json:"type,required"`
|
||||
JSON eventListResponseEventSessionCompactedJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionCompactedJSON contains the JSON metadata for the
|
||||
// struct [EventListResponseEventSessionCompacted]
|
||||
type eventListResponseEventSessionCompactedJSON struct {
|
||||
Properties apijson.Field
|
||||
Type apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionCompacted) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionCompactedJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
func (r EventListResponseEventSessionCompacted) implementsEventListResponse() {}
|
||||
|
||||
type EventListResponseEventSessionCompactedProperties struct {
|
||||
SessionID string `json:"sessionID,required"`
|
||||
JSON eventListResponseEventSessionCompactedPropertiesJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionCompactedPropertiesJSON contains the JSON metadata
|
||||
// for the struct [EventListResponseEventSessionCompactedProperties]
|
||||
type eventListResponseEventSessionCompactedPropertiesJSON struct {
|
||||
SessionID apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionCompactedProperties) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionCompactedPropertiesJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionCompactedType string
|
||||
|
||||
const (
|
||||
EventListResponseEventSessionCompactedTypeSessionCompacted EventListResponseEventSessionCompactedType = "session.compacted"
|
||||
)
|
||||
|
||||
func (r EventListResponseEventSessionCompactedType) IsKnown() bool {
|
||||
switch r {
|
||||
case EventListResponseEventSessionCompactedTypeSessionCompacted:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventPermissionUpdated struct {
|
||||
Properties Permission `json:"properties,required"`
|
||||
Type EventListResponseEventPermissionUpdatedType `json:"type,required"`
|
||||
@@ -740,6 +785,66 @@ func (r EventListResponseEventFileEditedType) IsKnown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionIdle struct {
|
||||
Properties EventListResponseEventSessionIdleProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionIdleType `json:"type,required"`
|
||||
JSON eventListResponseEventSessionIdleJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionIdleJSON contains the JSON metadata for the struct
|
||||
// [EventListResponseEventSessionIdle]
|
||||
type eventListResponseEventSessionIdleJSON struct {
|
||||
Properties apijson.Field
|
||||
Type apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionIdle) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionIdleJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
func (r EventListResponseEventSessionIdle) implementsEventListResponse() {}
|
||||
|
||||
type EventListResponseEventSessionIdleProperties struct {
|
||||
SessionID string `json:"sessionID,required"`
|
||||
JSON eventListResponseEventSessionIdlePropertiesJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionIdlePropertiesJSON contains the JSON metadata for
|
||||
// the struct [EventListResponseEventSessionIdleProperties]
|
||||
type eventListResponseEventSessionIdlePropertiesJSON struct {
|
||||
SessionID apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionIdleProperties) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionIdlePropertiesJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionIdleType string
|
||||
|
||||
const (
|
||||
EventListResponseEventSessionIdleTypeSessionIdle EventListResponseEventSessionIdleType = "session.idle"
|
||||
)
|
||||
|
||||
func (r EventListResponseEventSessionIdleType) IsKnown() bool {
|
||||
switch r {
|
||||
case EventListResponseEventSessionIdleTypeSessionIdle:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionUpdated struct {
|
||||
Properties EventListResponseEventSessionUpdatedProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionUpdatedType `json:"type,required"`
|
||||
@@ -860,66 +965,6 @@ func (r EventListResponseEventSessionDeletedType) IsKnown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionIdle struct {
|
||||
Properties EventListResponseEventSessionIdleProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionIdleType `json:"type,required"`
|
||||
JSON eventListResponseEventSessionIdleJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionIdleJSON contains the JSON metadata for the struct
|
||||
// [EventListResponseEventSessionIdle]
|
||||
type eventListResponseEventSessionIdleJSON struct {
|
||||
Properties apijson.Field
|
||||
Type apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionIdle) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionIdleJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
func (r EventListResponseEventSessionIdle) implementsEventListResponse() {}
|
||||
|
||||
type EventListResponseEventSessionIdleProperties struct {
|
||||
SessionID string `json:"sessionID,required"`
|
||||
JSON eventListResponseEventSessionIdlePropertiesJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionIdlePropertiesJSON contains the JSON metadata for
|
||||
// the struct [EventListResponseEventSessionIdleProperties]
|
||||
type eventListResponseEventSessionIdlePropertiesJSON struct {
|
||||
SessionID apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionIdleProperties) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionIdlePropertiesJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionIdleType string
|
||||
|
||||
const (
|
||||
EventListResponseEventSessionIdleTypeSessionIdle EventListResponseEventSessionIdleType = "session.idle"
|
||||
)
|
||||
|
||||
func (r EventListResponseEventSessionIdleType) IsKnown() bool {
|
||||
switch r {
|
||||
case EventListResponseEventSessionIdleTypeSessionIdle:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionError struct {
|
||||
Properties EventListResponseEventSessionErrorProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionErrorType `json:"type,required"`
|
||||
@@ -970,7 +1015,7 @@ func (r eventListResponseEventSessionErrorPropertiesJSON) RawJSON() string {
|
||||
|
||||
type EventListResponseEventSessionErrorPropertiesError struct {
|
||||
// This field can have the runtime type of [shared.ProviderAuthErrorData],
|
||||
// [shared.UnknownErrorData], [interface{}].
|
||||
// [shared.UnknownErrorData], [interface{}], [shared.MessageAbortedErrorData].
|
||||
Data interface{} `json:"data,required"`
|
||||
Name EventListResponseEventSessionErrorPropertiesErrorName `json:"name,required"`
|
||||
JSON eventListResponseEventSessionErrorPropertiesErrorJSON `json:"-"`
|
||||
@@ -1020,26 +1065,22 @@ type EventListResponseEventSessionErrorPropertiesErrorUnion interface {
|
||||
func init() {
|
||||
apijson.RegisterUnion(
|
||||
reflect.TypeOf((*EventListResponseEventSessionErrorPropertiesErrorUnion)(nil)).Elem(),
|
||||
"name",
|
||||
"",
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.ProviderAuthError{}),
|
||||
DiscriminatorValue: "ProviderAuthError",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.ProviderAuthError{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.UnknownError{}),
|
||||
DiscriminatorValue: "UnknownError",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.UnknownError{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionErrorPropertiesErrorMessageOutputLengthError{}),
|
||||
DiscriminatorValue: "MessageOutputLengthError",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(EventListResponseEventSessionErrorPropertiesErrorMessageOutputLengthError{}),
|
||||
},
|
||||
apijson.UnionVariant{
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.MessageAbortedError{}),
|
||||
DiscriminatorValue: "MessageAbortedError",
|
||||
TypeFilter: gjson.JSON,
|
||||
Type: reflect.TypeOf(shared.MessageAbortedError{}),
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -1116,66 +1157,6 @@ func (r EventListResponseEventSessionErrorType) IsKnown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionCompacted struct {
|
||||
Properties EventListResponseEventSessionCompactedProperties `json:"properties,required"`
|
||||
Type EventListResponseEventSessionCompactedType `json:"type,required"`
|
||||
JSON eventListResponseEventSessionCompactedJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionCompactedJSON contains the JSON metadata for the
|
||||
// struct [EventListResponseEventSessionCompacted]
|
||||
type eventListResponseEventSessionCompactedJSON struct {
|
||||
Properties apijson.Field
|
||||
Type apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionCompacted) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionCompactedJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
func (r EventListResponseEventSessionCompacted) implementsEventListResponse() {}
|
||||
|
||||
type EventListResponseEventSessionCompactedProperties struct {
|
||||
SessionID string `json:"sessionID,required"`
|
||||
JSON eventListResponseEventSessionCompactedPropertiesJSON `json:"-"`
|
||||
}
|
||||
|
||||
// eventListResponseEventSessionCompactedPropertiesJSON contains the JSON metadata
|
||||
// for the struct [EventListResponseEventSessionCompactedProperties]
|
||||
type eventListResponseEventSessionCompactedPropertiesJSON struct {
|
||||
SessionID apijson.Field
|
||||
raw string
|
||||
ExtraFields map[string]apijson.Field
|
||||
}
|
||||
|
||||
func (r *EventListResponseEventSessionCompactedProperties) UnmarshalJSON(data []byte) (err error) {
|
||||
return apijson.UnmarshalRoot(data, r)
|
||||
}
|
||||
|
||||
func (r eventListResponseEventSessionCompactedPropertiesJSON) RawJSON() string {
|
||||
return r.raw
|
||||
}
|
||||
|
||||
type EventListResponseEventSessionCompactedType string
|
||||
|
||||
const (
|
||||
EventListResponseEventSessionCompactedTypeSessionCompacted EventListResponseEventSessionCompactedType = "session.compacted"
|
||||
)
|
||||
|
||||
func (r EventListResponseEventSessionCompactedType) IsKnown() bool {
|
||||
switch r {
|
||||
case EventListResponseEventSessionCompactedTypeSessionCompacted:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EventListResponseEventServerConnected struct {
|
||||
Properties interface{} `json:"properties,required"`
|
||||
Type EventListResponseEventServerConnectedType `json:"type,required"`
|
||||
@@ -1224,20 +1205,20 @@ const (
|
||||
EventListResponseTypeMessageRemoved EventListResponseType = "message.removed"
|
||||
EventListResponseTypeMessagePartUpdated EventListResponseType = "message.part.updated"
|
||||
EventListResponseTypeMessagePartRemoved EventListResponseType = "message.part.removed"
|
||||
EventListResponseTypeSessionCompacted EventListResponseType = "session.compacted"
|
||||
EventListResponseTypePermissionUpdated EventListResponseType = "permission.updated"
|
||||
EventListResponseTypePermissionReplied EventListResponseType = "permission.replied"
|
||||
EventListResponseTypeFileEdited EventListResponseType = "file.edited"
|
||||
EventListResponseTypeSessionIdle EventListResponseType = "session.idle"
|
||||
EventListResponseTypeSessionUpdated EventListResponseType = "session.updated"
|
||||
EventListResponseTypeSessionDeleted EventListResponseType = "session.deleted"
|
||||
EventListResponseTypeSessionIdle EventListResponseType = "session.idle"
|
||||
EventListResponseTypeSessionError EventListResponseType = "session.error"
|
||||
EventListResponseTypeSessionCompacted EventListResponseType = "session.compacted"
|
||||
EventListResponseTypeServerConnected EventListResponseType = "server.connected"
|
||||
)
|
||||
|
||||
func (r EventListResponseType) IsKnown() bool {
|
||||
switch r {
|
||||
case EventListResponseTypeInstallationUpdated, EventListResponseTypeLspClientDiagnostics, EventListResponseTypeMessageUpdated, EventListResponseTypeMessageRemoved, EventListResponseTypeMessagePartUpdated, EventListResponseTypeMessagePartRemoved, EventListResponseTypePermissionUpdated, EventListResponseTypePermissionReplied, EventListResponseTypeFileEdited, EventListResponseTypeSessionUpdated, EventListResponseTypeSessionDeleted, EventListResponseTypeSessionIdle, EventListResponseTypeSessionError, EventListResponseTypeSessionCompacted, EventListResponseTypeServerConnected:
|
||||
case EventListResponseTypeInstallationUpdated, EventListResponseTypeLspClientDiagnostics, EventListResponseTypeMessageUpdated, EventListResponseTypeMessageRemoved, EventListResponseTypeMessagePartUpdated, EventListResponseTypeMessagePartRemoved, EventListResponseTypeSessionCompacted, EventListResponseTypePermissionUpdated, EventListResponseTypePermissionReplied, EventListResponseTypeFileEdited, EventListResponseTypeSessionIdle, EventListResponseTypeSessionUpdated, EventListResponseTypeSessionDeleted, EventListResponseTypeSessionError, EventListResponseTypeServerConnected:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
package internal
|
||||
|
||||
const PackageVersion = "0.9.0" // x-release-please-version
|
||||
const PackageVersion = "0.13.0" // x-release-please-version
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user