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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +207 -0
  2. package/README.md +110 -0
  3. package/dist/node/index.cjs +1 -1
  4. package/dist/node/index.d.cts +8 -3
  5. package/dist/node/index.d.cts.map +1 -1
  6. package/dist/node/index.d.ts +8 -3
  7. package/dist/node/index.d.ts.map +1 -1
  8. package/dist/node/index.js +1 -1
  9. package/dist/node/index.js.map +1 -1
  10. package/dist/node/loggers/index.d.cts +6 -6
  11. package/dist/node/loggers/index.d.cts.map +1 -1
  12. package/dist/node/loggers/index.d.ts +6 -6
  13. package/dist/node/loggers/index.d.ts.map +1 -1
  14. package/dist/node/loggers/index.js.map +1 -1
  15. package/dist/node/{payload-logger-BaW0K8yI.d.ts → payload-logger-n89AQdUn.d.cts} +6 -4
  16. package/dist/node/payload-logger-n89AQdUn.d.cts.map +1 -0
  17. package/dist/node/{payload-logger-BaW0K8yI.d.cts → payload-logger-n89AQdUn.d.ts} +6 -4
  18. package/dist/node/payload-logger-n89AQdUn.d.ts.map +1 -0
  19. package/package.json +10 -5
  20. package/src/openai/__tests__/abort-signal-wire.test.ts +210 -0
  21. package/src/openai/__tests__/strict-tools-closure.test.ts +49 -2
  22. package/src/openai/__tests__/tool-schema-projection.test.ts +16 -2
  23. package/src/openai/chat-completions-chat.ts +2 -2
  24. package/src/openai/interfaces/payload-logger.ts +5 -3
  25. package/src/openai/loggers/console-payload-logger.ts +2 -2
  26. package/src/openai/loggers/file-payload-logger.ts +6 -5
  27. package/src/openai/message-converter.ts +7 -3
  28. package/src/openai/responses-parser.test.ts +87 -0
  29. package/src/openai/responses-parser.ts +15 -9
  30. package/src/openai/responses-types.ts +2 -0
  31. package/src/openai/types.ts +7 -2
  32. package/dist/node/payload-logger-BaW0K8yI.d.cts.map +0 -1
  33. package/dist/node/payload-logger-BaW0K8yI.d.ts.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,207 @@
