UNPKG

@arizeai/phoenix-client

Version:

A client for the Phoenix API

130 lines 4.99 kB
import { assertUnreachable } from "../../../utils/assertUnreachable.js"; import { safelyStringifyJSON } from "../../../utils/safelyStringifyJSON.js"; import { jsonSchemaZodSchema } from "../../jsonSchema.js"; import { asToolResultPart, phoenixContentPartSchema, } from "./messagePartSchemas.js"; import { phoenixMessageSchema } from "./messageSchemas.js"; import { phoenixResponseFormatSchema } from "./responseFormatSchema.js"; import { phoenixToolCallSchema } from "./toolCallSchemas.js"; import { phoenixToolChoiceSchema } from "./toolChoiceSchemas.js"; import { phoenixToolDefinitionSchema } from "./toolSchemas.js"; /* * Conversion Functions * * These follow a hub-and-spoke model where OpenAI is the hub format. * All conversions between different formats go through OpenAI as an intermediate step. */ export const phoenixMessagePartToOpenAI = phoenixContentPartSchema.transform((part) => { const type = part.type; switch (type) { case "text": return { type: "text", text: part.text, }; case "tool_call": return null; case "tool_result": return null; default: return assertUnreachable(type); } }); /** * Spoke → Hub: Convert a Prompt message to OpenAI format */ export const phoenixMessageToOpenAI = phoenixMessageSchema.transform((prompt) => { const content = typeof prompt.content == "string" ? [{ type: "text", text: prompt.content }] : prompt.content; // Special handling for TOOL role messages if (prompt.role === "tool") { const toolResult = content .map((part) => asToolResultPart(part)) .find((part) => !!part); if (!toolResult) { throw new Error("TOOL role message must have a ToolResultContentPart"); } return { role: "tool", content: typeof toolResult.tool_result === "string" ? toolResult.tool_result : safelyStringifyJSON(toolResult.tool_result).json || "", tool_call_id: toolResult.tool_call_id, }; } // Handle other roles const role = prompt.role; switch (role) { case "system": case "developer": return { role: "system", content: content .map((part) => phoenixMessagePartToOpenAI.parse(part)) .filter((part) => part !== null && part.type === "text"), }; case "user": return { role: "user", content: content .map((part) => phoenixMessagePartToOpenAI.parse(part)) .filter((part) => part !== null && part.type === "text"), }; case "assistant": case "ai": case "model": return { role: "assistant", content: content .map((part) => phoenixMessagePartToOpenAI.parse(part)) .filter((part) => part !== null && part.type === "text"), tool_calls: content.some((part) => part.type === "tool_call") ? content .filter((part) => part.type === "tool_call") .map((part) => phoenixToolCallToOpenAI.parse(part)) .filter((part) => part !== null) : undefined, }; default: return assertUnreachable(role); } }); export const phoenixResponseFormatToOpenAI = phoenixResponseFormatSchema.transform((phoenix) => ({ type: "json_schema", json_schema: { name: phoenix.json_schema.name, description: phoenix.json_schema.description, schema: jsonSchemaZodSchema.parse(phoenix.json_schema.schema), }, })); export const phoenixToolCallToOpenAI = phoenixToolCallSchema.transform((prompt) => ({ type: "function", id: prompt.tool_call_id, function: { ...prompt.tool_call, arguments: typeof prompt.tool_call.arguments === "string" ? prompt.tool_call.arguments : (safelyStringifyJSON(prompt.tool_call.arguments).json ?? ""), }, })); export const phoenixToolDefinitionToOpenAI = phoenixToolDefinitionSchema.transform((phoenix) => ({ type: "function", function: { name: phoenix.function.name, description: phoenix.function.description, parameters: jsonSchemaZodSchema.parse(phoenix.function.parameters), }, })); export const phoenixToolChoiceToOpenAI = phoenixToolChoiceSchema.transform((phoenix) => { switch (phoenix.type) { case "none": return "none"; case "zero_or_more": return "auto"; case "one_or_more": return "required"; case "specific_function": return { type: "function", function: { name: phoenix.function_name } }; } }); //# sourceMappingURL=converters.js.map