refactor(ai): rename flattened tool helper

This commit is contained in:
Aiden Cline
2026-09-29 22:19:42 -05:00
parent 300dc84c69
commit 0dcebdb88a
12 changed files with 15 additions and 19 deletions
@@ -1031,10 +1031,9 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
// messages. Tools live highest in the cache hierarchy, so when callers
// over-mark we keep their tool hints and shed the message-tail ones first.
const breakpoints = Cache.newBreakpoints(ANTHROPIC_BREAKPOINT_CAP)
const definitions = ProviderShared.toolDefinitions(request.tools)
const tools = definitions.length === 0 ? undefined : definitions.map((tool) => lowerTool(breakpoints, tool))
const tools = ProviderShared.flatTools(request.tools).map((tool) => lowerTool(breakpoints, tool))
// Anthropic rejects tool_choice when tools are absent; "none" is only meaningful with tools present.
const toolChoice = tools === undefined || !request.toolChoice ? undefined : yield* lowerToolChoice(request.toolChoice)
const toolChoice = tools.length === 0 || !request.toolChoice ? undefined : yield* lowerToolChoice(request.toolChoice)
const systemParts = request.system.filter((part) => part.text.length > 0)
const system =
systemParts.length === 0
@@ -1057,7 +1056,7 @@ const fromRequest = Effect.fn("AnthropicMessages.fromRequest")(function* (reques
model: request.model.id,
system,
messages,
tools,
tools: tools.length === 0 ? undefined : tools,
tool_choice: toolChoice,
stream: true as const,
max_tokens: maxTokens,
@@ -463,7 +463,7 @@ const applyThinkingBindingDefault = (request: LLMRequest, thinking: Readonly<Rec
const fromRequest = Effect.fn("BedrockConverse.fromRequest")(function* (request: LLMRequest) {
const toolChoice = request.toolChoice ? yield* lowerToolChoice(request.toolChoice) : undefined
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
const generation = request.generation
const options = yield* decodeOptions(request.providerOptions ?? {})
const maxTokens =
+1 -1
View File
@@ -438,7 +438,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
})
const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request: LLMRequest) {
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
const hasTools = tools.length > 0
const generation = request.generation
const options = yield* decodeOptions(request.providerOptions ?? {})
+1 -1
View File
@@ -26,7 +26,7 @@ const Body = Schema.Struct({
})
const fromRequest = Effect.fn("MetaMessages.fromRequest")(function* (request: LLMRequest) {
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
const body = yield* AnthropicMessages.protocol.body.from(request)
return {
...body,
+1 -1
View File
@@ -67,7 +67,7 @@ const adapter = {
const fromRequest = Effect.fn("MetaResponses.fromRequest")(function* (request: LLMRequest) {
const key = request.model.route.providerMetadataKey ?? String(request.model.provider)
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
const projected = LLMRequest.update(request, {
messages: request.messages.map((message) =>
Message.make({
+1 -1
View File
@@ -390,7 +390,7 @@ export const fromRequest = Effect.fn("MistralChat.fromRequest")(function* (reque
tool: (name) => ({ type: "function" as const, function: { name } }),
})
: undefined
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
return {
model: request.model.id,
messages: yield* lowerMessages(request),
+1 -1
View File
@@ -816,7 +816,7 @@ export const fromRequestWithAdapter = Effect.fn("OpenResponses.fromRequestWithAd
request: LLMRequest,
adapter: ProviderAdapter,
) {
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
return {
...(yield* lowerConversation(request, adapter)),
...lowerGeneration(request),
+1 -1
View File
@@ -826,7 +826,7 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (
const zaiToolStream =
request.model.compatibility?.zaiToolStream ?? detectZaiToolStream(provider, baseURL, request.model.id)
const hasHistory = hasToolHistory(request.messages)
const tools = ProviderShared.toolDefinitions(request.tools)
const tools = ProviderShared.flatTools(request.tools)
const hasActiveTools = tools.length > 0
return {
model: request.model.id,
@@ -181,7 +181,7 @@ const lowerToolEntry = Effect.fn("OpenAIResponses.lowerToolEntry")(function* (to
type: "namespace" as const,
name: tool.name,
description: tool.description ?? `Tools in the ${tool.name} namespace.`,
tools: yield* Effect.forEach(ProviderShared.toolDefinitions(tool.tools), (leaf) =>
tools: yield* Effect.forEach(ProviderShared.flatTools(tool.tools), (leaf) =>
OpenResponses.lowerTool(NAME, leaf),
),
}
+2 -5
View File
@@ -287,11 +287,8 @@ export const unsupportedOperation = (input: {
}),
})
/**
* Tool definitions of a route-lowered request. The route flattens namespaces
* before a flat protocol's `body.from`, so no namespace reaches this point.
*/
export const toolDefinitions = (tools: ReadonlyArray<ToolEntry>) =>
/** The route flattens namespaces before a flat protocol's `body.from`, so only plain tools remain. */
export const flatTools = (tools: ReadonlyArray<ToolEntry>) =>
tools.filter((tool): tool is ToolDefinition => tool.type === "tool")
export const matchToolChoice = <Auto, None, Required, Tool>(
+1 -1
View File
@@ -95,7 +95,7 @@ export const protocol = Protocol.make({
})
export const compact = ResponsesCompaction.make(adapter, (request) =>
OpenResponses.lowerTools(ProviderShared.toolDefinitions(request.tools), adapter),
OpenResponses.lowerTools(ProviderShared.flatTools(request.tools), adapter),
)
export * as XAIResponses from "./xai-responses.js"
+1 -1
View File
@@ -487,7 +487,7 @@ function callOptions(
presencePenalty: request.generation?.presencePenalty,
frequencyPenalty: request.generation?.frequencyPenalty,
seed: request.generation?.seed,
tools: ProviderShared.toolDefinitions(request.tools).map(tool),
tools: ProviderShared.flatTools(request.tools).map(tool),
toolChoice: toolChoice(request.toolChoice),
headers: request.http?.headers,
providerOptions: requestProviderOptions(request.providerOptions, packageName, modelID, optionKey),