@robota-sdk/agent-provider-openai 3.0.0-beta.82 → 3.0.0-beta.83

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/CHANGELOG.md +207 -0
  2. package/README.md +110 -0
  3. package/dist/node/index.cjs +1 -1
  4. package/dist/node/index.d.cts +8 -3
  5. package/dist/node/index.d.cts.map +1 -1
  6. package/dist/node/index.d.ts +8 -3
  7. package/dist/node/index.d.ts.map +1 -1
  8. package/dist/node/index.js +1 -1
  9. package/dist/node/index.js.map +1 -1
  10. package/dist/node/loggers/index.d.cts +6 -6
  11. package/dist/node/loggers/index.d.cts.map +1 -1
  12. package/dist/node/loggers/index.d.ts +6 -6
  13. package/dist/node/loggers/index.d.ts.map +1 -1
  14. package/dist/node/loggers/index.js.map +1 -1
  15. package/dist/node/{payload-logger-BaW0K8yI.d.ts → payload-logger-n89AQdUn.d.cts} +6 -4
  16. package/dist/node/payload-logger-n89AQdUn.d.cts.map +1 -0
  17. package/dist/node/{payload-logger-BaW0K8yI.d.cts → payload-logger-n89AQdUn.d.ts} +6 -4
  18. package/dist/node/payload-logger-n89AQdUn.d.ts.map +1 -0
  19. package/package.json +10 -5
  20. package/src/openai/__tests__/abort-signal-wire.test.ts +210 -0
  21. package/src/openai/__tests__/strict-tools-closure.test.ts +49 -2
  22. package/src/openai/__tests__/tool-schema-projection.test.ts +16 -2
  23. package/src/openai/chat-completions-chat.ts +2 -2
  24. package/src/openai/interfaces/payload-logger.ts +5 -3
  25. package/src/openai/loggers/console-payload-logger.ts +2 -2
  26. package/src/openai/loggers/file-payload-logger.ts +6 -5
  27. package/src/openai/message-converter.ts +7 -3
  28. package/src/openai/responses-parser.test.ts +87 -0
  29. package/src/openai/responses-parser.ts +15 -9
  30. package/src/openai/responses-types.ts +2 -0
  31. package/src/openai/types.ts +7 -2
  32. package/dist/node/payload-logger-BaW0K8yI.d.cts.map +0 -1
  33. package/dist/node/payload-logger-BaW0K8yI.d.ts.map +0 -1
