package openai import ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" edgeservice "iop/apps/edge/internal/service" "iop/packages/go/config" iop "iop/proto/gen/iop" ) // TestResponsesProviderPoolTunnelSelectionUsesPassthrough verifies that when a // provider-pool catalog match is resolved and the selected provider is an // OpenAI-compatible type (tunnel executionPath), the Responses handler // dispatches via tunnel passthrough with the raw body preserved (model rewrite // only). This mirrors TestChatCompletionsProviderPoolTunnelSelectionUsesPassthrough // for /v1/responses. func TestResponsesProviderPoolTunnelSelectionUsesPassthrough(t *testing.T) { frames := make(chan *iop.ProviderTunnelFrame, 3) frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: 200} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(`{"ok":true}`)} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true} close(frames) fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), tunnelFrames: frames, } catalog := []config.ModelCatalogEntry{ {ID: "vllm-resp-model", Providers: map[string]string{"prov-vllm": "Qwen3-35B"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"vllm-resp-model", "input":"hello world" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Tunnel passthrough must use SubmitProviderPool tunnel path. tunnelReqs := fake.tunnelReqsSnapshot() reqs := fake.reqsSnapshot() if len(tunnelReqs) != 1 { t.Fatalf("expected 1 tunnel dispatch for vLLM path, got %d", len(tunnelReqs)) } if len(reqs) != 0 { t.Fatalf("expected 0 normalized SubmitRun for vLLM tunnel path, got %d", len(reqs)) } if !tunnelReqs[0].ProviderPool { t.Error("tunnel dispatch must have ProviderPool=true") } if tunnelReqs[0].Path != "/v1/responses" { t.Fatalf("tunnel path: got %q want /v1/responses", tunnelReqs[0].Path) } } // TestResponsesProviderPoolOllamaSelectionUsesNormalizedRun verifies that when a // provider-pool catalog match is resolved and the selected provider is an // Ollama type (normalized executionPath), the Responses handler dispatches via // normalized RunEvent path with the decoded prompt/input, not via tunnel. This // mirrors TestChatCompletionsProviderPoolOllamaSelectionUsesNormalizedRun for // /v1/responses. func TestResponsesProviderPoolOllamaSelectionUsesNormalizedRun(t *testing.T) { fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } catalog := []config.ModelCatalogEntry{ {ID: "ollama-resp-model", Providers: map[string]string{"prov-ollama": "qwen3.6:35b"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"ollama-resp-model", "input":"hello world" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Normalized Ollama path must use SubmitProviderPool normalized path. reqs := fake.reqsSnapshot() tunnelReqs := fake.tunnelReqsSnapshot() if len(reqs) != 1 { t.Fatalf("expected 1 normalized SubmitRun for Ollama path, got %d", len(reqs)) } if len(tunnelReqs) != 0 { t.Fatalf("expected 0 tunnel dispatch for Ollama normalized path, got %d", len(tunnelReqs)) } if !reqs[0].ProviderPool { t.Error("normalized dispatch must have ProviderPool=true") } if reqs[0].ModelGroupKey != "ollama-resp-model" { t.Fatalf("expected model group key %q, got %q", "ollama-resp-model", reqs[0].ModelGroupKey) } } // TestResponsesMixedProviderPoolTunnelSelection verifies S05: a mixed // provider-pool model group that selects an OpenAI-compatible (vLLM) provider // dispatches via tunnel passthrough for /v1/responses. func TestResponsesMixedProviderPoolTunnelSelection(t *testing.T) { tunnelFrames := make(chan *iop.ProviderTunnelFrame, 3) tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: 200} tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(`{"id":"resp-mixed","object":"response"}`)} tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true} close(tunnelFrames) fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), tunnelFrames: tunnelFrames, } catalog := []config.ModelCatalogEntry{ { ID: "mixed-resp-model", Providers: map[string]string{ "prov-vllm": "served-vllm", "prov-ollama": "served-ollama", }, }, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"mixed-resp-model", "input":"hello mixed" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 1 { t.Fatalf("expected 1 tunnel dispatch, got %d", len(tunnelReqs)) } if !tunnelReqs[0].ProviderPool { t.Error("tunnel request must have ProviderPool=true") } if tunnelReqs[0].Path != "/v1/responses" { t.Fatalf("tunnel path: got %q want /v1/responses", tunnelReqs[0].Path) } runReqs := fake.reqsSnapshot() if len(runReqs) != 0 { t.Errorf("expected 0 normalized SubmitRun calls, got %d", len(runReqs)) } } // TestResponsesMixedProviderPoolOllamaSelection verifies S05: when the mixed // model group selects an Ollama provider, the request is dispatched over the // normalized path (SubmitRun), and no tunnel dispatch is issued for /v1/responses. func TestResponsesMixedProviderPoolOllamaSelection(t *testing.T) { events := bufferedRunEvents( &iop.RunEvent{Type: "delta", Delta: "ollama-resp"}, &iop.RunEvent{Type: "complete"}, ) fake := &providerFakeRunService{ fakeRunService: fakeRunService{ events: events, }, poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } catalog := []config.ModelCatalogEntry{ { ID: "mixed-resp-model", Providers: map[string]string{ "prov-vllm": "served-vllm", "prov-ollama": "served-ollama", }, }, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"mixed-resp-model", "input":"hello mixed" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 0 { t.Fatalf("expected 0 tunnel dispatches for Ollama selection, got %d", len(tunnelReqs)) } runReqs := fake.reqsSnapshot() if len(runReqs) != 1 { t.Fatalf("expected 1 normalized SubmitRun, got %d", len(runReqs)) } if runReqs[0].ModelGroupKey != "mixed-resp-model" { t.Errorf("normalized ModelGroupKey: got %q, want mixed-resp-model", runReqs[0].ModelGroupKey) } if !runReqs[0].ProviderPool { t.Error("normalized run must have ProviderPool=true") } } func TestChatCompletionsProviderPoolOllamaSelectionUsesNormalizedRun(t *testing.T) { runEvents := make(chan *iop.RunEvent, 2) runEvents <- &iop.RunEvent{Type: "complete"} close(runEvents) fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), poolRunFrames: runEvents, } catalog := []config.ModelCatalogEntry{ {ID: "ollama-model", Providers: map[string]string{"prov-ollama": "qwen3.6:35b"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ "model":"ollama-model", "messages":[{"role":"user","content":"hello"}] }`)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Ollama-selected provider-pool should use normalized path (SubmitRun), // NOT tunnel passthrough. tunnelReqs := fake.tunnelReqsSnapshot() reqs := fake.reqsSnapshot() if len(tunnelReqs) != 0 { t.Fatalf("expected 0 tunnel dispatches for Ollama-normalized path, got %d", len(tunnelReqs)) } if len(reqs) != 1 { t.Fatalf("expected exactly 1 normalized SubmitRun for Ollama path, got %d", len(reqs)) } } // TestChatCompletionsProviderPoolTunnelSelectionUsesPassthrough verifies that // when a provider-pool catalog match is resolved and the selected provider is // an OpenAI-compatible type (tunnel executionPath), the Chat handler dispatches // via tunnel passthrough. func TestChatCompletionsProviderPoolTunnelSelectionUsesPassthrough(t *testing.T) { frames := make(chan *iop.ProviderTunnelFrame, 3) frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: 200} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(`{"ok":true}`)} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true} close(frames) fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), tunnelFrames: frames, } catalog := []config.ModelCatalogEntry{ {ID: "vllm-model", Providers: map[string]string{"prov-vllm": "Qwen3-35B"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ "model":"vllm-model", "messages":[{"role":"user","content":"hello"}] }`)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) // OpenAI-compatible provider-pool should use tunnel passthrough. tunnelReqs := fake.tunnelReqsSnapshot() reqs := fake.reqsSnapshot() if len(tunnelReqs) != 1 { t.Fatalf("expected 1 tunnel dispatch for vLLM path, got %d", len(tunnelReqs)) } if !tunnelReqs[0].ProviderPool { t.Error("tunnel dispatch must have ProviderPool=true") } if len(reqs) != 0 { t.Fatalf("expected 0 normalized SubmitRun for vLLM tunnel path, got %d", len(reqs)) } } // TestChatCompletionsMixedProviderPoolTunnelSelection verifies S05: a mixed // model group containing both OpenAI-compatible and Ollama providers dispatches // the selected tunnel-capable provider over the provider tunnel (passthrough) // path. Only one tunnel request is sent, no normalized SubmitRun is called. func TestChatCompletionsMixedProviderPoolTunnelSelection(t *testing.T) { // Tunnel frames for the tunnel path. tunnelFrames := make(chan *iop.ProviderTunnelFrame, 3) tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: 200} tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(`{"id":"cmpl-mixed","choices":[{"index":0,"message":{"role":"assistant","content":"tunnel"}}],"finish_reason":"stop"}`)} tunnelFrames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true} close(tunnelFrames) // Fake service selects tunnel path (simulating vLLM provider selection). fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), tunnelFrames: tunnelFrames, } // Mixed catalog: OpenAI-compatible (vLLM) + Ollama in same group. catalog := []config.ModelCatalogEntry{ { ID: "mixed-model", Providers: map[string]string{ "prov-vllm": "served-vllm", "prov-ollama": "served-ollama", }, }, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ "model":"mixed-model", "messages":[{"role":"user","content":"hello"}] }`)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Tunnel path: exactly 1 tunnel dispatch, 0 normalized SubmitRun. tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 1 { t.Fatalf("expected 1 tunnel dispatch, got %d", len(tunnelReqs)) } if !tunnelReqs[0].ProviderPool { t.Error("tunnel request must have ProviderPool=true") } if tunnelReqs[0].ModelGroupKey != "mixed-model" { t.Errorf("tunnel ModelGroupKey: got %q, want mixed-model", tunnelReqs[0].ModelGroupKey) } runReqs := fake.reqsSnapshot() if len(runReqs) != 0 { t.Errorf("expected 0 normalized SubmitRun calls, got %d", len(runReqs)) } } // TestChatCompletionsMixedProviderPoolOllamaSelection verifies S05: when the // mixed model group selects an Ollama provider, the request is dispatched over // the normalized path (SubmitRun), and no tunnel dispatch is issued. func TestChatCompletionsMixedProviderPoolOllamaSelection(t *testing.T) { // Normalized path events. events := bufferedRunEvents( &iop.RunEvent{Type: "delta", Delta: "ollama"}, &iop.RunEvent{Type: "complete"}, ) // Fake service selects normalized path (simulating Ollama provider selection). fake := &providerFakeRunService{ fakeRunService: fakeRunService{ events: events, }, poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } // Same mixed catalog: vLLM + Ollama. catalog := []config.ModelCatalogEntry{ { ID: "mixed-model", Providers: map[string]string{ "prov-vllm": "served-vllm", "prov-ollama": "served-ollama", }, }, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ "model":"mixed-model", "messages":[{"role":"user","content":"hello"}] }`)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Normalized path: 0 tunnel dispatches, 1 normalized SubmitRun. tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 0 { t.Fatalf("expected 0 tunnel dispatches for Ollama selection, got %d", len(tunnelReqs)) } runReqs := fake.reqsSnapshot() if len(runReqs) != 1 { t.Fatalf("expected 1 normalized SubmitRun, got %d", len(runReqs)) } // Adapter/Target are rewritten by the service's admitted candidate; the // fake here records the pre-admission request so the handler-level path // selection (tunnel vs normalized) is the assertion surface. if runReqs[0].ModelGroupKey != "mixed-model" { t.Errorf("normalized ModelGroupKey: got %q, want mixed-model", runReqs[0].ModelGroupKey) } if !runReqs[0].ProviderPool { t.Error("normalized run must have ProviderPool=true") } } // TestChatCompletionsOllamaOnlyProviderPoolUsesNormalizedPath verifies S05: // a model group containing only Ollama providers always dispatches over the // normalized path. No tunnel request is ever issued. func TestChatCompletionsOllamaOnlyProviderPoolUsesNormalizedPath(t *testing.T) { events := bufferedRunEvents( &iop.RunEvent{Type: "delta", Delta: "ollama-only"}, &iop.RunEvent{Type: "complete"}, ) // Fake service selects normalized path. fake := &providerFakeRunService{ fakeRunService: fakeRunService{ events: events, }, poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } // Ollama-only catalog. catalog := []config.ModelCatalogEntry{ { ID: "ollama-only-model", Providers: map[string]string{ "prov-ollama": "qwen3.6:35b", }, }, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ "model":"ollama-only-model", "messages":[{"role":"user","content":"hello"}] }`)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // Must not dispatch tunnel. tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 0 { t.Fatalf("ollama-only must not dispatch tunnel, got %d", len(tunnelReqs)) } // Must dispatch exactly one normalized run. runReqs := fake.reqsSnapshot() if len(runReqs) != 1 { t.Fatalf("expected 1 normalized SubmitRun, got %d", len(runReqs)) } if runReqs[0].ModelGroupKey != "ollama-only-model" { t.Errorf("ollama-only ModelGroupKey: got %q, want ollama-only-model", runReqs[0].ModelGroupKey) } if !runReqs[0].ProviderPool { t.Error("ollama-only normalized run must have ProviderPool=true") } } // TestChatCompletionsProviderPoolTunnelPreservesUnknownFields verifies that // when the provider-pool dispatch selects the tunnel path, the caller's raw // body is forwarded with model rewrite only: unknown top-level fields // (store, codex_trace, custom_provider_options, nested unknown object) and // Codex/provider-specific fields survive into the tunnel request body. No // IOP sideband key is injected into the pure response payload (SURFACE_FIELD). func TestChatCompletionsProviderPoolTunnelPreservesUnknownFields(t *testing.T) { frames := make(chan *iop.ProviderTunnelFrame, 3) frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_RESPONSE_START, StatusCode: 200} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_BODY, Body: []byte(`{"ok":true}`)} frames <- &iop.ProviderTunnelFrame{Kind: iop.ProviderTunnelFrameKind_PROVIDER_TUNNEL_FRAME_KIND_END, End: true} close(frames) fake := &providerFakeRunService{ tunnelFrames: frames, tunnelServedTarget: "served-model", } catalog := []config.ModelCatalogEntry{ {ID: "pool-model", Providers: map[string]string{"prov-vllm": "served-model"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) reqBody := `{ "model":"pool-model", "messages":[{"role":"user","content":"hello"}], "store":true, "parallel_tool_calls":true, "codex_trace":{"enabled":true}, "custom_provider_options":{"timeout_ms":5000}, "nested":{"unknown":{"deep":{"value":42}}}, "thinking_token_budget":1024 }` req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(reqBody)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 1 { t.Fatalf("expected 1 tunnel dispatch, got %d", len(tunnelReqs)) } // Parse the tunnel body as a JSON map and verify model rewrite + unknown preservation. tunnelBodies := fake.tunnelBodiesSnapshot() if len(tunnelBodies) != 1 { t.Fatalf("expected 1 tunnel body, got %d", len(tunnelBodies)) } var bodyMap map[string]json.RawMessage if err := json.Unmarshal(tunnelBodies[0], &bodyMap); err != nil { t.Fatalf("decode tunnel body: %v body=%s", err, string(tunnelBodies[0])) } // Model must be rewritten to the served target. var bodyModel string if err := json.Unmarshal(bodyMap["model"], &bodyModel); err != nil { t.Fatalf("decode model field: %v", err) } if bodyModel != "served-model" { t.Errorf("model rewrite: got %q, want served-model", bodyModel) } // Known fields must survive. if _, ok := bodyMap["messages"]; !ok { t.Error("messages must be preserved in tunnel body") } if _, ok := bodyMap["store"]; !ok { t.Error("store field must be preserved in tunnel body") } if _, ok := bodyMap["parallel_tool_calls"]; !ok { t.Error("parallel_tool_calls field must be preserved in tunnel body") } if _, ok := bodyMap["codex_trace"]; !ok { t.Error("codex_trace field must be preserved in tunnel body") } if _, ok := bodyMap["custom_provider_options"]; !ok { t.Error("custom_provider_options field must be preserved in tunnel body") } if _, ok := bodyMap["nested"]; !ok { t.Error("nested unknown object must be preserved in tunnel body") } if _, ok := bodyMap["thinking_token_budget"]; !ok { t.Error("thinking_token_budget must be preserved in tunnel body") } // No IOP-internal metadata keys should leak into the pure passthrough body. for _, key := range []string{"estimated_input_tokens", "context_class"} { if _, ok := bodyMap[key]; ok { t.Errorf("IOP internal key %q must not be in tunnel body", key) } } if len(fake.reqsSnapshot()) != 0 { t.Errorf("normalized SubmitRun must not be called for tunnel path, got %d", len(fake.reqsSnapshot())) } } // TestChatCompletionsProviderPoolNormalizedIgnoresUnknownFields verifies that // when the provider-pool dispatch selects the normalized path, the lenient // ingress accepts unknown/provider-specific fields without rejecting the // request, but the normalized RunRequest.Input only reflects standard supported // fields. Unknown fields must never be invented or propagated into the adapter // native request (SURFACE_FIELD). func TestChatCompletionsProviderPoolNormalizedIgnoresUnknownFields(t *testing.T) { completeEvent := &iop.RunEvent{ Type: "delta", Delta: "ok", } completeEvent2 := &iop.RunEvent{Type: "complete"} fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), poolRunFrames: bufferedRunEvents(completeEvent, completeEvent2), } catalog := []config.ModelCatalogEntry{ {ID: "ollama-pool-model", Providers: map[string]string{"prov-ollama": "qwen3.6:35b"}}, } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog(catalog) reqBody := `{ "model":"ollama-pool-model", "messages":[{"role":"user","content":"hello"}], "temperature":0.7, "store":true, "codex_trace":{"enabled":true}, "custom_provider_options":{"timeout_ms":5000}, "nested_unknown":{"deep":true}, "reasoning_effort":"high" }` req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(reqBody)) w := httptest.NewRecorder() srv.handleChatCompletions(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // The lenient ingress must NOT reject the request due to unknown fields. runReqs := fake.reqsSnapshot() if len(runReqs) != 1 { t.Fatalf("expected 1 normalized SubmitRun, got %d", len(runReqs)) } runReq := runReqs[0] if !runReq.ProviderPool { t.Error("normalized pool run must have ProviderPool=true") } // Standard supported fields must be present in Input. input := runReq.Input if _, ok := input["prompt"]; !ok { t.Error("prompt must be in normalized Input") } if _, ok := input["messages"]; !ok { t.Error("messages must be in normalized Input") } options, ok := input["options"].(map[string]any) if !ok { t.Fatalf("options must be in normalized Input, got %T", input["options"]) } if options["temperature"] != 0.7 { t.Errorf("temperature must be forwarded to normalized options, got %+v", options["temperature"]) } // Unknown/provider-specific fields must NOT be in the normalized Input. for _, key := range []string{"store", "codex_trace", "custom_provider_options", "nested_unknown"} { if _, ok := input[key]; ok { t.Errorf("unknown field %q must not be in normalized Input", key) } if _, ok := options[key]; ok { t.Errorf("unknown field %q must not be in normalized Input options", key) } } // The tunnel path must not be taken. tunnelReqs := fake.tunnelReqsSnapshot() if len(tunnelReqs) != 0 { t.Errorf("tunnel must not be dispatched for normalized path, got %d", len(tunnelReqs)) } } // TestResponsesProviderPoolTunnelUnknownFieldsUsesPoolSelection asserts that // when the selected provider is tunnel-passthrough (OpenAI-compatible), // unknown fields (tools, parallel_tool_calls, store, custom field) are // preserved verbatim in the tunnel body, and that the Run sent to // SubmitProviderPool carries a non-empty ModelGroupKey. func TestResponsesProviderPoolTunnelUnknownFieldsUsesPoolSelection(t *testing.T) { fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog([]config.ModelCatalogEntry{ {ID: "pool-model", Providers: map[string]string{"prov-tunnel": "served-tunnel"}}, }) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"pool-model", "input":"hello world", "tools":[{"type":"function","function":{"name":"lookup"}}], "parallel_tool_calls":true, "store":false, "custom_field":"keep-me" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // SubmitProviderPool must have been called with a populated Run. lastRun := fake.poolLastRunSnapshot() if lastRun.ModelGroupKey == "" { t.Error("SubmitProviderPool was called with empty Run.ModelGroupKey") } // The tunnel body must preserve unknown fields verbatim. if len(fake.tunnelBodiesSnapshot()) != 1 { t.Fatalf("expected exactly one tunnel body, got %d", len(fake.tunnelBodiesSnapshot())) } body := fake.tunnelBodiesSnapshot()[0] if !strings.Contains(string(body), "\"tools\"") { t.Error("tunnel body must preserve tools field") } if !strings.Contains(string(body), "\"parallel_tool_calls\"") { t.Error("tunnel body must preserve parallel_tool_calls field") } if !strings.Contains(string(body), "\"store\"") { t.Error("tunnel body must preserve store field") } if !strings.Contains(string(body), "\"custom_field\"") { t.Error("tunnel body must preserve custom_field") } } // TestResponsesProviderPoolOllamaSelectionRejectsUnknownFieldsWithoutTunnel // asserts that when the selected provider is normalized (Ollama/CLI), an // unknown-field request returns HTTP 400 and no tunnel or run dispatch occurs. func TestResponsesProviderPoolOllamaSelectionRejectsUnknownFieldsWithoutTunnel(t *testing.T) { fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog([]config.ModelCatalogEntry{ {ID: "ollama-model", Providers: map[string]string{"prov-ollama": "served-ollama"}}, }) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"ollama-model", "input":"hello", "unknown_field":"reject-me" }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusBadRequest { t.Fatalf("status: got %d body=%s, want 400", w.Code, w.Body.String()) } // No tunnel or run dispatch should have occurred. if len(fake.tunnelReqsSnapshot()) != 0 { t.Error("normalized path must not dispatch tunnel for unknown fields") } if len(fake.reqsSnapshot()) != 0 { t.Error("normalized path must not dispatch run for unknown fields") } // Verify pool dispatch was made. if fake.poolSubmitCountSnapshot() != 1 { t.Fatalf("pool submit count: got %d, want 1", fake.poolSubmitCountSnapshot()) } // Verify PrepareRun was called on the normalized path. prepareRunCalled := fake.poolPrepareRunCalledSnapshot() if !prepareRunCalled { t.Errorf("PrepareRun must be called on normalized path (poolSubmitCount=%d, poolLastRun.ModelGroupKey=%q)", fake.poolSubmitCountSnapshot(), fake.poolLastRunSnapshot().ModelGroupKey) } } // TestResponsesProviderPoolOllamaSelectionRejectsStreamingWithoutTunnel asserts // that when the selected provider is normalized, stream:true returns HTTP 400 // and no tunnel dispatch occurs. func TestResponsesProviderPoolOllamaSelectionRejectsStreamingWithoutTunnel(t *testing.T) { fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathNormalized), } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog([]config.ModelCatalogEntry{ {ID: "ollama-model", Providers: map[string]string{"prov-ollama": "served-ollama"}}, }) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"ollama-model", "input":"hello", "stream":true }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusBadRequest { t.Fatalf("status: got %d body=%s, want 400", w.Code, w.Body.String()) } // No tunnel dispatch for normalized path with stream:true. if len(fake.tunnelReqsSnapshot()) != 0 { t.Error("normalized path must not dispatch tunnel for stream:true") } if len(fake.reqsSnapshot()) != 0 { t.Error("normalized path must not dispatch run for stream:true") } if !fake.poolPrepareRunCalledSnapshot() { t.Error("PrepareRun must be called on normalized path") } } // TestResponsesProviderPoolTunnelStreamingUsesPoolSelection asserts that when // the selected provider is tunnel-passthrough, stream:true is relayed through // SubmitProviderPool with the raw SSE body preserved. func TestResponsesProviderPoolTunnelStreamingUsesPoolSelection(t *testing.T) { fake := &providerFakeRunService{ poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), tunnelFrames: staticProviderTunnelFrames(`{"id":"resp-1","output":[{"type":"message","role":"assistant","content":[{"type":"output_text","text":"hello"}]}],"stream":true}\n`), } srv := NewServer(config.EdgeOpenAIConf{}, fake, nil) srv.SetModelCatalog([]config.ModelCatalogEntry{ {ID: "pool-model", Providers: map[string]string{"prov-tunnel": "served-tunnel"}}, }) req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ "model":"pool-model", "input":"hello", "stream":true }`)) w := httptest.NewRecorder() srv.handleResponses(w, req) if w.Code != http.StatusOK { t.Fatalf("status: got %d body=%s", w.Code, w.Body.String()) } // SubmitProviderPool must have been called. if fake.poolSubmitCountSnapshot() != 1 { t.Fatalf("SubmitProviderPool call count: got %d, want 1", fake.poolSubmitCountSnapshot()) } // The tunnel body must preserve the raw SSE payload. if len(fake.tunnelBodiesSnapshot()) != 1 { t.Fatalf("expected one tunnel body, got %d", len(fake.tunnelBodiesSnapshot())) } body := fake.tunnelBodiesSnapshot()[0] if !strings.Contains(string(body), "\"stream\":true") { t.Error("tunnel body must preserve stream:true") } // PrepareRun must NOT be called on the tunnel path. if fake.poolPrepareRunCalledSnapshot() { t.Error("PrepareRun must NOT be called on tunnel path") } }