@openrouter/sdk 0.3.16 → 0.5.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/esm/funcs/modelsListForUser.d.ts +5 -2
- package/esm/funcs/modelsListForUser.js +6 -3
- package/esm/index.d.ts +1 -0
- package/esm/lib/config.d.ts +8 -2
- package/esm/lib/config.js +2 -2
- package/esm/lib/model-result.d.ts +24 -3
- package/esm/lib/model-result.js +116 -16
- package/esm/lib/sdks.d.ts +1 -1
- package/esm/lib/sdks.js +28 -8
- package/esm/lib/stream-transformers.d.ts +12 -0
- package/esm/lib/stream-transformers.js +211 -5
- package/esm/lib/stream-type-guards.d.ts +1 -1
- package/esm/lib/stream-type-guards.js +1 -1
- package/esm/lib/tool-executor.js +11 -14
- package/esm/lib/tool-orchestrator.js +2 -2
- package/esm/lib/tool-types.d.ts +2 -1
- package/esm/models/chatgenerationparams.d.ts +22 -22
- package/esm/models/chatgenerationparams.js +24 -21
- package/esm/models/index.d.ts +0 -5
- package/esm/models/index.js +0 -5
- package/esm/sdk/models.d.ts +4 -1
- package/esm/sdk/models.js +4 -1
- package/esm/sdk/sdk.d.ts +0 -3
- package/esm/sdk/sdk.js +0 -4
- package/jsr.json +1 -1
- package/package.json +11 -11
- package/esm/funcs/completionsGenerate.d.ts +0 -18
- package/esm/funcs/completionsGenerate.js +0 -83
- package/esm/models/completionchoice.d.ts +0 -25
- package/esm/models/completionchoice.js +0 -34
- package/esm/models/completioncreateparams.d.ts +0 -120
- package/esm/models/completioncreateparams.js +0 -118
- package/esm/models/completionlogprobs.d.ts +0 -15
- package/esm/models/completionlogprobs.js +0 -24
- package/esm/models/completionresponse.d.ts +0 -19
- package/esm/models/completionresponse.js +0 -28
- package/esm/models/completionusage.d.ts +0 -12
- package/esm/models/completionusage.js +0 -23
- package/esm/sdk/completions.d.ts +0 -12
- package/esm/sdk/completions.js +0 -19
|
@@ -10,7 +10,10 @@ import * as operations from "../models/operations/index.js";
|
|
|
10
10
|
import { APIPromise } from "../types/async.js";
|
|
11
11
|
import { Result } from "../types/fp.js";
|
|
12
12
|
/**
|
|
13
|
-
* List models filtered by user provider preferences
|
|
13
|
+
* List models filtered by user provider preferences, privacy settings, and guardrails
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* List models filtered by user provider preferences, [privacy settings](https://openrouter.ai/docs/guides/privacy/logging), and [guardrails](https://openrouter.ai/docs/guides/features/guardrails). If requesting through `eu.openrouter.ai/api/v1/...` the results will be filtered to models that satisfy [EU in-region routing](https://openrouter.ai/docs/guides/privacy/logging#enterprise-eu-in-region-routing).
|
|
14
17
|
*/
|
|
15
|
-
export declare function modelsListForUser(client: OpenRouterCore, security: operations.ListModelsUserSecurity, options?: RequestOptions): APIPromise<Result<models.ModelsListResponse, errors.UnauthorizedResponseError | errors.InternalServerResponseError | OpenRouterError | ResponseValidationError | ConnectionError | RequestAbortedError | RequestTimeoutError | InvalidRequestError | UnexpectedClientError | SDKValidationError>>;
|
|
18
|
+
export declare function modelsListForUser(client: OpenRouterCore, security: operations.ListModelsUserSecurity, options?: RequestOptions): APIPromise<Result<models.ModelsListResponse, errors.UnauthorizedResponseError | errors.NotFoundResponseError | errors.InternalServerResponseError | OpenRouterError | ResponseValidationError | ConnectionError | RequestAbortedError | RequestTimeoutError | InvalidRequestError | UnexpectedClientError | SDKValidationError>>;
|
|
16
19
|
//# sourceMappingURL=modelsListForUser.d.ts.map
|
|
@@ -10,7 +10,10 @@ import * as errors from "../models/errors/index.js";
|
|
|
10
10
|
import * as models from "../models/index.js";
|
|
11
11
|
import { APIPromise } from "../types/async.js";
|
|
12
12
|
/**
|
|
13
|
-
* List models filtered by user provider preferences
|
|
13
|
+
* List models filtered by user provider preferences, privacy settings, and guardrails
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* List models filtered by user provider preferences, [privacy settings](https://openrouter.ai/docs/guides/privacy/logging), and [guardrails](https://openrouter.ai/docs/guides/features/guardrails). If requesting through `eu.openrouter.ai/api/v1/...` the results will be filtered to models that satisfy [EU in-region routing](https://openrouter.ai/docs/guides/privacy/logging#enterprise-eu-in-region-routing).
|
|
14
17
|
*/
|
|
15
18
|
export function modelsListForUser(client, security, options) {
|
|
16
19
|
return new APIPromise($do(client, security, options));
|
|
@@ -54,7 +57,7 @@ async function $do(client, security, options) {
|
|
|
54
57
|
const req = requestRes.value;
|
|
55
58
|
const doResult = await client._do(req, {
|
|
56
59
|
context,
|
|
57
|
-
errorCodes: ["401", "4XX", "500", "5XX"],
|
|
60
|
+
errorCodes: ["401", "404", "4XX", "500", "5XX"],
|
|
58
61
|
retryConfig: context.retryConfig,
|
|
59
62
|
retryCodes: context.retryCodes,
|
|
60
63
|
});
|
|
@@ -65,7 +68,7 @@ async function $do(client, security, options) {
|
|
|
65
68
|
const responseFields = {
|
|
66
69
|
HttpMeta: { Response: response, Request: req },
|
|
67
70
|
};
|
|
68
|
-
const [result] = await M.match(M.json(200, models.ModelsListResponse$inboundSchema), M.jsonErr(401, errors.UnauthorizedResponseError$inboundSchema), M.jsonErr(500, errors.InternalServerResponseError$inboundSchema), M.fail("4XX"), M.fail("5XX"))(response, req, { extraFields: responseFields });
|
|
71
|
+
const [result] = await M.match(M.json(200, models.ModelsListResponse$inboundSchema), M.jsonErr(401, errors.UnauthorizedResponseError$inboundSchema), M.jsonErr(404, errors.NotFoundResponseError$inboundSchema), M.jsonErr(500, errors.InternalServerResponseError$inboundSchema), M.fail("4XX"), M.fail("5XX"))(response, req, { extraFields: responseFields });
|
|
69
72
|
if (!result.ok) {
|
|
70
73
|
return [result, { status: "complete", request: req, response }];
|
|
71
74
|
}
|
package/esm/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { HTTPClient } from './lib/http.js';
|
|
|
14
14
|
export { applyNextTurnParamsToRequest, buildNextTurnParamsContext, executeNextTurnParamsFunctions, } from './lib/next-turn-params.js';
|
|
15
15
|
export { finishReasonIs, hasToolCall, isStopConditionMet, maxCost, maxTokensUsed, stepCountIs, } from './lib/stop-conditions.js';
|
|
16
16
|
export { extractUnsupportedContent, getUnsupportedContentSummary, hasUnsupportedContent, } from './lib/stream-transformers.js';
|
|
17
|
+
export type { StreamableOutputItem } from './lib/stream-transformers.js';
|
|
17
18
|
export { tool } from './lib/tool.js';
|
|
18
19
|
export { hasApprovalRequiredTools, hasExecuteFunction, isGeneratorTool, isRegularExecuteTool, isToolPreliminaryResultEvent, isToolResultEvent, toolHasApprovalConfigured, ToolType, } from './lib/tool-types.js';
|
|
19
20
|
export { buildTurnContext, normalizeInputToArray } from './lib/turn-context.js';
|
package/esm/lib/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Hook } from "../hooks/types.js";
|
|
1
2
|
import { HTTPClient } from "./http.js";
|
|
2
3
|
import { Logger } from "./logger.js";
|
|
3
4
|
import { RetryConfig } from "./retries.js";
|
|
@@ -40,13 +41,18 @@ export type SDKOptions = {
|
|
|
40
41
|
retryConfig?: RetryConfig;
|
|
41
42
|
timeoutMs?: number;
|
|
42
43
|
debugLogger?: Logger;
|
|
44
|
+
/**
|
|
45
|
+
* Hooks for request/response lifecycle events.
|
|
46
|
+
* Can be a single hook object or an array of hooks.
|
|
47
|
+
*/
|
|
48
|
+
hooks?: Hook | Hook[];
|
|
43
49
|
};
|
|
44
50
|
export declare function serverURLFromOptions(options: SDKOptions): URL | null;
|
|
45
51
|
export declare const SDK_METADATA: {
|
|
46
52
|
readonly language: "typescript";
|
|
47
53
|
readonly openapiDocVersion: "1.0.0";
|
|
48
|
-
readonly sdkVersion: "0.
|
|
54
|
+
readonly sdkVersion: "0.5.1";
|
|
49
55
|
readonly genVersion: "2.788.4";
|
|
50
|
-
readonly userAgent: "speakeasy-sdk/typescript 0.
|
|
56
|
+
readonly userAgent: "speakeasy-sdk/typescript 0.5.1 2.788.4 1.0.0 @openrouter/sdk";
|
|
51
57
|
};
|
|
52
58
|
//# sourceMappingURL=config.d.ts.map
|
package/esm/lib/config.js
CHANGED
|
@@ -26,8 +26,8 @@ export function serverURLFromOptions(options) {
|
|
|
26
26
|
export const SDK_METADATA = {
|
|
27
27
|
language: "typescript",
|
|
28
28
|
openapiDocVersion: "1.0.0",
|
|
29
|
-
sdkVersion: "0.
|
|
29
|
+
sdkVersion: "0.5.1",
|
|
30
30
|
genVersion: "2.788.4",
|
|
31
|
-
userAgent: "speakeasy-sdk/typescript 0.
|
|
31
|
+
userAgent: "speakeasy-sdk/typescript 0.5.1 2.788.4 1.0.0 @openrouter/sdk",
|
|
32
32
|
};
|
|
33
33
|
//# sourceMappingURL=config.js.map
|
|
@@ -3,6 +3,7 @@ import type * as models from '../models/index.js';
|
|
|
3
3
|
import type { CallModelInput } from './async-params.js';
|
|
4
4
|
import type { RequestOptions } from './sdks.js';
|
|
5
5
|
import type { ConversationState, ResponseStreamEvent, InferToolEventsUnion, InferToolOutputsUnion, ParsedToolCall, StateAccessor, StopWhen, Tool, ToolStreamEvent, TurnContext } from './tool-types.js';
|
|
6
|
+
import { type StreamableOutputItem } from './stream-transformers.js';
|
|
6
7
|
export interface GetResponseOptions<TTools extends readonly Tool[]> {
|
|
7
8
|
request: CallModelInput<TTools>;
|
|
8
9
|
client: OpenRouterCore;
|
|
@@ -245,12 +246,32 @@ export declare class ModelResult<TTools extends readonly Tool[]> {
|
|
|
245
246
|
*/
|
|
246
247
|
getTextStream(): AsyncIterableIterator<string>;
|
|
247
248
|
/**
|
|
249
|
+
* Stream all output items cumulatively as they arrive.
|
|
250
|
+
* Items are emitted with the same ID but progressively updated content as streaming progresses.
|
|
251
|
+
* Also yields tool results (function_call_output) after tool execution completes.
|
|
252
|
+
*
|
|
253
|
+
* Item types include:
|
|
254
|
+
* - message: Assistant text responses (emitted cumulatively as text streams)
|
|
255
|
+
* - function_call: Tool calls (emitted cumulatively as arguments stream)
|
|
256
|
+
* - reasoning: Model reasoning (emitted cumulatively as thinking streams)
|
|
257
|
+
* - web_search_call: Web search operations
|
|
258
|
+
* - file_search_call: File search operations
|
|
259
|
+
* - image_generation_call: Image generation operations
|
|
260
|
+
* - function_call_output: Results from executed tools
|
|
261
|
+
*/
|
|
262
|
+
getItemsStream(): AsyncIterableIterator<StreamableOutputItem>;
|
|
263
|
+
/**
|
|
264
|
+
* @deprecated Use `getItemsStream()` instead. This method only streams messages,
|
|
265
|
+
* while `getItemsStream()` streams all output item types (messages, function_calls,
|
|
266
|
+
* reasoning, etc.) with cumulative updates.
|
|
267
|
+
*
|
|
248
268
|
* Stream incremental message updates as content is added in responses format.
|
|
249
269
|
* Each iteration yields an updated version of the message with new content.
|
|
250
|
-
* Also yields OpenResponsesFunctionCallOutput after tool execution completes.
|
|
251
|
-
* Returns ResponsesOutputMessage or OpenResponsesFunctionCallOutput
|
|
270
|
+
* Also yields function_call items and OpenResponsesFunctionCallOutput after tool execution completes.
|
|
271
|
+
* Returns ResponsesOutputMessage, ResponsesOutputItemFunctionCall, or OpenResponsesFunctionCallOutput
|
|
272
|
+
* compatible with OpenAI Responses API format.
|
|
252
273
|
*/
|
|
253
|
-
getNewMessagesStream(): AsyncIterableIterator<models.ResponsesOutputMessage | models.OpenResponsesFunctionCallOutput>;
|
|
274
|
+
getNewMessagesStream(): AsyncIterableIterator<models.ResponsesOutputMessage | models.OpenResponsesFunctionCallOutput | models.ResponsesOutputItemFunctionCall>;
|
|
254
275
|
/**
|
|
255
276
|
* Stream only reasoning deltas as they arrive.
|
|
256
277
|
* This filters the full event stream to only yield reasoning content.
|
package/esm/lib/model-result.js
CHANGED
|
@@ -3,11 +3,12 @@ import { betaResponsesSend } from '../funcs/betaResponsesSend.js';
|
|
|
3
3
|
import { hasAsyncFunctions, resolveAsyncFunctions, } from './async-params.js';
|
|
4
4
|
import { appendToMessages, createInitialState, createRejectedResult, createUnsentResult, extractTextFromResponse as extractTextFromResponseState, partitionToolCalls, unsentResultsToAPIFormat, updateState, } from './conversation-state.js';
|
|
5
5
|
import { ReusableReadableStream } from './reusable-stream.js';
|
|
6
|
-
import { buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from './stream-transformers.js';
|
|
6
|
+
import { buildItemsStream, buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from './stream-transformers.js';
|
|
7
7
|
import { executeTool } from './tool-executor.js';
|
|
8
8
|
import { executeNextTurnParamsFunctions, applyNextTurnParamsToRequest } from './next-turn-params.js';
|
|
9
9
|
import { hasExecuteFunction } from './tool-types.js';
|
|
10
10
|
import { isStopConditionMet, stepCountIs } from './stop-conditions.js';
|
|
11
|
+
import { isOutputMessage, isFunctionCallItem, isReasoningOutputItem, isWebSearchCallOutputItem, isFileSearchCallOutputItem, isImageGenerationCallOutputItem, hasTypeProperty, } from './stream-type-guards.js';
|
|
11
12
|
/**
|
|
12
13
|
* Default maximum number of tool execution steps if no stopWhen is specified.
|
|
13
14
|
* This prevents infinite loops in tool execution.
|
|
@@ -30,15 +31,6 @@ function isEventStream(value) {
|
|
|
30
31
|
const maybeStream = value;
|
|
31
32
|
return typeof maybeStream.toReadableStream === 'function';
|
|
32
33
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Type guard for output items with a type property
|
|
35
|
-
*/
|
|
36
|
-
function hasTypeProperty(item) {
|
|
37
|
-
return (typeof item === 'object' &&
|
|
38
|
-
item !== null &&
|
|
39
|
-
'type' in item &&
|
|
40
|
-
typeof item.type === 'string');
|
|
41
|
-
}
|
|
42
34
|
/**
|
|
43
35
|
* A wrapper around a streaming response that provides multiple consumption patterns.
|
|
44
36
|
*
|
|
@@ -313,6 +305,32 @@ export class ModelResult {
|
|
|
313
305
|
const tool = this.options.tools?.find((t) => t.function.name === toolCall.name);
|
|
314
306
|
if (!tool || !hasExecuteFunction(tool))
|
|
315
307
|
continue;
|
|
308
|
+
// Check if arguments failed to parse (remained as string instead of object)
|
|
309
|
+
// This happens when the model returns invalid JSON for tool call arguments
|
|
310
|
+
// We use 'unknown' cast because the type system doesn't know arguments can be a string
|
|
311
|
+
// when JSON parsing fails in stream-transformers.ts
|
|
312
|
+
const args = toolCall.arguments;
|
|
313
|
+
if (typeof args === 'string') {
|
|
314
|
+
const rawArgs = args;
|
|
315
|
+
const errorMessage = `Failed to parse tool call arguments for "${toolCall.name}": The model provided invalid JSON. ` +
|
|
316
|
+
`Raw arguments received: "${rawArgs}". ` +
|
|
317
|
+
`Please provide valid JSON arguments for this tool call.`;
|
|
318
|
+
// Emit error event if broadcaster exists
|
|
319
|
+
if (this.toolEventBroadcaster) {
|
|
320
|
+
this.toolEventBroadcaster.push({
|
|
321
|
+
type: 'tool_result',
|
|
322
|
+
toolCallId: toolCall.id,
|
|
323
|
+
result: { error: errorMessage },
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
toolResults.push({
|
|
327
|
+
type: 'function_call_output',
|
|
328
|
+
id: `output_${toolCall.id}`,
|
|
329
|
+
callId: toolCall.id,
|
|
330
|
+
output: JSON.stringify({ error: errorMessage }),
|
|
331
|
+
});
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
316
334
|
// Track preliminary results for this specific tool call
|
|
317
335
|
const preliminaryResultsForCall = [];
|
|
318
336
|
// Create callback for real-time preliminary results
|
|
@@ -360,7 +378,13 @@ export class ModelResult {
|
|
|
360
378
|
async resolveAsyncFunctionsForTurn(turnContext) {
|
|
361
379
|
if (hasAsyncFunctions(this.options.request)) {
|
|
362
380
|
const resolved = await resolveAsyncFunctions(this.options.request, turnContext);
|
|
363
|
-
|
|
381
|
+
// Preserve accumulated input from previous turns
|
|
382
|
+
const preservedInput = this.resolvedRequest?.input;
|
|
383
|
+
this.resolvedRequest = {
|
|
384
|
+
...resolved,
|
|
385
|
+
stream: false,
|
|
386
|
+
...(preservedInput !== undefined && { input: preservedInput }),
|
|
387
|
+
};
|
|
364
388
|
}
|
|
365
389
|
}
|
|
366
390
|
/**
|
|
@@ -387,8 +411,15 @@ export class ModelResult {
|
|
|
387
411
|
* @returns The new response from the API
|
|
388
412
|
*/
|
|
389
413
|
async makeFollowupRequest(currentResponse, toolResults) {
|
|
390
|
-
// Build new input
|
|
414
|
+
// Build new input preserving original conversation + tool results
|
|
415
|
+
const originalInput = this.resolvedRequest?.input;
|
|
416
|
+
const normalizedOriginalInput = Array.isArray(originalInput)
|
|
417
|
+
? originalInput
|
|
418
|
+
: originalInput
|
|
419
|
+
? [{ role: 'user', content: originalInput }]
|
|
420
|
+
: [];
|
|
391
421
|
const newInput = [
|
|
422
|
+
...normalizedOriginalInput,
|
|
392
423
|
...(Array.isArray(currentResponse.output)
|
|
393
424
|
? currentResponse.output
|
|
394
425
|
: [currentResponse.output]),
|
|
@@ -397,9 +428,13 @@ export class ModelResult {
|
|
|
397
428
|
if (!this.resolvedRequest) {
|
|
398
429
|
throw new Error('Request not initialized');
|
|
399
430
|
}
|
|
400
|
-
|
|
431
|
+
// Update resolvedRequest.input with accumulated conversation for next turn
|
|
432
|
+
this.resolvedRequest = {
|
|
401
433
|
...this.resolvedRequest,
|
|
402
434
|
input: newInput,
|
|
435
|
+
};
|
|
436
|
+
const newRequest = {
|
|
437
|
+
...this.resolvedRequest,
|
|
403
438
|
stream: false,
|
|
404
439
|
};
|
|
405
440
|
const newResult = await betaResponsesSend(this.options.client, newRequest, this.options.options);
|
|
@@ -875,10 +910,68 @@ export class ModelResult {
|
|
|
875
910
|
}.call(this);
|
|
876
911
|
}
|
|
877
912
|
/**
|
|
913
|
+
* Stream all output items cumulatively as they arrive.
|
|
914
|
+
* Items are emitted with the same ID but progressively updated content as streaming progresses.
|
|
915
|
+
* Also yields tool results (function_call_output) after tool execution completes.
|
|
916
|
+
*
|
|
917
|
+
* Item types include:
|
|
918
|
+
* - message: Assistant text responses (emitted cumulatively as text streams)
|
|
919
|
+
* - function_call: Tool calls (emitted cumulatively as arguments stream)
|
|
920
|
+
* - reasoning: Model reasoning (emitted cumulatively as thinking streams)
|
|
921
|
+
* - web_search_call: Web search operations
|
|
922
|
+
* - file_search_call: File search operations
|
|
923
|
+
* - image_generation_call: Image generation operations
|
|
924
|
+
* - function_call_output: Results from executed tools
|
|
925
|
+
*/
|
|
926
|
+
getItemsStream() {
|
|
927
|
+
return async function* () {
|
|
928
|
+
await this.initStream();
|
|
929
|
+
if (!this.reusableStream) {
|
|
930
|
+
throw new Error('Stream not initialized');
|
|
931
|
+
}
|
|
932
|
+
// Stream all items from the API response cumulatively
|
|
933
|
+
yield* buildItemsStream(this.reusableStream);
|
|
934
|
+
// Execute tools if needed
|
|
935
|
+
await this.executeToolsIfNeeded();
|
|
936
|
+
// Yield function calls and outputs for each tool round
|
|
937
|
+
for (const round of this.allToolExecutionRounds) {
|
|
938
|
+
// Round 0's function_calls already yielded via buildItemsStream
|
|
939
|
+
if (round.round > 0) {
|
|
940
|
+
for (const item of round.response.output) {
|
|
941
|
+
if (isFunctionCallItem(item)) {
|
|
942
|
+
yield item;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
for (const toolResult of round.toolResults) {
|
|
947
|
+
yield toolResult;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
// If tools were executed, yield all items from the final response
|
|
951
|
+
if (this.finalResponse && this.allToolExecutionRounds.length > 0) {
|
|
952
|
+
for (const item of this.finalResponse.output) {
|
|
953
|
+
if (isOutputMessage(item) ||
|
|
954
|
+
isFunctionCallItem(item) ||
|
|
955
|
+
isReasoningOutputItem(item) ||
|
|
956
|
+
isWebSearchCallOutputItem(item) ||
|
|
957
|
+
isFileSearchCallOutputItem(item) ||
|
|
958
|
+
isImageGenerationCallOutputItem(item)) {
|
|
959
|
+
yield item;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}.call(this);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* @deprecated Use `getItemsStream()` instead. This method only streams messages,
|
|
967
|
+
* while `getItemsStream()` streams all output item types (messages, function_calls,
|
|
968
|
+
* reasoning, etc.) with cumulative updates.
|
|
969
|
+
*
|
|
878
970
|
* Stream incremental message updates as content is added in responses format.
|
|
879
971
|
* Each iteration yields an updated version of the message with new content.
|
|
880
|
-
* Also yields OpenResponsesFunctionCallOutput after tool execution completes.
|
|
881
|
-
* Returns ResponsesOutputMessage or OpenResponsesFunctionCallOutput
|
|
972
|
+
* Also yields function_call items and OpenResponsesFunctionCallOutput after tool execution completes.
|
|
973
|
+
* Returns ResponsesOutputMessage, ResponsesOutputItemFunctionCall, or OpenResponsesFunctionCallOutput
|
|
974
|
+
* compatible with OpenAI Responses API format.
|
|
882
975
|
*/
|
|
883
976
|
getNewMessagesStream() {
|
|
884
977
|
return async function* () {
|
|
@@ -890,8 +983,15 @@ export class ModelResult {
|
|
|
890
983
|
yield* buildResponsesMessageStream(this.reusableStream);
|
|
891
984
|
// Execute tools if needed
|
|
892
985
|
await this.executeToolsIfNeeded();
|
|
893
|
-
// Yield function
|
|
986
|
+
// Yield function calls and their outputs for each executed tool
|
|
894
987
|
for (const round of this.allToolExecutionRounds) {
|
|
988
|
+
// First yield the function_call items from the response that triggered tool execution
|
|
989
|
+
for (const item of round.response.output) {
|
|
990
|
+
if (isFunctionCallItem(item)) {
|
|
991
|
+
yield item;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
// Then yield the function_call_output results
|
|
895
995
|
for (const toolResult of round.toolResults) {
|
|
896
996
|
yield toolResult;
|
|
897
997
|
}
|
package/esm/lib/sdks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SDKHooks } from "../hooks/hooks.js";
|
|
2
|
-
import { HookContext } from "../hooks/types.js";
|
|
2
|
+
import type { HookContext } from "../hooks/types.js";
|
|
3
3
|
import { ConnectionError, InvalidRequestError, RequestAbortedError, RequestTimeoutError, UnexpectedClientError } from "../models/errors/httpclienterrors.js";
|
|
4
4
|
import { Result } from "../types/fp.js";
|
|
5
5
|
import { SDKOptions } from "./config.js";
|
package/esm/lib/sdks.js
CHANGED
|
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
13
13
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
14
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
15
|
};
|
|
16
|
-
var _ClientSDK_httpClient, _ClientSDK_hooks, _ClientSDK_logger;
|
|
16
|
+
var _ClientSDK_instances, _ClientSDK_httpClient, _ClientSDK_hooks, _ClientSDK_logger, _ClientSDK_registerHook;
|
|
17
17
|
import { SDKHooks } from "../hooks/hooks.js";
|
|
18
18
|
import { ConnectionError, InvalidRequestError, RequestAbortedError, RequestTimeoutError, UnexpectedClientError, } from "../models/errors/httpclienterrors.js";
|
|
19
19
|
import { ERR, OK } from "../types/fp.js";
|
|
@@ -33,18 +33,22 @@ const isBrowserLike = webWorkerLike
|
|
|
33
33
|
|| (typeof window === "object" && typeof window.document !== "undefined");
|
|
34
34
|
export class ClientSDK {
|
|
35
35
|
constructor(options = {}) {
|
|
36
|
+
_ClientSDK_instances.add(this);
|
|
36
37
|
_ClientSDK_httpClient.set(this, void 0);
|
|
37
38
|
_ClientSDK_hooks.set(this, void 0);
|
|
38
39
|
_ClientSDK_logger.set(this, void 0);
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
&& "hooks" in opt
|
|
43
|
-
&& opt.hooks instanceof SDKHooks) {
|
|
44
|
-
__classPrivateFieldSet(this, _ClientSDK_hooks, opt.hooks, "f");
|
|
40
|
+
// Reuse existing SDKHooks if passed (for sub-SDKs)
|
|
41
|
+
if (options.hooks instanceof SDKHooks) {
|
|
42
|
+
__classPrivateFieldSet(this, _ClientSDK_hooks, options.hooks, "f");
|
|
45
43
|
}
|
|
46
44
|
else {
|
|
47
45
|
__classPrivateFieldSet(this, _ClientSDK_hooks, new SDKHooks(), "f");
|
|
46
|
+
if (options.hooks) {
|
|
47
|
+
const hooksArray = Array.isArray(options.hooks) ? options.hooks : [options.hooks];
|
|
48
|
+
for (const hook of hooksArray) {
|
|
49
|
+
__classPrivateFieldGet(this, _ClientSDK_instances, "m", _ClientSDK_registerHook).call(this, hook);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
const defaultHttpClient = new HTTPClient();
|
|
50
54
|
options.httpClient = options.httpClient || defaultHttpClient;
|
|
@@ -185,7 +189,23 @@ export class ClientSDK {
|
|
|
185
189
|
});
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
|
-
_ClientSDK_httpClient = new WeakMap(), _ClientSDK_hooks = new WeakMap(), _ClientSDK_logger = new WeakMap()
|
|
192
|
+
_ClientSDK_httpClient = new WeakMap(), _ClientSDK_hooks = new WeakMap(), _ClientSDK_logger = new WeakMap(), _ClientSDK_instances = new WeakSet(), _ClientSDK_registerHook = function _ClientSDK_registerHook(hook) {
|
|
193
|
+
if ("sdkInit" in hook) {
|
|
194
|
+
__classPrivateFieldGet(this, _ClientSDK_hooks, "f").registerSDKInitHook(hook);
|
|
195
|
+
}
|
|
196
|
+
if ("beforeCreateRequest" in hook) {
|
|
197
|
+
__classPrivateFieldGet(this, _ClientSDK_hooks, "f").registerBeforeCreateRequestHook(hook);
|
|
198
|
+
}
|
|
199
|
+
if ("beforeRequest" in hook) {
|
|
200
|
+
__classPrivateFieldGet(this, _ClientSDK_hooks, "f").registerBeforeRequestHook(hook);
|
|
201
|
+
}
|
|
202
|
+
if ("afterSuccess" in hook) {
|
|
203
|
+
__classPrivateFieldGet(this, _ClientSDK_hooks, "f").registerAfterSuccessHook(hook);
|
|
204
|
+
}
|
|
205
|
+
if ("afterError" in hook) {
|
|
206
|
+
__classPrivateFieldGet(this, _ClientSDK_hooks, "f").registerAfterErrorHook(hook);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
189
209
|
const jsonLikeContentTypeRE = /(application|text)\/.*?\+*json.*/;
|
|
190
210
|
const jsonlLikeContentTypeRE = /(application|text)\/(.*?\+*\bjsonl\b.*|.*?\+*\bx-ndjson\b.*)/;
|
|
191
211
|
async function logRequest(logger, req) {
|
|
@@ -18,6 +18,18 @@ export declare function extractToolDeltas(stream: ReusableReadableStream<models.
|
|
|
18
18
|
* Returns ResponsesOutputMessage (assistant/responses format)
|
|
19
19
|
*/
|
|
20
20
|
export declare function buildResponsesMessageStream(stream: ReusableReadableStream<models.OpenResponsesStreamEvent>): AsyncIterableIterator<models.ResponsesOutputMessage>;
|
|
21
|
+
/**
|
|
22
|
+
* Output item types that can be streamed from a response.
|
|
23
|
+
* This is the union of all item types that appear in response output,
|
|
24
|
+
* plus function_call_output for tool results.
|
|
25
|
+
*/
|
|
26
|
+
export type StreamableOutputItem = models.ResponsesOutputMessage | models.ResponsesOutputItemFunctionCall | models.ResponsesOutputItemReasoning | models.ResponsesWebSearchCallOutput | models.ResponsesOutputItemFileSearchCall | models.ResponsesImageGenerationCall | models.OpenResponsesFunctionCallOutput;
|
|
27
|
+
/**
|
|
28
|
+
* Build incremental output item updates from responses stream events.
|
|
29
|
+
* Yields all item types cumulatively - same item may be emitted multiple times
|
|
30
|
+
* with the same ID but progressively updated content as streaming progresses.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildItemsStream(stream: ReusableReadableStream<models.OpenResponsesStreamEvent>): AsyncIterableIterator<StreamableOutputItem>;
|
|
21
33
|
/**
|
|
22
34
|
* Build incremental message updates from responses stream events
|
|
23
35
|
* Returns AssistantMessage (chat format) instead of ResponsesOutputMessage
|