@adminforth/completion-adapter-openai-responses 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,3 +45,23 @@ The adapter supports:
45
45
  - tool calls
46
46
  - streaming output chunks
47
47
  - streaming reasoning chunks
48
+ - Responses API continuation with `previousResponseId`
49
+
50
+ ## Responses continuation
51
+
52
+ For regular completion flows you can pass the previous Responses API id to reuse
53
+ server-side context. The adapter returns the current `responseId`, which can be
54
+ used as `previousResponseId` on the next call:
55
+
56
+ ```ts
57
+ const first = await adapter.complete({
58
+ content: "Summarize the project requirements",
59
+ maxTokens: 300,
60
+ });
61
+
62
+ const second = await adapter.complete({
63
+ content: "Now turn that into three implementation milestones",
64
+ maxTokens: 300,
65
+ previousResponseId: first.responseId,
66
+ });
67
+ ```
package/dist/index.d.ts CHANGED
@@ -1,34 +1,13 @@
1
1
  import type { AdapterOptions } from "./types.js";
2
- import type { CompletionAdapter, CompletionStreamEvent, CompletionTool } from "adminforth";
3
- import { ChatOpenAI } from "@langchain/openai";
2
+ import type { CompletionAdapter, CompletionTool } from "adminforth";
3
+ import { type CompletionRequestInput, type CompletionResult, type ReasoningEffort, type StreamChunkCallback } from "./openai.js";
4
+ import { type AgentModelPurpose } from "./langchain.js";
4
5
  export type { AdapterOptions } from "./types.js";
5
- type StreamChunkCallback = (chunk: string, event?: CompletionStreamEvent) => void | Promise<void>;
6
- type ReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh";
7
- type AgentModelPurpose = "primary" | "summary";
8
- type CompletionRequestInput = {
9
- content: string;
10
- maxTokens?: number;
11
- outputSchema?: any;
12
- reasoningEffort?: ReasoningEffort;
13
- tools?: CompletionTool[];
14
- onChunk?: StreamChunkCallback;
15
- signal?: AbortSignal;
16
- };
17
- type UsedTokens = {
18
- input_uncached: number;
19
- input_cached: number;
20
- output: number;
21
- };
22
- type CompletionResult = {
23
- content?: string;
24
- finishReason?: string;
25
- error?: string;
26
- used_tokens?: UsedTokens;
27
- };
28
- export default class CompletionAdapterOpenAIResponses implements CompletionAdapter {
6
+ declare class CompletionAdapterOpenAIResponses implements CompletionAdapter {
29
7
  options: AdapterOptions;
30
8
  private encoding;
31
9
  private activeAbortController;
10
+ private openAi;
32
11
  constructor(options: AdapterOptions);
33
12
  validate(): void;
34
13
  measureTokensCount(content: string): number;
@@ -36,19 +15,14 @@ export default class CompletionAdapterOpenAIResponses implements CompletionAdapt
36
15
  isGenerationInProgress(): boolean;
37
16
  private getConfiguredBaseUrl;
38
17
  private shouldUseComplitionApi;
39
- private shouldDumpRawRequest;
40
- private getClientConfiguration;
41
- private createResponsesDebugFetch;
42
- private getFetchUrl;
43
- private isResponsesUrl;
44
- private dumpRawRequest;
45
- private getResponsesUrl;
46
18
  getLangChainAgentSpec(params: {
47
19
  maxTokens: number;
48
20
  purpose: AgentModelPurpose;
49
21
  }): {
50
- model: ChatOpenAI<import("@langchain/openai").ChatOpenAICallOptions>;
22
+ model: import("@langchain/openai").ChatOpenAI<import("@langchain/openai").ChatOpenAICallOptions>;
51
23
  middleware: import("langchain").AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ClientTool | import("@langchain/core/tools").ServerTool)[]>[];
52
24
  };
53
25
  complete: (requestOrContent: CompletionRequestInput | string, maxTokens?: number, outputSchema?: any, reasoningEffort?: ReasoningEffort, toolsOrOnChunk?: CompletionTool[] | StreamChunkCallback, onChunk?: StreamChunkCallback) => Promise<CompletionResult>;
54
26
  }