1
+ # @robota-sdk/agent-provider-openai
2
+
3
+ ## 3.0.0-beta.83
4
+
5
+ ### Patch Changes
6
+
7
+ - 8bd5fac: Cached input tokens are no longer dropped (#3209 R3). The OpenAI and OpenAI-compatible adapters read
8
+ `prompt_tokens_details.cached_tokens` (Chat Completions, including the final streamed usage chunk) and
9
+ `input_tokens_details.cached_tokens` (Responses, OpenAI and Qwen) into `cacheReadTokens` on the message
10
+ usage: the part of the prompt served from the provider's prompt cache, present only when reported.
11
+ It reaches the committed assistant message, `readTokenUsageFromMessage()`, and the
12
+ `provider_call_completed` execution event, so a consumer can apply the cache discount.
13
+
14
+ New `sumMessagesUsage(messages)` sums the usage on assistant messages (with `cacheReadTokens` when any
15
+ reported it), so one run's usage is `sumMessagesUsage(agent.getHistory().slice(before))` without
16
+ converting through `messageToHistoryEntry` (#3209 S1). `sumHistoryUsage` returns the same triple as before.
17
+
18
+ A forced-summary reply now keeps the usage its provider reported the same way a tool round's reply
19
+ does: an endpoint that omits `total_tokens` no longer loses exactly the summary call's usage (#3209 N3). Counts
20
+ the adapter could not attest as a consistent total are recorded with `usageProvenance: 'partial'`.
21
+
22
+ - 274328f: `OpenAIProvider({ strictTools: true })` now requests strict function calling on the Chat Completions
23
+ surface too (each tool is sent with `function.strict: true`), not only on the Responses surface. This
24
+ matters for every provider created with a `baseURL`, which defaults to Chat Completions. With
25
+ `strictTools` off the request is unchanged. `convertToOpenAICompatibleTools` accepts an optional
26
+ `{ strict }` argument.
27
+ - 57280bf: Every published package now declares `"engines": { "node": ">=22.12.0" }`. Before, 27 of the 38
28
+ packages declared no floor (`agent-core`, `agent-tools` and every provider among them),
29
+ `agent-session` and `agent-file-authority` declared `>=20.19.0`, and the other nine declared
30
+ `>=22.0.0`, so a consumer on Node 20 saw at most a warning from a transitive dependency.
31
+
32
+ Why 22.12: `agent-cli` and `agent-ui-terminal` need Node 22 through `ink` 7, and the CommonJS entries
33
+ of `agent-tools` and its dependents, `agent-transport`/`node` and its dependents, and
34
+ `agent-ui-terminal` `require()` ESM-only dependencies (`p-limit`, `jose`, `chalk`), which Node 22
35
+ supports unflagged only from 22.12. `engines` is advisory unless the consumer enables `engine-strict`.
36
+
37
+ No code changes: `tsdown` now reads `node22.12.0` as its build target from the field.
38
+
39
+ - 643effb: Aborting a run now cancels the provider's HTTP request on every call path. The non-streaming
40
+ `chat()` request — the one a forced end-of-round summary makes — sent no `AbortSignal` on OpenAI
41
+ Chat Completions, DeepSeek, Qwen (Chat Completions) and Gemma, so an aborted run left that request
42
+ running to completion; the same held for `chatStream()` on DeepSeek, Qwen (Chat Completions), Gemma
43
+ and Anthropic. Each now hands the call's `signal` to the SDK request.
44
+ - 18c0d5c: Every published package now exports `./package.json`, so `require('<package>/package.json')` and
45
+ `import('<package>/package.json', { with: { type: 'json' } })` work instead of failing with
46
+ `ERR_PACKAGE_PATH_NOT_EXPORTED`, and each tarball now ships the package's `CHANGELOG.md`.
47
+ - Updated dependencies [e689c8e]
48
+ - Updated dependencies [be0e53c]
49
+ - Updated dependencies [8bd5fac]
50
+ - Updated dependencies [274328f]
51
+ - Updated dependencies [57280bf]
52
+ - Updated dependencies [5033dd9]
53
+ - Updated dependencies [643effb]
54
+ - Updated dependencies [18c0d5c]
55
+ - Updated dependencies [dbd888d]
56
+ - Updated dependencies [1887e54]
57
+ - @robota-sdk/agent-core@3.0.0-beta.83
58
+ - @robota-sdk/agent-provider-openai-compatible@3.0.0-beta.83
59
+
60
+ ## 3.0.0-beta.82
61
+
62
+ ### Patch Changes
63
+
64
+ - Updated dependencies [c7f9203]
65
+ - @robota-sdk/agent-core@3.0.0-beta.82
66
+ - @robota-sdk/agent-provider-openai-compatible@3.0.0-beta.82
67
+
68
+ ## 3.0.0-beta.81
69
+
70
+ ### Patch Changes
71
+
72
+ - Updated dependencies [3038eb7]
73
+ - Updated dependencies [02b7452]
74
+ - Updated dependencies [ec5e477]
75
+ - @robota-sdk/agent-core@3.0.0-beta.81
76
+ - @robota-sdk/agent-provider-openai-compatible@3.0.0-beta.81
77
+
78
+ ## 3.0.0-beta.80
79
+
80
+ ### Minor Changes
81
+
82
+ - 1698be4: A child-process subagent can no longer send the parent's provider credential to a different
83
+ endpoint.
84
+
85
+ - **Before spawning a child**, the parent compares every environment variable that decides where
86
+ the provider connects or which credential it sends. If the child's environment differs, the job
87
+ is refused before the credential leaves the parent. The error names the variable, never its
88
+ value. The variables compared are:
89
+ - the proxy and TLS variables;
90
+ - the variables the provider's SDK reads, such as `OPENAI_BASE_URL`, `ANTHROPIC_AUTH_TOKEN` and
91
+ the Vertex settings;
92
+ - the credential's own variable.
93
+ - **The child** repeats the check before it builds its provider. It builds that provider from the
94
+ parent's effective connection exactly: it no longer fills in a base URL, options or a default
95
+ credential from its own registry, and a credential reference that resolves to nothing is refused.
96
+ - **Where the effective connection comes from:** the parent applies its own definition defaults
97
+ (base URL, options). `profileName` is sent only when it names the connection actually sent.
98
+ - **New contracts:**
99
+ - `IProviderDefinition.destinationEnvironment`, declared by every built-in provider.
100
+ - `createProviderFromExactProfile`, `connectionEnvironmentNames`,
101
+ `findConnectionEnvironmentDivergence`, `sealConnectionEnvironment`,
102
+ `verifyConnectionEnvironment` and `TRANSPORT_ENVIRONMENT`.
103
+ - The start payload's `connectionCheck`.
104
+ - The child-process runner's `providerDefinitions` option, now required: a provider with no
105
+ definition there is refused, because its connection cannot be checked.
106
+
107
+ - 4c73a0b: Provider failures keep the vendor's HTTP status and error type. `ProviderError` gains `status` and `type`, adapters throw `ProviderError` (or `RateLimitError` for a rate limit) instead of a bare `Error`, an Anthropic mid-stream `overloaded_error` event surfaces as a `ProviderError` with that type, and media errors carry `status`. New `classifyProviderFailure` says whether a failure is worth retrying on another model, and `toProviderError` is the shared adapter mapping.
108
+ - 7937c19: Split the `@robota-sdk/agent-provider` monolith into SDK-aligned leaf packages (ARCH-PROVIDER-002 Stage A). The single package that hard-bundled all three vendor SDKs (`@anthropic-ai/sdk`, `openai`, `@google/genai`) is **removed** and replaced by per-vendor leaves, each depending only on `@robota-sdk/agent-core` + its one SDK: `@robota-sdk/agent-provider-anthropic`, `@robota-sdk/agent-provider-openai`, `@robota-sdk/agent-provider-openai-compatible` (DeepSeek/Qwen/Gemma over the shared OpenAI-compatible base), `@robota-sdk/agent-provider-gemini` (+ a `./google` entry), and `@robota-sdk/agent-provider-bytedance` (media/video `IVideoGenerationProvider`). The aggregated `createDefaultProviderDefinitions()` now lives in the new `@robota-sdk/agent-builtin-providers` leaf.
109
+
110
+ Migration: replace `@robota-sdk/agent-provider/<vendor>` imports with the corresponding `@robota-sdk/agent-provider-<vendor>` package (`/deepseek`, `/qwen`, `/gemma` → `@robota-sdk/agent-provider-openai-compatible`; `/google` → `@robota-sdk/agent-provider-gemini/google`), and import `createDefaultProviderDefinitions` from `@robota-sdk/agent-builtin-providers`. Consumers now pull only the vendor SDK(s) they actually use.
111
+
112
+ ### Patch Changes
113
+
114
+ - 9fbab1b: Provider DIP Stage B (ARCH-PROVIDER-003), part 1: collapse infrastructure. Adds the
115
+ provider-registry-driven `@robota-sdk/dag-node-llm-text` node that supersedes the
116
+ per-vendor LLM nodes + router, relocates the provider config resolver into
117
+ `agent-core`, adds SSOT cost/allowedModels fields, inverts the `llm-text` validator
118
+ tombstone, and wires `createDagFramework({ providers })`. Additive — the per-vendor
119
+ nodes still exist; consumer migration + their removal follow in part 2.
120
+ - 4f3c075: Assemble complete, verified package generations before switching build output; preserve the previous generation on build failure and pack only verified regular-file images. Include copied CLI web assets in affected-build ordering and artifact transfer. Preserve the CLI version in managed build paths. Public runtime contracts remain compatible (patch).
121
+ - b6d14ce: Make the universal JSON-schema subset able to express an object, so a nested `z.object()` keeps its
122
+ properties and required fields instead of reaching the model as `{ "type": "object" }`. Tools and
123
+ structured-output schemas with one level of nesting are now advertised in full and enforced on the
124
+ tool-input path; `z.union` / `z.discriminatedUnion` / `z.literal` are supported and map to `anyOf`
125
+ and single-value enums; `.nullable()` keeps its null branch; and Zod's `strip`, `strict` and
126
+ `passthrough` modes stop collapsing into two `additionalProperties` emissions. Fixes the shipped
127
+ `Computer` and `AskUserQuestion` built-ins, whose action and question fields were being dropped
128
+ entirely.
129
+
130
+ `agent-core` is **minor**, not patch: `IObjectParameterSchema` is a new export, and
131
+ `IParameterSchema.type` became optional (a union node carries `anyOf` instead of a type), which is a
132
+ consumer-visible type change — two call sites in this repo needed editing to keep compiling.
133
+ `additionalProperties` also widened to `boolean | IParameterSchema`, and `required` and `anyOf` are
134
+ new members. The provider packages are **patch**: each adapts to the widened subset without changing
135
+ its own public surface.
136
+
137
+ - 93d061d: CORE-043: structured output now knows which transport can carry the schema before the first call
138
+
139
+ `run(input, { output })` asked every provider for `responseFormat: { type: 'json_schema' }`. A
140
+ provider whose surface cannot express that accepted the option and dropped it — and the schema was
141
+ stated in words only by the RETRY feedback turn, which runs on attempt two. So against such a
142
+ provider, attempt one carried nothing describing the required shape and could only succeed by luck:
143
+ the advertised three attempts were really two, and the first was spent discovering something the
144
+ capability table already knew.
145
+
146
+ A `(provider, model)` pair now resolves to a mechanism (`response_schema` / `json_object` / `none`)
147
+ and a provenance (`catalog` / `vendor-default` / `undeclared` / `unverified-endpoint`), and the
148
+ request is shaped to match at the one seam that holds both the resolved provider and the outgoing
149
+ messages. When the wire cannot carry the shape, the schema is stated in the prompt on the FIRST
150
+ attempt. Each structured request emits a `structured_output_transport` event reporting what the
151
+ request actually did.
152
+
153
+ - `IAIProvider.endpointIsVendorDefault?()` — a provider configured with a custom `baseURL` reports
154
+ it, so the runtime stops claiming enforcement a gateway may not provide. Separate from
155
+ `capabilityTable?()` on purpose: `@robota-sdk/agent-provider-openai` declares no table (nobody has
156
+ verified one) and must still be able to answer.
157
+ - DeepSeek's capability table declared `json_schema`; DeepSeek guarantees the response PARSES but
158
+ takes no schema parameter. Corrected to `json_object`.
159
+ - A provider that declares nothing is still sent the request unchanged — silence is not a denial.
160
+
161
+ - ebd40a0: Harden on-disk log permissions against CWE-377 (SEC-003, CodeQL `js/insecure-temporary-file`).
162
+
163
+ Session logs, externalized session payloads, and OpenAI request/response payload logs all carry
164
+ conversation and prompt content, but were created with the process umask (typically `0644`) inside a
165
+ caller-supplied directory that may be shared or world-writable. They are now created owner-only
166
+ (`0600`), and the directories that hold them are created `0700`.
167
+
168
+ This is a permissions change only — file locations, names, formats, and APIs are unchanged. Anything
169
+ that read these logs as a _different_ OS user will no longer be able to; the owning user is
170
+ unaffected.
171
+
172
+ - Updated dependencies [7b6234c]
173
+ - Updated dependencies [4eea54b]
174
+ - Updated dependencies [1698be4]
175
+ - Updated dependencies [d4189b9]
176
+ - Updated dependencies [9edae52]
177
+ - Updated dependencies [4078a72]
178
+ - Updated dependencies [4c73a0b]
179
+ - Updated dependencies [196a900]
180
+ - Updated dependencies [f336838]
181
+ - Updated dependencies [34e50f0]
182
+ - Updated dependencies [722e88a]
183
+ - Updated dependencies [d23c848]
184
+ - Updated dependencies [fec722f]
185
+ - Updated dependencies [2d3b2c0]
186
+ - Updated dependencies [4772067]
187
+ - Updated dependencies [7937c19]
188
+ - Updated dependencies [9fbab1b]
189
+ - Updated dependencies [a009f5b]
190
+ - Updated dependencies [4f3c075]
191
+ - Updated dependencies [475e085]
192
+ - Updated dependencies [e477440]
193
+ - Updated dependencies [9dcb5da]
194
+ - Updated dependencies [a95ca85]
195
+ - Updated dependencies [b6d14ce]
196
+ - Updated dependencies [0382a51]
197
+ - Updated dependencies [93d061d]
198
+ - Updated dependencies [39554a1]
199
+ - Updated dependencies [d28430a]
200
+ - Updated dependencies [07b627f]
201
+ - Updated dependencies [d0de5b2]
202
+ - Updated dependencies [2916d00]
203
+ - Updated dependencies [7669851]
204
+ - Updated dependencies [d6b9404]
205
+ - Updated dependencies [9814afc]
206
+ - @robota-sdk/agent-core@3.0.0-beta.80
207
+ - @robota-sdk/agent-provider-openai-compatible@3.0.0-beta.80
package/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # @robota-sdk/agent-provider-openai
2
+
3
+ OpenAI provider for the Robota SDK, built on the official `openai` SDK. `OpenAIProvider` implements
4
+ the `@robota-sdk/agent-core` provider contract, so a `Robota` agent can run on OpenAI models with
5
+ streaming and tool calling. It is a protocol client rather than a vendor lock: set `baseURL` and the
6
+ same provider talks to any OpenAI-compatible endpoint (AI gateways such as Vercel AI Gateway,
7
+ LiteLLM or OpenRouter, Azure OpenAI, vLLM, Ollama, LM Studio), with model ids passed through
8
+ verbatim.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @robota-sdk/agent-provider-openai @robota-sdk/agent-core
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```typescript
19
+ import { Robota } from '@robota-sdk/agent-core';
20
+ import { OpenAIProvider } from '@robota-sdk/agent-provider-openai';
21
+
22
+ const provider = new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY });
23
+
24
+ const agent = new Robota({
25
+ name: 'MyAgent',
26
+ aiProviders: [provider],
27
+ defaultModel: { provider: 'openai', model: 'gpt-4o' },
28
+ });
29
+
30
+ const response = await agent.run('Hello!');
31
+ console.log(response);
32
+ ```
33
+
34
+ The provider registers under the name `openai`, which is the value `defaultModel.provider` must use.
35
+
36
+ ### OpenAI-compatible endpoints
37
+
38
+ ```typescript
39
+ import { OpenAIProvider } from '@robota-sdk/agent-provider-openai';
40
+
41
+ // An OpenAI-protocol gateway serving a non-OpenAI model
42
+ const provider = new OpenAIProvider({
43
+ apiKey: process.env.AI_GATEWAY_API_KEY,
44
+ baseURL: 'https://ai-gateway.vercel.sh/v1',
45
+ });
46
+ // then: defaultModel: { provider: 'openai', model: 'anthropic/claude-sonnet-4-5' }
47
+ ```
48
+
49
+ The API surface follows `baseURL` unless `apiSurface` is set:
50
+
51
+ | Configuration | API surface |
52
+ | --------------------- | --------------------------------------- |
53
+ | No `baseURL` | Responses API (`'responses'`) |
54
+ | `baseURL` set | Chat Completions (`'chat-completions'`) |
55
+ | `apiSurface` provided | The surface you set, either way |
56
+
57
+ ### Strict tools
58
+
59
+ `strictTools: true` closes tool object schemas and requests OpenAI strict function calling. Every
60
+ object node of a tool's parameter schema, nested ones included, gets `additionalProperties: false`
61
+ and a complete `required` list, with optional properties turned into nullable ones, and each function
62
+ tool is sent with `strict: true` on both the Responses and Chat Completions surfaces. An
63
+ OpenAI-compatible endpoint that rejects the `strict` field needs `strictTools` left off. With
64
+ `strictTools` off (the default) tool schemas are forwarded as authored and no `strict` field is sent.
65
+
66
+ ## Options
67
+
68
+ `new OpenAIProvider(options: IOpenAIProviderOptions)`. One of `apiKey`, `client` or `executor` is
69
+ required; the constructor throws otherwise.
70
+
71
+ | Option | Type | Description |
72
+ | -------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
73
+ | `apiKey` | `string` | API key used to create the `openai` client. |
74
+ | `baseURL` | `string` | Endpoint base URL (default `https://api.openai.com/v1`). Also switches the default surface to Chat Completions. |
75
+ | `apiSurface` | `'responses' \| 'chat-completions'` | Forces the API surface instead of deriving it from `baseURL`. |
76
+ | `defaultModel` | `string` | Model used when a call does not name one. |
77
+ | `organization` | `string` | OpenAI organization ID. |
78
+ | `timeout` | `number` | Request timeout in milliseconds. |
79
+ | `strictTools` | `boolean` | Closes tool object schemas and requests OpenAI strict function calling (see above). |
80
+ | `responseFormat` | `'text' \| 'json_object' \| 'json_schema'` | Response format; `'json_schema'` uses `jsonSchema`. |
81
+ | `jsonSchema` | `IOpenAIJsonSchemaDefinition` | Schema for Structured Outputs when `responseFormat` is `'json_schema'`. |
82
+ | `reasoning` | `IOpenAIResponsesReasoningOptions` | Responses API reasoning controls (`effort`, `summary`). |
83
+ | `includeStreamUsage` | `boolean` | Requests token usage on streaming Chat Completions turns (default `true`). |
84
+ | `client` | `OpenAI` | A pre-built `openai` client, used instead of `apiKey`. |
85
+ | `executor` | `IExecutor` | Delegates chat calls to an executor instead of calling the API directly. |
86
+ | `payloadLogger` | `IPayloadLogger` | Logs a summary of each Chat Completions request (model, message count, tools present, temperature, max tokens). |
87
+ | `logger` | `ILogger` | Logger for internal provider messages (silent by default). |
88
+
89
+ ## Exports
90
+
91
+ - `OpenAIProvider` and its option types (`IOpenAIProviderOptions`, `TOpenAIApiSurface`, and others).
92
+ - `createOpenAIProviderDefinition()`: the provider definition used by Robota's built-in provider
93
+ registry.
94
+ - `@robota-sdk/agent-provider-openai/loggers`: `FilePayloadLogger` (Node.js, writes log files with
95
+ owner-only permissions) and `ConsolePayloadLogger` (browser console).
96
+
97
+ ## Related packages
98
+
99
+ - [`@robota-sdk/agent-core`](../agent-core/README.md): the `Robota` agent and the provider contract.
100
+ - [`@robota-sdk/agent-provider-openai-compatible`](../agent-provider-openai-compatible/README.md):
101
+ DeepSeek, Qwen and Gemma providers, plus the shared OpenAI-compatible protocol code this package
102
+ uses.
103
+ - [`@robota-sdk/agent-provider-anthropic`](../agent-provider-anthropic/README.md) and
104
+ [`@robota-sdk/agent-provider-gemini`](../agent-provider-gemini/README.md): other chat providers.
105
+
106
+ See [docs/SPEC.md](docs/SPEC.md) for the package contract.
107
+
108
+ ## License
109
+
110
+ Robota is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-CMqjfN_6.cjs");let t=require("@robota-sdk/agent-core"),n=require("openai");n=e.t(n,1);let r=require("@robota-sdk/agent-provider-openai-compatible/shared"),i=require("node:crypto");function a(e){return(0,r.convertToOpenAICompatibleMessages)(e)}function o(e){return(0,r.convertToOpenAICompatibleTools)(e)}function s(e,t){return t?.type===void 0?e:t.type===`json_schema`?{...e,responseFormat:`json_schema`,jsonSchema:{name:t.name??`structured_output`,schema:t.schema}}:{...e,responseFormat:t.type}}function c(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{type:`json_object`};let t=u(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 l(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{format:{type:`json_object`}};let t=u(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 u(e){let t=e.jsonSchema;if(e.responseFormat!==`json_schema`)throw Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw Error(`OpenAI jsonSchema.schema is required when responseFormat is json_schema`);return{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}async function d(e){if(typeof e.withResponse==`function`){let{data:t,request_id:n}=await e.withResponse();return{data:t,...typeof n==`string`&&n.length>0&&{providerRequestId:n}}}return{data:await e}}function f(e){let t=e?._request_id;return typeof t==`string`&&t.length>0?t:void 0}function p(e,t){return t===void 0?e:{...e,metadata:{...e.metadata,providerRequestId:t}}}function m(e,t){let n=t!==void 0&&Object.keys(t).length>0;if(!(!e&&!n))return{...e?{signal:e}:{},...n?{headers:{...t}}:{}}}async function ee(e){let n=v(e.client);try{let t=g(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await ne(n,e,{...t,stream:!0,...h(e)});await _(e,t,`chat`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:t});let r=m(void 0,e.requestHeaders),i=r?await n.chat.completions.create(t,r):await n.chat.completions.create(t);return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),p(e.responseParser.parseResponse(i),f(i))}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI chat failed`)}}async function*te(e){let n=v(e.client);try{let t={...g(e),stream:!0,...h(e)};await _(e,t,`stream`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:t});let{data:i,providerRequestId:a}=await d(n.chat.completions.create(t,m(e.chatOptions?.signal,e.requestHeaders)));for await(let t of(0,r.observeProviderNativeRawPayloadStream)(i,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let n=e.responseParser.parseStreamingChunk(t);n&&(yield p(n,a))}}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI stream failed`)}}function h(e){return e.providerOptions.includeStreamUsage===!1?{}:{stream_options:{include_usage:!0}}}function g(e){let t=a(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let i=c(s(e.providerOptions,e.chatOptions?.responseFormat));return{model:n,messages:t,...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_tokens:e.chatOptions.maxTokens},...e.chatOptions?.tools&&{tools:o(e.chatOptions.tools),tool_choice:(0,r.toOpenAICompatibleToolChoice)(e.chatOptions.toolChoice)},...i!==void 0&&{response_format:i}}}async function ne(e,n,i){try{await _(n,i,`stream`),n.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:i});let{data:t,providerRequestId:a}=await d(e.chat.completions.create(i,m(n.chatOptions?.signal,n.requestHeaders)));return p(await(0,r.assembleOpenAICompatibleStream)({stream:(0,r.observeProviderNativeRawPayloadStream)(t,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n.chatOptions?.onProviderNativeRawPayload}),onTextDelta:n.chatOptions?.onTextDelta??n.onTextDelta,signal:n.chatOptions?.signal}),a)}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI stream failed`)}}async function _(e,t,n){if(!e.payloadLogger?.isEnabled())return;let r={model:t.model,messagesCount:t.messages.length,hasTools:!!t.tools,temperature:t.temperature??void 0,maxTokens:t.max_tokens??void 0,timestamp:new Date().toISOString()};await e.payloadLogger.logPayload(r,n)}function v(e){if(!e)throw Error(`OpenAI client not available. Either provide a client/apiKey or use an executor.`);return e}const y={verifiedAt:`2026-09-11`,sourceUrl:`https://platform.openai.com/docs/api-reference/responses`,models:{"gpt-5.1":{supportedEfforts:[`none`,`low`,`medium`,`high`],defaultEffort:`none`,nativeControlId:`responses.reasoning.effort`}}};var b=class{parser;constructor(e){this.parser=new r.OpenAICompatibleResponseParser({logger:e})}parseResponse(e){try{return this.parser.parseResponse(e)}catch(e){let t=x(e instanceof Error?e.message:`OpenAI response parsing failed`);throw Error(`OpenAI response parsing failed: ${t}`)}}parseStreamingChunk(e){try{return this.parser.parseStreamingChunk(e)}catch(e){let t=x(e instanceof Error?e.message:`OpenAI chunk parsing failed`);throw Error(`OpenAI chunk parsing failed: ${t}`)}}};function x(e){return e.replace(/^OpenAI-compatible response parsing failed: /,``).replace(/^OpenAI-compatible chunk parsing failed: /,``).replace(`OpenAI-compatible response`,`OpenAI response`)}function S(e){return e}function C(e,t){if(t===void 0)return e;if(t.effective===null||t.disposition===`model-default`){if(e?.effort!==void 0)throw Error(`Static reasoning.effort ${e.effort} conflicts with ${t.disposition===`model-default`?`provider-default selection`:`an effort resolution that does not apply a native control`}.`);return e}let n=S(t.effective);if(e?.effort!==void 0&&e.effort!==n)throw Error(`Resolved effort ${n} conflicts with static reasoning.effort ${e.effort}.`);return{...e,effort:n}}function w(e){return e.flatMap(e=>re(e))}function T(e,t){let n=t??!1,r=e?.map(e=>({type:`function`,name:e.name,description:e.description,parameters:e.parameters,strict:n}))??[];return r.length>0?r:void 0}function re(e){if(e.role===`user`)return[E(`user`,ae(e.content,e.parts))];if(e.role===`system`)return[E(`system`,e.content)];if(e.role===`tool`){if(!e.toolCallId||e.toolCallId.trim().length===0)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return[{type:`function_call_output`,call_id:e.toolCallId,output:e.content||``}]}return ie(e)}function ie(e){let t=[];e.content&&e.content.length>0&&t.push(E(`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(E(`assistant`,``)),t}function ae(e,t){if(!t||t.length===0)return e;let n=t.map(e=>oe(e));return e.length>0&&!t.some(e=>e.type===`text`)?[{type:`input_text`,text:e},...n]:n}function oe(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 E(e,t){return{role:e,content:t}}async function*se(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let e=await ce(n,t);if(e.done||t?.aborted)break;yield e.value}}finally{t?.aborted&&await n.return?.()}}async function ce(e,t){if(!t)return e.next();if(t.aborted)return{done:!0,value:void 0};let n,r=new Promise(e=>{n=()=>e({done:!0,value:void 0}),t.addEventListener(`abort`,n,{once:!0})});try{return await Promise.race([e.next(),r])}finally{n&&t.removeEventListener(`abort`,n)}}function le(e){G(e);let t=e.output??[];return j({content:e.output_text??L(t),toolCalls:P(t),response:e,reasoning:B(t)})}async function D(e){let t={textParts:[],toolCalls:[],reasoning:H()};for await(let n of se(e.stream,e.signal))O(t,n,e.onTextDelta);return t.completedResponse===void 0?j({content:t.textParts.join(``),toolCalls:t.toolCalls,reasoning:t.reasoning}):A(t)}function O(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,U(e.reasoning,B(t.response.output??[]));return}if(t.type===`response.output_item.done`){k(e,t.item);return}if(t.type===`response.error`||t.type===`response.failed`||t.type===`response.incomplete`)throw Error(`OpenAI Responses API failed: ${ue(t)}`)}function k(e,t){if(F(t)){e.toolCalls.push(I(t));return}V(t)&&U(e.reasoning,B([t]))}function A(e){let t=e.completedResponse;if(t===void 0)throw Error(`OpenAI Responses stream completed without response metadata`);G(t);let n=t.output??[],r=P(n),i=e.textParts.length>0?e.textParts.join(``):t.output_text??L(n),a=B(n);return U(a,e.reasoning),j({content:i,toolCalls:r.length>0?r:e.toolCalls,response:t,reasoning:a})}function j(e){return{id:(0,i.randomUUID)(),role:`assistant`,content:e.content,state:`complete`,timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:N(e.response.usage)},metadata:{...M(e.response,e.reasoning),...e.response?.usage!==void 0&&{usageProvenance:e.response.usage.input_tokens!==void 0&&e.response.usage.output_tokens!==void 0&&e.response.usage.total_tokens!==void 0?`complete`:`partial`}}}}function M(e,t){return{providerApiSurface:`responses`,...e?.id!==void 0&&{responseId:e.id},...e?.model!==void 0&&{model:e.model},...e?.status!==void 0&&{finishReason:e.status},...t.reasoningSummaryCount>0&&{reasoningSummaryCount:t.reasoningSummaryCount,reasoningSummaries:t.reasoningSummaries},...t.hasEncryptedReasoning&&{hasEncryptedReasoning:!0}}}function N(e){return{promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,totalTokens:e.total_tokens??0}}function P(e){return e.filter(F).map(e=>I(e))}function F(e){return e.type===`function_call`&&`call_id`in e&&`name`in e&&`arguments`in e}function I(e){return{id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments}}}function L(e){return e.filter(z).flatMap(e=>e.content).map(R).join(``)}function R(e){return e.type===`refusal`?e.refusal:e.text}function z(e){return e.type===`message`&&`content`in e&&Array.isArray(e.content)}function B(e){let t=H();for(let n of e){if(!V(n))continue;let e=n.summary?.map(e=>e.text).filter(W)??[];t.reasoningSummaryCount+=e.length,t.reasoningSummaries.push(...e),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content}return t}function V(e){return e.type===`reasoning`}function H(){return{reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:!1}}function U(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning}function W(e){return e!==void 0}function G(e){if(e.status===`failed`||e.status===`incomplete`)throw Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function ue(e){return e.message??e.error?.message??e.response?.error?.message??`unknown error`}async function de(e){let n=e.chatOptions?.onTextDelta??e.onTextDelta;if(n)return K({...e,chatOptions:{...e.chatOptions,onTextDelta:n}});if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=q(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let n=await e.client.responses.create(t,m(e.chatOptions?.signal,e.requestHeaders));return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`response`,payload:n}),p(le(n),f(n))}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI responses failed`)}}async function*fe(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,r=K({...e,chatOptions:{...e.chatOptions,onTextDelta:e=>{n?.(e),ge(t,me(e))}}}).then(e=>_e(t,e)).catch(e=>ve(t,xe(e)));yield*he(t),await r}async function K(e){if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=pe(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let{data:n,providerRequestId:i}=await d(e.client.responses.create(t,m(e.chatOptions?.signal,e.requestHeaders)));return p(await D({stream:(0,r.observeProviderNativeRawPayloadStream)(n,{provider:`openai`,apiSurface:`responses`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal}),i)}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI responses stream failed`)}}function q(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let n=T(e.chatOptions?.tools,e.providerOptions.strictTools),i=l(e.providerOptions),a=C(e.providerOptions.reasoning,e.chatOptions?.effortResolution);return{model:t,input:w(e.messages),...n!==void 0&&{tools:n,tool_choice:(0,r.toOpenAIResponsesToolChoice)(e.chatOptions?.toolChoice)},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...i!==void 0&&{text:i},...a!==void 0&&{reasoning:a},...e.providerOptions.includeEncryptedReasoning===!0&&{include:[`reasoning.encrypted_content`]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function pe(e){return{...q(e),stream:!0}}function me(e){return{id:(0,i.randomUUID)(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{providerApiSurface:`responses`,isStreamChunk:!0,isComplete:!1}}}async function*he(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 ye(e)}}function ge(e,t){e.deltas.push(t),J(e)}function _e(e,t){e.finalMessage=t,J(e)}function ve(e,t){e.error=t,J(e)}function ye(e){return new Promise(t=>{e.wake=t})}function J(e){e.wake?.(),e.wake=void 0}function be(e){return{...e,content:``,metadata:{...e.metadata,isStreamChunk:!0,isComplete:!0}}}function xe(e){return e instanceof Error?e:Error(String(e))}var Y=class extends t.AbstractAIProvider{name=`openai`;version=`1.0.0`;client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(e){if(super(e.logger||t.SilentLogger),this.options=e,this.apiSurface=Se(e),Ce(this.apiSurface,e.nativeWebTools),e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new n.default({apiKey:e.apiKey,...e.organization&&{organization:e.organization},...e.timeout&&{timeout:e.timeout},...e.baseURL&&{baseURL:e.baseURL}});else throw Error(`Either OpenAI client, apiKey, or executor is required`);this.responseParser=new b(this.logger),this.payloadLogger=e.payloadLogger}async chat(e,t){this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=await this.executeViaExecutorOrDirect(e,n);return t.modelEffortOutcome===void 0&&this.publishModelEffortOutcome(n,`opaque-executor`),t.message}catch(e){throw this.logger.error(`OpenAI Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(this.apiSurface===`responses`){let t=await de({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),t}let r=await ee({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),r}async*chatStream(e,t){this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=!1;for await(let r of this.executeStreamViaExecutorOrDirect(e,n))r.kind===`message`?yield r.message:t=r.modelEffortOutcome!==void 0;t||this.publishModelEffortOutcome(n,`opaque-executor`);return}catch(e){throw this.logger.error(`OpenAI Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}yield*this.streamDirect(e,n)}async*streamDirect(e,t){if(this.apiSurface===`responses`){yield*fe({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t);return}yield*te({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t)}endpointIsVendorDefault(){return this.options.baseURL===void 0}canPropagateTraceContext(){return!this.executor&&this.effectiveBaseUrl()!==void 0}effectiveBaseUrl(){let e=this.client?.baseURL;return typeof e==`string`&&e.length>0?e:void 0}traceRequestHeaders(e){return this.canPropagateTraceContext()?(0,t.traceHeadersFor)(this.effectiveBaseUrl(),e?.outboundTraceContext):{}}effortTable(){return this.endpointIsVendorDefault()&&this.apiSurface===`responses`?y:void 0}resolveEffortOptions(e){if(e?.effort===void 0||e.effortResolution!==void 0)return e;let n=e.model??this.options.defaultModel;return n===void 0?e:{...e,effortResolution:(0,t.resolveModelEffort)(this.effortTable(),n,e.effort)}}projectionProfile(){return this.options.strictTools?{...t.STRICT_TOOL_SCHEMA_PROFILE,providerName:`openai`}:{...t.PERMISSIVE_TOOL_SCHEMA_PROFILE,providerName:`openai`}}projectChatOptions(e){if(!e?.tools)return e;let t=e.model??this.options.defaultModel??``,n=this.projectTools(e.tools,t);return{...e,tools:n&&n.length>0?n:void 0}}publishModelEffortOutcome(e,n){let r=e?.effortResolution,i=e?.onModelEffortOutcome;if(r===void 0||i===void 0)return;let a=n===void 0?r.effective!==null&&r.disposition!==`model-default`?{state:`sent`,id:`responses.reasoning.effort`}:{state:`omitted`,reason:r.disposition===`model-default`?`provider-default-selection`:`model-effort-not-applied`}:{state:`omitted`,reason:n},o=n===void 0?{state:`sent`}:{state:`not-dispatched`,reason:n};try{i((0,t.createModelEffortOutcome)(r,{nativeControl:a,providerDispatch:o}))}catch(e){this.logger.warn(`Model-effort outcome observer failed`,{error:e instanceof Error?e.message:String(e)})}}supportsTools(){return!0}getCapabilities(){let e=this.apiSurface===`chat-completions`?`openai-compatible-chat-completions`:`openai-responses`;return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`search`)},webFetch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`fetch`)}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}};function Se(e){return e.apiSurface===void 0?e.baseURL?`chat-completions`:`responses`:e.apiSurface}function X(e,t){return e===`chat-completions`?`OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${t}.`:`OpenAI Responses native web ${t} is not wired in this Robota provider version.`}function Ce(e,t){if(t?.webSearch===!0||t?.webFetch===!0)throw Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var we=class{static filterMessagesForOpenAI(e){return e.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`system`||e.role===`tool`&&!!(e.toolCallId&&e.toolCallId.trim()!==``&&e.toolCallId!==`unknown`))}static toOpenAIFormat(e){return this.filterMessagesForOpenAI(e).map(e=>this.convertMessage(e))}static convertMessage(e){let t=e.role;if(t===`user`)return{role:`user`,content:e.content};if(t===`assistant`){let t=e;return t.toolCalls&&t.toolCalls.length>0?{role:`assistant`,content:t.content===``?null:t.content||null,tool_calls:t.toolCalls.map(e=>({id:e.id,type:`function`,function:{name:e.function.name,arguments:e.function.arguments}}))}:{role:`assistant`,content:t.content===null||t.content===``?null:t.content||``}}if(t===`system`)return{role:`system`,content:e.content};if(t===`tool`){if(!e.toolCallId||e.toolCallId.trim()===``)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return{role:`tool`,content:e.content,tool_call_id:e.toolCallId}}throw Error(`Unsupported message role: ${t}`)}static addSystemPromptIfNeeded(e,t){return!t||e.some(e=>e.role===`system`)?e:[{role:`system`,content:t},...e]}};const Z=`$ENV:OPENAI_API_KEY`,Te=[{kind:`api-key`,label:`OpenAI API keys`,url:`https://platform.openai.com/api-keys`,sourceUrl:`https://developers.openai.com/api/reference/overview#authentication`,lastVerifiedAt:`2026-05-08`}];function Ee(){return{type:`openai`,displayName:`OpenAI`,description:`GPT series — general-purpose assistant. API key required.`,category:`cloud-paid`,costPerTokenUsd:.001,defaults:{apiKey:Z},endpoint:{host:`api.openai.com`,port:443},modelCatalog:{status:`unavailable`,sourceUrl:`https://platform.openai.com/docs/api-reference/models/list`,message:`OpenAI model availability should be discovered live from GET /v1/models.`},setupHelpLinks:Te,setupSteps:[{key:`model`,title:`OpenAI model`,required:!0},{key:`apiKey`,title:`OpenAI API key`,defaultValue:Z,masked:!0}],requiresApiKey:!0,probeProfile:r.probeOpenAICompatibleProfile,destinationEnvironment:[`OPENAI_BASE_URL`,`OPENAI_ORG_ID`,`OPENAI_PROJECT_ID`],createProvider:e=>{let t=Q(e.options),n=Oe(e.options);return ke(e.baseURL,t,n),new Y({apiKey:De(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 De(e){if(!e)throw Error(`Provider openai requires apiKey`);return e}function Q(e){let t=e?.apiSurface;if(t===`responses`||t===`chat-completions`)return t}function Oe(e){let t=$(e?.nativeWebTools)??$(e?.builtInWebTools);if(t!==void 0)return t}function $(e){if(e==null||e instanceof Date||Array.isArray(e)||typeof e!=`object`)return;let t=e.webSearch,n=e.webFetch;return{...typeof t==`boolean`&&{webSearch:t},...typeof n==`boolean`&&{webFetch:n}}}function ke(e,t,n){if(n?.webSearch===!0||n?.webFetch===!0)throw Error(e!==void 0||t===`chat-completions`?`Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`:`Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`)}exports.DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE=Z,exports.DEFAULT_OPENAI_PROVIDER_MODEL=void 0,exports.OpenAIConversationAdapter=we,exports.OpenAIProvider=Y,exports.createOpenAIProviderDefinition=Ee;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-CMqjfN_6.cjs");let t=require("@robota-sdk/agent-core"),n=require("openai");n=e.t(n,1);let r=require("@robota-sdk/agent-provider-openai-compatible/shared"),i=require("node:crypto");function a(e){return(0,r.convertToOpenAICompatibleMessages)(e)}function o(e,t){return(0,r.convertToOpenAICompatibleTools)(e,{strict:t===!0})}function s(e,t){return t?.type===void 0?e:t.type===`json_schema`?{...e,responseFormat:`json_schema`,jsonSchema:{name:t.name??`structured_output`,schema:t.schema}}:{...e,responseFormat:t.type}}function c(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{type:`json_object`};let t=u(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 l(e){if(e.responseFormat===void 0||e.responseFormat===`text`)return;if(e.responseFormat===`json_object`)return{format:{type:`json_object`}};let t=u(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 u(e){let t=e.jsonSchema;if(e.responseFormat!==`json_schema`)throw Error(`Unsupported OpenAI response format: ${e.responseFormat}`);if(!t?.schema)throw Error(`OpenAI jsonSchema.schema is required when responseFormat is json_schema`);return{name:t.name,schema:t.schema,...t.description!==void 0&&{description:t.description},...t.strict!==void 0&&{strict:t.strict}}}async function d(e){if(typeof e.withResponse==`function`){let{data:t,request_id:n}=await e.withResponse();return{data:t,...typeof n==`string`&&n.length>0&&{providerRequestId:n}}}return{data:await e}}function f(e){let t=e?._request_id;return typeof t==`string`&&t.length>0?t:void 0}function p(e,t){return t===void 0?e:{...e,metadata:{...e.metadata,providerRequestId:t}}}function m(e,t){let n=t!==void 0&&Object.keys(t).length>0;if(!(!e&&!n))return{...e?{signal:e}:{},...n?{headers:{...t}}:{}}}async function ee(e){let n=v(e.client);try{let t=g(e);if(e.chatOptions?.onTextDelta??e.onTextDelta)return await ne(n,e,{...t,stream:!0,...h(e)});await _(e,t,`chat`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:t});let r=m(e.chatOptions?.signal,e.requestHeaders),i=r?await n.chat.completions.create(t,r):await n.chat.completions.create(t);return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`response`,payload:i}),p(e.responseParser.parseResponse(i),f(i))}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI chat failed`)}}async function*te(e){let n=v(e.client);try{let t={...g(e),stream:!0,...h(e)};await _(e,t,`stream`),e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:t});let{data:i,providerRequestId:a}=await d(n.chat.completions.create(t,m(e.chatOptions?.signal,e.requestHeaders)));for await(let t of(0,r.observeProviderNativeRawPayloadStream)(i,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload})){let n=e.responseParser.parseStreamingChunk(t);n&&(yield p(n,a))}}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI stream failed`)}}function h(e){return e.providerOptions.includeStreamUsage===!1?{}:{stream_options:{include_usage:!0}}}function g(e){let t=a(e.messages),n=e.chatOptions?.model??e.providerOptions.defaultModel;if(!n)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let i=c(s(e.providerOptions,e.chatOptions?.responseFormat));return{model:n,messages:t,...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_tokens:e.chatOptions.maxTokens},...e.chatOptions?.tools&&{tools:o(e.chatOptions.tools,e.providerOptions.strictTools),tool_choice:(0,r.toOpenAICompatibleToolChoice)(e.chatOptions.toolChoice)},...i!==void 0&&{response_format:i}}}async function ne(e,n,i){try{await _(n,i,`stream`),n.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`chat-completions`,payloadKind:`request`,payload:i});let{data:t,providerRequestId:a}=await d(e.chat.completions.create(i,m(n.chatOptions?.signal,n.requestHeaders)));return p(await(0,r.assembleOpenAICompatibleStream)({stream:(0,r.observeProviderNativeRawPayloadStream)(t,{provider:`openai`,apiSurface:`chat-completions`,onProviderNativeRawPayload:n.chatOptions?.onProviderNativeRawPayload}),onTextDelta:n.chatOptions?.onTextDelta??n.onTextDelta,signal:n.chatOptions?.signal}),a)}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI stream failed`)}}async function _(e,t,n){if(!e.payloadLogger?.isEnabled())return;let r={model:t.model,messagesCount:t.messages.length,hasTools:!!t.tools,temperature:t.temperature??void 0,maxTokens:t.max_tokens??void 0,timestamp:new Date().toISOString()};await e.payloadLogger.logPayload(r,n)}function v(e){if(!e)throw Error(`OpenAI client not available. Either provide a client/apiKey or use an executor.`);return e}const y={verifiedAt:`2026-09-11`,sourceUrl:`https://platform.openai.com/docs/api-reference/responses`,models:{"gpt-5.1":{supportedEfforts:[`none`,`low`,`medium`,`high`],defaultEffort:`none`,nativeControlId:`responses.reasoning.effort`}}};var b=class{parser;constructor(e){this.parser=new r.OpenAICompatibleResponseParser({logger:e})}parseResponse(e){try{return this.parser.parseResponse(e)}catch(e){let t=x(e instanceof Error?e.message:`OpenAI response parsing failed`);throw Error(`OpenAI response parsing failed: ${t}`)}}parseStreamingChunk(e){try{return this.parser.parseStreamingChunk(e)}catch(e){let t=x(e instanceof Error?e.message:`OpenAI chunk parsing failed`);throw Error(`OpenAI chunk parsing failed: ${t}`)}}};function x(e){return e.replace(/^OpenAI-compatible response parsing failed: /,``).replace(/^OpenAI-compatible chunk parsing failed: /,``).replace(`OpenAI-compatible response`,`OpenAI response`)}function S(e){return e}function C(e,t){if(t===void 0)return e;if(t.effective===null||t.disposition===`model-default`){if(e?.effort!==void 0)throw Error(`Static reasoning.effort ${e.effort} conflicts with ${t.disposition===`model-default`?`provider-default selection`:`an effort resolution that does not apply a native control`}.`);return e}let n=S(t.effective);if(e?.effort!==void 0&&e.effort!==n)throw Error(`Resolved effort ${n} conflicts with static reasoning.effort ${e.effort}.`);return{...e,effort:n}}function w(e){return e.flatMap(e=>re(e))}function T(e,t){let n=t??!1,r=e?.map(e=>({type:`function`,name:e.name,description:e.description,parameters:e.parameters,strict:n}))??[];return r.length>0?r:void 0}function re(e){if(e.role===`user`)return[E(`user`,ae(e.content,e.parts))];if(e.role===`system`)return[E(`system`,e.content)];if(e.role===`tool`){if(!e.toolCallId||e.toolCallId.trim().length===0)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return[{type:`function_call_output`,call_id:e.toolCallId,output:e.content||``}]}return ie(e)}function ie(e){let t=[];e.content&&e.content.length>0&&t.push(E(`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(E(`assistant`,``)),t}function ae(e,t){if(!t||t.length===0)return e;let n=t.map(e=>oe(e));return e.length>0&&!t.some(e=>e.type===`text`)?[{type:`input_text`,text:e},...n]:n}function oe(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 E(e,t){return{role:e,content:t}}async function*se(e,t){let n=e[Symbol.asyncIterator]();try{for(;!t?.aborted;){let e=await ce(n,t);if(e.done||t?.aborted)break;yield e.value}}finally{t?.aborted&&await n.return?.()}}async function ce(e,t){if(!t)return e.next();if(t.aborted)return{done:!0,value:void 0};let n,r=new Promise(e=>{n=()=>e({done:!0,value:void 0}),t.addEventListener(`abort`,n,{once:!0})});try{return await Promise.race([e.next(),r])}finally{n&&t.removeEventListener(`abort`,n)}}function le(e){G(e);let t=e.output??[];return j({content:e.output_text??L(t),toolCalls:P(t),response:e,reasoning:B(t)})}async function D(e){let t={textParts:[],toolCalls:[],reasoning:H()};for await(let n of se(e.stream,e.signal))O(t,n,e.onTextDelta);return t.completedResponse===void 0?j({content:t.textParts.join(``),toolCalls:t.toolCalls,reasoning:t.reasoning}):A(t)}function O(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,U(e.reasoning,B(t.response.output??[]));return}if(t.type===`response.output_item.done`){k(e,t.item);return}if(t.type===`response.error`||t.type===`response.failed`||t.type===`response.incomplete`)throw Error(`OpenAI Responses API failed: ${ue(t)}`)}function k(e,t){if(F(t)){e.toolCalls.push(I(t));return}V(t)&&U(e.reasoning,B([t]))}function A(e){let t=e.completedResponse;if(t===void 0)throw Error(`OpenAI Responses stream completed without response metadata`);G(t);let n=t.output??[],r=P(n),i=e.textParts.length>0?e.textParts.join(``):t.output_text??L(n),a=B(n);return U(a,e.reasoning),j({content:i,toolCalls:r.length>0?r:e.toolCalls,response:t,reasoning:a})}function j(e){return{id:(0,i.randomUUID)(),role:`assistant`,content:e.content,state:`complete`,timestamp:new Date,...e.toolCalls.length>0&&{toolCalls:e.toolCalls},...e.response?.usage!==void 0&&{usage:N(e.response.usage)},metadata:{...M(e.response,e.reasoning),...e.response?.usage!==void 0&&{usageProvenance:e.response.usage.input_tokens!==void 0&&e.response.usage.output_tokens!==void 0&&e.response.usage.total_tokens!==void 0?`complete`:`partial`}}}}function M(e,t){return{providerApiSurface:`responses`,...e?.id!==void 0&&{responseId:e.id},...e?.model!==void 0&&{model:e.model},...e?.status!==void 0&&{finishReason:e.status},...t.reasoningSummaryCount>0&&{reasoningSummaryCount:t.reasoningSummaryCount,reasoningSummaries:t.reasoningSummaries},...t.hasEncryptedReasoning&&{hasEncryptedReasoning:!0}}}function N(e){let t=e.input_tokens_details?.cached_tokens;return{promptTokens:e.input_tokens??0,completionTokens:e.output_tokens??0,...e.total_tokens!==void 0&&{totalTokens:e.total_tokens},...typeof t==`number`&&{cacheReadTokens:t}}}function P(e){return e.filter(F).map(e=>I(e))}function F(e){return e.type===`function_call`&&`call_id`in e&&`name`in e&&`arguments`in e}function I(e){return{id:e.call_id,type:`function`,function:{name:e.name,arguments:e.arguments}}}function L(e){return e.filter(z).flatMap(e=>e.content).map(R).join(``)}function R(e){return e.type===`refusal`?e.refusal:e.text}function z(e){return e.type===`message`&&`content`in e&&Array.isArray(e.content)}function B(e){let t=H();for(let n of e){if(!V(n))continue;let e=n.summary?.map(e=>e.text).filter(W)??[];t.reasoningSummaryCount+=e.length,t.reasoningSummaries.push(...e),t.hasEncryptedReasoning=t.hasEncryptedReasoning||!!n.encrypted_content}return t}function V(e){return e.type===`reasoning`}function H(){return{reasoningSummaryCount:0,reasoningSummaries:[],hasEncryptedReasoning:!1}}function U(e,t){e.reasoningSummaryCount+=t.reasoningSummaryCount,e.reasoningSummaries.push(...t.reasoningSummaries),e.hasEncryptedReasoning=e.hasEncryptedReasoning||t.hasEncryptedReasoning}function W(e){return e!==void 0}function G(e){if(e.status===`failed`||e.status===`incomplete`)throw Error(`OpenAI Responses API failed: ${e.error?.message??e.status}`)}function ue(e){return e.message??e.error?.message??e.response?.error?.message??`unknown error`}async function de(e){let n=e.chatOptions?.onTextDelta??e.onTextDelta;if(n)return K({...e,chatOptions:{...e.chatOptions,onTextDelta:n}});if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=q(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let n=await e.client.responses.create(t,m(e.chatOptions?.signal,e.requestHeaders));return e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`response`,payload:n}),p(le(n),f(n))}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI responses failed`)}}async function*fe(e){let t={deltas:[]},n=e.chatOptions?.onTextDelta??e.onTextDelta,r=K({...e,chatOptions:{...e.chatOptions,onTextDelta:e=>{n?.(e),ge(t,me(e))}}}).then(e=>_e(t,e)).catch(e=>ve(t,xe(e)));yield*he(t),await r}async function K(e){if(!e.client)throw Error(`OpenAI Responses client not available.`);try{let t=pe(e);e.chatOptions?.onProviderNativeRawPayload?.({provider:`openai`,apiSurface:`responses`,payloadKind:`request`,payload:t});let{data:n,providerRequestId:i}=await d(e.client.responses.create(t,m(e.chatOptions?.signal,e.requestHeaders)));return p(await D({stream:(0,r.observeProviderNativeRawPayloadStream)(n,{provider:`openai`,apiSurface:`responses`,onProviderNativeRawPayload:e.chatOptions?.onProviderNativeRawPayload}),onTextDelta:e.chatOptions?.onTextDelta,signal:e.chatOptions?.signal}),i)}catch(e){throw(0,t.toProviderError)(e,`openai`,`OpenAI responses stream failed`)}}function q(e){let t=e.chatOptions?.model??e.providerOptions.defaultModel;if(!t)throw Error(`Model is required in chat options. Please specify a model in defaultModel configuration.`);let n=T(e.chatOptions?.tools,e.providerOptions.strictTools),i=l(e.providerOptions),a=C(e.providerOptions.reasoning,e.chatOptions?.effortResolution);return{model:t,input:w(e.messages),...n!==void 0&&{tools:n,tool_choice:(0,r.toOpenAIResponsesToolChoice)(e.chatOptions?.toolChoice)},...e.chatOptions?.temperature!==void 0&&{temperature:e.chatOptions.temperature},...e.chatOptions?.maxTokens!==void 0&&{max_output_tokens:e.chatOptions.maxTokens},...i!==void 0&&{text:i},...a!==void 0&&{reasoning:a},...e.providerOptions.includeEncryptedReasoning===!0&&{include:[`reasoning.encrypted_content`]},...e.providerOptions.store!==void 0&&{store:e.providerOptions.store}}}function pe(e){return{...q(e),stream:!0}}function me(e){return{id:(0,i.randomUUID)(),role:`assistant`,content:e,state:`complete`,timestamp:new Date,metadata:{providerApiSurface:`responses`,isStreamChunk:!0,isComplete:!1}}}async function*he(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 ye(e)}}function ge(e,t){e.deltas.push(t),J(e)}function _e(e,t){e.finalMessage=t,J(e)}function ve(e,t){e.error=t,J(e)}function ye(e){return new Promise(t=>{e.wake=t})}function J(e){e.wake?.(),e.wake=void 0}function be(e){return{...e,content:``,metadata:{...e.metadata,isStreamChunk:!0,isComplete:!0}}}function xe(e){return e instanceof Error?e:Error(String(e))}var Y=class extends t.AbstractAIProvider{name=`openai`;version=`1.0.0`;client;options;apiSurface;payloadLogger;responseParser;onTextDelta;constructor(e){if(super(e.logger||t.SilentLogger),this.options=e,this.apiSurface=Se(e),Ce(this.apiSurface,e.nativeWebTools),e.executor&&(this.executor=e.executor),!this.executor)if(e.client)this.client=e.client;else if(e.apiKey)this.client=new n.default({apiKey:e.apiKey,...e.organization&&{organization:e.organization},...e.timeout&&{timeout:e.timeout},...e.baseURL&&{baseURL:e.baseURL}});else throw Error(`Either OpenAI client, apiKey, or executor is required`);this.responseParser=new b(this.logger),this.payloadLogger=e.payloadLogger}async chat(e,t){this.validateMessages(e),this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=await this.executeViaExecutorOrDirect(e,n);return t.modelEffortOutcome===void 0&&this.publishModelEffortOutcome(n,`opaque-executor`),t.message}catch(e){throw this.logger.error(`OpenAI Provider executor chat error:`,e instanceof Error?e.message:String(e)),e}if(this.apiSurface===`responses`){let t=await de({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),t}let r=await ee({client:this.client,messages:e,chatOptions:this.projectChatOptions(n),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(n)});return this.publishModelEffortOutcome(n),r}async*chatStream(e,t){this.validateNativeWebTools(t?.nativeWebTools);let n=this.resolveEffortOptions(t);if(this.executor)try{let t=!1;for await(let r of this.executeStreamViaExecutorOrDirect(e,n))r.kind===`message`?yield r.message:t=r.modelEffortOutcome!==void 0;t||this.publishModelEffortOutcome(n,`opaque-executor`);return}catch(e){throw this.logger.error(`OpenAI Provider executor stream error:`,e instanceof Error?e.message:String(e)),e}yield*this.streamDirect(e,n)}async*streamDirect(e,t){if(this.apiSurface===`responses`){yield*fe({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t);return}yield*te({client:this.client,messages:e,chatOptions:this.projectChatOptions(t),providerOptions:this.options,payloadLogger:this.payloadLogger,responseParser:this.responseParser,onTextDelta:this.onTextDelta,requestHeaders:this.traceRequestHeaders(t)}),this.publishModelEffortOutcome(t)}endpointIsVendorDefault(){return this.options.baseURL===void 0}canPropagateTraceContext(){return!this.executor&&this.effectiveBaseUrl()!==void 0}effectiveBaseUrl(){let e=this.client?.baseURL;return typeof e==`string`&&e.length>0?e:void 0}traceRequestHeaders(e){return this.canPropagateTraceContext()?(0,t.traceHeadersFor)(this.effectiveBaseUrl(),e?.outboundTraceContext):{}}effortTable(){return this.endpointIsVendorDefault()&&this.apiSurface===`responses`?y:void 0}resolveEffortOptions(e){if(e?.effort===void 0||e.effortResolution!==void 0)return e;let n=e.model??this.options.defaultModel;return n===void 0?e:{...e,effortResolution:(0,t.resolveModelEffort)(this.effortTable(),n,e.effort)}}projectionProfile(){return this.options.strictTools?{...t.STRICT_TOOL_SCHEMA_PROFILE,providerName:`openai`}:{...t.PERMISSIVE_TOOL_SCHEMA_PROFILE,providerName:`openai`}}projectChatOptions(e){if(!e?.tools)return e;let t=e.model??this.options.defaultModel??``,n=this.projectTools(e.tools,t);return{...e,tools:n&&n.length>0?n:void 0}}publishModelEffortOutcome(e,n){let r=e?.effortResolution,i=e?.onModelEffortOutcome;if(r===void 0||i===void 0)return;let a=n===void 0?r.effective!==null&&r.disposition!==`model-default`?{state:`sent`,id:`responses.reasoning.effort`}:{state:`omitted`,reason:r.disposition===`model-default`?`provider-default-selection`:`model-effort-not-applied`}:{state:`omitted`,reason:n},o=n===void 0?{state:`sent`}:{state:`not-dispatched`,reason:n};try{i((0,t.createModelEffortOutcome)(r,{nativeControl:a,providerDispatch:o}))}catch(e){this.logger.warn(`Model-effort outcome observer failed`,{error:e instanceof Error?e.message:String(e)})}}supportsTools(){return!0}getCapabilities(){let e=this.apiSurface===`chat-completions`?`openai-compatible-chat-completions`:`openai-responses`;return{functionCalling:{supported:!0},nativeWebTools:{webSearch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`search`)},webFetch:{supported:!1,enabled:!1,source:e,reason:X(this.apiSurface,`fetch`)}}}}validateConfig(){return!!this.client&&!!this.options}async dispose(){}validateMessages(e){super.validateMessages(e);for(let t of e)if(t.role===`assistant`){let e=t;if(e.toolCalls&&e.toolCalls.length>0&&e.content===``)continue}}};function Se(e){return e.apiSurface===void 0?e.baseURL?`chat-completions`:`responses`:e.apiSurface}function X(e,t){return e===`chat-completions`?`OpenAI-compatible Chat Completions endpoints support declared function tools, not provider-native web ${t}.`:`OpenAI Responses native web ${t} is not wired in this Robota provider version.`}function Ce(e,t){if(t?.webSearch===!0||t?.webFetch===!0)throw Error(`Provider openai native web search/fetch is not supported for apiSurface ${e} in this Robota provider version.`)}var we=class{static filterMessagesForOpenAI(e){return e.filter(e=>e.role===`user`||e.role===`assistant`||e.role===`system`||e.role===`tool`&&!!(e.toolCallId&&e.toolCallId.trim()!==``&&e.toolCallId!==`unknown`))}static toOpenAIFormat(e){return this.filterMessagesForOpenAI(e).map(e=>this.convertMessage(e))}static convertMessage(e){let t=e.role;if(t===`user`)return{role:`user`,content:e.content};if(t===`assistant`){let t=e;return t.toolCalls&&t.toolCalls.length>0?{role:`assistant`,content:t.content===``?null:t.content||null,tool_calls:t.toolCalls.map(e=>({id:e.id,type:`function`,function:{name:e.function.name,arguments:e.function.arguments}}))}:{role:`assistant`,content:t.content===null||t.content===``?null:t.content||``}}if(t===`system`)return{role:`system`,content:e.content};if(t===`tool`){if(!e.toolCallId||e.toolCallId.trim()===``)throw Error(`Tool message missing toolCallId: ${JSON.stringify(e)}`);return{role:`tool`,content:e.content,tool_call_id:e.toolCallId}}throw Error(`Unsupported message role: ${t}`)}static addSystemPromptIfNeeded(e,t){return!t||e.some(e=>e.role===`system`)?e:[{role:`system`,content:t},...e]}};const Z=`$ENV:OPENAI_API_KEY`,Te=[{kind:`api-key`,label:`OpenAI API keys`,url:`https://platform.openai.com/api-keys`,sourceUrl:`https://developers.openai.com/api/reference/overview#authentication`,lastVerifiedAt:`2026-05-08`}];function Ee(){return{type:`openai`,displayName:`OpenAI`,description:`GPT series — general-purpose assistant. API key required.`,category:`cloud-paid`,costPerTokenUsd:.001,defaults:{apiKey:Z},endpoint:{host:`api.openai.com`,port:443},modelCatalog:{status:`unavailable`,sourceUrl:`https://platform.openai.com/docs/api-reference/models/list`,message:`OpenAI model availability should be discovered live from GET /v1/models.`},setupHelpLinks:Te,setupSteps:[{key:`model`,title:`OpenAI model`,required:!0},{key:`apiKey`,title:`OpenAI API key`,defaultValue:Z,masked:!0}],requiresApiKey:!0,probeProfile:r.probeOpenAICompatibleProfile,destinationEnvironment:[`OPENAI_BASE_URL`,`OPENAI_ORG_ID`,`OPENAI_PROJECT_ID`],createProvider:e=>{let t=Q(e.options),n=Oe(e.options);return ke(e.baseURL,t,n),new Y({apiKey:De(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 De(e){if(!e)throw Error(`Provider openai requires apiKey`);return e}function Q(e){let t=e?.apiSurface;if(t===`responses`||t===`chat-completions`)return t}function Oe(e){let t=$(e?.nativeWebTools)??$(e?.builtInWebTools);if(t!==void 0)return t}function $(e){if(e==null||e instanceof Date||Array.isArray(e)||typeof e!=`object`)return;let t=e.webSearch,n=e.webFetch;return{...typeof t==`boolean`&&{webSearch:t},...typeof n==`boolean`&&{webFetch:n}}}function ke(e,t,n){if(n?.webSearch===!0||n?.webFetch===!0)throw Error(e!==void 0||t===`chat-completions`?`Provider openai profile uses an OpenAI-compatible Chat Completions endpoint; native web search/fetch is not supported for this profile. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`:`Provider openai native web search/fetch is not wired in this Robota provider version. Use Robota local WebSearch/WebFetch tools or a provider with documented hosted web support.`)}exports.DEFAULT_OPENAI_PROVIDER_API_KEY_REFERENCE=Z,exports.DEFAULT_OPENAI_PROVIDER_MODEL=void 0,exports.OpenAIConversationAdapter=we,exports.OpenAIProvider=Y,exports.createOpenAIProviderDefinition=Ee;
@@ -1,4 +1,4 @@
1
- import { n as IPayloadLoggerOptions, t as IPayloadLogger } from "./payload-logger-BaW0K8yI.cjs";
1
+ import { n as IPayloadLoggerOptions, t as IPayloadLogger } from "./payload-logger-n89AQdUn.cjs";
2
2
  import { AbstractAIProvider, IChatOptions, IExecutor, ILogger, IProviderCapabilities, IProviderDefinition, IProviderModelEffortTable, IToolSchemaProjectionProfile, TProviderOptionValueBase, TTextDeltaCallback, TUniversalMessage } from "@robota-sdk/agent-core";
