@yolk-sdk/agent 0.1.0-canary.21 → 0.1.0-canary.22

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.
Files changed (33) hide show
  1. package/README.md +18 -5
  2. package/dist/loop/run.d.mts.map +1 -1
  3. package/dist/loop/run.mjs +38 -19
  4. package/dist/loop/run.mjs.map +1 -1
  5. package/dist/protocol/index.d.mts +2 -2
  6. package/dist/protocol/index.d.mts.map +1 -1
  7. package/dist/protocol/index.mjs +2 -2
  8. package/dist/protocol/message.d.mts +20 -1
  9. package/dist/protocol/message.d.mts.map +1 -1
  10. package/dist/protocol/message.mjs +59 -1
  11. package/dist/protocol/message.mjs.map +1 -1
  12. package/dist/providers/anthropic/claude-provider.d.mts.map +1 -1
  13. package/dist/providers/anthropic/claude-provider.mjs +2 -0
  14. package/dist/providers/anthropic/claude-provider.mjs.map +1 -1
  15. package/dist/providers/openai/codex-provider.d.mts.map +1 -1
  16. package/dist/providers/openai/codex-provider.mjs +2 -0
  17. package/dist/providers/openai/codex-provider.mjs.map +1 -1
  18. package/dist/providers/openai/provider.d.mts.map +1 -1
  19. package/dist/providers/openai/provider.mjs +2 -0
  20. package/dist/providers/openai/provider.mjs.map +1 -1
  21. package/dist/providers/transcript.d.mts +9 -0
  22. package/dist/providers/transcript.d.mts.map +1 -0
  23. package/dist/providers/transcript.mjs +17 -0
  24. package/dist/providers/transcript.mjs.map +1 -0
  25. package/package.json +1 -1
  26. package/src/loop/run.ts +56 -17
  27. package/src/protocol/index.ts +9 -1
  28. package/src/protocol/message.ts +127 -0
  29. package/src/providers/anthropic/claude-provider.ts +2 -0
  30. package/src/providers/openai/codex-provider.ts +2 -0
  31. package/src/providers/openai/provider.ts +2 -0
  32. package/src/providers/transcript.ts +24 -0
  33. package/src/tools/README.md +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"codex-provider.mjs","names":["Arr","LLMReasoningDelta","LLMTextDelta"],"sources":["../../../src/providers/openai/codex-provider.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option, Ref, Stream } from 'effect'\nimport {\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolCall,\n attachmentSourceDataUrl,\n assistantContent,\n assistantHostToolCalls,\n contentParts,\n messageContextText,\n prependMessageContextToContent,\n type AgentMessage,\n type AgentReasoningEffort,\n type Content,\n type ContentPart,\n type ProviderFailureKind,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMReasoningDelta,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport { openAiCodexAuthorizationHeaders, openAiCodexResponsesUrl } from './codex.ts'\nimport type { OAuthAccessToken } from '@yolk-sdk/agent/oauth'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\n\nexport type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed'\n\nexport type OpenAiCodexProviderConfig = {\n readonly token: OAuthAccessToken\n readonly responsesUrl?: string\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n}\n\ntype OpenAiCodexMessageInput = {\n readonly role: 'user' | 'assistant'\n readonly content: string | ReadonlyArray<OpenAiCodexInputContentPart>\n}\n\ntype OpenAiCodexInputTextPart = {\n readonly type: 'input_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputImagePart = {\n readonly type: 'input_image'\n readonly image_url: string\n}\n\ntype OpenAiCodexInputFilePart = {\n readonly type: 'input_file'\n readonly filename: string\n readonly file_data: string\n}\n\ntype OpenAiCodexOutputTextPart = {\n readonly type: 'output_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputContentPart =\n | OpenAiCodexInputTextPart\n | OpenAiCodexInputImagePart\n | OpenAiCodexInputFilePart\n | OpenAiCodexOutputTextPart\n\ntype OpenAiCodexFunctionCallInput = {\n readonly type: 'function_call'\n readonly call_id: string\n readonly name: string\n readonly arguments: string\n}\n\ntype OpenAiCodexFunctionOutputInput = {\n readonly type: 'function_call_output'\n readonly call_id: string\n readonly output: string\n}\n\ntype OpenAiCodexInputItem =\n | OpenAiCodexMessageInput\n | OpenAiCodexFunctionCallInput\n | OpenAiCodexFunctionOutputInput\n\ntype OpenAiCodexTool = {\n readonly type: 'function'\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n}\n\ntype OpenAiCodexRequestBody = {\n readonly model: string\n readonly instructions: string\n readonly input: ReadonlyArray<OpenAiCodexInputItem>\n readonly store: false\n readonly stream: true\n readonly reasoning: {\n readonly effort: AgentReasoningEffort\n readonly summary: OpenAiCodexReasoningSummary\n }\n readonly tools?: ReadonlyArray<OpenAiCodexTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiCodexReasoningSummaryText extends Schema.Class<OpenAiCodexReasoningSummaryText>(\n 'OpenAiCodexReasoningSummaryText'\n)({\n type: Schema.Literals(['summary_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningText extends Schema.Class<OpenAiCodexReasoningText>(\n 'OpenAiCodexReasoningText'\n)({\n type: Schema.Literals(['reasoning_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexOutputText extends Schema.Class<OpenAiCodexOutputText>('OpenAiCodexOutputText')({\n type: Schema.Literals(['output_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexMessageOutput extends Schema.Class<OpenAiCodexMessageOutput>(\n 'OpenAiCodexMessageOutput'\n)({\n type: Schema.Literals(['message']),\n content: Schema.Array(OpenAiCodexOutputText)\n}) {}\n\nclass OpenAiCodexFunctionCallOutput extends Schema.Class<OpenAiCodexFunctionCallOutput>(\n 'OpenAiCodexFunctionCallOutput'\n)({\n type: Schema.Literals(['function_call']),\n call_id: Schema.String,\n name: Schema.String,\n arguments: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningOutput extends Schema.Class<OpenAiCodexReasoningOutput>(\n 'OpenAiCodexReasoningOutput'\n)({\n type: Schema.Literals(['reasoning']),\n summary: Schema.optional(Schema.Array(OpenAiCodexReasoningSummaryText)),\n content: Schema.optional(Schema.Array(OpenAiCodexReasoningText))\n}) {}\n\nclass OpenAiCodexInputTokensDetails extends Schema.Class<OpenAiCodexInputTokensDetails>(\n 'OpenAiCodexInputTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexOutputTokensDetails extends Schema.Class<OpenAiCodexOutputTokensDetails>(\n 'OpenAiCodexOutputTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexUsageResponse extends Schema.Class<OpenAiCodexUsageResponse>(\n 'OpenAiCodexUsageResponse'\n)({\n input_tokens: Schema.Number,\n output_tokens: Schema.Number,\n input_tokens_details: Schema.optional(OpenAiCodexInputTokensDetails),\n output_tokens_details: Schema.optional(OpenAiCodexOutputTokensDetails)\n}) {}\n\nconst OpenAiCodexOutputItem = Schema.Union([\n OpenAiCodexMessageOutput,\n OpenAiCodexFunctionCallOutput,\n OpenAiCodexReasoningOutput\n])\ntype OpenAiCodexOutputItem = typeof OpenAiCodexOutputItem.Type\n\nclass OpenAiCodexResponse extends Schema.Class<OpenAiCodexResponse>('OpenAiCodexResponse')({\n output_text: Schema.optional(Schema.String),\n output: Schema.Array(OpenAiCodexOutputItem),\n usage: Schema.optional(OpenAiCodexUsageResponse)\n}) {}\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI Codex OAuth provider yet`,\n retryable: false\n })\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst userPartToCodexInputPart = (\n part: ContentPart\n): Effect.Effect<OpenAiCodexInputTextPart | OpenAiCodexInputImagePart | OpenAiCodexInputFilePart, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'input_text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url => Effect.succeed({\n type: 'input_image',\n image_url: url\n })\n })\n case 'Document':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved document source')),\n onSome: url => Effect.succeed({\n type: 'input_file',\n filename: part.filename,\n file_data: url\n })\n })\n case 'Audio':\n return Effect.fail(unsupportedContentError('User audio'))\n }\n}\n\nconst contentToUserInput = (\n content: Content\n): Effect.Effect<OpenAiCodexMessageInput['content'], LLMError> => {\n if (typeof content === 'string') {\n return Effect.succeed(content)\n }\n\n const parts = contentParts(content)\n const onlyPart = parts[0]\n\n if (onlyPart !== undefined && parts.length === 1 && onlyPart._tag === 'Text') {\n return Effect.succeed(onlyPart.text)\n }\n\n return Effect.forEach(parts, userPartToCodexInputPart)\n}\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI Codex tool arguments')\n\nconst toolCallToCodexInput = (\n call: ToolCall\n): Effect.Effect<OpenAiCodexFunctionCallInput, LLMError> =>\n Effect.gen(function* () {\n return {\n type: 'function_call',\n call_id: call.id,\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n })\n\nconst messageToCodexInput = (\n message: AgentMessage\n): Effect.Effect<ReadonlyArray<OpenAiCodexInputItem>, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return [\n {\n role: 'user',\n content: yield* contentToUserInput(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n ]\n case 'Assistant': {\n const content = yield* contentToText(\n prependMessageContextToContent(assistantContent(message), messageContextText(message)),\n 'Assistant'\n )\n const toolCallInputs = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToCodexInput\n )\n\n if (content.length > 0) {\n const assistantMessage: OpenAiCodexInputItem = { role: 'assistant', content }\n\n return [assistantMessage, ...toolCallInputs]\n }\n\n return toolCallInputs\n }\n case 'ToolResult':\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: yield* contentToText(\n prependMessageContextToContent(message.content, messageContextText(message)),\n 'Tool result'\n )\n }\n ]\n }\n })\n\nconst toOpenAiCodexTool = (tool: ToolDef): OpenAiCodexTool => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n})\n\nexport const toOpenAiCodexRequestBody = (\n request: LLMRequest,\n config?: {\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n }\n): Effect.Effect<OpenAiCodexRequestBody, LLMError> =>\n Effect.gen(function* () {\n const input = Arr.flatten(yield* Effect.forEach(request.messages, messageToCodexInput))\n\n const body: Omit<OpenAiCodexRequestBody, 'tools'> = {\n model: request.model,\n instructions: request.systemPrompt,\n input,\n store: false,\n stream: true,\n reasoning: {\n effort: request.reasoningEffort ?? config?.defaultReasoningEffort ?? 'low',\n summary: config?.reasoningSummary ?? 'auto'\n }\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiCodexTool),\n parallel_tool_calls: true\n }\n })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null\n\nconst stringField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return typeof field === 'string' ? field : undefined\n}\n\nconst recordField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return isRecord(field) ? field : undefined\n}\n\nconst openAiCodexProvider = 'openai_codex'\n\nconst providerSignalError = (input: {\n readonly message: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}) => {\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n message: input.message,\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.fallbackKind === undefined ? {} : { fallbackKind: input.fallbackKind })\n })\n\n return new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex stream error: ${input.message}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n}\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI Codex tool arguments JSON')\n\nconst textFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'message':\n return Arr.map(item.content, content => content.text)\n case 'function_call':\n case 'reasoning':\n return []\n }\n}\n\nconst textFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const textParts = Arr.flatten(Arr.map(items, textFromOutputItem))\n\n return textParts.join('')\n}\n\nconst reasoningFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'reasoning':\n return [\n ...(item.summary ?? []).map(summary => summary.text),\n ...(item.content ?? []).map(content => content.text)\n ]\n case 'message':\n case 'function_call':\n return []\n }\n}\n\nconst reasoningFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const reasoningParts = Arr.flatten(Arr.map(items, reasoningFromOutputItem))\n\n return reasoningParts.join('')\n}\n\nconst toAgentUsage = (usage: OpenAiCodexUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.input_tokens,\n uncached: usage.input_tokens - (usage.input_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.input_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.output_tokens,\n reasoning: usage.output_tokens_details?.reasoning_tokens,\n text: usage.output_tokens - (usage.output_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\ntype ToLlmEventsOptions = {\n readonly allowEmptyStop: boolean\n}\n\nconst toLlmEvents = (\n response: OpenAiCodexResponse,\n options: ToLlmEventsOptions\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const text = response.output_text ?? textFromOutputItems(response.output)\n const reasoning = reasoningFromOutputItems(response.output)\n const reasoningEvents =\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n const textEvents = text.length > 0 ? [LLMTextDelta.make({ text })] : []\n const toolCallEvents = Arr.getSomes(\n yield* Effect.forEach(response.output, item => {\n switch (item.type) {\n case 'message':\n case 'reasoning':\n return Effect.succeed(Option.none())\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params =>\n Option.some(\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n )\n )\n )\n }\n })\n )\n\n if (textEvents.length === 0 && toolCallEvents.length === 0 && !options.allowEmptyStop) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI Codex response did not include text or tool calls',\n retryable: false\n })\n )\n }\n\n const events: Array<LLMEvent> = [\n ...reasoningEvents,\n ...textEvents,\n ...toolCallEvents,\n LLMDone.make({ stopReason: toolCallEvents.length > 0 ? 'tool_use' : 'stop' })\n ]\n\n if (response.usage !== undefined) {\n events.push(LLMUsage.make({ usage: toAgentUsage(response.usage) }))\n }\n\n return events\n })\n\nconst decodeOpenAiCodexResponse = (json: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst parseOpenAiCodexJsonResponse = (\n raw: string\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const json = yield* decodeJsonString(raw, 'Could not parse OpenAI Codex response JSON')\n const parsed = yield* decodeOpenAiCodexResponse(json)\n\n return yield* toLlmEvents(parsed, { allowEmptyStop: false })\n })\n\ntype OpenAiCodexBodyFormat = 'undecided' | 'sse' | 'json'\n\ntype OpenAiCodexSseState = {\n readonly hasTextDelta: boolean\n readonly hasReasoningDelta: boolean\n readonly hasToolCall: boolean\n readonly hasDone: boolean\n}\n\ntype OpenAiCodexSseStep = {\n readonly state: OpenAiCodexSseState\n readonly events: ReadonlyArray<LLMEvent>\n}\n\ntype OpenAiCodexBodyState = {\n readonly format: OpenAiCodexBodyFormat\n readonly buffer: string\n readonly sse: OpenAiCodexSseState\n}\n\nconst initialSseState: OpenAiCodexSseState = {\n hasTextDelta: false,\n hasReasoningDelta: false,\n hasToolCall: false,\n hasDone: false\n}\n\nconst initialBodyState: OpenAiCodexBodyState = {\n format: 'undecided',\n buffer: '',\n sse: initialSseState\n}\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst classifyCodexBody = (buffer: string): OpenAiCodexBodyFormat => {\n const trimmed = buffer.trimStart()\n\n if (trimmed.length === 0) {\n return 'undecided'\n }\n\n if (trimmed.startsWith('event:') || trimmed.startsWith('data:')) {\n return 'sse'\n }\n\n if ('event:'.startsWith(trimmed) || 'data:'.startsWith(trimmed)) {\n return 'undecided'\n }\n\n return 'json'\n}\n\nconst splitCompleteSseBlocks = (buffer: string) => {\n const blocks = buffer.split('\\n\\n')\n const tail = blocks.at(-1) ?? ''\n\n return { completeBlocks: blocks.slice(0, -1), tail }\n}\n\nconst dataFromSseBlock = (block: string) => {\n const lines = Arr.map(\n Arr.filter(block.split('\\n'), line => line.startsWith('data:')),\n line => line.slice(5).trimStart()\n )\n\n const data = lines.join('\\n').trim()\n\n if (data.length === 0 || data === '[DONE]') {\n return undefined\n }\n\n return data\n}\n\nconst parseOpenAiCodexSseJson = (data: string) =>\n decodeJsonString(data, 'Could not parse OpenAI Codex stream event JSON')\n\nconst decodeOpenAiCodexOutputItem = (value: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexOutputItem)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex output item: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst invalidFunctionCallSseItemError = () =>\n new LLMError({\n cause: 'invalid_response',\n message: 'Invalid OpenAI Codex function call stream item',\n retryable: false\n })\n\nconst eventsFromOutputItem = (\n item: OpenAiCodexOutputItem\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> => {\n switch (item.type) {\n case 'message': {\n const text = textFromOutputItems([item])\n\n return Effect.succeed(text.length > 0 ? [LLMTextDelta.make({ text })] : [])\n }\n case 'reasoning': {\n const reasoning = reasoningFromOutputItems([item])\n\n return Effect.succeed(\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n )\n }\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params => [\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n ])\n )\n }\n}\n\nconst eventsFromOutputItemDone = (\n event: Record<string, unknown>\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n if (event.type !== 'response.output_item.done') {\n return []\n }\n\n const item = event.item\n\n if (item === undefined) {\n return yield* Effect.fail(invalidFunctionCallSseItemError())\n }\n\n return yield* decodeOpenAiCodexOutputItem(item).pipe(Effect.flatMap(eventsFromOutputItem))\n })\n\nconst finalResponseToEvents = (\n response: unknown,\n state: OpenAiCodexSseState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const parsedFinal = yield* decodeOpenAiCodexResponse(response)\n const finalEvents = yield* toLlmEvents(parsedFinal, {\n allowEmptyStop: state.hasTextDelta || state.hasToolCall\n })\n\n const shouldDedupe = state.hasTextDelta || state.hasReasoningDelta || state.hasToolCall\n const dedupedEvents = shouldDedupe\n ? finalEvents.filter(event => {\n if (state.hasTextDelta && event._tag === 'TextDelta') {\n return false\n }\n\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') {\n return false\n }\n\n if (state.hasToolCall && event._tag === 'ToolCall') {\n return false\n }\n\n return true\n })\n : finalEvents\n\n if (!state.hasToolCall) {\n return dedupedEvents\n }\n\n return dedupedEvents.map(event =>\n event._tag === 'Done' ? LLMDone.make({ stopReason: 'tool_use' }) : event\n )\n })\n\nconst processSseData = (\n state: OpenAiCodexSseState,\n data: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const parsed = yield* parseOpenAiCodexSseJson(data)\n\n if (!isRecord(parsed)) {\n return { state, events: [] }\n }\n\n if (\n (parsed.type === 'response.output_text.delta' ||\n parsed.type === 'response.content_part.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasTextDelta: true },\n events: [LLMTextDelta.make({ text: parsed.delta })]\n }\n }\n\n if (\n (parsed.type === 'response.reasoning_summary_text.delta' ||\n parsed.type === 'response.reasoning_text.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasReasoningDelta: true },\n events: [LLMReasoningDelta.make({ text: parsed.delta })]\n }\n }\n\n const outputItemDoneEvents = yield* eventsFromOutputItemDone(parsed)\n if (outputItemDoneEvents.length > 0) {\n const events = outputItemDoneEvents.filter(event => {\n if (state.hasTextDelta && event._tag === 'TextDelta') {\n return false\n }\n\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') {\n return false\n }\n\n if (state.hasToolCall && event._tag === 'ToolCall') {\n return false\n }\n\n return true\n })\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || events.some(event => event._tag === 'TextDelta'),\n hasReasoningDelta:\n state.hasReasoningDelta || events.some(event => event._tag === 'ReasoningDelta'),\n hasToolCall: state.hasToolCall || events.some(event => event._tag === 'ToolCall'),\n hasDone: state.hasDone\n },\n events\n }\n }\n\n if (parsed.type === 'response.completed') {\n const events = yield* finalResponseToEvents(parsed.response, state)\n const emittedText = events.some(event => event._tag === 'TextDelta')\n const emittedReasoning = events.some(event => event._tag === 'ReasoningDelta')\n const emittedToolCall = events.some(event => event._tag === 'ToolCall')\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || emittedText,\n hasReasoningDelta: state.hasReasoningDelta || emittedReasoning,\n hasToolCall: state.hasToolCall || emittedToolCall,\n hasDone: true\n },\n events\n }\n }\n\n if (parsed.type === 'response.failed') {\n const error = recordField(recordField(parsed, 'response'), 'error')\n const message = stringField(error, 'message') ?? 'OpenAI Codex response failed'\n const providerCode = stringField(error, 'code') ?? stringField(error, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n if (parsed.type === 'error' && typeof parsed.message === 'string') {\n const providerCode = stringField(parsed, 'code') ?? stringField(parsed, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message: parsed.message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n return { state, events: [] }\n })\n\nconst processSseBlock = (\n state: OpenAiCodexSseState,\n block: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> => {\n const data = dataFromSseBlock(block)\n\n if (data === undefined) {\n return Effect.succeed({ state, events: [] })\n }\n\n return processSseData(state, data)\n}\n\nconst processSseBlocks = (\n state: OpenAiCodexSseState,\n blocks: ReadonlyArray<string>\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const events: Array<LLMEvent> = []\n let currentState = state\n\n for (const block of blocks) {\n const step = yield* processSseBlock(currentState, block)\n currentState = step.state\n events.push(...step.events)\n }\n\n return { state: currentState, events }\n })\n\nconst processBodyChunk = (\n state: OpenAiCodexBodyState,\n chunk: string\n): Effect.Effect<OpenAiCodexSseStep & { readonly bodyState: OpenAiCodexBodyState }, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(`${state.buffer}${chunk}`)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format !== 'sse') {\n return {\n state: state.sse,\n bodyState: { ...state, format, buffer },\n events: []\n }\n }\n\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(state.sse, split.completeBlocks)\n\n return {\n state: step.state,\n bodyState: { format, buffer: split.tail, sse: step.state },\n events: step.events\n }\n })\n\nconst finalizeBodyState = (\n state: OpenAiCodexBodyState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(state.buffer)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format === 'json') {\n return yield* parseOpenAiCodexJsonResponse(buffer)\n }\n\n const events: Array<LLMEvent> = []\n let sseState = state.sse\n\n if (format === 'sse') {\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(sseState, split.completeBlocks)\n sseState = step.state\n events.push(...step.events)\n\n if (split.tail.trim().length > 0) {\n const tailStep = yield* processSseBlock(sseState, split.tail)\n sseState = tailStep.state\n events.push(...tailStep.events)\n }\n }\n\n if (!sseState.hasDone) {\n events.push(LLMDone.make({ stopReason: sseState.hasToolCall ? 'tool_use' : 'stop' }))\n }\n\n return events\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean, kind: ProviderFailureKind = 'network') =>\n (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: openAiCodexProvider,\n kind: retryable ? kind : 'unknown'\n })\n })\n\nexport const streamOpenAiCodexResponse = (\n response: HttpClientResponse.HttpClientResponse\n): Stream.Stream<LLMEvent, LLMError> =>\n Stream.unwrap(\n Ref.make(initialBodyState).pipe(\n Effect.map(bodyStateRef => {\n const chunks = response.stream.pipe(\n Stream.mapError(toHttpClientLlmError('Could not read OpenAI Codex stream', true, 'stream')),\n Stream.decodeText,\n Stream.mapEffect(chunk =>\n Effect.gen(function* () {\n const state = yield* Ref.get(bodyStateRef)\n const step = yield* processBodyChunk(state, chunk)\n yield* Ref.set(bodyStateRef, step.bodyState)\n return step.events\n })\n ),\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n\n const finalEvents = Stream.fromEffect(\n Ref.get(bodyStateRef).pipe(Effect.flatMap(finalizeBodyState))\n ).pipe(Stream.flatMap(events => Stream.fromIterable(events)))\n\n return chunks.pipe(Stream.concat(finalEvents))\n })\n )\n )\n\nconst sendOpenAiCodexRequest = (\n config: OpenAiCodexProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<HttpClientResponse.HttpClientResponse, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiCodexRequestBody(request, config)\n const serializedBody = yield* encodeJsonString(body, 'Could not serialize OpenAI Codex request')\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...openAiCodexAuthorizationHeaders(config.token),\n 'content-type': 'application/json',\n ...config.extraHeaders\n }\n\n const httpRequest = HttpClientRequest.post(config.responsesUrl ?? openAiCodexResponsesUrl).pipe(\n HttpClientRequest.setHeaders(headers),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI Codex request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI Codex error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n return response\n }).pipe(Effect.withSpan('OpenAiCodexProvider.stream'))\n\nexport const makeOpenAiCodexProviderLayer = (config: OpenAiCodexProviderConfig) =>\n Layer.effect(LLMProvider)(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiCodexRequest(config, request, client)).pipe(\n Stream.flatMap(streamOpenAiCodexResponse)\n )\n })\n })\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"codex-provider.mjs","names":["Arr","LLMReasoningDelta","LLMTextDelta"],"sources":["../../../src/providers/openai/codex-provider.ts"],"sourcesContent":["import { Array as Arr, Effect, Layer, Option, Ref, Stream } from 'effect'\nimport {\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n ToolCall,\n attachmentSourceDataUrl,\n assistantContent,\n assistantHostToolCalls,\n contentParts,\n messageContextText,\n prependMessageContextToContent,\n type AgentMessage,\n type AgentReasoningEffort,\n type Content,\n type ContentPart,\n type ProviderFailureKind,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMReasoningDelta,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport { openAiCodexAuthorizationHeaders, openAiCodexResponsesUrl } from './codex.ts'\nimport type { OAuthAccessToken } from '@yolk-sdk/agent/oauth'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\nimport { validateProviderTranscript } from '../transcript.ts'\n\nexport type OpenAiCodexReasoningSummary = 'auto' | 'concise' | 'detailed'\n\nexport type OpenAiCodexProviderConfig = {\n readonly token: OAuthAccessToken\n readonly responsesUrl?: string\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n}\n\ntype OpenAiCodexMessageInput = {\n readonly role: 'user' | 'assistant'\n readonly content: string | ReadonlyArray<OpenAiCodexInputContentPart>\n}\n\ntype OpenAiCodexInputTextPart = {\n readonly type: 'input_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputImagePart = {\n readonly type: 'input_image'\n readonly image_url: string\n}\n\ntype OpenAiCodexInputFilePart = {\n readonly type: 'input_file'\n readonly filename: string\n readonly file_data: string\n}\n\ntype OpenAiCodexOutputTextPart = {\n readonly type: 'output_text'\n readonly text: string\n}\n\ntype OpenAiCodexInputContentPart =\n | OpenAiCodexInputTextPart\n | OpenAiCodexInputImagePart\n | OpenAiCodexInputFilePart\n | OpenAiCodexOutputTextPart\n\ntype OpenAiCodexFunctionCallInput = {\n readonly type: 'function_call'\n readonly call_id: string\n readonly name: string\n readonly arguments: string\n}\n\ntype OpenAiCodexFunctionOutputInput = {\n readonly type: 'function_call_output'\n readonly call_id: string\n readonly output: string\n}\n\ntype OpenAiCodexInputItem =\n | OpenAiCodexMessageInput\n | OpenAiCodexFunctionCallInput\n | OpenAiCodexFunctionOutputInput\n\ntype OpenAiCodexTool = {\n readonly type: 'function'\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n}\n\ntype OpenAiCodexRequestBody = {\n readonly model: string\n readonly instructions: string\n readonly input: ReadonlyArray<OpenAiCodexInputItem>\n readonly store: false\n readonly stream: true\n readonly reasoning: {\n readonly effort: AgentReasoningEffort\n readonly summary: OpenAiCodexReasoningSummary\n }\n readonly tools?: ReadonlyArray<OpenAiCodexTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiCodexReasoningSummaryText extends Schema.Class<OpenAiCodexReasoningSummaryText>(\n 'OpenAiCodexReasoningSummaryText'\n)({\n type: Schema.Literals(['summary_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningText extends Schema.Class<OpenAiCodexReasoningText>(\n 'OpenAiCodexReasoningText'\n)({\n type: Schema.Literals(['reasoning_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexOutputText extends Schema.Class<OpenAiCodexOutputText>('OpenAiCodexOutputText')({\n type: Schema.Literals(['output_text']),\n text: Schema.String\n}) {}\n\nclass OpenAiCodexMessageOutput extends Schema.Class<OpenAiCodexMessageOutput>(\n 'OpenAiCodexMessageOutput'\n)({\n type: Schema.Literals(['message']),\n content: Schema.Array(OpenAiCodexOutputText)\n}) {}\n\nclass OpenAiCodexFunctionCallOutput extends Schema.Class<OpenAiCodexFunctionCallOutput>(\n 'OpenAiCodexFunctionCallOutput'\n)({\n type: Schema.Literals(['function_call']),\n call_id: Schema.String,\n name: Schema.String,\n arguments: Schema.String\n}) {}\n\nclass OpenAiCodexReasoningOutput extends Schema.Class<OpenAiCodexReasoningOutput>(\n 'OpenAiCodexReasoningOutput'\n)({\n type: Schema.Literals(['reasoning']),\n summary: Schema.optional(Schema.Array(OpenAiCodexReasoningSummaryText)),\n content: Schema.optional(Schema.Array(OpenAiCodexReasoningText))\n}) {}\n\nclass OpenAiCodexInputTokensDetails extends Schema.Class<OpenAiCodexInputTokensDetails>(\n 'OpenAiCodexInputTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexOutputTokensDetails extends Schema.Class<OpenAiCodexOutputTokensDetails>(\n 'OpenAiCodexOutputTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCodexUsageResponse extends Schema.Class<OpenAiCodexUsageResponse>(\n 'OpenAiCodexUsageResponse'\n)({\n input_tokens: Schema.Number,\n output_tokens: Schema.Number,\n input_tokens_details: Schema.optional(OpenAiCodexInputTokensDetails),\n output_tokens_details: Schema.optional(OpenAiCodexOutputTokensDetails)\n}) {}\n\nconst OpenAiCodexOutputItem = Schema.Union([\n OpenAiCodexMessageOutput,\n OpenAiCodexFunctionCallOutput,\n OpenAiCodexReasoningOutput\n])\ntype OpenAiCodexOutputItem = typeof OpenAiCodexOutputItem.Type\n\nclass OpenAiCodexResponse extends Schema.Class<OpenAiCodexResponse>('OpenAiCodexResponse')({\n output_text: Schema.optional(Schema.String),\n output: Schema.Array(OpenAiCodexOutputItem),\n usage: Schema.optional(OpenAiCodexUsageResponse)\n}) {}\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI Codex OAuth provider yet`,\n retryable: false\n })\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst userPartToCodexInputPart = (\n part: ContentPart\n): Effect.Effect<OpenAiCodexInputTextPart | OpenAiCodexInputImagePart | OpenAiCodexInputFilePart, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'input_text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url => Effect.succeed({\n type: 'input_image',\n image_url: url\n })\n })\n case 'Document':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved document source')),\n onSome: url => Effect.succeed({\n type: 'input_file',\n filename: part.filename,\n file_data: url\n })\n })\n case 'Audio':\n return Effect.fail(unsupportedContentError('User audio'))\n }\n}\n\nconst contentToUserInput = (\n content: Content\n): Effect.Effect<OpenAiCodexMessageInput['content'], LLMError> => {\n if (typeof content === 'string') {\n return Effect.succeed(content)\n }\n\n const parts = contentParts(content)\n const onlyPart = parts[0]\n\n if (onlyPart !== undefined && parts.length === 1 && onlyPart._tag === 'Text') {\n return Effect.succeed(onlyPart.text)\n }\n\n return Effect.forEach(parts, userPartToCodexInputPart)\n}\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI Codex tool arguments')\n\nconst toolCallToCodexInput = (\n call: ToolCall\n): Effect.Effect<OpenAiCodexFunctionCallInput, LLMError> =>\n Effect.gen(function* () {\n return {\n type: 'function_call',\n call_id: call.id,\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n })\n\nconst messageToCodexInput = (\n message: AgentMessage\n): Effect.Effect<ReadonlyArray<OpenAiCodexInputItem>, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return [\n {\n role: 'user',\n content: yield* contentToUserInput(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n ]\n case 'Assistant': {\n const content = yield* contentToText(\n prependMessageContextToContent(assistantContent(message), messageContextText(message)),\n 'Assistant'\n )\n const toolCallInputs = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToCodexInput\n )\n\n if (content.length > 0) {\n const assistantMessage: OpenAiCodexInputItem = { role: 'assistant', content }\n\n return [assistantMessage, ...toolCallInputs]\n }\n\n return toolCallInputs\n }\n case 'ToolResult':\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: yield* contentToText(\n prependMessageContextToContent(message.content, messageContextText(message)),\n 'Tool result'\n )\n }\n ]\n }\n })\n\nconst toOpenAiCodexTool = (tool: ToolDef): OpenAiCodexTool => ({\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n})\n\nexport const toOpenAiCodexRequestBody = (\n request: LLMRequest,\n config?: {\n readonly defaultReasoningEffort?: AgentReasoningEffort\n readonly reasoningSummary?: OpenAiCodexReasoningSummary\n }\n): Effect.Effect<OpenAiCodexRequestBody, LLMError> =>\n Effect.gen(function* () {\n yield* validateProviderTranscript(request.messages)\n const input = Arr.flatten(yield* Effect.forEach(request.messages, messageToCodexInput))\n\n const body: Omit<OpenAiCodexRequestBody, 'tools'> = {\n model: request.model,\n instructions: request.systemPrompt,\n input,\n store: false,\n stream: true,\n reasoning: {\n effort: request.reasoningEffort ?? config?.defaultReasoningEffort ?? 'low',\n summary: config?.reasoningSummary ?? 'auto'\n }\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiCodexTool),\n parallel_tool_calls: true\n }\n })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null\n\nconst stringField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return typeof field === 'string' ? field : undefined\n}\n\nconst recordField = (value: unknown, key: string) => {\n if (!isRecord(value)) {\n return undefined\n }\n\n const field = Object.getOwnPropertyDescriptor(value, key)?.value\n\n return isRecord(field) ? field : undefined\n}\n\nconst openAiCodexProvider = 'openai_codex'\n\nconst providerSignalError = (input: {\n readonly message: string\n readonly providerCode?: string\n readonly fallbackKind?: ProviderFailureKind\n}) => {\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n message: input.message,\n ...(input.providerCode === undefined ? {} : { providerCode: input.providerCode }),\n ...(input.fallbackKind === undefined ? {} : { fallbackKind: input.fallbackKind })\n })\n\n return new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex stream error: ${input.message}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n}\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI Codex tool arguments JSON')\n\nconst textFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'message':\n return Arr.map(item.content, content => content.text)\n case 'function_call':\n case 'reasoning':\n return []\n }\n}\n\nconst textFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const textParts = Arr.flatten(Arr.map(items, textFromOutputItem))\n\n return textParts.join('')\n}\n\nconst reasoningFromOutputItem = (item: OpenAiCodexOutputItem) => {\n switch (item.type) {\n case 'reasoning':\n return [\n ...(item.summary ?? []).map(summary => summary.text),\n ...(item.content ?? []).map(content => content.text)\n ]\n case 'message':\n case 'function_call':\n return []\n }\n}\n\nconst reasoningFromOutputItems = (items: ReadonlyArray<OpenAiCodexOutputItem>) => {\n const reasoningParts = Arr.flatten(Arr.map(items, reasoningFromOutputItem))\n\n return reasoningParts.join('')\n}\n\nconst toAgentUsage = (usage: OpenAiCodexUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.input_tokens,\n uncached: usage.input_tokens - (usage.input_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.input_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.output_tokens,\n reasoning: usage.output_tokens_details?.reasoning_tokens,\n text: usage.output_tokens - (usage.output_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\ntype ToLlmEventsOptions = {\n readonly allowEmptyStop: boolean\n}\n\nconst toLlmEvents = (\n response: OpenAiCodexResponse,\n options: ToLlmEventsOptions\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const text = response.output_text ?? textFromOutputItems(response.output)\n const reasoning = reasoningFromOutputItems(response.output)\n const reasoningEvents =\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n const textEvents = text.length > 0 ? [LLMTextDelta.make({ text })] : []\n const toolCallEvents = Arr.getSomes(\n yield* Effect.forEach(response.output, item => {\n switch (item.type) {\n case 'message':\n case 'reasoning':\n return Effect.succeed(Option.none())\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params =>\n Option.some(\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n )\n )\n )\n }\n })\n )\n\n if (textEvents.length === 0 && toolCallEvents.length === 0 && !options.allowEmptyStop) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI Codex response did not include text or tool calls',\n retryable: false\n })\n )\n }\n\n const events: Array<LLMEvent> = [\n ...reasoningEvents,\n ...textEvents,\n ...toolCallEvents,\n LLMDone.make({ stopReason: toolCallEvents.length > 0 ? 'tool_use' : 'stop' })\n ]\n\n if (response.usage !== undefined) {\n events.push(LLMUsage.make({ usage: toAgentUsage(response.usage) }))\n }\n\n return events\n })\n\nconst decodeOpenAiCodexResponse = (json: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst parseOpenAiCodexJsonResponse = (\n raw: string\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const json = yield* decodeJsonString(raw, 'Could not parse OpenAI Codex response JSON')\n const parsed = yield* decodeOpenAiCodexResponse(json)\n\n return yield* toLlmEvents(parsed, { allowEmptyStop: false })\n })\n\ntype OpenAiCodexBodyFormat = 'undecided' | 'sse' | 'json'\n\ntype OpenAiCodexSseState = {\n readonly hasTextDelta: boolean\n readonly hasReasoningDelta: boolean\n readonly hasToolCall: boolean\n readonly hasDone: boolean\n}\n\ntype OpenAiCodexSseStep = {\n readonly state: OpenAiCodexSseState\n readonly events: ReadonlyArray<LLMEvent>\n}\n\ntype OpenAiCodexBodyState = {\n readonly format: OpenAiCodexBodyFormat\n readonly buffer: string\n readonly sse: OpenAiCodexSseState\n}\n\nconst initialSseState: OpenAiCodexSseState = {\n hasTextDelta: false,\n hasReasoningDelta: false,\n hasToolCall: false,\n hasDone: false\n}\n\nconst initialBodyState: OpenAiCodexBodyState = {\n format: 'undecided',\n buffer: '',\n sse: initialSseState\n}\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n')\n\nconst classifyCodexBody = (buffer: string): OpenAiCodexBodyFormat => {\n const trimmed = buffer.trimStart()\n\n if (trimmed.length === 0) {\n return 'undecided'\n }\n\n if (trimmed.startsWith('event:') || trimmed.startsWith('data:')) {\n return 'sse'\n }\n\n if ('event:'.startsWith(trimmed) || 'data:'.startsWith(trimmed)) {\n return 'undecided'\n }\n\n return 'json'\n}\n\nconst splitCompleteSseBlocks = (buffer: string) => {\n const blocks = buffer.split('\\n\\n')\n const tail = blocks.at(-1) ?? ''\n\n return { completeBlocks: blocks.slice(0, -1), tail }\n}\n\nconst dataFromSseBlock = (block: string) => {\n const lines = Arr.map(\n Arr.filter(block.split('\\n'), line => line.startsWith('data:')),\n line => line.slice(5).trimStart()\n )\n\n const data = lines.join('\\n').trim()\n\n if (data.length === 0 || data === '[DONE]') {\n return undefined\n }\n\n return data\n}\n\nconst parseOpenAiCodexSseJson = (data: string) =>\n decodeJsonString(data, 'Could not parse OpenAI Codex stream event JSON')\n\nconst decodeOpenAiCodexOutputItem = (value: unknown) =>\n Schema.decodeUnknownEffect(OpenAiCodexOutputItem)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI Codex output item: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst invalidFunctionCallSseItemError = () =>\n new LLMError({\n cause: 'invalid_response',\n message: 'Invalid OpenAI Codex function call stream item',\n retryable: false\n })\n\nconst eventsFromOutputItem = (\n item: OpenAiCodexOutputItem\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> => {\n switch (item.type) {\n case 'message': {\n const text = textFromOutputItems([item])\n\n return Effect.succeed(text.length > 0 ? [LLMTextDelta.make({ text })] : [])\n }\n case 'reasoning': {\n const reasoning = reasoningFromOutputItems([item])\n\n return Effect.succeed(\n reasoning.length > 0 ? [LLMReasoningDelta.make({ text: reasoning })] : []\n )\n }\n case 'function_call':\n return parseToolArguments(item.arguments).pipe(\n Effect.map(params => [\n LLMToolCall.make({\n call: ToolCall.make({\n id: item.call_id,\n name: item.name,\n params\n })\n })\n ])\n )\n }\n}\n\nconst eventsFromOutputItemDone = (\n event: Record<string, unknown>\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n if (event.type !== 'response.output_item.done') {\n return []\n }\n\n const item = event.item\n\n if (item === undefined) {\n return yield* Effect.fail(invalidFunctionCallSseItemError())\n }\n\n return yield* decodeOpenAiCodexOutputItem(item).pipe(Effect.flatMap(eventsFromOutputItem))\n })\n\nconst finalResponseToEvents = (\n response: unknown,\n state: OpenAiCodexSseState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const parsedFinal = yield* decodeOpenAiCodexResponse(response)\n const finalEvents = yield* toLlmEvents(parsedFinal, {\n allowEmptyStop: state.hasTextDelta || state.hasToolCall\n })\n\n const shouldDedupe = state.hasTextDelta || state.hasReasoningDelta || state.hasToolCall\n const dedupedEvents = shouldDedupe\n ? finalEvents.filter(event => {\n if (state.hasTextDelta && event._tag === 'TextDelta') {\n return false\n }\n\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') {\n return false\n }\n\n if (state.hasToolCall && event._tag === 'ToolCall') {\n return false\n }\n\n return true\n })\n : finalEvents\n\n if (!state.hasToolCall) {\n return dedupedEvents\n }\n\n return dedupedEvents.map(event =>\n event._tag === 'Done' ? LLMDone.make({ stopReason: 'tool_use' }) : event\n )\n })\n\nconst processSseData = (\n state: OpenAiCodexSseState,\n data: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const parsed = yield* parseOpenAiCodexSseJson(data)\n\n if (!isRecord(parsed)) {\n return { state, events: [] }\n }\n\n if (\n (parsed.type === 'response.output_text.delta' ||\n parsed.type === 'response.content_part.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasTextDelta: true },\n events: [LLMTextDelta.make({ text: parsed.delta })]\n }\n }\n\n if (\n (parsed.type === 'response.reasoning_summary_text.delta' ||\n parsed.type === 'response.reasoning_text.delta') &&\n typeof parsed.delta === 'string'\n ) {\n return {\n state: { ...state, hasReasoningDelta: true },\n events: [LLMReasoningDelta.make({ text: parsed.delta })]\n }\n }\n\n const outputItemDoneEvents = yield* eventsFromOutputItemDone(parsed)\n if (outputItemDoneEvents.length > 0) {\n const events = outputItemDoneEvents.filter(event => {\n if (state.hasTextDelta && event._tag === 'TextDelta') {\n return false\n }\n\n if (state.hasReasoningDelta && event._tag === 'ReasoningDelta') {\n return false\n }\n\n if (state.hasToolCall && event._tag === 'ToolCall') {\n return false\n }\n\n return true\n })\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || events.some(event => event._tag === 'TextDelta'),\n hasReasoningDelta:\n state.hasReasoningDelta || events.some(event => event._tag === 'ReasoningDelta'),\n hasToolCall: state.hasToolCall || events.some(event => event._tag === 'ToolCall'),\n hasDone: state.hasDone\n },\n events\n }\n }\n\n if (parsed.type === 'response.completed') {\n const events = yield* finalResponseToEvents(parsed.response, state)\n const emittedText = events.some(event => event._tag === 'TextDelta')\n const emittedReasoning = events.some(event => event._tag === 'ReasoningDelta')\n const emittedToolCall = events.some(event => event._tag === 'ToolCall')\n\n return {\n state: {\n hasTextDelta: state.hasTextDelta || emittedText,\n hasReasoningDelta: state.hasReasoningDelta || emittedReasoning,\n hasToolCall: state.hasToolCall || emittedToolCall,\n hasDone: true\n },\n events\n }\n }\n\n if (parsed.type === 'response.failed') {\n const error = recordField(recordField(parsed, 'response'), 'error')\n const message = stringField(error, 'message') ?? 'OpenAI Codex response failed'\n const providerCode = stringField(error, 'code') ?? stringField(error, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n if (parsed.type === 'error' && typeof parsed.message === 'string') {\n const providerCode = stringField(parsed, 'code') ?? stringField(parsed, 'type')\n\n return yield* Effect.fail(\n providerSignalError({\n message: parsed.message,\n ...(providerCode === undefined ? {} : { providerCode })\n })\n )\n }\n\n return { state, events: [] }\n })\n\nconst processSseBlock = (\n state: OpenAiCodexSseState,\n block: string\n): Effect.Effect<OpenAiCodexSseStep, LLMError> => {\n const data = dataFromSseBlock(block)\n\n if (data === undefined) {\n return Effect.succeed({ state, events: [] })\n }\n\n return processSseData(state, data)\n}\n\nconst processSseBlocks = (\n state: OpenAiCodexSseState,\n blocks: ReadonlyArray<string>\n): Effect.Effect<OpenAiCodexSseStep, LLMError> =>\n Effect.gen(function* () {\n const events: Array<LLMEvent> = []\n let currentState = state\n\n for (const block of blocks) {\n const step = yield* processSseBlock(currentState, block)\n currentState = step.state\n events.push(...step.events)\n }\n\n return { state: currentState, events }\n })\n\nconst processBodyChunk = (\n state: OpenAiCodexBodyState,\n chunk: string\n): Effect.Effect<OpenAiCodexSseStep & { readonly bodyState: OpenAiCodexBodyState }, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(`${state.buffer}${chunk}`)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format !== 'sse') {\n return {\n state: state.sse,\n bodyState: { ...state, format, buffer },\n events: []\n }\n }\n\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(state.sse, split.completeBlocks)\n\n return {\n state: step.state,\n bodyState: { format, buffer: split.tail, sse: step.state },\n events: step.events\n }\n })\n\nconst finalizeBodyState = (\n state: OpenAiCodexBodyState\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const buffer = normalizeNewlines(state.buffer)\n const format = state.format === 'undecided' ? classifyCodexBody(buffer) : state.format\n\n if (format === 'json') {\n return yield* parseOpenAiCodexJsonResponse(buffer)\n }\n\n const events: Array<LLMEvent> = []\n let sseState = state.sse\n\n if (format === 'sse') {\n const split = splitCompleteSseBlocks(buffer)\n const step = yield* processSseBlocks(sseState, split.completeBlocks)\n sseState = step.state\n events.push(...step.events)\n\n if (split.tail.trim().length > 0) {\n const tailStep = yield* processSseBlock(sseState, split.tail)\n sseState = tailStep.state\n events.push(...tailStep.events)\n }\n }\n\n if (!sseState.hasDone) {\n events.push(LLMDone.make({ stopReason: sseState.hasToolCall ? 'tool_use' : 'stop' }))\n }\n\n return events\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean, kind: ProviderFailureKind = 'network') =>\n (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: openAiCodexProvider,\n kind: retryable ? kind : 'unknown'\n })\n })\n\nexport const streamOpenAiCodexResponse = (\n response: HttpClientResponse.HttpClientResponse\n): Stream.Stream<LLMEvent, LLMError> =>\n Stream.unwrap(\n Ref.make(initialBodyState).pipe(\n Effect.map(bodyStateRef => {\n const chunks = response.stream.pipe(\n Stream.mapError(toHttpClientLlmError('Could not read OpenAI Codex stream', true, 'stream')),\n Stream.decodeText,\n Stream.mapEffect(chunk =>\n Effect.gen(function* () {\n const state = yield* Ref.get(bodyStateRef)\n const step = yield* processBodyChunk(state, chunk)\n yield* Ref.set(bodyStateRef, step.bodyState)\n return step.events\n })\n ),\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n\n const finalEvents = Stream.fromEffect(\n Ref.get(bodyStateRef).pipe(Effect.flatMap(finalizeBodyState))\n ).pipe(Stream.flatMap(events => Stream.fromIterable(events)))\n\n return chunks.pipe(Stream.concat(finalEvents))\n })\n )\n )\n\nconst sendOpenAiCodexRequest = (\n config: OpenAiCodexProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<HttpClientResponse.HttpClientResponse, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiCodexRequestBody(request, config)\n const serializedBody = yield* encodeJsonString(body, 'Could not serialize OpenAI Codex request')\n\n const headers: Record<string, string> = {\n accept: 'application/json',\n ...openAiCodexAuthorizationHeaders(config.token),\n 'content-type': 'application/json',\n ...config.extraHeaders\n }\n\n const httpRequest = HttpClientRequest.post(config.responsesUrl ?? openAiCodexResponsesUrl).pipe(\n HttpClientRequest.setHeaders(headers),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI Codex request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI Codex error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: openAiCodexProvider,\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI Codex returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n return response\n }).pipe(Effect.withSpan('OpenAiCodexProvider.stream'))\n\nexport const makeOpenAiCodexProviderLayer = (config: OpenAiCodexProviderConfig) =>\n Layer.effect(LLMProvider)(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiCodexRequest(config, request, client)).pipe(\n Stream.flatMap(streamOpenAiCodexResponse)\n )\n })\n })\n )\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.mts","names":[],"sources":["../../../src/providers/openai/provider.ts"],"mappings":";;;;;KA2CY,oBAAA;EAAA,SACD,kBAAA;EAAA,SACA,mBAAA;EAAA,SACA,YAAA,GAAe,QAAA,CAAS,MAAA;EAAA,SACxB,MAAA,EAAQ,QAAA,CAAS,QAAA;AAAA;AAAA,KAGvB,qBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGV,sBAAA;EAAA,SACM,IAAA;EAAA,SACA,SAAA;IAAA,SACE,GAAA;EAAA;AAAA;AAAA,KAIR,iBAAA,YAA6B,aAAA,CAAc,qBAAA,GAAwB,sBAAA;AAAA,KAEnE,cAAA;EAAA,SACM,EAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;IAAA,SACE,IAAA;IAAA,SACA,SAAA;EAAA;AAAA;AAAA,KAIR,aAAA;EAAA,SACU,IAAA;EAAA,SAAyB,OAAA;AAAA;EAAA,SACzB,IAAA;EAAA,SAAuB,OAAA,EAAS,iBAAA;AAAA;EAAA,SAEhC,IAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,aAAA,CAAc,cAAA;AAAA;EAAA,SAE3B,IAAA;EAAA,SAAuB,YAAA;EAAA,SAA+B,OAAA;AAAA;AAAA,KAEhE,UAAA;EAAA,SACM,IAAA;EAAA,SACA,QAAA;IAAA,SACE,IAAA;IAAA,SACA,WAAA;IAAA,SACA,UAAA;EAAA;AAAA;AAAA,KAIR,iBAAA;EAAA,SACM,KAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,aAAA;EAAA,SACxB,qBAAA;EAAA,SACA,KAAA,GAAQ,aAAA,CAAc,UAAA;EAAA,SACtB,mBAAA;AAAA;AAAA,cAgPE,mBAAA,GACX,OAAA,EAAS,UAAA,EACT,MAAA;EAAA,SAAoB,mBAAA;AAAA,MACnB,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,QAAA;AAAA,cAgLvB,uBAAA,GAA2B,MAAA,EAAQ,oBAAA,KAAoB,KAAA,CAAA,KAAA,CAAA,WAAA,SAAA,UAAA,CAAA,UAAA;AAAA,cAevD,mBAAA,EAAmB,KAAA,CAAA,KAAA,CAAA,WAAA,EAAA,QAAA"}
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../../../src/providers/openai/provider.ts"],"mappings":";;;;;KA4CY,oBAAA;EAAA,SACD,kBAAA;EAAA,SACA,mBAAA;EAAA,SACA,YAAA,GAAe,QAAA,CAAS,MAAA;EAAA,SACxB,MAAA,EAAQ,QAAA,CAAS,QAAA;AAAA;AAAA,KAGvB,qBAAA;EAAA,SACM,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGV,sBAAA;EAAA,SACM,IAAA;EAAA,SACA,SAAA;IAAA,SACE,GAAA;EAAA;AAAA;AAAA,KAIR,iBAAA,YAA6B,aAAA,CAAc,qBAAA,GAAwB,sBAAA;AAAA,KAEnE,cAAA;EAAA,SACM,EAAA;EAAA,SACA,IAAA;EAAA,SACA,QAAA;IAAA,SACE,IAAA;IAAA,SACA,SAAA;EAAA;AAAA;AAAA,KAIR,aAAA;EAAA,SACU,IAAA;EAAA,SAAyB,OAAA;AAAA;EAAA,SACzB,IAAA;EAAA,SAAuB,OAAA,EAAS,iBAAA;AAAA;EAAA,SAEhC,IAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,aAAA,CAAc,cAAA;AAAA;EAAA,SAE3B,IAAA;EAAA,SAAuB,YAAA;EAAA,SAA+B,OAAA;AAAA;AAAA,KAEhE,UAAA;EAAA,SACM,IAAA;EAAA,SACA,QAAA;IAAA,SACE,IAAA;IAAA,SACA,WAAA;IAAA,SACA,UAAA;EAAA;AAAA;AAAA,KAIR,iBAAA;EAAA,SACM,KAAA;EAAA,SACA,QAAA,EAAU,aAAA,CAAc,aAAA;EAAA,SACxB,qBAAA;EAAA,SACA,KAAA,GAAQ,aAAA,CAAc,UAAA;EAAA,SACtB,mBAAA;AAAA;AAAA,cAgPE,mBAAA,GACX,OAAA,EAAS,UAAA,EACT,MAAA;EAAA,SAAoB,mBAAA;AAAA,MACnB,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,QAAA;AAAA,cAiLvB,uBAAA,GAA2B,MAAA,EAAQ,oBAAA,KAAoB,KAAA,CAAA,KAAA,CAAA,WAAA,SAAA,UAAA,CAAA,UAAA;AAAA,cAevD,mBAAA,EAAmB,KAAA,CAAA,KAAA,CAAA,WAAA,EAAA,QAAA"}
@@ -1,4 +1,5 @@
1
1
  import { classifyProviderFailure, providerErrorInfo, providerFailureCause, providerFailureRetryable } from "../provider-error.mjs";
2
+ import { validateProviderTranscript } from "../transcript.mjs";
2
3
  import { AgentInputUsage, AgentOutputUsage, AgentUsage, ToolCall, assistantContent, assistantHostToolCalls, attachmentSourceDataUrl, attachmentSourceText, isTextDocumentMimeType, messageContextText, prependMessageContextToContent } from "@yolk-sdk/agent/protocol";
3
4
  import { Config, Context, Effect, Layer, Option, Redacted, Stream } from "effect";
4
5
  import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
@@ -138,6 +139,7 @@ const toOpenAiTool = (tool) => ({
138
139
  }
139
140
  });
140
141
  const toOpenAiRequestBody = (request, config) => Effect.gen(function* () {
142
+ yield* validateProviderTranscript(request.messages);
141
143
  const messages = [{
142
144
  role: "system",
143
145
  content: request.systemPrompt
@@ -1 +1 @@
1
- {"version":3,"file":"provider.mjs","names":["LLMTextDelta"],"sources":["../../../src/providers/openai/provider.ts"],"sourcesContent":["import { Config, Context, Effect, Layer, Option, Redacted, Stream } from 'effect'\nimport {\n FetchHttpClient,\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n ToolCall,\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n attachmentSourceDataUrl,\n attachmentSourceText,\n assistantContent,\n assistantHostToolCalls,\n isTextDocumentMimeType,\n messageContextText,\n prependMessageContextToContent,\n type AgentMessage,\n type Content,\n type ContentPart,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\n\nexport type OpenAiProviderConfig = {\n readonly chatCompletionsUrl?: string\n readonly maxCompletionTokens?: number\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly apiKey: Redacted.Redacted<string>\n}\n\ntype OpenAiTextContentPart = {\n readonly type: 'text'\n readonly text: string\n}\n\ntype OpenAiImageContentPart = {\n readonly type: 'image_url'\n readonly image_url: {\n readonly url: string\n }\n}\n\ntype OpenAiUserContent = string | ReadonlyArray<OpenAiTextContentPart | OpenAiImageContentPart>\n\ntype OpenAiToolCall = {\n readonly id: string\n readonly type: 'function'\n readonly function: {\n readonly name: string\n readonly arguments: string\n }\n}\n\ntype OpenAiMessage =\n | { readonly role: 'system'; readonly content: string }\n | { readonly role: 'user'; readonly content: OpenAiUserContent }\n | {\n readonly role: 'assistant'\n readonly content: string | null\n readonly tool_calls?: ReadonlyArray<OpenAiToolCall>\n }\n | { readonly role: 'tool'; readonly tool_call_id: string; readonly content: string }\n\ntype OpenAiTool = {\n readonly type: 'function'\n readonly function: {\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n }\n}\n\ntype OpenAiRequestBody = {\n readonly model: string\n readonly messages: ReadonlyArray<OpenAiMessage>\n readonly max_completion_tokens: number\n readonly tools?: ReadonlyArray<OpenAiTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiFunctionResponse extends Schema.Class<OpenAiFunctionResponse>('OpenAiFunctionResponse')(\n {\n name: Schema.String,\n arguments: Schema.String\n }\n) {}\n\nclass OpenAiToolCallResponse extends Schema.Class<OpenAiToolCallResponse>('OpenAiToolCallResponse')(\n {\n id: Schema.String,\n type: Schema.Literals(['function']),\n function: OpenAiFunctionResponse\n }\n) {}\n\nclass OpenAiMessageResponse extends Schema.Class<OpenAiMessageResponse>('OpenAiMessageResponse')({\n content: Schema.NullOr(Schema.String),\n tool_calls: Schema.optional(Schema.Array(OpenAiToolCallResponse))\n}) {}\n\nclass OpenAiChoiceResponse extends Schema.Class<OpenAiChoiceResponse>('OpenAiChoiceResponse')({\n message: OpenAiMessageResponse\n}) {}\n\nclass OpenAiPromptTokensDetails extends Schema.Class<OpenAiPromptTokensDetails>(\n 'OpenAiPromptTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCompletionTokensDetails extends Schema.Class<OpenAiCompletionTokensDetails>(\n 'OpenAiCompletionTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiUsageResponse extends Schema.Class<OpenAiUsageResponse>('OpenAiUsageResponse')({\n prompt_tokens: Schema.Number,\n completion_tokens: Schema.Number,\n prompt_tokens_details: Schema.optional(OpenAiPromptTokensDetails),\n completion_tokens_details: Schema.optional(OpenAiCompletionTokensDetails)\n}) {}\n\nclass OpenAiChatCompletionResponse extends Schema.Class<OpenAiChatCompletionResponse>(\n 'OpenAiChatCompletionResponse'\n)({\n choices: Schema.Array(OpenAiChoiceResponse),\n usage: Schema.optional(OpenAiUsageResponse)\n}) {}\n\nclass OpenAiConfig extends Context.Service<OpenAiConfig, OpenAiProviderConfig>()(\n '@app/OpenAiConfig'\n) {}\n\nconst OpenAiConfigLayer = Layer.effect(\n OpenAiConfig,\n Effect.gen(function* () {\n const apiKey = yield* Config.redacted('OPENAI_API_KEY')\n return { apiKey }\n }).pipe(\n Effect.mapError(\n () =>\n new LLMError({\n cause: 'provider_error',\n message: 'OPENAI_API_KEY not found',\n retryable: false\n })\n )\n )\n)\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI provider yet`,\n retryable: false\n })\n\nconst textDocumentToOpenAiPart = (part: Extract<ContentPart, { readonly _tag: 'Document' }>) =>\n attachmentSourceText(part.source).pipe(\n Effect.mapError(() => unsupportedContentError('Invalid document text')),\n Effect.flatMap(\n Option.match({\n onNone: () => Effect.fail(unsupportedContentError('Unresolved document source')),\n onSome: text => {\n const block: OpenAiTextContentPart = {\n type: 'text',\n text: `Document: ${part.title ?? part.filename}\\n\\n${text}`\n }\n\n return Effect.succeed(block)\n }\n })\n )\n )\n\nconst contentPartToUserPart = (\n part: ContentPart\n): Effect.Effect<OpenAiTextContentPart | OpenAiImageContentPart, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url => Effect.succeed({ type: 'image_url', image_url: { url } })\n })\n case 'Document':\n return isTextDocumentMimeType(part.mimeType)\n ? textDocumentToOpenAiPart(part)\n : Effect.fail(unsupportedContentError('Document'))\n case 'Audio':\n return Effect.fail(unsupportedContentError('Audio'))\n }\n}\n\nconst contentToUserContent = (content: Content): Effect.Effect<OpenAiUserContent, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, contentPartToUserPart)\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI tool arguments')\n\nconst toolCallToOpenAiToolCall = (call: ToolCall): Effect.Effect<OpenAiToolCall, LLMError> =>\n Effect.gen(function* () {\n return {\n id: call.id,\n type: 'function',\n function: {\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n }\n })\n\nconst toOpenAiMessage = (message: AgentMessage): Effect.Effect<OpenAiMessage, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return {\n role: 'user',\n content: yield* contentToUserContent(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n case 'Assistant': {\n const content = prependMessageContextToContent(\n assistantContent(message),\n messageContextText(message)\n )\n const toolCalls = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToOpenAiToolCall\n )\n\n if (toolCalls.length > 0) {\n return {\n role: 'assistant',\n content: yield* contentToText(content, 'Assistant'),\n tool_calls: toolCalls\n }\n }\n\n return {\n role: 'assistant',\n content: yield* contentToText(content, 'Assistant')\n }\n }\n case 'ToolResult':\n return {\n role: 'tool',\n tool_call_id: message.toolCallId,\n content: yield* contentToText(\n prependMessageContextToContent(message.content, messageContextText(message)),\n 'Tool result'\n )\n }\n }\n })\n\nconst toOpenAiTool = (tool: ToolDef): OpenAiTool => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n }\n})\n\nexport const toOpenAiRequestBody = (\n request: LLMRequest,\n config?: { readonly maxCompletionTokens?: number }\n): Effect.Effect<OpenAiRequestBody, LLMError> =>\n Effect.gen(function* () {\n const systemMessage: OpenAiMessage = { role: 'system', content: request.systemPrompt }\n const requestMessages = yield* Effect.forEach(request.messages, toOpenAiMessage)\n const messages = [systemMessage, ...requestMessages]\n\n const body = {\n model: request.model,\n messages,\n max_completion_tokens: config?.maxCompletionTokens ?? 4096\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiTool),\n parallel_tool_calls: true\n }\n })\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI tool arguments JSON')\n\nconst toLlmEvents = (\n message: OpenAiMessageResponse\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const content = message.content ?? ''\n const textEvents = content.length > 0 ? [LLMTextDelta.make({ text: content })] : []\n const toolCallEvents = yield* Effect.forEach(message.tool_calls ?? [], call =>\n parseToolArguments(call.function.arguments).pipe(\n Effect.map(params =>\n LLMToolCall.make({\n call: ToolCall.make({\n id: call.id,\n name: call.function.name,\n params\n })\n })\n )\n )\n )\n\n if (toolCallEvents.length > 0) {\n return [...textEvents, ...toolCallEvents, LLMDone.make({ stopReason: 'tool_use' })]\n }\n\n return [...textEvents, LLMDone.make({ stopReason: 'stop' })]\n })\n\nconst toAgentUsage = (usage: OpenAiUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.prompt_tokens,\n uncached: usage.prompt_tokens - (usage.prompt_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.prompt_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.completion_tokens,\n reasoning: usage.completion_tokens_details?.reasoning_tokens,\n text: usage.completion_tokens - (usage.completion_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean) => (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: 'openai',\n kind: retryable ? 'network' : 'unknown'\n })\n })\n\nconst parseOpenAiResponseJson = (\n response: HttpClientResponse.HttpClientResponse\n): Effect.Effect<unknown, LLMError> =>\n response.json.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Could not parse OpenAI response JSON: ${error.message}`,\n retryable: false\n })\n )\n )\n\nconst sendOpenAiRequest = (\n config: OpenAiProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiRequestBody(request, config)\n const serializedBody = yield* encodeJsonString(body, 'Could not serialize OpenAI request')\n\n const httpRequest = HttpClientRequest.post(config.chatCompletionsUrl ?? 'https://api.openai.com/v1/chat/completions').pipe(\n HttpClientRequest.setHeaders({\n accept: 'application/json',\n authorization: `Bearer ${Redacted.value(config.apiKey)}`,\n 'content-type': 'application/json',\n ...config.extraHeaders\n }),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: 'openai',\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n const json = yield* parseOpenAiResponseJson(response)\n const parsed = yield* Schema.decodeUnknownEffect(OpenAiChatCompletionResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n const choice = parsed.choices[0]\n\n if (choice === undefined) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI response contained no choices',\n retryable: false\n })\n )\n }\n\n const events = yield* toLlmEvents(choice.message)\n\n if (parsed.usage === undefined) {\n return events\n }\n\n return [...events, LLMUsage.make({ usage: toAgentUsage(parsed.usage) })]\n }).pipe(Effect.withSpan('OpenAiProvider.stream'))\n\nexport const makeOpenAiProviderLayer = (config: OpenAiProviderConfig) =>\n Layer.effect(\n LLMProvider,\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiRequest(config, request, client)).pipe(\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n })\n })\n )\n\nexport const OpenAiProviderLayer = Layer.effect(\n LLMProvider,\n Effect.gen(function* () {\n const config = yield* OpenAiConfig\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiRequest(config, request, client)).pipe(\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n })\n })\n).pipe(Layer.provide(Layer.mergeAll(OpenAiConfigLayer, FetchHttpClient.layer)))\n"],"mappings":"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"}
1
+ {"version":3,"file":"provider.mjs","names":["LLMTextDelta"],"sources":["../../../src/providers/openai/provider.ts"],"sourcesContent":["import { Config, Context, Effect, Layer, Option, Redacted, Stream } from 'effect'\nimport {\n FetchHttpClient,\n HttpClient,\n HttpClientRequest,\n type HttpClientError,\n type HttpClientResponse\n} from 'effect/unstable/http'\nimport * as Schema from 'effect/Schema'\nimport {\n ToolCall,\n AgentInputUsage,\n AgentOutputUsage,\n AgentUsage,\n attachmentSourceDataUrl,\n attachmentSourceText,\n assistantContent,\n assistantHostToolCalls,\n isTextDocumentMimeType,\n messageContextText,\n prependMessageContextToContent,\n type AgentMessage,\n type Content,\n type ContentPart,\n type ToolDef\n} from '@yolk-sdk/agent/protocol'\nimport {\n LLMError,\n LLMDone,\n LLMProvider,\n LLMTextDelta,\n LLMToolCall,\n LLMUsage,\n type LLMEvent,\n type LLMRequest\n} from '@yolk-sdk/agent/loop'\nimport {\n classifyProviderFailure,\n providerErrorInfo,\n providerFailureCause,\n providerFailureRetryable\n} from '../provider-error.ts'\nimport { validateProviderTranscript } from '../transcript.ts'\n\nexport type OpenAiProviderConfig = {\n readonly chatCompletionsUrl?: string\n readonly maxCompletionTokens?: number\n readonly extraHeaders?: Readonly<Record<string, string>>\n readonly apiKey: Redacted.Redacted<string>\n}\n\ntype OpenAiTextContentPart = {\n readonly type: 'text'\n readonly text: string\n}\n\ntype OpenAiImageContentPart = {\n readonly type: 'image_url'\n readonly image_url: {\n readonly url: string\n }\n}\n\ntype OpenAiUserContent = string | ReadonlyArray<OpenAiTextContentPart | OpenAiImageContentPart>\n\ntype OpenAiToolCall = {\n readonly id: string\n readonly type: 'function'\n readonly function: {\n readonly name: string\n readonly arguments: string\n }\n}\n\ntype OpenAiMessage =\n | { readonly role: 'system'; readonly content: string }\n | { readonly role: 'user'; readonly content: OpenAiUserContent }\n | {\n readonly role: 'assistant'\n readonly content: string | null\n readonly tool_calls?: ReadonlyArray<OpenAiToolCall>\n }\n | { readonly role: 'tool'; readonly tool_call_id: string; readonly content: string }\n\ntype OpenAiTool = {\n readonly type: 'function'\n readonly function: {\n readonly name: string\n readonly description: string\n readonly parameters: unknown\n }\n}\n\ntype OpenAiRequestBody = {\n readonly model: string\n readonly messages: ReadonlyArray<OpenAiMessage>\n readonly max_completion_tokens: number\n readonly tools?: ReadonlyArray<OpenAiTool>\n readonly parallel_tool_calls?: true\n}\n\nclass OpenAiFunctionResponse extends Schema.Class<OpenAiFunctionResponse>('OpenAiFunctionResponse')(\n {\n name: Schema.String,\n arguments: Schema.String\n }\n) {}\n\nclass OpenAiToolCallResponse extends Schema.Class<OpenAiToolCallResponse>('OpenAiToolCallResponse')(\n {\n id: Schema.String,\n type: Schema.Literals(['function']),\n function: OpenAiFunctionResponse\n }\n) {}\n\nclass OpenAiMessageResponse extends Schema.Class<OpenAiMessageResponse>('OpenAiMessageResponse')({\n content: Schema.NullOr(Schema.String),\n tool_calls: Schema.optional(Schema.Array(OpenAiToolCallResponse))\n}) {}\n\nclass OpenAiChoiceResponse extends Schema.Class<OpenAiChoiceResponse>('OpenAiChoiceResponse')({\n message: OpenAiMessageResponse\n}) {}\n\nclass OpenAiPromptTokensDetails extends Schema.Class<OpenAiPromptTokensDetails>(\n 'OpenAiPromptTokensDetails'\n)({\n cached_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiCompletionTokensDetails extends Schema.Class<OpenAiCompletionTokensDetails>(\n 'OpenAiCompletionTokensDetails'\n)({\n reasoning_tokens: Schema.optional(Schema.Number)\n}) {}\n\nclass OpenAiUsageResponse extends Schema.Class<OpenAiUsageResponse>('OpenAiUsageResponse')({\n prompt_tokens: Schema.Number,\n completion_tokens: Schema.Number,\n prompt_tokens_details: Schema.optional(OpenAiPromptTokensDetails),\n completion_tokens_details: Schema.optional(OpenAiCompletionTokensDetails)\n}) {}\n\nclass OpenAiChatCompletionResponse extends Schema.Class<OpenAiChatCompletionResponse>(\n 'OpenAiChatCompletionResponse'\n)({\n choices: Schema.Array(OpenAiChoiceResponse),\n usage: Schema.optional(OpenAiUsageResponse)\n}) {}\n\nclass OpenAiConfig extends Context.Service<OpenAiConfig, OpenAiProviderConfig>()(\n '@app/OpenAiConfig'\n) {}\n\nconst OpenAiConfigLayer = Layer.effect(\n OpenAiConfig,\n Effect.gen(function* () {\n const apiKey = yield* Config.redacted('OPENAI_API_KEY')\n return { apiKey }\n }).pipe(\n Effect.mapError(\n () =>\n new LLMError({\n cause: 'provider_error',\n message: 'OPENAI_API_KEY not found',\n retryable: false\n })\n )\n )\n)\n\nconst unknownToMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error)\n\nconst encodeJsonString = (value: unknown, message: string) =>\n Schema.encodeUnknownEffect(Schema.UnknownFromJsonString)(value).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst decodeJsonString = (raw: string, message: string) =>\n Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)(raw).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `${message}: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n\nconst unsupportedContentError = (contentType: string) =>\n new LLMError({\n cause: 'provider_error',\n message: `${contentType} content is not supported by the OpenAI provider yet`,\n retryable: false\n })\n\nconst textDocumentToOpenAiPart = (part: Extract<ContentPart, { readonly _tag: 'Document' }>) =>\n attachmentSourceText(part.source).pipe(\n Effect.mapError(() => unsupportedContentError('Invalid document text')),\n Effect.flatMap(\n Option.match({\n onNone: () => Effect.fail(unsupportedContentError('Unresolved document source')),\n onSome: text => {\n const block: OpenAiTextContentPart = {\n type: 'text',\n text: `Document: ${part.title ?? part.filename}\\n\\n${text}`\n }\n\n return Effect.succeed(block)\n }\n })\n )\n )\n\nconst contentPartToUserPart = (\n part: ContentPart\n): Effect.Effect<OpenAiTextContentPart | OpenAiImageContentPart, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed({ type: 'text', text: part.text })\n case 'Image':\n return Option.match(attachmentSourceDataUrl(part.source, part.mimeType), {\n onNone: () => Effect.fail(unsupportedContentError('Unresolved image source')),\n onSome: url => Effect.succeed({ type: 'image_url', image_url: { url } })\n })\n case 'Document':\n return isTextDocumentMimeType(part.mimeType)\n ? textDocumentToOpenAiPart(part)\n : Effect.fail(unsupportedContentError('Document'))\n case 'Audio':\n return Effect.fail(unsupportedContentError('Audio'))\n }\n}\n\nconst contentToUserContent = (content: Content): Effect.Effect<OpenAiUserContent, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, contentPartToUserPart)\n\nconst contentPartToText = (part: ContentPart, owner: string): Effect.Effect<string, LLMError> => {\n switch (part._tag) {\n case 'Text':\n return Effect.succeed(part.text)\n case 'Image':\n return Effect.fail(unsupportedContentError(`${owner} image`))\n case 'Document':\n return Effect.fail(unsupportedContentError(`${owner} document`))\n case 'Audio':\n return Effect.fail(unsupportedContentError(`${owner} audio`))\n }\n}\n\nconst contentToText = (content: Content, owner: string): Effect.Effect<string, LLMError> =>\n typeof content === 'string'\n ? Effect.succeed(content)\n : Effect.forEach(content, part => contentPartToText(part, owner)).pipe(\n Effect.map(textParts => textParts.join('\\n'))\n )\n\nconst serializeToolArguments = (params: unknown) =>\n encodeJsonString(params, 'Could not serialize OpenAI tool arguments')\n\nconst toolCallToOpenAiToolCall = (call: ToolCall): Effect.Effect<OpenAiToolCall, LLMError> =>\n Effect.gen(function* () {\n return {\n id: call.id,\n type: 'function',\n function: {\n name: call.name,\n arguments: yield* serializeToolArguments(call.params)\n }\n }\n })\n\nconst toOpenAiMessage = (message: AgentMessage): Effect.Effect<OpenAiMessage, LLMError> =>\n Effect.gen(function* () {\n switch (message._tag) {\n case 'User':\n return {\n role: 'user',\n content: yield* contentToUserContent(\n prependMessageContextToContent(message.content, messageContextText(message))\n )\n }\n case 'Assistant': {\n const content = prependMessageContextToContent(\n assistantContent(message),\n messageContextText(message)\n )\n const toolCalls = yield* Effect.forEach(\n assistantHostToolCalls(message),\n toolCallToOpenAiToolCall\n )\n\n if (toolCalls.length > 0) {\n return {\n role: 'assistant',\n content: yield* contentToText(content, 'Assistant'),\n tool_calls: toolCalls\n }\n }\n\n return {\n role: 'assistant',\n content: yield* contentToText(content, 'Assistant')\n }\n }\n case 'ToolResult':\n return {\n role: 'tool',\n tool_call_id: message.toolCallId,\n content: yield* contentToText(\n prependMessageContextToContent(message.content, messageContextText(message)),\n 'Tool result'\n )\n }\n }\n })\n\nconst toOpenAiTool = (tool: ToolDef): OpenAiTool => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters\n }\n})\n\nexport const toOpenAiRequestBody = (\n request: LLMRequest,\n config?: { readonly maxCompletionTokens?: number }\n): Effect.Effect<OpenAiRequestBody, LLMError> =>\n Effect.gen(function* () {\n yield* validateProviderTranscript(request.messages)\n const systemMessage: OpenAiMessage = { role: 'system', content: request.systemPrompt }\n const requestMessages = yield* Effect.forEach(request.messages, toOpenAiMessage)\n const messages = [systemMessage, ...requestMessages]\n\n const body = {\n model: request.model,\n messages,\n max_completion_tokens: config?.maxCompletionTokens ?? 4096\n }\n\n if (request.tools.length === 0) {\n return body\n }\n\n return {\n ...body,\n tools: request.tools.map(toOpenAiTool),\n parallel_tool_calls: true\n }\n })\n\nconst parseToolArguments = (raw: string) =>\n decodeJsonString(raw, 'Invalid OpenAI tool arguments JSON')\n\nconst toLlmEvents = (\n message: OpenAiMessageResponse\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const content = message.content ?? ''\n const textEvents = content.length > 0 ? [LLMTextDelta.make({ text: content })] : []\n const toolCallEvents = yield* Effect.forEach(message.tool_calls ?? [], call =>\n parseToolArguments(call.function.arguments).pipe(\n Effect.map(params =>\n LLMToolCall.make({\n call: ToolCall.make({\n id: call.id,\n name: call.function.name,\n params\n })\n })\n )\n )\n )\n\n if (toolCallEvents.length > 0) {\n return [...textEvents, ...toolCallEvents, LLMDone.make({ stopReason: 'tool_use' })]\n }\n\n return [...textEvents, LLMDone.make({ stopReason: 'stop' })]\n })\n\nconst toAgentUsage = (usage: OpenAiUsageResponse) =>\n AgentUsage.make({\n input: AgentInputUsage.make({\n total: usage.prompt_tokens,\n uncached: usage.prompt_tokens - (usage.prompt_tokens_details?.cached_tokens ?? 0),\n cacheRead: usage.prompt_tokens_details?.cached_tokens\n }),\n output: AgentOutputUsage.make({\n total: usage.completion_tokens,\n reasoning: usage.completion_tokens_details?.reasoning_tokens,\n text: usage.completion_tokens - (usage.completion_tokens_details?.reasoning_tokens ?? 0)\n })\n })\n\nconst toHttpClientLlmError =\n (message: string, retryable: boolean) => (error: HttpClientError.HttpClientError) =>\n new LLMError({\n cause: 'provider_error',\n message: `${message}: ${error.message}`,\n retryable,\n provider: providerErrorInfo({\n provider: 'openai',\n kind: retryable ? 'network' : 'unknown'\n })\n })\n\nconst parseOpenAiResponseJson = (\n response: HttpClientResponse.HttpClientResponse\n): Effect.Effect<unknown, LLMError> =>\n response.json.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Could not parse OpenAI response JSON: ${error.message}`,\n retryable: false\n })\n )\n )\n\nconst sendOpenAiRequest = (\n config: OpenAiProviderConfig,\n request: LLMRequest,\n client: HttpClient.HttpClient\n): Effect.Effect<ReadonlyArray<LLMEvent>, LLMError> =>\n Effect.gen(function* () {\n const body = yield* toOpenAiRequestBody(request, config)\n const serializedBody = yield* encodeJsonString(body, 'Could not serialize OpenAI request')\n\n const httpRequest = HttpClientRequest.post(config.chatCompletionsUrl ?? 'https://api.openai.com/v1/chat/completions').pipe(\n HttpClientRequest.setHeaders({\n accept: 'application/json',\n authorization: `Bearer ${Redacted.value(config.apiKey)}`,\n 'content-type': 'application/json',\n ...config.extraHeaders\n }),\n HttpClientRequest.bodyText(serializedBody, 'application/json')\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(toHttpClientLlmError('OpenAI request failed', true)))\n\n if (response.status < 200 || response.status >= 300) {\n const errorText = yield* response.text.pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'provider_error',\n message: `Could not read OpenAI error body: ${error.message}`,\n retryable: false\n })\n )\n )\n\n const provider = classifyProviderFailure({\n provider: 'openai',\n status: response.status,\n headers: response.headers,\n body: errorText\n })\n\n return yield* Effect.fail(\n new LLMError({\n cause: providerFailureCause(provider.kind),\n message: `OpenAI returned ${response.status}`,\n retryable: providerFailureRetryable(provider.kind),\n provider\n })\n )\n }\n\n const json = yield* parseOpenAiResponseJson(response)\n const parsed = yield* Schema.decodeUnknownEffect(OpenAiChatCompletionResponse)(json).pipe(\n Effect.mapError(\n error =>\n new LLMError({\n cause: 'invalid_response',\n message: `Invalid OpenAI response: ${unknownToMessage(error)}`,\n retryable: false\n })\n )\n )\n const choice = parsed.choices[0]\n\n if (choice === undefined) {\n return yield* Effect.fail(\n new LLMError({\n cause: 'invalid_response',\n message: 'OpenAI response contained no choices',\n retryable: false\n })\n )\n }\n\n const events = yield* toLlmEvents(choice.message)\n\n if (parsed.usage === undefined) {\n return events\n }\n\n return [...events, LLMUsage.make({ usage: toAgentUsage(parsed.usage) })]\n }).pipe(Effect.withSpan('OpenAiProvider.stream'))\n\nexport const makeOpenAiProviderLayer = (config: OpenAiProviderConfig) =>\n Layer.effect(\n LLMProvider,\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiRequest(config, request, client)).pipe(\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n })\n })\n )\n\nexport const OpenAiProviderLayer = Layer.effect(\n LLMProvider,\n Effect.gen(function* () {\n const config = yield* OpenAiConfig\n const client = yield* HttpClient.HttpClient\n\n return LLMProvider.of({\n stream: request =>\n Stream.fromEffect(sendOpenAiRequest(config, request, client)).pipe(\n Stream.flatMap(events => Stream.fromIterable(events))\n )\n })\n })\n).pipe(Layer.provide(Layer.mergeAll(OpenAiConfigLayer, FetchHttpClient.layer)))\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { AgentMessage } from "@yolk-sdk/agent/protocol";
2
+ import { Effect } from "effect";
3
+ import { LLMError } from "@yolk-sdk/agent/loop";
4
+
5
+ //#region src/providers/transcript.d.ts
6
+ declare const validateProviderTranscript: (messages: ReadonlyArray<AgentMessage>) => Effect.Effect<void, LLMError>;
7
+ //#endregion
8
+ export { validateProviderTranscript };
9
+ //# sourceMappingURL=transcript.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.d.mts","names":[],"sources":["../../src/providers/transcript.ts"],"mappings":";;;;;cAOa,0BAAA,GACX,QAAA,EAAU,aAAA,CAAc,YAAA,MACvB,MAAA,CAAO,MAAA,OAAa,QAAA"}
@@ -0,0 +1,17 @@
1
+ import { validateNoDanglingHostToolCalls } from "@yolk-sdk/agent/protocol";
2
+ import { Effect } from "effect";
3
+ import { LLMError } from "@yolk-sdk/agent/loop";
4
+ //#region src/providers/transcript.ts
5
+ const validateProviderTranscript = (messages) => {
6
+ const validation = validateNoDanglingHostToolCalls(messages);
7
+ if (validation._tag === "Valid") return Effect.void;
8
+ return Effect.fail(new LLMError({
9
+ cause: "validation_error",
10
+ message: validation.message,
11
+ retryable: false
12
+ }));
13
+ };
14
+ //#endregion
15
+ export { validateProviderTranscript };
16
+
17
+ //# sourceMappingURL=transcript.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.mjs","names":[],"sources":["../../src/providers/transcript.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport {\n validateNoDanglingHostToolCalls,\n type AgentMessage\n} from '@yolk-sdk/agent/protocol'\nimport { LLMError } from '@yolk-sdk/agent/loop'\n\nexport const validateProviderTranscript = (\n messages: ReadonlyArray<AgentMessage>\n): Effect.Effect<void, LLMError> => {\n const validation = validateNoDanglingHostToolCalls(messages)\n\n if (validation._tag === 'Valid') {\n return Effect.void\n }\n\n return Effect.fail(\n new LLMError({\n cause: 'validation_error',\n message: validation.message,\n retryable: false\n })\n )\n}\n"],"mappings":";;;;AAOA,MAAa,8BACX,aACkC;CAClC,MAAM,aAAa,gCAAgC,QAAQ;CAE3D,IAAI,WAAW,SAAS,SACtB,OAAO,OAAO;CAGhB,OAAO,OAAO,KACZ,IAAI,SAAS;EACX,OAAO;EACP,SAAS,WAAW;EACpB,WAAW;CACb,CAAC,CACH;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yolk-sdk/agent",
3
- "version": "0.1.0-canary.21",
3
+ "version": "0.1.0-canary.22",
4
4
  "description": "Protocol, loop, runtime, client, compaction, tools, React, providers, OAuth, skillset, and voice primitives for building Yolk agents.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/loop/run.ts CHANGED
@@ -173,6 +173,52 @@ const subagentCompletedEvent = (input: {
173
173
  })
174
174
  }
175
175
 
176
+ const toolCompletionEvents = (input: {
177
+ readonly call: ToolCall
178
+ readonly result: ToolResult
179
+ readonly model: string
180
+ readonly startedAtMs: number
181
+ readonly endedAtMs: number
182
+ }): ReadonlyArray<AgentEvent> => {
183
+ const completed = subagentCompletedEvent(input)
184
+ const toolCompleted = ToolExecutionCompleted.make({
185
+ call: input.call,
186
+ result: input.result,
187
+ createdAtMs: input.endedAtMs
188
+ })
189
+
190
+ return completed === undefined ? [toolCompleted] : [toolCompleted, completed]
191
+ }
192
+
193
+ const toolErrorResult = (call: ToolCall, error: ToolError) =>
194
+ ToolResult.make({
195
+ toolCallId: call.id,
196
+ content: error.message,
197
+ isError: true
198
+ })
199
+
200
+ const toolErrorEvents = (input: {
201
+ readonly call: ToolCall
202
+ readonly error: ToolError
203
+ readonly model: string
204
+ readonly startedAtMs: number
205
+ readonly endedAtMs: number
206
+ }): ReadonlyArray<AgentEvent> => [
207
+ ToolExecutionError.make({
208
+ call: input.call,
209
+ message: input.error.message,
210
+ code: toolErrorCode(input.error),
211
+ createdAtMs: input.endedAtMs
212
+ }),
213
+ ...toolCompletionEvents({
214
+ call: input.call,
215
+ result: toolErrorResult(input.call, input.error),
216
+ model: input.model,
217
+ startedAtMs: input.startedAtMs,
218
+ endedAtMs: input.endedAtMs
219
+ })
220
+ ]
221
+
176
222
  const unsupportedInputError = (message: string) =>
177
223
  new LLMError({
178
224
  cause: 'validation_error',
@@ -400,22 +446,15 @@ const makeToolExecutionStream = (
400
446
  executor.execute(call).pipe(
401
447
  Effect.flatMap(result =>
402
448
  Clock.currentTimeMillis.pipe(
403
- Effect.map(endedAtMs => {
404
- const completed = subagentCompletedEvent({
449
+ Effect.map(endedAtMs =>
450
+ toolCompletionEvents({
405
451
  call,
406
452
  result,
407
453
  model,
408
454
  startedAtMs,
409
455
  endedAtMs
410
456
  })
411
- const toolCompleted = ToolExecutionCompleted.make({
412
- call,
413
- result,
414
- createdAtMs: endedAtMs
415
- })
416
-
417
- return completed === undefined ? [toolCompleted] : [toolCompleted, completed]
418
- })
457
+ )
419
458
  )
420
459
  )
421
460
  )
@@ -424,16 +463,16 @@ const makeToolExecutionStream = (
424
463
  Stream.catchTag('ToolError', error =>
425
464
  Stream.fromEffect(Clock.currentTimeMillis).pipe(
426
465
  Stream.flatMap(endedAtMs =>
427
- Stream.make(
428
- ToolExecutionError.make({
466
+ Stream.fromIterable(
467
+ toolErrorEvents({
429
468
  call,
430
- message: error.message,
431
- code: toolErrorCode(error),
432
- createdAtMs: endedAtMs
469
+ error,
470
+ model,
471
+ startedAtMs,
472
+ endedAtMs
433
473
  })
434
474
  )
435
- ),
436
- Stream.concat(Stream.fail(error))
475
+ )
437
476
  )
438
477
  )
439
478
  )
@@ -96,8 +96,16 @@ export {
96
96
  assistantContent,
97
97
  assistantHostToolCalls,
98
98
  assistantReasoningText,
99
+ danglingHostToolCalls,
99
100
  messageContextText,
100
- prependMessageContextToContent
101
+ prependMessageContextToContent,
102
+ repairDanglingHostToolCalls,
103
+ validateNoDanglingHostToolCalls
104
+ } from './message.ts'
105
+ export type {
106
+ DanglingHostToolCall,
107
+ RepairDanglingHostToolCallsOptions,
108
+ TranscriptInvariantValidation
101
109
  } from './message.ts'
102
110
  export { AgentReasoningEffort } from './reasoning.ts'
103
111
  export {