buildBackendChatModel function
ChatModel<ChatModelOptions>
buildBackendChatModel(
- ModelBackendSpec spec, {
- required String model,
- List<
Tool< ? tools,Object> > - Client? client,
Builds a configured dartantic ChatModel for spec.
model is the model id; tools are the tools to offer (names must already
be Anthropic-legal — the seam owns lenny's dotted-name encoding). A supplied
client is used directly on the swift-infer and Anthropic paths (so the
driver owns retry); the OpenAI path wraps it in a transport-retry client.
Implementation
ChatModel<ChatModelOptions> buildBackendChatModel(
ModelBackendSpec spec, {
required String model,
List<Tool>? tools,
http.Client? client,
}) {
switch (spec) {
case SwiftInferBackend s:
return SwiftInferChatModel(
name: model,
baseUrl: s.baseUrl,
bearerToken: s.bearerToken,
headers: s.headers,
tools: tools,
client: client,
defaultOptions: s.options,
);
case AnthropicBackend a:
return AnthropicChatModel(
name: model,
apiKey: a.apiKey,
baseUrl: a.baseUrl,
headers: a.headers,
tools: tools,
client: client,
enableThinking: a.enableThinking,
// Extended thinking (kept on, per the panel default) imposes two
// Anthropic constraints, so the default options must respect both:
// * tool_choice must NOT force a tool ("Thinking may not be enabled
// when tool_choice forces tool use") — so tool_choice:auto, not
// :any. Claude reliably calls a tool with thinking on, and the
// driver's SchemaRejection retry covers a rare prose-only turn.
// * temperature may only be 1 when thinking is enabled — so we omit
// a temperature override here (the tuned frontier 0.2 is
// incompatible with thinking) and let Anthropic use its default.
// An explicit [a.options] overrides these defaults; a caller that
// re-introduces forced tool_choice or a non-1 temperature alongside
// thinking owns that incompatible combination.
defaultOptions:
a.options ??
const AnthropicChatOptions(toolChoice: AnthropicToolChoice.auto()),
);
case OpenAIBackend o:
// NOTE: dartantic 3.4.1's OpenAI mapper hard-codes tool_choice:null, so
// the OpenAI tier CANNOT force a tool call the way the old provider did
// (tool_choice:'required'). The model usually calls a tool given tools +
// a directive prompt; the driver's SchemaRejection retry covers a miss.
// Tracked as a dartantic-upstream follow-up. Temperature defaults to the
// tuned frontier 0.2 (was silently 1.0 after the cutover).
return OpenAIProvider(
apiKey: o.apiKey,
baseUrl: o.baseUrl,
headers: o.headers ?? const {},
).createChatModel(
name: model,
tools: tools,
enableThinking: o.enableThinking,
temperature: o.temperature ?? 0.2,
options: o.options,
);
}
}