@robota-sdk/agent-provider-openai 3.0.0-beta.60 → 3.0.0-beta.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +13 -0
- package/dist/browser/index.d.ts +24 -2
- package/dist/browser/index.js +2 -1
- package/dist/node/index.cjs +2 -1
- package/dist/node/index.d.cts +24 -2
- package/dist/node/index.d.ts +24 -2
- package/dist/node/index.js +2 -1
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @robota-sdk/agent-provider-openai
|
|
2
2
|
|
|
3
|
+
## 3.0.0-beta.61
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 36eb7a9: Add provider-owned native replay payload hooks, replay validation coverage, and a session log validation command.
|
|
8
|
+
- d97bdf2: Add provider-owned model catalog metadata, route `/model` suggestions through the active provider, and make `cli:dev` resolve the CLI workspace dependency closure through source export conditions.
|
|
9
|
+
- Updated dependencies [1c0d44c]
|
|
10
|
+
- Updated dependencies [36eb7a9]
|
|
11
|
+
- Updated dependencies [d97bdf2]
|
|
12
|
+
- @robota-sdk/agent-core@3.0.0-beta.61
|
|
13
|
+
- @robota-sdk/agent-provider-openai-compatible@3.0.0-beta.61
|
|
14
|
+
|
|
3
15
|
## 3.0.0-beta.60
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ OpenAI Provider for Robota SDK - type-safe integration with the official OpenAI
|
|
|
12
12
|
- **🛠️ Function Calling**: Native OpenAI function calling with type validation
|
|
13
13
|
- **🧩 Structured Outputs**: JSON object and JSON Schema response formats
|
|
14
14
|
- **🌐 Capability Reporting**: Explicit native web search/fetch capability state without hidden local-tool fallback
|
|
15
|
+
- **Provider-Owned Model Catalog Refresh**: `/model` can discover OpenAI models through the provider definition without CLI/TUI-owned model lists
|
|
15
16
|
- **🔄 Provider-Agnostic Design**: Seamless integration with other Robota providers
|
|
16
17
|
- **📊 Payload Logging**: Optional API request/response logging for debugging
|
|
17
18
|
|
|
@@ -84,6 +85,14 @@ For provider packages that share OpenAI-compatible transport code, the reusable
|
|
|
84
85
|
|
|
85
86
|
OpenAI-compatible Chat Completions profiles, including LM Studio-style `baseURL` profiles, are custom function-tool capable but are not treated as provider-native hosted web search/fetch providers. Use Robota local `WebSearch`/`WebFetch` tools for explicit local web access unless a concrete provider package documents hosted web support.
|
|
86
87
|
|
|
88
|
+
### Model Catalog Refresh
|
|
89
|
+
|
|
90
|
+
`createOpenAIProviderDefinition()` exposes provider-owned setup help links and a
|
|
91
|
+
provider-owned `refreshModelCatalog` hook. SDK command
|
|
92
|
+
common APIs may call this hook to query the OpenAI Models API with the effective provider profile and
|
|
93
|
+
surface catalog freshness in `/model` output. CLI/TUI layers must render that result rather than
|
|
94
|
+
owning OpenAI model metadata.
|
|
95
|
+
|
|
87
96
|
### Streaming Responses
|
|
88
97
|
|
|
89
98
|
```typescript
|
|
@@ -104,6 +113,10 @@ for await (const chunk of stream) {
|
|
|
104
113
|
|
|
105
114
|
When `chat()` receives an `onTextDelta` callback, the provider uses the selected API surface's streaming path internally, forwards text deltas to the callback, assembles streamed tool-call chunks, and returns the final assistant message.
|
|
106
115
|
|
|
116
|
+
### Native Replay Payload Capture
|
|
117
|
+
|
|
118
|
+
When `IChatOptions.onProviderNativeRawPayload` is provided, the provider emits exact OpenAI SDK request, response, and stream event payloads with `apiSurface` set to either `responses` or `chat-completions`. `agent-core` routes these provider-owned callbacks into provider-neutral `provider_native_raw_payload` execution events for replay-grade session logs.
|
|
119
|
+
|
|
107
120
|
## 🛠️ Function Calling
|
|
108
121
|
|
|
109
122
|
OpenAI Provider supports type-safe function calling with automatic parameter validation:
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
2
|
+
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderProfileConfig, IProviderModelCatalog, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Payload logging data structure
|
|
@@ -278,8 +278,30 @@ declare class OpenAIConversationAdapter {
|
|
|
278
278
|
static addSystemPromptIfNeeded(messages: OpenAI.Chat.ChatCompletionMessageParam[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
interface IOpenAIModelCatalogResponse {
|
|
282
|
+
data?: readonly IOpenAIModelCatalogResource[];
|
|
283
|
+
}
|
|
284
|
+
interface IOpenAIModelCatalogResource {
|
|
285
|
+
id?: string;
|
|
286
|
+
}
|
|
287
|
+
interface IOpenAIModelCatalogFetchInit {
|
|
288
|
+
headers: Record<string, string>;
|
|
289
|
+
}
|
|
290
|
+
interface IOpenAIModelCatalogFetchResponse {
|
|
291
|
+
ok: boolean;
|
|
292
|
+
status: number;
|
|
293
|
+
statusText?: string;
|
|
294
|
+
json: () => Promise<IOpenAIModelCatalogResponse>;
|
|
295
|
+
}
|
|
296
|
+
type TOpenAIModelCatalogFetch = (url: string, init: IOpenAIModelCatalogFetchInit) => Promise<IOpenAIModelCatalogFetchResponse>;
|
|
297
|
+
interface IRefreshOpenAIModelCatalogOptions {
|
|
298
|
+
fetcher?: TOpenAIModelCatalogFetch;
|
|
299
|
+
now?: () => Date;
|
|
300
|
+
}
|
|
301
|
+
declare function refreshOpenAIModelCatalog(profile: IProviderProfileConfig, options?: IRefreshOpenAIModelCatalogOptions): Promise<IProviderModelCatalog>;
|
|
302
|
+
|
|
281
303
|
declare const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined;
|
|
282
304
|
declare const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = "$ENV:OPENAI_API_KEY";
|
|
283
305
|
declare function createOpenAIProviderDefinition(): IProviderDefinition;
|
|
284
306
|
|
|
285
|
-
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition };
|
|
307
|
+
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAIModelCatalogFetchInit, type IOpenAIModelCatalogFetchResponse, type IOpenAIModelCatalogResource, type IOpenAIModelCatalogResponse, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, type IRefreshOpenAIModelCatalogOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIModelCatalogFetch, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition, refreshOpenAIModelCatalog };
|
package/dist/browser/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import ye from'openai';import {AbstractAIProvider,SilentLogger}from'@robota-sdk/agent-core';import {probeOpenAICompatibleProfile,OpenAICompatibleResponseParser,assembleOpenAICompatibleStream,convertToOpenAICompatibleMessages,convertToOpenAICompatibleTools}from'@robota-sdk/agent-provider-openai-compatible';import {randomUUID}from'crypto';var i=class{parser;constructor(t){this.parser=new OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${s}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${s}`)}}};function f(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function O(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=g(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 h(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=g(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 g(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function A(e){return convertToOpenAICompatibleMessages(e)}function T(e){return convertToOpenAICompatibleTools(e)}async function R(e){let t=b(e.client);try{let n=v(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await G(t,e,{...n,stream:!0});await u(e,n,"chat");let o=await t.chat.completions.create(n);return e.responseParser.parseResponse(o)}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${o}`)}}async function*C(e){let t=b(e.client);try{let n={...v(e),stream:!0};await u(e,n,"stream");let s=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let o of s){let r=e.responseParser.parseStreamingChunk(o);r&&(yield r);}}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${o}`)}}function v(e){let t=A(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let s=O(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...s!==void 0&&{response_format:s}}}async function G(e,t,n){try{await u(t,n,"stream");let s=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return assembleOpenAICompatibleStream({stream:s,onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(s){let r=s.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function u(e,t,n){if(!e.payloadLogger?.isEnabled())return;let s={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(s,n);}function b(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function S(e){return e.flatMap(t=>B(t))}function x(e,t){let n=e?.map(s=>({type:"function",name:s.name,description:s.description,parameters:s.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function B(e){if(e.role==="user")return [p("user",X(e.content,e.parts))];if(e.role==="system")return [p("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return H(e)}function H(e){let t=[];e.content&&e.content.length>0&&t.push(p("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(p("assistant","")),t}function X(e,t){if(!t||t.length===0)return e;let n=t.map(s=>Z(s));return e.length>0&&!t.some(s=>s.type==="text")?[{type:"input_text",text:e},...n]:n}function Z(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 p(e,t){return {role:e,content:t}}async function*M(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let s=await ee(n,t);if(s.done||t?.aborted)break;yield s.value;}}finally{t?.aborted&&await n.return?.();}}async function ee(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,s=new Promise(o=>{n=()=>o({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),s])}finally{n&&t.removeEventListener("abort",n);}}function w(e){L(e);let t=e.output??[],n=e.output_text??k(t);return m({content:n,toolCalls:E(t),response:e,reasoning:l(t)})}async function P(e){let t={textParts:[],toolCalls:[],reasoning:F()};for await(let n of M(e.stream,e.signal))ne(t,n,e.onTextDelta);return t.completedResponse!==void 0?oe(t):m({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ne(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,d(e.reasoning,l(t.response.output??[]));return}if(t.type==="response.output_item.done"){se(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${ce(t)}`)}function se(e,t){if(U(t)){e.toolCalls.push(D(t));return}_(t)&&d(e.reasoning,l([t]));}function oe(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");L(t);let n=t.output??[],s=E(n),o=e.textParts.length>0?e.textParts.join(""):t.output_text??k(n),r=l(n);return d(r,e.reasoning),m({content:o,toolCalls:s.length>0?s:e.toolCalls,response:t,reasoning:r})}function m(e){return {id:randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:ae(e.response.usage)},metadata:re(e.response,e.reasoning)}}function re(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:true}}}function ae(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function E(e){return e.filter(U).map(t=>D(t))}function U(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function D(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function k(e){return e.filter(pe).flatMap(t=>t.content).map(ie).join("")}function ie(e){return e.type==="refusal"?e.refusal:e.text}function pe(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function l(e){let t=F();for(let n of e){if(!_(n))continue;let s=n.summary?.map(o=>o.text).filter(le)??[];t.reasoningSummaryCount+=s.length,t.reasoningSummaries.push(...s),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function _(e){return e.type==="reasoning"}function F(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function d(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function le(e){return e!==void 0}function L(e){if(e.status==="failed"||e.status==="incomplete")throw new 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 W(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return j({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=$(e),s=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return w(s)}catch(n){let o=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${o}`)}}async function*N(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,s=j({...e,chatOptions:{...e.chatOptions,onTextDelta:o=>{n?.(o),fe(t,de(o));}}}).then(o=>Oe(t,o)).catch(o=>he(t,Te(o)));yield*Ie(t),await s;}async function j(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=me(e),n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return P({stream:n,onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let s=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${s}`)}}function $(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=x(e.chatOptions?.tools,e.providerOptions.strictTools),s=h(e.providerOptions);return {model:t,input:S(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...s!==void 0&&{text:s},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function me(e){return {...$(e),stream:true}}function de(e){return {id:randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*Ie(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 Ae(e.finalMessage);return}await ge(e);}}function fe(e,t){e.deltas.push(t),I(e);}function Oe(e,t){e.finalMessage=t,I(e);}function he(e,t){e.error=t,I(e);}function ge(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function Ae(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Te(e){return e instanceof Error?e:new Error(String(e))}var a=class extends AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||SilentLogger),this.options=t,this.apiSurface=ve(t),be(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new ye({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new i(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(s){throw this.logger.error("OpenAI Provider executor chat error:",s instanceof Error?s.message:String(s)),s}return this.apiSurface==="responses"?W({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):R({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(s){throw this.logger.error("OpenAI Provider executor stream error:",s instanceof Error?s.message:String(s)),s}if(this.apiSurface==="responses"){yield*N({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*C({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let s=n;if(s.toolCalls&&s.toolCalls.length>0&&s.content==="")continue}}};function ve(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function q(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 be(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var Q=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(s=>this.convertMessage(s))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let o=t;return o.toolCalls&&o.toolCalls.length>0?{role:"assistant",content:o.content===""?null:o.content||null,tool_calls:o.toolCalls.map(c=>({id:c.id,type:"function",function:{name:c.function.name,arguments:c.function.arguments}}))}:{role:"assistant",content:o.content===null||o.content===""?null:o.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let s=n;throw new Error(`Unsupported message role: ${s}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(o=>o.role==="system")?t:[{role:"system",content:n},...t]}};var pt=void 0,V="$ENV:OPENAI_API_KEY";function lt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:V},setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:V,masked:true}],requiresApiKey:true,probeProfile:probeOpenAICompatibleProfile,createProvider:e=>{let t=Me(e.options),n=we(e.options);return Pe(e.baseURL,t,n),new a({apiKey:xe(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 xe(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function Me(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function we(e){let t=K(e?.nativeWebTools)??K(e?.builtInWebTools);if(t!==void 0)return t}function K(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 Pe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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{V as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,pt as DEFAULT_OPENAI_PROVIDER_MODEL,Q as OpenAIConversationAdapter,a as OpenAIProvider,lt as createOpenAIProviderDefinition};
|
|
1
|
+
import Se from'openai';import {AbstractAIProvider,SilentLogger}from'@robota-sdk/agent-core';import {probeOpenAICompatibleProfile,OpenAICompatibleResponseParser,observeProviderNativeRawPayloadStream,assembleOpenAICompatibleStream,convertToOpenAICompatibleMessages,convertToOpenAICompatibleTools}from'@robota-sdk/agent-provider-openai-compatible';import {randomUUID}from'crypto';var p=class{parser;constructor(t){this.parser=new OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${o}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${o}`)}}};function h(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function g(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=y(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 A(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=y(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 y(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function v(e){return convertToOpenAICompatibleMessages(e)}function T(e){return convertToOpenAICompatibleTools(e)}async function b(e){let t=M(e.client);try{let n=S(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await ee(t,e,{...n,stream:!0});await d(e,n,"chat"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let s=await t.chat.completions.create(n);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"response",payload:s}),e.responseParser.parseResponse(s)}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${s}`)}}async function*P(e){let t=M(e.client);try{let n={...S(e),stream:!0};await d(e,n,"stream"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let s of observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let r=e.responseParser.parseStreamingChunk(s);r&&(yield r);}}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${s}`)}}function S(e){let t=v(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let o=g(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...o!==void 0&&{response_format:o}}}async function ee(e,t,n){try{await d(t,n,"stream"),t.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return assembleOpenAICompatibleStream({stream:observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:t.chatOptions?.onProviderNativeRawPayload}),onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(o){let r=o.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function d(e,t,n){if(!e.payloadLogger?.isEnabled())return;let o={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(o,n);}function M(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function x(e){return e.flatMap(t=>te(t))}function w(e,t){let n=e?.map(o=>({type:"function",name:o.name,description:o.description,parameters:o.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function te(e){if(e.role==="user")return [l("user",oe(e.content,e.parts))];if(e.role==="system")return [l("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return ne(e)}function ne(e){let t=[];e.content&&e.content.length>0&&t.push(l("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(l("assistant","")),t}function oe(e,t){if(!t||t.length===0)return e;let n=t.map(o=>se(o));return e.length>0&&!t.some(o=>o.type==="text")?[{type:"input_text",text:e},...n]:n}function se(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 l(e,t){return {role:e,content:t}}async function*E(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let o=await re(n,t);if(o.done||t?.aborted)break;yield o.value;}}finally{t?.aborted&&await n.return?.();}}async function re(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,o=new Promise(s=>{n=()=>s({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),o])}finally{n&&t.removeEventListener("abort",n);}}function U(e){j(e);let t=e.output??[],n=e.output_text??N(t);return u({content:n,toolCalls:k(t),response:e,reasoning:c(t)})}async function _(e){let t={textParts:[],toolCalls:[],reasoning:W()};for await(let n of E(e.stream,e.signal))ie(t,n,e.onTextDelta);return t.completedResponse!==void 0?le(t):u({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ie(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,m(e.reasoning,c(t.response.output??[]));return}if(t.type==="response.output_item.done"){pe(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${fe(t)}`)}function pe(e,t){if(D(t)){e.toolCalls.push(F(t));return}L(t)&&m(e.reasoning,c([t]));}function le(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");j(t);let n=t.output??[],o=k(n),s=e.textParts.length>0?e.textParts.join(""):t.output_text??N(n),r=c(n);return m(r,e.reasoning),u({content:s,toolCalls:o.length>0?o:e.toolCalls,response:t,reasoning:r})}function u(e){return {id:randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:de(e.response.usage)},metadata:ce(e.response,e.reasoning)}}function ce(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:true}}}function de(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function k(e){return e.filter(D).map(t=>F(t))}function D(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function F(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function N(e){return e.filter(me).flatMap(t=>t.content).map(ue).join("")}function ue(e){return e.type==="refusal"?e.refusal:e.text}function me(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function c(e){let t=W();for(let n of e){if(!L(n))continue;let o=n.summary?.map(s=>s.text).filter(Ie)??[];t.reasoningSummaryCount+=o.length,t.reasoningSummaries.push(...o),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function L(e){return e.type==="reasoning"}function W(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function m(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function Ie(e){return e!==void 0}function j(e){if(e.status==="failed"||e.status==="incomplete")throw new Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function fe(e){return e.message??e.error?.message??e.response?.error?.message??"unknown error"}async function $(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return q({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=V(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:n});let o=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"response",payload:o}),U(o)}catch(n){let s=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${s}`)}}async function*K(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,o=q({...e,chatOptions:{...e.chatOptions,onTextDelta:s=>{n?.(s),ve(t,Ae(s));}}}).then(s=>Te(t,s)).catch(s=>Re(t,Pe(s)));yield*ye(t),await o;}async function q(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=ge(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:t});let n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return _({stream:observeProviderNativeRawPayloadStream(n,{provider:"openai",apiSurface:"responses",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let o=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${o}`)}}function V(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=w(e.chatOptions?.tools,e.providerOptions.strictTools),o=A(e.providerOptions);return {model:t,input:x(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...o!==void 0&&{text:o},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function ge(e){return {...V(e),stream:true}}function Ae(e){return {id:randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*ye(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 be(e.finalMessage);return}await Ce(e);}}function ve(e,t){e.deltas.push(t),I(e);}function Te(e,t){e.finalMessage=t,I(e);}function Re(e,t){e.error=t,I(e);}function Ce(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function be(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Pe(e){return e instanceof Error?e:new Error(String(e))}var i=class extends AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||SilentLogger),this.options=t,this.apiSurface=we(t),Ee(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new Se({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new p(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(o){throw this.logger.error("OpenAI Provider executor chat error:",o instanceof Error?o.message:String(o)),o}return this.apiSurface==="responses"?$({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):b({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(o){throw this.logger.error("OpenAI Provider executor stream error:",o instanceof Error?o.message:String(o)),o}if(this.apiSurface==="responses"){yield*K({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*P({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let o=n;if(o.toolCalls&&o.toolCalls.length>0&&o.content==="")continue}}};function we(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function Q(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 Ee(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var J=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(o=>this.convertMessage(o))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let s=t;return s.toolCalls&&s.toolCalls.length>0?{role:"assistant",content:s.content===""?null:s.content||null,tool_calls:s.toolCalls.map(a=>({id:a.id,type:"function",function:{name:a.function.name,arguments:a.function.arguments}}))}:{role:"assistant",content:s.content===null||s.content===""?null:s.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let o=n;throw new Error(`Unsupported message role: ${o}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(s=>s.role==="system")?t:[{role:"system",content:n},...t]}};var Ue="https://api.openai.com/v1/models",z="https://platform.openai.com/docs/api-reference/models/list";async function H(e,t={}){if(!e.apiKey)return f("OpenAI model catalog refresh requires apiKey.");let n=t.fetcher??Fe,o=t.now??(()=>new Date),s=_e(e.baseURL);try{let r=await n(s,{headers:{Authorization:`Bearer ${e.apiKey}`}});if(!r.ok)return f(De(r));let a=await r.json(),O=ke(a);return {status:"live",entries:O,lastVerifiedAt:o().toISOString(),sourceUrl:z,message:`${O.length} OpenAI model(s) discovered.`}}catch(r){return f(r instanceof Error?r.message:String(r))}}function _e(e){return e?`${e.replace(/\/$/,"")}/models`:Ue}function ke(e){return (e.data??[]).map(t=>t.id).filter(t=>t!==void 0&&t.trim().length>0).map(t=>({id:t,displayName:t,lifecycle:"active"}))}function De(e){let t=e.statusText?` ${e.statusText}`:"";return `OpenAI model catalog refresh failed: HTTP ${e.status}${t}`}function f(e){return {status:"unavailable",sourceUrl:z,message:e}}async function Fe(e,t){let n=await fetch(e,t);return {ok:n.ok,status:n.status,statusText:n.statusText,json:()=>n.json()}}var St=void 0,Y="$ENV:OPENAI_API_KEY",Le="https://platform.openai.com/api-keys",We="https://developers.openai.com/api/reference/overview#authentication",je="2026-05-08",$e=[{kind:"api-key",label:"OpenAI API keys",url:Le,sourceUrl:We,lastVerifiedAt:je}];function Mt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:Y},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:$e,setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:Y,masked:true}],requiresApiKey:true,probeProfile:probeOpenAICompatibleProfile,refreshModelCatalog:({profile:e})=>H(e),createProvider:e=>{let t=qe(e.options),n=Ve(e.options);return Qe(e.baseURL,t,n),new i({apiKey:Ke(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 Ke(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function qe(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function Ve(e){let t=G(e?.nativeWebTools)??G(e?.builtInWebTools);if(t!==void 0)return t}function G(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 Qe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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.")}
|
|
2
|
+
export{Y as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,St as DEFAULT_OPENAI_PROVIDER_MODEL,J as OpenAIConversationAdapter,i as OpenAIProvider,Mt as createOpenAIProviderDefinition,H as refreshOpenAIModelCatalog};
|
package/dist/node/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
'use strict';var ye=require('openai'),agentCore=require('@robota-sdk/agent-core'),agentProviderOpenaiCompatible=require('@robota-sdk/agent-provider-openai-compatible'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ye__default=/*#__PURE__*/_interopDefault(ye);var i=class{parser;constructor(t){this.parser=new agentProviderOpenaiCompatible.OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${s}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${s}`)}}};function f(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function O(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=g(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 h(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=g(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 g(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function A(e){return agentProviderOpenaiCompatible.convertToOpenAICompatibleMessages(e)}function T(e){return agentProviderOpenaiCompatible.convertToOpenAICompatibleTools(e)}async function R(e){let t=b(e.client);try{let n=v(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await G(t,e,{...n,stream:!0});await u(e,n,"chat");let o=await t.chat.completions.create(n);return e.responseParser.parseResponse(o)}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${o}`)}}async function*C(e){let t=b(e.client);try{let n={...v(e),stream:!0};await u(e,n,"stream");let s=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let o of s){let r=e.responseParser.parseStreamingChunk(o);r&&(yield r);}}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${o}`)}}function v(e){let t=A(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let s=O(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...s!==void 0&&{response_format:s}}}async function G(e,t,n){try{await u(t,n,"stream");let s=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return agentProviderOpenaiCompatible.assembleOpenAICompatibleStream({stream:s,onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(s){let r=s.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function u(e,t,n){if(!e.payloadLogger?.isEnabled())return;let s={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(s,n);}function b(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function S(e){return e.flatMap(t=>B(t))}function x(e,t){let n=e?.map(s=>({type:"function",name:s.name,description:s.description,parameters:s.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function B(e){if(e.role==="user")return [p("user",X(e.content,e.parts))];if(e.role==="system")return [p("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return H(e)}function H(e){let t=[];e.content&&e.content.length>0&&t.push(p("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(p("assistant","")),t}function X(e,t){if(!t||t.length===0)return e;let n=t.map(s=>Z(s));return e.length>0&&!t.some(s=>s.type==="text")?[{type:"input_text",text:e},...n]:n}function Z(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 p(e,t){return {role:e,content:t}}async function*M(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let s=await ee(n,t);if(s.done||t?.aborted)break;yield s.value;}}finally{t?.aborted&&await n.return?.();}}async function ee(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,s=new Promise(o=>{n=()=>o({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),s])}finally{n&&t.removeEventListener("abort",n);}}function w(e){L(e);let t=e.output??[],n=e.output_text??k(t);return m({content:n,toolCalls:E(t),response:e,reasoning:l(t)})}async function P(e){let t={textParts:[],toolCalls:[],reasoning:F()};for await(let n of M(e.stream,e.signal))ne(t,n,e.onTextDelta);return t.completedResponse!==void 0?oe(t):m({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ne(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,d(e.reasoning,l(t.response.output??[]));return}if(t.type==="response.output_item.done"){se(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${ce(t)}`)}function se(e,t){if(U(t)){e.toolCalls.push(D(t));return}_(t)&&d(e.reasoning,l([t]));}function oe(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");L(t);let n=t.output??[],s=E(n),o=e.textParts.length>0?e.textParts.join(""):t.output_text??k(n),r=l(n);return d(r,e.reasoning),m({content:o,toolCalls:s.length>0?s:e.toolCalls,response:t,reasoning:r})}function m(e){return {id:crypto.randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:ae(e.response.usage)},metadata:re(e.response,e.reasoning)}}function re(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:true}}}function ae(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function E(e){return e.filter(U).map(t=>D(t))}function U(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function D(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function k(e){return e.filter(pe).flatMap(t=>t.content).map(ie).join("")}function ie(e){return e.type==="refusal"?e.refusal:e.text}function pe(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function l(e){let t=F();for(let n of e){if(!_(n))continue;let s=n.summary?.map(o=>o.text).filter(le)??[];t.reasoningSummaryCount+=s.length,t.reasoningSummaries.push(...s),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function _(e){return e.type==="reasoning"}function F(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function d(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function le(e){return e!==void 0}function L(e){if(e.status==="failed"||e.status==="incomplete")throw new 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 W(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return j({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=$(e),s=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return w(s)}catch(n){let o=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${o}`)}}async function*N(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,s=j({...e,chatOptions:{...e.chatOptions,onTextDelta:o=>{n?.(o),fe(t,de(o));}}}).then(o=>Oe(t,o)).catch(o=>he(t,Te(o)));yield*Ie(t),await s;}async function j(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=me(e),n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return P({stream:n,onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let s=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${s}`)}}function $(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=x(e.chatOptions?.tools,e.providerOptions.strictTools),s=h(e.providerOptions);return {model:t,input:S(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...s!==void 0&&{text:s},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function me(e){return {...$(e),stream:true}}function de(e){return {id:crypto.randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*Ie(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 Ae(e.finalMessage);return}await ge(e);}}function fe(e,t){e.deltas.push(t),I(e);}function Oe(e,t){e.finalMessage=t,I(e);}function he(e,t){e.error=t,I(e);}function ge(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function Ae(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Te(e){return e instanceof Error?e:new Error(String(e))}var a=class extends agentCore.AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||agentCore.SilentLogger),this.options=t,this.apiSurface=ve(t),be(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new ye__default.default({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new i(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(s){throw this.logger.error("OpenAI Provider executor chat error:",s instanceof Error?s.message:String(s)),s}return this.apiSurface==="responses"?W({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):R({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(s){throw this.logger.error("OpenAI Provider executor stream error:",s instanceof Error?s.message:String(s)),s}if(this.apiSurface==="responses"){yield*N({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*C({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let s=n;if(s.toolCalls&&s.toolCalls.length>0&&s.content==="")continue}}};function ve(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function q(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 be(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var Q=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(s=>this.convertMessage(s))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let o=t;return o.toolCalls&&o.toolCalls.length>0?{role:"assistant",content:o.content===""?null:o.content||null,tool_calls:o.toolCalls.map(c=>({id:c.id,type:"function",function:{name:c.function.name,arguments:c.function.arguments}}))}:{role:"assistant",content:o.content===null||o.content===""?null:o.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let s=n;throw new Error(`Unsupported message role: ${s}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(o=>o.role==="system")?t:[{role:"system",content:n},...t]}};var pt=void 0,V="$ENV:OPENAI_API_KEY";function lt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:V},setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:V,masked:true}],requiresApiKey:true,probeProfile:agentProviderOpenaiCompatible.probeOpenAICompatibleProfile,createProvider:e=>{let t=Me(e.options),n=we(e.options);return Pe(e.baseURL,t,n),new a({apiKey:xe(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 xe(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function Me(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function we(e){let t=K(e?.nativeWebTools)??K(e?.builtInWebTools);if(t!==void 0)return t}function K(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 Pe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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.")}exports.DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE=V;exports.DEFAULT_OPENAI_PROVIDER_MODEL=pt;exports.OpenAIConversationAdapter=Q;exports.OpenAIProvider=a;exports.createOpenAIProviderDefinition=lt;
|
|
1
|
+
'use strict';var Se=require('openai'),agentCore=require('@robota-sdk/agent-core'),agentProviderOpenaiCompatible=require('@robota-sdk/agent-provider-openai-compatible'),crypto=require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Se__default=/*#__PURE__*/_interopDefault(Se);var p=class{parser;constructor(t){this.parser=new agentProviderOpenaiCompatible.OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${o}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${o}`)}}};function h(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function g(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=y(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 A(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=y(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 y(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function v(e){return agentProviderOpenaiCompatible.convertToOpenAICompatibleMessages(e)}function T(e){return agentProviderOpenaiCompatible.convertToOpenAICompatibleTools(e)}async function b(e){let t=M(e.client);try{let n=S(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await ee(t,e,{...n,stream:!0});await d(e,n,"chat"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let s=await t.chat.completions.create(n);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"response",payload:s}),e.responseParser.parseResponse(s)}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${s}`)}}async function*P(e){let t=M(e.client);try{let n={...S(e),stream:!0};await d(e,n,"stream"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let s of agentProviderOpenaiCompatible.observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let r=e.responseParser.parseStreamingChunk(s);r&&(yield r);}}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${s}`)}}function S(e){let t=v(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let o=g(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...o!==void 0&&{response_format:o}}}async function ee(e,t,n){try{await d(t,n,"stream"),t.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return agentProviderOpenaiCompatible.assembleOpenAICompatibleStream({stream:agentProviderOpenaiCompatible.observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:t.chatOptions?.onProviderNativeRawPayload}),onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(o){let r=o.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function d(e,t,n){if(!e.payloadLogger?.isEnabled())return;let o={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(o,n);}function M(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function x(e){return e.flatMap(t=>te(t))}function w(e,t){let n=e?.map(o=>({type:"function",name:o.name,description:o.description,parameters:o.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function te(e){if(e.role==="user")return [l("user",oe(e.content,e.parts))];if(e.role==="system")return [l("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return ne(e)}function ne(e){let t=[];e.content&&e.content.length>0&&t.push(l("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(l("assistant","")),t}function oe(e,t){if(!t||t.length===0)return e;let n=t.map(o=>se(o));return e.length>0&&!t.some(o=>o.type==="text")?[{type:"input_text",text:e},...n]:n}function se(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 l(e,t){return {role:e,content:t}}async function*E(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let o=await re(n,t);if(o.done||t?.aborted)break;yield o.value;}}finally{t?.aborted&&await n.return?.();}}async function re(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,o=new Promise(s=>{n=()=>s({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),o])}finally{n&&t.removeEventListener("abort",n);}}function U(e){j(e);let t=e.output??[],n=e.output_text??N(t);return u({content:n,toolCalls:k(t),response:e,reasoning:c(t)})}async function _(e){let t={textParts:[],toolCalls:[],reasoning:W()};for await(let n of E(e.stream,e.signal))ie(t,n,e.onTextDelta);return t.completedResponse!==void 0?le(t):u({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ie(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,m(e.reasoning,c(t.response.output??[]));return}if(t.type==="response.output_item.done"){pe(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${fe(t)}`)}function pe(e,t){if(D(t)){e.toolCalls.push(F(t));return}L(t)&&m(e.reasoning,c([t]));}function le(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");j(t);let n=t.output??[],o=k(n),s=e.textParts.length>0?e.textParts.join(""):t.output_text??N(n),r=c(n);return m(r,e.reasoning),u({content:s,toolCalls:o.length>0?o:e.toolCalls,response:t,reasoning:r})}function u(e){return {id:crypto.randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:de(e.response.usage)},metadata:ce(e.response,e.reasoning)}}function ce(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:true}}}function de(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function k(e){return e.filter(D).map(t=>F(t))}function D(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function F(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function N(e){return e.filter(me).flatMap(t=>t.content).map(ue).join("")}function ue(e){return e.type==="refusal"?e.refusal:e.text}function me(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function c(e){let t=W();for(let n of e){if(!L(n))continue;let o=n.summary?.map(s=>s.text).filter(Ie)??[];t.reasoningSummaryCount+=o.length,t.reasoningSummaries.push(...o),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function L(e){return e.type==="reasoning"}function W(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function m(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function Ie(e){return e!==void 0}function j(e){if(e.status==="failed"||e.status==="incomplete")throw new Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function fe(e){return e.message??e.error?.message??e.response?.error?.message??"unknown error"}async function $(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return q({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=V(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:n});let o=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"response",payload:o}),U(o)}catch(n){let s=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${s}`)}}async function*K(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,o=q({...e,chatOptions:{...e.chatOptions,onTextDelta:s=>{n?.(s),ve(t,Ae(s));}}}).then(s=>Te(t,s)).catch(s=>Re(t,Pe(s)));yield*ye(t),await o;}async function q(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=ge(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:t});let n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return _({stream:agentProviderOpenaiCompatible.observeProviderNativeRawPayloadStream(n,{provider:"openai",apiSurface:"responses",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let o=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${o}`)}}function V(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=w(e.chatOptions?.tools,e.providerOptions.strictTools),o=A(e.providerOptions);return {model:t,input:x(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...o!==void 0&&{text:o},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function ge(e){return {...V(e),stream:true}}function Ae(e){return {id:crypto.randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*ye(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 be(e.finalMessage);return}await Ce(e);}}function ve(e,t){e.deltas.push(t),I(e);}function Te(e,t){e.finalMessage=t,I(e);}function Re(e,t){e.error=t,I(e);}function Ce(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function be(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Pe(e){return e instanceof Error?e:new Error(String(e))}var i=class extends agentCore.AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||agentCore.SilentLogger),this.options=t,this.apiSurface=we(t),Ee(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new Se__default.default({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new p(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(o){throw this.logger.error("OpenAI Provider executor chat error:",o instanceof Error?o.message:String(o)),o}return this.apiSurface==="responses"?$({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):b({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(o){throw this.logger.error("OpenAI Provider executor stream error:",o instanceof Error?o.message:String(o)),o}if(this.apiSurface==="responses"){yield*K({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*P({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let o=n;if(o.toolCalls&&o.toolCalls.length>0&&o.content==="")continue}}};function we(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function Q(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 Ee(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var J=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(o=>this.convertMessage(o))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let s=t;return s.toolCalls&&s.toolCalls.length>0?{role:"assistant",content:s.content===""?null:s.content||null,tool_calls:s.toolCalls.map(a=>({id:a.id,type:"function",function:{name:a.function.name,arguments:a.function.arguments}}))}:{role:"assistant",content:s.content===null||s.content===""?null:s.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let o=n;throw new Error(`Unsupported message role: ${o}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(s=>s.role==="system")?t:[{role:"system",content:n},...t]}};var Ue="https://api.openai.com/v1/models",z="https://platform.openai.com/docs/api-reference/models/list";async function H(e,t={}){if(!e.apiKey)return f("OpenAI model catalog refresh requires apiKey.");let n=t.fetcher??Fe,o=t.now??(()=>new Date),s=_e(e.baseURL);try{let r=await n(s,{headers:{Authorization:`Bearer ${e.apiKey}`}});if(!r.ok)return f(De(r));let a=await r.json(),O=ke(a);return {status:"live",entries:O,lastVerifiedAt:o().toISOString(),sourceUrl:z,message:`${O.length} OpenAI model(s) discovered.`}}catch(r){return f(r instanceof Error?r.message:String(r))}}function _e(e){return e?`${e.replace(/\/$/,"")}/models`:Ue}function ke(e){return (e.data??[]).map(t=>t.id).filter(t=>t!==void 0&&t.trim().length>0).map(t=>({id:t,displayName:t,lifecycle:"active"}))}function De(e){let t=e.statusText?` ${e.statusText}`:"";return `OpenAI model catalog refresh failed: HTTP ${e.status}${t}`}function f(e){return {status:"unavailable",sourceUrl:z,message:e}}async function Fe(e,t){let n=await fetch(e,t);return {ok:n.ok,status:n.status,statusText:n.statusText,json:()=>n.json()}}var St=void 0,Y="$ENV:OPENAI_API_KEY",Le="https://platform.openai.com/api-keys",We="https://developers.openai.com/api/reference/overview#authentication",je="2026-05-08",$e=[{kind:"api-key",label:"OpenAI API keys",url:Le,sourceUrl:We,lastVerifiedAt:je}];function Mt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:Y},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:$e,setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:Y,masked:true}],requiresApiKey:true,probeProfile:agentProviderOpenaiCompatible.probeOpenAICompatibleProfile,refreshModelCatalog:({profile:e})=>H(e),createProvider:e=>{let t=qe(e.options),n=Ve(e.options);return Qe(e.baseURL,t,n),new i({apiKey:Ke(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 Ke(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function qe(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function Ve(e){let t=G(e?.nativeWebTools)??G(e?.builtInWebTools);if(t!==void 0)return t}function G(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 Qe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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.")}
|
|
2
|
+
exports.DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE=Y;exports.DEFAULT_OPENAI_PROVIDER_MODEL=St;exports.OpenAIConversationAdapter=J;exports.OpenAIProvider=i;exports.createOpenAIProviderDefinition=Mt;exports.refreshOpenAIModelCatalog=H;
|
package/dist/node/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
2
|
+
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderProfileConfig, IProviderModelCatalog, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Payload logging data structure
|
|
@@ -278,8 +278,30 @@ declare class OpenAIConversationAdapter {
|
|
|
278
278
|
static addSystemPromptIfNeeded(messages: OpenAI.Chat.ChatCompletionMessageParam[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
interface IOpenAIModelCatalogResponse {
|
|
282
|
+
data?: readonly IOpenAIModelCatalogResource[];
|
|
283
|
+
}
|
|
284
|
+
interface IOpenAIModelCatalogResource {
|
|
285
|
+
id?: string;
|
|
286
|
+
}
|
|
287
|
+
interface IOpenAIModelCatalogFetchInit {
|
|
288
|
+
headers: Record<string, string>;
|
|
289
|
+
}
|
|
290
|
+
interface IOpenAIModelCatalogFetchResponse {
|
|
291
|
+
ok: boolean;
|
|
292
|
+
status: number;
|
|
293
|
+
statusText?: string;
|
|
294
|
+
json: () => Promise<IOpenAIModelCatalogResponse>;
|
|
295
|
+
}
|
|
296
|
+
type TOpenAIModelCatalogFetch = (url: string, init: IOpenAIModelCatalogFetchInit) => Promise<IOpenAIModelCatalogFetchResponse>;
|
|
297
|
+
interface IRefreshOpenAIModelCatalogOptions {
|
|
298
|
+
fetcher?: TOpenAIModelCatalogFetch;
|
|
299
|
+
now?: () => Date;
|
|
300
|
+
}
|
|
301
|
+
declare function refreshOpenAIModelCatalog(profile: IProviderProfileConfig, options?: IRefreshOpenAIModelCatalogOptions): Promise<IProviderModelCatalog>;
|
|
302
|
+
|
|
281
303
|
declare const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined;
|
|
282
304
|
declare const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = "$ENV:OPENAI_API_KEY";
|
|
283
305
|
declare function createOpenAIProviderDefinition(): IProviderDefinition;
|
|
284
306
|
|
|
285
|
-
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition };
|
|
307
|
+
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAIModelCatalogFetchInit, type IOpenAIModelCatalogFetchResponse, type IOpenAIModelCatalogResource, type IOpenAIModelCatalogResponse, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, type IRefreshOpenAIModelCatalogOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIModelCatalogFetch, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition, refreshOpenAIModelCatalog };
|
package/dist/node/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
2
|
+
import { ILogger, IExecutor, TProviderOptionValueBase, AbstractAIProvider, TTextDeltaCallback, TUniversalMessage, IChatOptions, IProviderCapabilities, IProviderProfileConfig, IProviderModelCatalog, IProviderDefinition } from '@robota-sdk/agent-core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Payload logging data structure
|
|
@@ -278,8 +278,30 @@ declare class OpenAIConversationAdapter {
|
|
|
278
278
|
static addSystemPromptIfNeeded(messages: OpenAI.Chat.ChatCompletionMessageParam[], systemPrompt?: string): OpenAI.Chat.ChatCompletionMessageParam[];
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
interface IOpenAIModelCatalogResponse {
|
|
282
|
+
data?: readonly IOpenAIModelCatalogResource[];
|
|
283
|
+
}
|
|
284
|
+
interface IOpenAIModelCatalogResource {
|
|
285
|
+
id?: string;
|
|
286
|
+
}
|
|
287
|
+
interface IOpenAIModelCatalogFetchInit {
|
|
288
|
+
headers: Record<string, string>;
|
|
289
|
+
}
|
|
290
|
+
interface IOpenAIModelCatalogFetchResponse {
|
|
291
|
+
ok: boolean;
|
|
292
|
+
status: number;
|
|
293
|
+
statusText?: string;
|
|
294
|
+
json: () => Promise<IOpenAIModelCatalogResponse>;
|
|
295
|
+
}
|
|
296
|
+
type TOpenAIModelCatalogFetch = (url: string, init: IOpenAIModelCatalogFetchInit) => Promise<IOpenAIModelCatalogFetchResponse>;
|
|
297
|
+
interface IRefreshOpenAIModelCatalogOptions {
|
|
298
|
+
fetcher?: TOpenAIModelCatalogFetch;
|
|
299
|
+
now?: () => Date;
|
|
300
|
+
}
|
|
301
|
+
declare function refreshOpenAIModelCatalog(profile: IProviderProfileConfig, options?: IRefreshOpenAIModelCatalogOptions): Promise<IProviderModelCatalog>;
|
|
302
|
+
|
|
281
303
|
declare const DEFAULT_OPENAI_PROVIDER_MODEL: string | undefined;
|
|
282
304
|
declare const DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE = "$ENV:OPENAI_API_KEY";
|
|
283
305
|
declare function createOpenAIProviderDefinition(): IProviderDefinition;
|
|
284
306
|
|
|
285
|
-
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition };
|
|
307
|
+
export { DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE, DEFAULT_OPENAI_PROVIDER_MODEL, type IOpenAIJsonSchemaDefinition, type IOpenAIModelCatalogFetchInit, type IOpenAIModelCatalogFetchResponse, type IOpenAIModelCatalogResource, type IOpenAIModelCatalogResponse, type IOpenAINativeWebToolsOptions, type IOpenAIProviderOptions, type IOpenAIResponsesReasoningOptions, type IPayloadLogger, type IPayloadLoggerOptions, type IRefreshOpenAIModelCatalogOptions, OpenAIConversationAdapter, OpenAIProvider, type TOpenAIApiSurface, type TOpenAIModelCatalogFetch, type TOpenAIProviderOptionValue, createOpenAIProviderDefinition, refreshOpenAIModelCatalog };
|
package/dist/node/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import ye from'openai';import {AbstractAIProvider,SilentLogger}from'@robota-sdk/agent-core';import {probeOpenAICompatibleProfile,OpenAICompatibleResponseParser,assembleOpenAICompatibleStream,convertToOpenAICompatibleMessages,convertToOpenAICompatibleTools}from'@robota-sdk/agent-provider-openai-compatible';import {randomUUID}from'crypto';var i=class{parser;constructor(t){this.parser=new OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${s}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let s=f(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${s}`)}}};function f(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function O(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=g(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 h(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=g(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 g(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function A(e){return convertToOpenAICompatibleMessages(e)}function T(e){return convertToOpenAICompatibleTools(e)}async function R(e){let t=b(e.client);try{let n=v(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await G(t,e,{...n,stream:!0});await u(e,n,"chat");let o=await t.chat.completions.create(n);return e.responseParser.parseResponse(o)}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${o}`)}}async function*C(e){let t=b(e.client);try{let n={...v(e),stream:!0};await u(e,n,"stream");let s=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let o of s){let r=e.responseParser.parseStreamingChunk(o);r&&(yield r);}}catch(n){let o=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${o}`)}}function v(e){let t=A(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let s=O(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...s!==void 0&&{response_format:s}}}async function G(e,t,n){try{await u(t,n,"stream");let s=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return assembleOpenAICompatibleStream({stream:s,onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(s){let r=s.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function u(e,t,n){if(!e.payloadLogger?.isEnabled())return;let s={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(s,n);}function b(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function S(e){return e.flatMap(t=>B(t))}function x(e,t){let n=e?.map(s=>({type:"function",name:s.name,description:s.description,parameters:s.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function B(e){if(e.role==="user")return [p("user",X(e.content,e.parts))];if(e.role==="system")return [p("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return H(e)}function H(e){let t=[];e.content&&e.content.length>0&&t.push(p("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(p("assistant","")),t}function X(e,t){if(!t||t.length===0)return e;let n=t.map(s=>Z(s));return e.length>0&&!t.some(s=>s.type==="text")?[{type:"input_text",text:e},...n]:n}function Z(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 p(e,t){return {role:e,content:t}}async function*M(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let s=await ee(n,t);if(s.done||t?.aborted)break;yield s.value;}}finally{t?.aborted&&await n.return?.();}}async function ee(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,s=new Promise(o=>{n=()=>o({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),s])}finally{n&&t.removeEventListener("abort",n);}}function w(e){L(e);let t=e.output??[],n=e.output_text??k(t);return m({content:n,toolCalls:E(t),response:e,reasoning:l(t)})}async function P(e){let t={textParts:[],toolCalls:[],reasoning:F()};for await(let n of M(e.stream,e.signal))ne(t,n,e.onTextDelta);return t.completedResponse!==void 0?oe(t):m({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ne(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,d(e.reasoning,l(t.response.output??[]));return}if(t.type==="response.output_item.done"){se(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${ce(t)}`)}function se(e,t){if(U(t)){e.toolCalls.push(D(t));return}_(t)&&d(e.reasoning,l([t]));}function oe(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");L(t);let n=t.output??[],s=E(n),o=e.textParts.length>0?e.textParts.join(""):t.output_text??k(n),r=l(n);return d(r,e.reasoning),m({content:o,toolCalls:s.length>0?s:e.toolCalls,response:t,reasoning:r})}function m(e){return {id:randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:ae(e.response.usage)},metadata:re(e.response,e.reasoning)}}function re(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:true}}}function ae(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function E(e){return e.filter(U).map(t=>D(t))}function U(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function D(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function k(e){return e.filter(pe).flatMap(t=>t.content).map(ie).join("")}function ie(e){return e.type==="refusal"?e.refusal:e.text}function pe(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function l(e){let t=F();for(let n of e){if(!_(n))continue;let s=n.summary?.map(o=>o.text).filter(le)??[];t.reasoningSummaryCount+=s.length,t.reasoningSummaries.push(...s),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function _(e){return e.type==="reasoning"}function F(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function d(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function le(e){return e!==void 0}function L(e){if(e.status==="failed"||e.status==="incomplete")throw new 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 W(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return j({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=$(e),s=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return w(s)}catch(n){let o=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${o}`)}}async function*N(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,s=j({...e,chatOptions:{...e.chatOptions,onTextDelta:o=>{n?.(o),fe(t,de(o));}}}).then(o=>Oe(t,o)).catch(o=>he(t,Te(o)));yield*Ie(t),await s;}async function j(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=me(e),n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return P({stream:n,onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let s=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${s}`)}}function $(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=x(e.chatOptions?.tools,e.providerOptions.strictTools),s=h(e.providerOptions);return {model:t,input:S(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...s!==void 0&&{text:s},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function me(e){return {...$(e),stream:true}}function de(e){return {id:randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*Ie(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 Ae(e.finalMessage);return}await ge(e);}}function fe(e,t){e.deltas.push(t),I(e);}function Oe(e,t){e.finalMessage=t,I(e);}function he(e,t){e.error=t,I(e);}function ge(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function Ae(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Te(e){return e instanceof Error?e:new Error(String(e))}var a=class extends AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||SilentLogger),this.options=t,this.apiSurface=ve(t),be(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new ye({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new i(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(s){throw this.logger.error("OpenAI Provider executor chat error:",s instanceof Error?s.message:String(s)),s}return this.apiSurface==="responses"?W({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):R({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(s){throw this.logger.error("OpenAI Provider executor stream error:",s instanceof Error?s.message:String(s)),s}if(this.apiSurface==="responses"){yield*N({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*C({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let s=n;if(s.toolCalls&&s.toolCalls.length>0&&s.content==="")continue}}};function ve(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function q(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 be(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var Q=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(s=>this.convertMessage(s))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let o=t;return o.toolCalls&&o.toolCalls.length>0?{role:"assistant",content:o.content===""?null:o.content||null,tool_calls:o.toolCalls.map(c=>({id:c.id,type:"function",function:{name:c.function.name,arguments:c.function.arguments}}))}:{role:"assistant",content:o.content===null||o.content===""?null:o.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let s=n;throw new Error(`Unsupported message role: ${s}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(o=>o.role==="system")?t:[{role:"system",content:n},...t]}};var pt=void 0,V="$ENV:OPENAI_API_KEY";function lt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:V},setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:V,masked:true}],requiresApiKey:true,probeProfile:probeOpenAICompatibleProfile,createProvider:e=>{let t=Me(e.options),n=we(e.options);return Pe(e.baseURL,t,n),new a({apiKey:xe(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 xe(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function Me(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function we(e){let t=K(e?.nativeWebTools)??K(e?.builtInWebTools);if(t!==void 0)return t}function K(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 Pe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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{V as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,pt as DEFAULT_OPENAI_PROVIDER_MODEL,Q as OpenAIConversationAdapter,a as OpenAIProvider,lt as createOpenAIProviderDefinition};
|
|
1
|
+
import Se from'openai';import {AbstractAIProvider,SilentLogger}from'@robota-sdk/agent-core';import {probeOpenAICompatibleProfile,OpenAICompatibleResponseParser,observeProviderNativeRawPayloadStream,assembleOpenAICompatibleStream,convertToOpenAICompatibleMessages,convertToOpenAICompatibleTools}from'@robota-sdk/agent-provider-openai-compatible';import {randomUUID}from'crypto';var p=class{parser;constructor(t){this.parser=new OpenAICompatibleResponseParser({logger:t});}parseResponse(t){try{return this.parser.parseResponse(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI response parsing failed");throw new Error(`OpenAI response parsing failed: ${o}`)}}parseStreamingChunk(t){try{return this.parser.parseStreamingChunk(t)}catch(n){let o=h(n instanceof Error?n.message:"OpenAI chunk parsing failed");throw new Error(`OpenAI chunk parsing failed: ${o}`)}}};function h(e){return e.replace(/^OpenAI-compatible response parsing failed: /,"").replace(/^OpenAI-compatible chunk parsing failed: /,"").replace("OpenAI-compatible response","OpenAI response")}function g(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {type:"json_object"};let t=y(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 A(e){if(e.responseFormat===void 0||e.responseFormat==="text")return;if(e.responseFormat==="json_object")return {format:{type:"json_object"}};let t=y(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 y(e){let t=e.jsonSchema;if(e.responseFormat!=="json_schema")throw new Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw new 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}}}function v(e){return convertToOpenAICompatibleMessages(e)}function T(e){return convertToOpenAICompatibleTools(e)}async function b(e){let t=M(e.client);try{let n=S(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await ee(t,e,{...n,stream:!0});await d(e,n,"chat"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let s=await t.chat.completions.create(n);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"response",payload:s}),e.responseParser.parseResponse(s)}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI chat failed: ${s}`)}}async function*P(e){let t=M(e.client);try{let n={...S(e),stream:!0};await d(e,n,"stream"),e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await t.chat.completions.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);for await(let s of observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let r=e.responseParser.parseStreamingChunk(s);r&&(yield r);}}catch(n){let s=n.message||"OpenAI API request failed";throw new Error(`OpenAI stream failed: ${s}`)}}function S(e){let t=v(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let o=g(e.providerOptions);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:T(e.chatOptions.tools),tool_choice:"auto"},...o!==void 0&&{response_format:o}}}async function ee(e,t,n){try{await d(t,n,"stream"),t.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"chat-completions",payloadKind:"request",payload:n});let o=await e.chat.completions.create(n,t.chatOptions?.signal?{signal:t.chatOptions.signal}:void 0);return assembleOpenAICompatibleStream({stream:observeProviderNativeRawPayloadStream(o,{provider:"openai",apiSurface:"chat-completions",onProviderNativeRawPayload:t.chatOptions?.onProviderNativeRawPayload}),onTextDelta:t.chatOptions?.onTextDelta??t.onTextDelta,signal:t.chatOptions?.signal})}catch(o){let r=o.message||"OpenAI streaming request failed";throw new Error(`OpenAI stream failed: ${r}`)}}async function d(e,t,n){if(!e.payloadLogger?.isEnabled())return;let o={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(o,n);}function M(e){if(!e)throw new Error("OpenAI client not available. Either provide a client/apiKey or use an executor.");return e}function x(e){return e.flatMap(t=>te(t))}function w(e,t){let n=e?.map(o=>({type:"function",name:o.name,description:o.description,parameters:o.parameters,strict:t??false}))??[];return n.length>0?n:void 0}function te(e){if(e.role==="user")return [l("user",oe(e.content,e.parts))];if(e.role==="system")return [l("system",e.content)];if(e.role==="tool"){if(!e.toolCallId||e.toolCallId.trim().length===0)throw new Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return [{type:"function_call_output",call_id:e.toolCallId,output:e.content||""}]}return ne(e)}function ne(e){let t=[];e.content&&e.content.length>0&&t.push(l("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(l("assistant","")),t}function oe(e,t){if(!t||t.length===0)return e;let n=t.map(o=>se(o));return e.length>0&&!t.some(o=>o.type==="text")?[{type:"input_text",text:e},...n]:n}function se(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 l(e,t){return {role:e,content:t}}async function*E(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let o=await re(n,t);if(o.done||t?.aborted)break;yield o.value;}}finally{t?.aborted&&await n.return?.();}}async function re(e,t){if(!t)return e.next();if(t.aborted)return {done:true,value:void 0};let n,o=new Promise(s=>{n=()=>s({done:true,value:void 0}),t.addEventListener("abort",n,{once:true});});try{return await Promise.race([e.next(),o])}finally{n&&t.removeEventListener("abort",n);}}function U(e){j(e);let t=e.output??[],n=e.output_text??N(t);return u({content:n,toolCalls:k(t),response:e,reasoning:c(t)})}async function _(e){let t={textParts:[],toolCalls:[],reasoning:W()};for await(let n of E(e.stream,e.signal))ie(t,n,e.onTextDelta);return t.completedResponse!==void 0?le(t):u({content:t.textParts.join(""),toolCalls:t.toolCalls,reasoning:t.reasoning})}function ie(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,m(e.reasoning,c(t.response.output??[]));return}if(t.type==="response.output_item.done"){pe(e,t.item);return}if(t.type==="response.error"||t.type==="response.failed"||t.type==="response.incomplete")throw new Error(`OpenAI Responses API failed: ${fe(t)}`)}function pe(e,t){if(D(t)){e.toolCalls.push(F(t));return}L(t)&&m(e.reasoning,c([t]));}function le(e){let t=e.completedResponse;if(t===void 0)throw new Error("OpenAI Responses stream completed without response metadata");j(t);let n=t.output??[],o=k(n),s=e.textParts.length>0?e.textParts.join(""):t.output_text??N(n),r=c(n);return m(r,e.reasoning),u({content:s,toolCalls:o.length>0?o:e.toolCalls,response:t,reasoning:r})}function u(e){return {id:randomUUID(),role:"assistant",content:e.content,state:"complete",timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:de(e.response.usage)},metadata:ce(e.response,e.reasoning)}}function ce(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:true}}}function de(e){return {promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function k(e){return e.filter(D).map(t=>F(t))}function D(e){return e.type==="function_call"&&"call_id"in e&&"name"in e&&"arguments"in e}function F(e){return {id:e.call_id,type:"function",function:{name:e.name,arguments:e.arguments}}}function N(e){return e.filter(me).flatMap(t=>t.content).map(ue).join("")}function ue(e){return e.type==="refusal"?e.refusal:e.text}function me(e){return e.type==="message"&&"content"in e&&Array.isArray(e.content)}function c(e){let t=W();for(let n of e){if(!L(n))continue;let o=n.summary?.map(s=>s.text).filter(Ie)??[];t.reasoningSummaryCount+=o.length,t.reasoningSummaries.push(...o),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content;}return t}function L(e){return e.type==="reasoning"}function W(){return {reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:false}}function m(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning;}function Ie(e){return e!==void 0}function j(e){if(e.status==="failed"||e.status==="incomplete")throw new Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function fe(e){return e.message??e.error?.message??e.response?.error?.message??"unknown error"}async function $(e){let t=e.chatOptions?.onTextDelta??e.onTextDelta;if(t)return q({...e,chatOptions:{...e.chatOptions,onTextDelta:t}});if(!e.client)throw new Error("OpenAI Responses client not available.");try{let n=V(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:n});let o=await e.client.responses.create(n,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"response",payload:o}),U(o)}catch(n){let s=n.message||"OpenAI Responses API request failed";throw new Error(`OpenAI responses failed: ${s}`)}}async function*K(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,o=q({...e,chatOptions:{...e.chatOptions,onTextDelta:s=>{n?.(s),ve(t,Ae(s));}}}).then(s=>Te(t,s)).catch(s=>Re(t,Pe(s)));yield*ye(t),await o;}async function q(e){if(!e.client)throw new Error("OpenAI Responses client not available.");try{let t=ge(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:"openai",apiSurface:"responses",payloadKind:"request",payload:t});let n=await e.client.responses.create(t,e.chatOptions?.signal?{signal:e.chatOptions.signal}:void 0);return _({stream:observeProviderNativeRawPayloadStream(n,{provider:"openai",apiSurface:"responses",onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal})}catch(t){let o=t.message||"OpenAI Responses streaming request failed";throw new Error(`OpenAI responses stream failed: ${o}`)}}function V(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw new Error("Model is required in chat options. Please specify a model in defaultModel configuration.");let n=w(e.chatOptions?.tools,e.providerOptions.strictTools),o=A(e.providerOptions);return {model:t,input:x(e.messages),...n!==void 0&&{tools:n,tool_choice:"auto"},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...o!==void 0&&{text:o},...e.providerOptions.reasoning!==void 0&&{reasoning:e.providerOptions.reasoning},...e.providerOptions.includeEncryptedReasoning===true&&{include:["reasoning.encrypted_content"]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function ge(e){return {...V(e),stream:true}}function Ae(e){return {id:randomUUID(),role:"assistant",content:e,state:"complete",timestamp:new Date,metadata:{providerApiSurface:"responses",isStreamChunk:true,isComplete:false}}}async function*ye(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 be(e.finalMessage);return}await Ce(e);}}function ve(e,t){e.deltas.push(t),I(e);}function Te(e,t){e.finalMessage=t,I(e);}function Re(e,t){e.error=t,I(e);}function Ce(e){return new Promise(t=>{e.wake=t;})}function I(e){e.wake?.(),e.wake=void 0;}function be(e){return {...e,content:"",metadata:{...e.metadata,isStreamChunk:true,isComplete:true}}}function Pe(e){return e instanceof Error?e:new Error(String(e))}var i=class extends AbstractAIProvider{name="openai";version="1.0.0";client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(t){if(super(t.logger||SilentLogger),this.options=t,this.apiSurface=we(t),Ee(this.apiSurface,t.nativeWebTools),t.executor&&(this.executor=t.executor),!this.executor)if(t.client)this.client=t.client;else if(t.apiKey)this.client=new Se({apiKey:t.apiKey,...t.organization&&{organization:t.organization},...t.timeout&&{timeout:t.timeout},...t.baseURL&&{baseURL:t.baseURL}});else throw new Error("Either OpenAI client, apiKey, or executor is required");this.responseParser=new p(this.logger),this.payloadLogger=t.payloadLogger;}async chat(t,n){if(this.validateMessages(t),this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{return await this.executeViaExecutorOrDirect(t,n)}catch(o){throw this.logger.error("OpenAI Provider executor chat error:",o instanceof Error?o.message:String(o)),o}return this.apiSurface==="responses"?$({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta}):b({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta})}async*chatStream(t,n){if(this.validateNativeWebTools(n?.nativeWebTools),this.executor)try{yield*this.executeStreamViaExecutorOrDirect(t,n);return}catch(o){throw this.logger.error("OpenAI Provider executor stream error:",o instanceof Error?o.message:String(o)),o}if(this.apiSurface==="responses"){yield*K({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,onTextDelta:this.onTextDelta});return}yield*P({client:this.client,messages:t,chatOptions:n,providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta});}supportsTools(){return true}getCapabilities(){let t=this.apiSurface==="chat-completions"?"openai-compatible-chat-completions":"openai-responses";return {functionCalling:{supported:true},nativeWebTools:{webSearch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"search")},webFetch:{supported:false,enabled:false,source:t,reason:Q(this.apiSurface,"fetch")}}}}validateConfig(){return !!this.client&&!!this.options}async dispose(){}validateMessages(t){super.validateMessages(t);for(let n of t)if(n.role==="assistant"){let o=n;if(o.toolCalls&&o.toolCalls.length>0&&o.content==="")continue}}};function we(e){return e.apiSurface!==void 0?e.apiSurface:e.baseURL?"chat-completions":"responses"}function Q(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 Ee(e,t){if(!(t?.webSearch!==true&&t?.webFetch!==true))throw new Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var J=class{static filterMessagesForOpenAI(t){return t.filter(n=>n.role==="user"||n.role==="assistant"||n.role==="system"?true:n.role==="tool"?!!(n.toolCallId&&n.toolCallId.trim()!==""&&n.toolCallId!=="unknown"):false)}static toOpenAIFormat(t){return this.filterMessagesForOpenAI(t).map(o=>this.convertMessage(o))}static convertMessage(t){let n=t.role;if(n==="user")return {role:"user",content:t.content};if(n==="assistant"){let s=t;return s.toolCalls&&s.toolCalls.length>0?{role:"assistant",content:s.content===""?null:s.content||null,tool_calls:s.toolCalls.map(a=>({id:a.id,type:"function",function:{name:a.function.name,arguments:a.function.arguments}}))}:{role:"assistant",content:s.content===null||s.content===""?null:s.content||""}}if(n==="system")return {role:"system",content:t.content};if(n==="tool"){if(!t.toolCallId||t.toolCallId.trim()==="")throw new Error(`Tool message missing toolCallId: ${JSON.stringify(t)}`);return {role:"tool",content:t.content,tool_call_id:t.toolCallId}}let o=n;throw new Error(`Unsupported message role: ${o}`)}static addSystemPromptIfNeeded(t,n){return !n||t.some(s=>s.role==="system")?t:[{role:"system",content:n},...t]}};var Ue="https://api.openai.com/v1/models",z="https://platform.openai.com/docs/api-reference/models/list";async function H(e,t={}){if(!e.apiKey)return f("OpenAI model catalog refresh requires apiKey.");let n=t.fetcher??Fe,o=t.now??(()=>new Date),s=_e(e.baseURL);try{let r=await n(s,{headers:{Authorization:`Bearer ${e.apiKey}`}});if(!r.ok)return f(De(r));let a=await r.json(),O=ke(a);return {status:"live",entries:O,lastVerifiedAt:o().toISOString(),sourceUrl:z,message:`${O.length} OpenAI model(s) discovered.`}}catch(r){return f(r instanceof Error?r.message:String(r))}}function _e(e){return e?`${e.replace(/\/$/,"")}/models`:Ue}function ke(e){return (e.data??[]).map(t=>t.id).filter(t=>t!==void 0&&t.trim().length>0).map(t=>({id:t,displayName:t,lifecycle:"active"}))}function De(e){let t=e.statusText?` ${e.statusText}`:"";return `OpenAI model catalog refresh failed: HTTP ${e.status}${t}`}function f(e){return {status:"unavailable",sourceUrl:z,message:e}}async function Fe(e,t){let n=await fetch(e,t);return {ok:n.ok,status:n.status,statusText:n.statusText,json:()=>n.json()}}var St=void 0,Y="$ENV:OPENAI_API_KEY",Le="https://platform.openai.com/api-keys",We="https://developers.openai.com/api/reference/overview#authentication",je="2026-05-08",$e=[{kind:"api-key",label:"OpenAI API keys",url:Le,sourceUrl:We,lastVerifiedAt:je}];function Mt(){return {type:"openai",displayName:"OpenAI",description:"Official OpenAI Responses API provider",defaults:{apiKey:Y},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:$e,setupSteps:[{key:"model",title:"OpenAI model",required:true},{key:"apiKey",title:"OpenAI API key",defaultValue:Y,masked:true}],requiresApiKey:true,probeProfile:probeOpenAICompatibleProfile,refreshModelCatalog:({profile:e})=>H(e),createProvider:e=>{let t=qe(e.options),n=Ve(e.options);return Qe(e.baseURL,t,n),new i({apiKey:Ke(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 Ke(e){if(!e)throw new Error("Provider openai requires apiKey");return e}function qe(e){let t=e?.apiSurface;if(t==="responses"||t==="chat-completions")return t}function Ve(e){let t=G(e?.nativeWebTools)??G(e?.builtInWebTools);if(t!==void 0)return t}function G(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 Qe(e,t,n){if(!(n?.webSearch!==true&&n?.webFetch!==true))throw e!==void 0||t==="chat-completions"?new Error("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."):new Error("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.")}
|
|
2
|
+
export{Y as DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE,St as DEFAULT_OPENAI_PROVIDER_MODEL,J as OpenAIConversationAdapter,i as OpenAIProvider,Mt as createOpenAIProviderDefinition,H as refreshOpenAIModelCatalog};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-provider-openai",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.61",
|
|
4
4
|
"description": "OpenAI integration for Robota SDK using the Responses API, structured outputs, streaming, and tool calling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/node/index.d.ts",
|
|
12
|
+
"source": "./src/index.ts",
|
|
12
13
|
"node": {
|
|
13
14
|
"import": "./dist/node/index.js",
|
|
14
15
|
"require": "./dist/node/index.cjs"
|
|
@@ -76,10 +77,10 @@
|
|
|
76
77
|
"license": "MIT",
|
|
77
78
|
"dependencies": {
|
|
78
79
|
"openai": "^4.98.0",
|
|
79
|
-
"@robota-sdk/agent-provider-openai-compatible": "3.0.0-beta.
|
|
80
|
+
"@robota-sdk/agent-provider-openai-compatible": "3.0.0-beta.61"
|
|
80
81
|
},
|
|
81
82
|
"peerDependencies": {
|
|
82
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
83
|
+
"@robota-sdk/agent-core": "3.0.0-beta.61"
|
|
83
84
|
},
|
|
84
85
|
"devDependencies": {
|
|
85
86
|
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
|
@@ -89,7 +90,7 @@
|
|
|
89
90
|
"tsup": "^8.0.1",
|
|
90
91
|
"typescript": "^5.3.3",
|
|
91
92
|
"vitest": "^1.1.0",
|
|
92
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
93
|
+
"@robota-sdk/agent-core": "3.0.0-beta.61"
|
|
93
94
|
},
|
|
94
95
|
"publishConfig": {
|
|
95
96
|
"access": "public"
|