@@ -7,6 +7,80 @@ defmodule CodexPooler.Gateway.Payloads.PayloadNormalizerTest do
77 alias CodexPooler.Gateway.Payloads.RequestOptions
88
99 describe "upstream_payload/4" do
10+ test "removes backend Codex encrypted tool schema markers from HTTP upstream JSON" do
11+ payload = encrypted_tool_schema_payload ( )
12+ request_options = RequestOptions . build ( % { } , "/backend-api/codex/responses" , payload )
13+ model = % Model { upstream_model_id: "provider-model" }
14+
15+ assert { :ok , encoded } =
16+ PayloadNormalizer . upstream_payload (
17+ payload ,
18+ model ,
19+ "/backend-api/codex/responses" ,
20+ request_options
21+ )
22+
23+ upstream = Jason . decode! ( encoded )
24+
25+ assert get_in ( upstream , [ "tools" , Access . at ( 0 ) , "parameters" , "properties" , "message" ] ) ==
26+ % {
27+ "description" => "Initial plain-text task for the new agent." ,
28+ "type" => "string"
29+ }
30+
31+ assert get_in ( upstream , [
32+ "tools" ,
33+ Access . at ( 1 ) ,
34+ "function" ,
35+ "parameters" ,
36+ "properties" ,
37+ "message"
38+ ] ) ==
39+ % {
40+ "description" => "Message text to queue on the target agent." ,
41+ "type" => "string"
42+ }
43+ end
44+
45+ test "removes backend Codex encrypted tool schema markers from websocket upstream JSON" do
46+ payload = encrypted_tool_schema_payload ( )
47+
48+ request_options =
49+ % { }
50+ |> RequestOptions . build ( "/backend-api/codex/responses" , payload )
51+ |> RequestOptions . for_websocket ( payload )
52+
53+ model = % Model { upstream_model_id: "provider-model" }
54+
55+ assert { :ok , encoded } =
56+ PayloadNormalizer . upstream_payload (
57+ payload ,
58+ model ,
59+ "/backend-api/codex/responses" ,
60+ request_options
61+ )
62+
63+ upstream = Jason . decode! ( encoded )
64+ assert upstream [ "type" ] == "response.create"
65+
66+ refute Map . has_key? (
67+ get_in ( upstream , [ "tools" , Access . at ( 0 ) , "parameters" , "properties" , "message" ] ) ,
68+ "encrypted"
69+ )
70+
71+ refute Map . has_key? (
72+ get_in ( upstream , [
73+ "tools" ,
74+ Access . at ( 1 ) ,
75+ "function" ,
76+ "parameters" ,
77+ "properties" ,
78+ "message"
79+ ] ) ,
80+ "encrypted"
81+ )
82+ end
83+
1084 test "omits absent, auto, and default service tiers while preserving concrete tiers upstream" do
1185 model = % Model { upstream_model_id: "provider-model" }
1286
@@ -183,4 +257,51 @@ defmodule CodexPooler.Gateway.Payloads.PayloadNormalizerTest do
183257 assert Jason . decode! ( encoded ) [ "service_tier" ] == "priority"
184258 end
185259 end
260+
261+ defp encrypted_tool_schema_payload do
262+ % {
263+ "model" => "gpt-5.5" ,
264+ "input" => [ % { "role" => "user" , "content" => "hello" } ] ,
265+ "tools" => [
266+ % {
267+ "type" => "function" ,
268+ "name" => "spawn_agent" ,
269+ "strict" => false ,
270+ "parameters" => % {
271+ "type" => "object" ,
272+ "properties" => % {
273+ "message" => % {
274+ "type" => "string" ,
275+ "description" => "Initial plain-text task for the new agent." ,
276+ "encrypted" => true
277+ } ,
278+ "task_name" => % { "type" => "string" }
279+ } ,
280+ "required" => [ "task_name" , "message" ] ,
281+ "additionalProperties" => false
282+ }
283+ } ,
284+ % {
285+ "type" => "function" ,
286+ "function" => % {
287+ "name" => "send_message" ,
288+ "strict" => false ,
289+ "parameters" => % {
290+ "type" => "object" ,
291+ "properties" => % {
292+ "message" => % {
293+ "type" => "string" ,
294+ "description" => "Message text to queue on the target agent." ,
295+ "encrypted" => true
296+ } ,
297+ "target" => % { "type" => "string" }
298+ } ,
299+ "required" => [ "target" , "message" ] ,
300+ "additionalProperties" => false
301+ }
302+ }
303+ }
304+ ]
305+ }
306+ end
186307end
0 commit comments