UNPKG

@arizeai/phoenix-client

Version:

A client for the Phoenix API

310 lines 12.5 kB
import { assertUnreachable } from "../../utils/assertUnreachable.js"; import { safelyParseJSON } from "../../utils/safelyParseJSON.js"; import { SDKProviderConverterMap } from "./constants.js"; import { toolCallHeuristicSchema } from "./schemas.js"; import { detectMessagePartProvider, detectMessageProvider, detectToolCallProvider, detectToolChoiceProvider, detectToolDefinitionProvider, } from "./utils.js"; import invariant from "tiny-invariant"; export const safelyConvertMessageToProvider = ({ message, targetProvider, }) => { try { // convert incoming message to OpenAI format const openAIMessage = toOpenAIMessage(message); invariant(openAIMessage != null, `Could not convert message to ${targetProvider} format`); // convert the OpenAI format to the target provider format return fromOpenAIMessage({ message: openAIMessage, targetProvider }); } catch { return null; } }; export const safelyConvertToolCallToProvider = ({ toolCall, targetProvider, }) => { try { // convert incoming tool call to OpenAI format const openAIToolCall = toOpenAIToolCall(toolCall); invariant(openAIToolCall != null, `Could not convert tool call to ${targetProvider} format`); // convert the OpenAI format to the target provider format return fromOpenAIToolCall({ toolCall: openAIToolCall, targetProvider, }); } catch { return null; } }; export const safelyConvertToolDefinitionToProvider = ({ toolDefinition, targetProvider, }) => { try { // convert incoming tool definition to OpenAI format const openAIToolDefinition = toOpenAIToolDefinition(toolDefinition); invariant(openAIToolDefinition != null, `Could not convert tool definition to ${targetProvider} format`); // convert the OpenAI format to the target provider format return fromOpenAIToolDefinition({ toolDefinition: openAIToolDefinition, targetProvider, }); } catch { return null; } }; export const safelyConvertToolChoiceToProvider = ({ toolChoice, targetProvider, }) => { try { // convert incoming tool choice to OpenAI format const openAIToolChoice = toOpenAIToolChoice(toolChoice); invariant(openAIToolChoice != null, `Could not convert tool choice to ${targetProvider} format`); // convert the OpenAI format to the target provider format return fromOpenAIToolChoice({ toolChoice: openAIToolChoice, targetProvider, }); } catch { return null; } }; export const toOpenAIChatPart = (part) => { const { provider, validatedMessage } = detectMessagePartProvider(part); switch (provider) { case "AZURE_OPENAI": case "OPENAI": return validatedMessage; case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.messageParts.toOpenAI.parse(validatedMessage); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.messageParts.toOpenAI.parse(validatedMessage); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.messageParts.toOpenAI.parse(validatedMessage); case null: return null; default: return assertUnreachable(provider); } }; /** * Convert from any message format to OpenAI format if possible */ export const toOpenAIMessage = (message) => { const { provider, validatedMessage } = detectMessageProvider(message); switch (provider) { case "AZURE_OPENAI": case "OPENAI": return validatedMessage; case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.messages.toOpenAI.parse(validatedMessage); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.messages.toOpenAI.parse(validatedMessage); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.messages.toOpenAI.parse(validatedMessage); case null: return null; default: return assertUnreachable(provider); } }; /** * Convert from OpenAI message format to any other format */ export const fromOpenAIMessage = ({ message, targetProvider, }) => { switch (targetProvider) { case "AZURE_OPENAI": case "OPENAI": return SDKProviderConverterMap.OPENAI.messages.fromOpenAI.parse(message); case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.messages.fromOpenAI.parse(message); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.messages.fromOpenAI.parse(message); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.messages.fromOpenAI.parse(message); default: return assertUnreachable(targetProvider); } }; /** * Converts a tool call to the OpenAI format if possible * @param maybeToolCall a tool call from an unknown LlmProvider * @returns the tool call parsed to the OpenAI format */ export const toOpenAIToolCall = (maybeToolCall) => { const { provider, validatedToolCall } = detectToolCallProvider(maybeToolCall); switch (provider) { case "AZURE_OPENAI": case "OPENAI": return validatedToolCall; case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolCalls.toOpenAI.parse(validatedToolCall); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolCalls.toOpenAI.parse(validatedToolCall); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolCalls.toOpenAI.parse(validatedToolCall); case null: return null; default: return assertUnreachable(provider); } }; /** * Converts a tool call to a target provider format * @param params the parameters object * @param params.toolCall the tool call to convert * @param params.targetProvider the provider to convert the tool call to * @returns the tool call in the target provider format */ export const fromOpenAIToolCall = ({ toolCall, targetProvider, }) => { switch (targetProvider) { case "AZURE_OPENAI": case "OPENAI": return SDKProviderConverterMap.OPENAI.toolCalls.fromOpenAI.parse(toolCall); case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolCalls.fromOpenAI.parse(toolCall); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolCalls.fromOpenAI.parse(toolCall); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolCalls.fromOpenAI.parse(toolCall); default: assertUnreachable(targetProvider); } }; /** * Converts a tool choice to the OpenAI format * @param toolChoice a tool choice from an unknown LlmProvider * @returns the tool choice parsed to the OpenAI format */ export const toOpenAIToolChoice = (toolChoice) => { const { provider, toolChoice: validatedToolChoice } = detectToolChoiceProvider(toolChoice); if (provider == null || validatedToolChoice == null) { throw new Error("Could not detect provider of tool choice"); } switch (provider) { case "AZURE_OPENAI": case "OPENAI": return validatedToolChoice; case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolChoices.toOpenAI.parse(validatedToolChoice); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolChoices.toOpenAI.parse(validatedToolChoice); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolChoices.toOpenAI.parse(validatedToolChoice); default: assertUnreachable(provider); } }; /** * Converts a tool choice to a target provider format * @param params the parameters object * @param params.toolChoice the tool choice to convert * @param params.targetProvider the provider to convert the tool choice to * @returns the tool choice in the target provider format */ export const fromOpenAIToolChoice = ({ toolChoice, targetProvider, }) => { switch (targetProvider) { case "AZURE_OPENAI": case "OPENAI": return SDKProviderConverterMap.OPENAI.toolChoices.fromOpenAI.parse(toolChoice); case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolChoices.fromOpenAI.parse(toolChoice); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolChoices.fromOpenAI.parse(toolChoice); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolChoices.fromOpenAI.parse(toolChoice); default: assertUnreachable(targetProvider); } }; /** * Convert from any tool call format to OpenAI format if possible */ export const toOpenAIToolDefinition = (toolDefinition) => { const { provider, validatedToolDefinition } = detectToolDefinitionProvider(toolDefinition); switch (provider) { case "AZURE_OPENAI": case "OPENAI": return SDKProviderConverterMap.OPENAI.toolDefinitions.toOpenAI.parse(validatedToolDefinition); case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolDefinitions.toOpenAI.parse(validatedToolDefinition); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolDefinitions.toOpenAI.parse(validatedToolDefinition); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolDefinitions.toOpenAI.parse(validatedToolDefinition); case null: return null; default: assertUnreachable(provider); } }; /** * Convert from OpenAI tool call format to any other format */ export const fromOpenAIToolDefinition = ({ toolDefinition, targetProvider, }) => { switch (targetProvider) { case "AZURE_OPENAI": case "OPENAI": return SDKProviderConverterMap.OPENAI.toolDefinitions.fromOpenAI.parse(toolDefinition); case "ANTHROPIC": return SDKProviderConverterMap.ANTHROPIC.toolDefinitions.fromOpenAI.parse(toolDefinition); case "PHOENIX": return SDKProviderConverterMap.PHOENIX.toolDefinitions.fromOpenAI.parse(toolDefinition); case "VERCEL_AI": return SDKProviderConverterMap.VERCEL_AI.toolDefinitions.fromOpenAI.parse(toolDefinition); default: assertUnreachable(targetProvider); } }; export function findToolCallId(maybeToolCall) { let subject = maybeToolCall; if (typeof maybeToolCall === "string") { const parsed = safelyParseJSON(maybeToolCall); subject = parsed.json; } const toolCall = toOpenAIToolCall(subject); if (toolCall) { return toolCall.id; } // we don't have first class support for the incoming tool call // try some heuristics to find the id const heuristic = toolCallHeuristicSchema.safeParse(subject); if (heuristic.success) { return heuristic.data.id ?? heuristic.data.name ?? null; } return null; } export function findToolCallName(maybeToolCall) { let subject = maybeToolCall; if (typeof maybeToolCall === "string") { const parsed = safelyParseJSON(maybeToolCall); subject = parsed.json; } const toolCall = toOpenAIToolCall(subject); if (toolCall) { return toolCall.function.name; } // we don't have first class support for the incoming tool call // try some heuristics to find the name const heuristic = toolCallHeuristicSchema.safeParse(subject); if (heuristic.success) { return (heuristic.data.function?.name ?? heuristic.data.name ?? // fallback to id if we don't have a name heuristic.data.id ?? null); } return null; } export function findToolCallArguments(maybeToolCall) { let subject = maybeToolCall; if (typeof maybeToolCall === "string") { const parsed = safelyParseJSON(maybeToolCall); subject = parsed.json; } const toolCall = toOpenAIToolCall(subject); if (toolCall) { return toolCall.function.arguments; } // we don't have first class support for the incoming tool call // try some heuristics to find the arguments const heuristic = toolCallHeuristicSchema.safeParse(subject); if (heuristic.success) { return ((heuristic.data.arguments ?? heuristic.data.function?.arguments) ?? null); } return null; } //# sourceMappingURL=converters.js.map