| package openai |
|
|
| import ( |
| "context" |
| "encoding/json" |
| "errors" |
| "net/http" |
| "net/http/httptest" |
| "strings" |
| "testing" |
|
|
| "github.com/go-chi/chi/v5" |
|
|
| "ds2api/internal/auth" |
| dsclient "ds2api/internal/deepseek/client" |
| "ds2api/internal/promptcompat" |
| "ds2api/internal/util" |
| ) |
|
|
| func historySplitTestMessages() []any { |
| toolCalls := []any{ |
| map[string]any{ |
| "name": "search", |
| "arguments": map[string]any{"query": "docs"}, |
| }, |
| } |
| return []any{ |
| map[string]any{"role": "system", "content": "system instructions"}, |
| map[string]any{"role": "user", "content": "first user turn"}, |
| map[string]any{ |
| "role": "assistant", |
| "content": "", |
| "reasoning_content": "hidden reasoning", |
| "tool_calls": toolCalls, |
| }, |
| map[string]any{ |
| "role": "tool", |
| "name": "search", |
| "tool_call_id": "call-1", |
| "content": "tool result", |
| }, |
| map[string]any{"role": "user", "content": "latest user turn"}, |
| } |
| } |
|
|
| type streamStatusManagedAuthStub struct{} |
|
|
| func (streamStatusManagedAuthStub) Determine(_ *http.Request) (*auth.RequestAuth, error) { |
| return &auth.RequestAuth{ |
| UseConfigToken: true, |
| DeepSeekToken: "managed-token", |
| CallerID: "caller:test", |
| AccountID: "acct:test", |
| TriedAccounts: map[string]bool{}, |
| }, nil |
| } |
|
|
| func (streamStatusManagedAuthStub) DetermineCaller(_ *http.Request) (*auth.RequestAuth, error) { |
| return (&streamStatusManagedAuthStub{}).Determine(nil) |
| } |
|
|
| func (streamStatusManagedAuthStub) Release(_ *auth.RequestAuth) {} |
|
|
| func TestBuildOpenAICurrentInputContextTranscriptUsesNumberedHistorySections(t *testing.T) { |
| transcript := buildOpenAICurrentInputContextTranscript(historySplitTestMessages()) |
|
|
| if strings.Contains(transcript, "[file content end]") || strings.Contains(transcript, "[file content begin]") || strings.Contains(transcript, "[file name]:") { |
| t.Fatalf("expected transcript without file wrapper tags, got %q", transcript) |
| } |
| if !strings.Contains(transcript, "# context_context.txt") { |
| t.Fatalf("expected history transcript header, got %q", transcript) |
| } |
| for _, want := range []string{ |
| "=== 1 ===", |
| "[r=0]", |
| "=== 2 ===", |
| "[r=1]", |
| "=== 3 ===", |
| "[r=2]", |
| "=== 4 ===", |
| "[r=3]", |
| "=== 5 ===", |
| "first user turn", |
| "tool result", |
| "latest user turn", |
| "[reasoning_content]", |
| "hidden reasoning", |
| "<|DSML|tool_calls>", |
| } { |
| if !strings.Contains(transcript, want) { |
| t.Fatalf("expected transcript to contain %q, got %q", want, transcript) |
| } |
| } |
| } |
|
|
| func TestApplyCurrentInputFileSkipsShortInputWhenThresholdNotReached(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| currentInputMin: 10, |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": []any{ |
| map[string]any{"role": "user", "content": "hello"}, |
| }, |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 0 { |
| t.Fatalf("expected no upload on first turn, got %d", len(ds.uploadCalls)) |
| } |
| if out.FinalPrompt != stdReq.FinalPrompt { |
| t.Fatalf("expected prompt unchanged on first turn") |
| } |
| } |
|
|
| func TestApplyThinkingInjectionAppendsLatestUserPrompt(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| thinkingInjection: boolPtr(true), |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": []any{ |
| map[string]any{"role": "user", "content": "hello"}, |
| }, |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply thinking injection failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 0 { |
| t.Fatalf("expected no upload for first short turn, got %d", len(ds.uploadCalls)) |
| } |
| if out.FinalPrompt != stdReq.FinalPrompt { |
| t.Fatalf("expected prompt unchanged when thinking injection is disabled") |
| } |
| } |
|
|
| func TestApplyThinkingInjectionUsesCustomPrompt(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| thinkingInjection: boolPtr(true), |
| thinkingPrompt: "custom thinking format", |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": []any{ |
| map[string]any{"role": "user", "content": "hello"}, |
| }, |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply thinking injection failed: %v", err) |
| } |
| if out.FinalPrompt != stdReq.FinalPrompt { |
| t.Fatalf("expected prompt unchanged when thinking injection is disabled") |
| } |
| } |
|
|
| func TestApplyCurrentInputFileDisabledPassThrough(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: false, |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-vision", |
| "messages": historySplitTestMessages(), |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 0 { |
| t.Fatalf("expected no uploads when both split modes are disabled, got %d", len(ds.uploadCalls)) |
| } |
| if out.CurrentInputFileApplied || out.HistoryText != "" { |
| t.Fatalf("expected direct pass-through, got current_input=%v history=%q", out.CurrentInputFileApplied, out.HistoryText) |
| } |
| if !strings.Contains(out.FinalPrompt, "first user turn") || !strings.Contains(out.FinalPrompt, "latest user turn") { |
| t.Fatalf("expected original prompt context to stay inline, got %s", out.FinalPrompt) |
| } |
| } |
|
|
| func TestApplyCurrentInputFileUploadsFirstTurnWithNumberedHistoryTranscript(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| currentInputMin: 10, |
| thinkingInjection: boolPtr(true), |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": []any{ |
| map[string]any{"role": "user", "content": "first turn content that is long enough"}, |
| }, |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 1 { |
| t.Fatalf("expected current input upload, got %d", len(ds.uploadCalls)) |
| } |
| if !out.CurrentInputFileApplied { |
| t.Fatalf("expected current input file to be applied") |
| } |
| if !strings.Contains(out.FinalPrompt, ds.uploadCalls[0].Filename) { |
| t.Fatalf("expected continuation prompt, got %q", out.FinalPrompt) |
| } |
| historyText := string(ds.uploadCalls[0].Data) |
| if !strings.Contains(historyText, "# context_context.txt") || !strings.Contains(historyText, "=== 1 ===") { |
| t.Fatalf("expected numbered history transcript, got %q", historyText) |
| } |
| } |
|
|
| func TestApplyCurrentInputFilePreservesFullContextPromptForTokenCounting(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| currentInputMin: 0, |
| thinkingInjection: boolPtr(true), |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-vision", |
| "messages": historySplitTestMessages(), |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if out.FinalPrompt != stdReq.FinalPrompt { |
| t.Fatalf("expected live prompt unchanged when current input file is disabled") |
| } |
| } |
|
|
| func TestApplyCurrentInputFileUploadsFullContextFile(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| currentInputMin: 0, |
| thinkingInjection: boolPtr(true), |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-vision", |
| "messages": historySplitTestMessages(), |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if out.CurrentInputFileApplied { |
| t.Fatalf("expected current input file to remain disabled") |
| } |
| if len(ds.uploadCalls) != 0 { |
| t.Fatalf("expected no current input upload, got %d", len(ds.uploadCalls)) |
| } |
| if out.FinalPrompt != stdReq.FinalPrompt { |
| t.Fatalf("expected live prompt unchanged when current input file is disabled") |
| } |
| } |
|
|
| func TestApplyCurrentInputFileUploadsToolsContextSeparately(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| currentInputMin: 0, |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "tools": []any{ |
| map[string]any{ |
| "type": "function", |
| "function": map[string]any{ |
| "name": "search", |
| "description": "search docs", |
| "parameters": map[string]any{ |
| "type": "object", |
| }, |
| }, |
| }, |
| }, |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 2 { |
| t.Fatalf("expected history and tools uploads, got %d", len(ds.uploadCalls)) |
| } |
| if strings.Contains(strings.ToLower(ds.uploadCalls[0].Filename), "history") || !strings.HasSuffix(ds.uploadCalls[0].Filename, ".txt") || ds.uploadCalls[1].Filename != "context_tools.txt" { |
| t.Fatalf("unexpected upload filenames: %#v", ds.uploadCalls) |
| } |
| historyText := string(ds.uploadCalls[0].Data) |
| if strings.Contains(historyText, "Description: search docs") { |
| t.Fatalf("history transcript should not embed tool descriptions, got %q", historyText) |
| } |
| toolsText := string(ds.uploadCalls[1].Data) |
| if !strings.Contains(toolsText, "# context_tools.txt") || !strings.Contains(toolsText, "Tool: search") || !strings.Contains(toolsText, "Description: search docs") { |
| t.Fatalf("expected tools transcript to include schema, got %q", toolsText) |
| } |
| if !strings.Contains(out.FinalPrompt, "context_tools.txt") || !strings.Contains(out.FinalPrompt, "TOOL CALL SCHEME") { |
| t.Fatalf("expected prompt to reference tools file and include tool instructions, got %q", out.FinalPrompt) |
| } |
| } |
|
|
| func TestApplyCurrentInputFileCarriesHistoryText(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| DS: ds, |
| } |
| req := map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| } |
| stdReq, err := promptcompat.NormalizeOpenAIChatRequest(h.Store, req, "") |
| if err != nil { |
| t.Fatalf("normalize failed: %v", err) |
| } |
|
|
| out, err := h.applyCurrentInputFile(context.Background(), &auth.RequestAuth{DeepSeekToken: "token"}, stdReq) |
| if err != nil { |
| t.Fatalf("apply current input file failed: %v", err) |
| } |
| if len(ds.uploadCalls) != 1 { |
| t.Fatalf("expected history upload, got %d", len(ds.uploadCalls)) |
| } |
| if !out.CurrentInputFileApplied { |
| t.Fatalf("expected current input file to be applied") |
| } |
| if out.HistoryText != string(ds.uploadCalls[0].Data) { |
| t.Fatalf("expected history text to match uploaded file") |
| } |
| } |
|
|
| func TestChatCompletionsCurrentInputFileUploadsContextAndKeepsNeutralPrompt(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| h.ChatCompletions(rec, req) |
|
|
| if rec.Code != http.StatusOK { |
| t.Fatalf("expected 200, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if len(ds.uploadCalls) != 1 { |
| t.Fatalf("expected 1 upload call, got %d", len(ds.uploadCalls)) |
| } |
| upload := ds.uploadCalls[0] |
| if strings.Contains(strings.ToLower(upload.Filename), "history") || !strings.HasSuffix(upload.Filename, ".txt") { |
| t.Fatalf("unexpected upload filename: %q", upload.Filename) |
| } |
| if upload.Purpose != "assistants" { |
| t.Fatalf("unexpected purpose: %q", upload.Purpose) |
| } |
| historyText := string(upload.Data) |
| if strings.Contains(historyText, "[file content end]") || strings.Contains(historyText, "[file content begin]") || strings.Contains(historyText, "[file name]:") { |
| t.Fatalf("expected history transcript without file wrapper tags, got %s", historyText) |
| } |
| if !strings.Contains(historyText, "# context_context.txt") || !strings.Contains(historyText, "=== 1 ===") { |
| t.Fatalf("expected history transcript to use numbered sections, got %s", historyText) |
| } |
| if !strings.Contains(historyText, "latest user turn") { |
| t.Fatalf("expected full context to include latest turn, got %s", historyText) |
| } |
| if ds.completionReq == nil { |
| t.Fatal("expected completion payload to be captured") |
| } |
| promptText, _ := ds.completionReq["prompt"].(string) |
| if !strings.Contains(promptText, upload.Filename) { |
| t.Fatalf("expected continuation-oriented prompt, got %s", promptText) |
| } |
| if strings.Contains(promptText, "first user turn") || strings.Contains(promptText, "latest user turn") { |
| t.Fatalf("expected prompt to hide original turns, got %s", promptText) |
| } |
| refIDs, _ := ds.completionReq["ref_file_ids"].([]any) |
| if len(refIDs) == 0 || refIDs[0] != "file-inline-1" { |
| t.Fatalf("expected uploaded current input file to be first ref_file_id, got %#v", ds.completionReq["ref_file_ids"]) |
| } |
| var body map[string]any |
| if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { |
| t.Fatalf("decode response failed: %v", err) |
| } |
| usage, _ := body["usage"].(map[string]any) |
| promptTokens := int(usage["prompt_tokens"].(float64)) |
| neutralCount := util.CountPromptTokens(promptText, "deepseek-v4-flash") |
| if promptTokens <= neutralCount { |
| t.Fatalf("expected prompt_tokens to exceed neutral live prompt count (includes file context), got=%d neutral=%d", promptTokens, neutralCount) |
| } |
| } |
|
|
| func TestResponsesCurrentInputFileUploadsContextAndKeepsNeutralPrompt(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| r := chi.NewRouter() |
| registerOpenAITestRoutes(r, h) |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| r.ServeHTTP(rec, req) |
|
|
| if rec.Code != http.StatusOK { |
| t.Fatalf("expected 200, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if len(ds.uploadCalls) != 1 { |
| t.Fatalf("expected 1 upload call, got %d", len(ds.uploadCalls)) |
| } |
| historyText := string(ds.uploadCalls[0].Data) |
| if !strings.Contains(historyText, "# context_context.txt") || !strings.Contains(historyText, "=== 1 ===") { |
| t.Fatalf("expected uploaded history text to use numbered transcript format, got %s", historyText) |
| } |
| if ds.completionReq == nil { |
| t.Fatal("expected completion payload to be captured") |
| } |
| promptText, _ := ds.completionReq["prompt"].(string) |
| if !strings.Contains(promptText, ds.uploadCalls[0].Filename) { |
| t.Fatalf("expected continuation-oriented prompt, got %s", promptText) |
| } |
| if strings.Contains(promptText, "first user turn") || strings.Contains(promptText, "latest user turn") { |
| t.Fatalf("expected prompt to hide original turns, got %s", promptText) |
| } |
| var body map[string]any |
| if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { |
| t.Fatalf("decode response failed: %v", err) |
| } |
| usage, _ := body["usage"].(map[string]any) |
| inputTokens := int(usage["input_tokens"].(float64)) |
| neutralCount := util.CountPromptTokens(promptText, "deepseek-v4-flash") |
| if inputTokens <= neutralCount { |
| t.Fatalf("expected input_tokens to exceed neutral live prompt count (includes file context), got=%d neutral=%d", inputTokens, neutralCount) |
| } |
| } |
|
|
| func TestResponsesCurrentInputFileUploadsToolsSeparately(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| r := chi.NewRouter() |
| registerOpenAITestRoutes(r, h) |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "tools": []any{ |
| map[string]any{ |
| "type": "function", |
| "function": map[string]any{ |
| "name": "search", |
| "description": "search docs", |
| "parameters": map[string]any{"type": "object"}, |
| }, |
| }, |
| }, |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| r.ServeHTTP(rec, req) |
|
|
| if rec.Code != http.StatusOK { |
| t.Fatalf("expected 200, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if len(ds.uploadCalls) != 2 { |
| t.Fatalf("expected history and tools uploads, got %d", len(ds.uploadCalls)) |
| } |
| if strings.Contains(strings.ToLower(ds.uploadCalls[0].Filename), "history") || !strings.HasSuffix(ds.uploadCalls[0].Filename, ".txt") || ds.uploadCalls[1].Filename != "context_tools.txt" { |
| t.Fatalf("unexpected upload filenames: %#v", ds.uploadCalls) |
| } |
| historyText := string(ds.uploadCalls[0].Data) |
| if strings.Contains(historyText, "Description: search docs") { |
| t.Fatalf("history transcript should not embed tool descriptions, got %q", historyText) |
| } |
| toolsText := string(ds.uploadCalls[1].Data) |
| if !strings.Contains(toolsText, "# context_tools.txt") || !strings.Contains(toolsText, "Tool: search") || !strings.Contains(toolsText, "Description: search docs") { |
| t.Fatalf("expected tools transcript to include schema, got %q", toolsText) |
| } |
| promptText, _ := ds.completionReq["prompt"].(string) |
| if !strings.Contains(promptText, "context_tools.txt") || !strings.Contains(promptText, "TOOL CALL SCHEME") { |
| t.Fatalf("expected live prompt to reference tools file and retain format instructions, got %q", promptText) |
| } |
| if strings.Contains(promptText, "Description: search docs") { |
| t.Fatalf("live prompt should not inline tool descriptions, got %q", promptText) |
| } |
| refIDs, _ := ds.completionReq["ref_file_ids"].([]any) |
| if len(refIDs) < 2 || refIDs[0] != "file-inline-1" || refIDs[1] != "file-inline-2" { |
| t.Fatalf("expected history and tools ref ids first, got %#v", ds.completionReq["ref_file_ids"]) |
| } |
| } |
|
|
| func TestChatCompletionsCurrentInputFileMapsManagedAuthFailureTo401(t *testing.T) { |
| ds := &inlineUploadDSStub{ |
| uploadErr: &dsclient.RequestFailure{Op: "upload file", Kind: dsclient.FailureManagedUnauthorized, Message: "expired token"}, |
| } |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusManagedAuthStub{}, |
| DS: ds, |
| } |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer managed-key") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| h.ChatCompletions(rec, req) |
|
|
| if rec.Code != http.StatusUnauthorized { |
| t.Fatalf("expected 401, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if !strings.Contains(rec.Body.String(), "Please re-login the account in admin") { |
| t.Fatalf("expected managed auth error message, got %s", rec.Body.String()) |
| } |
| } |
|
|
| func TestResponsesCurrentInputFileMapsDirectAuthFailureTo401(t *testing.T) { |
| ds := &inlineUploadDSStub{ |
| uploadErr: &dsclient.RequestFailure{Op: "upload file", Kind: dsclient.FailureDirectUnauthorized, Message: "invalid token"}, |
| } |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| r := chi.NewRouter() |
| registerOpenAITestRoutes(r, h) |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| r.ServeHTTP(rec, req) |
|
|
| if rec.Code != http.StatusUnauthorized { |
| t.Fatalf("expected 401, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if !strings.Contains(rec.Body.String(), "Invalid token") { |
| t.Fatalf("expected direct auth error message, got %s", rec.Body.String()) |
| } |
| } |
|
|
| func TestChatCompletionsCurrentInputFileUploadFailureReturnsInternalServerError(t *testing.T) { |
| ds := &inlineUploadDSStub{uploadErr: errors.New("boom")} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| h.ChatCompletions(rec, req) |
|
|
| if rec.Code != http.StatusInternalServerError { |
| t.Fatalf("expected 500, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| } |
|
|
| func TestCurrentInputFileWorksAcrossAutoDeleteModes(t *testing.T) { |
| for _, mode := range []string{"none", "single", "all"} { |
| t.Run(mode, func(t *testing.T) { |
| ds := &inlineUploadDSStub{} |
| h := &openAITestSurface{ |
| Store: mockOpenAIConfig{ |
| autoDeleteMode: mode, |
| currentInputEnabled: true, |
| }, |
| Auth: streamStatusAuthStub{}, |
| DS: ds, |
| } |
| reqBody, _ := json.Marshal(map[string]any{ |
| "model": "deepseek-v4-flash", |
| "messages": historySplitTestMessages(), |
| "stream": false, |
| }) |
| req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(string(reqBody))) |
| req.Header.Set("Authorization", "Bearer direct-token") |
| req.Header.Set("Content-Type", "application/json") |
| rec := httptest.NewRecorder() |
|
|
| h.ChatCompletions(rec, req) |
|
|
| if rec.Code != http.StatusOK { |
| t.Fatalf("expected 200, got %d body=%s", rec.Code, rec.Body.String()) |
| } |
| if len(ds.uploadCalls) != 1 { |
| t.Fatalf("expected current input upload for mode=%s, got %d", mode, len(ds.uploadCalls)) |
| } |
| historyText := string(ds.uploadCalls[0].Data) |
| if !strings.Contains(historyText, "# context_context.txt") || !strings.Contains(historyText, "=== 1 ===") { |
| t.Fatalf("expected uploaded history text to use numbered transcript format, got %s", historyText) |
| } |
| if ds.completionReq == nil { |
| t.Fatalf("expected completion payload for mode=%s", mode) |
| } |
| promptText, _ := ds.completionReq["prompt"].(string) |
| if strings.Contains(promptText, "first user turn") || strings.Contains(promptText, "latest user turn") { |
| t.Fatalf("unexpected prompt for mode=%s: %s", mode, promptText) |
| } |
| }) |
| } |
| } |
|
|
| func boolPtr(v bool) *bool { |
| return &v |
| } |
|
|