@directive-run/ai 0.8.5 → 0.8.7
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.
- package/README.md +7 -0
- package/dist/anthropic.cjs +2 -3
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.d.cts +1 -1
- package/dist/anthropic.d.ts +1 -1
- package/dist/anthropic.js +2 -3
- package/dist/anthropic.js.map +1 -1
- package/dist/chunk-265ZKXYE.js +3 -0
- package/dist/chunk-265ZKXYE.js.map +1 -0
- package/dist/chunk-7EJPXKDP.js +50 -0
- package/dist/chunk-7EJPXKDP.js.map +1 -0
- package/dist/chunk-B4ATEGA2.cjs +50 -0
- package/dist/chunk-B4ATEGA2.cjs.map +1 -0
- package/dist/chunk-MNYANBNX.js +14 -0
- package/dist/chunk-MNYANBNX.js.map +1 -0
- package/dist/chunk-QXMXSHYS.cjs +3 -0
- package/dist/chunk-QXMXSHYS.cjs.map +1 -0
- package/dist/chunk-W6MVJKWN.cjs +3 -0
- package/dist/chunk-W6MVJKWN.cjs.map +1 -0
- package/dist/chunk-W6WZBQER.js +3 -0
- package/dist/chunk-W6WZBQER.js.map +1 -0
- package/dist/chunk-WCJFIC22.cjs +14 -0
- package/dist/chunk-WCJFIC22.cjs.map +1 -0
- package/dist/gemini.cjs +2 -3
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.d.cts +1 -1
- package/dist/gemini.d.ts +1 -1
- package/dist/gemini.js +2 -3
- package/dist/gemini.js.map +1 -1
- package/dist/index.cjs +30 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +194 -27
- package/dist/index.d.ts +194 -27
- package/dist/index.js +30 -89
- package/dist/index.js.map +1 -1
- package/dist/multi-agent-orchestrator-FEHVHZXA.js +2 -0
- package/dist/multi-agent-orchestrator-FEHVHZXA.js.map +1 -0
- package/dist/multi-agent-orchestrator-QWJNM4EZ.cjs +2 -0
- package/dist/multi-agent-orchestrator-QWJNM4EZ.cjs.map +1 -0
- package/dist/ollama.cjs +2 -2
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts +1 -1
- package/dist/ollama.d.ts +1 -1
- package/dist/ollama.js +2 -2
- package/dist/ollama.js.map +1 -1
- package/dist/openai.cjs +2 -3
- package/dist/openai.cjs.map +1 -1
- package/dist/openai.d.cts +2 -2
- package/dist/openai.d.ts +2 -2
- package/dist/openai.js +2 -3
- package/dist/openai.js.map +1 -1
- package/dist/{multi-agent-orchestrator-DHp8gHXi.d.ts → orchestrator-types-DryFJyW9.d.ts} +6 -142
- package/dist/{multi-agent-orchestrator-C3VKkLzg.d.cts → orchestrator-types-tATJCBi5.d.cts} +6 -142
- package/dist/{semantic-cache-F0psCRuz.d.cts → semantic-cache-nBpQqILc.d.cts} +5 -5
- package/dist/{semantic-cache-F0psCRuz.d.ts → semantic-cache-nBpQqILc.d.ts} +5 -5
- package/dist/testing.cjs +1 -48
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +1 -48
- package/dist/testing.js.map +1 -1
- package/dist/{types-BM-6xZf_.d.cts → types-CRmwFnVk.d.cts} +1 -1
- package/dist/{types-BM-6xZf_.d.ts → types-CRmwFnVk.d.ts} +1 -1
- package/package.json +3 -3
package/dist/openai.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent-utils.ts","../src/adapters/shared.ts","../src/adapters/openai.ts"],"names":["ALLOWED_PROTOCOLS","validateBaseURL","baseURL","url","err","createRunner","options","fetchFn","buildRequest","parseResponse","parseOutput","hooks","parse","text","agent","input","runOptions","startTime","messages","init","fetchInit","response","errBody","parsed","tokenUsage","assistantMessage","allMessages","durationMs","throwStreamingHTTPError","adapterName","getSSEReader","reader","warnIfMissingApiKey","apiKey","functionName","parseSSEStream","onToken","parseEvent","decoder","buf","fullText","inputTokens","outputTokens","done","value","lines","line","data","event","result","parseErr","fireBeforeCallHook","fireAfterCallHook","output","totalTokens","fireErrorHook","buildStreamingResult","OPENAI_PRICING","createOpenAIRunner","model","maxTokens","timeoutMs","temperature","topP","stop","responseFormat","resolvedResponseFormat","_input","m","res","createOpenAIEmbedder","dimensions","entry","createOpenAIStreamingRunner","callbacks","delta"],"mappings":"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","file":"openai.cjs","sourcesContent":["/**\n * Agent utilities — createRunner, estimateCost, state queries, URL validation.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n AgentRunner,\n AgentState,\n ApprovalState,\n Message,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// State Query Helpers\n// ============================================================================\n\n/**\n * Check whether an agent is currently executing a run.\n *\n * @param state - The current {@link AgentState} to inspect.\n * @returns `true` when the agent status is `\"running\"`.\n */\nexport function isAgentRunning(state: AgentState): boolean {\n return state.status === \"running\";\n}\n\n/**\n * Check whether there are tool-call approvals waiting for user confirmation.\n *\n * @param state - The current {@link ApprovalState} to inspect.\n * @returns `true` when one or more approvals are pending.\n */\nexport function hasPendingApprovals(state: ApprovalState): boolean {\n return state.pending.length > 0;\n}\n\n// ============================================================================\n// Cost Estimation\n// ============================================================================\n\n/**\n * Estimate the dollar cost of an agent run based on total token usage.\n *\n * @remarks\n * No default rate is provided — callers must supply the current per-million-token\n * price to avoid silently using stale pricing.\n *\n * @param tokenUsage - Total number of tokens consumed (input + output).\n * @param ratePerMillionTokens - Cost in dollars per one million tokens.\n * @returns Estimated cost in dollars.\n */\nexport function estimateCost(\n tokenUsage: number,\n ratePerMillionTokens: number,\n): number {\n return (tokenUsage / 1_000_000) * ratePerMillionTokens;\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\"]);\n\n/**\n * Validate that a base URL uses the `http:` or `https:` protocol.\n * Throws immediately at adapter creation time (not at call time) to surface\n * configuration errors before any LLM requests are made.\n *\n * @param baseURL - The base URL string to validate.\n * @throws When the URL is malformed or uses a protocol other than `http:` or `https:`.\n */\nexport function validateBaseURL(baseURL: string): void {\n try {\n const url = new URL(baseURL);\n if (!ALLOWED_PROTOCOLS.has(url.protocol)) {\n throw new Error(\n `[Directive] Invalid baseURL protocol \"${url.protocol}\" – only http: and https: are allowed`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith(\"[Directive]\")) {\n throw err;\n }\n\n throw new Error(\n `[Directive] Invalid baseURL \"${baseURL}\" – must be a valid URL (e.g. \"https://api.openai.com/v1\")`,\n );\n }\n}\n\n// ============================================================================\n// createRunner Helper\n// ============================================================================\n\n/** Parsed response from an LLM provider */\nexport interface ParsedResponse {\n text: string;\n totalTokens: number;\n /** Input token count, when available from the provider */\n inputTokens?: number;\n /** Output token count, when available from the provider */\n outputTokens?: number;\n}\n\n/** Options for creating an AgentRunner from buildRequest/parseResponse */\nexport interface CreateRunnerOptions {\n fetch?: typeof globalThis.fetch;\n buildRequest: (\n agent: AgentLike,\n input: string,\n messages: Message[],\n ) => { url: string; init: RequestInit };\n parseResponse: (\n response: Response,\n messages: Message[],\n ) => Promise<ParsedResponse>;\n parseOutput?: <T>(text: string) => T;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n}\n\n/**\n * Create an {@link AgentRunner} from `buildRequest`/`parseResponse` helpers, reducing\n * ~50 lines of fetch boilerplate to ~20 lines of configuration.\n *\n * @remarks\n * Supports lifecycle hooks for observability:\n * - `onBeforeCall` fires before each API request\n * - `onAfterCall` fires after a successful response (includes token breakdown)\n * - `onError` fires when the request fails\n *\n * Output parsing defaults to `JSON.parse` with a string fallback. Supply a custom\n * `parseOutput` to override (e.g. for structured output schemas).\n *\n * @param options - Configuration for the runner, including request building, response parsing, and hooks.\n * @returns An {@link AgentRunner} function that performs LLM calls via fetch.\n *\n * @example\n * ```typescript\n * const runClaude = createRunner({\n * buildRequest: (agent, input) => ({\n * url: \"/api/claude\",\n * init: {\n * method: \"POST\",\n * headers: { \"Content-Type\": \"application/json\" },\n * body: JSON.stringify({\n * model: agent.model ?? \"claude-haiku-4-5-20251001\",\n * system: agent.instructions ?? \"\",\n * messages: [{ role: \"user\", content: input }],\n * }),\n * },\n * }),\n * parseResponse: async (res) => {\n * const data = await res.json();\n * const inputTokens = data.usage?.input_tokens ?? 0;\n * const outputTokens = data.usage?.output_tokens ?? 0;\n * return {\n * text: data.content?.[0]?.text ?? \"\",\n * totalTokens: inputTokens + outputTokens,\n * inputTokens,\n * outputTokens,\n * };\n * },\n * hooks: {\n * onAfterCall: ({ durationMs, tokenUsage }) => {\n * console.log(`LLM call: ${durationMs}ms, ${tokenUsage.inputTokens}in/${tokenUsage.outputTokens}out`);\n * },\n * },\n * });\n * ```\n *\n * @public\n */\nexport function createRunner(options: CreateRunnerOptions): AgentRunner {\n const {\n fetch: fetchFn = globalThis.fetch,\n buildRequest,\n parseResponse,\n parseOutput,\n hooks,\n } = options;\n\n const defaultParseOutput = <T>(text: string): T => {\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n };\n\n const parse = parseOutput ?? defaultParseOutput;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n const messages: Message[] = [{ role: \"user\", content: input }];\n\n try {\n const { url, init } = buildRequest(agent, input, messages);\n\n const fetchInit: RequestInit = runOptions?.signal\n ? { ...init, signal: runOptions.signal }\n : init;\n\n const response = await fetchFn(url, fetchInit);\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] AgentRunner request failed: ${response.status} ${response.statusText}${errBody ? ` – ${errBody.slice(0, 300)}` : \"\"}`,\n );\n }\n\n const parsed = await parseResponse(response, messages);\n const tokenUsage: TokenUsage = {\n inputTokens: parsed.inputTokens ?? 0,\n outputTokens: parsed.outputTokens ?? 0,\n };\n\n const assistantMessage: Message = {\n role: \"assistant\",\n content: parsed.text,\n };\n const allMessages: Message[] = [...messages, assistantMessage];\n\n runOptions?.onMessage?.(assistantMessage);\n\n const durationMs = Date.now() - startTime;\n hooks?.onAfterCall?.({\n agent,\n input,\n output: parsed.text,\n totalTokens: parsed.totalTokens,\n tokenUsage,\n durationMs,\n timestamp: Date.now(),\n });\n\n return {\n output: parse<T>(parsed.text),\n messages: allMessages,\n toolCalls: [],\n totalTokens: parsed.totalTokens,\n tokenUsage,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs,\n timestamp: Date.now(),\n });\n }\n\n throw err;\n }\n };\n}\n","/**\n * Shared utilities for streaming adapters.\n *\n * Extracts common SSE parsing, error handling, hook lifecycle, and response\n * building logic used across Anthropic, OpenAI, and Gemini streaming runners.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n Message,\n TokenUsage,\n} from \"../types.js\";\n\n// ============================================================================\n// HTTP Error Handling\n// ============================================================================\n\n/**\n * Throw a standardized HTTP error from a streaming response.\n * Reads up to 200 chars of the error body for diagnostics.\n */\nexport async function throwStreamingHTTPError(\n response: Response,\n adapterName: string,\n): Promise<never> {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] ${adapterName} streaming error ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n}\n\n/**\n * Get an SSE reader from a response, throwing if body is missing.\n */\nexport function getSSEReader(\n response: Response,\n): ReadableStreamDefaultReader<Uint8Array> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"[Directive] No response body\");\n }\n\n return reader;\n}\n\n// ============================================================================\n// API Key Validation\n// ============================================================================\n\n/**\n * Warn in non-production environments if an API key is empty.\n */\nexport function warnIfMissingApiKey(\n apiKey: string | undefined,\n functionName: string,\n): void {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\" &&\n !apiKey\n ) {\n console.warn(\n `[Directive] ${functionName}: apiKey is empty. API calls will fail.`,\n );\n }\n}\n\n// ============================================================================\n// SSE Stream Parser\n// ============================================================================\n\n/** Result from parsing a single SSE event (provider-specific). */\nexport interface SSEEventResult {\n /** Text token to append to output. */\n text?: string;\n /** Updated input token count (cumulative, not delta). */\n inputTokens?: number;\n /** Updated output token count (cumulative, not delta). */\n outputTokens?: number;\n}\n\n/**\n * Parse an SSE stream from a Response, calling `onToken` for each text chunk\n * and `parseEvent` for provider-specific event extraction.\n *\n * Handles buffering, `[DONE]` sentinels, malformed JSON, and reader cleanup.\n *\n * @param reader - The ReadableStream reader from the response body.\n * @param onToken - Callback for each text token (may be undefined).\n * @param parseEvent - Provider-specific function to extract text and tokens from a parsed SSE event.\n * @param adapterName - Adapter name for dev-mode warnings.\n * @returns The full text output and final token counts.\n */\nexport async function parseSSEStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onToken: ((token: string) => void) | undefined,\n parseEvent: (event: Record<string, unknown>) => SSEEventResult,\n adapterName: string,\n): Promise<{ fullText: string; inputTokens: number; outputTokens: number }> {\n const decoder = new TextDecoder();\n let buf = \"\";\n let fullText = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) {\n continue;\n }\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") {\n continue;\n }\n\n try {\n const event = JSON.parse(data);\n const result = parseEvent(event);\n if (result.text) {\n fullText += result.text;\n onToken?.(result.text);\n }\n if (result.inputTokens !== undefined) {\n inputTokens = result.inputTokens;\n }\n if (result.outputTokens !== undefined) {\n outputTokens = result.outputTokens;\n }\n } catch (parseErr) {\n if (parseErr instanceof SyntaxError) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\"\n ) {\n console.warn(\n `[Directive] Malformed SSE event from ${adapterName}:`,\n data,\n );\n }\n } else {\n throw parseErr;\n }\n }\n }\n }\n } finally {\n reader.cancel().catch(() => {});\n }\n\n return { fullText, inputTokens, outputTokens };\n}\n\n// ============================================================================\n// Hook Lifecycle Helpers\n// ============================================================================\n\n/**\n * Fire the onBeforeCall hook and return the start timestamp.\n */\nexport function fireBeforeCallHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n): number {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n return startTime;\n}\n\n/**\n * Fire the onAfterCall hook with timing and token data.\n */\nexport function fireAfterCallHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n output: string,\n totalTokens: number,\n tokenUsage: TokenUsage,\n startTime: number,\n): void {\n hooks?.onAfterCall?.({\n agent,\n input,\n output,\n totalTokens,\n tokenUsage,\n durationMs: Date.now() - startTime,\n timestamp: Date.now(),\n });\n}\n\n/**\n * Fire the onError hook if the error is an Error instance.\n */\nexport function fireErrorHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n err: unknown,\n startTime: number,\n): void {\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs: Date.now() - startTime,\n timestamp: Date.now(),\n });\n }\n}\n\n// ============================================================================\n// Streaming Response Builder\n// ============================================================================\n\n/**\n * Build the standard streaming runner return value.\n */\nexport function buildStreamingResult(\n input: string,\n fullText: string,\n totalTokens: number,\n tokenUsage: TokenUsage,\n): {\n output: string;\n messages: Message[];\n toolCalls: never[];\n totalTokens: number;\n tokenUsage: TokenUsage;\n} {\n const assistantMsg: Message = { role: \"assistant\", content: fullText };\n\n return {\n output: fullText,\n messages: [{ role: \"user\" as const, content: input }, assistantMsg],\n toolCalls: [],\n totalTokens,\n tokenUsage,\n };\n}\n","/**\n * @directive-run/ai/openai\n *\n * OpenAI adapter for Directive AI. Provides runners and embedders\n * for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * @example\n * ```typescript\n * import { createOpenAIRunner, createOpenAIEmbedder } from '@directive-run/ai/openai';\n *\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { EmbedderFn, Embedding } from \"../guardrails/semantic-cache.js\";\nimport type {\n AdapterHooks,\n AgentRunner,\n} from \"../types.js\";\nimport type { StreamingCallbackRunner } from \"../types.js\";\nimport {\n buildStreamingResult,\n fireAfterCallHook,\n fireBeforeCallHook,\n fireErrorHook,\n getSSEReader,\n parseSSEStream,\n throwStreamingHTTPError,\n warnIfMissingApiKey,\n} from \"./shared.js\";\n\n// ============================================================================\n// Pricing Constants\n// ============================================================================\n\n/**\n * OpenAI model pricing (USD per million tokens).\n *\n * Use with `estimateCost()` for per-call cost tracking:\n * ```typescript\n * import { estimateCost } from '@directive-run/ai';\n * import { OPENAI_PRICING } from '@directive-run/ai/openai';\n *\n * const cost =\n * estimateCost(result.tokenUsage!.inputTokens, OPENAI_PRICING[\"gpt-4o\"].input) +\n * estimateCost(result.tokenUsage!.outputTokens, OPENAI_PRICING[\"gpt-4o\"].output);\n * ```\n *\n * **Note:** Pricing changes over time. These values are provided as a convenience\n * and may not reflect the latest rates. Always verify at https://openai.com/pricing\n */\nexport const OPENAI_PRICING: Record<string, { input: number; output: number }> =\n {\n \"gpt-4.1\": { input: 2, output: 8 },\n \"gpt-4.1-mini\": { input: 0.4, output: 1.6 },\n \"gpt-4.1-nano\": { input: 0.1, output: 0.4 },\n \"gpt-4o\": { input: 2.5, output: 10 },\n \"gpt-4o-mini\": { input: 0.15, output: 0.6 },\n \"gpt-4-turbo\": { input: 10, output: 30 },\n \"o4-mini\": { input: 1.1, output: 4.4 },\n \"o3\": { input: 10, output: 40 },\n \"o3-mini\": { input: 1.1, output: 4.4 },\n };\n\n// ============================================================================\n// OpenAI Runner\n// ============================================================================\n\n/** Options for createOpenAIRunner */\nexport interface OpenAIRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default undefined */\n timeoutMs?: number;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create an AgentRunner for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * // OpenAI\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n *\n * // Azure OpenAI\n * const azure = createOpenAIRunner({\n * apiKey: process.env.AZURE_KEY!,\n * baseURL: \"https://your-resource.openai.azure.com/v1\",\n * });\n *\n * // Together.ai (OpenAI-compatible)\n * const together = createOpenAIRunner({\n * apiKey: process.env.TOGETHER_KEY!,\n * baseURL: \"https://api.together.xyz/v1\",\n * });\n * ```\n */\nexport function createOpenAIRunner(options: OpenAIRunnerOptions): AgentRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return createRunner({\n fetch: fetchFn,\n hooks,\n buildRequest: (agent, _input, messages) => ({\n url: `${baseURL}/chat/completions`,\n init: {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n ...messages.map((m) => ({ role: m.role, content: m.content })),\n ],\n }),\n ...(timeoutMs != null\n ? { signal: AbortSignal.timeout(timeoutMs) }\n : {}),\n },\n }),\n parseResponse: async (res) => {\n const data = await res.json();\n const text = data.choices?.[0]?.message?.content ?? \"\";\n const inputTokens = data.usage?.prompt_tokens ?? 0;\n const outputTokens = data.usage?.completion_tokens ?? 0;\n\n return {\n text,\n totalTokens: inputTokens + outputTokens,\n inputTokens,\n outputTokens,\n };\n },\n });\n}\n\n// ============================================================================\n// OpenAI Embedder\n// ============================================================================\n\n/** Options for createOpenAIEmbedder */\nexport interface OpenAIEmbedderOptions {\n apiKey: string;\n model?: string;\n dimensions?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default 30000 */\n timeoutMs?: number;\n}\n\n/**\n * Create an EmbedderFn that calls the OpenAI embeddings API.\n *\n * @example\n * ```typescript\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedding = await embedder('How do constraints work?');\n * ```\n */\nexport function createOpenAIEmbedder(\n options: OpenAIEmbedderOptions,\n): EmbedderFn {\n const {\n apiKey,\n model = \"text-embedding-3-small\",\n dimensions = 1536,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIEmbedder\");\n\n return async (text: string): Promise<Embedding> => {\n const response = await fetchFn(`${baseURL}/embeddings`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ model, input: text, dimensions }),\n signal: AbortSignal.timeout(timeoutMs ?? 30_000),\n });\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] OpenAI embedding failed: ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[] }>;\n };\n\n const entry = data.data[0];\n if (!entry) {\n throw new Error(\n \"[Directive] OpenAI embedding response contained no data entries\",\n );\n }\n\n return entry.embedding;\n };\n}\n\n// ============================================================================\n// OpenAI Streaming Runner\n// ============================================================================\n\n/** Options for createOpenAIStreamingRunner */\nexport interface OpenAIStreamingRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create a StreamingCallbackRunner for OpenAI-compatible chat completions\n * with server-sent events. Can be used standalone or paired with `createOpenAIRunner`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * const streamingRunner = createOpenAIStreamingRunner({\n * apiKey: process.env.OPENAI_API_KEY!,\n * });\n * const streamRunner = createStreamingRunner(streamingRunner);\n * const { stream, result } = streamRunner(agent, input);\n * ```\n */\nexport function createOpenAIStreamingRunner(\n options: OpenAIStreamingRunnerOptions,\n): StreamingCallbackRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIStreamingRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return async (agent, input, callbacks) => {\n const startTime = fireBeforeCallHook(hooks, agent, input);\n\n try {\n const response = await fetchFn(`${baseURL}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n { role: \"user\", content: input },\n ],\n stream: true,\n stream_options: { include_usage: true },\n }),\n signal: callbacks.signal,\n });\n\n if (!response.ok) {\n await throwStreamingHTTPError(response, \"OpenAI\");\n }\n\n const reader = getSSEReader(response);\n\n const { fullText, inputTokens, outputTokens } = await parseSSEStream(\n reader,\n callbacks.onToken,\n (event) => {\n const result: { text?: string; inputTokens?: number; outputTokens?: number } = {};\n\n const delta = (event.choices as Array<Record<string, unknown>>)?.[0]\n ?.delta as Record<string, unknown> | undefined;\n if (delta?.content) {\n result.text = delta.content as string;\n }\n\n if (event.usage) {\n result.inputTokens = (event.usage as Record<string, unknown>).prompt_tokens as number ?? 0;\n result.outputTokens = (event.usage as Record<string, unknown>).completion_tokens as number ?? 0;\n }\n\n return result;\n },\n \"OpenAI\",\n );\n\n const tokenUsage = { inputTokens, outputTokens };\n const totalTokens = inputTokens + outputTokens;\n\n callbacks.onMessage?.({ role: \"assistant\", content: fullText });\n fireAfterCallHook(hooks, agent, input, fullText, totalTokens, tokenUsage, startTime);\n\n return buildStreamingResult(input, fullText, totalTokens, tokenUsage);\n } catch (err) {\n fireErrorHook(hooks, agent, input, err, startTime);\n\n throw err;\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/openai.ts"],"names":["OPENAI_PRICING","createOpenAIRunner","options","apiKey","model","maxTokens","baseURL","fetchFn","timeoutMs","hooks","temperature","topP","stop","responseFormat","validateBaseURL","warnIfMissingApiKey","resolvedResponseFormat","createRunner","agent","_input","messages","m","res","data","text","inputTokens","outputTokens","createOpenAIEmbedder","dimensions","response","errBody","entry","createOpenAIStreamingRunner","input","callbacks","startTime","fireBeforeCallHook","throwStreamingHTTPError","reader","getSSEReader","fullText","parseSSEStream","event","result","delta","tokenUsage","totalTokens","fireAfterCallHook","buildStreamingResult","err","fireErrorHook"],"mappings":"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","file":"openai.cjs","sourcesContent":["/**\n * @directive-run/ai/openai\n *\n * OpenAI adapter for Directive AI. Provides runners and embedders\n * for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * @example\n * ```typescript\n * import { createOpenAIRunner, createOpenAIEmbedder } from '@directive-run/ai/openai';\n *\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { EmbedderFn, Embedding } from \"../guardrails/semantic-cache.js\";\nimport type {\n AdapterHooks,\n AgentRunner,\n} from \"../types.js\";\nimport type { StreamingCallbackRunner } from \"../types.js\";\nimport {\n buildStreamingResult,\n fireAfterCallHook,\n fireBeforeCallHook,\n fireErrorHook,\n getSSEReader,\n parseSSEStream,\n throwStreamingHTTPError,\n warnIfMissingApiKey,\n} from \"./shared.js\";\n\n// ============================================================================\n// Pricing Constants\n// ============================================================================\n\n/**\n * OpenAI model pricing (USD per million tokens).\n *\n * Use with `estimateCost()` for per-call cost tracking:\n * ```typescript\n * import { estimateCost } from '@directive-run/ai';\n * import { OPENAI_PRICING } from '@directive-run/ai/openai';\n *\n * const cost =\n * estimateCost(result.tokenUsage!.inputTokens, OPENAI_PRICING[\"gpt-4o\"].input) +\n * estimateCost(result.tokenUsage!.outputTokens, OPENAI_PRICING[\"gpt-4o\"].output);\n * ```\n *\n * **Note:** Pricing changes over time. These values are provided as a convenience\n * and may not reflect the latest rates. Always verify at https://openai.com/pricing\n */\nexport const OPENAI_PRICING: Record<string, { input: number; output: number }> =\n {\n \"gpt-4.1\": { input: 2, output: 8 },\n \"gpt-4.1-mini\": { input: 0.4, output: 1.6 },\n \"gpt-4.1-nano\": { input: 0.1, output: 0.4 },\n \"gpt-4o\": { input: 2.5, output: 10 },\n \"gpt-4o-mini\": { input: 0.15, output: 0.6 },\n \"gpt-4-turbo\": { input: 10, output: 30 },\n \"o4-mini\": { input: 1.1, output: 4.4 },\n \"o3\": { input: 10, output: 40 },\n \"o3-mini\": { input: 1.1, output: 4.4 },\n };\n\n// ============================================================================\n// OpenAI Runner\n// ============================================================================\n\n/** Options for createOpenAIRunner */\nexport interface OpenAIRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default undefined */\n timeoutMs?: number;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create an AgentRunner for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * // OpenAI\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n *\n * // Azure OpenAI\n * const azure = createOpenAIRunner({\n * apiKey: process.env.AZURE_KEY!,\n * baseURL: \"https://your-resource.openai.azure.com/v1\",\n * });\n *\n * // Together.ai (OpenAI-compatible)\n * const together = createOpenAIRunner({\n * apiKey: process.env.TOGETHER_KEY!,\n * baseURL: \"https://api.together.xyz/v1\",\n * });\n * ```\n */\nexport function createOpenAIRunner(options: OpenAIRunnerOptions): AgentRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return createRunner({\n fetch: fetchFn,\n hooks,\n buildRequest: (agent, _input, messages) => ({\n url: `${baseURL}/chat/completions`,\n init: {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n ...messages.map((m) => ({ role: m.role, content: m.content })),\n ],\n }),\n ...(timeoutMs != null\n ? { signal: AbortSignal.timeout(timeoutMs) }\n : {}),\n },\n }),\n parseResponse: async (res) => {\n const data = await res.json();\n const text = data.choices?.[0]?.message?.content ?? \"\";\n const inputTokens = data.usage?.prompt_tokens ?? 0;\n const outputTokens = data.usage?.completion_tokens ?? 0;\n\n return {\n text,\n totalTokens: inputTokens + outputTokens,\n inputTokens,\n outputTokens,\n };\n },\n });\n}\n\n// ============================================================================\n// OpenAI Embedder\n// ============================================================================\n\n/** Options for createOpenAIEmbedder */\nexport interface OpenAIEmbedderOptions {\n apiKey: string;\n model?: string;\n dimensions?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default 30000 */\n timeoutMs?: number;\n}\n\n/**\n * Create an EmbedderFn that calls the OpenAI embeddings API.\n *\n * @example\n * ```typescript\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedding = await embedder('How do constraints work?');\n * ```\n */\nexport function createOpenAIEmbedder(\n options: OpenAIEmbedderOptions,\n): EmbedderFn {\n const {\n apiKey,\n model = \"text-embedding-3-small\",\n dimensions = 1536,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIEmbedder\");\n\n return async (text: string): Promise<Embedding> => {\n const response = await fetchFn(`${baseURL}/embeddings`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ model, input: text, dimensions }),\n signal: AbortSignal.timeout(timeoutMs ?? 30_000),\n });\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] OpenAI embedding failed: ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[] }>;\n };\n\n const entry = data.data[0];\n if (!entry) {\n throw new Error(\n \"[Directive] OpenAI embedding response contained no data entries\",\n );\n }\n\n return entry.embedding;\n };\n}\n\n// ============================================================================\n// OpenAI Streaming Runner\n// ============================================================================\n\n/** Options for createOpenAIStreamingRunner */\nexport interface OpenAIStreamingRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create a StreamingCallbackRunner for OpenAI-compatible chat completions\n * with server-sent events. Can be used standalone or paired with `createOpenAIRunner`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * const streamingRunner = createOpenAIStreamingRunner({\n * apiKey: process.env.OPENAI_API_KEY!,\n * });\n * const streamRunner = createStreamingRunner(streamingRunner);\n * const { stream, result } = streamRunner(agent, input);\n * ```\n */\nexport function createOpenAIStreamingRunner(\n options: OpenAIStreamingRunnerOptions,\n): StreamingCallbackRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIStreamingRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return async (agent, input, callbacks) => {\n const startTime = fireBeforeCallHook(hooks, agent, input);\n\n try {\n const response = await fetchFn(`${baseURL}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n { role: \"user\", content: input },\n ],\n stream: true,\n stream_options: { include_usage: true },\n }),\n signal: callbacks.signal,\n });\n\n if (!response.ok) {\n await throwStreamingHTTPError(response, \"OpenAI\");\n }\n\n const reader = getSSEReader(response);\n\n const { fullText, inputTokens, outputTokens } = await parseSSEStream(\n reader,\n callbacks.onToken,\n (event) => {\n const result: { text?: string; inputTokens?: number; outputTokens?: number } = {};\n\n const delta = (event.choices as Array<Record<string, unknown>>)?.[0]\n ?.delta as Record<string, unknown> | undefined;\n if (delta?.content) {\n result.text = delta.content as string;\n }\n\n if (event.usage) {\n result.inputTokens = (event.usage as Record<string, unknown>).prompt_tokens as number ?? 0;\n result.outputTokens = (event.usage as Record<string, unknown>).completion_tokens as number ?? 0;\n }\n\n return result;\n },\n \"OpenAI\",\n );\n\n const tokenUsage = { inputTokens, outputTokens };\n const totalTokens = inputTokens + outputTokens;\n\n callbacks.onMessage?.({ role: \"assistant\", content: fullText });\n fireAfterCallHook(hooks, agent, input, fullText, totalTokens, tokenUsage, startTime);\n\n return buildStreamingResult(input, fullText, totalTokens, tokenUsage);\n } catch (err) {\n fireErrorHook(hooks, agent, input, err, startTime);\n\n throw err;\n }\n };\n}\n"]}
|
package/dist/openai.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as EmbedderFn } from './semantic-cache-
|
|
2
|
-
import { a as AdapterHooks, b as AgentRunner, aX as StreamingCallbackRunner } from './types-
|
|
1
|
+
import { a as EmbedderFn } from './semantic-cache-nBpQqILc.cjs';
|
|
2
|
+
import { a as AdapterHooks, b as AgentRunner, aX as StreamingCallbackRunner } from './types-CRmwFnVk.cjs';
|
|
3
3
|
import '@directive-run/core';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/openai.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as EmbedderFn } from './semantic-cache-
|
|
2
|
-
import { a as AdapterHooks, b as AgentRunner, aX as StreamingCallbackRunner } from './types-
|
|
1
|
+
import { a as EmbedderFn } from './semantic-cache-nBpQqILc.js';
|
|
2
|
+
import { a as AdapterHooks, b as AgentRunner, aX as StreamingCallbackRunner } from './types-CRmwFnVk.js';
|
|
3
3
|
import '@directive-run/core';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/openai.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
export{B as OPENAI_PRICING,K as createOpenAIEmbedder,F as createOpenAIRunner,q as createOpenAIStreamingRunner};//# sourceMappingURL=openai.js.map
|
|
1
|
+
import {c,e as e$1,a,b,d as d$1,f,h,g}from'./chunk-265ZKXYE.js';import {d,e}from'./chunk-W6WZBQER.js';var L={"gpt-4.1":{input:2,output:8},"gpt-4.1-mini":{input:.4,output:1.6},"gpt-4.1-nano":{input:.1,output:.4},"gpt-4o":{input:2.5,output:10},"gpt-4o-mini":{input:.15,output:.6},"gpt-4-turbo":{input:10,output:30},"o4-mini":{input:1.1,output:4.4},o3:{input:10,output:40},"o3-mini":{input:1.1,output:4.4}};function B(g){let{apiKey:s,model:h="gpt-4o",maxTokens:m,baseURL:r="https://api.openai.com/v1",fetch:b=globalThis.fetch,timeoutMs:i,hooks:c$1,temperature:n,topP:l,stop:a,responseFormat:p}=g;d(r),c(s,"createOpenAIRunner");let o=p==="json"?{type:"json_object"}:p??void 0;return e({fetch:b,hooks:c$1,buildRequest:(t,u,d)=>({url:`${r}/chat/completions`,init:{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({model:t.model??h,...m!=null?{max_tokens:m}:{},...n!=null?{temperature:n}:{},...l!=null?{top_p:l}:{},...a!=null?{stop:a}:{},...o!=null?{response_format:o}:{},messages:[...t.instructions?[{role:"system",content:t.instructions}]:[],...d.map(e=>({role:e.role,content:e.content}))]}),...i!=null?{signal:AbortSignal.timeout(i)}:{}}}),parseResponse:async t=>{let u=await t.json(),d=u.choices?.[0]?.message?.content??"",e=u.usage?.prompt_tokens??0,f=u.usage?.completion_tokens??0;return {text:d,totalTokens:e+f,inputTokens:e,outputTokens:f}}})}function M(g){let{apiKey:s,model:h="text-embedding-3-small",dimensions:m=1536,baseURL:r="https://api.openai.com/v1",fetch:b=globalThis.fetch,timeoutMs:i}=g;return d(r),c(s,"createOpenAIEmbedder"),async c=>{let n=await b(`${r}/embeddings`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({model:h,input:c,dimensions:m}),signal:AbortSignal.timeout(i??3e4)});if(!n.ok){let p=await n.text().catch(()=>"");throw new Error(`[Directive] OpenAI embedding failed: ${n.status}${p?` \u2013 ${p.slice(0,200)}`:""}`)}let a=(await n.json()).data[0];if(!a)throw new Error("[Directive] OpenAI embedding response contained no data entries");return a.embedding}}function v(g$1){let{apiKey:s,model:h$1="gpt-4o",maxTokens:m,baseURL:r="https://api.openai.com/v1",fetch:b$1=globalThis.fetch,hooks:i,temperature:c$1,topP:n,stop:l,responseFormat:a$1}=g$1;d(r),c(s,"createOpenAIStreamingRunner");let p=a$1==="json"?{type:"json_object"}:a$1??void 0;return async(o,t,u)=>{let d=e$1(i,o,t);try{let e=await b$1(`${r}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({model:o.model??h$1,...m!=null?{max_tokens:m}:{},...c$1!=null?{temperature:c$1}:{},...n!=null?{top_p:n}:{},...l!=null?{stop:l}:{},...p!=null?{response_format:p}:{},messages:[...o.instructions?[{role:"system",content:o.instructions}]:[],{role:"user",content:t}],stream:!0,stream_options:{include_usage:!0}}),signal:u.signal});e.ok||await a(e,"OpenAI");let f$1=b(e),{fullText:T,inputTokens:O,outputTokens:S}=await d$1(f$1,u.onToken,k=>{let y={},w=k.choices?.[0]?.delta;return w?.content&&(y.text=w.content),k.usage&&(y.inputTokens=k.usage.prompt_tokens??0,y.outputTokens=k.usage.completion_tokens??0),y},"OpenAI"),_={inputTokens:O,outputTokens:S},j=O+S;return u.onMessage?.({role:"assistant",content:T}),f(i,o,t,T,j,_,d),h(t,T,j,_)}catch(e){throw g(i,o,t,e,d),e}}}
|
|
2
|
+
export{L as OPENAI_PRICING,M as createOpenAIEmbedder,B as createOpenAIRunner,v as createOpenAIStreamingRunner};//# sourceMappingURL=openai.js.map
|
|
4
3
|
//# sourceMappingURL=openai.js.map
|
package/dist/openai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent-utils.ts","../src/adapters/shared.ts","../src/adapters/openai.ts"],"names":["ALLOWED_PROTOCOLS","validateBaseURL","baseURL","url","err","createRunner","options","fetchFn","buildRequest","parseResponse","parseOutput","hooks","parse","text","agent","input","runOptions","startTime","messages","init","fetchInit","response","errBody","parsed","tokenUsage","assistantMessage","allMessages","durationMs","throwStreamingHTTPError","adapterName","getSSEReader","reader","warnIfMissingApiKey","apiKey","functionName","parseSSEStream","onToken","parseEvent","decoder","buf","fullText","inputTokens","outputTokens","done","value","lines","line","data","event","result","parseErr","fireBeforeCallHook","fireAfterCallHook","output","totalTokens","fireErrorHook","buildStreamingResult","OPENAI_PRICING","createOpenAIRunner","model","maxTokens","timeoutMs","temperature","topP","stop","responseFormat","resolvedResponseFormat","_input","m","res","createOpenAIEmbedder","dimensions","entry","createOpenAIStreamingRunner","callbacks","delta"],"mappings":"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","file":"openai.js","sourcesContent":["/**\n * Agent utilities — createRunner, estimateCost, state queries, URL validation.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n AgentRunner,\n AgentState,\n ApprovalState,\n Message,\n RunOptions,\n RunResult,\n TokenUsage,\n} from \"./types.js\";\n\n// ============================================================================\n// State Query Helpers\n// ============================================================================\n\n/**\n * Check whether an agent is currently executing a run.\n *\n * @param state - The current {@link AgentState} to inspect.\n * @returns `true` when the agent status is `\"running\"`.\n */\nexport function isAgentRunning(state: AgentState): boolean {\n return state.status === \"running\";\n}\n\n/**\n * Check whether there are tool-call approvals waiting for user confirmation.\n *\n * @param state - The current {@link ApprovalState} to inspect.\n * @returns `true` when one or more approvals are pending.\n */\nexport function hasPendingApprovals(state: ApprovalState): boolean {\n return state.pending.length > 0;\n}\n\n// ============================================================================\n// Cost Estimation\n// ============================================================================\n\n/**\n * Estimate the dollar cost of an agent run based on total token usage.\n *\n * @remarks\n * No default rate is provided — callers must supply the current per-million-token\n * price to avoid silently using stale pricing.\n *\n * @param tokenUsage - Total number of tokens consumed (input + output).\n * @param ratePerMillionTokens - Cost in dollars per one million tokens.\n * @returns Estimated cost in dollars.\n */\nexport function estimateCost(\n tokenUsage: number,\n ratePerMillionTokens: number,\n): number {\n return (tokenUsage / 1_000_000) * ratePerMillionTokens;\n}\n\n// ============================================================================\n// Validation Helpers\n// ============================================================================\n\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\"]);\n\n/**\n * Validate that a base URL uses the `http:` or `https:` protocol.\n * Throws immediately at adapter creation time (not at call time) to surface\n * configuration errors before any LLM requests are made.\n *\n * @param baseURL - The base URL string to validate.\n * @throws When the URL is malformed or uses a protocol other than `http:` or `https:`.\n */\nexport function validateBaseURL(baseURL: string): void {\n try {\n const url = new URL(baseURL);\n if (!ALLOWED_PROTOCOLS.has(url.protocol)) {\n throw new Error(\n `[Directive] Invalid baseURL protocol \"${url.protocol}\" – only http: and https: are allowed`,\n );\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith(\"[Directive]\")) {\n throw err;\n }\n\n throw new Error(\n `[Directive] Invalid baseURL \"${baseURL}\" – must be a valid URL (e.g. \"https://api.openai.com/v1\")`,\n );\n }\n}\n\n// ============================================================================\n// createRunner Helper\n// ============================================================================\n\n/** Parsed response from an LLM provider */\nexport interface ParsedResponse {\n text: string;\n totalTokens: number;\n /** Input token count, when available from the provider */\n inputTokens?: number;\n /** Output token count, when available from the provider */\n outputTokens?: number;\n}\n\n/** Options for creating an AgentRunner from buildRequest/parseResponse */\nexport interface CreateRunnerOptions {\n fetch?: typeof globalThis.fetch;\n buildRequest: (\n agent: AgentLike,\n input: string,\n messages: Message[],\n ) => { url: string; init: RequestInit };\n parseResponse: (\n response: Response,\n messages: Message[],\n ) => Promise<ParsedResponse>;\n parseOutput?: <T>(text: string) => T;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n}\n\n/**\n * Create an {@link AgentRunner} from `buildRequest`/`parseResponse` helpers, reducing\n * ~50 lines of fetch boilerplate to ~20 lines of configuration.\n *\n * @remarks\n * Supports lifecycle hooks for observability:\n * - `onBeforeCall` fires before each API request\n * - `onAfterCall` fires after a successful response (includes token breakdown)\n * - `onError` fires when the request fails\n *\n * Output parsing defaults to `JSON.parse` with a string fallback. Supply a custom\n * `parseOutput` to override (e.g. for structured output schemas).\n *\n * @param options - Configuration for the runner, including request building, response parsing, and hooks.\n * @returns An {@link AgentRunner} function that performs LLM calls via fetch.\n *\n * @example\n * ```typescript\n * const runClaude = createRunner({\n * buildRequest: (agent, input) => ({\n * url: \"/api/claude\",\n * init: {\n * method: \"POST\",\n * headers: { \"Content-Type\": \"application/json\" },\n * body: JSON.stringify({\n * model: agent.model ?? \"claude-haiku-4-5-20251001\",\n * system: agent.instructions ?? \"\",\n * messages: [{ role: \"user\", content: input }],\n * }),\n * },\n * }),\n * parseResponse: async (res) => {\n * const data = await res.json();\n * const inputTokens = data.usage?.input_tokens ?? 0;\n * const outputTokens = data.usage?.output_tokens ?? 0;\n * return {\n * text: data.content?.[0]?.text ?? \"\",\n * totalTokens: inputTokens + outputTokens,\n * inputTokens,\n * outputTokens,\n * };\n * },\n * hooks: {\n * onAfterCall: ({ durationMs, tokenUsage }) => {\n * console.log(`LLM call: ${durationMs}ms, ${tokenUsage.inputTokens}in/${tokenUsage.outputTokens}out`);\n * },\n * },\n * });\n * ```\n *\n * @public\n */\nexport function createRunner(options: CreateRunnerOptions): AgentRunner {\n const {\n fetch: fetchFn = globalThis.fetch,\n buildRequest,\n parseResponse,\n parseOutput,\n hooks,\n } = options;\n\n const defaultParseOutput = <T>(text: string): T => {\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n };\n\n const parse = parseOutput ?? defaultParseOutput;\n\n return async <T = unknown>(\n agent: AgentLike,\n input: string,\n runOptions?: RunOptions,\n ): Promise<RunResult<T>> => {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n const messages: Message[] = [{ role: \"user\", content: input }];\n\n try {\n const { url, init } = buildRequest(agent, input, messages);\n\n const fetchInit: RequestInit = runOptions?.signal\n ? { ...init, signal: runOptions.signal }\n : init;\n\n const response = await fetchFn(url, fetchInit);\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] AgentRunner request failed: ${response.status} ${response.statusText}${errBody ? ` – ${errBody.slice(0, 300)}` : \"\"}`,\n );\n }\n\n const parsed = await parseResponse(response, messages);\n const tokenUsage: TokenUsage = {\n inputTokens: parsed.inputTokens ?? 0,\n outputTokens: parsed.outputTokens ?? 0,\n };\n\n const assistantMessage: Message = {\n role: \"assistant\",\n content: parsed.text,\n };\n const allMessages: Message[] = [...messages, assistantMessage];\n\n runOptions?.onMessage?.(assistantMessage);\n\n const durationMs = Date.now() - startTime;\n hooks?.onAfterCall?.({\n agent,\n input,\n output: parsed.text,\n totalTokens: parsed.totalTokens,\n tokenUsage,\n durationMs,\n timestamp: Date.now(),\n });\n\n return {\n output: parse<T>(parsed.text),\n messages: allMessages,\n toolCalls: [],\n totalTokens: parsed.totalTokens,\n tokenUsage,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs,\n timestamp: Date.now(),\n });\n }\n\n throw err;\n }\n };\n}\n","/**\n * Shared utilities for streaming adapters.\n *\n * Extracts common SSE parsing, error handling, hook lifecycle, and response\n * building logic used across Anthropic, OpenAI, and Gemini streaming runners.\n */\n\nimport type {\n AdapterHooks,\n AgentLike,\n Message,\n TokenUsage,\n} from \"../types.js\";\n\n// ============================================================================\n// HTTP Error Handling\n// ============================================================================\n\n/**\n * Throw a standardized HTTP error from a streaming response.\n * Reads up to 200 chars of the error body for diagnostics.\n */\nexport async function throwStreamingHTTPError(\n response: Response,\n adapterName: string,\n): Promise<never> {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] ${adapterName} streaming error ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n}\n\n/**\n * Get an SSE reader from a response, throwing if body is missing.\n */\nexport function getSSEReader(\n response: Response,\n): ReadableStreamDefaultReader<Uint8Array> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"[Directive] No response body\");\n }\n\n return reader;\n}\n\n// ============================================================================\n// API Key Validation\n// ============================================================================\n\n/**\n * Warn in non-production environments if an API key is empty.\n */\nexport function warnIfMissingApiKey(\n apiKey: string | undefined,\n functionName: string,\n): void {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\" &&\n !apiKey\n ) {\n console.warn(\n `[Directive] ${functionName}: apiKey is empty. API calls will fail.`,\n );\n }\n}\n\n// ============================================================================\n// SSE Stream Parser\n// ============================================================================\n\n/** Result from parsing a single SSE event (provider-specific). */\nexport interface SSEEventResult {\n /** Text token to append to output. */\n text?: string;\n /** Updated input token count (cumulative, not delta). */\n inputTokens?: number;\n /** Updated output token count (cumulative, not delta). */\n outputTokens?: number;\n}\n\n/**\n * Parse an SSE stream from a Response, calling `onToken` for each text chunk\n * and `parseEvent` for provider-specific event extraction.\n *\n * Handles buffering, `[DONE]` sentinels, malformed JSON, and reader cleanup.\n *\n * @param reader - The ReadableStream reader from the response body.\n * @param onToken - Callback for each text token (may be undefined).\n * @param parseEvent - Provider-specific function to extract text and tokens from a parsed SSE event.\n * @param adapterName - Adapter name for dev-mode warnings.\n * @returns The full text output and final token counts.\n */\nexport async function parseSSEStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n onToken: ((token: string) => void) | undefined,\n parseEvent: (event: Record<string, unknown>) => SSEEventResult,\n adapterName: string,\n): Promise<{ fullText: string; inputTokens: number; outputTokens: number }> {\n const decoder = new TextDecoder();\n let buf = \"\";\n let fullText = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) {\n continue;\n }\n const data = line.slice(6).trim();\n if (data === \"[DONE]\") {\n continue;\n }\n\n try {\n const event = JSON.parse(data);\n const result = parseEvent(event);\n if (result.text) {\n fullText += result.text;\n onToken?.(result.text);\n }\n if (result.inputTokens !== undefined) {\n inputTokens = result.inputTokens;\n }\n if (result.outputTokens !== undefined) {\n outputTokens = result.outputTokens;\n }\n } catch (parseErr) {\n if (parseErr instanceof SyntaxError) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV === \"development\"\n ) {\n console.warn(\n `[Directive] Malformed SSE event from ${adapterName}:`,\n data,\n );\n }\n } else {\n throw parseErr;\n }\n }\n }\n }\n } finally {\n reader.cancel().catch(() => {});\n }\n\n return { fullText, inputTokens, outputTokens };\n}\n\n// ============================================================================\n// Hook Lifecycle Helpers\n// ============================================================================\n\n/**\n * Fire the onBeforeCall hook and return the start timestamp.\n */\nexport function fireBeforeCallHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n): number {\n const startTime = Date.now();\n hooks?.onBeforeCall?.({ agent, input, timestamp: startTime });\n\n return startTime;\n}\n\n/**\n * Fire the onAfterCall hook with timing and token data.\n */\nexport function fireAfterCallHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n output: string,\n totalTokens: number,\n tokenUsage: TokenUsage,\n startTime: number,\n): void {\n hooks?.onAfterCall?.({\n agent,\n input,\n output,\n totalTokens,\n tokenUsage,\n durationMs: Date.now() - startTime,\n timestamp: Date.now(),\n });\n}\n\n/**\n * Fire the onError hook if the error is an Error instance.\n */\nexport function fireErrorHook(\n hooks: AdapterHooks | undefined,\n agent: AgentLike,\n input: string,\n err: unknown,\n startTime: number,\n): void {\n if (err instanceof Error) {\n hooks?.onError?.({\n agent,\n input,\n error: err,\n durationMs: Date.now() - startTime,\n timestamp: Date.now(),\n });\n }\n}\n\n// ============================================================================\n// Streaming Response Builder\n// ============================================================================\n\n/**\n * Build the standard streaming runner return value.\n */\nexport function buildStreamingResult(\n input: string,\n fullText: string,\n totalTokens: number,\n tokenUsage: TokenUsage,\n): {\n output: string;\n messages: Message[];\n toolCalls: never[];\n totalTokens: number;\n tokenUsage: TokenUsage;\n} {\n const assistantMsg: Message = { role: \"assistant\", content: fullText };\n\n return {\n output: fullText,\n messages: [{ role: \"user\" as const, content: input }, assistantMsg],\n toolCalls: [],\n totalTokens,\n tokenUsage,\n };\n}\n","/**\n * @directive-run/ai/openai\n *\n * OpenAI adapter for Directive AI. Provides runners and embedders\n * for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * @example\n * ```typescript\n * import { createOpenAIRunner, createOpenAIEmbedder } from '@directive-run/ai/openai';\n *\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { EmbedderFn, Embedding } from \"../guardrails/semantic-cache.js\";\nimport type {\n AdapterHooks,\n AgentRunner,\n} from \"../types.js\";\nimport type { StreamingCallbackRunner } from \"../types.js\";\nimport {\n buildStreamingResult,\n fireAfterCallHook,\n fireBeforeCallHook,\n fireErrorHook,\n getSSEReader,\n parseSSEStream,\n throwStreamingHTTPError,\n warnIfMissingApiKey,\n} from \"./shared.js\";\n\n// ============================================================================\n// Pricing Constants\n// ============================================================================\n\n/**\n * OpenAI model pricing (USD per million tokens).\n *\n * Use with `estimateCost()` for per-call cost tracking:\n * ```typescript\n * import { estimateCost } from '@directive-run/ai';\n * import { OPENAI_PRICING } from '@directive-run/ai/openai';\n *\n * const cost =\n * estimateCost(result.tokenUsage!.inputTokens, OPENAI_PRICING[\"gpt-4o\"].input) +\n * estimateCost(result.tokenUsage!.outputTokens, OPENAI_PRICING[\"gpt-4o\"].output);\n * ```\n *\n * **Note:** Pricing changes over time. These values are provided as a convenience\n * and may not reflect the latest rates. Always verify at https://openai.com/pricing\n */\nexport const OPENAI_PRICING: Record<string, { input: number; output: number }> =\n {\n \"gpt-4.1\": { input: 2, output: 8 },\n \"gpt-4.1-mini\": { input: 0.4, output: 1.6 },\n \"gpt-4.1-nano\": { input: 0.1, output: 0.4 },\n \"gpt-4o\": { input: 2.5, output: 10 },\n \"gpt-4o-mini\": { input: 0.15, output: 0.6 },\n \"gpt-4-turbo\": { input: 10, output: 30 },\n \"o4-mini\": { input: 1.1, output: 4.4 },\n \"o3\": { input: 10, output: 40 },\n \"o3-mini\": { input: 1.1, output: 4.4 },\n };\n\n// ============================================================================\n// OpenAI Runner\n// ============================================================================\n\n/** Options for createOpenAIRunner */\nexport interface OpenAIRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default undefined */\n timeoutMs?: number;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create an AgentRunner for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * // OpenAI\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n *\n * // Azure OpenAI\n * const azure = createOpenAIRunner({\n * apiKey: process.env.AZURE_KEY!,\n * baseURL: \"https://your-resource.openai.azure.com/v1\",\n * });\n *\n * // Together.ai (OpenAI-compatible)\n * const together = createOpenAIRunner({\n * apiKey: process.env.TOGETHER_KEY!,\n * baseURL: \"https://api.together.xyz/v1\",\n * });\n * ```\n */\nexport function createOpenAIRunner(options: OpenAIRunnerOptions): AgentRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return createRunner({\n fetch: fetchFn,\n hooks,\n buildRequest: (agent, _input, messages) => ({\n url: `${baseURL}/chat/completions`,\n init: {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n ...messages.map((m) => ({ role: m.role, content: m.content })),\n ],\n }),\n ...(timeoutMs != null\n ? { signal: AbortSignal.timeout(timeoutMs) }\n : {}),\n },\n }),\n parseResponse: async (res) => {\n const data = await res.json();\n const text = data.choices?.[0]?.message?.content ?? \"\";\n const inputTokens = data.usage?.prompt_tokens ?? 0;\n const outputTokens = data.usage?.completion_tokens ?? 0;\n\n return {\n text,\n totalTokens: inputTokens + outputTokens,\n inputTokens,\n outputTokens,\n };\n },\n });\n}\n\n// ============================================================================\n// OpenAI Embedder\n// ============================================================================\n\n/** Options for createOpenAIEmbedder */\nexport interface OpenAIEmbedderOptions {\n apiKey: string;\n model?: string;\n dimensions?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default 30000 */\n timeoutMs?: number;\n}\n\n/**\n * Create an EmbedderFn that calls the OpenAI embeddings API.\n *\n * @example\n * ```typescript\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedding = await embedder('How do constraints work?');\n * ```\n */\nexport function createOpenAIEmbedder(\n options: OpenAIEmbedderOptions,\n): EmbedderFn {\n const {\n apiKey,\n model = \"text-embedding-3-small\",\n dimensions = 1536,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIEmbedder\");\n\n return async (text: string): Promise<Embedding> => {\n const response = await fetchFn(`${baseURL}/embeddings`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ model, input: text, dimensions }),\n signal: AbortSignal.timeout(timeoutMs ?? 30_000),\n });\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] OpenAI embedding failed: ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[] }>;\n };\n\n const entry = data.data[0];\n if (!entry) {\n throw new Error(\n \"[Directive] OpenAI embedding response contained no data entries\",\n );\n }\n\n return entry.embedding;\n };\n}\n\n// ============================================================================\n// OpenAI Streaming Runner\n// ============================================================================\n\n/** Options for createOpenAIStreamingRunner */\nexport interface OpenAIStreamingRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create a StreamingCallbackRunner for OpenAI-compatible chat completions\n * with server-sent events. Can be used standalone or paired with `createOpenAIRunner`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * const streamingRunner = createOpenAIStreamingRunner({\n * apiKey: process.env.OPENAI_API_KEY!,\n * });\n * const streamRunner = createStreamingRunner(streamingRunner);\n * const { stream, result } = streamRunner(agent, input);\n * ```\n */\nexport function createOpenAIStreamingRunner(\n options: OpenAIStreamingRunnerOptions,\n): StreamingCallbackRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIStreamingRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return async (agent, input, callbacks) => {\n const startTime = fireBeforeCallHook(hooks, agent, input);\n\n try {\n const response = await fetchFn(`${baseURL}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n { role: \"user\", content: input },\n ],\n stream: true,\n stream_options: { include_usage: true },\n }),\n signal: callbacks.signal,\n });\n\n if (!response.ok) {\n await throwStreamingHTTPError(response, \"OpenAI\");\n }\n\n const reader = getSSEReader(response);\n\n const { fullText, inputTokens, outputTokens } = await parseSSEStream(\n reader,\n callbacks.onToken,\n (event) => {\n const result: { text?: string; inputTokens?: number; outputTokens?: number } = {};\n\n const delta = (event.choices as Array<Record<string, unknown>>)?.[0]\n ?.delta as Record<string, unknown> | undefined;\n if (delta?.content) {\n result.text = delta.content as string;\n }\n\n if (event.usage) {\n result.inputTokens = (event.usage as Record<string, unknown>).prompt_tokens as number ?? 0;\n result.outputTokens = (event.usage as Record<string, unknown>).completion_tokens as number ?? 0;\n }\n\n return result;\n },\n \"OpenAI\",\n );\n\n const tokenUsage = { inputTokens, outputTokens };\n const totalTokens = inputTokens + outputTokens;\n\n callbacks.onMessage?.({ role: \"assistant\", content: fullText });\n fireAfterCallHook(hooks, agent, input, fullText, totalTokens, tokenUsage, startTime);\n\n return buildStreamingResult(input, fullText, totalTokens, tokenUsage);\n } catch (err) {\n fireErrorHook(hooks, agent, input, err, startTime);\n\n throw err;\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/openai.ts"],"names":["OPENAI_PRICING","createOpenAIRunner","options","apiKey","model","maxTokens","baseURL","fetchFn","timeoutMs","hooks","temperature","topP","stop","responseFormat","validateBaseURL","warnIfMissingApiKey","resolvedResponseFormat","createRunner","agent","_input","messages","m","res","data","text","inputTokens","outputTokens","createOpenAIEmbedder","dimensions","response","errBody","entry","createOpenAIStreamingRunner","input","callbacks","startTime","fireBeforeCallHook","throwStreamingHTTPError","reader","getSSEReader","fullText","parseSSEStream","event","result","delta","tokenUsage","totalTokens","fireAfterCallHook","buildStreamingResult","err","fireErrorHook"],"mappings":"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","file":"openai.js","sourcesContent":["/**\n * @directive-run/ai/openai\n *\n * OpenAI adapter for Directive AI. Provides runners and embedders\n * for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * @example\n * ```typescript\n * import { createOpenAIRunner, createOpenAIEmbedder } from '@directive-run/ai/openai';\n *\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * ```\n */\n\nimport { createRunner, validateBaseURL } from \"../agent-utils.js\";\nimport type { EmbedderFn, Embedding } from \"../guardrails/semantic-cache.js\";\nimport type {\n AdapterHooks,\n AgentRunner,\n} from \"../types.js\";\nimport type { StreamingCallbackRunner } from \"../types.js\";\nimport {\n buildStreamingResult,\n fireAfterCallHook,\n fireBeforeCallHook,\n fireErrorHook,\n getSSEReader,\n parseSSEStream,\n throwStreamingHTTPError,\n warnIfMissingApiKey,\n} from \"./shared.js\";\n\n// ============================================================================\n// Pricing Constants\n// ============================================================================\n\n/**\n * OpenAI model pricing (USD per million tokens).\n *\n * Use with `estimateCost()` for per-call cost tracking:\n * ```typescript\n * import { estimateCost } from '@directive-run/ai';\n * import { OPENAI_PRICING } from '@directive-run/ai/openai';\n *\n * const cost =\n * estimateCost(result.tokenUsage!.inputTokens, OPENAI_PRICING[\"gpt-4o\"].input) +\n * estimateCost(result.tokenUsage!.outputTokens, OPENAI_PRICING[\"gpt-4o\"].output);\n * ```\n *\n * **Note:** Pricing changes over time. These values are provided as a convenience\n * and may not reflect the latest rates. Always verify at https://openai.com/pricing\n */\nexport const OPENAI_PRICING: Record<string, { input: number; output: number }> =\n {\n \"gpt-4.1\": { input: 2, output: 8 },\n \"gpt-4.1-mini\": { input: 0.4, output: 1.6 },\n \"gpt-4.1-nano\": { input: 0.1, output: 0.4 },\n \"gpt-4o\": { input: 2.5, output: 10 },\n \"gpt-4o-mini\": { input: 0.15, output: 0.6 },\n \"gpt-4-turbo\": { input: 10, output: 30 },\n \"o4-mini\": { input: 1.1, output: 4.4 },\n \"o3\": { input: 10, output: 40 },\n \"o3-mini\": { input: 1.1, output: 4.4 },\n };\n\n// ============================================================================\n// OpenAI Runner\n// ============================================================================\n\n/** Options for createOpenAIRunner */\nexport interface OpenAIRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default undefined */\n timeoutMs?: number;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create an AgentRunner for OpenAI-compatible APIs (OpenAI, Azure, Together, etc.)\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * // OpenAI\n * const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });\n *\n * // Azure OpenAI\n * const azure = createOpenAIRunner({\n * apiKey: process.env.AZURE_KEY!,\n * baseURL: \"https://your-resource.openai.azure.com/v1\",\n * });\n *\n * // Together.ai (OpenAI-compatible)\n * const together = createOpenAIRunner({\n * apiKey: process.env.TOGETHER_KEY!,\n * baseURL: \"https://api.together.xyz/v1\",\n * });\n * ```\n */\nexport function createOpenAIRunner(options: OpenAIRunnerOptions): AgentRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return createRunner({\n fetch: fetchFn,\n hooks,\n buildRequest: (agent, _input, messages) => ({\n url: `${baseURL}/chat/completions`,\n init: {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n ...messages.map((m) => ({ role: m.role, content: m.content })),\n ],\n }),\n ...(timeoutMs != null\n ? { signal: AbortSignal.timeout(timeoutMs) }\n : {}),\n },\n }),\n parseResponse: async (res) => {\n const data = await res.json();\n const text = data.choices?.[0]?.message?.content ?? \"\";\n const inputTokens = data.usage?.prompt_tokens ?? 0;\n const outputTokens = data.usage?.completion_tokens ?? 0;\n\n return {\n text,\n totalTokens: inputTokens + outputTokens,\n inputTokens,\n outputTokens,\n };\n },\n });\n}\n\n// ============================================================================\n// OpenAI Embedder\n// ============================================================================\n\n/** Options for createOpenAIEmbedder */\nexport interface OpenAIEmbedderOptions {\n apiKey: string;\n model?: string;\n dimensions?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** @default 30000 */\n timeoutMs?: number;\n}\n\n/**\n * Create an EmbedderFn that calls the OpenAI embeddings API.\n *\n * @example\n * ```typescript\n * const embedder = createOpenAIEmbedder({ apiKey: process.env.OPENAI_API_KEY! });\n * const embedding = await embedder('How do constraints work?');\n * ```\n */\nexport function createOpenAIEmbedder(\n options: OpenAIEmbedderOptions,\n): EmbedderFn {\n const {\n apiKey,\n model = \"text-embedding-3-small\",\n dimensions = 1536,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n timeoutMs,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIEmbedder\");\n\n return async (text: string): Promise<Embedding> => {\n const response = await fetchFn(`${baseURL}/embeddings`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ model, input: text, dimensions }),\n signal: AbortSignal.timeout(timeoutMs ?? 30_000),\n });\n\n if (!response.ok) {\n const errBody = await response.text().catch(() => \"\");\n\n throw new Error(\n `[Directive] OpenAI embedding failed: ${response.status}${errBody ? ` – ${errBody.slice(0, 200)}` : \"\"}`,\n );\n }\n\n const data = (await response.json()) as {\n data: Array<{ embedding: number[] }>;\n };\n\n const entry = data.data[0];\n if (!entry) {\n throw new Error(\n \"[Directive] OpenAI embedding response contained no data entries\",\n );\n }\n\n return entry.embedding;\n };\n}\n\n// ============================================================================\n// OpenAI Streaming Runner\n// ============================================================================\n\n/** Options for createOpenAIStreamingRunner */\nexport interface OpenAIStreamingRunnerOptions {\n apiKey: string;\n model?: string;\n maxTokens?: number;\n baseURL?: string;\n fetch?: typeof globalThis.fetch;\n /** Lifecycle hooks for tracing, logging, and metrics */\n hooks?: AdapterHooks;\n /** Sampling temperature (0–2). Higher = more random. */\n temperature?: number;\n /** Nucleus sampling: top-P probability mass (0–1). */\n topP?: number;\n /** Up to 4 sequences where the API will stop generating. */\n stop?: string | string[];\n /**\n * Response format for structured output.\n * - `\"json\"` enables JSON mode (`{ type: \"json_object\" }`)\n * - Object form enables JSON Schema mode (`{ type: \"json_schema\", json_schema: ... }`)\n */\n responseFormat?: \"json\" | { type: \"json_schema\"; json_schema: unknown };\n}\n\n/**\n * Create a StreamingCallbackRunner for OpenAI-compatible chat completions\n * with server-sent events. Can be used standalone or paired with `createOpenAIRunner`.\n *\n * Returns `tokenUsage` with input/output breakdown for cost tracking.\n *\n * @example\n * ```typescript\n * const streamingRunner = createOpenAIStreamingRunner({\n * apiKey: process.env.OPENAI_API_KEY!,\n * });\n * const streamRunner = createStreamingRunner(streamingRunner);\n * const { stream, result } = streamRunner(agent, input);\n * ```\n */\nexport function createOpenAIStreamingRunner(\n options: OpenAIStreamingRunnerOptions,\n): StreamingCallbackRunner {\n const {\n apiKey,\n model = \"gpt-4o\",\n maxTokens,\n baseURL = \"https://api.openai.com/v1\",\n fetch: fetchFn = globalThis.fetch,\n hooks,\n temperature,\n topP,\n stop,\n responseFormat,\n } = options;\n\n validateBaseURL(baseURL);\n warnIfMissingApiKey(apiKey, \"createOpenAIStreamingRunner\");\n\n const resolvedResponseFormat =\n responseFormat === \"json\"\n ? { type: \"json_object\" as const }\n : responseFormat ?? undefined;\n\n return async (agent, input, callbacks) => {\n const startTime = fireBeforeCallHook(hooks, agent, input);\n\n try {\n const response = await fetchFn(`${baseURL}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: agent.model ?? model,\n ...(maxTokens != null ? { max_tokens: maxTokens } : {}),\n ...(temperature != null ? { temperature } : {}),\n ...(topP != null ? { top_p: topP } : {}),\n ...(stop != null ? { stop } : {}),\n ...(resolvedResponseFormat != null\n ? { response_format: resolvedResponseFormat }\n : {}),\n messages: [\n ...(agent.instructions\n ? [{ role: \"system\", content: agent.instructions }]\n : []),\n { role: \"user\", content: input },\n ],\n stream: true,\n stream_options: { include_usage: true },\n }),\n signal: callbacks.signal,\n });\n\n if (!response.ok) {\n await throwStreamingHTTPError(response, \"OpenAI\");\n }\n\n const reader = getSSEReader(response);\n\n const { fullText, inputTokens, outputTokens } = await parseSSEStream(\n reader,\n callbacks.onToken,\n (event) => {\n const result: { text?: string; inputTokens?: number; outputTokens?: number } = {};\n\n const delta = (event.choices as Array<Record<string, unknown>>)?.[0]\n ?.delta as Record<string, unknown> | undefined;\n if (delta?.content) {\n result.text = delta.content as string;\n }\n\n if (event.usage) {\n result.inputTokens = (event.usage as Record<string, unknown>).prompt_tokens as number ?? 0;\n result.outputTokens = (event.usage as Record<string, unknown>).completion_tokens as number ?? 0;\n }\n\n return result;\n },\n \"OpenAI\",\n );\n\n const tokenUsage = { inputTokens, outputTokens };\n const totalTokens = inputTokens + outputTokens;\n\n callbacks.onMessage?.({ role: \"assistant\", content: fullText });\n fireAfterCallHook(hooks, agent, input, fullText, totalTokens, tokenUsage, startTime);\n\n return buildStreamingResult(input, fullText, totalTokens, tokenUsage);\n } catch (err) {\n fireErrorHook(hooks, agent, input, err, startTime);\n\n throw err;\n }\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as Message$1,
|
|
1
|
+
import { M as Message$1, n as RunResult, A as AgentLike, G as GuardrailFn, O as OutputGuardrailData, aX as StreamingCallbackRunner, q as DebugEvent, a8 as DebugEventType, b as AgentRunner, az as OrchestratorState, au as NamedGuardrail, I as InputGuardrailData, W as Checkpoint, L as BreakpointModifications, N as BreakpointRequest, o as OrchestratorConstraint, ax as OrchestratorResolver, aj as GuardrailsConfig, z as ApprovalRequest, av as OrchestratorDebugConfig, w as AgentRetryConfig, aw as OrchestratorLifecycleHooks, aU as SelfHealingConfig, e as CheckpointStore, H as BreakpointConfig, am as HealthMonitorConfig, p as RunOptions, T as ToolCallGuardrailData, l as PatternCheckpointConfig, i as DagPattern, m as GoalPattern, j as GoalNode, g as AgentSelectionStrategy, R as RelaxationTier, r as GoalResult, ab as GoalCheckpointState, aV as SequentialCheckpointState, aY as SupervisorCheckpointState, aG as ReflectCheckpointState, a5 as DebateCheckpointState, a2 as DagCheckpointState, aS as Scratchpad, as as MultiAgentLifecycleHooks, at as MultiAgentSelfHealingConfig, aq as MultiAgentBreakpointType, a0 as CrossAgentDerivationFn } from './types-CRmwFnVk.js';
|
|
2
2
|
import { Plugin, System, Requirement } from '@directive-run/core';
|
|
3
3
|
import { CircuitBreaker } from '@directive-run/core/plugins';
|
|
4
4
|
|
|
@@ -998,8 +998,8 @@ interface AgentOrchestrator<F extends Record<string, unknown>> {
|
|
|
998
998
|
cancelBreakpoint(id: string, reason?: string): void;
|
|
999
999
|
/** Get all currently pending breakpoint requests. */
|
|
1000
1000
|
getPendingBreakpoints(): BreakpointRequest[];
|
|
1001
|
-
/**
|
|
1002
|
-
|
|
1001
|
+
/** Destroy the orchestrator, releasing all resources. */
|
|
1002
|
+
destroy(): void;
|
|
1003
1003
|
}
|
|
1004
1004
|
/**
|
|
1005
1005
|
* Create a constraint-driven agent orchestrator backed by a Directive System.
|
|
@@ -1208,97 +1208,6 @@ declare class ReflectionExhaustedError extends Error {
|
|
|
1208
1208
|
*/
|
|
1209
1209
|
declare function withReflection<T = unknown>(runner: AgentRunner, config: ReflectionConfig<T>): AgentRunner;
|
|
1210
1210
|
|
|
1211
|
-
/**
|
|
1212
|
-
* Get the current step/round/iteration count from a pattern checkpoint state.
|
|
1213
|
-
*
|
|
1214
|
-
* Maps each pattern type to its natural progress counter: `step` for sequential
|
|
1215
|
-
* and goal, `round` for supervisor and debate, `iteration` for reflect, and
|
|
1216
|
-
* `completedCount` for DAG.
|
|
1217
|
-
*
|
|
1218
|
-
* @param state - The pattern checkpoint state to inspect.
|
|
1219
|
-
* @returns The current progress count for the pattern.
|
|
1220
|
-
*/
|
|
1221
|
-
declare function getPatternStep(state: PatternCheckpointState): number;
|
|
1222
|
-
/**
|
|
1223
|
-
* Compute progress metrics from a pattern checkpoint state.
|
|
1224
|
-
*
|
|
1225
|
-
* Returns percentage complete, steps completed/remaining, tokens consumed,
|
|
1226
|
-
* and estimated tokens remaining (when computable). Each pattern type
|
|
1227
|
-
* calculates these metrics from its own state structure.
|
|
1228
|
-
*
|
|
1229
|
-
* @param state - The pattern checkpoint state to analyze.
|
|
1230
|
-
* @returns A {@link CheckpointProgress} object with completion metrics.
|
|
1231
|
-
*/
|
|
1232
|
-
declare function getCheckpointProgress(state: PatternCheckpointState): CheckpointProgress;
|
|
1233
|
-
/**
|
|
1234
|
-
* Compute the diff between two checkpoint states of the same pattern type.
|
|
1235
|
-
*
|
|
1236
|
-
* Returns the delta in steps, tokens, and time between checkpoints.
|
|
1237
|
-
* Useful for understanding how much progress occurred between saves.
|
|
1238
|
-
*
|
|
1239
|
-
* @param a - The earlier checkpoint state.
|
|
1240
|
-
* @param b - The later checkpoint state.
|
|
1241
|
-
* @returns A {@link CheckpointDiff} with step, token, and time deltas.
|
|
1242
|
-
* @throws If the two checkpoints have different pattern types.
|
|
1243
|
-
*/
|
|
1244
|
-
declare function diffCheckpoints(a: PatternCheckpointState, b: PatternCheckpointState): CheckpointDiff;
|
|
1245
|
-
/**
|
|
1246
|
-
* Fork an orchestrator from a checkpoint — creates a new independent orchestrator
|
|
1247
|
-
* restored to the checkpoint's state, ready to diverge from that point.
|
|
1248
|
-
*
|
|
1249
|
-
* @param options - The original orchestrator options used to create the orchestrator
|
|
1250
|
-
* @param checkpointStore - The checkpoint store containing the checkpoint
|
|
1251
|
-
* @param checkpointId - The ID of the checkpoint to fork from
|
|
1252
|
-
* @returns A new independent MultiAgentOrchestrator restored to checkpoint state
|
|
1253
|
-
*
|
|
1254
|
-
* @example
|
|
1255
|
-
* ```typescript
|
|
1256
|
-
* const forked = await forkFromCheckpoint(orchestratorOptions, store, "ckpt_abc123");
|
|
1257
|
-
* const result = await forked.replay("ckpt_abc123", pattern, { input: "new input" });
|
|
1258
|
-
* ```
|
|
1259
|
-
*/
|
|
1260
|
-
declare function forkFromCheckpoint(options: MultiAgentOrchestratorOptions, checkpointStore: CheckpointStore, checkpointId: string): Promise<MultiAgentOrchestrator>;
|
|
1261
|
-
/**
|
|
1262
|
-
* Async semaphore for controlling concurrent access.
|
|
1263
|
-
* Uses a queue-based approach instead of polling for efficiency.
|
|
1264
|
-
*
|
|
1265
|
-
* @example
|
|
1266
|
-
* ```typescript
|
|
1267
|
-
* import { Semaphore } from '@directive-run/ai';
|
|
1268
|
-
*
|
|
1269
|
-
* const sem = new Semaphore(3); // Allow 3 concurrent operations
|
|
1270
|
-
*
|
|
1271
|
-
* async function doWork() {
|
|
1272
|
-
* const release = await sem.acquire();
|
|
1273
|
-
* try {
|
|
1274
|
-
* await performWork();
|
|
1275
|
-
* } finally {
|
|
1276
|
-
* release();
|
|
1277
|
-
* }
|
|
1278
|
-
* }
|
|
1279
|
-
* ```
|
|
1280
|
-
*/
|
|
1281
|
-
declare class Semaphore {
|
|
1282
|
-
private count;
|
|
1283
|
-
private readonly maxPermits;
|
|
1284
|
-
private readonly queue;
|
|
1285
|
-
constructor(max: number);
|
|
1286
|
-
/** Create a one-shot release function that guards against double-release */
|
|
1287
|
-
private createReleaseFn;
|
|
1288
|
-
/** Acquire a permit, optionally with abort signal support */
|
|
1289
|
-
acquire(signal?: AbortSignal): Promise<() => void>;
|
|
1290
|
-
/** Non-blocking acquire — returns null if no permits available */
|
|
1291
|
-
tryAcquire(): (() => void) | null;
|
|
1292
|
-
private release;
|
|
1293
|
-
/** Get current available permits */
|
|
1294
|
-
get available(): number;
|
|
1295
|
-
/** Get number of waiters in queue */
|
|
1296
|
-
get waiting(): number;
|
|
1297
|
-
/** Get maximum permits */
|
|
1298
|
-
get max(): number;
|
|
1299
|
-
/** Reject all pending waiters with an error and reset permits */
|
|
1300
|
-
drain(): void;
|
|
1301
|
-
}
|
|
1302
1211
|
/** Configuration for a registered agent */
|
|
1303
1212
|
interface AgentRegistration {
|
|
1304
1213
|
/** The agent instance */
|
|
@@ -1854,53 +1763,8 @@ interface MultiAgentOrchestrator {
|
|
|
1854
1763
|
onDerivedChange(callback: (id: string, value: unknown) => void): () => void;
|
|
1855
1764
|
/** Shared scratchpad (null when not configured) */
|
|
1856
1765
|
readonly scratchpad: Scratchpad | null;
|
|
1857
|
-
/**
|
|
1858
|
-
|
|
1766
|
+
/** Destroy the orchestrator, resetting all state and releasing resources. */
|
|
1767
|
+
destroy(): void;
|
|
1859
1768
|
}
|
|
1860
|
-
/**
|
|
1861
|
-
* Create a multi-agent orchestrator backed by a Directive System.
|
|
1862
|
-
*
|
|
1863
|
-
* Each registered agent becomes a namespaced Directive module with reactive state,
|
|
1864
|
-
* constraint evaluation, guardrails, streaming, approval, memory, retry, budget,
|
|
1865
|
-
* hooks, and time-travel debugging -- all features at parity with {@link createAgentOrchestrator}.
|
|
1866
|
-
*
|
|
1867
|
-
* @param options - Orchestrator configuration including runner, agent registry, patterns, guardrails, and plugins.
|
|
1868
|
-
* @returns A {@link MultiAgentOrchestrator} instance with `runAgent`, `runPattern`, `handoff`, and checkpoint APIs.
|
|
1869
|
-
*
|
|
1870
|
-
* @example
|
|
1871
|
-
* ```typescript
|
|
1872
|
-
* const orchestrator = createMultiAgentOrchestrator({
|
|
1873
|
-
* runner,
|
|
1874
|
-
* agents: {
|
|
1875
|
-
* researcher: { agent: researchAgent, maxConcurrent: 3 },
|
|
1876
|
-
* writer: { agent: writerAgent },
|
|
1877
|
-
* reviewer: { agent: reviewerAgent },
|
|
1878
|
-
* },
|
|
1879
|
-
* guardrails: {
|
|
1880
|
-
* input: [detectPII],
|
|
1881
|
-
* output: [checkToxicity],
|
|
1882
|
-
* },
|
|
1883
|
-
* hooks: {
|
|
1884
|
-
* onAgentStart: ({ agentId, input }) => console.log(`${agentId}: ${input}`),
|
|
1885
|
-
* },
|
|
1886
|
-
* maxTokenBudget: 50000,
|
|
1887
|
-
* debug: true,
|
|
1888
|
-
* });
|
|
1889
|
-
*
|
|
1890
|
-
* // Run with full guardrails + approval + streaming
|
|
1891
|
-
* const result = await orchestrator.runAgent('researcher', 'What is AI?');
|
|
1892
|
-
*
|
|
1893
|
-
* // Stream agent output
|
|
1894
|
-
* const { stream } = orchestrator.runAgentStream('writer', 'Write about AI');
|
|
1895
|
-
* for await (const chunk of stream) {
|
|
1896
|
-
* if (chunk.type === 'token') process.stdout.write(chunk.data);
|
|
1897
|
-
* }
|
|
1898
|
-
* ```
|
|
1899
|
-
*
|
|
1900
|
-
* @throws If a pattern references an agent that is not in the registry
|
|
1901
|
-
* @throws If autoApproveToolCalls is false but no onApprovalRequest callback is provided
|
|
1902
|
-
* @public
|
|
1903
|
-
*/
|
|
1904
|
-
declare function createMultiAgentOrchestrator(options: MultiAgentOrchestratorOptions): MultiAgentOrchestrator;
|
|
1905
1769
|
|
|
1906
|
-
export { type SafeParseResult as $, type AgentRegistry as A, type BackpressureStrategy as B, type
|
|
1770
|
+
export { type SafeParseResult as $, type AgentRegistry as A, type BackpressureStrategy as B, type MessageChunk as C, type DebatePattern as D, type ExecutionPattern as E, type MessageSummarizer as F, type GuardrailTriggeredChunk as G, type HealthMonitor as H, type MultiAgentRunCallOptions as I, type MultiAgentState as J, type MultiplexedStreamChunk as K, type MultiplexedStreamResult as L, type MultiAgentOrchestratorOptions as M, type OrchestratorStreamChunk as N, type OrchestratorOptions as O, type ParallelPattern as P, type OrchestratorStreamResult as Q, type RacePattern as R, type SequentialPattern as S, type ProgressChunk as T, type RaceResult as U, type RaceSuccessEntry as V, type ReflectionConfig as W, type ReflectionContext as X, type ReflectionEvaluator as Y, ReflectionExhaustedError as Z, type RunCallOptions as _, type MultiAgentOrchestrator as a, type SafeParseable as a0, type StreamChunk as a1, type StreamRunOptions as a2, type StreamRunner as a3, type StreamingGuardrail as a4, type StreamingGuardrailResult as a5, type StreamingRunResult as a6, type StructuredOutputConfig as a7, StructuredOutputError as a8, type TaskContext as a9, tapStream as aA, withReflection as aB, withStructuredOutput as aC, type TaskRegistration as aa, type TokenChunk as ab, type ToolEndChunk as ac, type ToolStartChunk as ad, adaptOutputGuardrail as ae, collectTokens as af, combineStreamingGuardrails as ag, createAgentMemory as ah, createAgentOrchestrator as ai, createDebugTimeline as aj, createDebugTimelinePlugin as ak, createHealthMonitor as al, createHybridStrategy as am, createKeyPointsSummarizer as an, createLLMSummarizer as ao, createLengthStreamingGuardrail as ap, createPatternStreamingGuardrail as aq, createSlidingWindowStrategy as ar, createStreamingRunner as as, createTokenBasedStrategy as at, createToxicityStreamingGuardrail as au, createTruncationSummarizer as av, extractJsonFromOutput as aw, filterStream as ax, mapStream as ay, mergeTaggedStreams as az, type ReflectionEvaluation as b, type ReflectIterationRecord as c, type ReflectPattern as d, type SupervisorPattern as e, type RunAgentRequirement as f, type DebateResult as g, type AgentHealthMetrics as h, type DebugTimeline as i, type AgentMemory as j, type AgentMemoryConfig as k, type AgentOrchestrator as l, type AgentRegistration as m, type DebugTimelineListener as n, type DebugTimelineOptions as o, type DoneChunk as p, type ErrorChunk as q, type HandoffRequest as r, type HandoffResult as s, type HealthCircuitState as t, type MemoryManageResult as u, type MemoryState as v, type MemoryStrategy as w, type MemoryStrategyConfig as x, type MemoryStrategyResult as y, type MergedTaggedStreamResult as z };
|