Skip to content

Commit 6c2d07d

Browse files
robert-j-yOpenRouter Team
andauthored
chore: sync from monorepo (#167)
Automated export from OpenRouter monorepo. This PR was created by Copybara to sync changes from the monorepo source of truth. Co-authored-by: OpenRouter Team <engineering@openrouter.ai>
1 parent cb302be commit 6c2d07d

17 files changed

+1525
-85
lines changed

.speakeasy/gen.lock

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
lockVersion: 2.0.0
22
id: 8b6cd71c-ea04-44da-af45-e43968b5928d
33
management:
4-
docChecksum: ad7e31da06ce6399342bfab65b33bd39
4+
docChecksum: 73e9a83b95df662091c1325b5ce88d01
55
docVersion: 1.0.0
66
speakeasyVersion: 1.680.0
77
generationVersion: 2.788.4
8-
releaseVersion: 0.4.0
9-
configChecksum: 0a5239ed77eed75be925b208e69544ac
8+
releaseVersion: 0.5.1
9+
configChecksum: cc01f824304d9ee6508e348557713ecb
1010
repoURL: https://github.com/OpenRouterTeam/typescript-sdk.git
1111
installationURL: https://github.com/OpenRouterTeam/typescript-sdk
1212
published: true
1313
persistentEdits:
14-
generation_id: c0170acd-b4b0-4bfe-9c01-d03b417ce575
15-
pristine_commit_hash: 18739563fe8d4aa756fe9a335822327a1788b932
16-
pristine_tree_hash: 08bd942e9790b82b3751e5e9560b1b41b57f369f
14+
generation_id: 17290e1f-a7b8-4a42-8730-8e335b3b4185
15+
pristine_commit_hash: 6cb777df87266ed92b16464de80b5097796805a3
16+
pristine_tree_hash: c21b5a7b386b90ca65fb1c97f21ac93f27a49d86
1717
features:
1818
typescript:
1919
acceptHeaders: 2.81.2
@@ -2172,12 +2172,12 @@ trackedFiles:
21722172
pristine_git_object: 410efafd6a7f50d91ccb87131fedbe0c3d47e15a
21732173
jsr.json:
21742174
id: 7f6ab7767282
2175-
last_write_checksum: sha1:bb8995e8816ebd2e300540b21c73454fd64e0f3a
2176-
pristine_git_object: 8d3bd8a29dc48b27ed24cb0bd9fe33dd16884817
2175+
last_write_checksum: sha1:9968774b7b8c66dc585f852bfcf6f5d3911206fc
2176+
pristine_git_object: 8f77d11a532ea048a80c81db3b3f982a2c8e7374
21772177
package.json:
21782178
id: 7030d0b2f71b
2179-
last_write_checksum: sha1:789426bc32a7c6a9fe8f6bdc83bc5e805aed3c02
2180-
pristine_git_object: 6ea02ca0d9df128a198bd0d2e0632797ed887b5c
2179+
last_write_checksum: sha1:9e2d85ad86eb1769b9492b6589e55c57e9e327de
2180+
pristine_git_object: 7587aa9f3c653ad96e1d117cf30361a76e728486
21812181
src/core.ts:
21822182
id: f431fdbcd144
21832183
last_write_checksum: sha1:5aa66b0b6a5964f3eea7f3098c2eb3c0ee9c0131
@@ -2336,16 +2336,16 @@ trackedFiles:
23362336
pristine_git_object: ccd5e5d812cb4d21a1013c89f04daad9d2f72190
23372337
src/index.ts:
23382338
id: c5fb850250c7
2339-
last_write_checksum: sha1:7ed2a5fa061eff70d4a20f33fc3269c60a5b1821
2340-
pristine_git_object: 35c2fb4c999bde2ca2b78b36088b052235d4bdff
2339+
last_write_checksum: sha1:8232ceb975ab0ad9abc06fe63c7ce79b18bb47d0
2340+
pristine_git_object: bb0c15148be25feb935e2d50c35c072b516cbcb5
23412341
src/lib/base64.ts:
23422342
id: "598522066688"
23432343
last_write_checksum: sha1:26b234d589cc15afab76ac7aaba1dd1bd4b4a84c
23442344
pristine_git_object: a187e58707bdb726ca2aff74941efe7493422d4e
23452345
src/lib/config.ts:
23462346
id: 320761608fb3
2347-
last_write_checksum: sha1:a6271bf3fb3922ca9db0c16da69be69e649eb004
2348-
pristine_git_object: 37e685251021b0799254a065c4157bd321f07ba5
2347+
last_write_checksum: sha1:3fef41a7e2402f2b9c0609d94ecd42e4bffb754c
2348+
pristine_git_object: 004af19750619bf38869027939712180f7bb6837
23492349
src/lib/dlv.ts:
23502350
id: b1988214835a
23512351
last_write_checksum: sha1:eaac763b22717206a6199104e0403ed17a4e2711

.speakeasy/gen.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ generation:
3333
skipResponseBodyAssertions: false
3434
preApplyUnionDiscriminators: true
3535
typescript:
36-
version: 0.4.0
36+
version: 0.5.1
3737
acceptHeaderEnum: false
3838
additionalDependencies:
3939
dependencies:

.speakeasy/in.openapi.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9467,7 +9467,7 @@ paths:
94679467
x-speakeasy-name-override: create
94689468
x-speakeasy-stream-request-field: stream
94699469
tags:
9470-
- anthropic.messages
9470+
- Anthropic Messages
94719471
summary: Create a message
94729472
description: >-
94739473
Creates a message using the Anthropic Messages API format. Supports text, images, PDFs, tools, and extended
@@ -13581,6 +13581,8 @@ tags:
1358113581
description: API key management endpoints
1358213582
- name: Analytics
1358313583
description: Analytics and usage endpoints
13584+
- name: Anthropic Messages
13585+
description: Anthropic Messages endpoints
1358413586
- name: Chat
1358513587
description: Chat completion endpoints
1358613588
- name: Credits
@@ -13599,8 +13601,6 @@ tags:
1359913601
description: OAuth authentication endpoints
1360013602
- name: Providers
1360113603
description: Provider information endpoints
13602-
- name: anthropic.messages
13603-
description: anthropic.messages endpoints
1360413604
- name: beta.responses
1360513605
description: beta.responses endpoints
1360613606
x-fern-base-path: /

.speakeasy/out.openapi.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9491,7 +9491,7 @@ paths:
94919491
x-speakeasy-name-override: create
94929492
x-speakeasy-stream-request-field: stream
94939493
tags:
9494-
- anthropic.messages
9494+
- Anthropic Messages
94959495
summary: Create a message
94969496
description: >-
94979497
Creates a message using the Anthropic Messages API format. Supports text, images, PDFs, tools, and extended thinking.
@@ -13581,6 +13581,8 @@ tags:
1358113581
description: API key management endpoints
1358213582
- name: Analytics
1358313583
description: Analytics and usage endpoints
13584+
- name: Anthropic Messages
13585+
description: Anthropic Messages endpoints
1358413586
- name: Chat
1358513587
description: Chat completion endpoints
1358613588
- name: Credits
@@ -13599,8 +13601,6 @@ tags:
1359913601
description: OAuth authentication endpoints
1360013602
- name: Providers
1360113603
description: Provider information endpoints
13602-
- name: anthropic.messages
13603-
description: anthropic.messages endpoints
1360413604
- name: beta.responses
1360513605
description: beta.responses endpoints
1360613606
x-fern-base-path: /

.speakeasy/workflow.lock

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ speakeasyVersion: 1.680.0
22
sources:
33
OpenRouter API:
44
sourceNamespace: open-router-chat-completions-api
5-
sourceRevisionDigest: sha256:918ea9897844be80c8981f374291b9731af294730415cfa27a98da846b02416a
6-
sourceBlobDigest: sha256:f10085a818483a67ece3ac3b9e8112cc26cffdab3ec7e583f1be2ca78fdc1c78
5+
sourceRevisionDigest: sha256:d0f1998ad92ab7b3f66f9d40fbde6c4b922137e768efb4adb91907d12c3bb235
6+
sourceBlobDigest: sha256:f5e39b02fd76a6dbd02df72a4d5b281038b40ecac762921a6157221e98485574
77
tags:
88
- latest
9+
- main
910
- 1.0.0
1011
targets:
1112
openrouter:
1213
source: OpenRouter API
1314
sourceNamespace: open-router-chat-completions-api
14-
sourceRevisionDigest: sha256:918ea9897844be80c8981f374291b9731af294730415cfa27a98da846b02416a
15-
sourceBlobDigest: sha256:f10085a818483a67ece3ac3b9e8112cc26cffdab3ec7e583f1be2ca78fdc1c78
15+
sourceRevisionDigest: sha256:d0f1998ad92ab7b3f66f9d40fbde6c4b922137e768efb4adb91907d12c3bb235
16+
sourceBlobDigest: sha256:f5e39b02fd76a6dbd02df72a4d5b281038b40ecac762921a6157221e98485574
1617
workflow:
1718
workflowVersion: 1.0.0
1819
speakeasyVersion: 1.680.0

jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
{
44
"name": "@openrouter/sdk",
5-
"version": "0.4.0",
5+
"version": "0.5.1",
66
"exports": {
77
".": "./src/index.ts",
88
"./models/errors": "./src/models/errors/index.ts",

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openrouter/sdk",
3-
"version": "0.4.0",
3+
"version": "0.5.1",
44
"author": "OpenRouter",
55
"description": "The OpenRouter TypeScript SDK is a type-safe toolkit for building AI applications with access to 300+ language models through a unified API.",
66
"keywords": [
@@ -89,4 +89,4 @@
8989
"zod": "^3.25.0 || ^4.0.0"
9090
},
9191
"packageManager": "pnpm@10.22.0"
92-
}
92+
}

src/lib/config.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* @generated-id: 320761608fb3
44
*/
55

6+
import type { Hook } from "../hooks/types.js";
67
import { HTTPClient } from "./http.js";
78
import { Logger } from "./logger.js";
89
import { RetryConfig } from "./retries.js";
@@ -51,6 +52,11 @@ export type SDKOptions = {
5152
retryConfig?: RetryConfig;
5253
timeoutMs?: number;
5354
debugLogger?: Logger;
55+
/**
56+
* Hooks for request/response lifecycle events.
57+
* Can be a single hook object or an array of hooks.
58+
*/
59+
hooks?: Hook | Hook[];
5460
};
5561

5662
export function serverURLFromOptions(options: SDKOptions): URL | null {
@@ -70,7 +76,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
7076
export const SDK_METADATA = {
7177
language: "typescript",
7278
openapiDocVersion: "1.0.0",
73-
sdkVersion: "0.4.0",
79+
sdkVersion: "0.5.1",
7480
genVersion: "2.788.4",
75-
userAgent: "speakeasy-sdk/typescript 0.4.0 2.788.4 1.0.0 @openrouter/sdk",
81+
userAgent: "speakeasy-sdk/typescript 0.5.1 2.788.4 1.0.0 @openrouter/sdk",
7682
} as const;

src/lib/model-result.ts

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import { hasExecuteFunction } from './tool-types.js';
5454
import { isStopConditionMet, stepCountIs } from './stop-conditions.js';
5555
import {
5656
isOutputMessage,
57-
isFunctionCallOutputItem,
57+
isFunctionCallItem,
5858
isReasoningOutputItem,
5959
isWebSearchCallOutputItem,
6060
isFileSearchCallOutputItem,
@@ -478,6 +478,35 @@ export class ModelResult<TTools extends readonly Tool[]> {
478478
const tool = this.options.tools?.find((t) => t.function.name === toolCall.name);
479479
if (!tool || !hasExecuteFunction(tool)) continue;
480480

481+
// Check if arguments failed to parse (remained as string instead of object)
482+
// This happens when the model returns invalid JSON for tool call arguments
483+
// We use 'unknown' cast because the type system doesn't know arguments can be a string
484+
// when JSON parsing fails in stream-transformers.ts
485+
const args: unknown = toolCall.arguments;
486+
if (typeof args === 'string') {
487+
const rawArgs = args;
488+
const errorMessage = `Failed to parse tool call arguments for "${toolCall.name}": The model provided invalid JSON. ` +
489+
`Raw arguments received: "${rawArgs}". ` +
490+
`Please provide valid JSON arguments for this tool call.`;
491+
492+
// Emit error event if broadcaster exists
493+
if (this.toolEventBroadcaster) {
494+
this.toolEventBroadcaster.push({
495+
type: 'tool_result' as const,
496+
toolCallId: toolCall.id,
497+
result: { error: errorMessage } as InferToolOutputsUnion<TTools>,
498+
});
499+
}
500+
501+
toolResults.push({
502+
type: 'function_call_output' as const,
503+
id: `output_${toolCall.id}`,
504+
callId: toolCall.id,
505+
output: JSON.stringify({ error: errorMessage }),
506+
});
507+
continue;
508+
}
509+
481510
// Track preliminary results for this specific tool call
482511
const preliminaryResultsForCall: InferToolEventsUnion<TTools>[] = [];
483512

@@ -531,7 +560,13 @@ export class ModelResult<TTools extends readonly Tool[]> {
531560
private async resolveAsyncFunctionsForTurn(turnContext: TurnContext): Promise<void> {
532561
if (hasAsyncFunctions(this.options.request)) {
533562
const resolved = await resolveAsyncFunctions(this.options.request, turnContext);
534-
this.resolvedRequest = { ...resolved, stream: false };
563+
// Preserve accumulated input from previous turns
564+
const preservedInput = this.resolvedRequest?.input;
565+
this.resolvedRequest = {
566+
...resolved,
567+
stream: false,
568+
...(preservedInput !== undefined && { input: preservedInput }),
569+
};
535570
}
536571
}
537572

@@ -572,8 +607,17 @@ export class ModelResult<TTools extends readonly Tool[]> {
572607
currentResponse: models.OpenResponsesNonStreamingResponse,
573608
toolResults: models.OpenResponsesFunctionCallOutput[]
574609
): Promise<models.OpenResponsesNonStreamingResponse> {
575-
// Build new input with tool results
610+
// Build new input preserving original conversation + tool results
611+
const originalInput = this.resolvedRequest?.input;
612+
const normalizedOriginalInput: models.OpenResponsesInput1[] =
613+
Array.isArray(originalInput)
614+
? originalInput
615+
: originalInput
616+
? [{ role: 'user', content: originalInput }]
617+
: [];
618+
576619
const newInput: models.OpenResponsesInput = [
620+
...normalizedOriginalInput,
577621
...(Array.isArray(currentResponse.output)
578622
? currentResponse.output
579623
: [currentResponse.output]),
@@ -584,9 +628,14 @@ export class ModelResult<TTools extends readonly Tool[]> {
584628
throw new Error('Request not initialized');
585629
}
586630

587-
const newRequest: models.OpenResponsesRequest = {
631+
// Update resolvedRequest.input with accumulated conversation for next turn
632+
this.resolvedRequest = {
588633
...this.resolvedRequest,
589634
input: newInput,
635+
};
636+
637+
const newRequest: models.OpenResponsesRequest = {
638+
...this.resolvedRequest,
590639
stream: false,
591640
};
592641

@@ -1184,8 +1233,16 @@ export class ModelResult<TTools extends readonly Tool[]> {
11841233
// Execute tools if needed
11851234
await this.executeToolsIfNeeded();
11861235

1187-
// Yield function call outputs for each executed tool
1236+
// Yield function calls and outputs for each tool round
11881237
for (const round of this.allToolExecutionRounds) {
1238+
// Round 0's function_calls already yielded via buildItemsStream
1239+
if (round.round > 0) {
1240+
for (const item of round.response.output) {
1241+
if (isFunctionCallItem(item)) {
1242+
yield item;
1243+
}
1244+
}
1245+
}
11891246
for (const toolResult of round.toolResults) {
11901247
yield toolResult;
11911248
}
@@ -1196,7 +1253,7 @@ export class ModelResult<TTools extends readonly Tool[]> {
11961253
for (const item of this.finalResponse.output) {
11971254
if (
11981255
isOutputMessage(item) ||
1199-
isFunctionCallOutputItem(item) ||
1256+
isFunctionCallItem(item) ||
12001257
isReasoningOutputItem(item) ||
12011258
isWebSearchCallOutputItem(item) ||
12021259
isFileSearchCallOutputItem(item) ||
@@ -1216,11 +1273,12 @@ export class ModelResult<TTools extends readonly Tool[]> {
12161273
*
12171274
* Stream incremental message updates as content is added in responses format.
12181275
* Each iteration yields an updated version of the message with new content.
1219-
* Also yields OpenResponsesFunctionCallOutput after tool execution completes.
1220-
* Returns ResponsesOutputMessage or OpenResponsesFunctionCallOutput compatible with OpenAI Responses API format.
1276+
* Also yields function_call items and OpenResponsesFunctionCallOutput after tool execution completes.
1277+
* Returns ResponsesOutputMessage, ResponsesOutputItemFunctionCall, or OpenResponsesFunctionCallOutput
1278+
* compatible with OpenAI Responses API format.
12211279
*/
12221280
getNewMessagesStream(): AsyncIterableIterator<
1223-
models.ResponsesOutputMessage | models.OpenResponsesFunctionCallOutput
1281+
models.ResponsesOutputMessage | models.OpenResponsesFunctionCallOutput | models.ResponsesOutputItemFunctionCall
12241282
> {
12251283
return async function* (this: ModelResult<TTools>) {
12261284
await this.initStream();
@@ -1234,8 +1292,15 @@ export class ModelResult<TTools extends readonly Tool[]> {
12341292
// Execute tools if needed
12351293
await this.executeToolsIfNeeded();
12361294

1237-
// Yield function call outputs for each executed tool
1295+
// Yield function calls and their outputs for each executed tool
12381296
for (const round of this.allToolExecutionRounds) {
1297+
// First yield the function_call items from the response that triggered tool execution
1298+
for (const item of round.response.output) {
1299+
if (isFunctionCallItem(item)) {
1300+
yield item;
1301+
}
1302+
}
1303+
// Then yield the function_call_output results
12391304
for (const toolResult of round.toolResults) {
12401305
yield toolResult;
12411306
}

0 commit comments

Comments
 (0)