@@ -217,7 +217,7 @@ test("WebSearch matches rate limit errors case-sensitively", async () => {
217217 assert . deepEqual ( rateLimitedTools , [ ] ) ;
218218} ) ;
219219
220- test ( "WebSearch uses DeepSeek Responses API with the required model " , async ( ) => {
220+ test ( "WebSearch accepts a completed DeepSeek response with partial web search failures " , async ( ) => {
221221 const workspace = createTempWorkspace ( ) ;
222222 const starts : Array < { id : string | number ; command : string } > = [ ] ;
223223 const exits : Array < string | number > = [ ] ;
@@ -252,7 +252,10 @@ test("WebSearch uses DeepSeek Responses API with the required model", async () =
252252 responseRequests . push ( request ) ;
253253 return {
254254 status : "completed" ,
255- output : [ { type : "web_search_call" , status : "completed" } ] ,
255+ output : [
256+ { type : "web_search_call" , status : "completed" } ,
257+ { type : "web_search_call" , status : "failed" } ,
258+ ] ,
256259 output_text : "Node.js 24 is the latest release." ,
257260 } ;
258261 } ,
@@ -288,13 +291,55 @@ test("WebSearch uses DeepSeek Responses API with the required model", async () =
288291 assert . deepEqual ( exits , [ starts [ 0 ] . id ] ) ;
289292} ) ;
290293
291- test ( "WebSearch rejects invalid DeepSeek web search responses" , async ( ) => {
294+ test ( "WebSearch treats an incomplete empty DeepSeek response as a successful empty result" , async ( ) => {
295+ const workspace = createTempWorkspace ( ) ;
296+ const fakeClient = {
297+ chat : {
298+ completions : {
299+ create : async ( ) => ( {
300+ choices : [
301+ {
302+ message : {
303+ content : '{"dominant_language":"en","reason":"English sources are more useful."}' ,
304+ } ,
305+ } ,
306+ ] ,
307+ } ) ,
308+ } ,
309+ } ,
310+ responses : {
311+ create : async ( ) => ( {
312+ status : "incomplete" ,
313+ output : [ ] ,
314+ output_text : " " ,
315+ } ) ,
316+ } ,
317+ } as unknown as OpenAI ;
318+
319+ const result = await handleWebSearchTool (
320+ { query : "latest node release" } ,
321+ createContext ( workspace , {
322+ client : fakeClient ,
323+ baseURL : "https://api.deepseek.com" ,
324+ } )
325+ ) ;
326+
327+ assert . equal ( result . ok , true ) ;
328+ assert . equal ( result . output , "No web search results were returned." ) ;
329+ } ) ;
330+
331+ test ( "WebSearch rejects DeepSeek request and provider failures" , async ( ) => {
292332 const responseCases = [
293333 {
294334 response : null ,
295335 requestError : new Error ( "network unavailable" ) ,
296336 error : "WebSearch default mode failed: network unavailable" ,
297337 } ,
338+ {
339+ response : null ,
340+ requestError : new Error ( "429 rate limit exceeded" ) ,
341+ error : "WebSearch default mode failed: 429 rate limit exceeded" ,
342+ } ,
298343 {
299344 response : {
300345 status : "failed" ,
@@ -303,30 +348,6 @@ test("WebSearch rejects invalid DeepSeek web search responses", async () => {
303348 } ,
304349 error : "WebSearch default mode failed: DeepSeek Responses API returned status failed." ,
305350 } ,
306- {
307- response : {
308- status : "completed" ,
309- output : [ ] ,
310- output_text : "An answer without a search call." ,
311- } ,
312- error : "WebSearch default mode failed: DeepSeek Responses API did not perform a web search." ,
313- } ,
314- {
315- response : {
316- status : "completed" ,
317- output : [ { type : "web_search_call" , status : "failed" } ] ,
318- output_text : "An answer from an incomplete search." ,
319- } ,
320- error : "WebSearch default mode failed: DeepSeek Responses API returned an incomplete web search call." ,
321- } ,
322- {
323- response : {
324- status : "completed" ,
325- output : [ { type : "web_search_call" , status : "completed" } ] ,
326- output_text : " " ,
327- } ,
328- error : "WebSearch default mode failed: The DeepSeek web search response was empty." ,
329- } ,
330351 ] ;
331352
332353 for ( const responseCase of responseCases ) {
0 commit comments