Skip to content

Commit c58edfe

Browse files
committed
refactor: Convert response API from hanging promises to getter methods
Convert all getter properties that return promises/iterators into explicit methods with get*() naming for better API clarity and consistency. Changes: - response.text → response.getText() - response.message → response.getMessage() - response.textStream → response.getTextStream() - response.newMessagesStream → response.getNewMessagesStream() - response.fullResponsesStream → response.getFullResponsesStream() - response.reasoningStream → response.getReasoningStream() - response.toolStream → response.getToolStream() - response.fullChatStream → response.getFullChatStream() Updated all test files, examples, and JSDoc documentation to reflect the new API. All 20 e2e tests pass successfully.
1 parent b46cc86 commit c58edfe

File tree

4 files changed

+56
-56
lines changed

4 files changed

+56
-56
lines changed

src/funcs/getResponse.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import * as models from "../models/index.js";
1010
* Creates a response using the OpenResponses API in streaming mode and returns
1111
* a wrapper that allows consuming the response in multiple ways:
1212
*
13-
* - `await response.message` - Get the completed message
14-
* - `await response.text` - Get just the text content
15-
* - `for await (const delta of response.textStream)` - Stream text deltas
16-
* - `for await (const delta of response.reasoningStream)` - Stream reasoning deltas
17-
* - `for await (const delta of response.toolStream)` - Stream tool call argument deltas
18-
* - `for await (const msg of response.newMessagesStream)` - Stream incremental message updates
19-
* - `for await (const event of response.fullResponsesStream)` - Stream all response events
20-
* - `for await (const chunk of response.fullChatStream)` - Stream in chat-compatible format
13+
* - `await response.getMessage()` - Get the completed message
14+
* - `await response.getText()` - Get just the text content
15+
* - `for await (const delta of response.getTextStream())` - Stream text deltas
16+
* - `for await (const delta of response.getReasoningStream())` - Stream reasoning deltas
17+
* - `for await (const delta of response.getToolStream())` - Stream tool call argument deltas
18+
* - `for await (const msg of response.getNewMessagesStream())` - Stream incremental message updates
19+
* - `for await (const event of response.getFullResponsesStream())` - Stream all response events
20+
* - `for await (const chunk of response.getFullChatStream())` - Stream in chat-compatible format
2121
*
2222
* All consumption patterns can be used concurrently on the same response.
2323
*
@@ -28,15 +28,15 @@ import * as models from "../models/index.js";
2828
* model: "anthropic/claude-3-opus",
2929
* input: [{ role: "user", content: "Hello!" }]
3030
* });
31-
* const text = await response.text;
31+
* const text = await response.getText();
3232
* console.log(text);
3333
*
3434
* // Streaming text
3535
* const response = openrouter.beta.responses.get({
3636
* model: "anthropic/claude-3-opus",
3737
* input: [{ role: "user", content: "Hello!" }]
3838
* });
39-
* for await (const delta of response.textStream) {
39+
* for await (const delta of response.getTextStream()) {
4040
* process.stdout.write(delta);
4141
* }
4242
*
@@ -45,7 +45,7 @@ import * as models from "../models/index.js";
4545
* model: "anthropic/claude-3-opus",
4646
* input: [{ role: "user", content: "Hello!" }]
4747
* });
48-
* const message = await response.message;
48+
* const message = await response.getMessage();
4949
* console.log(message.content);
5050
* ```
5151
*/

src/lib/response-wrapper.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ export interface GetResponseOptions {
2424
* A wrapper around a streaming response that provides multiple consumption patterns.
2525
*
2626
* Allows consuming the response in multiple ways:
27-
* - `await response.message` - Get the completed message
28-
* - `await response.text` - Get just the text
29-
* - `for await (const delta of response.textStream)` - Stream text deltas
30-
* - `for await (const msg of response.messageStream)` - Stream incremental message updates
31-
* - `for await (const event of response.fullResponsesStream)` - Stream all response events
27+
* - `await response.getMessage()` - Get the completed message
28+
* - `await response.getText()` - Get just the text
29+
* - `for await (const delta of response.getTextStream())` - Stream text deltas
30+
* - `for await (const msg of response.getNewMessagesStream())` - Stream incremental message updates
31+
* - `for await (const event of response.getFullResponsesStream())` - Stream all response events
3232
*
3333
* All consumption patterns can be used concurrently thanks to the underlying
3434
* ReusableReadableStream implementation.
@@ -83,7 +83,7 @@ export class ResponseWrapper {
8383
* This will consume the stream until completion and extract the first message.
8484
* Returns an AssistantMessage in chat format.
8585
*/
86-
get message(): Promise<models.AssistantMessage> {
86+
getMessage(): Promise<models.AssistantMessage> {
8787
if (this.messagePromise) {
8888
return this.messagePromise;
8989
}
@@ -105,7 +105,7 @@ export class ResponseWrapper {
105105
* Get just the text content from the response.
106106
* This will consume the stream until completion and extract the text.
107107
*/
108-
get text(): Promise<string> {
108+
getText(): Promise<string> {
109109
if (this.textPromise) {
110110
return this.textPromise;
111111
}
@@ -127,7 +127,7 @@ export class ResponseWrapper {
127127
* Stream all response events as they arrive.
128128
* Multiple consumers can iterate over this stream concurrently.
129129
*/
130-
get fullResponsesStream(): AsyncIterableIterator<models.OpenResponsesStreamEvent> {
130+
getFullResponsesStream(): AsyncIterableIterator<models.OpenResponsesStreamEvent> {
131131
return (async function* (this: ResponseWrapper) {
132132
await this.initStream();
133133
if (!this.reusableStream) {
@@ -143,7 +143,7 @@ export class ResponseWrapper {
143143
* Stream only text deltas as they arrive.
144144
* This filters the full event stream to only yield text content.
145145
*/
146-
get textStream(): AsyncIterableIterator<string> {
146+
getTextStream(): AsyncIterableIterator<string> {
147147
return (async function* (this: ResponseWrapper) {
148148
await this.initStream();
149149
if (!this.reusableStream) {
@@ -159,7 +159,7 @@ export class ResponseWrapper {
159159
* Each iteration yields an updated version of the message with new content.
160160
* Returns AssistantMessage in chat format.
161161
*/
162-
get newMessagesStream(): AsyncIterableIterator<models.AssistantMessage> {
162+
getNewMessagesStream(): AsyncIterableIterator<models.AssistantMessage> {
163163
return (async function* (this: ResponseWrapper) {
164164
await this.initStream();
165165
if (!this.reusableStream) {
@@ -174,7 +174,7 @@ export class ResponseWrapper {
174174
* Stream only reasoning deltas as they arrive.
175175
* This filters the full event stream to only yield reasoning content.
176176
*/
177-
get reasoningStream(): AsyncIterableIterator<string> {
177+
getReasoningStream(): AsyncIterableIterator<string> {
178178
return (async function* (this: ResponseWrapper) {
179179
await this.initStream();
180180
if (!this.reusableStream) {
@@ -189,7 +189,7 @@ export class ResponseWrapper {
189189
* Stream only tool call argument deltas as they arrive.
190190
* This filters the full event stream to only yield function call arguments.
191191
*/
192-
get toolStream(): AsyncIterableIterator<string> {
192+
getToolStream(): AsyncIterableIterator<string> {
193193
return (async function* (this: ResponseWrapper) {
194194
await this.initStream();
195195
if (!this.reusableStream) {
@@ -209,7 +209,7 @@ export class ResponseWrapper {
209209
* stream into a format similar to the chat API. Due to differences in the APIs,
210210
* this may not be a perfect mapping.
211211
*/
212-
get fullChatStream(): AsyncIterableIterator<any> {
212+
getFullChatStream(): AsyncIterableIterator<any> {
213213
return (async function* (this: ResponseWrapper) {
214214
await this.initStream();
215215
if (!this.reusableStream) {

src/sdk/sdk.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ export class OpenRouter extends ClientSDK {
8888
*
8989
* @remarks
9090
* Returns a wrapper that allows consuming the response in multiple ways:
91-
* - `await response.message` - Get the completed message
92-
* - `await response.text` - Get just the text content
93-
* - `for await (const delta of response.textStream)` - Stream text deltas
94-
* - `for await (const msg of response.messageStream)` - Stream incremental message updates
95-
* - `for await (const event of response.fullResponsesStream)` - Stream all response events
96-
* - `for await (const chunk of response.fullChatStream)` - Stream in chat-compatible format
91+
* - `await response.getMessage()` - Get the completed message
92+
* - `await response.getText()` - Get just the text content
93+
* - `for await (const delta of response.getTextStream())` - Stream text deltas
94+
* - `for await (const msg of response.getNewMessagesStream())` - Stream incremental message updates
95+
* - `for await (const event of response.getFullResponsesStream())` - Stream all response events
96+
* - `for await (const chunk of response.getFullChatStream())` - Stream in chat-compatible format
9797
*
9898
* All consumption patterns can be used concurrently on the same response.
9999
*
@@ -104,15 +104,15 @@ export class OpenRouter extends ClientSDK {
104104
* model: "anthropic/claude-3-opus",
105105
* input: [{ role: "user", content: "Hello!" }]
106106
* });
107-
* const text = await response.text;
107+
* const text = await response.getText();
108108
* console.log(text);
109109
*
110110
* // Streaming text
111111
* const response = openRouter.getResponse({
112112
* model: "anthropic/claude-3-opus",
113113
* input: [{ role: "user", content: "Hello!" }]
114114
* });
115-
* for await (const delta of response.textStream) {
115+
* for await (const delta of response.getTextStream()) {
116116
* process.stdout.write(delta);
117117
* }
118118
* ```

