tracia 0.2.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/client.ts","../src/prompts.ts","../src/traces.ts","../src/index.ts"],"sourcesContent":["import { TraciaErrorCode } from './types'\n\nexport class TraciaError extends Error {\n readonly code: TraciaErrorCode\n readonly statusCode?: number\n\n constructor(code: TraciaErrorCode, message: string, statusCode?: number) {\n super(message)\n this.name = 'TraciaError'\n this.code = code\n this.statusCode = statusCode\n\n Object.setPrototypeOf(this, TraciaError.prototype)\n }\n}","export interface TraciaOptions {\n apiKey: string\n}\n\nexport interface RunVariables {\n [key: string]: string\n}\n\nexport interface RunOptions {\n model?: string\n tags?: string[]\n userId?: string\n sessionId?: string\n}\n\nexport interface TokenUsage {\n inputTokens: number\n outputTokens: number\n totalTokens: number\n}\n\nexport interface RunResult {\n text: string\n traceId: string\n promptVersion: number\n latencyMs: number\n usage: TokenUsage\n cost: number\n}\n\nexport enum TraciaErrorCode {\n UNAUTHORIZED = 'UNAUTHORIZED',\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n MISSING_PROVIDER_KEY = 'MISSING_PROVIDER_KEY',\n PROVIDER_ERROR = 'PROVIDER_ERROR',\n MISSING_VARIABLES = 'MISSING_VARIABLES',\n INVALID_REQUEST = 'INVALID_REQUEST',\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n UNKNOWN = 'UNKNOWN',\n}\n\nexport interface ApiErrorResponse {\n error: {\n code: string\n message: string\n }\n}\n\nexport interface ApiSuccessResponse {\n text: string\n traceId: string\n promptVersion: number\n latencyMs: number\n usage: TokenUsage\n cost: number\n}\n\nexport type MessageRole = 'system' | 'user' | 'assistant'\n\nexport interface PromptMessage {\n id: string\n role: MessageRole\n content: string\n}\n\nexport interface Prompt {\n id: string\n slug: string\n name: string\n description: string | null\n model: string | null\n currentVersion: number\n content: PromptMessage[]\n variables: string[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface PromptListItem {\n id: string\n slug: string\n name: string\n description: string | null\n model: string | null\n currentVersion: number\n variables: string[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreatePromptOptions {\n name: string\n slug?: string\n description?: string\n content: PromptMessage[]\n}\n\nexport interface UpdatePromptOptions {\n name?: string\n slug?: string\n description?: string\n content?: PromptMessage[]\n}\n\nexport interface ListPromptsResponse {\n prompts: PromptListItem[]\n}\n\nexport interface DeletePromptResponse {\n success: boolean\n}\n\nexport type TraceStatus = 'SUCCESS' | 'ERROR'\n\nexport interface TraceListItem {\n id: string\n traceId: string\n promptSlug: string\n model: string\n status: TraceStatus\n latencyMs: number\n inputTokens: number\n outputTokens: number\n totalTokens: number\n cost: number | null\n createdAt: string\n}\n\nexport interface Trace {\n id: string\n traceId: string\n promptSlug: string\n promptVersion: number\n model: string\n provider: string\n input: { messages: PromptMessage[] }\n variables: Record<string, string> | null\n output: string | null\n status: TraceStatus\n error: string | null\n latencyMs: number\n inputTokens: number\n outputTokens: number\n totalTokens: number\n cost: number | null\n tags: string[]\n userId: string | null\n sessionId: string | null\n createdAt: string\n}\n\nexport interface ListTracesOptions {\n promptSlug?: string\n status?: TraceStatus\n startDate?: Date\n endDate?: Date\n userId?: string\n sessionId?: string\n tags?: string[]\n limit?: number\n cursor?: string\n}\n\nexport interface ListTracesResult {\n traces: TraceListItem[]\n nextCursor?: string\n}\n\nexport interface EvaluateOptions {\n evaluator: string\n value: number\n note?: string\n}\n\nexport interface EvaluateResult {\n id: string\n evaluatorKey: string\n evaluatorName: string\n value: number\n source: string\n note: string | null\n createdAt: string\n}","import { TraciaError } from './errors'\nimport {\n TraciaErrorCode,\n ApiErrorResponse,\n ApiSuccessResponse,\n} from './types'\n\nconst SDK_VERSION = process.env.SDK_VERSION || '0.0.0'\nconst DEFAULT_TIMEOUT_MS = 120000\n\ninterface HttpClientOptions {\n apiKey: string\n baseUrl: string\n}\n\ninterface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n path: string\n body?: unknown\n}\n\nfunction mapApiErrorCodeToTraciaErrorCode(apiCode: string): TraciaErrorCode {\n const codeMap: Record<string, TraciaErrorCode> = {\n UNAUTHORIZED: TraciaErrorCode.UNAUTHORIZED,\n NOT_FOUND: TraciaErrorCode.NOT_FOUND,\n CONFLICT: TraciaErrorCode.CONFLICT,\n MISSING_PROVIDER_KEY: TraciaErrorCode.MISSING_PROVIDER_KEY,\n PROVIDER_ERROR: TraciaErrorCode.PROVIDER_ERROR,\n MISSING_VARIABLES: TraciaErrorCode.MISSING_VARIABLES,\n INVALID_REQUEST: TraciaErrorCode.INVALID_REQUEST,\n }\n return codeMap[apiCode] ?? TraciaErrorCode.UNKNOWN\n}\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>({ method: 'GET', path })\n }\n\n async post<T = ApiSuccessResponse>(path: string, body: unknown): Promise<T> {\n return this.request<T>({ method: 'POST', path, body })\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body })\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>({ method: 'DELETE', path })\n }\n\n private async request<T>(options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${options.path}`\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS)\n\n try {\n const response = await fetch(url, {\n method: options.method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'User-Agent': `tracia-sdk/${SDK_VERSION}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n let errorData: ApiErrorResponse | undefined\n try {\n errorData = (await response.json()) as ApiErrorResponse\n } catch {\n throw new TraciaError(\n TraciaErrorCode.UNKNOWN,\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n )\n }\n\n if (errorData?.error) {\n const errorCode = mapApiErrorCodeToTraciaErrorCode(errorData.error.code)\n throw new TraciaError(errorCode, errorData.error.message, response.status)\n }\n\n throw new TraciaError(\n TraciaErrorCode.UNKNOWN,\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n )\n }\n\n return (await response.json()) as T\n } catch (error) {\n clearTimeout(timeoutId)\n\n if (error instanceof TraciaError) {\n throw error\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new TraciaError(\n TraciaErrorCode.TIMEOUT,\n `Request timed out after ${DEFAULT_TIMEOUT_MS}ms`\n )\n }\n\n throw new TraciaError(\n TraciaErrorCode.NETWORK_ERROR,\n `Network error: ${error.message}`\n )\n }\n\n throw new TraciaError(TraciaErrorCode.UNKNOWN, 'An unknown error occurred')\n }\n }\n}","import { HttpClient } from './client'\nimport {\n RunVariables,\n RunOptions,\n RunResult,\n ApiSuccessResponse,\n Prompt,\n PromptListItem,\n CreatePromptOptions,\n UpdatePromptOptions,\n ListPromptsResponse,\n DeletePromptResponse,\n} from './types'\n\ninterface RunRequestBody {\n variables?: RunVariables\n model?: string\n tags?: string[]\n userId?: string\n sessionId?: string\n}\n\nexport class Prompts {\n constructor(private readonly client: HttpClient) {}\n\n async list(): Promise<PromptListItem[]> {\n const response = await this.client.get<ListPromptsResponse>('/api/v1/prompts')\n return response.prompts\n }\n\n async get(slug: string): Promise<Prompt> {\n return this.client.get<Prompt>(`/api/v1/prompts/${encodeURIComponent(slug)}`)\n }\n\n async create(options: CreatePromptOptions): Promise<Prompt> {\n return this.client.post<Prompt>('/api/v1/prompts', options)\n }\n\n async update(slug: string, options: UpdatePromptOptions): Promise<Prompt> {\n return this.client.put<Prompt>(\n `/api/v1/prompts/${encodeURIComponent(slug)}`,\n options\n )\n }\n\n async delete(slug: string): Promise<void> {\n await this.client.delete<DeletePromptResponse>(\n `/api/v1/prompts/${encodeURIComponent(slug)}`\n )\n }\n\n async run(\n slug: string,\n variables?: RunVariables,\n options?: RunOptions\n ): Promise<RunResult> {\n const requestBody: RunRequestBody = {}\n\n if (variables && Object.keys(variables).length > 0) {\n requestBody.variables = variables\n }\n\n if (options?.model) {\n requestBody.model = options.model\n }\n\n if (options?.tags && options.tags.length > 0) {\n requestBody.tags = options.tags\n }\n\n if (options?.userId) {\n requestBody.userId = options.userId\n }\n\n if (options?.sessionId) {\n requestBody.sessionId = options.sessionId\n }\n\n const response = await this.client.post<ApiSuccessResponse>(\n `/api/v1/prompts/${encodeURIComponent(slug)}/run`,\n requestBody\n )\n\n return {\n text: response.text,\n traceId: response.traceId,\n promptVersion: response.promptVersion,\n latencyMs: response.latencyMs,\n usage: response.usage,\n cost: response.cost,\n }\n }\n}\n","import { HttpClient } from './client'\nimport { TraciaError } from './errors'\nimport {\n Trace,\n ListTracesOptions,\n ListTracesResult,\n EvaluateOptions,\n EvaluateResult,\n TraciaErrorCode,\n} from './types'\n\nexport class Traces {\n constructor(private readonly client: HttpClient) {}\n\n async get(traceId: string): Promise<Trace> {\n return this.client.get<Trace>(`/api/v1/traces/${encodeURIComponent(traceId)}`)\n }\n\n async list(options?: ListTracesOptions): Promise<ListTracesResult> {\n const params = new URLSearchParams()\n\n if (options?.promptSlug) {\n params.set('promptSlug', options.promptSlug)\n }\n\n if (options?.status) {\n params.set('status', options.status)\n }\n\n if (options?.startDate) {\n params.set('startDate', options.startDate.toISOString())\n }\n\n if (options?.endDate) {\n params.set('endDate', options.endDate.toISOString())\n }\n\n if (options?.userId) {\n params.set('userId', options.userId)\n }\n\n if (options?.sessionId) {\n params.set('sessionId', options.sessionId)\n }\n\n if (options?.tags && options.tags.length > 0) {\n params.set('tags', options.tags.join(','))\n }\n\n if (options?.limit) {\n params.set('limit', String(options.limit))\n }\n\n if (options?.cursor) {\n params.set('cursor', options.cursor)\n }\n\n const query = params.toString()\n const path = query ? `/api/v1/traces?${query}` : '/api/v1/traces'\n\n return this.client.get<ListTracesResult>(path)\n }\n\n async evaluate(traceId: string, options: EvaluateOptions): Promise<EvaluateResult> {\n if (typeof options.value !== 'number') {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n `Invalid evaluation value. Must be a number.`\n )\n }\n\n const body: { evaluatorKey: string; value: number; note?: string } = {\n evaluatorKey: options.evaluator,\n value: options.value,\n }\n\n if (options.note !== undefined) {\n body.note = options.note\n }\n\n return this.client.post<EvaluateResult>(\n `/api/v1/traces/${encodeURIComponent(traceId)}/evaluations`,\n body\n )\n }\n}\n","import { HttpClient } from './client'\nimport { Prompts } from './prompts'\nimport { Traces } from './traces'\nimport { TraciaOptions } from './types'\n\nexport { TraciaError } from './errors'\nexport type {\n TraciaOptions,\n RunVariables,\n RunOptions,\n RunResult,\n TokenUsage,\n Prompt,\n PromptListItem,\n PromptMessage,\n MessageRole,\n CreatePromptOptions,\n UpdatePromptOptions,\n Trace,\n TraceListItem,\n TraceStatus,\n ListTracesOptions,\n ListTracesResult,\n EvaluateOptions,\n EvaluateResult,\n} from './types'\nexport { TraciaErrorCode } from './types'\n\nexport const Eval = {\n POSITIVE: 1,\n NEGATIVE: 0,\n} as const\n\nconst DEFAULT_BASE_URL = 'https://app.tracia.io'\n\nexport class Tracia {\n private readonly client: HttpClient\n readonly prompts: Prompts\n readonly traces: Traces\n\n constructor(options: TraciaOptions) {\n if (!options.apiKey) {\n throw new Error('apiKey is required')\n }\n\n this.client = new HttpClient({\n apiKey: options.apiKey,\n baseUrl: DEFAULT_BASE_URL,\n })\n\n this.prompts = new Prompts(this.client)\n this.traces = new Traces(this.client)\n }\n}\n"],"mappings":"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","names":["TraciaErrorCode"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/client.ts","../src/prompts.ts","../src/models.ts","../src/providers/ai-sdk.ts","../src/traces.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import { TraciaErrorCode } from './types'\n\nexport class TraciaError extends Error {\n readonly code: TraciaErrorCode\n readonly statusCode?: number\n\n constructor(code: TraciaErrorCode, message: string, statusCode?: number) {\n super(message)\n this.name = 'TraciaError'\n this.code = code\n this.statusCode = statusCode\n\n Object.setPrototypeOf(this, TraciaError.prototype)\n }\n}","export interface TraciaOptions {\n apiKey: string\n /** Called when background trace creation fails */\n onTraceError?: (error: Error, traceId: string) => void\n}\n\nexport interface RunVariables {\n [key: string]: string\n}\n\nexport interface RunOptions {\n model?: string\n tags?: string[]\n userId?: string\n sessionId?: string\n}\n\nexport interface TokenUsage {\n inputTokens: number\n outputTokens: number\n totalTokens: number\n}\n\nexport interface RunResult {\n text: string\n traceId: string\n promptVersion: number\n latencyMs: number\n usage: TokenUsage\n cost: number\n}\n\nexport enum TraciaErrorCode {\n UNAUTHORIZED = 'UNAUTHORIZED',\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n MISSING_PROVIDER_KEY = 'MISSING_PROVIDER_KEY',\n PROVIDER_ERROR = 'PROVIDER_ERROR',\n MISSING_VARIABLES = 'MISSING_VARIABLES',\n INVALID_REQUEST = 'INVALID_REQUEST',\n NETWORK_ERROR = 'NETWORK_ERROR',\n TIMEOUT = 'TIMEOUT',\n ABORTED = 'ABORTED',\n UNKNOWN = 'UNKNOWN',\n MISSING_PROVIDER_SDK = 'MISSING_PROVIDER_SDK',\n MISSING_PROVIDER_API_KEY = 'MISSING_PROVIDER_API_KEY',\n UNSUPPORTED_MODEL = 'UNSUPPORTED_MODEL',\n}\n\nexport enum LLMProvider {\n OPENAI = 'openai',\n ANTHROPIC = 'anthropic',\n GOOGLE = 'google',\n}\n\nexport interface ApiErrorResponse {\n error: {\n code: string\n message: string\n }\n}\n\nexport interface ApiSuccessResponse {\n text: string\n traceId: string\n promptVersion: number\n latencyMs: number\n usage: TokenUsage\n cost: number\n}\n\nexport type MessageRole = 'system' | 'user' | 'assistant' | 'tool'\n\nexport interface PromptMessage {\n id: string\n role: MessageRole\n content: string\n}\n\nexport interface Prompt {\n id: string\n slug: string\n name: string\n description: string | null\n model: string | null\n currentVersion: number\n content: PromptMessage[]\n variables: string[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface PromptListItem {\n id: string\n slug: string\n name: string\n description: string | null\n model: string | null\n currentVersion: number\n variables: string[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface CreatePromptOptions {\n name: string\n slug?: string\n description?: string\n content: PromptMessage[]\n}\n\nexport interface UpdatePromptOptions {\n name?: string\n slug?: string\n description?: string\n content?: PromptMessage[]\n}\n\nexport interface ListPromptsResponse {\n prompts: PromptListItem[]\n}\n\nexport interface DeletePromptResponse {\n success: boolean\n}\n\nexport type TraceStatus = 'SUCCESS' | 'ERROR'\n\nexport interface TraceListItem {\n id: string\n traceId: string\n promptSlug: string\n model: string\n status: TraceStatus\n latencyMs: number\n inputTokens: number\n outputTokens: number\n totalTokens: number\n cost: number | null\n createdAt: string\n}\n\nexport interface Trace {\n id: string\n traceId: string\n promptSlug: string\n promptVersion: number\n model: string\n provider: string\n input: { messages: PromptMessage[] }\n variables: Record<string, string> | null\n output: string | null\n status: TraceStatus\n error: string | null\n latencyMs: number\n inputTokens: number\n outputTokens: number\n totalTokens: number\n cost: number | null\n tags: string[]\n userId: string | null\n sessionId: string | null\n createdAt: string\n}\n\nexport interface ListTracesOptions {\n promptSlug?: string\n status?: TraceStatus\n startDate?: Date\n endDate?: Date\n userId?: string\n sessionId?: string\n tags?: string[]\n limit?: number\n cursor?: string\n}\n\nexport interface ListTracesResult {\n traces: TraceListItem[]\n nextCursor?: string\n}\n\nexport interface EvaluateOptions {\n evaluator: string\n value: number\n note?: string\n}\n\nexport interface EvaluateResult {\n id: string\n evaluatorKey: string\n evaluatorName: string\n value: number\n source: string\n note: string | null\n createdAt: string\n}\n\n// Tool types\n\nexport interface ToolDefinition {\n name: string\n description: string\n parameters: ToolParameters\n}\n\nexport interface ToolParameters {\n type: 'object'\n properties: Record<string, JsonSchemaProperty>\n required?: string[]\n}\n\nexport interface JsonSchemaProperty {\n type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object'\n description?: string\n enum?: (string | number)[]\n items?: JsonSchemaProperty\n properties?: Record<string, JsonSchemaProperty>\n required?: string[]\n}\n\n/**\n * Tool call returned in results - user-friendly format.\n */\nexport interface ToolCall {\n id: string\n name: string\n arguments: Record<string, unknown>\n}\n\nexport type ToolChoice = 'auto' | 'none' | 'required' | { tool: string }\n\nexport type FinishReason = 'stop' | 'tool_calls' | 'max_tokens'\n\n// ============================================================================\n// Message content parts\n// ============================================================================\n\n/**\n * Text content part for messages.\n */\nexport interface TextPart {\n type: 'text'\n text: string\n}\n\n/**\n * Tool call part in assistant messages.\n */\nexport interface ToolCallPart {\n type: 'tool_call'\n id: string\n name: string\n arguments: Record<string, unknown>\n}\n\nexport type ContentPart = TextPart | ToolCallPart\n\n// ============================================================================\n// Messages\n// ============================================================================\n\n/**\n * Message format for LLM conversations.\n *\n * @example System message\n * ```typescript\n * { role: 'system', content: 'You are a helpful assistant.' }\n * ```\n *\n * @example User message\n * ```typescript\n * { role: 'user', content: 'What is the weather?' }\n * ```\n *\n * @example Assistant message with tool calls\n * ```typescript\n * {\n * role: 'assistant',\n * content: [\n * { type: 'text', text: 'Let me check the weather.' },\n * { type: 'tool_call', id: 'call_123', name: 'get_weather', arguments: { location: 'Paris' } }\n * ]\n * }\n * ```\n *\n * @example Tool result message (simple format)\n * ```typescript\n * { role: 'tool', toolCallId: 'call_123', toolName: 'get_weather', content: '{\"temp\": 22, \"unit\": \"celsius\"}' }\n * ```\n */\nexport interface LocalPromptMessage {\n role: MessageRole\n content: string | ContentPart[]\n /** Required when role is 'tool' - the ID of the tool call this is responding to */\n toolCallId?: string\n /** Required when role is 'tool' - the name of the tool that was called */\n toolName?: string\n}\n\nexport interface RunLocalInput {\n messages: LocalPromptMessage[]\n model: string\n\n /** Enable streaming. When true, returns LocalStream. When false/undefined, returns Promise<RunLocalResult>. */\n stream?: boolean\n\n /** Explicitly specify the provider. Use for new/custom models not in the built-in list. */\n provider?: LLMProvider\n\n temperature?: number\n maxOutputTokens?: number\n topP?: number\n stopSequences?: string[]\n /** Timeout in milliseconds for the LLM call */\n timeoutMs?: number\n\n /** Provider-specific options passed directly to the SDK */\n customOptions?: Record<string, unknown>\n\n variables?: Record<string, string>\n\n providerApiKey?: string\n\n tags?: string[]\n userId?: string\n sessionId?: string\n sendTrace?: boolean\n /** Custom trace ID. Must match format: tr_ + 16 hex characters */\n traceId?: string\n\n /** Tool definitions for function calling */\n tools?: ToolDefinition[]\n /** Control which tools the model can use */\n toolChoice?: ToolChoice\n\n /** AbortSignal to cancel the request (only used when stream: true) */\n signal?: AbortSignal\n}\n\nexport interface RunLocalResult {\n text: string\n traceId: string\n latencyMs: number\n usage: TokenUsage\n cost: number | null\n provider: LLMProvider\n model: string\n /** Tool calls made by the model, empty array if none */\n toolCalls: ToolCall[]\n /** Reason the model stopped generating */\n finishReason: FinishReason\n /** Full assistant message for round-tripping in multi-turn conversations */\n message: LocalPromptMessage\n}\n\nexport interface CreateTracePayload {\n traceId: string\n model: string\n provider: LLMProvider\n input: { messages: LocalPromptMessage[] }\n variables: Record<string, string> | null\n output: string | null\n status: TraceStatus\n error: string | null\n latencyMs: number\n inputTokens: number\n outputTokens: number\n totalTokens: number\n tags?: string[]\n userId?: string\n sessionId?: string\n temperature?: number\n maxOutputTokens?: number\n topP?: number\n tools?: ToolDefinition[]\n toolCalls?: ToolCall[]\n}\n\nexport interface CreateTraceResult {\n traceId: string\n cost: number | null\n}\n\n// Streaming types\n\n/**\n * Final result returned after a stream completes.\n * Includes all fields from RunLocalResult plus abort status.\n */\nexport interface StreamResult extends RunLocalResult {\n /** Whether the stream was aborted before completion */\n aborted: boolean\n}\n\n/**\n * A streaming response from runLocal({ stream: true }).\n *\n * @example\n * ```typescript\n * const stream = tracia.runLocal({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Write a haiku' }],\n * stream: true,\n * })\n *\n * // traceId is available immediately\n * console.log('Trace:', stream.traceId)\n *\n * // Iterate over text chunks as they arrive\n * for await (const chunk of stream) {\n * process.stdout.write(chunk)\n * }\n *\n * // Get final result with usage stats after iteration completes\n * const result = await stream.result\n * console.log(result.usage)\n * ```\n *\n * @remarks\n * - You must iterate over the stream for the result promise to resolve\n * - Calling abort() will stop the stream and resolve result with aborted: true\n * - The stream can only be iterated once\n */\nexport interface LocalStream {\n /** Trace ID for this request, available immediately */\n readonly traceId: string\n\n /** Async iterator yielding text chunks */\n [Symbol.asyncIterator](): AsyncIterator<string>\n\n /**\n * Promise that resolves to the final result after stream completes.\n * Only resolves after the stream has been fully iterated or aborted.\n */\n readonly result: Promise<StreamResult>\n\n /** Abort the stream. The result promise will resolve with aborted: true */\n abort(): void\n}\n\n// ============================================================================\n// Responses API types (OpenAI-specific)\n// ============================================================================\n\n/**\n * Input item for the Responses API.\n * Can be a message (developer/user) or a function call output.\n */\nexport type ResponsesInputItem =\n | { role: 'developer' | 'user'; content: string }\n | { type: 'function_call_output'; call_id: string; output: string }\n | ResponsesOutputItem\n\n/**\n * Output item from a Responses API call.\n * These can be added back to input for multi-turn conversations.\n */\nexport interface ResponsesOutputItem {\n type: 'message' | 'function_call' | 'reasoning'\n [key: string]: unknown\n}\n\n/**\n * Event yielded during Responses API streaming.\n */\nexport type ResponsesEvent =\n | { type: 'text_delta'; data: string }\n | { type: 'text'; data: string }\n | { type: 'reasoning'; content: string }\n | { type: 'tool_call'; id: string; callId: string; name: string; arguments: Record<string, unknown> }\n | { type: 'done'; usage: TokenUsage }\n\n/**\n * Input options for runResponses().\n */\nexport interface RunResponsesInput {\n /** Model to use (e.g., 'gpt-4o', 'o1', 'o3-mini') */\n model: string\n\n /** Input items for the conversation */\n input: ResponsesInputItem[]\n\n /** Enable streaming. When true, returns ResponsesStream. When false/undefined, returns Promise<RunResponsesResult>. */\n stream?: boolean\n\n /** Tool definitions for function calling */\n tools?: ToolDefinition[]\n\n /** Maximum output tokens */\n maxOutputTokens?: number\n\n /** Provider API key override */\n providerApiKey?: string\n\n /** AbortSignal to cancel the request (only used when stream: true) */\n signal?: AbortSignal\n\n /** Timeout in milliseconds */\n timeoutMs?: number\n\n /** Whether to send trace to Tracia (default: true) */\n sendTrace?: boolean\n\n /** Custom trace ID */\n traceId?: string\n\n /** Tags for the trace */\n tags?: string[]\n\n /** User ID for the trace */\n userId?: string\n\n /** Session ID for the trace */\n sessionId?: string\n}\n\n/**\n * Final result from a Responses API call.\n */\nexport interface RunResponsesResult {\n /** Final text output */\n text: string\n\n /** Trace ID for this request */\n traceId: string\n\n /** Latency in milliseconds */\n latencyMs: number\n\n /** Token usage */\n usage: TokenUsage\n\n /** Output items that can be added back to input for multi-turn */\n outputItems: ResponsesOutputItem[]\n\n /** Tool calls made by the model */\n toolCalls: Array<{ id: string; callId: string; name: string; arguments: Record<string, unknown> }>\n\n /** Whether the stream was aborted */\n aborted: boolean\n}\n\n/**\n * A streaming response from runResponses({ stream: true }).\n *\n * @example\n * ```typescript\n * const stream = tracia.runResponses({\n * model: 'o3-mini',\n * input: [\n * { role: 'developer', content: 'You are a helpful assistant.' },\n * { role: 'user', content: 'What is 2+2?' },\n * ],\n * stream: true,\n * })\n *\n * for await (const event of stream) {\n * if (event.type === 'text_delta') process.stdout.write(event.data)\n * if (event.type === 'reasoning') console.log('Thinking:', event.content)\n * if (event.type === 'tool_call') console.log('Tool:', event.name)\n * }\n *\n * const result = await stream.result\n * console.log('Output items:', result.outputItems)\n * ```\n */\nexport interface ResponsesStream {\n /** Trace ID for this request, available immediately */\n readonly traceId: string\n\n /** Async iterator yielding events */\n [Symbol.asyncIterator](): AsyncIterator<ResponsesEvent>\n\n /** Promise that resolves to the final result after stream completes */\n readonly result: Promise<RunResponsesResult>\n\n /** Abort the stream */\n abort(): void\n}\n","import { TraciaError } from './errors'\nimport {\n TraciaErrorCode,\n ApiErrorResponse,\n ApiSuccessResponse,\n} from './types'\n\nconst SDK_VERSION = process.env.SDK_VERSION || '0.0.0'\nconst DEFAULT_TIMEOUT_MS = 120000\n\ninterface HttpClientOptions {\n apiKey: string\n baseUrl: string\n}\n\ninterface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n path: string\n body?: unknown\n}\n\nfunction mapApiErrorCodeToTraciaErrorCode(apiCode: string): TraciaErrorCode {\n const codeMap: Record<string, TraciaErrorCode> = {\n UNAUTHORIZED: TraciaErrorCode.UNAUTHORIZED,\n NOT_FOUND: TraciaErrorCode.NOT_FOUND,\n CONFLICT: TraciaErrorCode.CONFLICT,\n MISSING_PROVIDER_KEY: TraciaErrorCode.MISSING_PROVIDER_KEY,\n PROVIDER_ERROR: TraciaErrorCode.PROVIDER_ERROR,\n MISSING_VARIABLES: TraciaErrorCode.MISSING_VARIABLES,\n INVALID_REQUEST: TraciaErrorCode.INVALID_REQUEST,\n }\n return codeMap[apiCode] ?? TraciaErrorCode.UNKNOWN\n}\n\nexport class HttpClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>({ method: 'GET', path })\n }\n\n async post<T = ApiSuccessResponse>(path: string, body: unknown): Promise<T> {\n return this.request<T>({ method: 'POST', path, body })\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>({ method: 'PUT', path, body })\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>({ method: 'DELETE', path })\n }\n\n private async request<T>(options: RequestOptions): Promise<T> {\n const url = `${this.baseUrl}${options.path}`\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS)\n\n try {\n const response = await fetch(url, {\n method: options.method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'User-Agent': `tracia-sdk/${SDK_VERSION}`,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n let errorData: ApiErrorResponse | undefined\n try {\n errorData = (await response.json()) as ApiErrorResponse\n } catch {\n throw new TraciaError(\n TraciaErrorCode.UNKNOWN,\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n )\n }\n\n if (errorData?.error) {\n const errorCode = mapApiErrorCodeToTraciaErrorCode(errorData.error.code)\n throw new TraciaError(errorCode, errorData.error.message, response.status)\n }\n\n throw new TraciaError(\n TraciaErrorCode.UNKNOWN,\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n )\n }\n\n return (await response.json()) as T\n } catch (error) {\n clearTimeout(timeoutId)\n\n if (error instanceof TraciaError) {\n throw error\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new TraciaError(\n TraciaErrorCode.TIMEOUT,\n `Request timed out after ${DEFAULT_TIMEOUT_MS}ms`\n )\n }\n\n throw new TraciaError(\n TraciaErrorCode.NETWORK_ERROR,\n `Network error: ${error.message}`\n )\n }\n\n throw new TraciaError(TraciaErrorCode.UNKNOWN, 'An unknown error occurred')\n }\n }\n}","import { HttpClient } from './client'\nimport {\n RunVariables,\n RunOptions,\n RunResult,\n ApiSuccessResponse,\n Prompt,\n PromptListItem,\n CreatePromptOptions,\n UpdatePromptOptions,\n ListPromptsResponse,\n DeletePromptResponse,\n} from './types'\n\ninterface RunRequestBody {\n variables?: RunVariables\n model?: string\n tags?: string[]\n userId?: string\n sessionId?: string\n}\n\nexport class Prompts {\n constructor(private readonly client: HttpClient) {}\n\n async list(): Promise<PromptListItem[]> {\n const response = await this.client.get<ListPromptsResponse>('/api/v1/prompts')\n return response.prompts\n }\n\n async get(slug: string): Promise<Prompt> {\n return this.client.get<Prompt>(`/api/v1/prompts/${encodeURIComponent(slug)}`)\n }\n\n async create(options: CreatePromptOptions): Promise<Prompt> {\n return this.client.post<Prompt>('/api/v1/prompts', options)\n }\n\n async update(slug: string, options: UpdatePromptOptions): Promise<Prompt> {\n return this.client.put<Prompt>(\n `/api/v1/prompts/${encodeURIComponent(slug)}`,\n options\n )\n }\n\n async delete(slug: string): Promise<void> {\n await this.client.delete<DeletePromptResponse>(\n `/api/v1/prompts/${encodeURIComponent(slug)}`\n )\n }\n\n async run(\n slug: string,\n variables?: RunVariables,\n options?: RunOptions\n ): Promise<RunResult> {\n const requestBody: RunRequestBody = {}\n\n if (variables && Object.keys(variables).length > 0) {\n requestBody.variables = variables\n }\n\n if (options?.model) {\n requestBody.model = options.model\n }\n\n if (options?.tags && options.tags.length > 0) {\n requestBody.tags = options.tags\n }\n\n if (options?.userId) {\n requestBody.userId = options.userId\n }\n\n if (options?.sessionId) {\n requestBody.sessionId = options.sessionId\n }\n\n const response = await this.client.post<ApiSuccessResponse>(\n `/api/v1/prompts/${encodeURIComponent(slug)}/run`,\n requestBody\n )\n\n return {\n text: response.text,\n traceId: response.traceId,\n promptVersion: response.promptVersion,\n latencyMs: response.latencyMs,\n usage: response.usage,\n cost: response.cost,\n }\n }\n}\n","import { LLMProvider } from './types'\n\nconst MODEL_TO_PROVIDER: Record<string, LLMProvider> = {\n // OpenAI\n 'chatgpt-4o-latest': LLMProvider.OPENAI,\n 'gpt-3.5-turbo': LLMProvider.OPENAI,\n 'gpt-3.5-turbo-0125': LLMProvider.OPENAI,\n 'gpt-3.5-turbo-1106': LLMProvider.OPENAI,\n 'gpt-3.5-turbo-16k': LLMProvider.OPENAI,\n 'gpt-4': LLMProvider.OPENAI,\n 'gpt-4-0125-preview': LLMProvider.OPENAI,\n 'gpt-4-1106-preview': LLMProvider.OPENAI,\n 'gpt-4-turbo': LLMProvider.OPENAI,\n 'gpt-4-turbo-2024-04-09': LLMProvider.OPENAI,\n 'gpt-4-turbo-preview': LLMProvider.OPENAI,\n 'gpt-4.1': LLMProvider.OPENAI,\n 'gpt-4.1-2025-04-14': LLMProvider.OPENAI,\n 'gpt-4.1-mini': LLMProvider.OPENAI,\n 'gpt-4.1-mini-2025-04-14': LLMProvider.OPENAI,\n 'gpt-4.1-nano': LLMProvider.OPENAI,\n 'gpt-4.1-nano-2025-04-14': LLMProvider.OPENAI,\n 'gpt-4o': LLMProvider.OPENAI,\n 'gpt-4o-2024-05-13': LLMProvider.OPENAI,\n 'gpt-4o-2024-08-06': LLMProvider.OPENAI,\n 'gpt-4o-2024-11-20': LLMProvider.OPENAI,\n 'gpt-4o-mini': LLMProvider.OPENAI,\n 'gpt-4o-mini-2024-07-18': LLMProvider.OPENAI,\n 'gpt-4o-mini-search-preview': LLMProvider.OPENAI,\n 'gpt-4o-mini-search-preview-2025-03-11': LLMProvider.OPENAI,\n 'gpt-4o-search-preview': LLMProvider.OPENAI,\n 'gpt-4o-search-preview-2025-03-11': LLMProvider.OPENAI,\n 'gpt-5': LLMProvider.OPENAI,\n 'gpt-5.1': LLMProvider.OPENAI,\n 'gpt-5.1-2025-11-13': LLMProvider.OPENAI,\n 'gpt-5.1-chat-latest': LLMProvider.OPENAI,\n 'gpt-5.2': LLMProvider.OPENAI,\n 'gpt-5.2-2025-12-11': LLMProvider.OPENAI,\n 'gpt-5.2-chat-latest': LLMProvider.OPENAI,\n 'gpt-5.2-pro': LLMProvider.OPENAI,\n 'gpt-5.2-pro-2025-12-11': LLMProvider.OPENAI,\n 'gpt-5-pro': LLMProvider.OPENAI,\n 'gpt-5-pro-2025-10-06': LLMProvider.OPENAI,\n 'gpt-5-2025-08-07': LLMProvider.OPENAI,\n 'gpt-5-chat-latest': LLMProvider.OPENAI,\n 'gpt-5-codex': LLMProvider.OPENAI,\n 'gpt-5.1-codex': LLMProvider.OPENAI,\n 'gpt-5.1-codex-max': LLMProvider.OPENAI,\n 'gpt-5.1-codex-mini': LLMProvider.OPENAI,\n 'gpt-5-mini': LLMProvider.OPENAI,\n 'gpt-5-mini-2025-08-07': LLMProvider.OPENAI,\n 'gpt-5-nano': LLMProvider.OPENAI,\n 'gpt-5-nano-2025-08-07': LLMProvider.OPENAI,\n 'o1': LLMProvider.OPENAI,\n 'o1-2024-12-17': LLMProvider.OPENAI,\n 'o1-pro': LLMProvider.OPENAI,\n 'o1-pro-2025-03-19': LLMProvider.OPENAI,\n 'o3': LLMProvider.OPENAI,\n 'o3-2025-04-16': LLMProvider.OPENAI,\n 'o3-mini': LLMProvider.OPENAI,\n 'o3-mini-2025-01-31': LLMProvider.OPENAI,\n 'o4-mini': LLMProvider.OPENAI,\n 'o4-mini-2025-04-16': LLMProvider.OPENAI,\n\n // Anthropic\n 'claude-haiku-4-5-20251001': LLMProvider.ANTHROPIC,\n 'claude-haiku-4-5': LLMProvider.ANTHROPIC,\n 'claude-3-7-sonnet-20250219': LLMProvider.ANTHROPIC,\n 'claude-3-haiku-20240307': LLMProvider.ANTHROPIC,\n 'claude-3-opus-20240229': LLMProvider.ANTHROPIC,\n 'claude-4-opus-20250514': LLMProvider.ANTHROPIC,\n 'claude-4-sonnet-20250514': LLMProvider.ANTHROPIC,\n 'claude-sonnet-4-5': LLMProvider.ANTHROPIC,\n 'claude-sonnet-4-5-20250929': LLMProvider.ANTHROPIC,\n 'claude-opus-4-1': LLMProvider.ANTHROPIC,\n 'claude-opus-4-1-20250805': LLMProvider.ANTHROPIC,\n 'claude-opus-4-20250514': LLMProvider.ANTHROPIC,\n 'claude-opus-4-5-20251101': LLMProvider.ANTHROPIC,\n 'claude-opus-4-5': LLMProvider.ANTHROPIC,\n 'claude-sonnet-4-20250514': LLMProvider.ANTHROPIC,\n\n // Google\n 'gemini-2.0-flash': LLMProvider.GOOGLE,\n 'gemini-2.0-flash-001': LLMProvider.GOOGLE,\n 'gemini-2.0-flash-exp': LLMProvider.GOOGLE,\n 'gemini-2.0-flash-lite': LLMProvider.GOOGLE,\n 'gemini-2.0-flash-lite-001': LLMProvider.GOOGLE,\n 'gemini-2.5-flash': LLMProvider.GOOGLE,\n 'gemini-2.5-flash-lite': LLMProvider.GOOGLE,\n 'gemini-2.5-flash-lite-preview-09-2025': LLMProvider.GOOGLE,\n 'gemini-2.5-flash-preview-09-2025': LLMProvider.GOOGLE,\n 'gemini-2.5-pro': LLMProvider.GOOGLE,\n 'gemini-3-pro-preview': LLMProvider.GOOGLE,\n 'gemini-3-flash-preview': LLMProvider.GOOGLE,\n}\n\nexport function getProviderForModel(modelId: string): LLMProvider | undefined {\n return MODEL_TO_PROVIDER[modelId]\n}\n","import { TraciaError } from '../errors'\nimport { getProviderForModel } from '../models'\nimport {\n LLMProvider,\n TraciaErrorCode,\n LocalPromptMessage,\n ToolDefinition,\n ToolChoice,\n ToolCall,\n FinishReason,\n TokenUsage,\n ResponsesInputItem,\n ResponsesOutputItem,\n ResponsesEvent,\n} from '../types'\n\nexport interface CompletionOptions {\n model: string\n messages: LocalPromptMessage[]\n apiKey: string\n provider?: LLMProvider\n temperature?: number\n maxOutputTokens?: number\n topP?: number\n stopSequences?: string[]\n tools?: ToolDefinition[]\n toolChoice?: ToolChoice\n timeoutMs?: number\n}\n\nexport interface CompletionResult {\n text: string\n inputTokens: number\n outputTokens: number\n totalTokens: number\n toolCalls: ToolCall[]\n finishReason: FinishReason\n provider: LLMProvider\n}\n\nexport interface StreamOptions extends CompletionOptions {\n signal?: AbortSignal\n}\n\nexport interface StreamResult {\n chunks: AsyncIterable<string>\n result: Promise<CompletionResult>\n}\n\nexport interface ResponsesOptions {\n model: string\n input: ResponsesInputItem[]\n apiKey: string\n tools?: ToolDefinition[]\n maxOutputTokens?: number\n timeoutMs?: number\n signal?: AbortSignal\n}\n\nexport interface ResponsesResult {\n text: string\n usage: TokenUsage\n outputItems: ResponsesOutputItem[]\n toolCalls: Array<{ id: string; callId: string; name: string; arguments: Record<string, unknown> }>\n aborted: boolean\n}\n\nexport interface ResponsesStreamResult {\n events: AsyncIterable<ResponsesEvent>\n result: Promise<ResponsesResult>\n}\n\ntype AISDKModule = typeof import('ai')\ntype OpenAIProviderModule = typeof import('@ai-sdk/openai')\ntype AnthropicProviderModule = typeof import('@ai-sdk/anthropic')\ntype GoogleProviderModule = typeof import('@ai-sdk/google')\n\nlet aiSdk: AISDKModule | null = null\nlet openaiProvider: OpenAIProviderModule | null = null\nlet anthropicProvider: AnthropicProviderModule | null = null\nlet googleProvider: GoogleProviderModule | null = null\n\nasync function loadAISdk(): Promise<AISDKModule> {\n if (aiSdk) return aiSdk\n try {\n aiSdk = await import('ai')\n return aiSdk\n } catch {\n throw new TraciaError(\n TraciaErrorCode.MISSING_PROVIDER_SDK,\n 'Vercel AI SDK not installed. Run: npm install ai'\n )\n }\n}\n\nasync function loadOpenAIProvider(): Promise<OpenAIProviderModule> {\n if (openaiProvider) return openaiProvider\n try {\n openaiProvider = await import('@ai-sdk/openai')\n return openaiProvider\n } catch {\n throw new TraciaError(\n TraciaErrorCode.MISSING_PROVIDER_SDK,\n 'OpenAI provider not installed. Run: npm install @ai-sdk/openai'\n )\n }\n}\n\nasync function loadAnthropicProvider(): Promise<AnthropicProviderModule> {\n if (anthropicProvider) return anthropicProvider\n try {\n anthropicProvider = await import('@ai-sdk/anthropic')\n return anthropicProvider\n } catch {\n throw new TraciaError(\n TraciaErrorCode.MISSING_PROVIDER_SDK,\n 'Anthropic provider not installed. Run: npm install @ai-sdk/anthropic'\n )\n }\n}\n\nasync function loadGoogleProvider(): Promise<GoogleProviderModule> {\n if (googleProvider) return googleProvider\n try {\n googleProvider = await import('@ai-sdk/google')\n return googleProvider\n } catch {\n throw new TraciaError(\n TraciaErrorCode.MISSING_PROVIDER_SDK,\n 'Google provider not installed. Run: npm install @ai-sdk/google'\n )\n }\n}\n\n/**\n * Combines multiple abort signals into one, with proper cleanup to prevent memory leaks.\n * Returns undefined if no signals need to be combined.\n */\nfunction combineAbortSignals(userSignal?: AbortSignal, timeoutMs?: number): AbortSignal | undefined {\n if (!timeoutMs && !userSignal) return undefined\n if (timeoutMs && !userSignal) return AbortSignal.timeout(timeoutMs)\n if (!timeoutMs && userSignal) return userSignal\n\n const timeoutSignal = AbortSignal.timeout(timeoutMs!)\n const controller = new AbortController()\n\n const cleanup = () => {\n userSignal!.removeEventListener('abort', onAbort)\n timeoutSignal.removeEventListener('abort', onAbort)\n }\n\n const onAbort = () => {\n cleanup()\n controller.abort()\n }\n\n userSignal!.addEventListener('abort', onAbort, { once: true })\n timeoutSignal.addEventListener('abort', onAbort, { once: true })\n\n return controller.signal\n}\n\n/**\n * Sanitizes error messages to prevent leaking sensitive information like API keys.\n * Removes common patterns that might contain credentials.\n */\nfunction sanitizeErrorMessage(message: string): string {\n return message\n // Remove potential API keys (sk-xxx, tr_xxx, key-xxx patterns)\n .replace(/\\b(sk-|tr_|key-|api[_-]?key[=:\\s]+)[a-zA-Z0-9_-]{10,}\\b/gi, '[REDACTED]')\n // Remove Bearer tokens\n .replace(/Bearer\\s+[a-zA-Z0-9_.-]+/gi, 'Bearer [REDACTED]')\n // Remove base64-encoded credentials\n .replace(/Basic\\s+[a-zA-Z0-9+/=]{20,}/gi, 'Basic [REDACTED]')\n // Remove authorization headers content\n .replace(/(authorization[=:\\s]+)[^\\s,}]+/gi, '$1[REDACTED]')\n}\n\nexport function resolveProvider(model: string, explicitProvider?: LLMProvider): LLMProvider {\n if (explicitProvider) return explicitProvider\n\n const fromRegistry = getProviderForModel(model)\n if (fromRegistry) return fromRegistry\n\n if (model.startsWith('gpt-') || model.startsWith('o1') || model.startsWith('o3') || model.startsWith('o4')) {\n return LLMProvider.OPENAI\n }\n if (model.startsWith('claude-')) {\n return LLMProvider.ANTHROPIC\n }\n if (model.startsWith('gemini-')) {\n return LLMProvider.GOOGLE\n }\n\n throw new TraciaError(\n TraciaErrorCode.UNSUPPORTED_MODEL,\n `Cannot determine provider for model: ${model}. Specify provider explicitly.`\n )\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function getLanguageModel(provider: LLMProvider, model: string, apiKey: string): Promise<any> {\n switch (provider) {\n case LLMProvider.OPENAI: {\n const { createOpenAI } = await loadOpenAIProvider()\n const openai = createOpenAI({ apiKey })\n return openai(model)\n }\n case LLMProvider.ANTHROPIC: {\n const { createAnthropic } = await loadAnthropicProvider()\n const anthropic = createAnthropic({ apiKey })\n return anthropic(model)\n }\n case LLMProvider.GOOGLE: {\n const { createGoogleGenerativeAI } = await loadGoogleProvider()\n const google = createGoogleGenerativeAI({ apiKey })\n return google(model)\n }\n default:\n throw new TraciaError(\n TraciaErrorCode.UNSUPPORTED_MODEL,\n `Unsupported provider: ${provider}`\n )\n }\n}\n\n/**\n * Converts Tracia messages to AI SDK v6 ModelMessage format.\n */\nfunction convertMessages(messages: LocalPromptMessage[]): Array<{\n role: 'system' | 'user' | 'assistant' | 'tool'\n content: string | Array<{ type: string; text?: string; toolCallId?: string; toolName?: string; input?: unknown; output?: unknown }>\n}> {\n return messages.map(msg => {\n // Tool messages: convert from simple format { role: 'tool', toolCallId, toolName, content: string }\n // to AI SDK format { role: 'tool', content: [{ type: 'tool-result', ... }] }\n if (msg.role === 'tool') {\n return {\n role: 'tool' as const,\n content: [{\n type: 'tool-result',\n toolCallId: msg.toolCallId,\n toolName: msg.toolName ?? msg.toolCallId, // Use toolName, fallback to toolCallId\n output: { type: 'text', value: msg.content as string },\n }],\n }\n }\n\n // Assistant messages with array content: convert tool_call parts to AI SDK tool-call format\n if (msg.role === 'assistant' && Array.isArray(msg.content)) {\n if (msg.content.length === 0) {\n return { role: 'assistant' as const, content: '' }\n }\n const convertedContent = msg.content.map(part => {\n if (part.type === 'tool_call') {\n const toolCall = part as { type: 'tool_call'; id: string; name: string; arguments: Record<string, unknown> }\n return {\n type: 'tool-call',\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n input: toolCall.arguments,\n }\n }\n return part // TextPart passes through unchanged\n })\n return {\n role: 'assistant' as const,\n content: convertedContent,\n }\n }\n\n // System/user/assistant messages with string content: pass through\n return {\n role: msg.role as 'system' | 'user' | 'assistant',\n content: typeof msg.content === 'string'\n ? msg.content\n : msg.content.map(b => b.type === 'text' ? (b as { text: string }).text : '').join(''),\n }\n })\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function convertTools(tools?: ToolDefinition[]): Promise<Record<string, any> | undefined> {\n if (!tools || tools.length === 0) return undefined\n\n const { tool, jsonSchema } = await loadAISdk()\n\n const result: Record<string, any> = {}\n for (const toolDef of tools) {\n result[toolDef.name] = tool({\n description: toolDef.description,\n inputSchema: jsonSchema(toolDef.parameters),\n execute: async (args: any) => args, // No-op execute function\n })\n }\n\n return result\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction convertToolChoice(toolChoice?: ToolChoice): any {\n if (!toolChoice) return undefined\n if (toolChoice === 'auto') return 'auto'\n if (toolChoice === 'none') return 'none'\n if (toolChoice === 'required') return 'required'\n return { type: 'tool', toolName: toolChoice.tool }\n}\n\nfunction parseFinishReason(reason?: string): FinishReason {\n if (reason === 'tool-calls') return 'tool_calls'\n if (reason === 'length') return 'max_tokens'\n return 'stop'\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction extractToolCalls(toolCalls?: any[]): ToolCall[] {\n if (!toolCalls) return []\n return toolCalls\n .filter(tc => tc.toolCallId && tc.toolName)\n .map(tc => ({\n id: tc.toolCallId,\n name: tc.toolName,\n arguments: (tc.input as Record<string, unknown>) ?? {},\n }))\n}\n\nexport async function complete(options: CompletionOptions): Promise<CompletionResult> {\n const { generateText } = await loadAISdk()\n const provider = resolveProvider(options.model, options.provider)\n const model = await getLanguageModel(provider, options.model, options.apiKey)\n\n const convertedMessages = convertMessages(options.messages)\n const convertedTools = await convertTools(options.tools)\n const convertedToolChoice = convertToolChoice(options.toolChoice)\n\n try {\n const result = await generateText({\n model,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: convertedMessages as any,\n temperature: options.temperature,\n maxOutputTokens: options.maxOutputTokens,\n topP: options.topP,\n stopSequences: options.stopSequences,\n tools: convertedTools,\n toolChoice: convertedToolChoice,\n abortSignal: options.timeoutMs ? AbortSignal.timeout(options.timeoutMs) : undefined,\n })\n\n const toolCalls = extractToolCalls(result.toolCalls)\n\n return {\n text: result.text,\n inputTokens: result.usage?.inputTokens ?? 0,\n outputTokens: result.usage?.outputTokens ?? 0,\n totalTokens: result.usage?.totalTokens ?? 0,\n toolCalls,\n finishReason: parseFinishReason(result.finishReason),\n provider,\n }\n } catch (error) {\n if (error instanceof TraciaError) throw error\n const rawMessage = error instanceof Error ? error.message : String(error)\n throw new TraciaError(\n TraciaErrorCode.PROVIDER_ERROR,\n `${provider} error: ${sanitizeErrorMessage(rawMessage)}`\n )\n }\n}\n\nexport function stream(options: StreamOptions): StreamResult {\n const provider = resolveProvider(options.model, options.provider)\n\n let resolveResult: (result: CompletionResult) => void\n let rejectResult: (error: Error) => void\n const resultPromise = new Promise<CompletionResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n\n async function* generateChunks(): AsyncGenerator<string> {\n try {\n const { streamText } = await loadAISdk()\n const model = await getLanguageModel(provider, options.model, options.apiKey)\n\n const convertedMessages = convertMessages(options.messages)\n const convertedTools = await convertTools(options.tools)\n const convertedToolChoice = convertToolChoice(options.toolChoice)\n const abortSignal = combineAbortSignals(options.signal, options.timeoutMs)\n\n const result = streamText({\n model,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: convertedMessages as any,\n temperature: options.temperature,\n maxOutputTokens: options.maxOutputTokens,\n topP: options.topP,\n stopSequences: options.stopSequences,\n tools: convertedTools,\n toolChoice: convertedToolChoice,\n abortSignal,\n })\n\n for await (const chunk of result.textStream) {\n yield chunk\n }\n\n const [text, usageData, toolCallsData, finishReasonData] = await Promise.all([\n result.text,\n result.usage,\n result.toolCalls,\n result.finishReason,\n ])\n const toolCalls = extractToolCalls(toolCallsData)\n\n resolveResult!({\n text,\n inputTokens: usageData?.inputTokens ?? 0,\n outputTokens: usageData?.outputTokens ?? 0,\n totalTokens: usageData?.totalTokens ?? 0,\n toolCalls,\n finishReason: parseFinishReason(finishReasonData),\n provider,\n })\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n const traciaError = new TraciaError(TraciaErrorCode.ABORTED, 'Stream aborted')\n rejectResult!(traciaError)\n throw traciaError\n }\n const rawMessage = error instanceof Error ? error.message : String(error)\n const traciaError = error instanceof TraciaError\n ? error\n : new TraciaError(\n TraciaErrorCode.PROVIDER_ERROR,\n `${provider} error: ${sanitizeErrorMessage(rawMessage)}`\n )\n rejectResult!(traciaError)\n throw traciaError\n }\n }\n\n return {\n chunks: generateChunks(),\n result: resultPromise,\n }\n}\n\nexport function responsesStream(options: ResponsesOptions): ResponsesStreamResult {\n let resolveResult: (result: ResponsesResult) => void\n let rejectResult: (error: Error) => void\n const resultPromise = new Promise<ResponsesResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n\n async function* generateEvents(): AsyncGenerator<ResponsesEvent> {\n let fullText = ''\n let usage: TokenUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 }\n const outputItems: ResponsesOutputItem[] = []\n const toolCalls: Array<{ id: string; callId: string; name: string; arguments: Record<string, unknown> }> = []\n let aborted = false\n\n try {\n const { createOpenAI } = await loadOpenAIProvider()\n const openai = createOpenAI({ apiKey: options.apiKey })\n const model = openai.responses(options.model)\n\n const { streamText } = await loadAISdk()\n\n // Convert tools for Responses API\n const convertedTools = options.tools ? await convertTools(options.tools) : undefined\n const abortSignal = combineAbortSignals(options.signal, options.timeoutMs)\n\n const result = streamText({\n model,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: options.input as any,\n maxOutputTokens: options.maxOutputTokens,\n tools: convertedTools,\n abortSignal,\n })\n\n for await (const chunk of result.textStream) {\n fullText += chunk\n yield { type: 'text_delta', data: chunk }\n }\n\n const [usageData, toolCallsData] = await Promise.all([\n result.usage,\n result.toolCalls,\n ])\n\n usage = {\n inputTokens: usageData?.inputTokens ?? 0,\n outputTokens: usageData?.outputTokens ?? 0,\n totalTokens: usageData?.totalTokens ?? 0,\n }\n\n if (toolCallsData) {\n for (const tc of toolCallsData) {\n // Validate required fields before using\n if (!tc.toolCallId || !tc.toolName) continue\n const toolCall = {\n id: tc.toolCallId,\n callId: tc.toolCallId,\n name: tc.toolName,\n arguments: (tc.input as Record<string, unknown>) ?? {},\n }\n toolCalls.push(toolCall)\n yield {\n type: 'tool_call',\n id: toolCall.id,\n callId: toolCall.callId,\n name: toolCall.name,\n arguments: toolCall.arguments,\n }\n }\n }\n\n if (fullText) {\n yield { type: 'text', data: fullText }\n outputItems.push({ type: 'message', content: fullText })\n }\n\n yield { type: 'done', usage }\n\n resolveResult!({\n text: fullText,\n usage,\n outputItems,\n toolCalls,\n aborted,\n })\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n aborted = true\n resolveResult!({\n text: fullText,\n usage,\n outputItems,\n toolCalls,\n aborted,\n })\n return\n }\n const rawMessage = error instanceof Error ? error.message : String(error)\n const traciaError = new TraciaError(\n TraciaErrorCode.PROVIDER_ERROR,\n `OpenAI Responses API error: ${sanitizeErrorMessage(rawMessage)}`\n )\n rejectResult!(traciaError)\n throw traciaError\n }\n }\n\n return {\n events: generateEvents(),\n result: resultPromise,\n }\n}\n","import { HttpClient } from './client'\nimport { TraciaError } from './errors'\nimport {\n Trace,\n ListTracesOptions,\n ListTracesResult,\n EvaluateOptions,\n EvaluateResult,\n TraciaErrorCode,\n CreateTracePayload,\n CreateTraceResult,\n} from './types'\n\n/** @internal Symbol for setting pending traces map - not part of public API */\nexport const INTERNAL_SET_PENDING_TRACES = Symbol('setPendingTracesMap')\n\nexport class Traces {\n private pendingTraces: Map<string, Promise<void>> | null = null\n\n constructor(private readonly client: HttpClient) {}\n\n /** @internal */\n [INTERNAL_SET_PENDING_TRACES](map: Map<string, Promise<void>>): void {\n this.pendingTraces = map\n }\n\n async create(payload: CreateTracePayload): Promise<CreateTraceResult> {\n return this.client.post<CreateTraceResult>('/api/v1/traces', payload)\n }\n\n async get(traceId: string): Promise<Trace> {\n return this.client.get<Trace>(`/api/v1/traces/${encodeURIComponent(traceId)}`)\n }\n\n async list(options?: ListTracesOptions): Promise<ListTracesResult> {\n const params = new URLSearchParams()\n\n if (options?.promptSlug) {\n params.set('promptSlug', options.promptSlug)\n }\n\n if (options?.status) {\n params.set('status', options.status)\n }\n\n if (options?.startDate) {\n params.set('startDate', options.startDate.toISOString())\n }\n\n if (options?.endDate) {\n params.set('endDate', options.endDate.toISOString())\n }\n\n if (options?.userId) {\n params.set('userId', options.userId)\n }\n\n if (options?.sessionId) {\n params.set('sessionId', options.sessionId)\n }\n\n if (options?.tags && options.tags.length > 0) {\n params.set('tags', options.tags.join(','))\n }\n\n if (options?.limit) {\n params.set('limit', String(options.limit))\n }\n\n if (options?.cursor) {\n params.set('cursor', options.cursor)\n }\n\n const query = params.toString()\n const path = query ? `/api/v1/traces?${query}` : '/api/v1/traces'\n\n return this.client.get<ListTracesResult>(path)\n }\n\n async evaluate(traceId: string, options: EvaluateOptions): Promise<EvaluateResult> {\n if (this.pendingTraces) {\n const pendingTrace = this.pendingTraces.get(traceId)\n if (pendingTrace) {\n await pendingTrace\n }\n }\n\n if (typeof options.value !== 'number') {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n `Invalid evaluation value. Must be a number.`\n )\n }\n\n const body: { evaluatorKey: string; value: number; note?: string } = {\n evaluatorKey: options.evaluator,\n value: options.value,\n }\n\n if (options.note !== undefined) {\n body.note = options.note\n }\n\n return this.client.post<EvaluateResult>(\n `/api/v1/traces/${encodeURIComponent(traceId)}/evaluations`,\n body\n )\n }\n}\n","import crypto from 'crypto'\n\nconst TRACE_ID_REGEX = /^tr_[a-f0-9]{16}$/i\n\nexport function generateTraceId(): string {\n const randomPart = crypto.randomBytes(8).toString('hex')\n return `tr_${randomPart}`\n}\n\nexport function isValidTraceIdFormat(traceId: string): boolean {\n return TRACE_ID_REGEX.test(traceId)\n}\n","import { HttpClient } from './client'\nimport { TraciaError } from './errors'\nimport { Prompts } from './prompts'\nimport {\n complete,\n stream,\n responsesStream,\n resolveProvider,\n CompletionResult,\n} from './providers'\nimport { Traces, INTERNAL_SET_PENDING_TRACES } from './traces'\nimport {\n TraciaOptions,\n TraciaErrorCode,\n LLMProvider,\n LocalPromptMessage,\n RunLocalInput,\n RunLocalResult,\n StreamResult,\n LocalStream,\n TraceStatus,\n ToolCall,\n ContentPart,\n RunResponsesInput,\n RunResponsesResult,\n ResponsesStream,\n ResponsesEvent,\n ResponsesInputItem,\n} from './types'\nimport { generateTraceId, isValidTraceIdFormat } from './utils'\n\nexport { TraciaError } from './errors'\nexport type {\n TraciaOptions,\n RunVariables,\n RunOptions,\n RunResult,\n TokenUsage,\n Prompt,\n PromptListItem,\n PromptMessage,\n MessageRole,\n CreatePromptOptions,\n UpdatePromptOptions,\n Trace,\n TraceListItem,\n TraceStatus,\n ListTracesOptions,\n ListTracesResult,\n EvaluateOptions,\n EvaluateResult,\n LocalPromptMessage,\n RunLocalInput,\n RunLocalResult,\n StreamResult,\n LocalStream,\n CreateTracePayload,\n CreateTraceResult,\n ToolDefinition,\n ToolParameters,\n JsonSchemaProperty,\n ToolCall,\n ToolChoice,\n FinishReason,\n // Message content parts\n TextPart,\n ToolCallPart,\n ContentPart,\n // Responses API types\n ResponsesInputItem,\n ResponsesOutputItem,\n ResponsesEvent,\n RunResponsesInput,\n RunResponsesResult,\n ResponsesStream,\n} from './types'\nexport { TraciaErrorCode, LLMProvider } from './types'\n\nexport const Eval = {\n POSITIVE: 1,\n NEGATIVE: 0,\n} as const\n\nconst DEFAULT_BASE_URL = 'https://app.tracia.io'\nconst MAX_PENDING_TRACES = 1000\nconst TRACE_RETRY_ATTEMPTS = 2\nconst TRACE_RETRY_DELAY_MS = 500\n\nconst TRACE_STATUS_SUCCESS: TraceStatus = 'SUCCESS'\nconst TRACE_STATUS_ERROR: TraceStatus = 'ERROR'\n\nconst ENV_VAR_MAP: Record<LLMProvider, string> = {\n [LLMProvider.OPENAI]: 'OPENAI_API_KEY',\n [LLMProvider.ANTHROPIC]: 'ANTHROPIC_API_KEY',\n [LLMProvider.GOOGLE]: 'GOOGLE_API_KEY',\n}\n\nfunction convertResponsesItemToMessage(item: ResponsesInputItem): LocalPromptMessage {\n if ('role' in item && (item.role === 'developer' || item.role === 'user')) {\n const messageItem = item as { role: 'developer' | 'user'; content: string }\n return {\n role: messageItem.role === 'developer' ? 'system' : 'user',\n content: messageItem.content,\n }\n }\n\n if ('type' in item && item.type === 'function_call_output') {\n // Convert Responses API function_call_output to Tracia tool message format\n const outputItem = item as { type: 'function_call_output'; call_id: string; output: string }\n return {\n role: 'tool',\n toolCallId: outputItem.call_id,\n content: outputItem.output,\n }\n }\n\n if ('type' in item) {\n return {\n role: 'assistant',\n content: JSON.stringify(item),\n }\n }\n\n return {\n role: 'user',\n content: JSON.stringify(item),\n }\n}\n\nexport class Tracia {\n private readonly client: HttpClient\n private readonly pendingTraces = new Map<string, Promise<void>>()\n private readonly onTraceError?: (error: Error, traceId: string) => void\n readonly prompts: Prompts\n readonly traces: Traces\n\n constructor(options: TraciaOptions) {\n if (!options.apiKey) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'apiKey is required'\n )\n }\n\n this.client = new HttpClient({\n apiKey: options.apiKey,\n baseUrl: DEFAULT_BASE_URL,\n })\n\n this.onTraceError = options.onTraceError\n this.prompts = new Prompts(this.client)\n this.traces = new Traces(this.client)\n this.traces[INTERNAL_SET_PENDING_TRACES](this.pendingTraces)\n }\n\n /**\n * Execute an LLM call locally using the Vercel AI SDK.\n *\n * @example Non-streaming (default)\n * ```typescript\n * const result = await tracia.runLocal({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Hello' }],\n * })\n * console.log(result.text)\n * ```\n *\n * @example Streaming\n * ```typescript\n * const stream = tracia.runLocal({\n * model: 'gpt-4o',\n * messages: [{ role: 'user', content: 'Write a poem' }],\n * stream: true,\n * })\n *\n * for await (const chunk of stream) {\n * process.stdout.write(chunk)\n * }\n *\n * const result = await stream.result\n * console.log('Tokens used:', result.usage.totalTokens)\n * ```\n */\n runLocal(input: RunLocalInput & { stream: true }): LocalStream\n runLocal(input: RunLocalInput & { stream?: false }): Promise<RunLocalResult>\n runLocal(input: RunLocalInput): Promise<RunLocalResult> | LocalStream {\n if (input.stream === true) {\n return this.runLocalStreaming(input)\n }\n return this.runLocalNonStreaming(input)\n }\n\n private async runLocalNonStreaming(input: RunLocalInput): Promise<RunLocalResult> {\n this.validateRunLocalInput(input)\n\n let traceId = ''\n if (input.sendTrace !== false) {\n if (input.traceId && !isValidTraceIdFormat(input.traceId)) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n `Invalid trace ID format. Must match: tr_ + 16 hex characters (e.g., tr_1234567890abcdef)`\n )\n }\n traceId = input.traceId || generateTraceId()\n }\n\n const interpolatedMessages = this.interpolateMessages(input.messages, input.variables)\n const provider = resolveProvider(input.model, input.provider)\n const apiKey = this.getProviderApiKey(provider, input.providerApiKey)\n\n const startTime = Date.now()\n let completionResult: CompletionResult | null = null\n let errorMessage: string | null = null\n\n try {\n completionResult = await complete({\n model: input.model,\n messages: interpolatedMessages,\n apiKey,\n provider: input.provider,\n temperature: input.temperature,\n maxOutputTokens: input.maxOutputTokens,\n topP: input.topP,\n stopSequences: input.stopSequences,\n tools: input.tools,\n toolChoice: input.toolChoice,\n timeoutMs: input.timeoutMs,\n })\n } catch (error) {\n if (error instanceof TraciaError) {\n errorMessage = error.message\n } else {\n errorMessage = error instanceof Error ? error.message : String(error)\n }\n }\n\n const latencyMs = Date.now() - startTime\n\n if (traceId) {\n this.scheduleTraceCreation(traceId, {\n traceId,\n model: input.model,\n provider: completionResult?.provider ?? provider,\n input: { messages: interpolatedMessages },\n variables: input.variables ?? null,\n output: completionResult?.text ?? null,\n status: errorMessage ? TRACE_STATUS_ERROR : TRACE_STATUS_SUCCESS,\n error: errorMessage,\n latencyMs,\n inputTokens: completionResult?.inputTokens ?? 0,\n outputTokens: completionResult?.outputTokens ?? 0,\n totalTokens: completionResult?.totalTokens ?? 0,\n tags: input.tags,\n userId: input.userId,\n sessionId: input.sessionId,\n temperature: input.temperature,\n maxOutputTokens: input.maxOutputTokens,\n topP: input.topP,\n tools: input.tools,\n toolCalls: completionResult?.toolCalls,\n })\n }\n\n if (errorMessage) {\n throw new TraciaError(TraciaErrorCode.PROVIDER_ERROR, errorMessage)\n }\n\n const toolCalls = completionResult!.toolCalls\n const finishReason = completionResult!.finishReason\n const message = this.buildAssistantMessage(completionResult!.text, toolCalls)\n\n return {\n text: completionResult!.text,\n traceId,\n latencyMs,\n usage: {\n inputTokens: completionResult!.inputTokens,\n outputTokens: completionResult!.outputTokens,\n totalTokens: completionResult!.totalTokens,\n },\n cost: null,\n provider: completionResult!.provider,\n model: input.model,\n toolCalls,\n finishReason,\n message,\n }\n }\n\n private runLocalStreaming(input: RunLocalInput): LocalStream {\n this.validateRunLocalInput(input)\n\n let traceId = ''\n if (input.sendTrace !== false) {\n if (input.traceId && !isValidTraceIdFormat(input.traceId)) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n `Invalid trace ID format. Must match: tr_ + 16 hex characters (e.g., tr_1234567890abcdef)`\n )\n }\n traceId = input.traceId || generateTraceId()\n }\n\n const interpolatedMessages = this.interpolateMessages(input.messages, input.variables)\n const provider = resolveProvider(input.model, input.provider)\n const apiKey = this.getProviderApiKey(provider, input.providerApiKey)\n\n const abortController = new AbortController()\n const combinedSignal = input.signal\n ? this.combineAbortSignals(input.signal, abortController.signal)\n : abortController.signal\n\n return this.createLocalStream(\n input,\n interpolatedMessages,\n provider,\n apiKey,\n traceId,\n combinedSignal,\n abortController\n )\n }\n\n /**\n * Execute an LLM call using OpenAI's Responses API.\n *\n * The Responses API is OpenAI-specific and supports:\n * - Reasoning models (o1, o3-mini) with reasoning summaries\n * - Multi-turn conversations with output items\n * - Different input format (developer/user roles, function_call_output)\n *\n * @example Non-streaming (default)\n * ```typescript\n * const result = await tracia.runResponses({\n * model: 'o3-mini',\n * input: [\n * { role: 'developer', content: 'You are helpful.' },\n * { role: 'user', content: 'What is 2+2?' },\n * ],\n * })\n * console.log(result.text)\n * ```\n *\n * @example Streaming\n * ```typescript\n * const stream = tracia.runResponses({\n * model: 'o3-mini',\n * input: [\n * { role: 'developer', content: 'You are helpful.' },\n * { role: 'user', content: 'What is 2+2?' },\n * ],\n * stream: true,\n * })\n *\n * for await (const event of stream) {\n * if (event.type === 'text_delta') process.stdout.write(event.data)\n * if (event.type === 'reasoning') console.log('Reasoning:', event.content)\n * if (event.type === 'tool_call') console.log('Tool:', event.name, event.arguments)\n * }\n *\n * const result = await stream.result\n * console.log('Output items:', result.outputItems)\n * ```\n */\n runResponses(input: RunResponsesInput & { stream: true }): ResponsesStream\n runResponses(input: RunResponsesInput & { stream?: false }): Promise<RunResponsesResult>\n runResponses(input: RunResponsesInput): Promise<RunResponsesResult> | ResponsesStream {\n if (input.stream === true) {\n return this.runResponsesStreaming(input)\n }\n return this.runResponsesNonStreaming(input)\n }\n\n private async runResponsesNonStreaming(input: RunResponsesInput): Promise<RunResponsesResult> {\n const stream = this.runResponsesStreaming(input)\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n for await (const _event of stream) {\n // Consume events\n }\n\n return stream.result\n }\n\n private runResponsesStreaming(input: RunResponsesInput): ResponsesStream {\n this.validateResponsesInput(input)\n\n let traceId = ''\n if (input.sendTrace !== false) {\n if (input.traceId && !isValidTraceIdFormat(input.traceId)) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n `Invalid trace ID format. Must match: tr_ + 16 hex characters (e.g., tr_1234567890abcdef)`\n )\n }\n traceId = input.traceId || generateTraceId()\n }\n\n const apiKey = this.getProviderApiKey(LLMProvider.OPENAI, input.providerApiKey)\n\n const abortController = new AbortController()\n const combinedSignal = input.signal\n ? this.combineAbortSignals(input.signal, abortController.signal)\n : abortController.signal\n\n return this.createResponsesStream(\n input,\n apiKey,\n traceId,\n combinedSignal,\n abortController\n )\n }\n\n private validateResponsesInput(input: RunResponsesInput): void {\n if (!input.model || input.model.trim() === '') {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'model is required and cannot be empty'\n )\n }\n\n if (!input.input || input.input.length === 0) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'input array is required and cannot be empty'\n )\n }\n }\n\n private createResponsesStream(\n input: RunResponsesInput,\n apiKey: string,\n traceId: string,\n signal: AbortSignal,\n abortController: AbortController\n ): ResponsesStream {\n const startTime = Date.now()\n let aborted = false\n let resolveResult: (result: RunResponsesResult) => void\n let rejectResult: (error: Error) => void\n\n const resultPromise = new Promise<RunResponsesResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n\n const providerStream = responsesStream({\n model: input.model,\n input: input.input,\n apiKey,\n tools: input.tools,\n maxOutputTokens: input.maxOutputTokens,\n timeoutMs: input.timeoutMs,\n signal,\n })\n\n let collectedText = ''\n const scheduleTrace = this.scheduleTraceCreation.bind(this)\n\n async function* wrappedEvents(): AsyncGenerator<ResponsesEvent> {\n try {\n for await (const event of providerStream.events) {\n if (event.type === 'text_delta') {\n collectedText += event.data\n }\n yield event\n }\n\n const providerResult = await providerStream.result\n const latencyMs = Date.now() - startTime\n\n if (traceId) {\n scheduleTrace(traceId, {\n traceId,\n model: input.model,\n provider: LLMProvider.OPENAI,\n input: { messages: input.input.map(item => convertResponsesItemToMessage(item)) },\n variables: null,\n output: providerResult.text,\n status: providerResult.aborted ? TRACE_STATUS_ERROR : TRACE_STATUS_SUCCESS,\n error: providerResult.aborted ? 'Stream aborted' : null,\n latencyMs,\n inputTokens: providerResult.usage.inputTokens,\n outputTokens: providerResult.usage.outputTokens,\n totalTokens: providerResult.usage.totalTokens,\n tags: input.tags,\n userId: input.userId,\n sessionId: input.sessionId,\n tools: input.tools,\n toolCalls: providerResult.toolCalls.map(tc => ({\n id: tc.id,\n name: tc.name,\n arguments: tc.arguments,\n })),\n })\n }\n\n resolveResult!({\n text: providerResult.text,\n traceId,\n latencyMs,\n usage: providerResult.usage,\n outputItems: providerResult.outputItems,\n toolCalls: providerResult.toolCalls,\n aborted: providerResult.aborted,\n })\n } catch (error) {\n const latencyMs = Date.now() - startTime\n const isAborted = aborted || signal.aborted\n const errorMessage = isAborted\n ? 'Stream aborted'\n : error instanceof Error\n ? error.message\n : String(error)\n\n if (traceId) {\n scheduleTrace(traceId, {\n traceId,\n model: input.model,\n provider: LLMProvider.OPENAI,\n input: { messages: input.input.map(item => convertResponsesItemToMessage(item)) },\n variables: null,\n output: collectedText || null,\n status: TRACE_STATUS_ERROR,\n error: errorMessage,\n latencyMs,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n tags: input.tags,\n userId: input.userId,\n sessionId: input.sessionId,\n tools: input.tools,\n })\n }\n\n if (isAborted) {\n resolveResult!({\n text: collectedText,\n traceId,\n latencyMs,\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n outputItems: [],\n toolCalls: [],\n aborted: true,\n })\n } else {\n const traciaError =\n error instanceof TraciaError\n ? error\n : new TraciaError(TraciaErrorCode.PROVIDER_ERROR, errorMessage)\n rejectResult!(traciaError)\n throw traciaError\n }\n }\n }\n\n const asyncIterator = wrappedEvents()\n\n return {\n traceId,\n [Symbol.asyncIterator]() {\n return asyncIterator\n },\n result: resultPromise,\n abort() {\n aborted = true\n abortController.abort()\n },\n }\n }\n\n private createLocalStream(\n input: RunLocalInput,\n interpolatedMessages: LocalPromptMessage[],\n provider: LLMProvider,\n apiKey: string,\n traceId: string,\n signal: AbortSignal,\n abortController: AbortController\n ): LocalStream {\n const startTime = Date.now()\n let aborted = false\n let resolveResult: (result: StreamResult) => void\n let rejectResult: (error: Error) => void\n\n const resultPromise = new Promise<StreamResult>((resolve, reject) => {\n resolveResult = resolve\n rejectResult = reject\n })\n\n const providerStream = stream({\n model: input.model,\n messages: interpolatedMessages,\n apiKey,\n provider: input.provider,\n temperature: input.temperature,\n maxOutputTokens: input.maxOutputTokens,\n topP: input.topP,\n stopSequences: input.stopSequences,\n tools: input.tools,\n toolChoice: input.toolChoice,\n timeoutMs: input.timeoutMs,\n signal,\n })\n\n let collectedText = ''\n const scheduleTrace = this.scheduleTraceCreation.bind(this)\n const buildAssistantMessage = this.buildAssistantMessage.bind(this)\n\n async function* wrappedChunks(): AsyncGenerator<string> {\n try {\n for await (const chunk of providerStream.chunks) {\n collectedText += chunk\n yield chunk\n }\n\n const completionResult = await providerStream.result\n const latencyMs = Date.now() - startTime\n\n if (traceId) {\n scheduleTrace(traceId, {\n traceId,\n model: input.model,\n provider: completionResult.provider,\n input: { messages: interpolatedMessages },\n variables: input.variables ?? null,\n output: completionResult.text,\n status: TRACE_STATUS_SUCCESS,\n error: null,\n latencyMs,\n inputTokens: completionResult.inputTokens,\n outputTokens: completionResult.outputTokens,\n totalTokens: completionResult.totalTokens,\n tags: input.tags,\n userId: input.userId,\n sessionId: input.sessionId,\n temperature: input.temperature,\n maxOutputTokens: input.maxOutputTokens,\n topP: input.topP,\n tools: input.tools,\n toolCalls: completionResult.toolCalls,\n })\n }\n\n const toolCalls = completionResult.toolCalls\n const finishReason = completionResult.finishReason\n const message = buildAssistantMessage(completionResult.text, toolCalls)\n\n resolveResult!({\n text: completionResult.text,\n traceId,\n latencyMs,\n usage: {\n inputTokens: completionResult.inputTokens,\n outputTokens: completionResult.outputTokens,\n totalTokens: completionResult.totalTokens,\n },\n cost: null,\n provider: completionResult.provider,\n model: input.model,\n aborted: false,\n toolCalls,\n finishReason,\n message,\n })\n } catch (error) {\n const latencyMs = Date.now() - startTime\n const isAborted = aborted || signal.aborted\n const errorMessage = isAborted\n ? 'Stream aborted'\n : error instanceof Error\n ? error.message\n : String(error)\n\n if (traceId) {\n scheduleTrace(traceId, {\n traceId,\n model: input.model,\n provider,\n input: { messages: interpolatedMessages },\n variables: input.variables ?? null,\n output: collectedText || null,\n status: TRACE_STATUS_ERROR,\n error: errorMessage,\n latencyMs,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n tags: input.tags,\n userId: input.userId,\n sessionId: input.sessionId,\n temperature: input.temperature,\n maxOutputTokens: input.maxOutputTokens,\n topP: input.topP,\n })\n }\n\n if (isAborted) {\n const abortedMessage = buildAssistantMessage(collectedText, [])\n resolveResult!({\n text: collectedText,\n traceId,\n latencyMs,\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n cost: null,\n provider,\n model: input.model,\n aborted: true,\n toolCalls: [],\n finishReason: 'stop',\n message: abortedMessage,\n })\n } else {\n const traciaError =\n error instanceof TraciaError\n ? error\n : new TraciaError(TraciaErrorCode.PROVIDER_ERROR, errorMessage)\n rejectResult!(traciaError)\n throw traciaError\n }\n }\n }\n\n const asyncIterator = wrappedChunks()\n\n return {\n traceId,\n [Symbol.asyncIterator]() {\n return asyncIterator\n },\n result: resultPromise,\n abort() {\n aborted = true\n abortController.abort()\n },\n }\n }\n\n private combineAbortSignals(signal1: AbortSignal, signal2: AbortSignal): AbortSignal {\n const controller = new AbortController()\n\n if (signal1.aborted || signal2.aborted) {\n controller.abort()\n return controller.signal\n }\n\n const onAbort = () => {\n signal1.removeEventListener('abort', onAbort)\n signal2.removeEventListener('abort', onAbort)\n controller.abort()\n }\n\n signal1.addEventListener('abort', onAbort, { once: true })\n signal2.addEventListener('abort', onAbort, { once: true })\n\n return controller.signal\n }\n\n async flush(): Promise<void> {\n await Promise.all(this.pendingTraces.values())\n }\n\n private validateRunLocalInput(input: RunLocalInput): void {\n if (!input.model || input.model.trim() === '') {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'model is required and cannot be empty'\n )\n }\n\n if (!input.messages || input.messages.length === 0) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'messages array is required and cannot be empty'\n )\n }\n\n for (const message of input.messages) {\n if (message.role === 'tool') {\n // Tool messages must have toolCallId and string content\n if (!message.toolCallId) {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'Tool messages must include toolCallId. ' +\n 'Example: { role: \"tool\", toolCallId: \"call_123\", content: \\'{\"result\": \"data\"}\\' }'\n )\n }\n if (typeof message.content !== 'string') {\n throw new TraciaError(\n TraciaErrorCode.INVALID_REQUEST,\n 'Tool message content must be a string (the tool result). ' +\n 'Example: { role: \"tool\", toolCallId: \"call_123\", content: \\'{\"result\": \"data\"}\\' }'\n )\n }\n }\n }\n }\n\n private scheduleTraceCreation(\n traceId: string,\n payload: Parameters<Traces['create']>[0]\n ): void {\n if (this.pendingTraces.size >= MAX_PENDING_TRACES) {\n const oldestTraceId = this.pendingTraces.keys().next().value\n if (oldestTraceId) {\n this.pendingTraces.delete(oldestTraceId)\n }\n }\n\n const tracePromise = this.createTraceWithRetry(traceId, payload)\n this.pendingTraces.set(traceId, tracePromise)\n tracePromise.finally(() => this.pendingTraces.delete(traceId))\n }\n\n private async createTraceWithRetry(\n traceId: string,\n payload: Parameters<Traces['create']>[0]\n ): Promise<void> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt <= TRACE_RETRY_ATTEMPTS; attempt++) {\n try {\n await this.traces.create(payload)\n return\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n if (attempt < TRACE_RETRY_ATTEMPTS) {\n await this.delay(TRACE_RETRY_DELAY_MS * (attempt + 1))\n }\n }\n }\n\n if (this.onTraceError && lastError) {\n this.onTraceError(lastError, traceId)\n }\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n }\n\n private interpolateMessages(\n messages: LocalPromptMessage[],\n variables?: Record<string, string>\n ): LocalPromptMessage[] {\n if (!variables) return messages\n\n return messages.map(message => {\n if (typeof message.content === 'string') {\n return {\n ...message,\n content: message.content.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (match, key) => variables[key] ?? match\n ),\n }\n }\n\n if (message.role === 'tool') {\n return message\n }\n\n return {\n ...message,\n content: message.content.map(block => {\n if (block.type === 'text') {\n return {\n ...block,\n text: block.text.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (match, key) => variables[key] ?? match\n ),\n }\n }\n return block\n }),\n }\n })\n }\n\n private buildAssistantMessage(text: string, toolCalls: ToolCall[]): LocalPromptMessage {\n if (toolCalls.length === 0) {\n return { role: 'assistant', content: text }\n }\n\n const contentParts: ContentPart[] = []\n\n if (text) {\n contentParts.push({ type: 'text', text })\n }\n\n for (const toolCall of toolCalls) {\n contentParts.push({\n type: 'tool_call',\n id: toolCall.id,\n name: toolCall.name,\n arguments: toolCall.arguments,\n })\n }\n\n return { role: 'assistant', content: contentParts }\n }\n\n private getProviderApiKey(provider: LLMProvider, override?: string): string {\n if (override) return override\n\n const envVar = ENV_VAR_MAP[provider]\n const key = process.env[envVar]\n\n if (!key) {\n throw new TraciaError(\n TraciaErrorCode.MISSING_PROVIDER_API_KEY,\n `Missing API key for ${provider}. Set the ${envVar} environment variable or provide providerApiKey in options.`\n )\n }\n\n return key\n }\n}\n"],"mappings":"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","names":["TraciaErrorCode","LLMProvider","traciaError","stream"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tracia",
3
- "version": "0.2.0",
3
+ "version": "0.2.3",
4
4
  "description": "TypeScript/JavaScript SDK for Tracia - store, test, and trace LLM prompts",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -40,22 +40,47 @@
40
40
  "claude",
41
41
  "google",
42
42
  "gemini",
43
- "ai"
43
+ "ai",
44
+ "vercel-ai-sdk"
44
45
  ],
