Upgrade to Zod v4 (#2605)

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Dax
2025-09-15 03:12:07 -04:00
committed by GitHub
parent 89d820b1c4
commit c1b4e1f19d
75 changed files with 1106 additions and 1304 deletions

View File

@@ -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=="],

View File

@@ -1,11 +1,11 @@
import { z } from "zod"
export function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.output<T>) => Result) {
const result = (input: z.input<T>) => {
export function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.infer<T>) => Result) {
const result = (input: z.infer<T>) => {
const parsed = schema.parse(input)
return cb(parsed)
}
result.force = (input: z.input<T>) => cb(input)
result.force = (input: z.infer<T>) => cb(input)
result.schema = schema
return result
}

View File

@@ -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"

View File

@@ -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:"
}
}

View File

@@ -1,13 +1,12 @@
#!/usr/bin/env bun
import "zod-openapi/extend"
import { z } from "zod/v4"
import { Config } from "../src/config/config"
import { zodToJsonSchema } from "zod-to-json-schema"
const file = process.argv[2]
console.log(file)
const result = zodToJsonSchema(Config.Info, {
const result = z.toJSONSchema(Config.Info, {
/**
* We'll use the `default` values of the field as the only value in `examples`.
* This will ensure no docs are needed to be read, as the configuration is
@@ -15,10 +14,8 @@ const result = zodToJsonSchema(Config.Info, {
*
* See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
*/
postProcess(jsonSchema) {
const schema = jsonSchema as typeof jsonSchema & {
examples?: unknown[]
}
override(input) {
const schema = input.jsonSchema
if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
if (!schema.examples) {
schema.examples = [schema.default]
@@ -29,8 +26,6 @@ const result = zodToJsonSchema(Config.Info, {
.join("\n\n")
.trim()
}
return jsonSchema
},
}) as Record<string, unknown> & {
allowComments?: boolean

View File

@@ -1,5 +1,5 @@
import { Config } from "../config/config"
import z from "zod"
import z from "zod/v4"
import { Provider } from "../provider/provider"
import { generateObject, type ModelMessage } from "ai"
import PROMPT_GENERATE from "./generate.txt"
@@ -28,10 +28,10 @@ export namespace Agent {
})
.optional(),
prompt: z.string().optional(),
tools: z.record(z.boolean()),
tools: z.record(z.string(), z.boolean()),
options: z.record(z.string(), z.any()),
})
.openapi({
.meta({
ref: "Agent",
})
export type Info = z.infer<typeof Info>

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { Auth } from "./index"
import { NamedError } from "../util/error"

View File

@@ -1,7 +1,7 @@
import path from "path"
import { Global } from "../global"
import fs from "fs/promises"
import { z } from "zod"
import z from "zod/v4"
export namespace Auth {
export const Oauth = z
@@ -11,14 +11,14 @@ export namespace Auth {
access: z.string(),
expires: z.number(),
})
.openapi({ ref: "OAuth" })
.meta({ ref: "OAuth" })
export const Api = z
.object({
type: z.literal("api"),
key: z.string(),
})
.openapi({ ref: "ApiAuth" })
.meta({ ref: "ApiAuth" })
export const WellKnown = z
.object({
@@ -26,9 +26,9 @@ export namespace Auth {
key: z.string(),
token: z.string(),
})
.openapi({ ref: "WellKnownAuth" })
.meta({ ref: "WellKnownAuth" })
export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).openapi({ ref: "Auth" })
export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).meta({ ref: "Auth" })
export type Info = z.infer<typeof Info>
const filepath = path.join(Global.Path.data, "auth.json")

View File

@@ -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"

View File

@@ -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,
}),
)

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { EOL } from "os"
import { NamedError } from "../util/error"

View File

@@ -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<typeof Info>

View File

@@ -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<typeof Agent>
@@ -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<typeof Layout>
@@ -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<z.ZodIssue[]>().optional(),
issues: z.custom<z.core.$ZodIssue[]>().optional(),
message: z.string().optional(),
}),
)

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { Bus } from "../bus"
import { $ } from "bun"
import { formatPatch, structuredPatch } from "diff"
@@ -18,7 +18,7 @@ export namespace File {
removed: z.number().int(),
status: z.enum(["added", "deleted", "modified"]),
})
.openapi({
.meta({
ref: "File",
})
@@ -32,7 +32,7 @@ export namespace File {
type: z.enum(["file", "directory"]),
ignored: z.boolean(),
})
.openapi({
.meta({
ref: "FileNode",
})
export type Node = z.infer<typeof Node>
@@ -60,7 +60,7 @@ export namespace File {
})
.optional(),
})
.openapi({
.meta({
ref: "FileContent",
})
export type Content = z.infer<typeof Content>

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { randomBytes } from "crypto"
export namespace Identifier {

View File

@@ -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"

View File

@@ -1,4 +1,3 @@
import "zod-openapi/extend"
import yargs from "yargs"
import { hideBin } from "yargs/helpers"
import { RunCommand } from "./cli/cmd/run"

View File

@@ -1,6 +1,6 @@
import path from "path"
import { $ } from "bun"
import { z } from "zod"
import z from "zod/v4"
import { NamedError } from "../util/error"
import { Bus } from "../bus"
import { Log } from "../util/log"
@@ -28,7 +28,7 @@ export namespace Installation {
version: z.string(),
latest: z.string(),
})
.openapi({
.meta({
ref: "InstallationInfo",
})
export type Info = z.infer<typeof Info>

View File

@@ -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"

View File

@@ -2,7 +2,7 @@ import { Log } from "../util/log"
import { LSPClient } from "./client"
import path from "path"
import { LSPServer } from "./server"
import { z } from "zod"
import z from "zod/v4"
import { Config } from "../config/config"
import { spawn } from "child_process"
import { Instance } from "../project/instance"
@@ -21,7 +21,7 @@ export namespace LSP {
character: z.number(),
}),
})
.openapi({
.meta({
ref: "Range",
})
export type Range = z.infer<typeof Range>
@@ -35,7 +35,7 @@ export namespace LSP {
range: Range,
}),
})
.openapi({
.meta({
ref: "Symbol",
})
export type Symbol = z.infer<typeof Symbol>
@@ -48,7 +48,7 @@ export namespace LSP {
range: Range,
selectionRange: Range,
})
.openapi({
.meta({
ref: "DocumentSymbol",
})
export type DocumentSymbol = z.infer<typeof DocumentSymbol>

View File

@@ -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"

View File

@@ -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<typeof Info>

View File

@@ -1,4 +1,4 @@
import z from "zod"
import z from "zod/v4"
import { Filesystem } from "../util/filesystem"
import path from "path"
import { $ } from "bun"
@@ -17,7 +17,7 @@ export namespace Project {
initialized: z.number().optional(),
}),
})
.openapi({
.meta({
ref: "Project",
})
export type Info = z.infer<typeof Info>

View File

@@ -1,7 +1,7 @@
import { Global } from "../global"
import { Log } from "../util/log"
import path from "path"
import { z } from "zod"
import z from "zod/v4"
import { data } from "./models-macro" with { type: "macro" }
import { Installation } from "../installation"
@@ -29,10 +29,10 @@ export namespace ModelsDev {
output: z.number(),
}),
experimental: z.boolean().optional(),
options: z.record(z.any()),
options: z.record(z.string(), z.any()),
provider: z.object({ npm: z.string() }).optional(),
})
.openapi({
.meta({
ref: "Model",
})
export type Model = z.infer<typeof Model>
@@ -44,9 +44,9 @@ export namespace ModelsDev {
env: z.array(z.string()),
id: z.string(),
npm: z.string().optional(),
models: z.record(Model),
models: z.record(z.string(), Model),
})
.openapi({
.meta({
ref: "Provider",
})

View File

@@ -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"

View File

@@ -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
}
}

View File

@@ -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"

View File

@@ -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")

View File

@@ -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"

View File

@@ -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<typeof Info>
@@ -66,7 +66,7 @@ export namespace Session {
secret: z.string(),
url: z.string(),
})
.openapi({
.meta({
ref: "SessionShare",
})
export type ShareInfo = z.output<typeof ShareInfo>

View File

@@ -1,4 +1,4 @@
import z from "zod"
import z from "zod/v4"
import { Bus } from "../bus"
import { NamedError } from "../util/error"
import { Message } from "./message"
@@ -8,7 +8,7 @@ import { LSP } from "../lsp"
export namespace MessageV2 {
export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
export const AbortedError = NamedError.create("MessageAbortedError", z.object({}))
export const AbortedError = NamedError.create("MessageAbortedError", z.object({ message: z.string() }))
export const AuthError = NamedError.create(
"ProviderAuthError",
z.object({
@@ -21,7 +21,7 @@ export namespace MessageV2 {
.object({
status: z.literal("pending"),
})
.openapi({
.meta({
ref: "ToolStatePending",
})
@@ -32,12 +32,12 @@ export namespace MessageV2 {
status: z.literal("running"),
input: z.any(),
title: z.string().optional(),
metadata: z.record(z.any()).optional(),
metadata: z.record(z.string(), z.any()).optional(),
time: z.object({
start: z.number(),
}),
})
.openapi({
.meta({
ref: "ToolStateRunning",
})
export type ToolStateRunning = z.infer<typeof ToolStateRunning>
@@ -45,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<typeof ToolStateCompleted>
@@ -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<typeof ToolStateError>
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<typeof SnapshotPart>
@@ -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<typeof PatchPart>
@@ -115,7 +115,7 @@ export namespace MessageV2 {
end: z.number().optional(),
})
.optional(),
}).openapi({
}).meta({
ref: "TextPart",
})
export type TextPart = z.infer<typeof TextPart>
@@ -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<typeof ReasoningPart>
@@ -138,7 +138,7 @@ export namespace MessageV2 {
callID: z.string(),
tool: z.string(),
state: ToolState,
}).openapi({
}).meta({
ref: "ToolPart",
})
export type ToolPart = z.infer<typeof ToolPart>
@@ -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<typeof FilePart>
@@ -197,14 +197,14 @@ export namespace MessageV2 {
end: z.number().int(),
})
.optional(),
}).openapi({
}).meta({
ref: "AgentPart",
})
export type AgentPart = z.infer<typeof AgentPart>
export const StepStartPart = PartBase.extend({
type: z.literal("step-start"),
}).openapi({
}).meta({
ref: "StepStartPart",
})
export type StepStartPart = z.infer<typeof StepStartPart>
@@ -221,7 +221,7 @@ export namespace MessageV2 {
write: z.number(),
}),
}),
}).openapi({
}).meta({
ref: "StepFinishPart",
})
export type StepFinishPart = z.infer<typeof StepFinishPart>
@@ -236,7 +236,7 @@ export namespace MessageV2 {
time: z.object({
created: z.number(),
}),
}).openapi({
}).meta({
ref: "UserMessage",
})
export type User = z.infer<typeof User>
@@ -253,7 +253,7 @@ export namespace MessageV2 {
PatchPart,
AgentPart,
])
.openapi({
.meta({
ref: "Part",
})
export type Part = z.infer<typeof Part>
@@ -291,12 +291,12 @@ export namespace MessageV2 {
write: z.number(),
}),
}),
}).openapi({
}).meta({
ref: "AssistantMessage",
})
export type Assistant = z.infer<typeof Assistant>
export const Info = z.discriminatedUnion("role", [User, Assistant]).openapi({
export const Info = z.discriminatedUnion("role", [User, Assistant]).meta({
ref: "Message",
})
export type Info = z.infer<typeof Info>

View File

@@ -1,4 +1,4 @@
import z from "zod"
import z from "zod/v4"
import { NamedError } from "../util/error"
export namespace Message {
@@ -19,7 +19,7 @@ export namespace Message {
toolName: z.string(),
args: z.custom<Required<unknown>>(),
})
.openapi({
.meta({
ref: "ToolCall",
})
export type ToolCall = z.infer<typeof ToolCall>
@@ -32,7 +32,7 @@ export namespace Message {
toolName: z.string(),
args: z.custom<Required<unknown>>(),
})
.openapi({
.meta({
ref: "ToolPartialCall",
})
export type ToolPartialCall = z.infer<typeof ToolPartialCall>
@@ -46,12 +46,12 @@ export namespace Message {
args: z.custom<Required<unknown>>(),
result: z.string(),
})
.openapi({
.meta({
ref: "ToolResult",
})
export type ToolResult = z.infer<typeof ToolResult>
export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).openapi({
export const ToolInvocation = z.discriminatedUnion("state", [ToolCall, ToolPartialCall, ToolResult]).meta({
ref: "ToolInvocation",
})
export type ToolInvocation = z.infer<typeof ToolInvocation>
@@ -61,7 +61,7 @@ export namespace Message {
type: z.literal("text"),
text: z.string(),
})
.openapi({
.meta({
ref: "TextPart",
})
export type TextPart = z.infer<typeof TextPart>
@@ -70,9 +70,9 @@ export namespace Message {
.object({
type: z.literal("reasoning"),
text: z.string(),
providerMetadata: z.record(z.any()).optional(),
providerMetadata: z.record(z.string(), z.any()).optional(),
})
.openapi({
.meta({
ref: "ReasoningPart",
})
export type ReasoningPart = z.infer<typeof ReasoningPart>
@@ -82,7 +82,7 @@ export namespace Message {
type: z.literal("tool-invocation"),
toolInvocation: ToolInvocation,
})
.openapi({
.meta({
ref: "ToolInvocationPart",
})
export type ToolInvocationPart = z.infer<typeof ToolInvocationPart>
@@ -93,9 +93,9 @@ export namespace Message {
sourceId: z.string(),
url: z.string(),
title: z.string().optional(),
providerMetadata: z.record(z.any()).optional(),
providerMetadata: z.record(z.string(), z.any()).optional(),
})
.openapi({
.meta({
ref: "SourceUrlPart",
})
export type SourceUrlPart = z.infer<typeof SourceUrlPart>
@@ -107,7 +107,7 @@ export namespace Message {
filename: z.string().optional(),
url: z.string(),
})
.openapi({
.meta({
ref: "FilePart",
})
export type FilePart = z.infer<typeof FilePart>
@@ -116,14 +116,14 @@ export namespace Message {
.object({
type: z.literal("step-start"),
})
.openapi({
.meta({
ref: "StepStartPart",
})
export type StepStartPart = z.infer<typeof StepStartPart>
export const MessagePart = z
.discriminatedUnion("type", [TextPart, ReasoningPart, ToolInvocationPart, SourceUrlPart, FilePart, StepStartPart])
.openapi({
.meta({
ref: "MessagePart",
})
export type MessagePart = z.infer<typeof MessagePart>
@@ -180,9 +180,9 @@ export namespace Message {
.optional(),
snapshot: z.string().optional(),
})
.openapi({ ref: "MessageMetadata" }),
.meta({ ref: "MessageMetadata" }),
})
.openapi({
.meta({
ref: "Message",
})
export type Info = z.infer<typeof Info>

View File

@@ -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",

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { exec } from "child_process"
import { Tool } from "./tool"

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { Tool } from "./tool"
import { Ripgrep } from "../file/ripgrep"

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import z from "zod/v4"
import { Tool } from "./tool"
export const InvalidTool = Tool.define("invalid", {

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import z from "zod"
import z from "zod/v4"
import { BashTool } from "./bash"
import { EditTool } from "./edit"
import { GlobTool } from "./glob"
@@ -124,35 +124,13 @@ export namespace ToolRegistry {
return allTools().map((t) => t.id)
}
export async function tools(providerID: string, _modelID: string) {
export async function tools(_providerID: string, _modelID: string) {
const result = await Promise.all(
allTools().map(async (t) => ({
id: t.id,
...(await t.init()),
})),
)
if (providerID === "openai") {
return result.map((t) => ({
...t,
parameters: optionalToNullable(t.parameters as unknown as z.ZodTypeAny),
}))
}
if (providerID === "azure") {
return result.map((t) => ({
...t,
parameters: optionalToNullable(t.parameters as unknown as z.ZodTypeAny),
}))
}
if (providerID === "google") {
return result.map((t) => ({
...t,
parameters: sanitizeGeminiParameters(t.parameters as unknown as z.ZodTypeAny),
}))
}
return result
}
@@ -178,93 +156,4 @@ export namespace ToolRegistry {
return result
}
function sanitizeGeminiParameters(schema: z.ZodTypeAny, visited = new Set()): z.ZodTypeAny {
if (!schema || visited.has(schema)) {
return schema
}
visited.add(schema)
if (schema instanceof z.ZodDefault) {
const innerSchema = schema.removeDefault()
// Handle Gemini's incompatibility with `default` on `anyOf` (unions).
if (innerSchema instanceof z.ZodUnion) {
// The schema was `z.union(...).default(...)`, which is not allowed.
// We strip the default and return the sanitized union.
return sanitizeGeminiParameters(innerSchema, visited)
}
// Otherwise, the default is on a regular type, which is allowed.
// We recurse on the inner type and then re-apply the default.
return sanitizeGeminiParameters(innerSchema, visited).default(schema._def.defaultValue())
}
if (schema instanceof z.ZodOptional) {
return z.optional(sanitizeGeminiParameters(schema.unwrap(), visited))
}
if (schema instanceof z.ZodObject) {
const newShape: Record<string, z.ZodTypeAny> = {}
for (const [key, value] of Object.entries(schema.shape)) {
newShape[key] = sanitizeGeminiParameters(value as z.ZodTypeAny, visited)
}
return z.object(newShape)
}
if (schema instanceof z.ZodArray) {
return z.array(sanitizeGeminiParameters(schema.element, visited))
}
if (schema instanceof z.ZodUnion) {
// This schema corresponds to `anyOf` in JSON Schema.
// We recursively sanitize each option in the union.
const sanitizedOptions = schema.options.map((option: z.ZodTypeAny) => sanitizeGeminiParameters(option, visited))
return z.union(sanitizedOptions as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]])
}
if (schema instanceof z.ZodString) {
const newSchema = z.string({ description: schema.description })
const safeChecks = ["min", "max", "length", "regex", "startsWith", "endsWith", "includes", "trim"]
// rome-ignore lint/suspicious/noExplicitAny: <explanation>
;(newSchema._def as any).checks = (schema._def as z.ZodStringDef).checks.filter((check) =>
safeChecks.includes(check.kind),
)
return newSchema
}
return schema
}
function optionalToNullable(schema: z.ZodTypeAny): z.ZodTypeAny {
if (schema instanceof z.ZodObject) {
const shape = schema.shape
const newShape: Record<string, z.ZodTypeAny> = {}
for (const [key, value] of Object.entries(shape)) {
const zodValue = value as z.ZodTypeAny
if (zodValue instanceof z.ZodOptional) {
newShape[key] = zodValue.unwrap().nullable()
} else {
newShape[key] = optionalToNullable(zodValue)
}
}
return z.object(newShape)
}
if (schema instanceof z.ZodArray) {
return z.array(optionalToNullable(schema.element))
}
if (schema instanceof z.ZodUnion) {
return z.union(
schema.options.map((option: z.ZodTypeAny) => optionalToNullable(option)) as [
z.ZodTypeAny,
z.ZodTypeAny,
...z.ZodTypeAny[],
],
)
}
return schema
}
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,4 +1,4 @@
import type { StandardSchemaV1 } from "@standard-schema/spec"
import z from "zod/v4"
export namespace Tool {
interface Metadata {
@@ -13,13 +13,13 @@ export namespace Tool {
extra?: { [key: string]: any }
metadata(input: { title?: string; metadata?: M }): void
}
export interface Info<Parameters extends StandardSchemaV1 = StandardSchemaV1, M extends Metadata = Metadata> {
export interface Info<Parameters extends z.ZodType = z.ZodType, M extends Metadata = Metadata> {
id: string
init: () => Promise<{
description: string
parameters: Parameters
execute(
args: StandardSchemaV1.InferOutput<Parameters>,
args: z.infer<Parameters>,
ctx: Context,
): Promise<{
title: string
@@ -29,7 +29,7 @@ export namespace Tool {
}>
}
export function define<Parameters extends StandardSchemaV1, Result extends Metadata>(
export function define<Parameters extends z.ZodType, Result extends Metadata>(
id: string,
init: Info<Parameters, Result>["init"] | Awaited<ReturnType<Info<Parameters, Result>["init"]>>,
): Info<Parameters, Result> {

View File

@@ -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"

View File

@@ -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"

View File

@@ -1,19 +1,19 @@
import { z, type ZodSchema } from "zod"
import z from "zod/v4"
// import { Log } from "./log"
// const log = Log.create()
export abstract class NamedError extends Error {
abstract schema(): ZodSchema
abstract schema(): z.core.$ZodType
abstract toObject(): { name: string; data: any }
static create<Name extends string, Data extends ZodSchema>(name: Name, data: Data) {
static create<Name extends string, Data extends z.core.$ZodType>(name: Name, data: Data) {
const schema = z
.object({
name: z.literal(name),
data,
})
.openapi({
.meta({
ref: name,
})
const result = class extends NamedError {

View File

@@ -1,10 +1,10 @@
import path from "path"
import fs from "fs/promises"
import { Global } from "../global"
import z from "zod"
import z from "zod/v4"
export namespace Log {
export const Level = z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).openapi({ ref: "LogLevel", description: "Log level" })
export const Level = z.enum(["DEBUG", "INFO", "WARN", "ERROR"]).meta({ ref: "LogLevel", description: "Log level" })
export type Level = z.infer<typeof Level>
const levelPriority: Record<Level, number> = {

View File

@@ -1,4 +1,3 @@
import "zod-openapi/extend"
import { describe, expect, test } from "bun:test"
import path from "path"
import os from "os"

View File

@@ -1,3 +1,3 @@
{
".": "0.9.0"
".": "0.13.0"
}

View File

@@ -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

View File

@@ -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)

View File

@@ -24,7 +24,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->
```sh
go get -u 'github.com/sst/opencode-sdk-go@v0.9.0'
go get -u 'github.com/sst/opencode-sdk-go@v0.13.0'
```
<!-- x-release-please-end -->

View File

@@ -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

View File

@@ -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
}

View File

@@ -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,16 +700,16 @@ 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 {
DisablePasteSummary apijson.Field
Hook apijson.Field
SummarizePaste apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(McpRemoteConfig{}),
DiscriminatorValue: "remote",
},
)
}
@@ -1753,7 +1753,7 @@ func (r ConfigShare) IsKnown() bool {
// TUI specific settings
type ConfigTui struct {
// TUI scroll speed
ScrollSpeed float64 `json:"scroll_speed,required"`
ScrollSpeed float64 `json:"scroll_speed"`
JSON configTuiJSON `json:"-"`
}
@@ -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:"-"`
}

View File

@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventLspClientDiagnostics{}),
DiscriminatorValue: "lsp.client.diagnostics",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventMessageUpdated{}),
DiscriminatorValue: "message.updated",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventMessageRemoved{}),
DiscriminatorValue: "message.removed",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventMessagePartUpdated{}),
DiscriminatorValue: "message.part.updated",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventMessagePartRemoved{}),
DiscriminatorValue: "message.part.removed",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventPermissionUpdated{}),
DiscriminatorValue: "permission.updated",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventPermissionReplied{}),
DiscriminatorValue: "permission.replied",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventFileEdited{}),
DiscriminatorValue: "file.edited",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionUpdated{}),
DiscriminatorValue: "session.updated",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionDeleted{}),
DiscriminatorValue: "session.deleted",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionIdle{}),
DiscriminatorValue: "session.idle",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionError{}),
DiscriminatorValue: "session.error",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionCompacted{}),
DiscriminatorValue: "session.compacted",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventPermissionUpdated{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventPermissionReplied{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventFileEdited{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionIdle{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionUpdated{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionDeleted{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionError{}),
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventServerConnected{}),
DiscriminatorValue: "server.connected",
},
)
}
@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(shared.UnknownError{}),
DiscriminatorValue: "UnknownError",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(EventListResponseEventSessionErrorPropertiesErrorMessageOutputLengthError{}),
DiscriminatorValue: "MessageOutputLengthError",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(shared.MessageAbortedError{}),
DiscriminatorValue: "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

View File

@@ -2,4 +2,4 @@
package internal
const PackageVersion = "0.9.0" // x-release-please-version
const PackageVersion = "0.13.0" // x-release-please-version

View File

@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(shared.UnknownError{}),
DiscriminatorValue: "UnknownError",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(AssistantMessageErrorMessageOutputLengthError{}),
DiscriminatorValue: "MessageOutputLengthError",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(shared.MessageAbortedError{}),
DiscriminatorValue: "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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(SymbolSource{}),
DiscriminatorValue: "symbol",
},
)
}
@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(AssistantMessage{}),
DiscriminatorValue: "assistant",
},
)
}
@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ReasoningPart{}),
DiscriminatorValue: "reasoning",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(FilePart{}),
DiscriminatorValue: "file",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ToolPart{}),
DiscriminatorValue: "tool",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(StepStartPart{}),
DiscriminatorValue: "step-start",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(StepFinishPart{}),
DiscriminatorValue: "step-finish",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(SnapshotPart{}),
DiscriminatorValue: "snapshot",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(PartPatchPart{}),
DiscriminatorValue: "patch",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(AgentPart{}),
DiscriminatorValue: "agent",
},
)
}
@@ -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",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ToolStateRunning{}),
DiscriminatorValue: "running",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ToolStateCompleted{}),
DiscriminatorValue: "completed",
},
apijson.UnionVariant{
TypeFilter: gjson.JSON,
Type: reflect.TypeOf(ToolStateError{}),
DiscriminatorValue: "error",
},
)
}
@@ -2046,6 +2025,7 @@ func (r ToolStateCompletedStatus) IsKnown() bool {
type ToolStateCompletedTime struct {
End float64 `json:"end,required"`
Start float64 `json:"start,required"`
Compacted float64 `json:"compacted"`
JSON toolStateCompletedTimeJSON `json:"-"`
}
@@ -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

View File

@@ -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 {

View File

@@ -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 (

View File

@@ -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<ThrowOnError extends boolean = false>(
options: Options<PostSessionByIdPermissionsByPermissionIdData, ThrowOnError>,
public postSessionIdPermissionsPermissionId<ThrowOnError extends boolean = false>(
options: Options<PostSessionIdPermissionsPermissionIdData, ThrowOnError>,
) {
return (options.client ?? this._client).post<
PostSessionByIdPermissionsByPermissionIdResponses,
unknown,
ThrowOnError
>({
return (options.client ?? this._client).post<PostSessionIdPermissionsPermissionIdResponses, unknown, ThrowOnError>({
url: "/session/{id}/permissions/{permissionID}",
...options,
headers: {

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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.