@@ -1,2 +1,2 @@
1
- import{AbstractAIProvider as e,PERMISSIVE_TOOL_SCHEMA_PROFILE as t,STRICT_TOOL_SCHEMA_PROFILE as n,SilentLogger as r,createModelEffortOutcome as i,resolveModelEffort as a,toProviderError as o,traceHeadersFor as ee}from"@robota-sdk/agent-core";import te from"openai";import{OpenAICompatibleResponseParser as ne,assembleOpenAICompatibleStream as re,convertToOpenAICompatibleMessages as ie,convertToOpenAICompatibleTools as ae,observeProviderNativeRawPayloadStream as s,probeOpenAICompatibleProfile as oe,toOpenAICompatibleToolChoice as se,toOpenAIResponsesToolChoice as ce}from"@robota-sdk/agent-provider-openai-compatible/shared";import{randomUUID as c}from"node:crypto";function le(e){return ie(e)}function l(e){return ae(e)}function u(e,t){return t?.type===void 0?e:t.type===`json_schema`?{...e,responseFormat:`json_schema`,jsonSchema:{name:t.name??`structured_output`,schema:t.schema}}:{...e,responseFormat:t.type}}function ue(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{type:`json_object`};let t=d(e);return{type:`json_schema`,json_schema:{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}}function de(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{format:{type:`json_object`}};let t=d(e);return{format:{type:`json_schema`,name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}}function d(e){let t=e.jsonSchema;if(e.responseFormat!==`json_schema`)throw Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw Error(`OpenAI jsonSchema.schema is required when responseFormat is json_schema`);return{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}async function f(e){if(typeof e.withResponse==`function`){let{data:t,request_id:n}=await e.withResponse();return{data:t,...typeof n==`string`&&n.length>0&&{providerRequestId:n}}}return{data:await e}}function p(e){let t=e?._request_id;return typeof t==`string`&&t.length>0?t:void 0}function m(e,t){return t===void 0?e:{...e,metadata:{...e.metadata,providerRequestId:t}}}function h(e,t){let n=t!==void 0&&Object.keys(t).length>0;if(!(!e&&!n))return{...e?{signal:e}:{},...n?{headers:{...t}}:{}}}async function fe(e){let t=y(e.client);try{let n=_(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await me(t,e,{...n,stream:!0,...g(e)});await v(e,n,`chat`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let r=h(void 0,e.requestHeaders),i=r?await t.chat.completions.create(n,r):await t.chat.completions.create(n);return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),m(e.responseParser.parseResponse(i),p(i))}catch(e){throw o(e,`openai`,`OpenAI chat failed`)}}async function*pe(e){let t=y(e.client);try{let n={..._(e),stream:!0,...g(e)};await v(e,n,`stream`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let{data:r,providerRequestId:i}=await f(t.chat.completions.create(n,h(e.chatOptions?.signal,e.requestHeaders)));for await(let t of s(r,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let n=e.responseParser.parseStreamingChunk(t);n&&(yield m(n,i))}}catch(e){throw o(e,`openai`,`OpenAI stream failed`)}}function g(e){return e.providerOptions.includeStreamUsage===!1?{}:{stream_options:{include_usage:!0}}}function _(e){let t=le(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let r=ue(u(e.providerOptions,e.chatOptions?.responseFormat));return{model:n,messages:t,...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_tokens:e.chatOptions.maxTokens},...e.chatOptions?.tools&&{tools:l(e.chatOptions.tools),tool_choice:se(e.chatOptions.toolChoice)},...r!==void 0&&{response_format:r}}}async function me(e,t,n){try{await v(t,n,`stream`),t.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let{data:r,providerRequestId:i}=await f(e.chat.completions.create(n,h(t.chatOptions?.signal,t.requestHeaders)));return m(await re({stream:s(r,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:t.chatOptions?.onProviderNativeRawPayload}),onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal}),i)}catch(e){throw o(e,`openai`,`OpenAI stream failed`)}}async function v(e,t,n){if(!e.payloadLogger?.isEnabled())return;let r={model:t.model,messagesCount:t.messages.length,hasTools:!!t.tools,temperature:t.temperature??void 0,maxTokens:t.max_tokens??void 0,timestamp:new Date().toISOString()};await e.payloadLogger.logPayload(r,n)}function y(e){if(!e)throw Error(`OpenAI client not available. Either provide a client/apiKey or use an executor.`);return e}const he={verifiedAt:`2026-09-11`,sourceUrl:`https://platform.openai.com/docs/api-reference/responses`,models:{"gpt-5.1":{supportedEfforts:[`none`,`low`,`medium`,`high`],defaultEffort:`none`,nativeControlId:`responses.reasoning.effort`}}};var ge=class{parser;constructor(e){this.parser=new ne({logger:e})}parseResponse(e){try{return this.parser.parseResponse(e)}catch(e){let t=b(e instanceof Error?e.message:`OpenAI response parsing failed`);throw Error(`OpenAI response parsing failed: ${t}`)}}parseStreamingChunk(e){try{return this.parser.parseStreamingChunk(e)}catch(e){let t=b(e instanceof Error?e.message:`OpenAI chunk parsing failed`);throw Error(`OpenAI chunk parsing failed: ${t}`)}}};function b(e){return e.replace(/^OpenAI-compatible response parsing failed: /,``).replace(/^OpenAI-compatible chunk parsing failed: /,``).replace(`OpenAI-compatible response`,`OpenAI response`)}function _e(e){return e}function x(e,t){if(t===void 0)return e;if(t.effective===null||t.disposition===`model-default`){if(e?.effort!==void 0)throw Error(`Static reasoning.effort ${e.effort} conflicts with ${t.disposition===`model-default`?`provider-default selection`:`an effort resolution that does not apply a native control`}.`);return e}let n=_e(t.effective);if(e?.effort!==void 0&&e.effort!==n)throw Error(`Resolved effort ${n} conflicts with static reasoning.effort ${e.effort}.`);return{...e,effort:n}}function S(e){return e.flatMap(e=>w(e))}function C(e,t){let n=t??!1,r=e?.map(e=>({type:`function`,name:e.name,description:e.description,parameters:e.parameters,strict:n}))??[];return r.length>0?r:void 0}function w(e){if(e.role===`user`)return[O(`user`,E(e.content,e.parts))];if(e.role===`system`)return[O(`system`,e.content)];if(e.role===`tool`){if(!e.toolCallId||e.toolCallId.trim().length===0)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return[{type:`function_call_output`,call_id:e.toolCallId,output:e.content||``}]}return T(e)}function T(e){let t=[];e.content&&e.content.length>0&&t.push(O(`assistant`,e.content));for(let n of e.toolCalls??[])t.push({type:`function_call`,call_id:n.id,name:n.function.name,arguments:n.function.arguments});return t.length===0&&t.push(O(`assistant`,``)),t}function E(e,t){if(!t||t.length===0)return e;let n=t.map(e=>D(e));return e.length>0&&!t.some(e=>e.type===`text`)?[{type:`input_text`,text:e},...n]:n}function D(e){return e.type===`text`?{type:`input_text`,text:e.text}:e.type===`image_uri`?{type:`input_image`,image_url:e.uri}:{type:`input_image`,image_url:`data:${e.mimeType};base64,${e.data}`}}function O(e,t){return{role:e,content:t}}async function*k(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let e=await A(n,t);if(e.done||t?.aborted)break;yield e.value}}finally{t?.aborted&&await n.return?.()}}async function A(e,t){if(!t)return e.next();if(t.aborted)return{done:!0,value:void 0};let n,r=new Promise(e=>{n=()=>e({done:!0,value:void 0}),t.addEventListener(`abort`,n,{once:!0})});try{return await Promise.race([e.next(),r])}finally{n&&t.removeEventListener(`abort`,n)}}function j(e){G(e);let t=e.output??[];return I({content:e.output_text??B(t),toolCalls:L(t),response:e,reasoning:V(t)})}async function M(e){let t={textParts:[],toolCalls:[],reasoning:U()};for await(let n of k(e.stream,e.signal))N(t,n,e.onTextDelta);return t.completedResponse===void 0?I({content:t.textParts.join(``),toolCalls:t.toolCalls,reasoning:t.reasoning}):F(t)}function N(e,t,n){if(t.type===`response.output_text.delta`){e.textParts.push(t.delta),n?.(t.delta);return}if(t.type===`response.completed`){e.completedResponse=t.response,W(e.reasoning,V(t.response.output??[]));return}if(t.type===`response.output_item.done`){P(e,t.item);return}if(t.type===`response.error`||t.type===`response.failed`||t.type===`response.incomplete`)throw Error(`OpenAI Responses API failed: ${Ce(t)}`)}function P(e,t){if(R(t)){e.toolCalls.push(z(t));return}H(t)&&W(e.reasoning,V([t]))}function F(e){let t=e.completedResponse;if(t===void 0)throw Error(`OpenAI Responses stream completed without response metadata`);G(t);let n=t.output??[],r=L(n),i=e.textParts.length>0?e.textParts.join(``):t.output_text??B(n),a=V(n);return W(a,e.reasoning),I({content:i,toolCalls:r.length>0?r:e.toolCalls,response:t,reasoning:a})}function I(e){return{id:c(),role:`assistant`,content:e.content,state:`complete`,timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:ye(e.response.usage)},metadata:{...ve(e.response,e.reasoning),...e.response?.usage!==void 0&&{usageProvenance:e.response.usage.input_tokens!==void 0&&e.response.usage.output_tokens!==void 0&&e.response.usage.total_tokens!==void 0?`complete`:`partial`}}}}function ve(e,t){return{providerApiSurface:`responses`,...e?.id!==void 0&&{responseId:e.id},...e?.model!==void 0&&{model:e.model},...e?.status!==void 0&&{finishReason:e.status},...t.reasoningSummaryCount>0&&{reasoningSummaryCount:t.reasoningSummaryCount,reasoningSummaries:t.reasoningSummaries},...t.hasEncryptedReasoning&&{hasEncryptedReasoning:!0}}}function ye(e){return{promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function L(e){return e.filter(R).map(e=>z(e))}function R(e){return e.type===`function_call`&&`call_id`in e&&`name`in e&&`arguments`in e}function z(e){return{id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments}}}function B(e){return e.filter(xe).flatMap(e=>e.content).map(be).join(``)}function be(e){return e.type===`refusal`?e.refusal:e.text}function xe(e){return e.type===`message`&&`content`in e&&Array.isArray(e.content)}function V(e){let t=U();for(let n of e){if(!H(n))continue;let e=n.summary?.map(e=>e.text).filter(Se)??[];t.reasoningSummaryCount+=e.length,t.reasoningSummaries.push(...e),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content}return t}function H(e){return e.type===`reasoning`}function U(){return{reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:!1}}function W(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning}function Se(e){return e!==void 0}function G(e){if(e.status===`failed`||e.status===`incomplete`)throw Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function Ce(e){return e.message??e.error?.message??e.response?.error?.message??`unknown error`}async function we(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return K({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=q(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let n=await e.client.responses.create(t,h(e.chatOptions?.signal,e.requestHeaders));return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`response`,payload:n}),m(j(n),p(n))}catch(e){throw o(e,`openai`,`OpenAI responses failed`)}}async function*Te(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,r=K({...e,chatOptions:{...e.chatOptions,onTextDelta:e=>{n?.(e),ke(t,De(e))}}}).then(e=>Ae(t,e)).catch(e=>je(t,Pe(e)));yield*Oe(t),await r}async function K(e){if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=Ee(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let{data:n,providerRequestId:r}=await f(e.client.responses.create(t,h(e.chatOptions?.signal,e.requestHeaders)));return m(await M({stream:s(n,{provider:`openai`,apiSurface:`responses`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal}),r)}catch(e){throw o(e,`openai`,`OpenAI responses stream failed`)}}function q(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let n=C(e.chatOptions?.tools,e.providerOptions.strictTools),r=de(e.providerOptions),i=x(e.providerOptions.reasoning,e.chatOptions?.effortResolution);return{model:t,input:S(e.messages),...n!==void 0&&{tools:n,tool_choice:ce(e.chatOptions?.toolChoice)},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...r!==void 0&&{text:r},...i!==void 0&&{reasoning:i},...e.providerOptions.includeEncryptedReasoning===!0&&{include:[`reasoning.encrypted_content`]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function Ee(e){return{...q(e),stream:!0}}function De(e){return{id:c(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{providerApiSurface:`responses`,isStreamChunk:!0,isComplete:!1}}}async function*Oe(e){for(;;){let t=e.deltas.shift();if(t!==void 0){yield t;continue}if(e.error!==void 0)throw e.error;if(e.finalMessage!==void 0){yield Ne(e.finalMessage);return}await Me(e)}}function ke(e,t){e.deltas.push(t),J(e)}function Ae(e,t){e.finalMessage=t,J(e)}function je(e,t){e.error=t,J(e)}function Me(e){return new Promise(t=>{e.wake=t})}function J(e){e.wake?.(),e.wake=void 0}function Ne(e){return{...e,content:``,metadata:{...e.metadata,isStreamChunk:!0,isComplete:!0}}}function Pe(e){return e instanceof Error?e:Error(String(e))}var Y=class extends e{name=`openai`;version=`1.0.0`;client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(e){if(super(e.logger||r),this.options=e,this.apiSurface=Fe(e),Ie(this.apiSurface,e.nativeWebTools),e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new te({apiKey:e.apiKey,...e.organization&&{organization:e.organization},...e.timeout&&{timeout:e.timeout},...e.baseURL&&{baseURL:e.baseURL}});else throw Error(`Either OpenAI client, apiKey, or executor is required`);this.responseParser=new ge(this.logger),this.payloadLogger=e.payloadLogger}async chat(e,t){this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=await this.executeViaExecutorOrDirect(e,n);return t.modelEffortOutcome===void 0&&this.publishModelEffortOutcome(n,`opaque-executor`),t.message}catch(e){throw this.logger.error(`OpenAI Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(this.apiSurface===`responses`){let t=await we({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),t}let r=await fe({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),r}async*chatStream(e,t){this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=!1;for await(let r of this.executeStreamViaExecutorOrDirect(e,n))r.kind===`message`?yield r.message:t=r.modelEffortOutcome!==void 0;t||this.publishModelEffortOutcome(n,`opaque-executor`);return}catch(e){throw this.logger.error(`OpenAI Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}yield*this.streamDirect(e,n)}async*streamDirect(e,t){if(this.apiSurface===`responses`){yield*Te({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t);return}yield*pe({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t)}endpointIsVendorDefault(){return this.options.baseURL===void 0}canPropagateTraceContext(){return!this.executor&&this.effectiveBaseUrl()!==void 0}effectiveBaseUrl(){let e=this.client?.baseURL;return typeof e==`string`&&e.length>0?e:void 0}traceRequestHeaders(e){return this.canPropagateTraceContext()?ee(this.effectiveBaseUrl(),e?.outboundTraceContext):{}}effortTable(){return this.endpointIsVendorDefault()&&this.apiSurface===`responses`?he:void 0}resolveEffortOptions(e){if(e?.effort===void 0||e.effortResolution!==void 0)return e;let t=e.model??this.options.defaultModel;return t===void 0?e:{...e,effortResolution:a(this.effortTable(),t,e.effort)}}projectionProfile(){return this.options.strictTools?{...n,providerName:`openai`}:{...t,providerName:`openai`}}projectChatOptions(e){if(!e?.tools)return e;let t=e.model??this.options.defaultModel??``,n=this.projectTools(e.tools,t);return{...e,tools:n&&n.length>0?n:void 0}}publishModelEffortOutcome(e,t){let n=e?.effortResolution,r=e?.onModelEffortOutcome;if(n===void 0||r===void 0)return;let a=t===void 0?n.effective!==null&&n.disposition!==`model-default`?{state:`sent`,id:`responses.reasoning.effort`}:{state:`omitted`,reason:n.disposition===`model-default`?`provider-default-selection`:`model-effort-not-applied`}:{state:`omitted`,reason:t},o=t===void 0?{state:`sent`}:{state:`not-dispatched`,reason:t};try{r(i(n,{nativeControl:a,providerDispatch:o}))}catch(e){this.logger.warn(`Model-effort outcome observer failed`,{error:e instanceof Error?e.message:String(e)})}}supportsTools(){return!0}getCapabilities(){let e=this.apiSurface===`chat-completions`?`openai-compatible-chat-completions`:`openai-responses`;return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`search`)},webFetch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`fetch`)}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}};function Fe(e){return e.apiSurface===void 0?e.baseURL?`chat-completions`:`responses`:e.apiSurface}function X(e,t){return e===`chat-completions`?`OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${t}.`:`OpenAI Responses native web ${t} is not wired in this Robota provider version.`}function Ie(e,t){if(t?.webSearch===!0||t?.webFetch===!0)throw Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var Le=class{static filterMessagesForOpenAI(e){return e.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`system`||e.role===`tool`&&!!(e.toolCallId&&e.toolCallId.trim()!==``&&e.toolCallId!==`unknown`))}static toOpenAIFormat(e){return this.filterMessagesForOpenAI(e).map(e=>this.convertMessage(e))}static convertMessage(e){let t=e.role;if(t===`user`)return{role:`user`,content:e.content};if(t===`assistant`){let t=e;return t.toolCalls&&t.toolCalls.length>0?{role:`assistant`,content:t.content===``?null:t.content||null,tool_calls:t.toolCalls.map(e=>({id:e.id,type:`function`,function:{name:e.function.name,arguments:e.function.arguments}}))}:{role:`assistant`,content:t.content===null||t.content===``?null:t.content||``}}if(t===`system`)return{role:`system`,content:e.content};if(t===`tool`){if(!e.toolCallId||e.toolCallId.trim()===``)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return{role:`tool`,content:e.content,tool_call_id:e.toolCallId}}throw Error(`Unsupported message role: ${t}`)}static addSystemPromptIfNeeded(e,t){return!t||e.some(e=>e.role===`system`)?e:[{role:`system`,content:t},...e]}};const Re=void 0,Z=`$ENV:OPENAI_API_KEY`,Q=[{kind:`api-key`,label:`OpenAI API keys`,url:`https://platform.openai.com/api-keys`,sourceUrl:`https://developers.openai.com/api/reference/overview#authentication`,lastVerifiedAt:`2026-05-08`}];function ze(){return{type:`openai`,displayName:`OpenAI`,description:`GPT series — general-purpose assistant. API key required.`,category:`cloud-paid`,costPerTokenUsd:.001,defaults:{apiKey:Z},endpoint:{host:`api.openai.com`,port:443},modelCatalog:{status:`unavailable`,sourceUrl:`https://platform.openai.com/docs/api-reference/models/list`,message:`OpenAI model availability should be discovered live from GET /v1/models.`},setupHelpLinks:Q,setupSteps:[{key:`model`,title:`OpenAI model`,required:!0},{key:`apiKey`,title:`OpenAI API key`,defaultValue:Z,masked:!0}],requiresApiKey:!0,probeProfile:oe,destinationEnvironment:[`OPENAI_BASE_URL`,`OPENAI_ORG_ID`,`OPENAI_PROJECT_ID`],createProvider:e=>{let t=Ve(e.options),n=He(e.options);return Ue(e.baseURL,t,n),new Y({apiKey:Be(e.apiKey),...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout},...t!==void 0&&{apiSurface:t},...n!==void 0&&{nativeWebTools:n},defaultModel:e.model})}}}function Be(e){if(!e)throw Error(`Provider openai requires apiKey`);return e}function Ve(e){let t=e?.apiSurface;if(t===`responses`||t===`chat-completions`)return t}function He(e){let t=$(e?.nativeWebTools)??$(e?.builtInWebTools);if(t!==void 0)return t}function $(e){if(e==null||e instanceof Date||Array.isArray(e)||typeof e!=`object`)return;let t=e.webSearch,n=e.webFetch;return{...typeof t==`boolean`&&{webSearch:t},...typeof n==`boolean`&&{webFetch:n}}}function Ue(e,t,n){if(n?.webSearch===!0||n?.webFetch===!0)throw Error(e!==void 0||t===`chat-completions`?`Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`:`Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`)}export{Z as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,Re as DEFAULT_OPENAI_PROVIDER_MODEL,Le as OpenAIConversationAdapter,Y as OpenAIProvider,ze as createOpenAIProviderDefinition};
1
+ import{AbstractAIProvider as e,PERMISSIVE_TOOL_SCHEMA_PROFILE as t,STRICT_TOOL_SCHEMA_PROFILE as n,SilentLogger as r,createModelEffortOutcome as i,resolveModelEffort as a,toProviderError as o,traceHeadersFor as ee}from"@robota-sdk/agent-core";import te from"openai";import{OpenAICompatibleResponseParser as ne,assembleOpenAICompatibleStream as re,convertToOpenAICompatibleMessages as ie,convertToOpenAICompatibleTools as ae,observeProviderNativeRawPayloadStream as s,probeOpenAICompatibleProfile as oe,toOpenAICompatibleToolChoice as se,toOpenAIResponsesToolChoice as ce}from"@robota-sdk/agent-provider-openai-compatible/shared";import{randomUUID as c}from"node:crypto";function le(e){return ie(e)}function l(e,t){return ae(e,{strict:t===!0})}function u(e,t){return t?.type===void 0?e:t.type===`json_schema`?{...e,responseFormat:`json_schema`,jsonSchema:{name:t.name??`structured_output`,schema:t.schema}}:{...e,responseFormat:t.type}}function ue(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{type:`json_object`};let t=d(e);return{type:`json_schema`,json_schema:{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}}function de(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{format:{type:`json_object`}};let t=d(e);return{format:{type:`json_schema`,name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}}function d(e){let t=e.jsonSchema;if(e.responseFormat!==`json_schema`)throw Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw Error(`OpenAI jsonSchema.schema is required when responseFormat is json_schema`);return{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}async function f(e){if(typeof e.withResponse==`function`){let{data:t,request_id:n}=await e.withResponse();return{data:t,...typeof n==`string`&&n.length>0&&{providerRequestId:n}}}return{data:await e}}function p(e){let t=e?._request_id;return typeof t==`string`&&t.length>0?t:void 0}function m(e,t){return t===void 0?e:{...e,metadata:{...e.metadata,providerRequestId:t}}}function h(e,t){let n=t!==void 0&&Object.keys(t).length>0;if(!(!e&&!n))return{...e?{signal:e}:{},...n?{headers:{...t}}:{}}}async function fe(e){let t=y(e.client);try{let n=_(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await me(t,e,{...n,stream:!0,...g(e)});await v(e,n,`chat`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let r=h(e.chatOptions?.signal,e.requestHeaders),i=r?await t.chat.completions.create(n,r):await t.chat.completions.create(n);return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),m(e.responseParser.parseResponse(i),p(i))}catch(e){throw o(e,`openai`,`OpenAI chat failed`)}}async function*pe(e){let t=y(e.client);try{let n={..._(e),stream:!0,...g(e)};await v(e,n,`stream`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let{data:r,providerRequestId:i}=await f(t.chat.completions.create(n,h(e.chatOptions?.signal,e.requestHeaders)));for await(let t of s(r,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let n=e.responseParser.parseStreamingChunk(t);n&&(yield m(n,i))}}catch(e){throw o(e,`openai`,`OpenAI stream failed`)}}function g(e){return e.providerOptions.includeStreamUsage===!1?{}:{stream_options:{include_usage:!0}}}function _(e){let t=le(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let r=ue(u(e.providerOptions,e.chatOptions?.responseFormat));return{model:n,messages:t,...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_tokens:e.chatOptions.maxTokens},...e.chatOptions?.tools&&{tools:l(e.chatOptions.tools,e.providerOptions.strictTools),tool_choice:se(e.chatOptions.toolChoice)},...r!==void 0&&{response_format:r}}}async function me(e,t,n){try{await v(t,n,`stream`),t.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:n});let{data:r,providerRequestId:i}=await f(e.chat.completions.create(n,h(t.chatOptions?.signal,t.requestHeaders)));return m(await re({stream:s(r,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:t.chatOptions?.onProviderNativeRawPayload}),onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal}),i)}catch(e){throw o(e,`openai`,`OpenAI stream failed`)}}async function v(e,t,n){if(!e.payloadLogger?.isEnabled())return;let r={model:t.model,messagesCount:t.messages.length,hasTools:!!t.tools,temperature:t.temperature??void 0,maxTokens:t.max_tokens??void 0,timestamp:new Date().toISOString()};await e.payloadLogger.logPayload(r,n)}function y(e){if(!e)throw Error(`OpenAI client not available. Either provide a client/apiKey or use an executor.`);return e}const he={verifiedAt:`2026-09-11`,sourceUrl:`https://platform.openai.com/docs/api-reference/responses`,models:{"gpt-5.1":{supportedEfforts:[`none`,`low`,`medium`,`high`],defaultEffort:`none`,nativeControlId:`responses.reasoning.effort`}}};var ge=class{parser;constructor(e){this.parser=new ne({logger:e})}parseResponse(e){try{return this.parser.parseResponse(e)}catch(e){let t=b(e instanceof Error?e.message:`OpenAI response parsing failed`);throw Error(`OpenAI response parsing failed: ${t}`)}}parseStreamingChunk(e){try{return this.parser.parseStreamingChunk(e)}catch(e){let t=b(e instanceof Error?e.message:`OpenAI chunk parsing failed`);throw Error(`OpenAI chunk parsing failed: ${t}`)}}};function b(e){return e.replace(/^OpenAI-compatible response parsing failed: /,``).replace(/^OpenAI-compatible chunk parsing failed: /,``).replace(`OpenAI-compatible response`,`OpenAI response`)}function _e(e){return e}function x(e,t){if(t===void 0)return e;if(t.effective===null||t.disposition===`model-default`){if(e?.effort!==void 0)throw Error(`Static reasoning.effort ${e.effort} conflicts with ${t.disposition===`model-default`?`provider-default selection`:`an effort resolution that does not apply a native control`}.`);return e}let n=_e(t.effective);if(e?.effort!==void 0&&e.effort!==n)throw Error(`Resolved effort ${n} conflicts with static reasoning.effort ${e.effort}.`);return{...e,effort:n}}function S(e){return e.flatMap(e=>w(e))}function C(e,t){let n=t??!1,r=e?.map(e=>({type:`function`,name:e.name,description:e.description,parameters:e.parameters,strict:n}))??[];return r.length>0?r:void 0}function w(e){if(e.role===`user`)return[O(`user`,E(e.content,e.parts))];if(e.role===`system`)return[O(`system`,e.content)];if(e.role===`tool`){if(!e.toolCallId||e.toolCallId.trim().length===0)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return[{type:`function_call_output`,call_id:e.toolCallId,output:e.content||``}]}return T(e)}function T(e){let t=[];e.content&&e.content.length>0&&t.push(O(`assistant`,e.content));for(let n of e.toolCalls??[])t.push({type:`function_call`,call_id:n.id,name:n.function.name,arguments:n.function.arguments});return t.length===0&&t.push(O(`assistant`,``)),t}function E(e,t){if(!t||t.length===0)return e;let n=t.map(e=>D(e));return e.length>0&&!t.some(e=>e.type===`text`)?[{type:`input_text`,text:e},...n]:n}function D(e){return e.type===`text`?{type:`input_text`,text:e.text}:e.type===`image_uri`?{type:`input_image`,image_url:e.uri}:{type:`input_image`,image_url:`data:${e.mimeType};base64,${e.data}`}}function O(e,t){return{role:e,content:t}}async function*k(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let e=await A(n,t);if(e.done||t?.aborted)break;yield e.value}}finally{t?.aborted&&await n.return?.()}}async function A(e,t){if(!t)return e.next();if(t.aborted)return{done:!0,value:void 0};let n,r=new Promise(e=>{n=()=>e({done:!0,value:void 0}),t.addEventListener(`abort`,n,{once:!0})});try{return await Promise.race([e.next(),r])}finally{n&&t.removeEventListener(`abort`,n)}}function j(e){G(e);let t=e.output??[];return I({content:e.output_text??B(t),toolCalls:L(t),response:e,reasoning:V(t)})}async function M(e){let t={textParts:[],toolCalls:[],reasoning:U()};for await(let n of k(e.stream,e.signal))N(t,n,e.onTextDelta);return t.completedResponse===void 0?I({content:t.textParts.join(``),toolCalls:t.toolCalls,reasoning:t.reasoning}):F(t)}function N(e,t,n){if(t.type===`response.output_text.delta`){e.textParts.push(t.delta),n?.(t.delta);return}if(t.type===`response.completed`){e.completedResponse=t.response,W(e.reasoning,V(t.response.output??[]));return}if(t.type===`response.output_item.done`){P(e,t.item);return}if(t.type===`response.error`||t.type===`response.failed`||t.type===`response.incomplete`)throw Error(`OpenAI Responses API failed: ${Ce(t)}`)}function P(e,t){if(R(t)){e.toolCalls.push(z(t));return}H(t)&&W(e.reasoning,V([t]))}function F(e){let t=e.completedResponse;if(t===void 0)throw Error(`OpenAI Responses stream completed without response metadata`);G(t);let n=t.output??[],r=L(n),i=e.textParts.length>0?e.textParts.join(``):t.output_text??B(n),a=V(n);return W(a,e.reasoning),I({content:i,toolCalls:r.length>0?r:e.toolCalls,response:t,reasoning:a})}function I(e){return{id:c(),role:`assistant`,content:e.content,state:`complete`,timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:ye(e.response.usage)},metadata:{...ve(e.response,e.reasoning),...e.response?.usage!==void 0&&{usageProvenance:e.response.usage.input_tokens!==void 0&&e.response.usage.output_tokens!==void 0&&e.response.usage.total_tokens!==void 0?`complete`:`partial`}}}}function ve(e,t){return{providerApiSurface:`responses`,...e?.id!==void 0&&{responseId:e.id},...e?.model!==void 0&&{model:e.model},...e?.status!==void 0&&{finishReason:e.status},...t.reasoningSummaryCount>0&&{reasoningSummaryCount:t.reasoningSummaryCount,reasoningSummaries:t.reasoningSummaries},...t.hasEncryptedReasoning&&{hasEncryptedReasoning:!0}}}function ye(e){let t=e.input_tokens_details?.cached_tokens;return{promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,...e.total_tokens!==void 0&&{totalTokens:e.total_tokens},...typeof t==`number`&&{cacheReadTokens:t}}}function L(e){return e.filter(R).map(e=>z(e))}function R(e){return e.type===`function_call`&&`call_id`in e&&`name`in e&&`arguments`in e}function z(e){return{id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments}}}function B(e){return e.filter(xe).flatMap(e=>e.content).map(be).join(``)}function be(e){return e.type===`refusal`?e.refusal:e.text}function xe(e){return e.type===`message`&&`content`in e&&Array.isArray(e.content)}function V(e){let t=U();for(let n of e){if(!H(n))continue;let e=n.summary?.map(e=>e.text).filter(Se)??[];t.reasoningSummaryCount+=e.length,t.reasoningSummaries.push(...e),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content}return t}function H(e){return e.type===`reasoning`}function U(){return{reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:!1}}function W(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning}function Se(e){return e!==void 0}function G(e){if(e.status===`failed`||e.status===`incomplete`)throw Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function Ce(e){return e.message??e.error?.message??e.response?.error?.message??`unknown error`}async function we(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return K({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=q(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let n=await e.client.responses.create(t,h(e.chatOptions?.signal,e.requestHeaders));return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`response`,payload:n}),m(j(n),p(n))}catch(e){throw o(e,`openai`,`OpenAI responses failed`)}}async function*Te(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,r=K({...e,chatOptions:{...e.chatOptions,onTextDelta:e=>{n?.(e),ke(t,De(e))}}}).then(e=>Ae(t,e)).catch(e=>je(t,Pe(e)));yield*Oe(t),await r}async function K(e){if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=Ee(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let{data:n,providerRequestId:r}=await f(e.client.responses.create(t,h(e.chatOptions?.signal,e.requestHeaders)));return m(await M({stream:s(n,{provider:`openai`,apiSurface:`responses`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal}),r)}catch(e){throw o(e,`openai`,`OpenAI responses stream failed`)}}function q(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let n=C(e.chatOptions?.tools,e.providerOptions.strictTools),r=de(e.providerOptions),i=x(e.providerOptions.reasoning,e.chatOptions?.effortResolution);return{model:t,input:S(e.messages),...n!==void 0&&{tools:n,tool_choice:ce(e.chatOptions?.toolChoice)},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...r!==void 0&&{text:r},...i!==void 0&&{reasoning:i},...e.providerOptions.includeEncryptedReasoning===!0&&{include:[`reasoning.encrypted_content`]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function Ee(e){return{...q(e),stream:!0}}function De(e){return{id:c(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{providerApiSurface:`responses`,isStreamChunk:!0,isComplete:!1}}}async function*Oe(e){for(;;){let t=e.deltas.shift();if(t!==void 0){yield t;continue}if(e.error!==void 0)throw e.error;if(e.finalMessage!==void 0){yield Ne(e.finalMessage);return}await Me(e)}}function ke(e,t){e.deltas.push(t),J(e)}function Ae(e,t){e.finalMessage=t,J(e)}function je(e,t){e.error=t,J(e)}function Me(e){return new Promise(t=>{e.wake=t})}function J(e){e.wake?.(),e.wake=void 0}function Ne(e){return{...e,content:``,metadata:{...e.metadata,isStreamChunk:!0,isComplete:!0}}}function Pe(e){return e instanceof Error?e:Error(String(e))}var Y=class extends e{name=`openai`;version=`1.0.0`;client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(e){if(super(e.logger||r),this.options=e,this.apiSurface=Fe(e),Ie(this.apiSurface,e.nativeWebTools),e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new te({apiKey:e.apiKey,...e.organization&&{organization:e.organization},...e.timeout&&{timeout:e.timeout},...e.baseURL&&{baseURL:e.baseURL}});else throw Error(`Either OpenAI client, apiKey, or executor is required`);this.responseParser=new ge(this.logger),this.payloadLogger=e.payloadLogger}async chat(e,t){this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=await this.executeViaExecutorOrDirect(e,n);return t.modelEffortOutcome===void 0&&this.publishModelEffortOutcome(n,`opaque-executor`),t.message}catch(e){throw this.logger.error(`OpenAI Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(this.apiSurface===`responses`){let t=await we({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),t}let r=await fe({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),r}async*chatStream(e,t){this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=!1;for await(let r of this.executeStreamViaExecutorOrDirect(e,n))r.kind===`message`?yield r.message:t=r.modelEffortOutcome!==void 0;t||this.publishModelEffortOutcome(n,`opaque-executor`);return}catch(e){throw this.logger.error(`OpenAI Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}yield*this.streamDirect(e,n)}async*streamDirect(e,t){if(this.apiSurface===`responses`){yield*Te({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t);return}yield*pe({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t)}endpointIsVendorDefault(){return this.options.baseURL===void 0}canPropagateTraceContext(){return!this.executor&&this.effectiveBaseUrl()!==void 0}effectiveBaseUrl(){let e=this.client?.baseURL;return typeof e==`string`&&e.length>0?e:void 0}traceRequestHeaders(e){return this.canPropagateTraceContext()?ee(this.effectiveBaseUrl(),e?.outboundTraceContext):{}}effortTable(){return this.endpointIsVendorDefault()&&this.apiSurface===`responses`?he:void 0}resolveEffortOptions(e){if(e?.effort===void 0||e.effortResolution!==void 0)return e;let t=e.model??this.options.defaultModel;return t===void 0?e:{...e,effortResolution:a(this.effortTable(),t,e.effort)}}projectionProfile(){return this.options.strictTools?{...n,providerName:`openai`}:{...t,providerName:`openai`}}projectChatOptions(e){if(!e?.tools)return e;let t=e.model??this.options.defaultModel??``,n=this.projectTools(e.tools,t);return{...e,tools:n&&n.length>0?n:void 0}}publishModelEffortOutcome(e,t){let n=e?.effortResolution,r=e?.onModelEffortOutcome;if(n===void 0||r===void 0)return;let a=t===void 0?n.effective!==null&&n.disposition!==`model-default`?{state:`sent`,id:`responses.reasoning.effort`}:{state:`omitted`,reason:n.disposition===`model-default`?`provider-default-selection`:`model-effort-not-applied`}:{state:`omitted`,reason:t},o=t===void 0?{state:`sent`}:{state:`not-dispatched`,reason:t};try{r(i(n,{nativeControl:a,providerDispatch:o}))}catch(e){this.logger.warn(`Model-effort outcome observer failed`,{error:e instanceof Error?e.message:String(e)})}}supportsTools(){return!0}getCapabilities(){let e=this.apiSurface===`chat-completions`?`openai-compatible-chat-completions`:`openai-responses`;return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`search`)},webFetch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`fetch`)}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}};function Fe(e){return e.apiSurface===void 0?e.baseURL?`chat-completions`:`responses`:e.apiSurface}function X(e,t){return e===`chat-completions`?`OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${t}.`:`OpenAI Responses native web ${t} is not wired in this Robota provider version.`}function Ie(e,t){if(t?.webSearch===!0||t?.webFetch===!0)throw Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var Le=class{static filterMessagesForOpenAI(e){return e.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`system`||e.role===`tool`&&!!(e.toolCallId&&e.toolCallId.trim()!==``&&e.toolCallId!==`unknown`))}static toOpenAIFormat(e){return this.filterMessagesForOpenAI(e).map(e=>this.convertMessage(e))}static convertMessage(e){let t=e.role;if(t===`user`)return{role:`user`,content:e.content};if(t===`assistant`){let t=e;return t.toolCalls&&t.toolCalls.length>0?{role:`assistant`,content:t.content===``?null:t.content||null,tool_calls:t.toolCalls.map(e=>({id:e.id,type:`function`,function:{name:e.function.name,arguments:e.function.arguments}}))}:{role:`assistant`,content:t.content===null||t.content===``?null:t.content||``}}if(t===`system`)return{role:`system`,content:e.content};if(t===`tool`){if(!e.toolCallId||e.toolCallId.trim()===``)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return{role:`tool`,content:e.content,tool_call_id:e.toolCallId}}throw Error(`Unsupported message role: ${t}`)}static addSystemPromptIfNeeded(e,t){return!t||e.some(e=>e.role===`system`)?e:[{role:`system`,content:t},...e]}};const Re=void 0,Z=`$ENV:OPENAI_API_KEY`,Q=[{kind:`api-key`,label:`OpenAI API keys`,url:`https://platform.openai.com/api-keys`,sourceUrl:`https://developers.openai.com/api/reference/overview#authentication`,lastVerifiedAt:`2026-05-08`}];function ze(){return{type:`openai`,displayName:`OpenAI`,description:`GPT series — general-purpose assistant. API key required.`,category:`cloud-paid`,costPerTokenUsd:.001,defaults:{apiKey:Z},endpoint:{host:`api.openai.com`,port:443},modelCatalog:{status:`unavailable`,sourceUrl:`https://platform.openai.com/docs/api-reference/models/list`,message:`OpenAI model availability should be discovered live from GET /v1/models.`},setupHelpLinks:Q,setupSteps:[{key:`model`,title:`OpenAI model`,required:!0},{key:`apiKey`,title:`OpenAI API key`,defaultValue:Z,masked:!0}],requiresApiKey:!0,probeProfile:oe,destinationEnvironment:[`OPENAI_BASE_URL`,`OPENAI_ORG_ID`,`OPENAI_PROJECT_ID`],createProvider:e=>{let t=Ve(e.options),n=He(e.options);return Ue(e.baseURL,t,n),new Y({apiKey:Be(e.apiKey),...e.baseURL!==void 0&&{baseURL:e.baseURL},...e.timeout!==void 0&&{timeout:e.timeout},...t!==void 0&&{apiSurface:t},...n!==void 0&&{nativeWebTools:n},defaultModel:e.model})}}}function Be(e){if(!e)throw Error(`Provider openai requires apiKey`);return e}function Ve(e){let t=e?.apiSurface;if(t===`responses`||t===`chat-completions`)return t}function He(e){let t=$(e?.nativeWebTools)??$(e?.builtInWebTools);if(t!==void 0)return t}function $(e){if(e==null||e instanceof Date||Array.isArray(e)||typeof e!=`object`)return;let t=e.webSearch,n=e.webFetch;return{...typeof t==`boolean`&&{webSearch:t},...typeof n==`boolean`&&{webFetch:n}}}function Ue(e,t,n){if(n?.webSearch===!0||n?.webFetch===!0)throw Error(e!==void 0||t===`chat-completions`?`Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`:`Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`)}export{Z as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,Re as DEFAULT_OPENAI_PROVIDER_MODEL,Le as OpenAIConversationAdapter,Y as OpenAIProvider,ze as createOpenAIProviderDefinition};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["assembleOpenAIStream","exhaustive"],"sources":["../../src/openai/message-converter.ts","../../src/openai/openai-request-format.ts","../../src/openai/request-id.ts","../../src/openai/request-options.ts","../../src/openai/chat-completions-chat.ts","../../src/openai/model-effort-table.ts","../../src/openai/parsers/response-parser.ts","../../src/openai/reasoning-effort.ts","../../src/openai/responses-converter.ts","../../src/openai/responses-stream-utils.ts","../../src/openai/responses-parser.ts","../../src/openai/responses-chat.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"sourcesContent":["import {\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport type { IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * Convert TUniversalMessage array to OpenAI chat completion message format.\n */\nexport function convertToOpenAIMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return convertToOpenAICompatibleMessages(messages);\n}\n\n/**\n * Convert tool schemas to OpenAI function tool format.\n */\nexport function convertToOpenAITools(tools: IToolSchema[]): OpenAI.Chat.ChatCompletionTool[] {\n return convertToOpenAICompatibleTools(tools);\n}\n","import type {\n IOpenAIResponsesTextConfig,\n IOpenAIResponsesTextFormatJsonSchema,\n} from './responses-types';\nimport type { IOpenAIProviderOptions, TOpenAIProviderOptionValue } from './types';\nimport type { IChatOptions } from '@robota-sdk/agent-core';\n\nexport interface IOpenAIChatTextFormatText {\n type: 'text';\n}\n\nexport interface IOpenAIChatTextFormatJsonObject {\n type: 'json_object';\n}\n\nexport interface IOpenAIChatTextFormatJsonSchema {\n type: 'json_schema';\n json_schema: {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n };\n}\n\nexport type TOpenAIChatResponseFormat =\n IOpenAIChatTextFormatText | IOpenAIChatTextFormatJsonObject | IOpenAIChatTextFormatJsonSchema;\n\n/**\n * Merge a per-call `IChatOptions.responseFormat` onto the provider options (CORE-015).\n * A `json_schema` chat option carries its schema payload into `jsonSchema`; the\n * provider-level `jsonSchema` option remains as-is for `text`/`json_object`.\n */\nexport function mergeChatResponseFormat(\n providerOptions: IOpenAIProviderOptions,\n responseFormat: IChatOptions['responseFormat'],\n): IOpenAIProviderOptions {\n if (responseFormat?.type === undefined) {\n return providerOptions;\n }\n if (responseFormat.type === 'json_schema') {\n return {\n ...providerOptions,\n responseFormat: 'json_schema',\n jsonSchema: {\n name: responseFormat.name ?? 'structured_output',\n schema: responseFormat.schema as Record<string, TOpenAIProviderOptionValue>,\n },\n };\n }\n return { ...providerOptions, responseFormat: responseFormat.type };\n}\n\nexport function buildOpenAIChatResponseFormat(\n options: IOpenAIProviderOptions,\n): TOpenAIChatResponseFormat | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { type: 'json_object' };\n }\n\n const schema = requireJsonSchema(options);\n return {\n type: 'json_schema',\n json_schema: {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n },\n };\n}\n\nexport function buildOpenAIResponsesTextConfig(\n options: IOpenAIProviderOptions,\n): IOpenAIResponsesTextConfig | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { format: { type: 'json_object' } };\n }\n\n const schema = requireJsonSchema(options);\n const format: IOpenAIResponsesTextFormatJsonSchema = {\n type: 'json_schema',\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n return { format };\n}\n\nfunction requireJsonSchema(input: IOpenAIProviderOptions): {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n} {\n const schema = input.jsonSchema;\n if (input.responseFormat !== 'json_schema') {\n throw new Error(`Unsupported OpenAI response format: ${input.responseFormat}`);\n }\n if (!schema?.schema) {\n throw new Error('OpenAI jsonSchema.schema is required when responseFormat is json_schema');\n }\n return {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n}\n","import type { TUniversalMessage } from '@robota-sdk/agent-core';\n\n/** The subset of the OpenAI SDK's `APIPromise` this module depends on. */\ninterface IWithResponseCapable<T> {\n withResponse?: () => Promise<{ data: T; request_id?: string | null }>;\n}\n\n/**\n * Await an OpenAI `create()` call, reading the server's own request ID off `.withResponse()` when\n * the client exposes it. A test double or older client that resolves to a plain value has no\n * `withResponse`, so this falls back to the awaited value with no ID — never a fabricated one.\n */\nexport async function awaitWithProviderRequestId<T>(\n call: PromiseLike<T> & IWithResponseCapable<T>,\n): Promise<{ data: T; providerRequestId?: string }> {\n if (typeof call.withResponse === 'function') {\n const { data, request_id } = await call.withResponse();\n return {\n data,\n ...(typeof request_id === 'string' && request_id.length > 0 && { providerRequestId: request_id }),\n };\n }\n return { data: await call };\n}\n\n/** The non-stream response shape the SDK attaches its own request ID to directly. */\nexport function readOpenAIRequestId(response: unknown): string | undefined {\n const id = (response as { _request_id?: string | null } | null | undefined)?._request_id;\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n}\n\n/** Merge a provider-returned request ID into a message's metadata; a no-op when there isn't one. */\nexport function withProviderRequestId<T extends TUniversalMessage>(\n message: T,\n providerRequestId: string | undefined,\n): T {\n if (providerRequestId === undefined) return message;\n return { ...message, metadata: { ...message.metadata, providerRequestId } };\n}\n","import type OpenAI from 'openai';\n\n/**\n * Per-request SDK options, or none at all when there is neither a signal nor a header to send, so\n * a call without either keeps the exact shape it always had.\n */\nexport function openAIRequestOptions(\n signal: AbortSignal | undefined,\n headers: Readonly<Record<string, string>> | undefined,\n): OpenAI.RequestOptions | undefined {\n const hasHeaders = headers !== undefined && Object.keys(headers).length > 0;\n if (!signal && !hasHeaders) return undefined;\n return { ...(signal ? { signal } : {}), ...(hasHeaders ? { headers: { ...headers } } : {}) };\n}\n","import { toProviderError } from '@robota-sdk/agent-core';\nimport {\n observeProviderNativeRawPayloadStream,\n toOpenAICompatibleToolChoice,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { convertToOpenAIMessages, convertToOpenAITools } from './message-converter';\nimport { buildOpenAIChatResponseFormat, mergeChatResponseFormat } from './openai-request-format';\nimport {\n awaitWithProviderRequestId,\n readOpenAIRequestId,\n withProviderRequestId,\n} from './request-id';\nimport { openAIRequestOptions } from './request-options';\nimport { assembleOpenAIStream } from './streaming/stream-assembler';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { OpenAIResponseParser } from './parsers/response-parser';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IOpenAILogData } from './types/api-types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIChatCompletionsOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n payloadLogger?: IPayloadLogger;\n responseParser: OpenAIResponseParser;\n onTextDelta?: TTextDeltaCallback;\n /** Per-request headers (trusted `traceparent`), sent after the raw request payload is captured. */\n requestHeaders?: Readonly<Record<string, string>>;\n}\n\nexport async function chatWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): Promise<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams = buildChatRequestParams(input);\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return await chatWithStreamingAssembly(client, input, {\n ...requestParams,\n stream: true,\n ...buildStreamOptions(input),\n });\n }\n\n await logPayload(input, requestParams, 'chat');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const requestOptions = openAIRequestOptions(undefined, input.requestHeaders);\n const response = requestOptions\n ? await client.chat.completions.create(requestParams, requestOptions)\n : await client.chat.completions.create(requestParams);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return withProviderRequestId(\n input.responseParser.parseResponse(response),\n readOpenAIRequestId(response),\n );\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI chat failed');\n }\n}\n\nexport async function* chatStreamWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): AsyncIterable<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n ...buildChatRequestParams(input),\n stream: true,\n ...buildStreamOptions(input),\n };\n\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n client.chat.completions.create(\n requestParams,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n\n for await (const chunk of observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n })) {\n const universalMessage = input.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield withProviderRequestId(universalMessage, providerRequestId);\n }\n }\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI stream failed');\n }\n}\n\n/**\n * Streaming requests opt into token usage via `stream_options: { include_usage: true }`\n * unless the provider sets `includeStreamUsage: false`. Only ever sent on streaming requests.\n */\nfunction buildStreamOptions(\n input: IOpenAIChatCompletionsOptions,\n): { stream_options: { include_usage: true } } | Record<string, never> {\n if (input.providerOptions.includeStreamUsage === false) {\n return {};\n }\n return { stream_options: { include_usage: true } };\n}\n\nfunction buildChatRequestParams(\n input: IOpenAIChatCompletionsOptions,\n): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const openaiMessages = convertToOpenAIMessages(input.messages);\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const responseFormat = buildOpenAIChatResponseFormat(\n mergeChatResponseFormat(input.providerOptions, input.chatOptions?.responseFormat),\n );\n return {\n model,\n messages: openaiMessages,\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && { max_tokens: input.chatOptions.maxTokens }),\n ...(input.chatOptions?.tools && {\n tools: convertToOpenAITools(input.chatOptions.tools),\n tool_choice: toOpenAICompatibleToolChoice(input.chatOptions.toolChoice),\n }),\n ...(responseFormat !== undefined && { response_format: responseFormat }),\n } as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n}\n\nasync function chatWithStreamingAssembly(\n client: OpenAI,\n input: IOpenAIChatCompletionsOptions,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n): Promise<TUniversalMessage> {\n try {\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n client.chat.completions.create(\n requestParams,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n\n const assembled = await assembleOpenAIStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n }),\n onTextDelta: input.chatOptions?.onTextDelta ?? input.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n return withProviderRequestId(assembled, providerRequestId);\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI stream failed');\n }\n}\n\nasync function logPayload(\n input: IOpenAIChatCompletionsOptions,\n requestParams:\n | OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n | OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n type: 'chat' | 'stream',\n): Promise<void> {\n if (!input.payloadLogger?.isEnabled()) {\n return;\n }\n\n const logData: IOpenAILogData = {\n model: requestParams.model,\n messagesCount: requestParams.messages.length,\n hasTools: !!requestParams.tools,\n temperature: requestParams.temperature ?? undefined,\n maxTokens: requestParams.max_tokens ?? undefined,\n timestamp: new Date().toISOString(),\n };\n await input.payloadLogger.logPayload(logData, type);\n}\n\nfunction requireClient(client: OpenAI | undefined): OpenAI {\n if (!client) {\n throw new Error(\n 'OpenAI client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n return client;\n}\n","import type { IProviderModelEffortTable } from '@robota-sdk/agent-core';\n\n/**\n * Exact model facts verified against OpenAI's Responses reference on 2026-09-11.\n *\n * The adapter deliberately declares no prefix or vendor-wide fallback. A different model id must\n * remain `not-applied` until its documented controls and default are added here.\n */\nexport const OPENAI_MODEL_EFFORT_TABLE: IProviderModelEffortTable = {\n verifiedAt: '2026-09-11',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/responses',\n models: {\n 'gpt-5.1': {\n supportedEfforts: ['none', 'low', 'medium', 'high'],\n defaultEffort: 'none',\n nativeControlId: 'responses.reasoning.effort',\n },\n },\n};\n","import { OpenAICompatibleResponseParser } from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport type { ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI response parser compatibility wrapper.\n *\n * The implementation delegates to the shared OpenAI-compatible parser while\n * preserving the OpenAI-branded error messages that are part of this package's\n * current test contract.\n */\nexport class OpenAIResponseParser {\n private readonly parser: OpenAICompatibleResponseParser;\n\n constructor(logger?: ILogger) {\n this.parser = new OpenAICompatibleResponseParser({ logger });\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n return this.parser.parseResponse(response);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI response parsing failed',\n );\n throw new Error(`OpenAI response parsing failed: ${message}`);\n }\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n return this.parser.parseStreamingChunk(chunk);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI chunk parsing failed',\n );\n throw new Error(`OpenAI chunk parsing failed: ${message}`);\n }\n }\n}\n\nfunction normalizeParserMessage(message: string): string {\n return message\n .replace(/^OpenAI-compatible response parsing failed: /, '')\n .replace(/^OpenAI-compatible chunk parsing failed: /, '')\n .replace('OpenAI-compatible response', 'OpenAI response');\n}\n","import type { IOpenAIResponsesReasoningOptions } from './types';\nimport type { IModelEffortResolution, TModelEffort } from '@robota-sdk/agent-core';\n\n/**\n * Map the framework's per-call reasoning-effort dial onto the OpenAI Responses API\n * `reasoning.effort` parameter.\n *\n * Per-model support and downward clamping are resolved by the Core table before this boundary.\n * This function only serializes the verified concrete value, without reinterpreting it.\n */\nexport function mapEffortToOpenAIReasoningEffort(\n effort: TModelEffort,\n): IOpenAIResponsesReasoningOptions['effort'] {\n return effort;\n}\n\n/**\n * Merge the per-call effort dial into the provider's static reasoning options.\n *\n * A verified concrete resolution takes precedence over static native control; a conflicting static\n * control is rejected rather than silently overwritten. `auto` and `not-applied` resolutions leave\n * the provider default untouched and never manufacture a native effort field.\n */\nexport function resolveOpenAIReasoningOptions(\n staticReasoning: IOpenAIResponsesReasoningOptions | undefined,\n resolution: IModelEffortResolution | undefined,\n): IOpenAIResponsesReasoningOptions | undefined {\n if (resolution === undefined) {\n return staticReasoning;\n }\n if (resolution.effective === null || resolution.disposition === 'model-default') {\n if (staticReasoning?.effort !== undefined) {\n throw new Error(\n `Static reasoning.effort ${staticReasoning.effort} conflicts with ${resolution.disposition === 'model-default' ? 'provider-default selection' : 'an effort resolution that does not apply a native control'}.`,\n );\n }\n return staticReasoning;\n }\n const effort = mapEffortToOpenAIReasoningEffort(resolution.effective);\n if (staticReasoning?.effort !== undefined && staticReasoning.effort !== effort) {\n throw new Error(\n `Resolved effort ${effort} conflicts with static reasoning.effort ${staticReasoning.effort}.`,\n );\n }\n return {\n ...staticReasoning,\n effort,\n };\n}\n","import type {\n IOpenAIResponsesFunctionTool,\n IOpenAIResponsesMessageInput,\n TOpenAIResponsesInputContent,\n TOpenAIResponsesInputItem,\n} from './responses-types';\nimport type {\n IAssistantMessage,\n IToolSchema,\n TUniversalMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nexport function convertToOpenAIResponsesInput(\n messages: TUniversalMessage[],\n): TOpenAIResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\n/**\n * MCP-005: `tools` arrives ALREADY projected — `AbstractAIProvider.projectTools()` ran the strict or\n * permissive profile (`STRICT_TOOL_SCHEMA_PROFILE` / `PERMISSIVE_TOOL_SCHEMA_PROFILE`) over every\n * schema before this converter ever sees it, closing objects for strict mode where PROV-007's\n * `closeObjectSchemas` used to run inline here. This function does no schema transformation of its\n * own — it only shapes the already-projected `parameters` into the wire tool definition and keeps\n * `strict: true` on the emitted field when `strictTools` is on (a request-field concern, not a schema\n * one: the schema was already closed by the projection step).\n */\nexport function convertToOpenAIResponsesTools(\n tools: IToolSchema[] | undefined,\n strictTools: boolean | undefined,\n): IOpenAIResponsesFunctionTool[] | undefined {\n const strict = strictTools ?? false;\n const converted =\n tools?.map((tool) => ({\n type: 'function' as const,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n strict,\n })) ?? [];\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction convertMessage(message: TUniversalMessage): TOpenAIResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', getUserContent(message.content, message.parts))];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TOpenAIResponsesInputItem[] {\n const items: TOpenAIResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction getUserContent(\n content: string,\n parts: TUniversalMessagePart[] | undefined,\n): string | TOpenAIResponsesInputContent[] {\n if (!parts || parts.length === 0) {\n return content;\n }\n\n const converted = parts.map((part) => convertPart(part));\n if (content.length > 0 && !parts.some((part) => part.type === 'text')) {\n return [{ type: 'input_text', text: content }, ...converted];\n }\n return converted;\n}\n\nfunction convertPart(part: TUniversalMessagePart): TOpenAIResponsesInputContent {\n if (part.type === 'text') {\n return { type: 'input_text', text: part.text };\n }\n if (part.type === 'image_uri') {\n return { type: 'input_image', image_url: part.uri };\n }\n return {\n type: 'input_image',\n image_url: `data:${part.mimeType};base64,${part.data}`,\n };\n}\n\nfunction createMessageInput(\n role: IOpenAIResponsesMessageInput['role'],\n content: string | TOpenAIResponsesInputContent[],\n): IOpenAIResponsesMessageInput {\n return {\n role,\n content,\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done || signal?.aborted) {\n break;\n }\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) {\n return iterator.next();\n }\n if (signal.aborted) {\n return { done: true, value: undefined as T };\n }\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) {\n signal.removeEventListener('abort', abortListener);\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { streamWithAbort } from './responses-stream-utils';\n\nimport type {\n IOpenAIResponsesErrorEvent,\n IOpenAIResponsesFunctionCallOutputItem,\n IOpenAIResponsesMessageOutputItem,\n IOpenAIResponsesReasoningOutputItem,\n IOpenAIResponsesResponse,\n IOpenAIResponsesUsage,\n TOpenAIResponsesOutputContent,\n TOpenAIResponsesOutputItem,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type { IToolCall, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\n\ninterface IOpenAIResponsesStreamAssemblyOptions {\n stream: AsyncIterable<TOpenAIResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IOpenAIResponsesReasoningMetadata {\n reasoningSummaryCount: number;\n reasoningSummaries: string[];\n hasEncryptedReasoning: boolean;\n}\n\ninterface IOpenAIResponseUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\ninterface IOpenAIResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}\n\nexport function parseOpenAIResponsesResponse(\n response: IOpenAIResponsesResponse,\n): TUniversalMessage {\n assertUsableResponse(response);\n const output = response.output ?? [];\n const content = response.output_text ?? extractMessageText(output);\n return buildAssistantMessage({\n content,\n toolCalls: extractFunctionToolCalls(output),\n response,\n reasoning: collectReasoningMetadata(output),\n });\n}\n\nexport async function assembleOpenAIResponsesStream(\n options: IOpenAIResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IOpenAIResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n reasoning: createEmptyReasoningMetadata(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n reasoning: state.reasoning,\n });\n}\n\nfunction applyStreamEvent(\n state: IOpenAIResponsesStreamState,\n event: TOpenAIResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata(event.response.output ?? []));\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (\n event.type === 'response.error' ||\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n throw new Error(`OpenAI Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction applyOutputItem(\n state: IOpenAIResponsesStreamState,\n item: TOpenAIResponsesOutputItem,\n): void {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n return;\n }\n if (isReasoningOutputItem(item)) {\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata([item]));\n }\n}\n\nfunction buildMessageFromCompletedResponse(state: IOpenAIResponsesStreamState): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('OpenAI Responses stream completed without response metadata');\n }\n\n assertUsableResponse(response);\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const reasoning = collectReasoningMetadata(output);\n mergeReasoningMetadata(reasoning, state.reasoning);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n reasoning,\n });\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && { usage: mapUsage(input.response.usage) }),\n metadata: {\n ...buildMetadata(input.response, input.reasoning),\n ...(input.response?.usage !== undefined && {\n usageProvenance:\n input.response.usage.input_tokens !== undefined &&\n input.response.usage.output_tokens !== undefined &&\n input.response.usage.total_tokens !== undefined\n ? 'complete'\n : 'partial',\n }),\n },\n };\n}\n\nfunction buildMetadata(\n response: IOpenAIResponsesResponse | undefined,\n reasoning: IOpenAIResponsesReasoningMetadata,\n): NonNullable<TUniversalMessage['metadata']> {\n return {\n providerApiSurface: 'responses',\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n ...(reasoning.reasoningSummaryCount > 0 && {\n reasoningSummaryCount: reasoning.reasoningSummaryCount,\n reasoningSummaries: reasoning.reasoningSummaries,\n }),\n ...(reasoning.hasEncryptedReasoning && { hasEncryptedReasoning: true }),\n };\n}\n\nfunction mapUsage(usage: IOpenAIResponsesUsage): IOpenAIResponseUsage {\n return {\n promptTokens: usage.input_tokens ?? 0,\n completionTokens: usage.output_tokens ?? 0,\n totalTokens: usage.total_tokens ?? 0,\n };\n}\n\nfunction extractFunctionToolCalls(output: readonly TOpenAIResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IOpenAIResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TOpenAIResponsesOutputItem[]): string {\n return output\n .filter(isMessageOutputItem)\n .flatMap((item) => item.content)\n .map(extractTextContent)\n .join('');\n}\n\nfunction extractTextContent(content: TOpenAIResponsesOutputContent): string {\n if (content.type === 'refusal') {\n return content.refusal;\n }\n return content.text;\n}\n\nfunction isMessageOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesMessageOutputItem {\n return item.type === 'message' && 'content' in item && Array.isArray(item.content);\n}\n\nfunction collectReasoningMetadata(\n output: readonly TOpenAIResponsesOutputItem[],\n): IOpenAIResponsesReasoningMetadata {\n const metadata = createEmptyReasoningMetadata();\n for (const item of output) {\n if (!isReasoningOutputItem(item)) {\n continue;\n }\n const summaries = item.summary?.map((summary) => summary.text).filter(isString) ?? [];\n metadata.reasoningSummaryCount += summaries.length;\n metadata.reasoningSummaries.push(...summaries);\n metadata.hasEncryptedReasoning = metadata.hasEncryptedReasoning || !!item.encrypted_content;\n }\n return metadata;\n}\n\nfunction isReasoningOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesReasoningOutputItem {\n return item.type === 'reasoning';\n}\n\nfunction createEmptyReasoningMetadata(): IOpenAIResponsesReasoningMetadata {\n return {\n reasoningSummaryCount: 0,\n reasoningSummaries: [],\n hasEncryptedReasoning: false,\n };\n}\n\nfunction mergeReasoningMetadata(\n target: IOpenAIResponsesReasoningMetadata,\n source: IOpenAIResponsesReasoningMetadata,\n): void {\n target.reasoningSummaryCount += source.reasoningSummaryCount;\n target.reasoningSummaries.push(...source.reasoningSummaries);\n target.hasEncryptedReasoning = target.hasEncryptedReasoning || source.hasEncryptedReasoning;\n}\n\nfunction isString(value: string | undefined): value is string {\n return value !== undefined;\n}\n\nfunction assertUsableResponse(response: IOpenAIResponsesResponse): void {\n if (response.status === 'failed' || response.status === 'incomplete') {\n throw new Error(`OpenAI Responses API failed: ${response.error?.message ?? response.status}`);\n }\n}\n\nfunction extractErrorMessage(event: IOpenAIResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { toProviderError } from '@robota-sdk/agent-core';\n\nimport {\n observeProviderNativeRawPayloadStream,\n toOpenAIResponsesToolChoice,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { buildOpenAIResponsesTextConfig } from './openai-request-format';\nimport { resolveOpenAIReasoningOptions } from './reasoning-effort';\nimport {\n awaitWithProviderRequestId,\n readOpenAIRequestId,\n withProviderRequestId,\n} from './request-id';\nimport {\n convertToOpenAIResponsesInput,\n convertToOpenAIResponsesTools,\n} from './responses-converter';\nimport { openAIRequestOptions } from './request-options';\nimport { assembleOpenAIResponsesStream, parseOpenAIResponsesResponse } from './responses-parser';\n\nimport type {\n IOpenAIResponsesRequestNonStreaming,\n IOpenAIResponsesRequestStreaming,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n onTextDelta?: TTextDeltaCallback;\n /** Per-request headers (trusted `traceparent`), sent after the raw request payload is captured. */\n requestHeaders?: Readonly<Record<string, string>>;\n}\n\ninterface IResponsesStreamMessageQueue {\n deltas: TUniversalMessage[];\n finalMessage?: TUniversalMessage;\n error?: Error;\n wake?: () => void;\n}\n\nexport async function chatWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return withProviderRequestId(\n parseOpenAIResponsesResponse(response),\n readOpenAIRequestId(response),\n );\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI responses failed');\n }\n}\n\nexport async function* chatStreamWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const queue: IResponsesStreamMessageQueue = { deltas: [] };\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n const assembly = chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n textDeltaCb?.(delta);\n enqueueStreamDelta(queue, createStreamDeltaMessage(delta));\n },\n },\n })\n .then((result) => finishStreamQueue(queue, result))\n .catch((error) => failStreamQueue(queue, toError(error)));\n\n yield* drainResponsesStreamQueue(queue);\n await assembly;\n}\n\nasync function chatWithOpenAIResponsesStreamingAssembly(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n const assembled = await assembleOpenAIResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TOpenAIResponsesStreamEvent>,\n {\n provider: 'openai',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n return withProviderRequestId(assembled, providerRequestId);\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI responses stream failed');\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const tools = convertToOpenAIResponsesTools(\n input.chatOptions?.tools,\n input.providerOptions.strictTools,\n );\n const textConfig = buildOpenAIResponsesTextConfig(input.providerOptions);\n // Native effort mapping: thread the per-call reasoning-effort dial onto the Responses\n // API `reasoning.effort` parameter, merged with any static reasoning options.\n const reasoning = resolveOpenAIReasoningOptions(\n input.providerOptions.reasoning,\n input.chatOptions?.effortResolution,\n );\n return {\n model,\n input: convertToOpenAIResponsesInput(input.messages),\n ...(tools !== undefined && {\n tools,\n tool_choice: toOpenAIResponsesToolChoice(input.chatOptions?.toolChoice),\n }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(textConfig !== undefined && { text: textConfig }),\n ...(reasoning !== undefined && {\n reasoning,\n }),\n ...(input.providerOptions.includeEncryptedReasoning === true && {\n include: ['reasoning.encrypted_content'],\n }),\n ...(input.providerOptions.store !== undefined && { store: input.providerOptions.store }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n providerApiSurface: 'responses',\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n\nasync function* drainResponsesStreamQueue(\n queue: IResponsesStreamMessageQueue,\n): AsyncIterable<TUniversalMessage> {\n while (true) {\n const next = queue.deltas.shift();\n if (next !== undefined) {\n yield next;\n continue;\n }\n if (queue.error !== undefined) {\n throw queue.error;\n }\n if (queue.finalMessage !== undefined) {\n yield createFinalStreamMessage(queue.finalMessage);\n return;\n }\n await waitForStreamQueue(queue);\n }\n}\n\nfunction enqueueStreamDelta(queue: IResponsesStreamMessageQueue, message: TUniversalMessage): void {\n queue.deltas.push(message);\n wakeStreamQueue(queue);\n}\n\nfunction finishStreamQueue(queue: IResponsesStreamMessageQueue, result: TUniversalMessage): void {\n queue.finalMessage = result;\n wakeStreamQueue(queue);\n}\n\nfunction failStreamQueue(queue: IResponsesStreamMessageQueue, error: Error): void {\n queue.error = error;\n wakeStreamQueue(queue);\n}\n\nfunction waitForStreamQueue(queue: IResponsesStreamMessageQueue): Promise<void> {\n return new Promise((resolve) => {\n queue.wake = resolve;\n });\n}\n\nfunction wakeStreamQueue(queue: IResponsesStreamMessageQueue): void {\n queue.wake?.();\n queue.wake = undefined;\n}\n\nfunction createFinalStreamMessage(result: TUniversalMessage): TUniversalMessage {\n return {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nfunction toError(error: Error | string): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n","import { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport { createModelEffortOutcome } from '@robota-sdk/agent-core';\nimport { PERMISSIVE_TOOL_SCHEMA_PROFILE, STRICT_TOOL_SCHEMA_PROFILE } from '@robota-sdk/agent-core';\nimport { resolveModelEffort } from '@robota-sdk/agent-core';\nimport { SilentLogger } from '@robota-sdk/agent-core';\nimport { traceHeadersFor } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport {\n chatStreamWithOpenAIChatCompletions,\n chatWithOpenAIChatCompletions,\n} from './chat-completions-chat';\nimport { OPENAI_MODEL_EFFORT_TABLE } from './model-effort-table';\nimport { OpenAIResponseParser } from './parsers/response-parser';\nimport { chatStreamWithOpenAIResponsesApi, chatWithOpenAIResponsesApi } from './responses-chat';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { IOpenAIProviderOptions, TOpenAIApiSurface } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IAssistantMessage,\n IProviderCapabilities,\n IProviderModelEffortTable,\n IToolSchemaProjectionProfile,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\n\n/**\n * OpenAI provider implementation for Robota\n *\n * Provides integration with OpenAI models through the Robota provider contract.\n * Uses OpenAI SDK native types internally for optimal performance and feature support.\n *\n * @public\n */\nexport class OpenAIProvider extends AbstractAIProvider {\n override readonly name = 'openai';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IOpenAIProviderOptions;\n private readonly apiSurface: TOpenAIApiSurface;\n private readonly payloadLogger: IPayloadLogger | undefined;\n private readonly responseParser: OpenAIResponseParser;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IOpenAIProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n this.apiSurface = resolveApiSurface(options);\n validateOpenAIProviderNativeWebTools(this.apiSurface, options.nativeWebTools);\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.organization && { organization: options.organization }),\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either OpenAI client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAIResponseParser(this.logger);\n this.payloadLogger = options.payloadLogger;\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n const resolvedOptions = this.resolveEffortOptions(options);\n\n if (this.executor) {\n try {\n const result = await this.executeViaExecutorOrDirect(messages, resolvedOptions);\n if (result.modelEffortOutcome === undefined) {\n this.publishModelEffortOutcome(resolvedOptions, 'opaque-executor');\n }\n return result.message;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n const response = await chatWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return response;\n }\n\n const response = await chatWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return response;\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateNativeWebTools(options?.nativeWebTools);\n const resolvedOptions = this.resolveEffortOptions(options);\n\n if (this.executor) {\n try {\n let executorOutcomeSeen = false;\n for await (const event of this.executeStreamViaExecutorOrDirect(\n messages,\n resolvedOptions,\n )) {\n if (event.kind === 'message') {\n yield event.message;\n } else {\n executorOutcomeSeen = event.modelEffortOutcome !== undefined;\n }\n }\n if (!executorOutcomeSeen) {\n this.publishModelEffortOutcome(resolvedOptions, 'opaque-executor');\n }\n return;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n yield* this.streamDirect(messages, resolvedOptions);\n }\n\n private async *streamDirect(\n messages: TUniversalMessage[],\n resolvedOptions: IChatOptions | undefined,\n ): AsyncIterable<TUniversalMessage> {\n if (this.apiSurface === 'responses') {\n yield* chatStreamWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return;\n }\n\n yield* chatStreamWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n }\n\n /**\n * CORE-043: this provider declares no capability table — nobody has verified one for OpenAI, and\n * inventing one would be a fabricated claim. It can still answer THIS question honestly, which is\n * why the endpoint signal is not a field on the table.\n *\n * It matters most here of all the providers: setting `baseURL` also switches the API surface to\n * `chat-completions` (see `resolveApiSurface`), so the advertised gateway configuration is exactly\n * the one where a structured request is least likely to be enforced by whatever is on the far end.\n */\n endpointIsVendorDefault(): boolean {\n return this.options.baseURL === undefined;\n }\n\n /**\n * The client's own base URL is the origin every request goes to (the SDK has already applied a\n * constructor option or `OPENAI_BASE_URL`). An executor sends elsewhere, and an injected client\n * whose base URL cannot be read gives no origin to compare, so neither can propagate.\n */\n canPropagateTraceContext(): boolean {\n return !this.executor && this.effectiveBaseUrl() !== undefined;\n }\n\n private effectiveBaseUrl(): string | undefined {\n const baseURL: unknown = (this.client as { baseURL?: unknown } | undefined)?.baseURL;\n return typeof baseURL === 'string' && baseURL.length > 0 ? baseURL : undefined;\n }\n\n private traceRequestHeaders(options: IChatOptions | undefined): Readonly<Record<string, string>> {\n if (!this.canPropagateTraceContext()) return {};\n return traceHeadersFor(this.effectiveBaseUrl(), options?.outboundTraceContext);\n }\n\n override effortTable(): IProviderModelEffortTable | undefined {\n return this.endpointIsVendorDefault() && this.apiSurface === 'responses'\n ? OPENAI_MODEL_EFFORT_TABLE\n : undefined;\n }\n\n private resolveEffortOptions(options: IChatOptions | undefined): IChatOptions | undefined {\n if (options?.effort === undefined || options.effortResolution !== undefined) return options;\n const model = options.model ?? this.options.defaultModel;\n if (model === undefined) return options;\n return {\n ...options,\n effortResolution: resolveModelEffort(this.effortTable(), model, options.effort),\n };\n }\n\n /**\n * MCP-005: strict mode's supported subset is documented; non-strict accepts standard JSON Schema.\n * Both the Responses and Chat Completions surfaces honor `strictTools` identically (§ Profiles).\n */\n protected override projectionProfile(): IToolSchemaProjectionProfile | undefined {\n return this.options.strictTools\n ? { ...STRICT_TOOL_SCHEMA_PROFILE, providerName: 'openai' }\n : { ...PERMISSIVE_TOOL_SCHEMA_PROFILE, providerName: 'openai' };\n }\n\n /**\n * Project `chatOptions.tools` through `projectionProfile()` before either request-building module\n * (`responses-chat.ts`, `chat-completions-chat.ts`) sees them — the module helpers receive the\n * projected array as a parameter; `options.tools` itself is never mutated. An empty projected array\n * (every tool quarantined) becomes `undefined` so the downstream `tools &&` truthiness checks treat\n * it the same as \"no tools\", not as a zero-length `tools: []` request field.\n */\n private projectChatOptions(chatOptions: IChatOptions | undefined): IChatOptions | undefined {\n if (!chatOptions?.tools) {\n return chatOptions;\n }\n const model = chatOptions.model ?? this.options.defaultModel ?? '';\n const projected = this.projectTools(chatOptions.tools, model);\n return {\n ...chatOptions,\n tools: projected && projected.length > 0 ? projected : undefined,\n };\n }\n\n private publishModelEffortOutcome(\n options: IChatOptions | undefined,\n opaqueReason?: string,\n ): void {\n const resolution = options?.effortResolution;\n const observer = options?.onModelEffortOutcome;\n if (resolution === undefined || observer === undefined) return;\n\n const nativeControl =\n opaqueReason !== undefined\n ? { state: 'omitted' as const, reason: opaqueReason }\n : resolution.effective !== null && resolution.disposition !== 'model-default'\n ? { state: 'sent' as const, id: 'responses.reasoning.effort' }\n : {\n state: 'omitted' as const,\n reason:\n resolution.disposition === 'model-default'\n ? 'provider-default-selection'\n : 'model-effort-not-applied',\n };\n const providerDispatch =\n opaqueReason !== undefined\n ? { state: 'not-dispatched' as const, reason: opaqueReason }\n : { state: 'sent' as const };\n try {\n observer(createModelEffortOutcome(resolution, { nativeControl, providerDispatch }));\n } catch (error) {\n this.logger.warn('Model-effort outcome observer failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n const source =\n this.apiSurface === 'chat-completions'\n ? 'openai-compatible-chat-completions'\n : 'openai-responses';\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'search'),\n },\n webFetch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'fetch'),\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI client doesn't need explicit cleanup\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n}\n\nfunction resolveApiSurface(options: IOpenAIProviderOptions): TOpenAIApiSurface {\n if (options.apiSurface !== undefined) {\n return options.apiSurface;\n }\n return options.baseURL ? 'chat-completions' : 'responses';\n}\n\nfunction getOpenAIUnsupportedNativeWebReason(\n apiSurface: TOpenAIApiSurface,\n toolKind: 'search' | 'fetch',\n): string {\n if (apiSurface === 'chat-completions') {\n return `OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${toolKind}.`;\n }\n return `OpenAI Responses native web ${toolKind} is not wired in this Robota provider version.`;\n}\n\nfunction validateOpenAIProviderNativeWebTools(\n apiSurface: TOpenAIApiSurface,\n nativeWebTools: IOpenAIProviderOptions['nativeWebTools'],\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n throw new Error(\n `Provider openai native web search/fetch is not supported for apiSurface ${apiSurface} in this Robota provider version.`,\n );\n}\n","import type { TUniversalMessage, IAssistantMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI Conversation Adapter\n *\n * Converts between TUniversalMessage format and OpenAI native types.\n * Provides bidirectional conversion for seamless integration.\n *\n * @public\n */\nexport class OpenAIConversationAdapter {\n /**\n * Filter messages for OpenAI compatibility\n *\n * OpenAI has specific requirements:\n * - Tool messages must have valid toolCallId\n * - Messages must be in proper sequence\n * - Tool messages without toolCallId should be excluded\n */\n static filterMessagesForOpenAI(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages.filter((msg) => {\n // Always include user, assistant, and system messages\n if (msg.role === 'user' || msg.role === 'assistant' || msg.role === 'system') {\n return true;\n }\n\n // For tool messages, only include if they have a valid toolCallId\n if (msg.role === 'tool') {\n // Must have toolCallId and it must not be empty or 'unknown'\n return !!(msg.toolCallId && msg.toolCallId.trim() !== '' && msg.toolCallId !== 'unknown');\n }\n\n return false;\n });\n }\n\n /**\n * Convert TUniversalMessage array to OpenAI message format\n * Now properly handles tool messages for OpenAI's tool calling feature\n */\n static toOpenAIFormat(messages: TUniversalMessage[]): OpenAI.Chat.ChatCompletionMessageParam[] {\n // First filter messages for OpenAI compatibility\n const filteredMessages = this.filterMessagesForOpenAI(messages);\n return filteredMessages.map((msg) => this.convertMessage(msg));\n }\n\n /**\n * Convert a single TUniversalMessage to OpenAI format\n * Handles all message types including tool messages\n */\n static convertMessage(msg: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n const messageRole = msg.role;\n\n if (messageRole === 'user') {\n return {\n role: 'user',\n content: msg.content,\n };\n }\n\n if (messageRole === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Handle tool_calls format\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const result: OpenAI.Chat.ChatCompletionAssistantMessageParam = {\n role: 'assistant',\n // CRITICAL: OpenAI API requires content to be null (not empty string) when tool_calls are present\n // VERIFIED: 2024-12 - This prevents \"400 Bad Request\" errors from OpenAI API\n // DO NOT CHANGE without testing against actual OpenAI API\n content: assistantMsg.content === '' ? null : assistantMsg.content || null,\n tool_calls: assistantMsg.toolCalls.map((toolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n return result;\n }\n\n // Regular assistant message (without tool calls)\n // VERIFIED: OpenAI accepts both null and string content for regular messages\n // We preserve null when content is null or empty string for API consistency\n return {\n role: 'assistant',\n content:\n assistantMsg.content === null\n ? null\n : assistantMsg.content === ''\n ? null\n : assistantMsg.content || '',\n };\n }\n\n if (messageRole === 'system') {\n return {\n role: 'system',\n content: msg.content,\n };\n }\n\n // Handle tool messages for OpenAI tool calling\n if (messageRole === 'tool') {\n if (!msg.toolCallId || msg.toolCallId.trim() === '') {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(msg)}`);\n }\n\n const result: OpenAI.Chat.ChatCompletionToolMessageParam = {\n role: 'tool',\n content: msg.content,\n tool_call_id: msg.toolCallId,\n };\n return result;\n }\n\n const exhaustive: never = messageRole;\n throw new Error(`Unsupported message role: ${exhaustive}`);\n }\n\n /**\n * Add system prompt to message array if needed\n */\n static addSystemPromptIfNeeded(\n messages: OpenAI.Chat.ChatCompletionMessageParam[],\n systemPrompt?: string,\n ): OpenAI.Chat.ChatCompletionMessageParam[] {\n if (!systemPrompt) {\n return messages;\n }\n\n // Check if system message already exists\n const hasSystemMessage = messages.some((msg) => msg.role === 'system');\n\n if (hasSystemMessage) {\n return messages;\n }\n\n // Add system prompt at the beginning\n return [{ role: 'system', content: systemPrompt }, ...messages];\n }\n}\n","import { probeOpenAICompatibleProfile } from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { OpenAIProvider } from './provider';\n\nimport type { IOpenAINativeWebToolsOptions, TOpenAIApiSurface } from './types';\nimport type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined = undefined;\nexport const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = '$ENV:OPENAI_API_KEY';\nconst OPENAI_API_KEY_URL = 'https://platform.openai.com/api-keys';\nconst OPENAI_SETUP_SOURCE_URL =\n 'https://developers.openai.com/api/reference/overview#authentication';\nconst OPENAI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst OPENAI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'OpenAI API keys',\n url: OPENAI_API_KEY_URL,\n sourceUrl: OPENAI_SETUP_SOURCE_URL,\n lastVerifiedAt: OPENAI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createOpenAIProviderDefinition(): IProviderDefinition {\n return {\n type: 'openai',\n displayName: 'OpenAI',\n description: 'GPT series — general-purpose assistant. API key required.',\n category: 'cloud-paid',\n // Interim provider-level cost (ARCH-PROVIDER-003), migrated from the former llm-text-openai node.\n costPerTokenUsd: 0.001,\n defaults: {\n apiKey: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n },\n // OBSERVABILITY-1991: the SDK embeds this endpoint; declared here for the pre-session doctor only.\n endpoint: { host: 'api.openai.com', port: 443 },\n modelCatalog: {\n status: 'unavailable',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n message: 'OpenAI model availability should be discovered live from GET /v1/models.',\n },\n setupHelpLinks: OPENAI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'OpenAI model',\n required: true,\n },\n {\n key: 'apiKey',\n title: 'OpenAI API key',\n defaultValue: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n // The OpenAI SDK falls back to the base URL variable when none is configured, and sends the\n // organization and project the others name.\n destinationEnvironment: ['OPENAI_BASE_URL', 'OPENAI_ORG_ID', 'OPENAI_PROJECT_ID'],\n createProvider: (config) => {\n const apiSurface = readApiSurface(config.options);\n const nativeWebTools = readNativeWebTools(config.options);\n validateOpenAINativeWebTools(config.baseURL, apiSurface, nativeWebTools);\n return new OpenAIProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(apiSurface !== undefined && { apiSurface }),\n ...(nativeWebTools !== undefined && { nativeWebTools }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider openai requires apiKey');\n }\n return apiKey;\n}\n\nfunction readApiSurface(\n options: Record<string, TUniversalValue> | undefined,\n): TOpenAIApiSurface | undefined {\n const apiSurface = options?.['apiSurface'];\n if (apiSurface === 'responses' || apiSurface === 'chat-completions') {\n return apiSurface;\n }\n return undefined;\n}\n\nfunction readNativeWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n const nativeWebTools =\n readNativeWebToolsRecord(options?.['nativeWebTools']) ??\n readNativeWebToolsRecord(options?.['builtInWebTools']);\n if (nativeWebTools === undefined) {\n return undefined;\n }\n return nativeWebTools;\n}\n\nfunction readNativeWebToolsRecord(\n value: TUniversalValue | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n if (typeof value !== 'object') {\n return undefined;\n }\n const webSearch = value['webSearch'];\n const webFetch = value['webFetch'];\n return {\n ...(typeof webSearch === 'boolean' && { webSearch }),\n ...(typeof webFetch === 'boolean' && { webFetch }),\n };\n}\n\nfunction validateOpenAINativeWebTools(\n baseURL: string | undefined,\n apiSurface: TOpenAIApiSurface | undefined,\n nativeWebTools: IOpenAINativeWebToolsOptions | undefined,\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n if (baseURL !== undefined || apiSurface === 'chat-completions') {\n throw new Error(\n 'Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n }\n throw new Error(\n 'Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["assembleOpenAIStream","exhaustive"],"sources":["../../src/openai/message-converter.ts","../../src/openai/openai-request-format.ts","../../src/openai/request-id.ts","../../src/openai/request-options.ts","../../src/openai/chat-completions-chat.ts","../../src/openai/model-effort-table.ts","../../src/openai/parsers/response-parser.ts","../../src/openai/reasoning-effort.ts","../../src/openai/responses-converter.ts","../../src/openai/responses-stream-utils.ts","../../src/openai/responses-parser.ts","../../src/openai/responses-chat.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"sourcesContent":["import {\n convertToOpenAICompatibleMessages,\n convertToOpenAICompatibleTools,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport type { IToolSchema, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * Convert TUniversalMessage array to OpenAI chat completion message format.\n */\nexport function convertToOpenAIMessages(\n messages: TUniversalMessage[],\n): OpenAI.Chat.ChatCompletionMessageParam[] {\n return convertToOpenAICompatibleMessages(messages);\n}\n\n/**\n * Convert tool schemas to OpenAI function tool format. With `strictTools` each function is declared\n * `strict: true`, as the Responses surface does, so strict mode is requested on both surfaces.\n */\nexport function convertToOpenAITools(\n tools: IToolSchema[],\n strictTools?: boolean,\n): OpenAI.Chat.ChatCompletionTool[] {\n return convertToOpenAICompatibleTools(tools, { strict: strictTools === true });\n}\n","import type {\n IOpenAIResponsesTextConfig,\n IOpenAIResponsesTextFormatJsonSchema,\n} from './responses-types';\nimport type { IOpenAIProviderOptions, TOpenAIProviderOptionValue } from './types';\nimport type { IChatOptions } from '@robota-sdk/agent-core';\n\nexport interface IOpenAIChatTextFormatText {\n type: 'text';\n}\n\nexport interface IOpenAIChatTextFormatJsonObject {\n type: 'json_object';\n}\n\nexport interface IOpenAIChatTextFormatJsonSchema {\n type: 'json_schema';\n json_schema: {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n };\n}\n\nexport type TOpenAIChatResponseFormat =\n IOpenAIChatTextFormatText | IOpenAIChatTextFormatJsonObject | IOpenAIChatTextFormatJsonSchema;\n\n/**\n * Merge a per-call `IChatOptions.responseFormat` onto the provider options (CORE-015).\n * A `json_schema` chat option carries its schema payload into `jsonSchema`; the\n * provider-level `jsonSchema` option remains as-is for `text`/`json_object`.\n */\nexport function mergeChatResponseFormat(\n providerOptions: IOpenAIProviderOptions,\n responseFormat: IChatOptions['responseFormat'],\n): IOpenAIProviderOptions {\n if (responseFormat?.type === undefined) {\n return providerOptions;\n }\n if (responseFormat.type === 'json_schema') {\n return {\n ...providerOptions,\n responseFormat: 'json_schema',\n jsonSchema: {\n name: responseFormat.name ?? 'structured_output',\n schema: responseFormat.schema as Record<string, TOpenAIProviderOptionValue>,\n },\n };\n }\n return { ...providerOptions, responseFormat: responseFormat.type };\n}\n\nexport function buildOpenAIChatResponseFormat(\n options: IOpenAIProviderOptions,\n): TOpenAIChatResponseFormat | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { type: 'json_object' };\n }\n\n const schema = requireJsonSchema(options);\n return {\n type: 'json_schema',\n json_schema: {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n },\n };\n}\n\nexport function buildOpenAIResponsesTextConfig(\n options: IOpenAIProviderOptions,\n): IOpenAIResponsesTextConfig | undefined {\n if (options.responseFormat === undefined || options.responseFormat === 'text') {\n return undefined;\n }\n if (options.responseFormat === 'json_object') {\n return { format: { type: 'json_object' } };\n }\n\n const schema = requireJsonSchema(options);\n const format: IOpenAIResponsesTextFormatJsonSchema = {\n type: 'json_schema',\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n return { format };\n}\n\nfunction requireJsonSchema(input: IOpenAIProviderOptions): {\n name: string;\n schema: Record<string, TOpenAIProviderOptionValue>;\n description?: string;\n strict?: boolean;\n} {\n const schema = input.jsonSchema;\n if (input.responseFormat !== 'json_schema') {\n throw new Error(`Unsupported OpenAI response format: ${input.responseFormat}`);\n }\n if (!schema?.schema) {\n throw new Error('OpenAI jsonSchema.schema is required when responseFormat is json_schema');\n }\n return {\n name: schema.name,\n schema: schema.schema,\n ...(schema.description !== undefined && { description: schema.description }),\n ...(schema.strict !== undefined && { strict: schema.strict }),\n };\n}\n","import type { TUniversalMessage } from '@robota-sdk/agent-core';\n\n/** The subset of the OpenAI SDK's `APIPromise` this module depends on. */\ninterface IWithResponseCapable<T> {\n withResponse?: () => Promise<{ data: T; request_id?: string | null }>;\n}\n\n/**\n * Await an OpenAI `create()` call, reading the server's own request ID off `.withResponse()` when\n * the client exposes it. A test double or older client that resolves to a plain value has no\n * `withResponse`, so this falls back to the awaited value with no ID — never a fabricated one.\n */\nexport async function awaitWithProviderRequestId<T>(\n call: PromiseLike<T> & IWithResponseCapable<T>,\n): Promise<{ data: T; providerRequestId?: string }> {\n if (typeof call.withResponse === 'function') {\n const { data, request_id } = await call.withResponse();\n return {\n data,\n ...(typeof request_id === 'string' && request_id.length > 0 && { providerRequestId: request_id }),\n };\n }\n return { data: await call };\n}\n\n/** The non-stream response shape the SDK attaches its own request ID to directly. */\nexport function readOpenAIRequestId(response: unknown): string | undefined {\n const id = (response as { _request_id?: string | null } | null | undefined)?._request_id;\n return typeof id === 'string' && id.length > 0 ? id : undefined;\n}\n\n/** Merge a provider-returned request ID into a message's metadata; a no-op when there isn't one. */\nexport function withProviderRequestId<T extends TUniversalMessage>(\n message: T,\n providerRequestId: string | undefined,\n): T {\n if (providerRequestId === undefined) return message;\n return { ...message, metadata: { ...message.metadata, providerRequestId } };\n}\n","import type OpenAI from 'openai';\n\n/**\n * Per-request SDK options, or none at all when there is neither a signal nor a header to send, so\n * a call without either keeps the exact shape it always had.\n */\nexport function openAIRequestOptions(\n signal: AbortSignal | undefined,\n headers: Readonly<Record<string, string>> | undefined,\n): OpenAI.RequestOptions | undefined {\n const hasHeaders = headers !== undefined && Object.keys(headers).length > 0;\n if (!signal && !hasHeaders) return undefined;\n return { ...(signal ? { signal } : {}), ...(hasHeaders ? { headers: { ...headers } } : {}) };\n}\n","import { toProviderError } from '@robota-sdk/agent-core';\nimport {\n observeProviderNativeRawPayloadStream,\n toOpenAICompatibleToolChoice,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { convertToOpenAIMessages, convertToOpenAITools } from './message-converter';\nimport { buildOpenAIChatResponseFormat, mergeChatResponseFormat } from './openai-request-format';\nimport {\n awaitWithProviderRequestId,\n readOpenAIRequestId,\n withProviderRequestId,\n} from './request-id';\nimport { openAIRequestOptions } from './request-options';\nimport { assembleOpenAIStream } from './streaming/stream-assembler';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { OpenAIResponseParser } from './parsers/response-parser';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IOpenAILogData } from './types/api-types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIChatCompletionsOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n payloadLogger?: IPayloadLogger;\n responseParser: OpenAIResponseParser;\n onTextDelta?: TTextDeltaCallback;\n /** Per-request headers (trusted `traceparent`), sent after the raw request payload is captured. */\n requestHeaders?: Readonly<Record<string, string>>;\n}\n\nexport async function chatWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): Promise<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams = buildChatRequestParams(input);\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return await chatWithStreamingAssembly(client, input, {\n ...requestParams,\n stream: true,\n ...buildStreamOptions(input),\n });\n }\n\n await logPayload(input, requestParams, 'chat');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const requestOptions = openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders);\n const response = requestOptions\n ? await client.chat.completions.create(requestParams, requestOptions)\n : await client.chat.completions.create(requestParams);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'response',\n payload: response,\n });\n return withProviderRequestId(\n input.responseParser.parseResponse(response),\n readOpenAIRequestId(response),\n );\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI chat failed');\n }\n}\n\nexport async function* chatStreamWithOpenAIChatCompletions(\n input: IOpenAIChatCompletionsOptions,\n): AsyncIterable<TUniversalMessage> {\n const client = requireClient(input.client);\n\n try {\n const requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n ...buildChatRequestParams(input),\n stream: true,\n ...buildStreamOptions(input),\n };\n\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n client.chat.completions.create(\n requestParams,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n\n for await (const chunk of observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n })) {\n const universalMessage = input.responseParser.parseStreamingChunk(chunk);\n if (universalMessage) {\n yield withProviderRequestId(universalMessage, providerRequestId);\n }\n }\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI stream failed');\n }\n}\n\n/**\n * Streaming requests opt into token usage via `stream_options: { include_usage: true }`\n * unless the provider sets `includeStreamUsage: false`. Only ever sent on streaming requests.\n */\nfunction buildStreamOptions(\n input: IOpenAIChatCompletionsOptions,\n): { stream_options: { include_usage: true } } | Record<string, never> {\n if (input.providerOptions.includeStreamUsage === false) {\n return {};\n }\n return { stream_options: { include_usage: true } };\n}\n\nfunction buildChatRequestParams(\n input: IOpenAIChatCompletionsOptions,\n): OpenAI.Chat.ChatCompletionCreateParamsNonStreaming {\n const openaiMessages = convertToOpenAIMessages(input.messages);\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const responseFormat = buildOpenAIChatResponseFormat(\n mergeChatResponseFormat(input.providerOptions, input.chatOptions?.responseFormat),\n );\n return {\n model,\n messages: openaiMessages,\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && { max_tokens: input.chatOptions.maxTokens }),\n ...(input.chatOptions?.tools && {\n tools: convertToOpenAITools(input.chatOptions.tools, input.providerOptions.strictTools),\n tool_choice: toOpenAICompatibleToolChoice(input.chatOptions.toolChoice),\n }),\n ...(responseFormat !== undefined && { response_format: responseFormat }),\n } as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;\n}\n\nasync function chatWithStreamingAssembly(\n client: OpenAI,\n input: IOpenAIChatCompletionsOptions,\n requestParams: OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n): Promise<TUniversalMessage> {\n try {\n await logPayload(input, requestParams, 'stream');\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'chat-completions',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n client.chat.completions.create(\n requestParams,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n\n const assembled = await assembleOpenAIStream({\n stream: observeProviderNativeRawPayloadStream(stream, {\n provider: 'openai',\n apiSurface: 'chat-completions',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n }),\n onTextDelta: input.chatOptions?.onTextDelta ?? input.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n return withProviderRequestId(assembled, providerRequestId);\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI stream failed');\n }\n}\n\nasync function logPayload(\n input: IOpenAIChatCompletionsOptions,\n requestParams:\n | OpenAI.Chat.ChatCompletionCreateParamsNonStreaming\n | OpenAI.Chat.ChatCompletionCreateParamsStreaming,\n type: 'chat' | 'stream',\n): Promise<void> {\n if (!input.payloadLogger?.isEnabled()) {\n return;\n }\n\n const logData: IOpenAILogData = {\n model: requestParams.model,\n messagesCount: requestParams.messages.length,\n hasTools: !!requestParams.tools,\n temperature: requestParams.temperature ?? undefined,\n maxTokens: requestParams.max_tokens ?? undefined,\n timestamp: new Date().toISOString(),\n };\n await input.payloadLogger.logPayload(logData, type);\n}\n\nfunction requireClient(client: OpenAI | undefined): OpenAI {\n if (!client) {\n throw new Error(\n 'OpenAI client not available. Either provide a client/apiKey or use an executor.',\n );\n }\n return client;\n}\n","import type { IProviderModelEffortTable } from '@robota-sdk/agent-core';\n\n/**\n * Exact model facts verified against OpenAI's Responses reference on 2026-09-11.\n *\n * The adapter deliberately declares no prefix or vendor-wide fallback. A different model id must\n * remain `not-applied` until its documented controls and default are added here.\n */\nexport const OPENAI_MODEL_EFFORT_TABLE: IProviderModelEffortTable = {\n verifiedAt: '2026-09-11',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/responses',\n models: {\n 'gpt-5.1': {\n supportedEfforts: ['none', 'low', 'medium', 'high'],\n defaultEffort: 'none',\n nativeControlId: 'responses.reasoning.effort',\n },\n },\n};\n","import { OpenAICompatibleResponseParser } from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport type { ILogger, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI response parser compatibility wrapper.\n *\n * The implementation delegates to the shared OpenAI-compatible parser while\n * preserving the OpenAI-branded error messages that are part of this package's\n * current test contract.\n */\nexport class OpenAIResponseParser {\n private readonly parser: OpenAICompatibleResponseParser;\n\n constructor(logger?: ILogger) {\n this.parser = new OpenAICompatibleResponseParser({ logger });\n }\n\n parseResponse(response: OpenAI.Chat.ChatCompletion): TUniversalMessage {\n try {\n return this.parser.parseResponse(response);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI response parsing failed',\n );\n throw new Error(`OpenAI response parsing failed: ${message}`);\n }\n }\n\n parseStreamingChunk(chunk: OpenAI.Chat.ChatCompletionChunk): TUniversalMessage | null {\n try {\n return this.parser.parseStreamingChunk(chunk);\n } catch (error) {\n const message = normalizeParserMessage(\n error instanceof Error ? error.message : 'OpenAI chunk parsing failed',\n );\n throw new Error(`OpenAI chunk parsing failed: ${message}`);\n }\n }\n}\n\nfunction normalizeParserMessage(message: string): string {\n return message\n .replace(/^OpenAI-compatible response parsing failed: /, '')\n .replace(/^OpenAI-compatible chunk parsing failed: /, '')\n .replace('OpenAI-compatible response', 'OpenAI response');\n}\n","import type { IOpenAIResponsesReasoningOptions } from './types';\nimport type { IModelEffortResolution, TModelEffort } from '@robota-sdk/agent-core';\n\n/**\n * Map the framework's per-call reasoning-effort dial onto the OpenAI Responses API\n * `reasoning.effort` parameter.\n *\n * Per-model support and downward clamping are resolved by the Core table before this boundary.\n * This function only serializes the verified concrete value, without reinterpreting it.\n */\nexport function mapEffortToOpenAIReasoningEffort(\n effort: TModelEffort,\n): IOpenAIResponsesReasoningOptions['effort'] {\n return effort;\n}\n\n/**\n * Merge the per-call effort dial into the provider's static reasoning options.\n *\n * A verified concrete resolution takes precedence over static native control; a conflicting static\n * control is rejected rather than silently overwritten. `auto` and `not-applied` resolutions leave\n * the provider default untouched and never manufacture a native effort field.\n */\nexport function resolveOpenAIReasoningOptions(\n staticReasoning: IOpenAIResponsesReasoningOptions | undefined,\n resolution: IModelEffortResolution | undefined,\n): IOpenAIResponsesReasoningOptions | undefined {\n if (resolution === undefined) {\n return staticReasoning;\n }\n if (resolution.effective === null || resolution.disposition === 'model-default') {\n if (staticReasoning?.effort !== undefined) {\n throw new Error(\n `Static reasoning.effort ${staticReasoning.effort} conflicts with ${resolution.disposition === 'model-default' ? 'provider-default selection' : 'an effort resolution that does not apply a native control'}.`,\n );\n }\n return staticReasoning;\n }\n const effort = mapEffortToOpenAIReasoningEffort(resolution.effective);\n if (staticReasoning?.effort !== undefined && staticReasoning.effort !== effort) {\n throw new Error(\n `Resolved effort ${effort} conflicts with static reasoning.effort ${staticReasoning.effort}.`,\n );\n }\n return {\n ...staticReasoning,\n effort,\n };\n}\n","import type {\n IOpenAIResponsesFunctionTool,\n IOpenAIResponsesMessageInput,\n TOpenAIResponsesInputContent,\n TOpenAIResponsesInputItem,\n} from './responses-types';\nimport type {\n IAssistantMessage,\n IToolSchema,\n TUniversalMessage,\n TUniversalMessagePart,\n} from '@robota-sdk/agent-core';\n\nexport function convertToOpenAIResponsesInput(\n messages: TUniversalMessage[],\n): TOpenAIResponsesInputItem[] {\n return messages.flatMap((message) => convertMessage(message));\n}\n\n/**\n * MCP-005: `tools` arrives ALREADY projected — `AbstractAIProvider.projectTools()` ran the strict or\n * permissive profile (`STRICT_TOOL_SCHEMA_PROFILE` / `PERMISSIVE_TOOL_SCHEMA_PROFILE`) over every\n * schema before this converter ever sees it, closing objects for strict mode where PROV-007's\n * `closeObjectSchemas` used to run inline here. This function does no schema transformation of its\n * own — it only shapes the already-projected `parameters` into the wire tool definition and keeps\n * `strict: true` on the emitted field when `strictTools` is on (a request-field concern, not a schema\n * one: the schema was already closed by the projection step).\n */\nexport function convertToOpenAIResponsesTools(\n tools: IToolSchema[] | undefined,\n strictTools: boolean | undefined,\n): IOpenAIResponsesFunctionTool[] | undefined {\n const strict = strictTools ?? false;\n const converted =\n tools?.map((tool) => ({\n type: 'function' as const,\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n strict,\n })) ?? [];\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction convertMessage(message: TUniversalMessage): TOpenAIResponsesInputItem[] {\n if (message.role === 'user') {\n return [createMessageInput('user', getUserContent(message.content, message.parts))];\n }\n if (message.role === 'system') {\n return [createMessageInput('system', message.content)];\n }\n if (message.role === 'tool') {\n if (!message.toolCallId || message.toolCallId.trim().length === 0) {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(message)}`);\n }\n return [\n {\n type: 'function_call_output',\n call_id: message.toolCallId,\n output: message.content || '',\n },\n ];\n }\n return convertAssistantMessage(message);\n}\n\nfunction convertAssistantMessage(message: IAssistantMessage): TOpenAIResponsesInputItem[] {\n const items: TOpenAIResponsesInputItem[] = [];\n if (message.content && message.content.length > 0) {\n items.push(createMessageInput('assistant', message.content));\n }\n for (const toolCall of message.toolCalls ?? []) {\n items.push({\n type: 'function_call',\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n });\n }\n if (items.length === 0) {\n items.push(createMessageInput('assistant', ''));\n }\n return items;\n}\n\nfunction getUserContent(\n content: string,\n parts: TUniversalMessagePart[] | undefined,\n): string | TOpenAIResponsesInputContent[] {\n if (!parts || parts.length === 0) {\n return content;\n }\n\n const converted = parts.map((part) => convertPart(part));\n if (content.length > 0 && !parts.some((part) => part.type === 'text')) {\n return [{ type: 'input_text', text: content }, ...converted];\n }\n return converted;\n}\n\nfunction convertPart(part: TUniversalMessagePart): TOpenAIResponsesInputContent {\n if (part.type === 'text') {\n return { type: 'input_text', text: part.text };\n }\n if (part.type === 'image_uri') {\n return { type: 'input_image', image_url: part.uri };\n }\n return {\n type: 'input_image',\n image_url: `data:${part.mimeType};base64,${part.data}`,\n };\n}\n\nfunction createMessageInput(\n role: IOpenAIResponsesMessageInput['role'],\n content: string | TOpenAIResponsesInputContent[],\n): IOpenAIResponsesMessageInput {\n return {\n role,\n content,\n };\n}\n","export async function* streamWithAbort<T>(\n source: AsyncIterable<T>,\n signal?: AbortSignal,\n): AsyncGenerator<T> {\n const iterator = source[Symbol.asyncIterator]();\n try {\n while (!signal?.aborted) {\n const item = await nextStreamItem(iterator, signal);\n if (item.done || signal?.aborted) {\n break;\n }\n yield item.value;\n }\n } finally {\n if (signal?.aborted) {\n await iterator.return?.();\n }\n }\n}\n\nasync function nextStreamItem<T>(\n iterator: AsyncIterator<T>,\n signal?: AbortSignal,\n): Promise<IteratorResult<T>> {\n if (!signal) {\n return iterator.next();\n }\n if (signal.aborted) {\n return { done: true, value: undefined as T };\n }\n\n let abortListener: (() => void) | undefined;\n const aborted = new Promise<IteratorResult<T>>((resolve) => {\n abortListener = (): void => resolve({ done: true, value: undefined as T });\n signal.addEventListener('abort', abortListener, { once: true });\n });\n\n try {\n return await Promise.race([iterator.next(), aborted]);\n } finally {\n if (abortListener) {\n signal.removeEventListener('abort', abortListener);\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { streamWithAbort } from './responses-stream-utils';\n\nimport type {\n IOpenAIResponsesErrorEvent,\n IOpenAIResponsesFunctionCallOutputItem,\n IOpenAIResponsesMessageOutputItem,\n IOpenAIResponsesReasoningOutputItem,\n IOpenAIResponsesResponse,\n IOpenAIResponsesUsage,\n TOpenAIResponsesOutputContent,\n TOpenAIResponsesOutputItem,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type {\n IToolCall,\n ITokenUsageWithCacheRead,\n TTextDeltaCallback,\n TUniversalMessage,\n} from '@robota-sdk/agent-core';\n\n/** Message usage; `totalTokens` is absent when the response omitted `total_tokens`. */\ntype TResponsesMessageUsage = Omit<ITokenUsageWithCacheRead, 'totalTokens'> &\n Partial<Pick<ITokenUsageWithCacheRead, 'totalTokens'>>;\n\ninterface IOpenAIResponsesStreamAssemblyOptions {\n stream: AsyncIterable<TOpenAIResponsesStreamEvent>;\n onTextDelta?: TTextDeltaCallback;\n signal?: AbortSignal;\n}\n\ninterface IOpenAIResponsesReasoningMetadata {\n reasoningSummaryCount: number;\n reasoningSummaries: string[];\n hasEncryptedReasoning: boolean;\n}\n\ninterface IOpenAIResponsesStreamState {\n textParts: string[];\n toolCalls: IToolCall[];\n completedResponse?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}\n\nexport function parseOpenAIResponsesResponse(\n response: IOpenAIResponsesResponse,\n): TUniversalMessage {\n assertUsableResponse(response);\n const output = response.output ?? [];\n const content = response.output_text ?? extractMessageText(output);\n return buildAssistantMessage({\n content,\n toolCalls: extractFunctionToolCalls(output),\n response,\n reasoning: collectReasoningMetadata(output),\n });\n}\n\nexport async function assembleOpenAIResponsesStream(\n options: IOpenAIResponsesStreamAssemblyOptions,\n): Promise<TUniversalMessage> {\n const state: IOpenAIResponsesStreamState = {\n textParts: [],\n toolCalls: [],\n reasoning: createEmptyReasoningMetadata(),\n };\n\n for await (const event of streamWithAbort(options.stream, options.signal)) {\n applyStreamEvent(state, event, options.onTextDelta);\n }\n\n if (state.completedResponse !== undefined) {\n return buildMessageFromCompletedResponse(state);\n }\n\n return buildAssistantMessage({\n content: state.textParts.join(''),\n toolCalls: state.toolCalls,\n reasoning: state.reasoning,\n });\n}\n\nfunction applyStreamEvent(\n state: IOpenAIResponsesStreamState,\n event: TOpenAIResponsesStreamEvent,\n onTextDelta: TTextDeltaCallback | undefined,\n): void {\n if (event.type === 'response.output_text.delta') {\n state.textParts.push(event.delta);\n onTextDelta?.(event.delta);\n return;\n }\n\n if (event.type === 'response.completed') {\n state.completedResponse = event.response;\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata(event.response.output ?? []));\n return;\n }\n\n if (event.type === 'response.output_item.done') {\n applyOutputItem(state, event.item);\n return;\n }\n\n if (\n event.type === 'response.error' ||\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n throw new Error(`OpenAI Responses API failed: ${extractErrorMessage(event)}`);\n }\n}\n\nfunction applyOutputItem(\n state: IOpenAIResponsesStreamState,\n item: TOpenAIResponsesOutputItem,\n): void {\n if (isFunctionCallOutputItem(item)) {\n state.toolCalls.push(convertFunctionCall(item));\n return;\n }\n if (isReasoningOutputItem(item)) {\n mergeReasoningMetadata(state.reasoning, collectReasoningMetadata([item]));\n }\n}\n\nfunction buildMessageFromCompletedResponse(state: IOpenAIResponsesStreamState): TUniversalMessage {\n const response = state.completedResponse;\n if (response === undefined) {\n throw new Error('OpenAI Responses stream completed without response metadata');\n }\n\n assertUsableResponse(response);\n const output = response.output ?? [];\n const responseToolCalls = extractFunctionToolCalls(output);\n const content =\n state.textParts.length > 0\n ? state.textParts.join('')\n : (response.output_text ?? extractMessageText(output));\n const reasoning = collectReasoningMetadata(output);\n mergeReasoningMetadata(reasoning, state.reasoning);\n\n return buildAssistantMessage({\n content,\n toolCalls: responseToolCalls.length > 0 ? responseToolCalls : state.toolCalls,\n response,\n reasoning,\n });\n}\n\nfunction buildAssistantMessage(input: {\n content: string;\n toolCalls: IToolCall[];\n response?: IOpenAIResponsesResponse;\n reasoning: IOpenAIResponsesReasoningMetadata;\n}): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: input.content,\n state: 'complete',\n timestamp: new Date(),\n ...(input.toolCalls.length > 0 && { toolCalls: input.toolCalls }),\n ...(input.response?.usage !== undefined && { usage: mapUsage(input.response.usage) }),\n metadata: {\n ...buildMetadata(input.response, input.reasoning),\n ...(input.response?.usage !== undefined && {\n usageProvenance:\n input.response.usage.input_tokens !== undefined &&\n input.response.usage.output_tokens !== undefined &&\n input.response.usage.total_tokens !== undefined\n ? 'complete'\n : 'partial',\n }),\n },\n };\n}\n\nfunction buildMetadata(\n response: IOpenAIResponsesResponse | undefined,\n reasoning: IOpenAIResponsesReasoningMetadata,\n): NonNullable<TUniversalMessage['metadata']> {\n return {\n providerApiSurface: 'responses',\n ...(response?.id !== undefined && { responseId: response.id }),\n ...(response?.model !== undefined && { model: response.model }),\n ...(response?.status !== undefined && { finishReason: response.status }),\n ...(reasoning.reasoningSummaryCount > 0 && {\n reasoningSummaryCount: reasoning.reasoningSummaryCount,\n reasoningSummaries: reasoning.reasoningSummaries,\n }),\n ...(reasoning.hasEncryptedReasoning && { hasEncryptedReasoning: true }),\n };\n}\n\nfunction mapUsage(usage: IOpenAIResponsesUsage): TResponsesMessageUsage {\n const cachedTokens = usage.input_tokens_details?.cached_tokens;\n return {\n promptTokens: usage.input_tokens ?? 0,\n completionTokens: usage.output_tokens ?? 0,\n // An omitted total stays omitted: a 0 reads downstream as a real, empty call.\n ...(usage.total_tokens !== undefined && { totalTokens: usage.total_tokens }),\n ...(typeof cachedTokens === 'number' && { cacheReadTokens: cachedTokens }),\n };\n}\n\nfunction extractFunctionToolCalls(output: readonly TOpenAIResponsesOutputItem[]): IToolCall[] {\n return output.filter(isFunctionCallOutputItem).map((item) => convertFunctionCall(item));\n}\n\nfunction isFunctionCallOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesFunctionCallOutputItem {\n return (\n item.type === 'function_call' && 'call_id' in item && 'name' in item && 'arguments' in item\n );\n}\n\nfunction convertFunctionCall(item: IOpenAIResponsesFunctionCallOutputItem): IToolCall {\n return {\n id: item.call_id,\n type: 'function',\n function: {\n name: item.name,\n arguments: item.arguments,\n },\n };\n}\n\nfunction extractMessageText(output: readonly TOpenAIResponsesOutputItem[]): string {\n return output\n .filter(isMessageOutputItem)\n .flatMap((item) => item.content)\n .map(extractTextContent)\n .join('');\n}\n\nfunction extractTextContent(content: TOpenAIResponsesOutputContent): string {\n if (content.type === 'refusal') {\n return content.refusal;\n }\n return content.text;\n}\n\nfunction isMessageOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesMessageOutputItem {\n return item.type === 'message' && 'content' in item && Array.isArray(item.content);\n}\n\nfunction collectReasoningMetadata(\n output: readonly TOpenAIResponsesOutputItem[],\n): IOpenAIResponsesReasoningMetadata {\n const metadata = createEmptyReasoningMetadata();\n for (const item of output) {\n if (!isReasoningOutputItem(item)) {\n continue;\n }\n const summaries = item.summary?.map((summary) => summary.text).filter(isString) ?? [];\n metadata.reasoningSummaryCount += summaries.length;\n metadata.reasoningSummaries.push(...summaries);\n metadata.hasEncryptedReasoning = metadata.hasEncryptedReasoning || !!item.encrypted_content;\n }\n return metadata;\n}\n\nfunction isReasoningOutputItem(\n item: TOpenAIResponsesOutputItem,\n): item is IOpenAIResponsesReasoningOutputItem {\n return item.type === 'reasoning';\n}\n\nfunction createEmptyReasoningMetadata(): IOpenAIResponsesReasoningMetadata {\n return {\n reasoningSummaryCount: 0,\n reasoningSummaries: [],\n hasEncryptedReasoning: false,\n };\n}\n\nfunction mergeReasoningMetadata(\n target: IOpenAIResponsesReasoningMetadata,\n source: IOpenAIResponsesReasoningMetadata,\n): void {\n target.reasoningSummaryCount += source.reasoningSummaryCount;\n target.reasoningSummaries.push(...source.reasoningSummaries);\n target.hasEncryptedReasoning = target.hasEncryptedReasoning || source.hasEncryptedReasoning;\n}\n\nfunction isString(value: string | undefined): value is string {\n return value !== undefined;\n}\n\nfunction assertUsableResponse(response: IOpenAIResponsesResponse): void {\n if (response.status === 'failed' || response.status === 'incomplete') {\n throw new Error(`OpenAI Responses API failed: ${response.error?.message ?? response.status}`);\n }\n}\n\nfunction extractErrorMessage(event: IOpenAIResponsesErrorEvent): string {\n return event.message ?? event.error?.message ?? event.response?.error?.message ?? 'unknown error';\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { toProviderError } from '@robota-sdk/agent-core';\n\nimport {\n observeProviderNativeRawPayloadStream,\n toOpenAIResponsesToolChoice,\n} from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { buildOpenAIResponsesTextConfig } from './openai-request-format';\nimport { resolveOpenAIReasoningOptions } from './reasoning-effort';\nimport {\n awaitWithProviderRequestId,\n readOpenAIRequestId,\n withProviderRequestId,\n} from './request-id';\nimport {\n convertToOpenAIResponsesInput,\n convertToOpenAIResponsesTools,\n} from './responses-converter';\nimport { openAIRequestOptions } from './request-options';\nimport { assembleOpenAIResponsesStream, parseOpenAIResponsesResponse } from './responses-parser';\n\nimport type {\n IOpenAIResponsesRequestNonStreaming,\n IOpenAIResponsesRequestStreaming,\n TOpenAIResponsesStreamEvent,\n} from './responses-types';\nimport type { IOpenAIProviderOptions } from './types';\nimport type { IChatOptions, TTextDeltaCallback, TUniversalMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\nexport interface IOpenAIResponsesChatOptions {\n client?: OpenAI;\n messages: TUniversalMessage[];\n chatOptions?: IChatOptions;\n providerOptions: IOpenAIProviderOptions;\n onTextDelta?: TTextDeltaCallback;\n /** Per-request headers (trusted `traceparent`), sent after the raw request payload is captured. */\n requestHeaders?: Readonly<Record<string, string>>;\n}\n\ninterface IResponsesStreamMessageQueue {\n deltas: TUniversalMessage[];\n finalMessage?: TUniversalMessage;\n error?: Error;\n wake?: () => void;\n}\n\nexport async function chatWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n if (textDeltaCb) {\n return chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: textDeltaCb,\n },\n });\n }\n\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const response = await input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsNonStreaming,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n );\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'response',\n payload: response,\n });\n return withProviderRequestId(\n parseOpenAIResponsesResponse(response),\n readOpenAIRequestId(response),\n );\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI responses failed');\n }\n}\n\nexport async function* chatStreamWithOpenAIResponsesApi(\n input: IOpenAIResponsesChatOptions,\n): AsyncIterable<TUniversalMessage> {\n const queue: IResponsesStreamMessageQueue = { deltas: [] };\n const textDeltaCb = input.chatOptions?.onTextDelta ?? input.onTextDelta;\n const assembly = chatWithOpenAIResponsesStreamingAssembly({\n ...input,\n chatOptions: {\n ...input.chatOptions,\n onTextDelta: (delta) => {\n textDeltaCb?.(delta);\n enqueueStreamDelta(queue, createStreamDeltaMessage(delta));\n },\n },\n })\n .then((result) => finishStreamQueue(queue, result))\n .catch((error) => failStreamQueue(queue, toError(error)));\n\n yield* drainResponsesStreamQueue(queue);\n await assembly;\n}\n\nasync function chatWithOpenAIResponsesStreamingAssembly(\n input: IOpenAIResponsesChatOptions,\n): Promise<TUniversalMessage> {\n if (!input.client) {\n throw new Error('OpenAI Responses client not available.');\n }\n\n try {\n const requestParams = buildResponsesStreamingRequestParams(input);\n input.chatOptions?.onProviderNativeRawPayload?.({\n provider: 'openai',\n apiSurface: 'responses',\n payloadKind: 'request',\n payload: requestParams,\n });\n const { data: stream, providerRequestId } = await awaitWithProviderRequestId(\n input.client.responses.create(\n requestParams as OpenAI.Responses.ResponseCreateParamsStreaming,\n openAIRequestOptions(input.chatOptions?.signal, input.requestHeaders),\n ),\n );\n const assembled = await assembleOpenAIResponsesStream({\n stream: observeProviderNativeRawPayloadStream(\n stream as AsyncIterable<TOpenAIResponsesStreamEvent>,\n {\n provider: 'openai',\n apiSurface: 'responses',\n onProviderNativeRawPayload: input.chatOptions?.onProviderNativeRawPayload,\n },\n ),\n onTextDelta: input.chatOptions?.onTextDelta,\n signal: input.chatOptions?.signal,\n });\n return withProviderRequestId(assembled, providerRequestId);\n } catch (error) {\n throw toProviderError(error, 'openai', 'OpenAI responses stream failed');\n }\n}\n\nfunction buildResponsesRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestNonStreaming {\n const model = input.chatOptions?.model ?? input.providerOptions.defaultModel;\n if (!model) {\n throw new Error(\n 'Model is required in chat options. Please specify a model in defaultModel configuration.',\n );\n }\n\n const tools = convertToOpenAIResponsesTools(\n input.chatOptions?.tools,\n input.providerOptions.strictTools,\n );\n const textConfig = buildOpenAIResponsesTextConfig(input.providerOptions);\n // Native effort mapping: thread the per-call reasoning-effort dial onto the Responses\n // API `reasoning.effort` parameter, merged with any static reasoning options.\n const reasoning = resolveOpenAIReasoningOptions(\n input.providerOptions.reasoning,\n input.chatOptions?.effortResolution,\n );\n return {\n model,\n input: convertToOpenAIResponsesInput(input.messages),\n ...(tools !== undefined && {\n tools,\n tool_choice: toOpenAIResponsesToolChoice(input.chatOptions?.toolChoice),\n }),\n ...(input.chatOptions?.temperature !== undefined && {\n temperature: input.chatOptions.temperature,\n }),\n ...(input.chatOptions?.maxTokens !== undefined && {\n max_output_tokens: input.chatOptions.maxTokens,\n }),\n ...(textConfig !== undefined && { text: textConfig }),\n ...(reasoning !== undefined && {\n reasoning,\n }),\n ...(input.providerOptions.includeEncryptedReasoning === true && {\n include: ['reasoning.encrypted_content'],\n }),\n ...(input.providerOptions.store !== undefined && { store: input.providerOptions.store }),\n };\n}\n\nfunction buildResponsesStreamingRequestParams(\n input: IOpenAIResponsesChatOptions,\n): IOpenAIResponsesRequestStreaming {\n return {\n ...buildResponsesRequestParams(input),\n stream: true,\n };\n}\n\nfunction createStreamDeltaMessage(delta: string): TUniversalMessage {\n return {\n id: randomUUID(),\n role: 'assistant',\n content: delta,\n state: 'complete',\n timestamp: new Date(),\n metadata: {\n providerApiSurface: 'responses',\n isStreamChunk: true,\n isComplete: false,\n },\n };\n}\n\nasync function* drainResponsesStreamQueue(\n queue: IResponsesStreamMessageQueue,\n): AsyncIterable<TUniversalMessage> {\n while (true) {\n const next = queue.deltas.shift();\n if (next !== undefined) {\n yield next;\n continue;\n }\n if (queue.error !== undefined) {\n throw queue.error;\n }\n if (queue.finalMessage !== undefined) {\n yield createFinalStreamMessage(queue.finalMessage);\n return;\n }\n await waitForStreamQueue(queue);\n }\n}\n\nfunction enqueueStreamDelta(queue: IResponsesStreamMessageQueue, message: TUniversalMessage): void {\n queue.deltas.push(message);\n wakeStreamQueue(queue);\n}\n\nfunction finishStreamQueue(queue: IResponsesStreamMessageQueue, result: TUniversalMessage): void {\n queue.finalMessage = result;\n wakeStreamQueue(queue);\n}\n\nfunction failStreamQueue(queue: IResponsesStreamMessageQueue, error: Error): void {\n queue.error = error;\n wakeStreamQueue(queue);\n}\n\nfunction waitForStreamQueue(queue: IResponsesStreamMessageQueue): Promise<void> {\n return new Promise((resolve) => {\n queue.wake = resolve;\n });\n}\n\nfunction wakeStreamQueue(queue: IResponsesStreamMessageQueue): void {\n queue.wake?.();\n queue.wake = undefined;\n}\n\nfunction createFinalStreamMessage(result: TUniversalMessage): TUniversalMessage {\n return {\n ...result,\n content: '',\n metadata: {\n ...result.metadata,\n isStreamChunk: true,\n isComplete: true,\n },\n };\n}\n\nfunction toError(error: Error | string): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n","import { AbstractAIProvider } from '@robota-sdk/agent-core';\nimport { createModelEffortOutcome } from '@robota-sdk/agent-core';\nimport { PERMISSIVE_TOOL_SCHEMA_PROFILE, STRICT_TOOL_SCHEMA_PROFILE } from '@robota-sdk/agent-core';\nimport { resolveModelEffort } from '@robota-sdk/agent-core';\nimport { SilentLogger } from '@robota-sdk/agent-core';\nimport { traceHeadersFor } from '@robota-sdk/agent-core';\nimport OpenAI from 'openai';\n\nimport {\n chatStreamWithOpenAIChatCompletions,\n chatWithOpenAIChatCompletions,\n} from './chat-completions-chat';\nimport { OPENAI_MODEL_EFFORT_TABLE } from './model-effort-table';\nimport { OpenAIResponseParser } from './parsers/response-parser';\nimport { chatStreamWithOpenAIResponsesApi, chatWithOpenAIResponsesApi } from './responses-chat';\n\nimport type { IPayloadLogger } from './interfaces/payload-logger';\nimport type { IOpenAIProviderOptions, TOpenAIApiSurface } from './types';\nimport type {\n TUniversalMessage,\n IChatOptions,\n IAssistantMessage,\n IProviderCapabilities,\n IProviderModelEffortTable,\n IToolSchemaProjectionProfile,\n TTextDeltaCallback,\n} from '@robota-sdk/agent-core';\n\n/**\n * OpenAI provider implementation for Robota\n *\n * Provides integration with OpenAI models through the Robota provider contract.\n * Uses OpenAI SDK native types internally for optimal performance and feature support.\n *\n * @public\n */\nexport class OpenAIProvider extends AbstractAIProvider {\n override readonly name = 'openai';\n override readonly version = '1.0.0';\n\n private readonly client?: OpenAI;\n private readonly options: IOpenAIProviderOptions;\n private readonly apiSurface: TOpenAIApiSurface;\n private readonly payloadLogger: IPayloadLogger | undefined;\n private readonly responseParser: OpenAIResponseParser;\n\n /**\n * Optional callback for text deltas during streaming.\n * Set by the consumer (e.g., Session) to receive real-time text chunks.\n * When set, chat() uses streaming internally while still returning\n * the complete assembled message.\n */\n onTextDelta?: TTextDeltaCallback;\n\n constructor(options: IOpenAIProviderOptions) {\n super(options.logger || SilentLogger);\n this.options = options;\n this.apiSurface = resolveApiSurface(options);\n validateOpenAIProviderNativeWebTools(this.apiSurface, options.nativeWebTools);\n\n if (options.executor) {\n this.executor = options.executor;\n }\n\n if (!this.executor) {\n if (options.client) {\n this.client = options.client;\n } else if (options.apiKey) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n ...(options.organization && { organization: options.organization }),\n ...(options.timeout && { timeout: options.timeout }),\n ...(options.baseURL && { baseURL: options.baseURL }),\n });\n } else {\n throw new Error('Either OpenAI client, apiKey, or executor is required');\n }\n }\n\n this.responseParser = new OpenAIResponseParser(this.logger);\n this.payloadLogger = options.payloadLogger;\n }\n\n override async chat(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): Promise<TUniversalMessage> {\n this.validateMessages(messages);\n this.validateNativeWebTools(options?.nativeWebTools);\n const resolvedOptions = this.resolveEffortOptions(options);\n\n if (this.executor) {\n try {\n const result = await this.executeViaExecutorOrDirect(messages, resolvedOptions);\n if (result.modelEffortOutcome === undefined) {\n this.publishModelEffortOutcome(resolvedOptions, 'opaque-executor');\n }\n return result.message;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor chat error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n if (this.apiSurface === 'responses') {\n const response = await chatWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return response;\n }\n\n const response = await chatWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return response;\n }\n\n override async *chatStream(\n messages: TUniversalMessage[],\n options?: IChatOptions,\n ): AsyncIterable<TUniversalMessage> {\n this.validateNativeWebTools(options?.nativeWebTools);\n const resolvedOptions = this.resolveEffortOptions(options);\n\n if (this.executor) {\n try {\n let executorOutcomeSeen = false;\n for await (const event of this.executeStreamViaExecutorOrDirect(\n messages,\n resolvedOptions,\n )) {\n if (event.kind === 'message') {\n yield event.message;\n } else {\n executorOutcomeSeen = event.modelEffortOutcome !== undefined;\n }\n }\n if (!executorOutcomeSeen) {\n this.publishModelEffortOutcome(resolvedOptions, 'opaque-executor');\n }\n return;\n } catch (error) {\n this.logger.error(\n 'OpenAI Provider executor stream error:',\n error instanceof Error ? error.message : String(error),\n );\n throw error;\n }\n }\n\n yield* this.streamDirect(messages, resolvedOptions);\n }\n\n private async *streamDirect(\n messages: TUniversalMessage[],\n resolvedOptions: IChatOptions | undefined,\n ): AsyncIterable<TUniversalMessage> {\n if (this.apiSurface === 'responses') {\n yield* chatStreamWithOpenAIResponsesApi({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n return;\n }\n\n yield* chatStreamWithOpenAIChatCompletions({\n client: this.client,\n messages,\n chatOptions: this.projectChatOptions(resolvedOptions),\n providerOptions: this.options,\n payloadLogger: this.payloadLogger,\n responseParser: this.responseParser,\n onTextDelta: this.onTextDelta,\n requestHeaders: this.traceRequestHeaders(resolvedOptions),\n });\n this.publishModelEffortOutcome(resolvedOptions);\n }\n\n /**\n * CORE-043: this provider declares no capability table — nobody has verified one for OpenAI, and\n * inventing one would be a fabricated claim. It can still answer THIS question honestly, which is\n * why the endpoint signal is not a field on the table.\n *\n * It matters most here of all the providers: setting `baseURL` also switches the API surface to\n * `chat-completions` (see `resolveApiSurface`), so the advertised gateway configuration is exactly\n * the one where a structured request is least likely to be enforced by whatever is on the far end.\n */\n endpointIsVendorDefault(): boolean {\n return this.options.baseURL === undefined;\n }\n\n /**\n * The client's own base URL is the origin every request goes to (the SDK has already applied a\n * constructor option or `OPENAI_BASE_URL`). An executor sends elsewhere, and an injected client\n * whose base URL cannot be read gives no origin to compare, so neither can propagate.\n */\n canPropagateTraceContext(): boolean {\n return !this.executor && this.effectiveBaseUrl() !== undefined;\n }\n\n private effectiveBaseUrl(): string | undefined {\n const baseURL: unknown = (this.client as { baseURL?: unknown } | undefined)?.baseURL;\n return typeof baseURL === 'string' && baseURL.length > 0 ? baseURL : undefined;\n }\n\n private traceRequestHeaders(options: IChatOptions | undefined): Readonly<Record<string, string>> {\n if (!this.canPropagateTraceContext()) return {};\n return traceHeadersFor(this.effectiveBaseUrl(), options?.outboundTraceContext);\n }\n\n override effortTable(): IProviderModelEffortTable | undefined {\n return this.endpointIsVendorDefault() && this.apiSurface === 'responses'\n ? OPENAI_MODEL_EFFORT_TABLE\n : undefined;\n }\n\n private resolveEffortOptions(options: IChatOptions | undefined): IChatOptions | undefined {\n if (options?.effort === undefined || options.effortResolution !== undefined) return options;\n const model = options.model ?? this.options.defaultModel;\n if (model === undefined) return options;\n return {\n ...options,\n effortResolution: resolveModelEffort(this.effortTable(), model, options.effort),\n };\n }\n\n /**\n * MCP-005: strict mode's supported subset is documented; non-strict accepts standard JSON Schema.\n * Both the Responses and Chat Completions surfaces honor `strictTools` identically (§ Profiles).\n */\n protected override projectionProfile(): IToolSchemaProjectionProfile | undefined {\n return this.options.strictTools\n ? { ...STRICT_TOOL_SCHEMA_PROFILE, providerName: 'openai' }\n : { ...PERMISSIVE_TOOL_SCHEMA_PROFILE, providerName: 'openai' };\n }\n\n /**\n * Project `chatOptions.tools` through `projectionProfile()` before either request-building module\n * (`responses-chat.ts`, `chat-completions-chat.ts`) sees them — the module helpers receive the\n * projected array as a parameter; `options.tools` itself is never mutated. An empty projected array\n * (every tool quarantined) becomes `undefined` so the downstream `tools &&` truthiness checks treat\n * it the same as \"no tools\", not as a zero-length `tools: []` request field.\n */\n private projectChatOptions(chatOptions: IChatOptions | undefined): IChatOptions | undefined {\n if (!chatOptions?.tools) {\n return chatOptions;\n }\n const model = chatOptions.model ?? this.options.defaultModel ?? '';\n const projected = this.projectTools(chatOptions.tools, model);\n return {\n ...chatOptions,\n tools: projected && projected.length > 0 ? projected : undefined,\n };\n }\n\n private publishModelEffortOutcome(\n options: IChatOptions | undefined,\n opaqueReason?: string,\n ): void {\n const resolution = options?.effortResolution;\n const observer = options?.onModelEffortOutcome;\n if (resolution === undefined || observer === undefined) return;\n\n const nativeControl =\n opaqueReason !== undefined\n ? { state: 'omitted' as const, reason: opaqueReason }\n : resolution.effective !== null && resolution.disposition !== 'model-default'\n ? { state: 'sent' as const, id: 'responses.reasoning.effort' }\n : {\n state: 'omitted' as const,\n reason:\n resolution.disposition === 'model-default'\n ? 'provider-default-selection'\n : 'model-effort-not-applied',\n };\n const providerDispatch =\n opaqueReason !== undefined\n ? { state: 'not-dispatched' as const, reason: opaqueReason }\n : { state: 'sent' as const };\n try {\n observer(createModelEffortOutcome(resolution, { nativeControl, providerDispatch }));\n } catch (error) {\n this.logger.warn('Model-effort outcome observer failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n override supportsTools(): boolean {\n return true;\n }\n\n override getCapabilities(): IProviderCapabilities {\n const source =\n this.apiSurface === 'chat-completions'\n ? 'openai-compatible-chat-completions'\n : 'openai-responses';\n return {\n functionCalling: { supported: true },\n nativeWebTools: {\n webSearch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'search'),\n },\n webFetch: {\n supported: false,\n enabled: false,\n source,\n reason: getOpenAIUnsupportedNativeWebReason(this.apiSurface, 'fetch'),\n },\n },\n };\n }\n\n override validateConfig(): boolean {\n return !!this.client && !!this.options;\n }\n\n override async dispose(): Promise<void> {\n // OpenAI client doesn't need explicit cleanup\n }\n\n protected override validateMessages(messages: TUniversalMessage[]): void {\n super.validateMessages(messages);\n\n for (const message of messages) {\n if (message.role === 'assistant') {\n const assistantMsg = message as IAssistantMessage;\n if (\n assistantMsg.toolCalls &&\n assistantMsg.toolCalls.length > 0 &&\n assistantMsg.content === ''\n ) {\n continue;\n }\n }\n }\n }\n}\n\nfunction resolveApiSurface(options: IOpenAIProviderOptions): TOpenAIApiSurface {\n if (options.apiSurface !== undefined) {\n return options.apiSurface;\n }\n return options.baseURL ? 'chat-completions' : 'responses';\n}\n\nfunction getOpenAIUnsupportedNativeWebReason(\n apiSurface: TOpenAIApiSurface,\n toolKind: 'search' | 'fetch',\n): string {\n if (apiSurface === 'chat-completions') {\n return `OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${toolKind}.`;\n }\n return `OpenAI Responses native web ${toolKind} is not wired in this Robota provider version.`;\n}\n\nfunction validateOpenAIProviderNativeWebTools(\n apiSurface: TOpenAIApiSurface,\n nativeWebTools: IOpenAIProviderOptions['nativeWebTools'],\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n throw new Error(\n `Provider openai native web search/fetch is not supported for apiSurface ${apiSurface} in this Robota provider version.`,\n );\n}\n","import type { TUniversalMessage, IAssistantMessage } from '@robota-sdk/agent-core';\nimport type OpenAI from 'openai';\n\n/**\n * OpenAI Conversation Adapter\n *\n * Converts between TUniversalMessage format and OpenAI native types.\n * Provides bidirectional conversion for seamless integration.\n *\n * @public\n */\nexport class OpenAIConversationAdapter {\n /**\n * Filter messages for OpenAI compatibility\n *\n * OpenAI has specific requirements:\n * - Tool messages must have valid toolCallId\n * - Messages must be in proper sequence\n * - Tool messages without toolCallId should be excluded\n */\n static filterMessagesForOpenAI(messages: TUniversalMessage[]): TUniversalMessage[] {\n return messages.filter((msg) => {\n // Always include user, assistant, and system messages\n if (msg.role === 'user' || msg.role === 'assistant' || msg.role === 'system') {\n return true;\n }\n\n // For tool messages, only include if they have a valid toolCallId\n if (msg.role === 'tool') {\n // Must have toolCallId and it must not be empty or 'unknown'\n return !!(msg.toolCallId && msg.toolCallId.trim() !== '' && msg.toolCallId !== 'unknown');\n }\n\n return false;\n });\n }\n\n /**\n * Convert TUniversalMessage array to OpenAI message format\n * Now properly handles tool messages for OpenAI's tool calling feature\n */\n static toOpenAIFormat(messages: TUniversalMessage[]): OpenAI.Chat.ChatCompletionMessageParam[] {\n // First filter messages for OpenAI compatibility\n const filteredMessages = this.filterMessagesForOpenAI(messages);\n return filteredMessages.map((msg) => this.convertMessage(msg));\n }\n\n /**\n * Convert a single TUniversalMessage to OpenAI format\n * Handles all message types including tool messages\n */\n static convertMessage(msg: TUniversalMessage): OpenAI.Chat.ChatCompletionMessageParam {\n const messageRole = msg.role;\n\n if (messageRole === 'user') {\n return {\n role: 'user',\n content: msg.content,\n };\n }\n\n if (messageRole === 'assistant') {\n const assistantMsg = msg as IAssistantMessage;\n\n // Handle tool_calls format\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const result: OpenAI.Chat.ChatCompletionAssistantMessageParam = {\n role: 'assistant',\n // CRITICAL: OpenAI API requires content to be null (not empty string) when tool_calls are present\n // VERIFIED: 2024-12 - This prevents \"400 Bad Request\" errors from OpenAI API\n // DO NOT CHANGE without testing against actual OpenAI API\n content: assistantMsg.content === '' ? null : assistantMsg.content || null,\n tool_calls: assistantMsg.toolCalls.map((toolCall) => ({\n id: toolCall.id,\n type: 'function',\n function: {\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n },\n })),\n };\n return result;\n }\n\n // Regular assistant message (without tool calls)\n // VERIFIED: OpenAI accepts both null and string content for regular messages\n // We preserve null when content is null or empty string for API consistency\n return {\n role: 'assistant',\n content:\n assistantMsg.content === null\n ? null\n : assistantMsg.content === ''\n ? null\n : assistantMsg.content || '',\n };\n }\n\n if (messageRole === 'system') {\n return {\n role: 'system',\n content: msg.content,\n };\n }\n\n // Handle tool messages for OpenAI tool calling\n if (messageRole === 'tool') {\n if (!msg.toolCallId || msg.toolCallId.trim() === '') {\n throw new Error(`Tool message missing toolCallId: ${JSON.stringify(msg)}`);\n }\n\n const result: OpenAI.Chat.ChatCompletionToolMessageParam = {\n role: 'tool',\n content: msg.content,\n tool_call_id: msg.toolCallId,\n };\n return result;\n }\n\n const exhaustive: never = messageRole;\n throw new Error(`Unsupported message role: ${exhaustive}`);\n }\n\n /**\n * Add system prompt to message array if needed\n */\n static addSystemPromptIfNeeded(\n messages: OpenAI.Chat.ChatCompletionMessageParam[],\n systemPrompt?: string,\n ): OpenAI.Chat.ChatCompletionMessageParam[] {\n if (!systemPrompt) {\n return messages;\n }\n\n // Check if system message already exists\n const hasSystemMessage = messages.some((msg) => msg.role === 'system');\n\n if (hasSystemMessage) {\n return messages;\n }\n\n // Add system prompt at the beginning\n return [{ role: 'system', content: systemPrompt }, ...messages];\n }\n}\n","import { probeOpenAICompatibleProfile } from '@robota-sdk/agent-provider-openai-compatible/shared';\n\nimport { OpenAIProvider } from './provider';\n\nimport type { IOpenAINativeWebToolsOptions, TOpenAIApiSurface } from './types';\nimport type { IProviderDefinition, TUniversalValue } from '@robota-sdk/agent-core';\n\nexport const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined = undefined;\nexport const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = '$ENV:OPENAI_API_KEY';\nconst OPENAI_API_KEY_URL = 'https://platform.openai.com/api-keys';\nconst OPENAI_SETUP_SOURCE_URL =\n 'https://developers.openai.com/api/reference/overview#authentication';\nconst OPENAI_SETUP_LAST_VERIFIED_AT = '2026-05-08';\nconst OPENAI_SETUP_HELP_LINKS: NonNullable<IProviderDefinition['setupHelpLinks']> = [\n {\n kind: 'api-key',\n label: 'OpenAI API keys',\n url: OPENAI_API_KEY_URL,\n sourceUrl: OPENAI_SETUP_SOURCE_URL,\n lastVerifiedAt: OPENAI_SETUP_LAST_VERIFIED_AT,\n },\n];\n\nexport function createOpenAIProviderDefinition(): IProviderDefinition {\n return {\n type: 'openai',\n displayName: 'OpenAI',\n description: 'GPT series — general-purpose assistant. API key required.',\n category: 'cloud-paid',\n // Interim provider-level cost (ARCH-PROVIDER-003), migrated from the former llm-text-openai node.\n costPerTokenUsd: 0.001,\n defaults: {\n apiKey: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n },\n // OBSERVABILITY-1991: the SDK embeds this endpoint; declared here for the pre-session doctor only.\n endpoint: { host: 'api.openai.com', port: 443 },\n modelCatalog: {\n status: 'unavailable',\n sourceUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n message: 'OpenAI model availability should be discovered live from GET /v1/models.',\n },\n setupHelpLinks: OPENAI_SETUP_HELP_LINKS,\n setupSteps: [\n {\n key: 'model',\n title: 'OpenAI model',\n required: true,\n },\n {\n key: 'apiKey',\n title: 'OpenAI API key',\n defaultValue: DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,\n masked: true,\n },\n ],\n requiresApiKey: true,\n probeProfile: probeOpenAICompatibleProfile,\n // The OpenAI SDK falls back to the base URL variable when none is configured, and sends the\n // organization and project the others name.\n destinationEnvironment: ['OPENAI_BASE_URL', 'OPENAI_ORG_ID', 'OPENAI_PROJECT_ID'],\n createProvider: (config) => {\n const apiSurface = readApiSurface(config.options);\n const nativeWebTools = readNativeWebTools(config.options);\n validateOpenAINativeWebTools(config.baseURL, apiSurface, nativeWebTools);\n return new OpenAIProvider({\n apiKey: requireApiKey(config.apiKey),\n ...(config.baseURL !== undefined && { baseURL: config.baseURL }),\n ...(config.timeout !== undefined && { timeout: config.timeout }),\n ...(apiSurface !== undefined && { apiSurface }),\n ...(nativeWebTools !== undefined && { nativeWebTools }),\n defaultModel: config.model,\n });\n },\n };\n}\n\nfunction requireApiKey(apiKey: string | undefined): string {\n if (!apiKey) {\n throw new Error('Provider openai requires apiKey');\n }\n return apiKey;\n}\n\nfunction readApiSurface(\n options: Record<string, TUniversalValue> | undefined,\n): TOpenAIApiSurface | undefined {\n const apiSurface = options?.['apiSurface'];\n if (apiSurface === 'responses' || apiSurface === 'chat-completions') {\n return apiSurface;\n }\n return undefined;\n}\n\nfunction readNativeWebTools(\n options: Record<string, TUniversalValue> | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n const nativeWebTools =\n readNativeWebToolsRecord(options?.['nativeWebTools']) ??\n readNativeWebToolsRecord(options?.['builtInWebTools']);\n if (nativeWebTools === undefined) {\n return undefined;\n }\n return nativeWebTools;\n}\n\nfunction readNativeWebToolsRecord(\n value: TUniversalValue | undefined,\n): IOpenAINativeWebToolsOptions | undefined {\n if (value === null || value === undefined || value instanceof Date || Array.isArray(value)) {\n return undefined;\n }\n if (typeof value !== 'object') {\n return undefined;\n }\n const webSearch = value['webSearch'];\n const webFetch = value['webFetch'];\n return {\n ...(typeof webSearch === 'boolean' && { webSearch }),\n ...(typeof webFetch === 'boolean' && { webFetch }),\n };\n}\n\nfunction validateOpenAINativeWebTools(\n baseURL: string | undefined,\n apiSurface: TOpenAIApiSurface | undefined,\n nativeWebTools: IOpenAINativeWebToolsOptions | undefined,\n): void {\n if (nativeWebTools?.webSearch !== true && nativeWebTools?.webFetch !== true) {\n return;\n }\n if (baseURL !== undefined || apiSurface === 'chat-completions') {\n throw new Error(\n 'Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n }\n throw new Error(\n 'Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.',\n );\n}\n"],"mappings":"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"}