Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/core/src/v1/config/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const AgentSchema = Schema.StructWithRest(
}),
temperature: Schema.optional(Schema.Finite),
top_p: Schema.optional(Schema.Finite),
tool_choice: Schema.optional(Schema.Literals(["auto", "required", "none"])).annotate({
description: "How the model selects tools for this agent (default: auto).",
}),
prompt: Schema.optional(Schema.String),
tools: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)).annotate({
description: "@deprecated Use 'permission' field instead",
Expand Down Expand Up @@ -48,6 +51,7 @@ const KNOWN_KEYS = new Set([
"description",
"temperature",
"top_p",
"tool_choice",
"mode",
"hidden",
"color",
Expand Down
17 changes: 17 additions & 0 deletions packages/core/test/config/agent-v1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, expect, test } from "bun:test"
import { Schema } from "effect"
import { ConfigAgentV1 } from "@opencode-ai/core/v1/config/agent"

const decode = Schema.decodeUnknownSync(ConfigAgentV1.Info)

describe("ConfigAgentV1 tool_choice", () => {
test("keeps tool_choice as a known top-level field", () => {
const agent = decode({ tool_choice: "required" })
expect(agent.tool_choice).toBe("required")
expect(agent.options?.["tool_choice"]).toBeUndefined()
})

test("rejects an unknown tool_choice value", () => {
expect(() => decode({ tool_choice: "sometimes" })).toThrow()
})
})
2 changes: 2 additions & 0 deletions packages/opencode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const Info = Schema.Struct({
hidden: Schema.optional(Schema.Boolean),
topP: Schema.optional(Schema.Finite),
temperature: Schema.optional(Schema.Finite),
toolChoice: Schema.optional(Schema.Literals(["auto", "required", "none"])),
color: Schema.optional(Schema.String),
permission: PermissionV1.Ruleset,
model: Schema.optional(
Expand Down Expand Up @@ -282,6 +283,7 @@ export const layer = Layer.effect(
item.description = value.description ?? item.description
item.temperature = value.temperature ?? item.temperature
item.topP = value.top_p ?? item.topP
item.toolChoice = value.tool_choice ?? item.toolChoice
item.mode = value.mode ?? item.mode
item.color = value.color ?? item.color
item.hidden = value.hidden ?? item.hidden
Expand Down
2 changes: 1 addition & 1 deletion packages/opencode/src/session/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ export const layer = Layer.effect(
messages: [...modelMsgs, ...(isLastStep ? [{ role: "assistant" as const, content: MAX_STEPS }] : [])],
tools,
model,
toolChoice: format.type === "json_schema" ? "required" : undefined,
toolChoice: format.type === "json_schema" ? "required" : agent.toolChoice,
})

if (structured !== undefined) {
Expand Down
Loading