refactor(core): simplify location filesystem (#31545)
This commit is contained in:
parent
0777cf1ccf
commit
132ef57272
73 changed files with 1048 additions and 1416 deletions
|
|
@ -14,7 +14,7 @@ import {
|
|||
type ProviderMetadata,
|
||||
type ToolCallPart,
|
||||
type ToolDefinition,
|
||||
type ToolResultContentPart,
|
||||
type ToolContent,
|
||||
type ToolResultPart,
|
||||
} from "../schema"
|
||||
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared"
|
||||
|
|
@ -321,10 +321,10 @@ const lowerImage = Effect.fn("AnthropicMessages.lowerImage")(function* (part: Me
|
|||
// Tool results may carry structured text/images. Keep media as provider-native
|
||||
// content instead of JSON-stringifying base64 into a prompt string.
|
||||
const lowerToolResultContentItem = Effect.fn("AnthropicMessages.lowerToolResultContentItem")(function* (
|
||||
item: ToolResultContentPart,
|
||||
item: ToolContent,
|
||||
) {
|
||||
if (item.type === "text") return { type: "text" as const, text: item.text } satisfies AnthropicTextBlock
|
||||
const media = yield* ProviderShared.validateMedia(
|
||||
const media = yield* ProviderShared.validateToolFile(
|
||||
"Anthropic Messages",
|
||||
item,
|
||||
new Set<string>(ProviderShared.IMAGE_MIMES),
|
||||
|
|
@ -344,7 +344,7 @@ const lowerToolResultContent = Effect.fn("AnthropicMessages.lowerToolResultConte
|
|||
// with existing cassettes and provider expectations.
|
||||
if (part.result.type !== "content") return ProviderShared.toolResultText(part)
|
||||
// Preserve the narrowed array element type when compiled through a consumer package.
|
||||
const content: ReadonlyArray<ToolResultContentPart> = part.result.value
|
||||
const content: ReadonlyArray<ToolContent> = part.result.value
|
||||
return yield* Effect.forEach(content, lowerToolResultContentItem)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ const lowerToolResultContent = Effect.fn("BedrockConverse.lowerToolResultContent
|
|||
content.push({ text: item.text })
|
||||
continue
|
||||
}
|
||||
const media = yield* BedrockMedia.lower(item)
|
||||
const media = yield* BedrockMedia.lower({ type: "media", mediaType: item.mime, data: item.uri, filename: item.name })
|
||||
if (!("image" in media))
|
||||
return yield* ProviderShared.invalidRequest("Bedrock Converse only supports image media in tool results")
|
||||
content.push(media)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
type TextPart,
|
||||
type ToolCallPart,
|
||||
type ToolDefinition,
|
||||
type ToolResultContentPart,
|
||||
type ToolContent,
|
||||
} from "../schema"
|
||||
import { JsonObject, optionalArray, ProviderShared } from "./shared"
|
||||
import { GeminiToolSchema } from "./utils/gemini-tool-schema"
|
||||
|
|
@ -262,7 +262,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
|
|||
})
|
||||
continue
|
||||
}
|
||||
const content: ReadonlyArray<ToolResultContentPart> = part.result.value
|
||||
const content: ReadonlyArray<ToolContent> = part.result.value
|
||||
const text = content.filter((item) => item.type === "text").map((item) => item.text)
|
||||
parts.push({
|
||||
functionResponse: {
|
||||
|
|
@ -275,7 +275,7 @@ const lowerMessages = Effect.fn("Gemini.lowerMessages")(function* (request: LLMR
|
|||
})
|
||||
for (const item of content) {
|
||||
if (item.type === "text") continue
|
||||
const media = yield* ProviderShared.validateMedia("Gemini", item, IMAGE_MIMES)
|
||||
const media = yield* ProviderShared.validateToolFile("Gemini", item, IMAGE_MIMES)
|
||||
parts.push({ inlineData: { mimeType: media.mime, data: media.base64 } })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
type TextPart,
|
||||
type ToolCallPart,
|
||||
type ToolDefinition,
|
||||
type ToolResultContentPart,
|
||||
type ToolContent,
|
||||
} from "../schema"
|
||||
import { isRecord, JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared"
|
||||
import { OpenAIOptions } from "./utils/openai-options"
|
||||
|
|
@ -201,7 +201,7 @@ const lowerToolCall = (part: ToolCallPart): OpenAIChatAssistantToolCall => ({
|
|||
})
|
||||
|
||||
const lowerMedia = Effect.fn("OpenAIChat.lowerMedia")(function* (
|
||||
part: Extract<MediaPart | ToolResultContentPart, { type: "media" }>,
|
||||
part: MediaPart,
|
||||
) {
|
||||
const media = yield* ProviderShared.validateMedia("OpenAI Chat", part, IMAGE_MIMES)
|
||||
return { type: "image_url" as const, image_url: { url: media.dataUrl } }
|
||||
|
|
@ -271,13 +271,15 @@ const lowerToolMessages = Effect.fn("OpenAIChat.lowerToolMessages")(function* (m
|
|||
messages.push({ role: "tool", tool_call_id: part.id, content: ProviderShared.toolResultText(part) })
|
||||
continue
|
||||
}
|
||||
const content: ReadonlyArray<ToolResultContentPart> = part.result.value
|
||||
const content: ReadonlyArray<ToolContent> = part.result.value
|
||||
const text = content.filter((item) => item.type === "text").map((item) => item.text)
|
||||
messages.push({ role: "tool", tool_call_id: part.id, content: text.join("\n") })
|
||||
const media = content.filter(
|
||||
(item): item is Extract<ToolResultContentPart, { type: "media" }> => item.type === "media",
|
||||
const files = content.filter((item) => item.type === "file")
|
||||
images.push(
|
||||
...(yield* Effect.forEach(files, (item) =>
|
||||
lowerMedia({ type: "media", mediaType: item.mime, data: item.uri, filename: item.name }),
|
||||
)),
|
||||
)
|
||||
images.push(...(yield* Effect.forEach(media, lowerMedia)))
|
||||
}
|
||||
return { messages, images }
|
||||
})
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
type TextPart,
|
||||
type ToolCallPart,
|
||||
type ToolDefinition,
|
||||
type ToolResultContentPart,
|
||||
type ToolContent,
|
||||
type ToolResultPart,
|
||||
} from "../schema"
|
||||
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared"
|
||||
|
|
@ -318,10 +318,10 @@ const lowerUserContent = Effect.fn("OpenAIResponses.lowerUserContent")(function*
|
|||
// Tool results may carry structured text/images. Keep media as provider-native
|
||||
// content instead of JSON-stringifying base64 into a prompt string.
|
||||
const lowerToolResultContentItem = Effect.fn("OpenAIResponses.lowerToolResultContentItem")(function* (
|
||||
item: ToolResultContentPart,
|
||||
item: ToolContent,
|
||||
) {
|
||||
if (item.type === "text") return { type: "input_text" as const, text: item.text }
|
||||
const media = yield* ProviderShared.validateMedia(
|
||||
const media = yield* ProviderShared.validateToolFile(
|
||||
"OpenAI Responses",
|
||||
item,
|
||||
new Set<string>(ProviderShared.IMAGE_MIMES),
|
||||
|
|
@ -334,7 +334,7 @@ const lowerToolResultOutput = Effect.fn("OpenAIResponses.lowerToolResultOutput")
|
|||
// compatibility with existing cassettes and provider expectations.
|
||||
if (part.result.type !== "content") return ProviderShared.toolResultText(part)
|
||||
// Preserve the narrowed array element type when compiled through a consumer package.
|
||||
const content: ReadonlyArray<ToolResultContentPart> = part.result.value
|
||||
const content: ReadonlyArray<ToolContent> = part.result.value
|
||||
return yield* Effect.forEach(content, lowerToolResultContentItem)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
type ContentPart,
|
||||
type LLMRequest,
|
||||
type MediaPart,
|
||||
type ToolFileContent,
|
||||
type TextPart,
|
||||
type ToolResultPart,
|
||||
} from "../schema"
|
||||
|
|
@ -233,6 +234,9 @@ export const validateMedia = Effect.fn("ProviderShared.validateMedia")(function*
|
|||
return { mime, base64, dataUrl: `data:${mime};base64,${base64}`, bytes } satisfies ValidatedMedia
|
||||
})
|
||||
|
||||
export const validateToolFile = (route: string, part: ToolFileContent, supportedMimes: ReadonlySet<string>) =>
|
||||
validateMedia(route, { type: "media", mediaType: part.mime, data: part.uri, filename: part.name }, supportedMimes)
|
||||
|
||||
export const trimBaseUrl = (value: string) => value.replace(/\/+$/, "")
|
||||
|
||||
export const toolResultText = (part: ToolResultPart) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue