@@ -7,87 +7,120 @@ import dotenv from "dotenv";
77dotenv . config ( ) ;
88
99/**
10- * Example usage of the @openrouter/sdk SDK for chat completions
10+ * Example demonstrating multi-turn chat conversations with reasoning models.
11+ *
12+ * This example shows how to build a conversation over 3 turns,
13+ * carrying the message history forward with each request.
1114 *
1215 * To run this example from the examples directory with Bun:
13- * bun run chatCompletions .example.ts
16+ * bun run chat-reasoning .example.ts
1417 */
1518
19+ import type { Message } from "../src/models/index.js" ;
1620import { OpenRouter } from "../src/index.js" ;
1721
1822if ( ! process . env [ "OPENROUTER_API_KEY" ] ) {
1923 throw new Error ( "Missing OPENROUTER_API_KEY environment variable" ) ;
2024}
25+
2126const openRouter = new OpenRouter ( {
2227 apiKey : process . env [ "OPENROUTER_API_KEY" ] ?? "" ,
23- debugLogger : console ,
2428} ) ;
2529
26- async function nonStreamingExample ( ) {
27- const result = await openRouter . chat . send ( {
28- model : "qwen/qwen3-max" ,
29- messages : [
30- {
31- role : "user" ,
32- content : "Tell me a short joke about programming" ,
33- } ,
34- ] ,
30+ async function multiTurnConversation ( ) {
31+ const model = "google/gemini-3-pro-preview" ;
32+
33+ // Initialize message history with the first user message
34+ const messages : Message [ ] = [
35+ {
36+ role : "user" ,
37+ content : "What are the three most important principles of good software architecture?" ,
38+ } ,
39+ ] ;
40+
41+ console . log ( "=== Turn 1 ===" ) ;
42+ console . log ( "User:" , messages [ 0 ] . content ) ;
43+ console . log ( ) ;
44+
45+ // First turn
46+ const result1 = await openRouter . chat . send ( {
47+ model,
48+ messages,
3549 stream : false ,
3650 } ) ;
3751
38- if ( "choices" in result ) {
39- console . log ( result . choices [ 0 ] . message . content ) ;
52+ if ( ! ( "choices" in result1 ) ) {
53+ throw new Error ( "Unexpected response format" ) ;
4054 }
41- }
4255
43- async function streamingExample ( ) {
44- const result = await openRouter . chat . send ( {
45- model : "qwen/qwen3-max" ,
46- messages : [
47- {
48- role : "user" ,
49- content : "Write a haiku about TypeScript" ,
50- } ,
51- ] ,
52- stream : true ,
53- streamOptions : {
54- includeUsage : true ,
55- } ,
56+ const assistant1 = result1 . choices [ 0 ] . message ;
57+ console . log ( "Assistant:" , assistant1 . content ) ;
58+ console . log ( ) ;
59+
60+ // Add assistant response and next user message to history
61+ messages . push ( assistant1 ) ;
62+ messages . push ( {
63+ role : "user" ,
64+ content : "Can you elaborate on the second principle? Give me a concrete example." ,
65+ } ) ;
66+
67+ console . log ( "=== Turn 2 ===" ) ;
68+ console . log ( "User:" , messages [ messages . length - 1 ] . content ) ;
69+ console . log ( ) ;
70+
71+ // Second turn
72+ const result2 = await openRouter . chat . send ( {
73+ model,
74+ messages,
75+ stream : false ,
5676 } ) ;
5777
58- if ( result && typeof result === "object" && Symbol . asyncIterator in result ) {
59- const stream = result ;
60- let _fullContent = "" ;
61-
62- for await ( const chunk of stream ) {
63- if ( chunk . choices [ 0 ] . delta ?. reasoning_details ) {
64- console . log (
65- `REASONING_DETAILS:` ,
66- chunk . choices [ 0 ] . delta . reasoning_details
67- ) ;
68- } else if ( chunk . choices [ 0 ] . delta ?. content ) {
69- console . log ( `CONTENT: ${ chunk . choices [ 0 ] . delta . content } ` ) ;
70- }
71-
72- if ( chunk . choices ?. [ 0 ] ?. delta ?. content ) {
73- const content = chunk . choices [ 0 ] . delta . content ;
74- process . stdout . write ( content ) ;
75- _fullContent += content ;
76- }
77-
78- if ( chunk . usage ) {
79- console . log ( chunk . usage ) ;
80- }
81- }
78+ if ( ! ( "choices" in result2 ) ) {
79+ throw new Error ( "Unexpected response format" ) ;
8280 }
81+
82+ const assistant2 = result2 . choices [ 0 ] . message ;
83+ console . log ( "Assistant:" , assistant2 . content ) ;
84+ console . log ( ) ;
85+
86+ // Add assistant response and next user message to history
87+ messages . push ( assistant2 ) ;
88+ messages . push ( {
89+ role : "user" ,
90+ content : "How would you apply this in a TypeScript project specifically?" ,
91+ } ) ;
92+
93+ console . log ( "=== Turn 3 ===" ) ;
94+ console . log ( "User:" , messages [ messages . length - 1 ] . content ) ;
95+ console . log ( ) ;
96+
97+ // Third turn
98+ const result3 = await openRouter . chat . send ( {
99+ model,
100+ messages,
101+ stream : false ,
102+ } ) ;
103+
104+ if ( ! ( "choices" in result3 ) ) {
105+ throw new Error ( "Unexpected response format" ) ;
106+ }
107+
108+ const assistant3 = result3 . choices [ 0 ] . message ;
109+ console . log ( "Assistant:" , assistant3 . content ) ;
110+ console . log ( ) ;
111+
112+ // Final message history
113+ messages . push ( assistant3 ) ;
114+
115+ console . log ( "=== Conversation Complete ===" ) ;
116+ console . log ( `Total messages in history: ${ messages . length } ` ) ;
83117}
84118
85119async function main ( ) {
86120 try {
87- await nonStreamingExample ( ) ;
88- await streamingExample ( ) ;
89- } catch ( _error ) {
90- console . error ( _error ) ;
121+ await multiTurnConversation ( ) ;
122+ } catch ( error ) {
123+ console . error ( "Error:" , error ) ;
91124 }
92125}
93126
0 commit comments