@@ -212,6 +212,192 @@ var _ = Describe("Server", func() {
212212
213213 })
214214
215+ Context ("request ID headers" , func () {
216+ It ("Should include X-Request-Id in response when enabled" , func () {
217+ ctx := context .TODO ()
218+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho ,
219+ "--enable-request-id-headers" }
220+ client , err := startServerWithArgs (ctx , args )
221+ Expect (err ).NotTo (HaveOccurred ())
222+
223+ reqBody := `{
224+ "messages": [{"role": "user", "content": "Hello"}],
225+ "model": "` + testModel + `",
226+ "max_tokens": 5
227+ }`
228+
229+ req , err := http .NewRequest ("POST" , "http://localhost/v1/chat/completions" , strings .NewReader (reqBody ))
230+ Expect (err ).NotTo (HaveOccurred ())
231+ req .Header .Set ("Content-Type" , "application/json" )
232+ req .Header .Set ("X-Request-Id" , "test-request-id-123" )
233+
234+ resp , err := client .Do (req )
235+ Expect (err ).NotTo (HaveOccurred ())
236+ defer func () {
237+ err := resp .Body .Close ()
238+ Expect (err ).NotTo (HaveOccurred ())
239+ }()
240+
241+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
242+ Expect (resp .Header .Get ("X-Request-Id" )).To (Equal ("test-request-id-123" ))
243+ })
244+
245+ It ("Should not include X-Request-Id in response when disabled" , func () {
246+ ctx := context .TODO ()
247+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho }
248+ client , err := startServerWithArgs (ctx , args )
249+ Expect (err ).NotTo (HaveOccurred ())
250+
251+ reqBody := `{
252+ "messages": [{"role": "user", "content": "Hello"}],
253+ "model": "` + testModel + `",
254+ "max_tokens": 5
255+ }`
256+
257+ req , err := http .NewRequest ("POST" , "http://localhost/v1/chat/completions" , strings .NewReader (reqBody ))
258+ Expect (err ).NotTo (HaveOccurred ())
259+ req .Header .Set ("Content-Type" , "application/json" )
260+ req .Header .Set ("X-Request-Id" , "test-request-id-456" )
261+
262+ resp , err := client .Do (req )
263+ Expect (err ).NotTo (HaveOccurred ())
264+ defer func () {
265+ err := resp .Body .Close ()
266+ Expect (err ).NotTo (HaveOccurred ())
267+ }()
268+
269+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
270+ Expect (resp .Header .Get ("X-Request-Id" )).To (BeEmpty ())
271+ })
272+
273+ It ("Should include X-Request-Id in streaming response when enabled" , func () {
274+ ctx := context .TODO ()
275+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho ,
276+ "--enable-request-id-headers" }
277+ client , err := startServerWithArgs (ctx , args )
278+ Expect (err ).NotTo (HaveOccurred ())
279+
280+ reqBody := `{
281+ "messages": [{"role": "user", "content": "Hello"}],
282+ "model": "` + testModel + `",
283+ "max_tokens": 5,
284+ "stream": true
285+ }`
286+
287+ req , err := http .NewRequest ("POST" , "http://localhost/v1/chat/completions" , strings .NewReader (reqBody ))
288+ Expect (err ).NotTo (HaveOccurred ())
289+ req .Header .Set ("Content-Type" , "application/json" )
290+ req .Header .Set ("X-Request-Id" , "test-streaming-request-789" )
291+
292+ resp , err := client .Do (req )
293+ Expect (err ).NotTo (HaveOccurred ())
294+ defer func () {
295+ err := resp .Body .Close ()
296+ Expect (err ).NotTo (HaveOccurred ())
297+ }()
298+
299+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
300+ Expect (resp .Header .Get ("X-Request-Id" )).To (Equal ("test-streaming-request-789" ))
301+ })
302+
303+ It ("Should use request ID in response body ID field when enabled" , func () {
304+ ctx := context .TODO ()
305+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho ,
306+ "--enable-request-id-headers" }
307+ client , err := startServerWithArgs (ctx , args )
308+ Expect (err ).NotTo (HaveOccurred ())
309+
310+ reqBody := `{
311+ "messages": [{"role": "user", "content": "Hello"}],
312+ "model": "` + testModel + `",
313+ "max_tokens": 5
314+ }`
315+
316+ req , err := http .NewRequest ("POST" , "http://localhost/v1/chat/completions" , strings .NewReader (reqBody ))
317+ Expect (err ).NotTo (HaveOccurred ())
318+ req .Header .Set ("Content-Type" , "application/json" )
319+ req .Header .Set ("X-Request-Id" , "body-test-request-999" )
320+
321+ resp , err := client .Do (req )
322+ Expect (err ).NotTo (HaveOccurred ())
323+ defer func () {
324+ err := resp .Body .Close ()
325+ Expect (err ).NotTo (HaveOccurred ())
326+ }()
327+
328+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
329+
330+ body , err := io .ReadAll (resp .Body )
331+ Expect (err ).NotTo (HaveOccurred ())
332+
333+ var completionResp map [string ]interface {}
334+ err = json .Unmarshal (body , & completionResp )
335+ Expect (err ).NotTo (HaveOccurred ())
336+
337+ // The response ID should start with "chatcmpl-" followed by the request ID
338+ responseID , ok := completionResp ["id" ].(string )
339+ Expect (ok ).To (BeTrue ())
340+ Expect (responseID ).To (Equal ("chatcmpl-body-test-request-999" ))
341+ })
342+
343+ It ("Should work with text completions endpoint" , func () {
344+ ctx := context .TODO ()
345+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho ,
346+ "--enable-request-id-headers" }
347+ client , err := startServerWithArgs (ctx , args )
348+ Expect (err ).NotTo (HaveOccurred ())
349+
350+ reqBody := `{
351+ "prompt": "Hello world",
352+ "model": "` + testModel + `",
353+ "max_tokens": 5
354+ }`
355+
356+ req , err := http .NewRequest ("POST" , "http://localhost/v1/completions" , strings .NewReader (reqBody ))
357+ Expect (err ).NotTo (HaveOccurred ())
358+ req .Header .Set ("Content-Type" , "application/json" )
359+ req .Header .Set ("X-Request-Id" , "text-completion-request-111" )
360+
361+ resp , err := client .Do (req )
362+ Expect (err ).NotTo (HaveOccurred ())
363+ defer func () {
364+ err := resp .Body .Close ()
365+ Expect (err ).NotTo (HaveOccurred ())
366+ }()
367+
368+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
369+ Expect (resp .Header .Get ("X-Request-Id" )).To (Equal ("text-completion-request-111" ))
370+ })
371+
372+ It ("Should generate UUID when no X-Request-Id header provided and feature enabled" , func () {
373+ ctx := context .TODO ()
374+ args := []string {"cmd" , "--model" , testModel , "--mode" , common .ModeEcho ,
375+ "--enable-request-id-headers" }
376+ client , err := startServerWithArgs (ctx , args )
377+ Expect (err ).NotTo (HaveOccurred ())
378+
379+ reqBody := `{
380+ "messages": [{"role": "user", "content": "Hello"}],
381+ "model": "` + testModel + `",
382+ "max_tokens": 5
383+ }`
384+
385+ resp , err := client .Post ("http://localhost/v1/chat/completions" , "application/json" , strings .NewReader (reqBody ))
386+ Expect (err ).NotTo (HaveOccurred ())
387+ defer func () {
388+ err := resp .Body .Close ()
389+ Expect (err ).NotTo (HaveOccurred ())
390+ }()
391+
392+ Expect (resp .StatusCode ).To (Equal (http .StatusOK ))
393+ // Should have a generated UUID in the response header
394+ requestID := resp .Header .Get ("X-Request-Id" )
395+ Expect (requestID ).NotTo (BeEmpty ())
396+ // UUID format check (basic validation)
397+ Expect (len (requestID )).To (BeNumerically (">" , 30 ))
398+ })
399+ })
400+
215401 Context ("sleep mode" , Ordered , func () {
216402 AfterAll (func () {
217403 err := os .RemoveAll (tmpDir )
0 commit comments