@@ -29,8 +29,45 @@ function requireAuth(): string {
2929 return creds . apiKey ;
3030}
3131
32- async function readSseText ( res : Response ) : Promise < string > {
33- return res . text ( ) ;
32+
33+ async function assertOk ( res : Response , label : string ) : Promise < string > {
34+ const text = await res . text ( ) ;
35+ if ( res . status !== 200 ) {
36+ throw new Error ( `${ label } : expected 200, got ${ res . status } \n${ text . slice ( 0 , 2000 ) } ` ) ;
37+ }
38+ return text ;
39+ }
40+
41+ /** Concatenate streamed text/reasoning deltas from an OpenAI SSE body. */
42+ function sseAssistantText ( sse : string ) : string {
43+ let out = "" ;
44+ for ( const line of sse . split ( "\n" ) ) {
45+ if ( ! line . startsWith ( "data: " ) ) continue ;
46+ const raw = line . slice ( 6 ) . trim ( ) ;
47+ if ( ! raw || raw === "[DONE]" ) continue ;
48+ try {
49+ const chunk = JSON . parse ( raw ) as {
50+ choices ?: Array < {
51+ delta ?: { content ?: string ; reasoning_content ?: string } ;
52+ message ?: { content ?: string ; reasoning_content ?: string } ;
53+ } > ;
54+ } ;
55+ const choice = chunk . choices ?. [ 0 ] ;
56+ const delta = choice ?. delta ;
57+ const message = choice ?. message ;
58+ if ( typeof delta ?. content === "string" ) out += delta . content ;
59+ if ( typeof delta ?. reasoning_content === "string" ) {
60+ out += delta . reasoning_content ;
61+ }
62+ if ( typeof message ?. content === "string" ) out += message . content ;
63+ if ( typeof message ?. reasoning_content === "string" ) {
64+ out += message . reasoning_content ;
65+ }
66+ } catch {
67+ // ignore non-JSON keepalives
68+ }
69+ }
70+ return out ;
3471}
3572
3673async function main ( ) {
@@ -63,9 +100,9 @@ async function main() {
63100 ] ,
64101 } ) ,
65102 } ) ;
66- assert . equal ( res . status , 200 , await res . text ( ) ) ;
67- const text = await readSseText ( res ) ;
68- assert . ok ( / L a g u n a l i v e o k / i. test ( text ) , text . slice ( 0 , 2000 ) ) ;
103+ const text = await assertOk ( res , "plain" ) ;
104+ const assistant = sseAssistantText ( text ) ;
105+ assert . ok ( / L a g u n a l i v e o k / i. test ( assistant ) , assistant || text . slice ( 0 , 2000 ) ) ;
69106 assert . ok ( text . includes ( "usage" ) , "expected usage in stream" ) ;
70107 console . log ( "✓ live plain completion" ) ;
71108 }
@@ -108,8 +145,8 @@ async function main() {
108145 ] ,
109146 } ) ,
110147 } ) ;
111- assert . equal ( res . status , 200 , await res . text ( ) ) ;
112- const json = ( await res . json ( ) ) as {
148+ const raw = await assertOk ( res , "attachments" ) ;
149+ const json = JSON . parse ( raw ) as {
113150 choices : Array < { message : { content : string } } > ;
114151 usage ?: { prompt_tokens : number } ;
115152 } ;
@@ -159,8 +196,7 @@ async function main() {
159196 tools,
160197 } ) ,
161198 } ) ;
162- assert . equal ( res1 . status , 200 , await res1 . text ( ) ) ;
163- const turn1 = await readSseText ( res1 ) ;
199+ const turn1 = await assertOk ( res1 , "tools-turn1" ) ;
164200 assert . ok (
165201 turn1 . includes ( "add_numbers" ) || turn1 . includes ( "tool_calls" ) ,
166202 turn1 . slice ( 0 , 2500 ) ,
@@ -202,7 +238,6 @@ async function main() {
202238 } catch {
203239 parsed = { } ;
204240 }
205- // args may have been streamed in pieces — try to find numbers in the SSE
206241 if ( typeof parsed . a !== "number" ) {
207242 const m = turn1 . match ( / " a " \s * : \s * ( \d + ) / ) ;
208243 const n = turn1 . match ( / " b " \s * : \s * ( \d + ) / ) ;
@@ -254,18 +289,18 @@ async function main() {
254289 tools,
255290 } ) ,
256291 } ) ;
257- assert . equal ( res2 . status , 200 , await res2 . text ( ) ) ;
258- const turn2 = await readSseText ( res2 ) ;
259- assert . ok ( / 4 2 / . test ( turn2 ) , turn2 . slice ( 0 , 2000 ) ) ;
292+ const turn2 = await assertOk ( res2 , "tools-turn2" ) ;
293+ const assistant2 = sseAssistantText ( turn2 ) ;
294+ assert . ok ( / 4 2 / . test ( assistant2 ) || / 4 2 / . test ( turn2 ) , assistant2 || turn2 . slice ( 0 , 2000 ) ) ;
260295 console . log ( "✓ live tools park/resume" ) ;
261296 }
262297 }
263298
264299 // 4) Usage totals
265300 {
266301 const res = await fetch ( `${ base } /v1/usage` ) ;
267- assert . equal ( res . status , 200 ) ;
268- const json = ( await res . json ( ) ) as {
302+ const raw = await assertOk ( res , "usage" ) ;
303+ const json = JSON . parse ( raw ) as {
269304 total : { prompt_tokens : number ; completion_tokens : number } ;
270305 sessions : Array < { tools : unknown [ ] ; contextWindow : number } > ;
271306 } ;
@@ -295,8 +330,8 @@ async function main() {
295330 ] ,
296331 } ) ,
297332 } ) ;
298- assert . equal ( res . status , 200 , await res . text ( ) ) ;
299- const json = ( await res . json ( ) ) as {
333+ const raw = await assertOk ( res , "compact" ) ;
334+ const json = JSON . parse ( raw ) as {
300335 choices : Array < { message : { content ?: string ; reasoning_content ?: string } } > ;
301336 } ;
302337 const content =
0 commit comments