3
3
  import OpenAI from "openai";
4
4
  //#region src/openai/types.d.ts
@@ -70,7 +70,7 @@ interface IOpenAIProviderOptions {
70
70
  * @example
71
71
  * ```ts
72
72
  * // Vercel AI Gateway with a non-OpenAI model slug
73
- * createOpenAIProvider({
73
+ * new OpenAIProvider({
74
74
  * apiKey: process.env.AI_GATEWAY_API_KEY,
75
75
  * baseURL: 'https://ai-gateway.vercel.sh/v1',
76
76
  * defaultModel: 'anthropic/claude-sonnet-4-5',
@@ -125,6 +125,9 @@ interface IOpenAIProviderOptions {
125
125
  * schema marked optional becomes required and gains a `null` branch. The model must then supply
126
126
  * the key explicitly, with `null` standing for "not provided". A tool whose handler distinguishes
127
127
  * an absent key from a null value will see the difference.
128
+ *
129
+ * Both surfaces declare the functions strict (`strict: true` on each tool), so an OpenAI-compatible
130
+ * endpoint that rejects that field needs `strictTools` left off.
128
131
  */
129
132
  strictTools?: boolean;
130
133
  /**
@@ -140,7 +143,9 @@ interface IOpenAIProviderOptions {
140
143
  */
141
144
  client?: OpenAI;
142
145
  /**
143
- * Payload logger instance for debugging API requests/responses
146
+ * Payload logger that receives a summary of each Chat Completions request (model, message
147
+ * count, whether tools were sent, temperature, max tokens) for debugging — not prompt or
148
+ * response content. Not called on the Responses API surface.
144
149
  *
145
150
  * Use different implementations based on your environment:
146
151
  * - FilePayloadLogger: Node.js file-based logging
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/openai/types.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"mappings":";;;;KAIY;UAEK;EACf;EACA;EACA,SAAS,eAAe;EACxB;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;;;;KAMU,4EAMR,8BACA,+BACA,mCACA,SACA,iBACA,UACA,YACA,2BACA;GACG,cAAc;;;;;UAKJ;;;;GAId,cAAc;;;;EAKf;;;;EAKA;;;;EAKA;;;;;;;EAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA;;;;EAKA;;;;;;;EAQA,aAAa;;;;;;;EAQb;;;;EAKA,aAAa;;;;;EAMb,YAAY;;;;EAKZ;;;;EAKA;;;;;;;;;;;;;;EAeA;;;;;;;;EASA,iBAAiB;;;;EAKjB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BT,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BhB,WAAW;;;;;EAMX,SAAS;;;;;;;;;;;;cCrME,uBAAuB;WAChB;WACA;mBAED;mBACA;mBACA;mBACA;mBACA;;;;;;;EAQjB,cAAc;EAEF,YAAA,SAAS;EA6BN,KACb,UAAU,qBACV,UAAU,eACT,QAAQ;EAgDK,WACd,UAAU,qBACV,UAAU,eACT,cAAc;UAiCF;;;;;;;;;;EAuCf;;;;;;EASA;UAIQ;UAKA;EAKC,eAAe;UAMhB;;;;;YAcW,qBAAqB;;;;;;;;UAahC;UAYA;EAiCC;EAIA,mBAAmB;EAwBnB;EAIM,WAAW;YAIP,iBAAiB,UAAU;;;;;;;;;;;;cC/UnC;;;;;;;;;SASJ,wBAAwB,UAAU,sBAAsB;;;;;SAqBxD,eAAe,UAAU,sBAAsB,OAAO,KAAK;;;;;SAU3D,eAAe,KAAK,oBAAoB,OAAO,KAAK;;;;SA2EpD,wBACL,UAAU,OAAO,KAAK,8BACtB,wBACC,OAAO,KAAK;;;;cC1HJ;cACA;iBAeG,kCAAkC"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/openai/types.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"mappings":";;;;KAIY;UAEK;EACf;EACA;EACA,SAAS,eAAe;EACxB;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;;;;KAMU,4EAMR,8BACA,+BACA,mCACA,SACA,iBACA,UACA,YACA,2BACA;GACG,cAAc;;;;;UAKJ;;;;GAId,cAAc;;;;EAKf;;;;EAKA;;;;EAKA;;;;;;;EAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA;;;;EAKA;;;;;;;EAQA,aAAa;;;;;;;EAQb;;;;EAKA,aAAa;;;;;EAMb,YAAY;;;;EAKZ;;;;EAKA;;;;;;;;;;;;;;;;;EAkBA;;;;;;;;EASA,iBAAiB;;;;EAKjB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BT,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BhB,WAAW;;;;;EAMX,SAAS;;;;;;;;;;;;cC1ME,uBAAuB;WAChB;WACA;mBAED;mBACA;mBACA;mBACA;mBACA;;;;;;;EAQjB,cAAc;EAEF,YAAA,SAAS;EA6BN,KACb,UAAU,qBACV,UAAU,eACT,QAAQ;EAgDK,WACd,UAAU,qBACV,UAAU,eACT,cAAc;UAiCF;;;;;;;;;;EAuCf;;;;;;EASA;UAIQ;UAKA;EAKC,eAAe;UAMhB;;;;;YAcW,qBAAqB;;;;;;;;UAahC;UAYA;EAiCC;EAIA,mBAAmB;EAwBnB;EAIM,WAAW;YAIP,iBAAiB,UAAU;;;;;;;;;;;;cC/UnC;;;;;;;;;SASJ,wBAAwB,UAAU,sBAAsB;;;;;SAqBxD,eAAe,UAAU,sBAAsB,OAAO,KAAK;;;;;SAU3D,eAAe,KAAK,oBAAoB,OAAO,KAAK;;;;SA2EpD,wBACL,UAAU,OAAO,KAAK,8BACtB,wBACC,OAAO,KAAK;;;;cC1HJ;cACA;iBAeG,kCAAkC"}
@@ -1,4 +1,4 @@
1
- import { n as IPayloadLoggerOptions, t as IPayloadLogger } from "./payload-logger-BaW0K8yI.js";
1
+ import { n as IPayloadLoggerOptions, t as IPayloadLogger } from "./payload-logger-n89AQdUn.js";
2
2
  import { AbstractAIProvider, IChatOptions, IExecutor, ILogger, IProviderCapabilities, IProviderDefinition, IProviderModelEffortTable, IToolSchemaProjectionProfile, TProviderOptionValueBase, TTextDeltaCallback, TUniversalMessage } from "@robota-sdk/agent-core";
3
3
  import OpenAI from "openai";
4
4
  //#region src/openai/types.d.ts
@@ -70,7 +70,7 @@ interface IOpenAIProviderOptions {
70
70
  * @example
71
71
  * ```ts
72
72
  * // Vercel AI Gateway with a non-OpenAI model slug
73
- * createOpenAIProvider({
73
+ * new OpenAIProvider({
74
74
  * apiKey: process.env.AI_GATEWAY_API_KEY,
75
75
  * baseURL: 'https://ai-gateway.vercel.sh/v1',
76
76
  * defaultModel: 'anthropic/claude-sonnet-4-5',
@@ -125,6 +125,9 @@ interface IOpenAIProviderOptions {
125
125
  * schema marked optional becomes required and gains a `null` branch. The model must then supply
126
126
  * the key explicitly, with `null` standing for "not provided". A tool whose handler distinguishes
127
127
  * an absent key from a null value will see the difference.
128
+ *
129
+ * Both surfaces declare the functions strict (`strict: true` on each tool), so an OpenAI-compatible
130
+ * endpoint that rejects that field needs `strictTools` left off.
128
131
  */
129
132
  strictTools?: boolean;
130
133
  /**
@@ -140,7 +143,9 @@ interface IOpenAIProviderOptions {
140
143
  */
141
144
  client?: OpenAI;
142
145
  /**
143
- * Payload logger instance for debugging API requests/responses
146
+ * Payload logger that receives a summary of each Chat Completions request (model, message
147
+ * count, whether tools were sent, temperature, max tokens) for debugging — not prompt or
148
+ * response content. Not called on the Responses API surface.
144
149
  *
145
150
  * Use different implementations based on your environment:
146
151
  * - FilePayloadLogger: Node.js file-based logging
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/openai/types.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"mappings":";;;;KAIY;UAEK;EACf;EACA;EACA,SAAS,eAAe;EACxB;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;;;;KAMU,4EAMR,8BACA,+BACA,mCACA,SACA,iBACA,UACA,YACA,2BACA;GACG,cAAc;;;;;UAKJ;;;;GAId,cAAc;;;;EAKf;;;;EAKA;;;;EAKA;;;;;;;EAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA;;;;EAKA;;;;;;;EAQA,aAAa;;;;;;;EAQb;;;;EAKA,aAAa;;;;;EAMb,YAAY;;;;EAKZ;;;;EAKA;;;;;;;;;;;;;;EAeA;;;;;;;;EASA,iBAAiB;;;;EAKjB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BT,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BhB,WAAW;;;;;EAMX,SAAS;;;;;;;;;;;;cCrME,uBAAuB;WAChB;WACA;mBAED;mBACA;mBACA;mBACA;mBACA;;;;;;;EAQjB,cAAc;EAEF,YAAA,SAAS;EA6BN,KACb,UAAU,qBACV,UAAU,eACT,QAAQ;EAgDK,WACd,UAAU,qBACV,UAAU,eACT,cAAc;UAiCF;;;;;;;;;;EAuCf;;;;;;EASA;UAIQ;UAKA;EAKC,eAAe;UAMhB;;;;;YAcW,qBAAqB;;;;;;;;UAahC;UAYA;EAiCC;EAIA,mBAAmB;EAwBnB;EAIM,WAAW;YAIP,iBAAiB,UAAU;;;;;;;;;;;;cC/UnC;;;;;;;;;SASJ,wBAAwB,UAAU,sBAAsB;;;;;SAqBxD,eAAe,UAAU,sBAAsB,OAAO,KAAK;;;;;SAU3D,eAAe,KAAK,oBAAoB,OAAO,KAAK;;;;SA2EpD,wBACL,UAAU,OAAO,KAAK,8BACtB,wBACC,OAAO,KAAK;;;;cC1HJ;cACA;iBAeG,kCAAkC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/openai/types.ts","../../src/openai/provider.ts","../../src/openai/adapter.ts","../../src/openai/provider-definition.ts"],"mappings":";;;;KAIY;UAEK;EACf;EACA;EACA,SAAS,eAAe;EACxB;;UAGe;EACf;EACA;;UAGe;EACf;EACA;;;;;KAMU,4EAMR,8BACA,+BACA,mCACA,SACA,iBACA,UACA,YACA,2BACA;GACG,cAAc;;;;;UAKJ;;;;GAId,cAAc;;;;EAKf;;;;EAKA;;;;EAKA;;;;;;;EAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA;;;;EAKA;;;;;;;EAQA,aAAa;;;;;;;EAQb;;;;EAKA,aAAa;;;;;EAMb,YAAY;;;;EAKZ;;;;EAKA;;;;;;;;;;;;;;;;;EAkBA;;;;;;;;EASA,iBAAiB;;;;EAKjB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BT,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BhB,WAAW;;;;;EAMX,SAAS;;;;;;;;;;;;cC1ME,uBAAuB;WAChB;WACA;mBAED;mBACA;mBACA;mBACA;mBACA;;;;;;;EAQjB,cAAc;EAEF,YAAA,SAAS;EA6BN,KACb,UAAU,qBACV,UAAU,eACT,QAAQ;EAgDK,WACd,UAAU,qBACV,UAAU,eACT,cAAc;UAiCF;;;;;;;;;;EAuCf;;;;;;EASA;UAIQ;UAKA;EAKC,eAAe;UAMhB;;;;;YAcW,qBAAqB;;;;;;;;UAahC;UAYA;EAiCC;EAIA,mBAAmB;EAwBnB;EAIM,WAAW;YAIP,iBAAiB,UAAU;;;;;;;;;;;;cC/UnC;;;;;;;;;SASJ,wBAAwB,UAAU,sBAAsB;;;;;SAqBxD,eAAe,UAAU,sBAAsB,OAAO,KAAK;;;;;SAU3D,eAAe,KAAK,oBAAoB,OAAO,KAAK;;;;SA2EpD,wBACL,UAAU,OAAO,KAAK,8BACtB,wBACC,OAAO,KAAK;;;;cC1HJ;cACA;iBAeG,kCAAkC"}