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

@@ -117,6 +117,78 @@ try {
---
## Structured Output
You can request structured JSON output from the model by specifying an `outputFormat` with a JSON schema. The model will use a `StructuredOutput` tool to return validated JSON matching your schema.
### Basic Usage
```typescript
const result = await client.session.prompt({
path: { id: sessionId },
body: {
parts: [{ type: 'text', text: 'Research Anthropic and provide company info' }],
outputFormat: {
type: 'json_schema',
schema: {
type: 'object',
properties: {
company: { type: 'string', description: 'Company name' },
founded: { type: 'number', description: 'Year founded' },
products: {
type: 'array',
items: { type: 'string' },
description: 'Main products'
}
},
required: ['company', 'founded']
}
}
}
})
// Access the structured output
console.log(result.data.info.structured_output)
// { company: "Anthropic", founded: 2021, products: ["Claude", "Claude API"] }
```
### Output Format Types
| Type | Description |
|------|-------------|
| `text` | Default. Standard text response (no structured output) |
| `json_schema` | Returns validated JSON matching the provided schema |
### JSON Schema Format
When using `type: 'json_schema'`, provide:
| Field | Type | Description |
|-------|------|-------------|
| `type` | `'json_schema'` | Required. Specifies JSON schema mode |
| `schema` | `object` | Required. JSON Schema object defining the output structure |
| `retryCount` | `number` | Optional. Number of validation retries (default: 2) |
### Error Handling
If the model fails to produce valid structured output after all retries, the response will include a `StructuredOutputError`:
```typescript
if (result.data.info.error?.name === 'StructuredOutputError') {
console.error('Failed to produce structured output:', result.data.info.error.message)
console.error('Attempts:', result.data.info.error.retries)
}
```
### Best Practices
1. **Provide clear descriptions** in your schema properties to help the model understand what data to extract
2. **Use `required`** to specify which fields must be present
3. **Keep schemas focused** - complex nested schemas may be harder for the model to fill correctly
4. **Set appropriate `retryCount`** - increase for complex schemas, decrease for simple ones
---
## APIs
The SDK exposes all server APIs through a type-safe client.
@@ -241,7 +313,7 @@ const { providers, default: defaults } = await client.config.providers()
| `session.summarize({ path, body })` | Summarize session | Returns `boolean` |
| `session.messages({ path })` | List messages in a session | Returns `{ info: `<a href={typesUrl}><code>Message</code></a>`, parts: `<a href={typesUrl}><code>Part[]</code></a>`}[]` |
| `session.message({ path })` | Get message details | Returns `{ info: `<a href={typesUrl}><code>Message</code></a>`, parts: `<a href={typesUrl}><code>Part[]</code></a>`}` |
| `session.prompt({ path, body })` | Send prompt message | `body.noReply: true` returns UserMessage (context only). Default returns <a href={typesUrl}><code>AssistantMessage</code></a> with AI response |
| `session.prompt({ path, body })` | Send prompt message | `body.noReply: true` returns UserMessage (context only). Default returns <a href={typesUrl}><code>AssistantMessage</code></a> with AI response. Supports `body.outputFormat` for [structured output](#structured-output) |
| `session.command({ path, body })` | Send command to session | Returns `{ info: `<a href={typesUrl}><code>AssistantMessage</code></a>`, parts: `<a href={typesUrl}><code>Part[]</code></a>`}` |
| `session.shell({ path, body })` | Run a shell command | Returns <a href={typesUrl}><code>AssistantMessage</code></a> |
| `session.revert({ path, body })` | Revert a message | Returns <a href={typesUrl}><code>Session</code></a> |