45
46
  "author": "Tracia",
46
47
  "license": "MIT",
47
48
  "repository": {
48
49
  "type": "git",
49
- "url": "https://github.com/tracia-io/tracia-node"
50
+ "url": "git+https://github.com/tracia-io/tracia-node.git"
50
51
  },
51
52
  "homepage": "https://tracia.io",
52
53
  "bugs": {
53
54
  "url": "https://github.com/tracia-io/tracia-node/issues"
54
55
  },
56
+ "peerDependencies": {
57
+ "@ai-sdk/anthropic": ">=3.0.0",
58
+ "@ai-sdk/google": ">=3.0.0",
59
+ "@ai-sdk/openai": ">=3.0.0",
60
+ "ai": ">=6.0.0"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "ai": {
64
+ "optional": false
65
+ },
66
+ "@ai-sdk/openai": {
67
+ "optional": true
68
+ },
69
+ "@ai-sdk/anthropic": {
70
+ "optional": true
71
+ },
72
+ "@ai-sdk/google": {
73
+ "optional": true
74
+ }
75
+ },
55
76
  "devDependencies": {
77
+ "@ai-sdk/anthropic": "^3.0.33",
78
+ "@ai-sdk/google": "^3.0.18",
79
+ "@ai-sdk/openai": "^3.0.23",
56
80
  "@types/node": "^20.10.0",
57
81
  "@typescript-eslint/eslint-plugin": "^6.13.0",
58
82
  "@typescript-eslint/parser": "^6.13.0",
83
+ "ai": "^6.0.64",
59
84
  "eslint": "^8.55.0",
60
85
  "tsup": "^8.0.0",
61
86
  "typescript": "^5.3.0",