diff --git a/bun.lock b/bun.lock index b52e9112..7219ac32 100644 --- a/bun.lock +++ b/bun.lock @@ -7,7 +7,7 @@ "pulumi-stripe": "0.0.24", }, "devDependencies": { - "prettier": "3.5.3", + "prettier": "3.6.2", "sst": "3.17.13", }, }, @@ -26,7 +26,7 @@ }, "cloud/core": { "name": "@opencode/cloud-core", - "version": "0.7.6", + "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.7.6", + "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.7.6", + "version": "0.8.0", "dependencies": { "@opencode/cloud-core": "workspace:*", "tsx": "4.20.5", @@ -81,7 +81,7 @@ }, "packages/function": { "name": "@opencode/function", - "version": "0.7.6", + "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.7.6", + "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.7.6", + "version": "0.8.0", "dependencies": { "@opencode-ai/sdk": "workspace:*", }, @@ -157,7 +157,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "0.7.6", + "version": "0.8.0", "dependencies": { "@hey-api/openapi-ts": "0.81.0", }, @@ -169,7 +169,7 @@ }, "packages/web": { "name": "@opencode/web", - "version": "0.7.6", + "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=="], @@ -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=="], diff --git a/cloud/core/src/util/fn.ts b/cloud/core/src/util/fn.ts index 52df65e2..9efe4622 100644 --- a/cloud/core/src/util/fn.ts +++ b/cloud/core/src/util/fn.ts @@ -1,11 +1,11 @@ import { z } from "zod" -export function fn(schema: T, cb: (input: z.output) => Result) { - const result = (input: z.input) => { +export function fn(schema: T, cb: (input: z.infer) => Result) { + const result = (input: z.infer) => { const parsed = schema.parse(input) return cb(parsed) } - result.force = (input: z.input) => cb(input) + result.force = (input: z.infer) => cb(input) result.schema = schema return result } diff --git a/package.json b/package.json index 5d3ab0f9..1e339ead 100644 --- a/package.json +++ b/package.json @@ -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,7 +33,7 @@ "pulumi-stripe": "0.0.24" }, "devDependencies": { - "prettier": "3.5.3", + "prettier": "3.6.2", "sst": "3.17.13" }, "repository": { @@ -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" diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 14280c6c..544bb609 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -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:" } } diff --git a/packages/opencode/script/schema.ts b/packages/opencode/script/schema.ts index 27450fd3..7e450df9 100755 --- a/packages/opencode/script/schema.ts +++ b/packages/opencode/script/schema.ts @@ -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 & { allowComments?: boolean diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index 71058990..252c0bd6 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -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 diff --git a/packages/opencode/src/auth/github-copilot.ts b/packages/opencode/src/auth/github-copilot.ts index ba5274e5..c9d90cd5 100644 --- a/packages/opencode/src/auth/github-copilot.ts +++ b/packages/opencode/src/auth/github-copilot.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { Auth } from "./index" import { NamedError } from "../util/error" diff --git a/packages/opencode/src/auth/index.ts b/packages/opencode/src/auth/index.ts index a0914343..ef9846a3 100644 --- a/packages/opencode/src/auth/index.ts +++ b/packages/opencode/src/auth/index.ts @@ -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 const filepath = path.join(Global.Path.data, "auth.json") diff --git a/packages/opencode/src/bun/index.ts b/packages/opencode/src/bun/index.ts index cd413ff4..d6fb29d6 100644 --- a/packages/opencode/src/bun/index.ts +++ b/packages/opencode/src/bun/index.ts @@ -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" diff --git a/packages/opencode/src/bus/index.ts b/packages/opencode/src/bus/index.ts index be42bf80..cfd3958d 100644 --- a/packages/opencode/src/bus/index.ts +++ b/packages/opencode/src/bus/index.ts @@ -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, }), ) diff --git a/packages/opencode/src/cli/ui.ts b/packages/opencode/src/cli/ui.ts index 0fa4d1ce..bdbaed91 100644 --- a/packages/opencode/src/cli/ui.ts +++ b/packages/opencode/src/cli/ui.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { EOL } from "os" import { NamedError } from "../util/error" diff --git a/packages/opencode/src/command/index.ts b/packages/opencode/src/command/index.ts index 8ee1df2b..f879e627 100644 --- a/packages/opencode/src/command/index.ts +++ b/packages/opencode/src/command/index.ts @@ -1,4 +1,4 @@ -import z from "zod" +import z from "zod/v4" import { Config } from "../config/config" import { Instance } from "../project/instance" @@ -12,7 +12,7 @@ export namespace Command { template: z.string(), subtask: z.boolean().optional(), }) - .openapi({ + .meta({ ref: "Command", }) export type Info = z.infer diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 22ff58db..74413657 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -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", }) @@ -267,7 +267,7 @@ export namespace Config { .optional(), }) .catchall(z.any()) - .openapi({ + .meta({ ref: "AgentConfig", }) export type Agent = z.infer @@ -342,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", }) @@ -350,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 @@ -407,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(), @@ -505,7 +506,7 @@ export namespace Config { .optional(), }) .strict() - .openapi({ + .meta({ ref: "Config", }) @@ -644,7 +645,7 @@ export namespace Config { "ConfigInvalidError", z.object({ path: z.string(), - issues: z.custom().optional(), + issues: z.custom().optional(), message: z.string().optional(), }), ) diff --git a/packages/opencode/src/file/fzf.ts b/packages/opencode/src/file/fzf.ts index 3b732027..7a35351f 100644 --- a/packages/opencode/src/file/fzf.ts +++ b/packages/opencode/src/file/fzf.ts @@ -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" diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts index dda220be..40f52aa3 100644 --- a/packages/opencode/src/file/index.ts +++ b/packages/opencode/src/file/index.ts @@ -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 @@ -60,7 +60,7 @@ export namespace File { }) .optional(), }) - .openapi({ + .meta({ ref: "FileContent", }) export type Content = z.infer diff --git a/packages/opencode/src/file/ripgrep.ts b/packages/opencode/src/file/ripgrep.ts index f21cbdef..1cbf6b8a 100644 --- a/packages/opencode/src/file/ripgrep.ts +++ b/packages/opencode/src/file/ripgrep.ts @@ -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" diff --git a/packages/opencode/src/file/watch.ts b/packages/opencode/src/file/watch.ts index 587ad54d..526b29c9 100644 --- a/packages/opencode/src/file/watch.ts +++ b/packages/opencode/src/file/watch.ts @@ -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" diff --git a/packages/opencode/src/id/id.ts b/packages/opencode/src/id/id.ts index f2b961e4..ec24f30d 100644 --- a/packages/opencode/src/id/id.ts +++ b/packages/opencode/src/id/id.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { randomBytes } from "crypto" export namespace Identifier { diff --git a/packages/opencode/src/ide/index.ts b/packages/opencode/src/ide/index.ts index 300aa9f5..7ab2e7ff 100644 --- a/packages/opencode/src/ide/index.ts +++ b/packages/opencode/src/ide/index.ts @@ -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" diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 6e224abd..a45ec3ac 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -1,4 +1,3 @@ -import "zod-openapi/extend" import yargs from "yargs" import { hideBin } from "yargs/helpers" import { RunCommand } from "./cli/cmd/run" diff --git a/packages/opencode/src/installation/index.ts b/packages/opencode/src/installation/index.ts index 343d9615..b01ce5f7 100644 --- a/packages/opencode/src/installation/index.ts +++ b/packages/opencode/src/installation/index.ts @@ -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 diff --git a/packages/opencode/src/lsp/client.ts b/packages/opencode/src/lsp/client.ts index 20c11c9f..66cc8eaa 100644 --- a/packages/opencode/src/lsp/client.ts +++ b/packages/opencode/src/lsp/client.ts @@ -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" diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts index a0133b27..0cf98c86 100644 --- a/packages/opencode/src/lsp/index.ts +++ b/packages/opencode/src/lsp/index.ts @@ -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 @@ -35,7 +35,7 @@ export namespace LSP { range: Range, }), }) - .openapi({ + .meta({ ref: "Symbol", }) export type Symbol = z.infer @@ -48,7 +48,7 @@ export namespace LSP { range: Range, selectionRange: Range, }) - .openapi({ + .meta({ ref: "DocumentSymbol", }) export type DocumentSymbol = z.infer diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index 702f644d..dc90dfe5 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -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" diff --git a/packages/opencode/src/permission/index.ts b/packages/opencode/src/permission/index.ts index dd198dac..f4b17823 100644 --- a/packages/opencode/src/permission/index.ts +++ b/packages/opencode/src/permission/index.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { Bus } from "../bus" import { Log } from "../util/log" import { Identifier } from "../id/id" @@ -27,12 +27,12 @@ export namespace Permission { 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 diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts index b6dfc58b..a1f79dcc 100644 --- a/packages/opencode/src/project/project.ts +++ b/packages/opencode/src/project/project.ts @@ -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 diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index e41221c2..514203e9 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -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 @@ -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", }) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 834a5b2d..2d30a738 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -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" diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts index a9616cfd..094d0244 100644 --- a/packages/opencode/src/provider/transform.ts +++ b/packages/opencode/src/provider/transform.ts @@ -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 + } } diff --git a/packages/opencode/src/server/project.ts b/packages/opencode/src/server/project.ts index a89061b7..616a2f7e 100644 --- a/packages/opencode/src/server/project.ts +++ b/packages/opencode/src/server/project.ts @@ -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" diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index c2c08e3b..19727e84 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -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" @@ -39,7 +38,7 @@ const ERRORS = { .object({ data: z.record(z.string(), z.any()), }) - .openapi({ + .meta({ ref: "Error", }), ), @@ -59,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({ @@ -67,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({})), @@ -115,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", @@ -129,6 +127,7 @@ export namespace Server { }, }), ) + .use(validator("query", z.object({ directory: z.string().optional() }))) .route("/project", ProjectRoute) .get( "/event", @@ -141,7 +140,7 @@ export namespace Server { content: { "text/event-stream": { schema: resolver( - Bus.payloads().openapi({ + Bus.payloads().meta({ ref: "Event", }), ), @@ -211,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) @@ -227,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" })), }, }, }, @@ -257,9 +256,9 @@ export namespace Server { description: z.string(), parameters: z.any(), }) - .openapi({ ref: "ToolListItem" }), + .meta({ ref: "ToolListItem" }), ) - .openapi({ ref: "ToolList" }), + .meta({ ref: "ToolList" }), ), }, }, @@ -267,7 +266,7 @@ export namespace Server { ...ERRORS, }, }), - zValidator( + validator( "query", z.object({ provider: z.string(), @@ -305,7 +304,7 @@ export namespace Server { worktree: z.string(), directory: z.string(), }) - .openapi({ + .meta({ ref: "Path", }), ), @@ -361,7 +360,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -389,7 +388,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -418,7 +417,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "json", z .object({ @@ -449,7 +448,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -476,13 +475,13 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), }), ), - zValidator( + validator( "json", z.object({ title: z.string().optional(), @@ -517,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(), @@ -554,7 +553,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -580,7 +579,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -609,7 +608,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -638,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(), @@ -674,10 +673,10 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ - id: z.string().openapi({ description: "Session ID" }), + id: z.string().meta({ description: "Session ID" }), }), ), async (c) => { @@ -706,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) => { @@ -740,13 +739,13 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ - id: z.string().openapi({ description: "Session ID" }), + id: z.string().meta({ description: "Session ID" }), }), ), - zValidator("json", SessionPrompt.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") @@ -775,13 +774,13 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ - id: z.string().openapi({ description: "Session ID" }), + id: z.string().meta({ description: "Session ID" }), }), ), - zValidator("json", SessionPrompt.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") @@ -805,13 +804,13 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ - id: z.string().openapi({ description: "Session ID" }), + id: z.string().meta({ description: "Session ID" }), }), ), - zValidator("json", SessionPrompt.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") @@ -835,13 +834,13 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), }), ), - zValidator("json", SessionRevert.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")) @@ -865,7 +864,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "param", z.object({ id: z.string(), @@ -892,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 @@ -974,7 +973,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "query", z.object({ pattern: z.string(), @@ -1006,7 +1005,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "query", z.object({ query: z.string(), @@ -1038,7 +1037,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "query", z.object({ query: z.string(), @@ -1066,7 +1065,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "query", z.object({ path: z.string(), @@ -1094,7 +1093,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "query", z.object({ path: z.string(), @@ -1143,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) => { @@ -1214,7 +1213,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "json", z.object({ text: z.string(), @@ -1346,7 +1345,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "json", z.object({ command: z.string(), @@ -1370,7 +1369,7 @@ export namespace Server { }, }, }), - zValidator( + validator( "json", z.object({ title: z.string().optional(), @@ -1398,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") diff --git a/packages/opencode/src/session/compaction.ts b/packages/opencode/src/session/compaction.ts index 6af398f1..3f4d4b83 100644 --- a/packages/opencode/src/session/compaction.ts +++ b/packages/opencode/src/session/compaction.ts @@ -7,7 +7,7 @@ import { defer } from "../util/defer" import { MessageV2 } from "./message-v2" import { SystemPrompt } from "./system" import { Bus } from "../bus" -import z from "zod" +import z from "zod/v4" import type { ModelsDev } from "../provider/models" import { SessionPrompt } from "./prompt" import { Flag } from "../flag/flag" diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index 92f0afb0..18bb7aef 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -1,5 +1,5 @@ import { Decimal } from "decimal.js" -import { z } from "zod" +import z from "zod/v4" import { type LanguageModelUsage, type ProviderMetadata } from "ai" import PROMPT_INITIALIZE from "../session/prompt/initialize.txt" @@ -56,7 +56,7 @@ export namespace Session { }) .optional(), }) - .openapi({ + .meta({ ref: "Session", }) export type Info = z.output @@ -66,7 +66,7 @@ export namespace Session { secret: z.string(), url: z.string(), }) - .openapi({ + .meta({ ref: "SessionShare", }) export type ShareInfo = z.output diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts index c031dbe7..2d850e0a 100644 --- a/packages/opencode/src/session/message-v2.ts +++ b/packages/opencode/src/session/message-v2.ts @@ -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 @@ -45,17 +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 @@ -63,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 export const ToolState = z .discriminatedUnion("status", [ToolStatePending, ToolStateRunning, ToolStateCompleted, ToolStateError]) - .openapi({ + .meta({ ref: "ToolState", }) @@ -91,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 @@ -100,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 @@ -115,7 +115,7 @@ export namespace MessageV2 { end: z.number().optional(), }) .optional(), - }).openapi({ + }).meta({ ref: "TextPart", }) export type TextPart = z.infer @@ -123,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 @@ -138,7 +138,7 @@ export namespace MessageV2 { callID: z.string(), tool: z.string(), state: ToolState, - }).openapi({ + }).meta({ ref: "ToolPart", }) export type ToolPart = z.infer @@ -150,7 +150,7 @@ export namespace MessageV2 { start: z.number().int(), end: z.number().int(), }) - .openapi({ + .meta({ ref: "FilePartSourceText", }), }) @@ -158,7 +158,7 @@ export namespace MessageV2 { export const FileSource = FilePartSourceBase.extend({ type: z.literal("file"), path: z.string(), - }).openapi({ + }).meta({ ref: "FileSource", }) @@ -168,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", }) @@ -182,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 @@ -197,14 +197,14 @@ export namespace MessageV2 { end: z.number().int(), }) .optional(), - }).openapi({ + }).meta({ ref: "AgentPart", }) export type AgentPart = z.infer export const StepStartPart = PartBase.extend({ type: z.literal("step-start"), - }).openapi({ + }).meta({ ref: "StepStartPart", }) export type StepStartPart = z.infer @@ -221,7 +221,7 @@ export namespace MessageV2 { write: z.number(), }), }), - }).openapi({ + }).meta({ ref: "StepFinishPart", }) export type StepFinishPart = z.infer @@ -236,7 +236,7 @@ export namespace MessageV2 { time: z.object({ created: z.number(), }), - }).openapi({ + }).meta({ ref: "UserMessage", }) export type User = z.infer @@ -253,7 +253,7 @@ export namespace MessageV2 { PatchPart, AgentPart, ]) - .openapi({ + .meta({ ref: "Part", }) export type Part = z.infer @@ -291,12 +291,12 @@ export namespace MessageV2 { write: z.number(), }), }), - }).openapi({ + }).meta({ ref: "AssistantMessage", }) export type Assistant = z.infer - 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 diff --git a/packages/opencode/src/session/message.ts b/packages/opencode/src/session/message.ts index e71c35c5..f8b5115f 100644 --- a/packages/opencode/src/session/message.ts +++ b/packages/opencode/src/session/message.ts @@ -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>(), }) - .openapi({ + .meta({ ref: "ToolCall", }) export type ToolCall = z.infer @@ -32,7 +32,7 @@ export namespace Message { toolName: z.string(), args: z.custom>(), }) - .openapi({ + .meta({ ref: "ToolPartialCall", }) export type ToolPartialCall = z.infer @@ -46,12 +46,12 @@ export namespace Message { args: z.custom>(), result: z.string(), }) - .openapi({ + .meta({ ref: "ToolResult", }) export type ToolResult = z.infer - 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 @@ -61,7 +61,7 @@ export namespace Message { type: z.literal("text"), text: z.string(), }) - .openapi({ + .meta({ ref: "TextPart", }) export type TextPart = z.infer @@ -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 @@ -82,7 +82,7 @@ export namespace Message { type: z.literal("tool-invocation"), toolInvocation: ToolInvocation, }) - .openapi({ + .meta({ ref: "ToolInvocationPart", }) export type ToolInvocationPart = z.infer @@ -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 @@ -107,7 +107,7 @@ export namespace Message { filename: z.string().optional(), url: z.string(), }) - .openapi({ + .meta({ ref: "FilePart", }) export type FilePart = z.infer @@ -116,14 +116,14 @@ export namespace Message { .object({ type: z.literal("step-start"), }) - .openapi({ + .meta({ ref: "StepStartPart", }) export type StepStartPart = z.infer export const MessagePart = z .discriminatedUnion("type", [TextPart, ReasoningPart, ToolInvocationPart, SourceUrlPart, FilePart, StepStartPart]) - .openapi({ + .meta({ ref: "MessagePart", }) export type MessagePart = z.infer @@ -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 diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index f6f0ffb9..25e0c836 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1,7 +1,7 @@ import path from "path" import os from "os" import fs from "fs/promises" -import z, { ZodSchema } from "zod" +import z from "zod/v4" import { Identifier } from "../id/id" import { MessageV2 } from "./message-v2" import { Log } from "../util/log" @@ -19,6 +19,7 @@ import { type StreamTextResult, LoadAPIKeyError, stepCountIs, + jsonSchema, } from "ai" import { SessionCompaction } from "./compaction" import { Instance } from "../project/instance" @@ -95,7 +96,7 @@ export namespace SessionPrompt { .optional(), agent: z.string().optional(), system: z.string().optional(), - tools: z.record(z.boolean()).optional(), + tools: z.record(z.string(), z.boolean()).optional(), parts: z.array( z.discriminatedUnion("type", [ MessageV2.TextPart.omit({ @@ -105,7 +106,7 @@ export namespace SessionPrompt { .partial({ id: true, }) - .openapi({ + .meta({ ref: "TextPartInput", }), MessageV2.FilePart.omit({ @@ -115,7 +116,7 @@ export namespace SessionPrompt { .partial({ id: true, }) - .openapi({ + .meta({ ref: "FilePartInput", }), MessageV2.AgentPart.omit({ @@ -125,7 +126,7 @@ export namespace SessionPrompt { .partial({ id: true, }) - .openapi({ + .meta({ ref: "AgentPartInput", }), ]), @@ -393,10 +394,11 @@ export namespace SessionPrompt { ) for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) { if (Wildcard.all(item.id, enabledTools) === false) continue + const schema = ProviderTransform.schema(input.providerID, input.modelID, z.toJSONSchema(item.parameters)) tools[item.id] = tool({ id: item.id as any, description: item.description, - inputSchema: item.parameters as ZodSchema, + inputSchema: jsonSchema(schema as any), async execute(args, options) { await Plugin.trigger( "tool.execute.before", diff --git a/packages/opencode/src/session/revert.ts b/packages/opencode/src/session/revert.ts index 694834c4..052e582f 100644 --- a/packages/opencode/src/session/revert.ts +++ b/packages/opencode/src/session/revert.ts @@ -1,4 +1,4 @@ -import z from "zod" +import z from "zod/v4" import { Identifier } from "../id/id" import { Snapshot } from "../snapshot" import { MessageV2 } from "./message-v2" diff --git a/packages/opencode/src/snapshot/index.ts b/packages/opencode/src/snapshot/index.ts index 4152498d..f301c81f 100644 --- a/packages/opencode/src/snapshot/index.ts +++ b/packages/opencode/src/snapshot/index.ts @@ -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" diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts index 8149360f..ddf8227e 100644 --- a/packages/opencode/src/tool/bash.ts +++ b/packages/opencode/src/tool/bash.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { exec } from "child_process" import { Tool } from "./tool" diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts index 7218575f..b7f43126 100644 --- a/packages/opencode/src/tool/edit.ts +++ b/packages/opencode/src/tool/edit.ts @@ -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" diff --git a/packages/opencode/src/tool/glob.ts b/packages/opencode/src/tool/glob.ts index 9534f0af..dbbe8868 100644 --- a/packages/opencode/src/tool/glob.ts +++ b/packages/opencode/src/tool/glob.ts @@ -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" diff --git a/packages/opencode/src/tool/grep.ts b/packages/opencode/src/tool/grep.ts index a8a42a82..215659ce 100644 --- a/packages/opencode/src/tool/grep.ts +++ b/packages/opencode/src/tool/grep.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { Tool } from "./tool" import { Ripgrep } from "../file/ripgrep" diff --git a/packages/opencode/src/tool/invalid.ts b/packages/opencode/src/tool/invalid.ts index 4695f1b7..318c4b13 100644 --- a/packages/opencode/src/tool/invalid.ts +++ b/packages/opencode/src/tool/invalid.ts @@ -1,4 +1,4 @@ -import { z } from "zod" +import z from "zod/v4" import { Tool } from "./tool" export const InvalidTool = Tool.define("invalid", { diff --git a/packages/opencode/src/tool/ls.ts b/packages/opencode/src/tool/ls.ts index 5a8173ef..819e6fde 100644 --- a/packages/opencode/src/tool/ls.ts +++ b/packages/opencode/src/tool/ls.ts @@ -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" diff --git a/packages/opencode/src/tool/lsp-diagnostics.ts b/packages/opencode/src/tool/lsp-diagnostics.ts index b69e8485..6ea1b059 100644 --- a/packages/opencode/src/tool/lsp-diagnostics.ts +++ b/packages/opencode/src/tool/lsp-diagnostics.ts @@ -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" diff --git a/packages/opencode/src/tool/lsp-hover.ts b/packages/opencode/src/tool/lsp-hover.ts index b33a4e80..2999d17a 100644 --- a/packages/opencode/src/tool/lsp-hover.ts +++ b/packages/opencode/src/tool/lsp-hover.ts @@ -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" diff --git a/packages/opencode/src/tool/multiedit.ts b/packages/opencode/src/tool/multiedit.ts index 8ae81ab9..2a1b2fbb 100644 --- a/packages/opencode/src/tool/multiedit.ts +++ b/packages/opencode/src/tool/multiedit.ts @@ -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" diff --git a/packages/opencode/src/tool/patch.ts b/packages/opencode/src/tool/patch.ts index 77fac225..9397f114 100644 --- a/packages/opencode/src/tool/patch.ts +++ b/packages/opencode/src/tool/patch.ts @@ -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" diff --git a/packages/opencode/src/tool/read.ts b/packages/opencode/src/tool/read.ts index 2aaaf7a4..2ed3accb 100644 --- a/packages/opencode/src/tool/read.ts +++ b/packages/opencode/src/tool/read.ts @@ -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" diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index f4ca584c..379ca542 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -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 = {} - 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: - ;(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 = {} - - 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 - } } diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts index a16d94b8..163b5a2f 100644 --- a/packages/opencode/src/tool/task.ts +++ b/packages/opencode/src/tool/task.ts @@ -1,6 +1,6 @@ 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" diff --git a/packages/opencode/src/tool/todo.ts b/packages/opencode/src/tool/todo.ts index 96404458..9b4efddb 100644 --- a/packages/opencode/src/tool/todo.ts +++ b/packages/opencode/src/tool/todo.ts @@ -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" diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts index 871a10c8..6e2b9511 100644 --- a/packages/opencode/src/tool/tool.ts +++ b/packages/opencode/src/tool/tool.ts @@ -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 { + export interface Info { id: string init: () => Promise<{ description: string parameters: Parameters execute( - args: StandardSchemaV1.InferOutput, + args: z.infer, ctx: Context, ): Promise<{ title: string @@ -29,7 +29,7 @@ export namespace Tool { }> } - export function define( + export function define( id: string, init: Info["init"] | Awaited["init"]>>, ): Info { diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index 621421fe..4d184941 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -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" diff --git a/packages/opencode/src/tool/write.ts b/packages/opencode/src/tool/write.ts index dbd6e294..aa79c9bf 100644 --- a/packages/opencode/src/tool/write.ts +++ b/packages/opencode/src/tool/write.ts @@ -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" diff --git a/packages/opencode/src/util/error.ts b/packages/opencode/src/util/error.ts index 53b434c6..f74947b1 100644 --- a/packages/opencode/src/util/error.ts +++ b/packages/opencode/src/util/error.ts @@ -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: Name, data: Data) { + static create(name: Name, data: Data) { const schema = z .object({ name: z.literal(name), data, }) - .openapi({ + .meta({ ref: name, }) const result = class extends NamedError { diff --git a/packages/opencode/src/util/log.ts b/packages/opencode/src/util/log.ts index b4cdd920..5844a114 100644 --- a/packages/opencode/src/util/log.ts +++ b/packages/opencode/src/util/log.ts @@ -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 const levelPriority: Record = { diff --git a/packages/opencode/test/tool/register.test.ts b/packages/opencode/test/tool/register.test.ts index 2a72c119..834d1898 100644 --- a/packages/opencode/test/tool/register.test.ts +++ b/packages/opencode/test/tool/register.test.ts @@ -1,4 +1,3 @@ -import "zod-openapi/extend" import { describe, expect, test } from "bun:test" import path from "path" import os from "os" diff --git a/packages/sdk/go/.release-please-manifest.json b/packages/sdk/go/.release-please-manifest.json index 76d5538a..ed21d28c 100644 --- a/packages/sdk/go/.release-please-manifest.json +++ b/packages/sdk/go/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.0" + ".": "0.13.0" } diff --git a/packages/sdk/go/.stats.yml b/packages/sdk/go/.stats.yml index db940705..7f4a9c11 100644 --- a/packages/sdk/go/.stats.yml +++ b/packages/sdk/go/.stats.yml @@ -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 diff --git a/packages/sdk/go/CHANGELOG.md b/packages/sdk/go/CHANGELOG.md index fad7e683..01801706 100644 --- a/packages/sdk/go/CHANGELOG.md +++ b/packages/sdk/go/CHANGELOG.md @@ -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) diff --git a/packages/sdk/go/README.md b/packages/sdk/go/README.md index 0fe3d32b..2c48f53c 100644 --- a/packages/sdk/go/README.md +++ b/packages/sdk/go/README.md @@ -24,7 +24,7 @@ Or to pin the 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' ``` diff --git a/packages/sdk/go/aliases.go b/packages/sdk/go/aliases.go index 6ab36d04..50beeae9 100644 --- a/packages/sdk/go/aliases.go +++ b/packages/sdk/go/aliases.go @@ -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 diff --git a/packages/sdk/go/command.go b/packages/sdk/go/command.go index 2638fc60..44e3beb1 100644 --- a/packages/sdk/go/command.go +++ b/packages/sdk/go/command.go @@ -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 } diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go index b79bcb2e..d469bdff 100644 --- a/packages/sdk/go/config.go +++ b/packages/sdk/go/config.go @@ -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:"-"` } diff --git a/packages/sdk/go/event.go b/packages/sdk/go/event.go index 00ba202c..5d3bffcc 100644 --- a/packages/sdk/go/event.go +++ b/packages/sdk/go/event.go @@ -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 diff --git a/packages/sdk/go/internal/version.go b/packages/sdk/go/internal/version.go index 0e818c5b..871f0965 100644 --- a/packages/sdk/go/internal/version.go +++ b/packages/sdk/go/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.9.0" // x-release-please-version +const PackageVersion = "0.13.0" // x-release-please-version diff --git a/packages/sdk/go/session.go b/packages/sdk/go/session.go index 6696e0fa..260724e9 100644 --- a/packages/sdk/go/session.go +++ b/packages/sdk/go/session.go @@ -518,7 +518,7 @@ func (r assistantMessageTokensCacheJSON) RawJSON() string { type AssistantMessageError 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 AssistantMessageErrorName `json:"name,required"` JSON assistantMessageErrorJSON `json:"-"` @@ -566,26 +566,22 @@ type AssistantMessageErrorUnion interface { func init() { apijson.RegisterUnion( reflect.TypeOf((*AssistantMessageErrorUnion)(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(AssistantMessageErrorMessageOutputLengthError{}), - DiscriminatorValue: "MessageOutputLengthError", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(AssistantMessageErrorMessageOutputLengthError{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(shared.MessageAbortedError{}), - DiscriminatorValue: "MessageAbortedError", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(shared.MessageAbortedError{}), }, ) } @@ -778,16 +774,14 @@ type FilePartSourceUnion interface { func init() { apijson.RegisterUnion( reflect.TypeOf((*FilePartSourceUnion)(nil)).Elem(), - "type", + "", apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FileSource{}), - DiscriminatorValue: "file", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(FileSource{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(SymbolSource{}), - DiscriminatorValue: "symbol", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(SymbolSource{}), }, ) } @@ -986,16 +980,14 @@ type MessageUnion interface { func init() { apijson.RegisterUnion( reflect.TypeOf((*MessageUnion)(nil)).Elem(), - "role", + "", apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(UserMessage{}), - DiscriminatorValue: "user", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(UserMessage{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AssistantMessage{}), - DiscriminatorValue: "assistant", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(AssistantMessage{}), }, ) } @@ -1107,51 +1099,42 @@ type PartUnion interface { func init() { apijson.RegisterUnion( reflect.TypeOf((*PartUnion)(nil)).Elem(), - "type", + "", apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(TextPart{}), - DiscriminatorValue: "text", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(TextPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ReasoningPart{}), - DiscriminatorValue: "reasoning", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ReasoningPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(FilePart{}), - DiscriminatorValue: "file", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(FilePart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolPart{}), - DiscriminatorValue: "tool", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(StepStartPart{}), - DiscriminatorValue: "step-start", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(StepStartPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(StepFinishPart{}), - DiscriminatorValue: "step-finish", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(StepFinishPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(SnapshotPart{}), - DiscriminatorValue: "snapshot", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(SnapshotPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(PartPatchPart{}), - DiscriminatorValue: "patch", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(PartPatchPart{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(AgentPart{}), - DiscriminatorValue: "agent", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(AgentPart{}), }, ) } @@ -1941,26 +1924,22 @@ type ToolPartStateUnion interface { func init() { apijson.RegisterUnion( reflect.TypeOf((*ToolPartStateUnion)(nil)).Elem(), - "status", + "", apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolStatePending{}), - DiscriminatorValue: "pending", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolStatePending{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolStateRunning{}), - DiscriminatorValue: "running", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolStateRunning{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolStateCompleted{}), - DiscriminatorValue: "completed", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolStateCompleted{}), }, apijson.UnionVariant{ - TypeFilter: gjson.JSON, - Type: reflect.TypeOf(ToolStateError{}), - DiscriminatorValue: "error", + TypeFilter: gjson.JSON, + Type: reflect.TypeOf(ToolStateError{}), }, ) } @@ -2044,9 +2023,10 @@ func (r ToolStateCompletedStatus) IsKnown() bool { } type ToolStateCompletedTime struct { - End float64 `json:"end,required"` - Start float64 `json:"start,required"` - JSON toolStateCompletedTimeJSON `json:"-"` + End float64 `json:"end,required"` + Start float64 `json:"start,required"` + Compacted float64 `json:"compacted"` + JSON toolStateCompletedTimeJSON `json:"-"` } // toolStateCompletedTimeJSON contains the JSON metadata for the struct @@ -2054,6 +2034,7 @@ type ToolStateCompletedTime struct { type toolStateCompletedTimeJSON struct { End apijson.Field Start apijson.Field + Compacted apijson.Field raw string ExtraFields map[string]apijson.Field } @@ -2171,9 +2152,9 @@ func (r ToolStatePendingStatus) IsKnown() bool { } type ToolStateRunning struct { + Input interface{} `json:"input,required"` Status ToolStateRunningStatus `json:"status,required"` Time ToolStateRunningTime `json:"time,required"` - Input interface{} `json:"input"` Metadata map[string]interface{} `json:"metadata"` Title string `json:"title"` JSON toolStateRunningJSON `json:"-"` @@ -2182,9 +2163,9 @@ type ToolStateRunning struct { // toolStateRunningJSON contains the JSON metadata for the struct // [ToolStateRunning] type toolStateRunningJSON struct { + Input apijson.Field Status apijson.Field Time apijson.Field - Input apijson.Field Metadata apijson.Field Title apijson.Field raw string diff --git a/packages/sdk/go/session_test.go b/packages/sdk/go/session_test.go index f4cbc04b..61404d8b 100644 --- a/packages/sdk/go/session_test.go +++ b/packages/sdk/go/session_test.go @@ -196,7 +196,7 @@ func TestSessionCommandWithOptionalParams(t *testing.T) { Command: opencode.F("command"), Directory: opencode.F("directory"), Agent: opencode.F("agent"), - MessageID: opencode.F("msg"), + MessageID: opencode.F("msgJ!"), Model: opencode.F("model"), }, ) @@ -353,7 +353,7 @@ func TestSessionPromptWithOptionalParams(t *testing.T) { }}), Directory: opencode.F("directory"), Agent: opencode.F("agent"), - MessageID: opencode.F("msg"), + MessageID: opencode.F("msgJ!"), Model: opencode.F(opencode.SessionPromptParamsModel{ ModelID: opencode.F("modelID"), ProviderID: opencode.F("providerID"), @@ -389,9 +389,9 @@ func TestSessionRevertWithOptionalParams(t *testing.T) { context.TODO(), "id", opencode.SessionRevertParams{ - MessageID: opencode.F("msg"), + MessageID: opencode.F("msgJ!"), Directory: opencode.F("directory"), - PartID: opencode.F("prt"), + PartID: opencode.F("prtJ!"), }, ) if err != nil { diff --git a/packages/sdk/go/shared/shared.go b/packages/sdk/go/shared/shared.go index 58baf3d9..f2c6db0d 100644 --- a/packages/sdk/go/shared/shared.go +++ b/packages/sdk/go/shared/shared.go @@ -7,7 +7,7 @@ import ( ) type MessageAbortedError struct { - Data interface{} `json:"data,required"` + Data MessageAbortedErrorData `json:"data,required"` Name MessageAbortedErrorName `json:"name,required"` JSON messageAbortedErrorJSON `json:"-"` } @@ -33,6 +33,27 @@ func (r MessageAbortedError) ImplementsEventListResponseEventSessionErrorPropert func (r MessageAbortedError) ImplementsAssistantMessageError() {} +type MessageAbortedErrorData struct { + Message string `json:"message,required"` + JSON messageAbortedErrorDataJSON `json:"-"` +} + +// messageAbortedErrorDataJSON contains the JSON metadata for the struct +// [MessageAbortedErrorData] +type messageAbortedErrorDataJSON struct { + Message apijson.Field + raw string + ExtraFields map[string]apijson.Field +} + +func (r *MessageAbortedErrorData) UnmarshalJSON(data []byte) (err error) { + return apijson.UnmarshalRoot(data, r) +} + +func (r messageAbortedErrorDataJSON) RawJSON() string { + return r.raw +} + type MessageAbortedErrorName string const ( diff --git a/packages/sdk/js/src/gen/sdk.gen.ts b/packages/sdk/js/src/gen/sdk.gen.ts index ea9cfe9a..7e0f0dc8 100644 --- a/packages/sdk/js/src/gen/sdk.gen.ts +++ b/packages/sdk/js/src/gen/sdk.gen.ts @@ -58,8 +58,8 @@ import type { SessionRevertResponses, SessionUnrevertData, SessionUnrevertResponses, - PostSessionByIdPermissionsByPermissionIdData, - PostSessionByIdPermissionsByPermissionIdResponses, + PostSessionIdPermissionsPermissionIdData, + PostSessionIdPermissionsPermissionIdResponses, CommandListData, CommandListResponses, ConfigProvidersData, @@ -675,14 +675,10 @@ export class OpencodeClient extends _HeyApiClient { /** * Respond to a permission request */ - public postSessionByIdPermissionsByPermissionId( - options: Options, + public postSessionIdPermissionsPermissionId( + options: Options, ) { - return (options.client ?? this._client).post< - PostSessionByIdPermissionsByPermissionIdResponses, - unknown, - ThrowOnError - >({ + return (options.client ?? this._client).post({ url: "/session/{id}/permissions/{permissionID}", ...options, headers: { diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 864afa39..47668750 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -10,53 +10,6 @@ export type Project = { } } -export type Event = - | ({ - type: "installation.updated" - } & EventInstallationUpdated) - | ({ - type: "lsp.client.diagnostics" - } & EventLspClientDiagnostics) - | ({ - type: "message.updated" - } & EventMessageUpdated) - | ({ - type: "message.removed" - } & EventMessageRemoved) - | ({ - type: "message.part.updated" - } & EventMessagePartUpdated) - | ({ - type: "message.part.removed" - } & EventMessagePartRemoved) - | ({ - type: "session.compacted" - } & EventSessionCompacted) - | ({ - type: "permission.updated" - } & EventPermissionUpdated) - | ({ - type: "permission.replied" - } & EventPermissionReplied) - | ({ - type: "file.edited" - } & EventFileEdited) - | ({ - type: "session.idle" - } & EventSessionIdle) - | ({ - type: "session.updated" - } & EventSessionUpdated) - | ({ - type: "session.deleted" - } & EventSessionDeleted) - | ({ - type: "session.error" - } & EventSessionError) - | ({ - type: "server.connected" - } & EventServerConnected) - export type EventInstallationUpdated = { type: "installation.updated" properties: { @@ -72,21 +25,6 @@ export type EventLspClientDiagnostics = { } } -export type EventMessageUpdated = { - type: "message.updated" - properties: { - info: Message - } -} - -export type Message = - | ({ - role: "user" - } & UserMessage) - | ({ - role: "assistant" - } & AssistantMessage) - export type UserMessage = { id: string sessionID: string @@ -96,48 +34,6 @@ export type UserMessage = { } } -export type AssistantMessage = { - id: string - sessionID: string - role: "assistant" - time: { - created: number - completed?: number - } - error?: - | ({ - name: "ProviderAuthError" - } & ProviderAuthError) - | ({ - name: "UnknownError" - } & UnknownError) - | ({ - name: "MessageOutputLengthError" - } & MessageOutputLengthError) - | ({ - name: "MessageAbortedError" - } & MessageAbortedError) - system: Array - modelID: string - providerID: string - mode: string - path: { - cwd: string - root: string - } - summary?: boolean - cost: number - tokens: { - input: number - output: number - reasoning: number - cache: { - read: number - write: number - } - } -} - export type ProviderAuthError = { name: "ProviderAuthError" data: { @@ -163,7 +59,46 @@ export type MessageOutputLengthError = { export type MessageAbortedError = { name: "MessageAbortedError" data: { - [key: string]: unknown + message: string + } +} + +export type AssistantMessage = { + id: string + sessionID: string + role: "assistant" + time: { + created: number + completed?: number + } + error?: ProviderAuthError | UnknownError | MessageOutputLengthError | MessageAbortedError + system: Array + modelID: string + providerID: string + mode: string + path: { + cwd: string + root: string + } + summary?: boolean + cost: number + tokens: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } +} + +export type Message = UserMessage | AssistantMessage + +export type EventMessageUpdated = { + type: "message.updated" + properties: { + info: Message } } @@ -175,42 +110,6 @@ export type EventMessageRemoved = { } } -export type EventMessagePartUpdated = { - type: "message.part.updated" - properties: { - part: Part - } -} - -export type Part = - | ({ - type: "text" - } & TextPart) - | ({ - type: "reasoning" - } & ReasoningPart) - | ({ - type: "file" - } & FilePart) - | ({ - type: "tool" - } & ToolPart) - | ({ - type: "step-start" - } & StepStartPart) - | ({ - type: "step-finish" - } & StepFinishPart) - | ({ - type: "snapshot" - } & SnapshotPart) - | ({ - type: "patch" - } & PatchPart) - | ({ - type: "agent" - } & AgentPart) - export type TextPart = { id: string sessionID: string @@ -239,44 +138,16 @@ export type ReasoningPart = { } } -export type FilePart = { - id: string - sessionID: string - messageID: string - type: "file" - mime: string - filename?: string - url: string - source?: FilePartSource -} - -export type FilePartSource = - | ({ - type: "file" - } & FileSource) - | ({ - type: "symbol" - } & SymbolSource) - -export type FileSource = { - text: FilePartSourceText - type: "file" - path: string -} - export type FilePartSourceText = { value: string start: number end: number } -export type SymbolSource = { +export type FileSource = { text: FilePartSourceText - type: "symbol" + type: "file" path: string - range: Range - name: string - kind: number } export type Range = { @@ -290,37 +161,35 @@ export type Range = { } } -export type ToolPart = { +export type SymbolSource = { + text: FilePartSourceText + type: "symbol" + path: string + range: Range + name: string + kind: number +} + +export type FilePartSource = FileSource | SymbolSource + +export type FilePart = { id: string sessionID: string messageID: string - type: "tool" - callID: string - tool: string - state: ToolState + type: "file" + mime: string + filename?: string + url: string + source?: FilePartSource } -export type ToolState = - | ({ - status: "pending" - } & ToolStatePending) - | ({ - status: "running" - } & ToolStateRunning) - | ({ - status: "completed" - } & ToolStateCompleted) - | ({ - status: "error" - } & ToolStateError) - export type ToolStatePending = { status: "pending" } export type ToolStateRunning = { status: "running" - input?: unknown + input: unknown title?: string metadata?: { [key: string]: unknown @@ -362,6 +231,18 @@ export type ToolStateError = { } } +export type ToolState = ToolStatePending | ToolStateRunning | ToolStateCompleted | ToolStateError + +export type ToolPart = { + id: string + sessionID: string + messageID: string + type: "tool" + callID: string + tool: string + state: ToolState +} + export type StepStartPart = { id: string sessionID: string @@ -416,6 +297,24 @@ export type AgentPart = { } } +export type Part = + | TextPart + | ReasoningPart + | FilePart + | ToolPart + | StepStartPart + | StepFinishPart + | SnapshotPart + | PatchPart + | AgentPart + +export type EventMessagePartUpdated = { + type: "message.part.updated" + properties: { + part: Part + } +} + export type EventMessagePartRemoved = { type: "message.part.removed" properties: { @@ -432,11 +331,6 @@ export type EventSessionCompacted = { } } -export type EventPermissionUpdated = { - type: "permission.updated" - properties: Permission -} - export type Permission = { id: string type: string @@ -453,6 +347,11 @@ export type Permission = { } } +export type EventPermissionUpdated = { + type: "permission.updated" + properties: Permission +} + export type EventPermissionReplied = { type: "permission.replied" properties: { @@ -476,13 +375,6 @@ export type EventSessionIdle = { } } -export type EventSessionUpdated = { - type: "session.updated" - properties: { - info: Session - } -} - export type Session = { id: string projectID: string @@ -506,6 +398,13 @@ export type Session = { } } +export type EventSessionUpdated = { + type: "session.updated" + properties: { + info: Session + } +} + export type EventSessionDeleted = { type: "session.deleted" properties: { @@ -517,19 +416,7 @@ export type EventSessionError = { type: "session.error" properties: { sessionID?: string - error?: - | ({ - name: "ProviderAuthError" - } & ProviderAuthError) - | ({ - name: "UnknownError" - } & UnknownError) - | ({ - name: "MessageOutputLengthError" - } & MessageOutputLengthError) - | ({ - name: "MessageAbortedError" - } & MessageAbortedError) + error?: ProviderAuthError | UnknownError | MessageOutputLengthError | MessageAbortedError } } @@ -540,6 +427,316 @@ export type EventServerConnected = { } } +export type Event = + | EventInstallationUpdated + | EventLspClientDiagnostics + | EventMessageUpdated + | EventMessageRemoved + | EventMessagePartUpdated + | EventMessagePartRemoved + | EventSessionCompacted + | EventPermissionUpdated + | EventPermissionReplied + | EventFileEdited + | EventSessionIdle + | EventSessionUpdated + | EventSessionDeleted + | EventSessionError + | EventServerConnected + +/** + * Custom keybind configurations + */ +export type KeybindsConfig = { + /** + * Leader key for keybind combinations + */ + leader?: string + /** + * Show help dialog + */ + app_help?: string + /** + * Exit the application + */ + app_exit?: string + /** + * Open external editor + */ + editor_open?: string + /** + * List available themes + */ + theme_list?: string + /** + * Create/update AGENTS.md + */ + project_init?: string + /** + * Toggle tool details + */ + tool_details?: string + /** + * Toggle thinking blocks + */ + thinking_blocks?: string + /** + * Export session to editor + */ + session_export?: string + /** + * Create a new session + */ + session_new?: string + /** + * List all sessions + */ + session_list?: string + /** + * Show session timeline + */ + session_timeline?: string + /** + * Share current session + */ + session_share?: string + /** + * Unshare current session + */ + session_unshare?: string + /** + * Interrupt current session + */ + session_interrupt?: string + /** + * Compact the session + */ + session_compact?: string + /** + * Cycle to next child session + */ + session_child_cycle?: string + /** + * Cycle to previous child session + */ + session_child_cycle_reverse?: string + /** + * Scroll messages up by one page + */ + messages_page_up?: string + /** + * Scroll messages down by one page + */ + messages_page_down?: string + /** + * Scroll messages up by half page + */ + messages_half_page_up?: string + /** + * Scroll messages down by half page + */ + messages_half_page_down?: string + /** + * Navigate to first message + */ + messages_first?: string + /** + * Navigate to last message + */ + messages_last?: string + /** + * Copy message + */ + messages_copy?: string + /** + * Undo message + */ + messages_undo?: string + /** + * Redo message + */ + messages_redo?: string + /** + * List available models + */ + model_list?: string + /** + * Next recent model + */ + model_cycle_recent?: string + /** + * Previous recent model + */ + model_cycle_recent_reverse?: string + /** + * List agents + */ + agent_list?: string + /** + * Next agent + */ + agent_cycle?: string + /** + * Previous agent + */ + agent_cycle_reverse?: string + /** + * Clear input field + */ + input_clear?: string + /** + * Paste from clipboard + */ + input_paste?: string + /** + * Submit input + */ + input_submit?: string + /** + * Insert newline in input + */ + input_newline?: string + /** + * @deprecated use agent_cycle. Next mode + */ + switch_mode?: string + /** + * @deprecated use agent_cycle_reverse. Previous mode + */ + switch_mode_reverse?: string + /** + * @deprecated use agent_cycle. Next agent + */ + switch_agent?: string + /** + * @deprecated use agent_cycle_reverse. Previous agent + */ + switch_agent_reverse?: string + /** + * @deprecated Currently not available. List files + */ + file_list?: string + /** + * @deprecated Close file + */ + file_close?: string + /** + * @deprecated Search file + */ + file_search?: string + /** + * @deprecated Split/unified diff + */ + file_diff_toggle?: string + /** + * @deprecated Navigate to previous message + */ + messages_previous?: string + /** + * @deprecated Navigate to next message + */ + messages_next?: string + /** + * @deprecated Toggle layout + */ + messages_layout_toggle?: string + /** + * @deprecated use messages_undo. Revert message + */ + messages_revert?: string +} + +export type AgentConfig = { + model?: string + temperature?: number + top_p?: number + prompt?: string + tools?: { + [key: string]: boolean + } + disable?: boolean + /** + * Description of when to use the agent + */ + description?: string + mode?: "subagent" | "primary" | "all" + permission?: { + edit?: "ask" | "allow" | "deny" + bash?: + | ("ask" | "allow" | "deny") + | { + [key: string]: "ask" | "allow" | "deny" + } + webfetch?: "ask" | "allow" | "deny" + } + [key: string]: + | unknown + | string + | number + | { + [key: string]: boolean + } + | boolean + | ("subagent" | "primary" | "all") + | { + edit?: "ask" | "allow" | "deny" + bash?: + | ("ask" | "allow" | "deny") + | { + [key: string]: "ask" | "allow" | "deny" + } + webfetch?: "ask" | "allow" | "deny" + } + | undefined +} + +export type McpLocalConfig = { + /** + * Type of MCP server connection + */ + type: "local" + /** + * Command and arguments to run the MCP server + */ + command: Array + /** + * Environment variables to set when running the MCP server + */ + environment?: { + [key: string]: string + } + /** + * Enable or disable the MCP server on startup + */ + enabled?: boolean +} + +export type McpRemoteConfig = { + /** + * Type of MCP server connection + */ + type: "remote" + /** + * URL of the remote MCP server + */ + url: string + /** + * Enable or disable the MCP server on startup + */ + enabled?: boolean + /** + * Headers to send with the request + */ + headers?: { + [key: string]: string + } +} + +/** + * @deprecated Always uses stretch layout. + */ +export type LayoutConfig = "auto" | "stretch" + export type Config = { /** * JSON schema reference for configuration validation @@ -549,9 +746,6 @@ export type Config = { * Theme name to use for the interface */ theme?: string - /** - * Custom keybind configurations - */ keybinds?: KeybindsConfig /** * TUI specific settings @@ -560,7 +754,7 @@ export type Config = { /** * TUI scroll speed */ - scroll_speed: number + scroll_speed?: number } /** * Command configuration, see https://opencode.ai/docs/commands @@ -674,13 +868,7 @@ export type Config = { * MCP (Model Context Protocol) server configurations */ mcp?: { - [key: string]: - | ({ - type: "local" - } & McpLocalConfig) - | ({ - type: "remote" - } & McpRemoteConfig) + [key: string]: McpLocalConfig | McpRemoteConfig } formatter?: { [key: string]: { @@ -713,9 +901,6 @@ export type Config = { * Additional instruction files or patterns to include */ instructions?: Array - /** - * @deprecated Always uses stretch layout. - */ layout?: LayoutConfig permission?: { edit?: "ask" | "allow" | "deny" @@ -750,337 +935,19 @@ export type Config = { } } -export type KeybindsConfig = { - /** - * Leader key for keybind combinations - */ - leader: string - /** - * Show help dialog - */ - app_help: string - /** - * Exit the application - */ - app_exit: string - /** - * Open external editor - */ - editor_open: string - /** - * List available themes - */ - theme_list: string - /** - * Create/update AGENTS.md - */ - project_init: string - /** - * Toggle tool details - */ - tool_details: string - /** - * Toggle thinking blocks - */ - thinking_blocks: string - /** - * Export session to editor - */ - session_export: string - /** - * Create a new session - */ - session_new: string - /** - * List all sessions - */ - session_list: string - /** - * Show session timeline - */ - session_timeline: string - /** - * Share current session - */ - session_share: string - /** - * Unshare current session - */ - session_unshare: string - /** - * Interrupt current session - */ - session_interrupt: string - /** - * Compact the session - */ - session_compact: string - /** - * Cycle to next child session - */ - session_child_cycle: string - /** - * Cycle to previous child session - */ - session_child_cycle_reverse: string - /** - * Scroll messages up by one page - */ - messages_page_up: string - /** - * Scroll messages down by one page - */ - messages_page_down: string - /** - * Scroll messages up by half page - */ - messages_half_page_up: string - /** - * Scroll messages down by half page - */ - messages_half_page_down: string - /** - * Navigate to first message - */ - messages_first: string - /** - * Navigate to last message - */ - messages_last: string - /** - * Copy message - */ - messages_copy: string - /** - * Undo message - */ - messages_undo: string - /** - * Redo message - */ - messages_redo: string - /** - * List available models - */ - model_list: string - /** - * Next recent model - */ - model_cycle_recent: string - /** - * Previous recent model - */ - model_cycle_recent_reverse: string - /** - * List agents - */ - agent_list: string - /** - * Next agent - */ - agent_cycle: string - /** - * Previous agent - */ - agent_cycle_reverse: string - /** - * Clear input field - */ - input_clear: string - /** - * Paste from clipboard - */ - input_paste: string - /** - * Submit input - */ - input_submit: string - /** - * Insert newline in input - */ - input_newline: string - /** - * @deprecated use agent_cycle. Next mode - */ - switch_mode: string - /** - * @deprecated use agent_cycle_reverse. Previous mode - */ - switch_mode_reverse: string - /** - * @deprecated use agent_cycle. Next agent - */ - switch_agent: string - /** - * @deprecated use agent_cycle_reverse. Previous agent - */ - switch_agent_reverse: string - /** - * @deprecated Currently not available. List files - */ - file_list: string - /** - * @deprecated Close file - */ - file_close: string - /** - * @deprecated Search file - */ - file_search: string - /** - * @deprecated Split/unified diff - */ - file_diff_toggle: string - /** - * @deprecated Navigate to previous message - */ - messages_previous: string - /** - * @deprecated Navigate to next message - */ - messages_next: string - /** - * @deprecated Toggle layout - */ - messages_layout_toggle: string - /** - * @deprecated use messages_undo. Revert message - */ - messages_revert: string -} - -export type AgentConfig = { - model?: string - temperature?: number - top_p?: number - prompt?: string - tools?: { - [key: string]: boolean - } - disable?: boolean - /** - * Description of when to use the agent - */ - description?: string - mode?: "subagent" | "primary" | "all" - permission?: { - edit?: "ask" | "allow" | "deny" - bash?: - | ("ask" | "allow" | "deny") - | { - [key: string]: "ask" | "allow" | "deny" - } - webfetch?: "ask" | "allow" | "deny" - } - [key: string]: - | unknown - | string - | number - | { - [key: string]: boolean - } - | boolean - | ("subagent" | "primary" | "all") - | { - edit?: "ask" | "allow" | "deny" - bash?: - | ("ask" | "allow" | "deny") - | { - [key: string]: "ask" | "allow" | "deny" - } - webfetch?: "ask" | "allow" | "deny" - } - | undefined -} - -export type Provider = { - api?: string - name: string - env: Array - id: string - npm?: string - models: { - [key: string]: Model - } -} - -export type Model = { - id: string - name: string - release_date: string - attachment: boolean - reasoning: boolean - temperature: boolean - tool_call: boolean - cost: { - input: number - output: number - cache_read?: number - cache_write?: number - } - limit: { - context: number - output: number - } - experimental?: boolean - options: { - [key: string]: unknown - } - provider?: { - npm: string - } -} - -export type McpLocalConfig = { - /** - * Type of MCP server connection - */ - type: "local" - /** - * Command and arguments to run the MCP server - */ - command: Array - /** - * Environment variables to set when running the MCP server - */ - environment?: { - [key: string]: string - } - /** - * Enable or disable the MCP server on startup - */ - enabled?: boolean -} - -export type McpRemoteConfig = { - /** - * Type of MCP server connection - */ - type: "remote" - /** - * URL of the remote MCP server - */ - url: string - /** - * Enable or disable the MCP server on startup - */ - enabled?: boolean - /** - * Headers to send with the request - */ - headers?: { - [key: string]: string - } -} - -export type LayoutConfig = "auto" | "stretch" - export type _Error = { data: { [key: string]: unknown } } +export type HttpParamSpec = { + type: "string" | "number" | "boolean" | "array" + description?: string + optional?: boolean + items?: "string" | "number" | "boolean" +} + export type HttpToolRegistration = { id: string description: string @@ -1096,23 +963,16 @@ export type HttpToolRegistration = { } } -export type HttpParamSpec = { - type: "string" | "number" | "boolean" | "array" - description?: string - optional?: boolean - items?: "string" | "number" | "boolean" -} - export type ToolIds = Array -export type ToolList = Array - export type ToolListItem = { id: string description: string - parameters?: unknown + parameters: unknown } +export type ToolList = Array + export type Path = { state: string config: string @@ -1160,6 +1020,44 @@ export type Command = { subtask?: boolean } +export type Model = { + id: string + name: string + release_date: string + attachment: boolean + reasoning: boolean + temperature: boolean + tool_call: boolean + cost: { + input: number + output: number + cache_read?: number + cache_write?: number + } + limit: { + context: number + output: number + } + experimental?: boolean + options: { + [key: string]: unknown + } + provider?: { + npm: string + } +} + +export type Provider = { + api?: string + name: string + env: Array + id: string + npm?: string + models: { + [key: string]: Model + } +} + export type Symbol = { name: string kind: number @@ -1230,17 +1128,6 @@ export type Agent = { } } -export type Auth = - | ({ - type: "oauth" - } & OAuth) - | ({ - type: "api" - } & ApiAuth) - | ({ - type: "wellknown" - } & WellKnownAuth) - export type OAuth = { type: "oauth" refresh: string @@ -1259,6 +1146,8 @@ export type WellKnownAuth = { token: string } +export type Auth = OAuth | ApiAuth | WellKnownAuth + export type ProjectListData = { body?: never path?: never @@ -1713,17 +1602,7 @@ export type SessionPromptData = { tools?: { [key: string]: boolean } - parts: Array< - | ({ - type: "text" - } & TextPartInput) - | ({ - type: "file" - } & FilePartInput) - | ({ - type: "agent" - } & AgentPartInput) - > + parts: Array } path: { /** @@ -1880,7 +1759,7 @@ export type SessionUnrevertResponses = { export type SessionUnrevertResponse = SessionUnrevertResponses[keyof SessionUnrevertResponses] -export type PostSessionByIdPermissionsByPermissionIdData = { +export type PostSessionIdPermissionsPermissionIdData = { body?: { response: "once" | "always" | "reject" } @@ -1894,15 +1773,15 @@ export type PostSessionByIdPermissionsByPermissionIdData = { url: "/session/{id}/permissions/{permissionID}" } -export type PostSessionByIdPermissionsByPermissionIdResponses = { +export type PostSessionIdPermissionsPermissionIdResponses = { /** * Permission processed successfully */ 200: boolean } -export type PostSessionByIdPermissionsByPermissionIdResponse = - PostSessionByIdPermissionsByPermissionIdResponses[keyof PostSessionByIdPermissionsByPermissionIdResponses] +export type PostSessionIdPermissionsPermissionIdResponse = + PostSessionIdPermissionsPermissionIdResponses[keyof PostSessionIdPermissionsPermissionIdResponses] export type CommandListData = { body?: never diff --git a/packages/web/src/content/docs/agents.mdx b/packages/web/src/content/docs/agents.mdx index 16b194c3..4a445928 100644 --- a/packages/web/src/content/docs/agents.mdx +++ b/packages/web/src/content/docs/agents.mdx @@ -81,7 +81,6 @@ A general-purpose agent for researching complex questions, searching for code, a 1. For primary agents, use the **Tab** key to cycle through them during a session. You can also use your configured `switch_agent` keybind. 2. Subagents can be invoked: - - **Automatically** by primary agents for specialized tasks based on their descriptions. - Manually by **@ mentioning** a subagent in your message. For example. @@ -90,7 +89,6 @@ A general-purpose agent for researching complex questions, searching for code, a ``` 3. **Navigation between sessions**: When subagents create their own child sessions, you can navigate between the parent session and all child sessions using: - - **Ctrl+Right** (or your configured `session_child_cycle` keybind) to cycle forward through parent → child1 → child2 → ... → parent - **Ctrl+Left** (or your configured `session_child_cycle_reverse` keybind) to cycle backward through parent ← child1 ← child2 ← ... ← parent diff --git a/packages/web/src/content/docs/index.mdx b/packages/web/src/content/docs/index.mdx index 928f89c3..c8875bc1 100644 --- a/packages/web/src/content/docs/index.mdx +++ b/packages/web/src/content/docs/index.mdx @@ -18,7 +18,6 @@ Let's get started. To use opencode, you'll need: 1. A modern terminal emulator like: - - [WezTerm](https://wezterm.org), cross-platform - [Alacritty](https://alacritty.org), cross-platform - [Ghostty](https://ghostty.org), Linux and macOS diff --git a/packages/web/src/content/docs/providers.mdx b/packages/web/src/content/docs/providers.mdx index 7b109265..ab4ac3ed 100644 --- a/packages/web/src/content/docs/providers.mdx +++ b/packages/web/src/content/docs/providers.mdx @@ -89,7 +89,6 @@ To use Amazon Bedrock with opencode: ::: 1. You'll need either to set one of the following environment variables: - - `AWS_ACCESS_KEY_ID`: You can get this by creating an IAM user and generating an access key for it. - `AWS_PROFILE`: First login through AWS IAM Identity Center (or AWS SSO) using @@ -166,7 +165,6 @@ Or if you already have an API key, you can select **Manually enter API Key** and ### Azure OpenAI 1. Head over to the [Azure portal](https://portal.azure.com/) and create an **Azure OpenAI** resource. You'll need: - - **Resource name**: This becomes part of your API endpoint (`https://RESOURCE_NAME.openai.azure.com/`) - **API key**: Either `KEY 1` or `KEY 2` from your resource @@ -823,7 +821,6 @@ You can use any OpenAI-compatible provider with opencode. Most modern AI provide ``` Here are the configuration options: - - **npm**: AI SDK package to use, `@ai-sdk/openai-compatible` for OpenAI-compatible providers - **name**: Display name in UI. - **models**: Available models. @@ -879,7 +876,6 @@ If you are having trouble with configuring a provider, check the following: This doesn't apply to providers like Amazon Bedrock, that rely on environment variables for their auth. 2. For custom providers, check the opencode config and: - - Make sure the provider ID used in `opencode auth login` matches the ID in your opencode config. - The right npm package is used for the provider. For example, use `@ai-sdk/cerebras` for Cerebras. And for all other OpenAI-compatible providers, use `@ai-sdk/openai-compatible`. - Check correct API endpoint is used in the `options.baseURL` field.