27
+ export { CompletionAdapterOpenAIResponses };
28
+ export default CompletionAdapterOpenAIResponses;
package/dist/index.js CHANGED
@@ -7,175 +7,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- var __rest = (this && this.__rest) || function (s, e) {
11
- var t = {};
12
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
- t[p] = s[p];
14
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
- t[p[i]] = s[p[i]];
18
- }
19
- return t;
20
- };
21
- import { AIMessage } from "@langchain/core/messages";
22
- import { ChatOpenAI } from "@langchain/openai";
23
- import { createMiddleware } from "langchain";
24
10
  import { encoding_for_model } from "tiktoken";
25
- const DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1";
26
- const RAW_REQUEST_LOG_PREFIX = "[CompletionAdapterOpenAIResponses] Raw /responses request";
27
- function extractOutputText(data) {
28
- var _a;
29
- let text = "";
30
- for (const item of (_a = data.output) !== null && _a !== void 0 ? _a : []) {
31
- if (item.type !== "message" || !Array.isArray(item.content))
32
- continue;
33
- for (const part of item.content) {
34
- if (part.type === "output_text" && typeof part.text === "string") {
35
- text += part.text;
36
- }
37
- }
38
- }
39
- return text;
40
- }
41
- function extractReasoning(data) {
42
- var _a, _b, _c;
43
- let reasoning = "";
44
- for (const item of (_a = data.output) !== null && _a !== void 0 ? _a : []) {
45
- if (item.type !== "reasoning")
46
- continue;
47
- for (const part of (_b = item.summary) !== null && _b !== void 0 ? _b : []) {
48
- if ((part === null || part === void 0 ? void 0 : part.type) === "summary_text" && typeof part.text === "string") {
49
- reasoning += part.text;
50
- }
51
- }
52
- if (!reasoning) {
53
- for (const part of (_c = item.content) !== null && _c !== void 0 ? _c : []) {
54
- if ((part === null || part === void 0 ? void 0 : part.type) === "reasoning_text" && typeof part.text === "string") {
55
- reasoning += part.text;
56
- }
57
- }
58
- }
59
- }
60
- return reasoning || undefined;
61
- }
62
- function extractFunctionCall(data) {
63
- var _a;
64
- for (const item of (_a = data.output) !== null && _a !== void 0 ? _a : []) {
65
- if (item.type === "function_call") {
66
- return item;
67
- }
68
- }
69
- return undefined;
70
- }
71
- function extractUsedTokens(data) {
72
- var _a, _b;
73
- const usage = data.usage;
74
- if (!usage) {
75
- return undefined;
76
- }
77
- const inputCached = (_b = (_a = usage.input_tokens_details) === null || _a === void 0 ? void 0 : _a.cached_tokens) !== null && _b !== void 0 ? _b : 0;
78
- return {
79
- input_uncached: Math.max(usage.input_tokens - inputCached, 0),
80
- input_cached: inputCached,
81
- output: usage.output_tokens,
82
- };
83
- }
84
- function executeToolCall(toolCall, tools) {
85
- return __awaiter(this, void 0, void 0, function* () {
86
- const tool = tools === null || tools === void 0 ? void 0 : tools.find((candidate) => candidate.name === toolCall.name);
87
- if (!tool) {
88
- throw new Error(`Tool "${toolCall.name}" not found`);
89
- }
90
- const toolResult = yield tool.handler(JSON.parse(toolCall.arguments));
91
- if (typeof toolResult === "string")
92
- return toolResult;
93
- if (typeof toolResult === "undefined")
94
- return "";
95
- return JSON.stringify(toolResult);
96
- });
97
- }
98
- function parseSseBlock(block) {
99
- let event;
100
- let data = "";
101
- for (const rawLine of block.split("\n")) {
102
- const line = rawLine.trimEnd();
103
- if (!line)
104
- continue;
105
- if (line.startsWith("event:"))
106
- event = line.slice(6).trim();
107
- if (line.startsWith("data:"))
108
- data += line.slice(5).trim();
109
- }
110
- return data ? { event, data } : null;
111
- }
112
- function getAgentReasoningEffort(purpose) {
113
- return purpose === "summary" ? "minimal" : "low";
114
- }
115
- function buildReasoningConfig(params) {
116
- var _a;
117
- return Object.assign({ summary: "auto", effort: params.effort }, ((_a = params.reasoning) !== null && _a !== void 0 ? _a : {}));
118
- }
119
- function getTurnKey(context) {
120
- return `${context.sessionId}:${context.turnId}`;
121
- }
122
- function getResponseId(message) {
123
- var _a;
124
- const metadata = message.response_metadata;
125
- return (_a = metadata === null || metadata === void 0 ? void 0 : metadata.id) !== null && _a !== void 0 ? _a : null;
126
- }
127
- function getPreviousResponseId(modelSettings) {
128
- return modelSettings === null || modelSettings === void 0 ? void 0 : modelSettings.previous_response_id;
129
- }
130
- function getContinuationMessages(messages, previousResponseId) {
131
- var _a;
132
- let continuationStartIndex = null;
133
- for (let index = messages.length - 1; index >= 0; index -= 1) {
134
- const message = messages[index];
135
- if (AIMessage.isInstance(message) &&
136
- ((_a = message.response_metadata) === null || _a === void 0 ? void 0 : _a.id) ===
137
- previousResponseId) {
138
- continuationStartIndex = index + 1;
139
- break;
140
- }
141
- }
142
- if (continuationStartIndex === null) {
143
- return null;
144
- }
145
- return messages.slice(continuationStartIndex);
146
- }
147
- function createOpenAiResponsesContinuationMiddleware() {
148
- const responseIdsByTurn = new Map();
149
- return createMiddleware({
150
- name: "OpenAiResponsesContinuationMiddleware",
151
- wrapModelCall(request, handler) {
152
- return __awaiter(this, void 0, void 0, function* () {
153
- var _a;
154
- const context = request.runtime.context;
155
- const turnKey = getTurnKey(context);
156
- const previousResponseId = (_a = getPreviousResponseId(request.modelSettings)) !== null && _a !== void 0 ? _a : responseIdsByTurn.get(turnKey);
157
- const continuationMessages = previousResponseId
158
- ? getContinuationMessages(request.messages, previousResponseId)
159
- : null;
160
- const response = (yield handler(previousResponseId && continuationMessages
161
- ? Object.assign(Object.assign({}, request), { messages: continuationMessages, modelSettings: Object.assign(Object.assign({}, request.modelSettings), { previous_response_id: previousResponseId }) }) : request));
162
- const responseId = getResponseId(response);
163
- if (responseId) {
164
- responseIdsByTurn.set(turnKey, responseId);
165
- }
166
- else {
167
- responseIdsByTurn.delete(turnKey);
168
- }
169
- return response;
170
- });
171
- },
172
- });
173
- }
174
- export default class CompletionAdapterOpenAIResponses {
11
+ import { OpenAIResponsesService, } from "./openai.js";
12
+ import { createLangChainAgentSpec, } from "./langchain.js";
13
+ class CompletionAdapterOpenAIResponses {
175
14
  constructor(options) {
176
15
  this.activeAbortController = null;
177
16
  this.complete = (requestOrContent_1, ...args_1) => __awaiter(this, [requestOrContent_1, ...args_1], void 0, function* (requestOrContent, maxTokens = 50, outputSchema, reasoningEffort = "low", toolsOrOnChunk, onChunk) {
178
- var _a, _b, _c;
179
17
  const request = typeof requestOrContent === "string"
180
18
  ? {
181
19
  content: requestOrContent,
@@ -188,37 +26,7 @@ export default class CompletionAdapterOpenAIResponses {
188
26
  : onChunk,
189
27
  }
190
28
  : requestOrContent;
191
- const { content, maxTokens: requestMaxTokens = 50, outputSchema: requestOutputSchema, reasoningEffort: requestReasoningEffort = "low", tools, onChunk: streamChunkCallback, signal: requestSignal, } = request;
192
- const model = this.options.model || "gpt-5-nano";
193
- const isStreaming = typeof streamChunkCallback === "function";
194
- const extra = this.options.extraRequestBodyParameters;
195
- const _d = extra !== null && extra !== void 0 ? extra : {}, { reasoning: extraReasoning } = _d, extraWithoutReasoning = __rest(_d, ["reasoning"]);
196
- let openAiTools = undefined;
197
- if (tools && tools.length > 0) {
198
- openAiTools = tools.map((tool) => ({
199
- type: "function",
200
- name: tool.name,
201
- description: tool.description,
202
- parameters: tool.input_schema,
203
- strict: false,
204
- }));
205
- }
206
- const body = Object.assign({ model, input: content, max_output_tokens: requestMaxTokens, stream: isStreaming, text: requestOutputSchema
207
- ? {
208
- format: Object.assign({ type: "json_schema" }, requestOutputSchema),
209
- }
210
- : {
211
- format: {
212
- type: "text",
213
- },
214
- }, reasoning: Object.assign({}, buildReasoningConfig({
215
- reasoning: extraReasoning,
216
- effort: requestReasoningEffort,
217
- })), tools: openAiTools }, extraWithoutReasoning);
218
- const serializedBody = JSON.stringify(body);
219
- if (this.shouldDumpRawRequest()) {
220
- this.dumpRawRequest(this.getResponsesUrl(), serializedBody);
221
- }
29
+ const { signal: requestSignal } = request;
222
30
  const abortController = new AbortController();
223
31
  this.activeAbortController = abortController;
224
32
  const abortFromRequestSignal = () => abortController.abort(requestSignal === null || requestSignal === void 0 ? void 0 : requestSignal.reason);
@@ -228,269 +36,18 @@ export default class CompletionAdapterOpenAIResponses {
228
36
  else {
229
37
  requestSignal === null || requestSignal === void 0 ? void 0 : requestSignal.addEventListener("abort", abortFromRequestSignal, { once: true });
230
38
  }
231
- let resp = null;
232
39
  try {
233
- resp = yield fetch(this.getResponsesUrl(), {
234
- method: "POST",
235
- headers: {
236
- "Content-Type": "application/json",
237
- Authorization: `Bearer ${this.options.openAiApiKey}`,
238
- },
239
- body: serializedBody,
240
- signal: abortController.signal,
241
- });
242
- }
243
- catch (error) {
244
- if (this.activeAbortController === abortController) {
245
- this.activeAbortController = null;
246
- }
247
- if (abortController.signal.aborted) {
248
- return {
249
- error: (error === null || error === void 0 ? void 0 : error.message) || "Generation aborted",
250
- finishReason: "aborted",
251
- };
252
- }
253
- return {
254
- error: (error === null || error === void 0 ? void 0 : error.message) || "OpenAI request failed",
255
- };
40
+ return yield this.openAi.complete(request, abortController.signal);
256
41
  }
257
42
  finally {
258
43
  requestSignal === null || requestSignal === void 0 ? void 0 : requestSignal.removeEventListener("abort", abortFromRequestSignal);
259
- }
260
- if (!resp) {
261
- if (this.activeAbortController === abortController) {
262
- this.activeAbortController = null;
263
- }
264
- return {
265
- error: "OpenAI request failed",
266
- };
267
- }
268
- try {
269
- if (!resp.ok) {
270
- let errorMessage = `OpenAI request failed with status ${resp.status}`;
271
- try {
272
- const errorData = (yield resp.json());
273
- if ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.message)
274
- errorMessage = errorData.error.message;
275
- }
276
- catch (_e) { }
277
- return { error: errorMessage };
278
- }
279
- if (!isStreaming) {
280
- const json = yield resp.json();
281
- const data = json;
282
- if (data.error) {
283
- return { error: data.error.message };
284
- }
285
- const usedTokens = extractUsedTokens(data);
286
- const toolCall = extractFunctionCall(data);
287
- if (toolCall) {
288
- try {
289
- const toolResult = yield executeToolCall(toolCall, tools);
290
- return {
291
- content: toolResult,
292
- finishReason: "tool_call",
293
- used_tokens: usedTokens,
294
- };
295
- }
296
- catch (error) {
297
- return {
298
- error: (error === null || error === void 0 ? void 0 : error.message) || "Tool execution failed",
299
- finishReason: "tool_call",
300
- used_tokens: usedTokens,
301
- };
302
- }
303
- }
304
- const parsedContent = extractOutputText(data);
305
- return {
306
- content: parsedContent,
307
- finishReason: ((_b = data.incomplete_details) === null || _b === void 0 ? void 0 : _b.reason)
308
- ? data.incomplete_details.reason
309
- : undefined,
310
- used_tokens: usedTokens,
311
- };
312
- }
313
- if (!resp.body) {
314
- return { error: "Response body is empty" };
315
- }
316
- const reader = resp.body.getReader();
317
- const decoder = new TextDecoder("utf-8");
318
- let buffer = "";
319
- let fullContent = "";
320
- let fullReasoning = "";
321
- let finishReason;
322
- let completedResponse;
323
- let usedTokens;
324
- const handleEvent = (event, eventType) => __awaiter(this, void 0, void 0, function* () {
325
- var _a, _b, _c, _d;
326
- const type = (event === null || event === void 0 ? void 0 : event.type) || eventType;
327
- if (type === "response.output_text.delta") {
328
- const delta = (event === null || event === void 0 ? void 0 : event.delta) || "";
329
- if (!delta)
330
- return;
331
- fullContent += delta;
332
- yield (streamChunkCallback === null || streamChunkCallback === void 0 ? void 0 : streamChunkCallback(delta, { type: "output", delta, text: fullContent }));
333
- return;
334
- }
335
- if (type === "response.reasoning_summary_text.delta" ||
336
- type === "response.reasoning_text.delta") {
337
- const delta = (event === null || event === void 0 ? void 0 : event.delta) || "";
338
- if (!delta)
339
- return;
340
- fullReasoning += delta;
341
- yield (streamChunkCallback === null || streamChunkCallback === void 0 ? void 0 : streamChunkCallback(delta, {
342
- type: "reasoning",
343
- delta,
344
- text: fullReasoning,
345
- }));
346
- return;
347
- }
348
- if (type === "response.completed" || type === "response.incomplete") {
349
- const response = event === null || event === void 0 ? void 0 : event.response;
350
- if (!response)
351
- return;
352
- const finalContent = extractOutputText(response);
353
- if (finalContent.startsWith(fullContent)) {
354
- const delta = finalContent.slice(fullContent.length);
355
- if (delta) {
356
- fullContent = finalContent;
357
- yield (streamChunkCallback === null || streamChunkCallback === void 0 ? void 0 : streamChunkCallback(delta, {
358
- type: "output",
359
- delta,
360
- text: fullContent,
361
- }));
362
- }
363
- }
364
- const finalReasoning = extractReasoning(response) || "";
365
- if (finalReasoning.startsWith(fullReasoning)) {
366
- const delta = finalReasoning.slice(fullReasoning.length);
367
- if (delta) {
368
- fullReasoning = finalReasoning;
369
- yield (streamChunkCallback === null || streamChunkCallback === void 0 ? void 0 : streamChunkCallback(delta, {
370
- type: "reasoning",
371
- delta,
372
- text: fullReasoning,
373
- }));
374
- }
375
- }
376
- finishReason =
377
- ((_a = response.incomplete_details) === null || _a === void 0 ? void 0 : _a.reason) || response.status || finishReason;
378
- completedResponse = response;
379
- usedTokens = extractUsedTokens(response);
380
- return;
381
- }
382
- if (type === "response.failed") {
383
- throw new Error(((_c = (_b = event === null || event === void 0 ? void 0 : event.response) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message) ||
384
- ((_d = event === null || event === void 0 ? void 0 : event.error) === null || _d === void 0 ? void 0 : _d.message) ||
385
- "Response failed");
386
- }
387
- });
388
- try {
389
- while (true) {
390
- const { value, done } = yield reader.read();
391
- if (done)
392
- break;
393
- buffer += decoder.decode(value, { stream: true });
394
- const blocks = buffer.split("\n\n");
395
- buffer = blocks.pop() || "";
396
- for (const block of blocks) {
397
- const parsedBlock = parseSseBlock(block);
398
- if (!(parsedBlock === null || parsedBlock === void 0 ? void 0 : parsedBlock.data) || parsedBlock.data === "[DONE]")
399
- continue;
400
- let event;
401
- try {
402
- event = JSON.parse(parsedBlock.data);
403
- }
404
- catch (_f) {
405
- continue;
406
- }
407
- if ((_c = event === null || event === void 0 ? void 0 : event.error) === null || _c === void 0 ? void 0 : _c.message) {
408
- return { error: event.error.message };
409
- }
410
- yield handleEvent(event, parsedBlock.event);
411
- }
412
- }
413
- if (buffer.trim()) {
414
- const parsedBlock = parseSseBlock(buffer.trim());
415
- if ((parsedBlock === null || parsedBlock === void 0 ? void 0 : parsedBlock.data) && parsedBlock.data !== "[DONE]") {
416
- try {
417
- yield handleEvent(JSON.parse(parsedBlock.data), parsedBlock.event);
418
- }
419
- catch (error) {
420
- return {
421
- error: (error === null || error === void 0 ? void 0 : error.message) || "Streaming failed",
422
- content: fullContent || undefined,
423
- finishReason,
424
- };
425
- }
426
- }
427
- }
428
- if (completedResponse) {
429
- const toolCall = extractFunctionCall(completedResponse);
430
- if (toolCall) {
431
- try {
432
- const toolResult = yield executeToolCall(toolCall, tools);
433
- if (toolResult) {
434
- const delta = toolResult.startsWith(fullContent)
435
- ? toolResult.slice(fullContent.length)
436
- : toolResult;
437
- if (delta) {
438
- yield (streamChunkCallback === null || streamChunkCallback === void 0 ? void 0 : streamChunkCallback(delta, {
439
- type: "output",
440
- delta,
441
- text: toolResult,
442
- }));
443
- }
444
- }
445
- return {
446
- content: toolResult,
447
- finishReason: "tool_call",
448
- used_tokens: usedTokens,
449
- };
450
- }
451
- catch (error) {
452
- return {
453
- error: (error === null || error === void 0 ? void 0 : error.message) || "Tool execution failed",
454
- content: fullContent || undefined,
455
- finishReason: "tool_call",
456
- used_tokens: usedTokens,
457
- };
458
- }
459
- }
460
- }
461
- return {
462
- content: fullContent || undefined,
463
- finishReason,
464
- used_tokens: usedTokens,
465
- };
466
- }
467
- catch (error) {
468
- if (abortController.signal.aborted) {
469
- return {
470
- error: (error === null || error === void 0 ? void 0 : error.message) || "Generation aborted",
471
- content: fullContent || undefined,
472
- finishReason: "aborted",
473
- used_tokens: usedTokens,
474
- };
475
- }
476
- return {
477
- error: (error === null || error === void 0 ? void 0 : error.message) || "Streaming failed",
478
- content: fullContent || undefined,
479
- finishReason,
480
- used_tokens: usedTokens,
481
- };
482
- }
483
- finally {
484
- reader.releaseLock();
485
- }
486
- }
487
- finally {
488
44
  if (this.activeAbortController === abortController) {
489
45
  this.activeAbortController = null;
490
46
  }
491
47
  }
492
48
  });
493
49
  this.options = options;
50
+ this.openAi = new OpenAIResponsesService(options);
494
51
  try {
495
52
  this.encoding = encoding_for_model((this.options.model || "gpt-5-nano"));
496
53
  }
@@ -525,89 +82,16 @@ export default class CompletionAdapterOpenAIResponses {
525
82
  }
526
83
  return Boolean(this.getConfiguredBaseUrl());
527
84
  }
528
- shouldDumpRawRequest() {
529
- return this.options.dumpRawRequest === true;
530
- }
531
- getClientConfiguration() {
532
- const configuredBaseUrl = this.getConfiguredBaseUrl();
533
- const debugFetch = this.shouldDumpRawRequest()
534
- ? this.createResponsesDebugFetch()
535
- : undefined;
536
- if (!configuredBaseUrl && !debugFetch) {
537
- return undefined;
538
- }
539
- return Object.assign(Object.assign({}, (configuredBaseUrl ? { baseURL: configuredBaseUrl } : {})), (debugFetch ? { fetch: debugFetch } : {}));
540
- }
541
- createResponsesDebugFetch() {
542
- return (input, init) => __awaiter(this, void 0, void 0, function* () {
543
- const url = this.getFetchUrl(input);
544
- if (this.isResponsesUrl(url) && typeof (init === null || init === void 0 ? void 0 : init.body) === "string") {
545
- this.dumpRawRequest(url, init.body);
546
- }
547
- return fetch(input, init);
548
- });
549
- }
550
- getFetchUrl(input) {
551
- if (typeof input === "string") {
552
- return input;
553
- }
554
- if (input instanceof URL) {
555
- return input.toString();
556
- }
557
- return input.url;
558
- }
559
- isResponsesUrl(url) {
560
- try {
561
- return new URL(url).pathname.endsWith("/responses");
562
- }
563
- catch (_a) {
564
- return url.endsWith("/responses") || url.includes("/responses?");
565
- }
566
- }
567
- dumpRawRequest(url, body) {
568
- console.info(`${RAW_REQUEST_LOG_PREFIX} ${url}`);
569
- try {
570
- console.info(JSON.stringify(JSON.parse(body), null, 2));
571
- }
572
- catch (_a) {
573
- console.info(body);
574
- }
575
- }
576
- getResponsesUrl() {
577
- const baseUrl = this.getConfiguredBaseUrl() || DEFAULT_OPENAI_BASE_URL;
578
- const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
579
- return new URL("responses", normalizedBaseUrl).toString();
580
- }
581
85
  getLangChainAgentSpec(params) {
582
- const extraRequestBodyParameters = (this.options.extraRequestBodyParameters || {});
583
- const { reasoning } = extraRequestBodyParameters, modelKwargs = __rest(extraRequestBodyParameters, ["reasoning"]);
584
- const configuredBaseUrl = this.getConfiguredBaseUrl();
585
- const normalizedModelKwargs = Object.assign({}, modelKwargs);
586
- const clientConfiguration = this.getClientConfiguration();
587
- const useComplitionApi = this.shouldUseComplitionApi();
588
- const chatOpenAiOptions = {
589
- model: this.options.model || "gpt-5-nano",
590
- apiKey: this.options.openAiApiKey,
86
+ return createLangChainAgentSpec({
87
+ options: this.options,
591
88
  maxTokens: params.maxTokens,
592
- reasoning: buildReasoningConfig({
593
- reasoning,
594
- effort: getAgentReasoningEffort(params.purpose),
595
- }),
596
- modelKwargs: normalizedModelKwargs,
597
- };
598
- chatOpenAiOptions.useResponsesApi = !useComplitionApi;
599
- let supportsResponseContinuation = true;
600
- if (configuredBaseUrl || useComplitionApi) {
601
- supportsResponseContinuation = false;
602
- }
603
- if (clientConfiguration) {
604
- chatOpenAiOptions.configuration = clientConfiguration;
605
- }
606
- return {
607
- model: new ChatOpenAI(chatOpenAiOptions),
608
- middleware: params.purpose === "primary" && supportsResponseContinuation
609
- ? [createOpenAiResponsesContinuationMiddleware()]
610
- : [],
611
- };
89
+ purpose: params.purpose,
90
+ configuredBaseUrl: this.getConfiguredBaseUrl(),
91
+ clientConfiguration: this.openAi.getClientConfiguration(),
92
+ useComplitionApi: this.shouldUseComplitionApi(),
93
+ });
612
94
  }
613
95
  }
96
+ export { CompletionAdapterOpenAIResponses };
97
+ export default CompletionAdapterOpenAIResponses;