tests/e2e/getResponse.test.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe("getResponse E2E Tests", () => {
3030
],
3131
});
3232

33-
const text = await response.text;
33+
const text = await response.getText();
3434

3535
expect(text).toBeDefined();
3636
expect(typeof text).toBe("string");
@@ -57,7 +57,7 @@ describe("getResponse E2E Tests", () => {
5757
],
5858
});
5959

60-
const text = await response.text;
60+
const text = await response.getText();
6161

6262
expect(text).toBeDefined();
6363
expect(text.toLowerCase()).toContain("bob");
@@ -76,7 +76,7 @@ describe("getResponse E2E Tests", () => {
7676
],
7777
});
7878

79-
const message = await response.message;
79+
const message = await response.getMessage();
8080

8181
expect(message).toBeDefined();
8282
expect(message.role).toBe("assistant");
@@ -105,7 +105,7 @@ describe("getResponse E2E Tests", () => {
105105
],
106106
});
107107

108-
const message = await response.message;
108+
const message = await response.getMessage();
109109

110110
expect(message).toBeDefined();
111111
expect(message.role).toBe("assistant");
@@ -127,7 +127,7 @@ describe("getResponse E2E Tests", () => {
127127

128128
const deltas: string[] = [];
129129

130-
for await (const delta of response.textStream) {
130+
for await (const delta of response.getTextStream()) {
131131
expect(typeof delta).toBe("string");
132132
deltas.push(delta);
133133
}
@@ -154,7 +154,7 @@ describe("getResponse E2E Tests", () => {
154154
let lastDeltaTime: number | null = null;
155155
let deltaCount = 0;
156156

157-
for await (const delta of response.textStream) {
157+
for await (const delta of response.getTextStream()) {
158158
if (!firstDeltaTime) {
159159
firstDeltaTime = Date.now();
160160
}
@@ -187,7 +187,7 @@ describe("getResponse E2E Tests", () => {
187187

188188
const messages: Message[] = [];
189189

190-
for await (const message of response.newMessagesStream) {
190+
for await (const message of response.getNewMessagesStream()) {
191191
expect(message).toBeDefined();
192192
expect(message.role).toBe("assistant");
193193
expect(typeof message.content).toBe("string");
@@ -227,7 +227,7 @@ describe("getResponse E2E Tests", () => {
227227

228228
const reasoningDeltas: string[] = [];
229229

230-
for await (const delta of response.reasoningStream) {
230+
for await (const delta of response.getReasoningStream()) {
231231
expect(typeof delta).toBe("string");
232232
reasoningDeltas.push(delta);
233233
}
@@ -270,7 +270,7 @@ describe("getResponse E2E Tests", () => {
270270

271271
const toolDeltas: string[] = [];
272272

273-
for await (const delta of response.toolStream) {
273+
for await (const delta of response.getToolStream()) {
274274
expect(typeof delta).toBe("string");
275275
toolDeltas.push(delta);
276276
}
@@ -300,7 +300,7 @@ describe("getResponse E2E Tests", () => {
300300

301301
const events: any[] = [];
302302

303-
for await (const event of response.fullResponsesStream) {
303+
for await (const event of response.getFullResponsesStream()) {
304304
expect(event).toBeDefined();
305305
expect("type" in event).toBe(true);
306306
events.push(event);
@@ -332,7 +332,7 @@ describe("getResponse E2E Tests", () => {
332332

333333
const textDeltaEvents: any[] = [];
334334

335-
for await (const event of response.fullResponsesStream) {
335+
for await (const event of response.getFullResponsesStream()) {
336336
if ("type" in event && event.type === "response.output_text.delta") {
337337
textDeltaEvents.push(event);
338338
}
@@ -361,7 +361,7 @@ describe("getResponse E2E Tests", () => {
361361

362362
const chunks: any[] = [];
363363

364-
for await (const chunk of response.fullChatStream) {
364+
for await (const chunk of response.getFullChatStream()) {
365365
expect(chunk).toBeDefined();
366366
expect(chunk.type).toBeDefined();
367367
chunks.push(chunk);
@@ -388,10 +388,10 @@ describe("getResponse E2E Tests", () => {
388388
});
389389

390390
// Get full text and stream concurrently
391-
const textPromise = response.text;
391+
const textPromise = response.getText();
392392
const streamPromise = (async () => {
393393
const deltas: string[] = [];
394-
for await (const delta of response.textStream) {
394+
for await (const delta of response.getTextStream()) {
395395
deltas.push(delta);
396396
}
397397
return deltas;
@@ -422,15 +422,15 @@ describe("getResponse E2E Tests", () => {
422422
// Start two concurrent stream consumers
423423
const textStreamPromise = (async () => {
424424
const deltas: string[] = [];
425-
for await (const delta of response.textStream) {
425+
for await (const delta of response.getTextStream()) {
426426
deltas.push(delta);
427427
}
428428
return deltas;
429429
})();
430430

431431
const newMessagesStreamPromise = (async () => {
432432
const messages: any[] = [];
433-
for await (const message of response.newMessagesStream) {
433+
for await (const message of response.getNewMessagesStream()) {
434434
messages.push(message);
435435
}
436436
return messages;
@@ -464,13 +464,13 @@ describe("getResponse E2E Tests", () => {
464464
});
465465

466466
// First, get the full text
467-
const text = await response.text;
467+
const text = await response.getText();
468468
expect(text).toBeDefined();
469469
expect(text.length).toBeGreaterThan(0);
470470

471471
// Then, try to stream (should get same data from buffer)
472472
const deltas: string[] = [];
473-
for await (const delta of response.textStream) {
473+
for await (const delta of response.getTextStream()) {
474474
expect(typeof delta).toBe("string");
475475
deltas.push(delta);
476476
}
@@ -495,14 +495,14 @@ describe("getResponse E2E Tests", () => {
495495

496496
// First, collect deltas from stream
497497
const deltas: string[] = [];
498-
for await (const delta of response.textStream) {
498+
for await (const delta of response.getTextStream()) {
499499
expect(typeof delta).toBe("string");
500500
deltas.push(delta);
501501
}
502502
expect(deltas.length).toBeGreaterThan(0);
503503

504504
// Then, get the full text (should work even after stream consumed)
505-
const text = await response.text;
505+
const text = await response.getText();
506506
expect(text).toBeDefined();
507507
expect(text.length).toBeGreaterThan(0);
508508

@@ -524,7 +524,7 @@ describe("getResponse E2E Tests", () => {
524524
],
525525
});
526526

527-
await expect(response.text).rejects.toThrow();
527+
await expect(response.getText()).rejects.toThrow();
528528
});
529529

530530
it("should handle empty input", async () => {
@@ -535,7 +535,7 @@ describe("getResponse E2E Tests", () => {
535535

536536
// This might fail or return empty - both are acceptable
537537
try {
538-
const text = await response.text;
538+
const text = await response.getText();
539539
expect(text).toBeDefined();
540540
} catch (error) {
541541
expect(error).toBeDefined();
@@ -556,7 +556,7 @@ describe("getResponse E2E Tests", () => {
556556
maxOutputTokens: 10,
557557
});
558558

559-
const text = await response.text;
559+
const text = await response.getText();
560560

561561
expect(text).toBeDefined();
562562
// Text should be relatively short due to token limit
@@ -575,7 +575,7 @@ describe("getResponse E2E Tests", () => {
575575
instructions: "You are a helpful assistant. Keep responses concise.",
576576
});
577577

578-
const text = await response.text;
578+
const text = await response.getText();
579579

580580
expect(text).toBeDefined();
581581
expect(typeof text).toBe("string");

0 commit comments

Comments
 (0)