feat: support claude agent SDK-style structured outputs in the OpenCode SDK (#8161)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Dax Raad <d@ironbay.co>
This commit is contained in:
Kyle Mistele
2026-02-11 20:54:05 -08:00
committed by GitHub
parent 66780195dc
commit e269788a8f
10 changed files with 854 additions and 66 deletions

View File

@@ -15,6 +15,13 @@ import type { Provider } from "@/provider/provider"
export namespace MessageV2 {
export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
export const AbortedError = NamedError.create("MessageAbortedError", z.object({ message: z.string() }))
export const StructuredOutputError = NamedError.create(
"StructuredOutputError",
z.object({
message: z.string(),
retries: z.number(),
}),
)
export const AuthError = NamedError.create(
"ProviderAuthError",
z.object({
@@ -39,6 +46,29 @@ export namespace MessageV2 {
z.object({ message: z.string(), responseBody: z.string().optional() }),
)
export const OutputFormatText = z
.object({
type: z.literal("text"),
})
.meta({
ref: "OutputFormatText",
})
export const OutputFormatJsonSchema = z
.object({
type: z.literal("json_schema"),
schema: z.record(z.string(), z.any()).meta({ ref: "JSONSchema" }),
retryCount: z.number().int().min(0).default(2),
})
.meta({
ref: "OutputFormatJsonSchema",
})
export const Format = z.discriminatedUnion("type", [OutputFormatText, OutputFormatJsonSchema]).meta({
ref: "OutputFormat",
})
export type OutputFormat = z.infer<typeof Format>
const PartBase = z.object({
id: z.string(),
sessionID: z.string(),
@@ -313,6 +343,7 @@ export namespace MessageV2 {
time: z.object({
created: z.number(),
}),
format: Format.optional(),
summary: z
.object({
title: z.string().optional(),
@@ -365,6 +396,7 @@ export namespace MessageV2 {
NamedError.Unknown.Schema,
OutputLengthError.Schema,
AbortedError.Schema,
StructuredOutputError.Schema,
ContextOverflowError.Schema,
APIError.Schema,
])
@@ -393,6 +425,7 @@ export namespace MessageV2 {
write: z.number(),
}),
}),
structured: z.any().optional(),
variant: z.string().optional(),
finish: z.string().optional(),
}).meta({