diff --git a/.castiron.stats.yml b/.castiron.stats.yml index 38faa80ab..ffe9692f1 100644 --- a/.castiron.stats.yml +++ b/.castiron.stats.yml @@ -1,8 +1,8 @@ schema_version: 1 -generation_id: a2e15f59-94b2-41a7-83a2-0aa28ffd7091 -openapi_spec_hash: 0ba3e4acd88b521d832e2a42d5471e00 -openapi_transformed_spec_hash: 0a6002520553b981f4c0bf6555a0a623 -config_hash: d8813efd847d1966dd7f03bb648c41dc -codegen_sha: 23fe5abcd01bf9d6dd1c1ee49b6244f9d2d078ce -codegen_hash: 2c513214ca2f30afc9ae2724d5b78c068dac45d959bc1c4f1d8b4706f507f3ca -public_codegen_sha: 0c208e28bddcefe8be7b5a0b94be94b8b973ed4e +generation_id: 68d4a705-114e-4d0f-b282-8084d4e049f4 +openapi_spec_hash: 31ce930d0bb93c8c09944ca9f79407b5 +openapi_transformed_spec_hash: c534613fdbcd88ff44bf4c87957de72b +config_hash: 81fd1039eb373628d87269f065d30a69 +codegen_sha: c4459e20988e14ba81b4d4f1a6790ac544a5e421 +codegen_hash: 28149b737e64b789663beb69a8e0c6154b88e36b900b271018931a93eb2df85d +public_codegen_sha: a624824bbbc483b09c013338b191697bf3c22e98 diff --git a/api_reference/openapi.transformed.yml b/api_reference/openapi.transformed.yml index 272cbeaf2..db232b77d 100644 --- a/api_reference/openapi.transformed.yml +++ b/api_reference/openapi.transformed.yml @@ -1941,7 +1941,7 @@ paths: { "object": "chat.completion", "id": "chatcmpl-AyPNinnUqUDYo9SAdA52NobMflmj2", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "created": 1738960610, "request_id": "req_ded8ab984ec4bf840f37566c1011c417", "tool_choice": null, @@ -2018,7 +2018,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "messages": [ { "role": "developer", @@ -2035,7 +2035,7 @@ paths: client = OpenAI() completion = client.chat.completions.create( - model="gpt-5.6-sol", + model="gpt-6-astra", messages=[ {"role": "developer", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"} @@ -2051,7 +2051,7 @@ paths: async function main() { const completion = await openai.chat.completions.create({ messages: [{ role: "developer", content: "You are a helpful assistant." }], - model: "gpt-5.6-sol", + model: "gpt-6-astra", store: true, }); @@ -2066,7 +2066,7 @@ paths: using OpenAI.Chat; ChatClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -2084,7 +2084,7 @@ paths: "id": "chatcmpl-B9MBs8CjcvOU2jLn4n570S5qMJKcT", "object": "chat.completion", "created": 1741569952, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "choices": [ { "index": 0, @@ -2122,7 +2122,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "messages": [ { "role": "user", @@ -2148,7 +2148,7 @@ paths: client = OpenAI() response = client.chat.completions.create( - model="gpt-5.6-sol", + model="gpt-6-astra", messages=[ { "role": "user", @@ -2174,7 +2174,7 @@ paths: async function main() { const response = await openai.chat.completions.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", messages: [ { role: "user", @@ -2200,7 +2200,7 @@ paths: using OpenAI.Chat; ChatClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -2221,7 +2221,7 @@ paths: "id": "chatcmpl-B9MHDbslfkBeAs8l4bebGdFOJ6PeG", "object": "chat.completion", "created": 1741570283, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "choices": [ { "index": 0, @@ -2259,7 +2259,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "messages": [ { "role": "developer", @@ -2277,7 +2277,7 @@ paths: client = OpenAI() completion = client.chat.completions.create( - model="gpt-5.6-sol", + model="gpt-6-astra", messages=[ {"role": "developer", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"} @@ -2294,7 +2294,7 @@ paths: async function main() { const completion = await openai.chat.completions.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", messages: [ {"role": "developer", "content": "You are a helpful assistant."}, {"role": "user", "content": "Hello!"} @@ -2317,7 +2317,7 @@ paths: using OpenAI.Chat; ChatClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -2337,13 +2337,13 @@ paths: } } response: | - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]} - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}]} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}]} .... - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} - title: Functions request: curl: | @@ -2351,7 +2351,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "messages": [ { "role": "user", @@ -2409,7 +2409,7 @@ paths: ] messages = [{"role": "user", "content": "What's the weather like in Boston today?"}] completion = client.chat.completions.create( - model="gpt-5.6-sol", + model="gpt-6-astra", messages=messages, tools=tools, tool_choice="auto" @@ -2445,7 +2445,7 @@ paths: ]; const response = await openai.chat.completions.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", messages: messages, tools: tools, tool_choice: "auto", @@ -2462,7 +2462,7 @@ paths: using OpenAI.Chat; ChatClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -2507,7 +2507,7 @@ paths: "id": "chatcmpl-abc123", "object": "chat.completion", "created": 1699896916, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "choices": [ { "index": 0, @@ -2547,7 +2547,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "messages": [ { "role": "user", @@ -2563,7 +2563,7 @@ paths: client = OpenAI() completion = client.chat.completions.create( - model="gpt-5.6-sol", + model="gpt-6-astra", messages=[ {"role": "user", "content": "Hello!"} ], @@ -2582,7 +2582,7 @@ paths: async function main() { const completion = await openai.chat.completions.create({ messages: [{ role: "user", content: "Hello!" }], - model: "gpt-5.6-sol", + model: "gpt-6-astra", reasoning_effort: "none", logprobs: true, top_logprobs: 2, @@ -2599,7 +2599,7 @@ paths: using OpenAI.Chat; ChatClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -2623,7 +2623,7 @@ paths: "id": "chatcmpl-123", "object": "chat.completion", "created": 1702685778, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "choices": [ { "index": 0, @@ -2868,7 +2868,7 @@ paths: { "object": "chat.completion", "id": "chatcmpl-abc123", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "created": 1738960610, "request_id": "req_ded8ab984ec4bf840f37566c1011c417", "tool_choice": null, @@ -2957,7 +2957,7 @@ paths: { "object": "chat.completion", "id": "chatcmpl-AyPNinnUqUDYo9SAdA52NobMflmj2", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "created": 1738960610, "request_id": "req_ded8ab984ec4bf840f37566c1011c417", "tool_choice": null, @@ -5090,14 +5090,14 @@ paths: -X POST \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-Type: application/json" \ - -d '{"name":"gpt-5.6-sol","data_source":{"type":"completions","input_messages":{"type":"template","template":[{"role":"developer","content":"Categorize a given news headline into one of the following topics: Technology, Markets, World, Business, or Sports.\n\n# Steps\n\n1. Analyze the content of the news headline to understand its primary focus.\n2. Extract the subject matter, identifying any key indicators or keywords.\n3. Use the identified indicators to determine the most suitable category out of the five options: Technology, Markets, World, Business, or Sports.\n4. Ensure only one category is selected per headline.\n\n# Output Format\n\nRespond with the chosen category as a single word. For instance: \"Technology\", \"Markets\", \"World\", \"Business\", or \"Sports\".\n\n# Examples\n\n**Input**: \"Apple Unveils New iPhone Model, Featuring Advanced AI Features\" \n**Output**: \"Technology\"\n\n**Input**: \"Global Stocks Mixed as Investors Await Central Bank Decisions\" \n**Output**: \"Markets\"\n\n**Input**: \"War in Ukraine: Latest Updates on Negotiation Status\" \n**Output**: \"World\"\n\n**Input**: \"Microsoft in Talks to Acquire Gaming Company for $2 Billion\" \n**Output**: \"Business\"\n\n**Input**: \"Manchester United Secures Win in Premier League Football Match\" \n**Output**: \"Sports\" \n\n# Notes\n\n- If the headline appears to fit into more than one category, choose the most dominant theme.\n- Keywords or phrases such as \"stocks\", \"company acquisition\", \"match\", or technological brands can be good indicators for classification.\n"} , {"role":"user","content":"{{item.input}}"}]} ,"sampling_params":{"max_completions_tokens":2048},"model":"gpt-5.6-sol","source":{"type":"file_content","content":[{"item":{"input":"Tech Company Launches Advanced Artificial Intelligence Platform","ground_truth":"Technology"}}]}}}' + -d '{"name":"gpt-6-astra","data_source":{"type":"completions","input_messages":{"type":"template","template":[{"role":"developer","content":"Categorize a given news headline into one of the following topics: Technology, Markets, World, Business, or Sports.\n\n# Steps\n\n1. Analyze the content of the news headline to understand its primary focus.\n2. Extract the subject matter, identifying any key indicators or keywords.\n3. Use the identified indicators to determine the most suitable category out of the five options: Technology, Markets, World, Business, or Sports.\n4. Ensure only one category is selected per headline.\n\n# Output Format\n\nRespond with the chosen category as a single word. For instance: \"Technology\", \"Markets\", \"World\", \"Business\", or \"Sports\".\n\n# Examples\n\n**Input**: \"Apple Unveils New iPhone Model, Featuring Advanced AI Features\" \n**Output**: \"Technology\"\n\n**Input**: \"Global Stocks Mixed as Investors Await Central Bank Decisions\" \n**Output**: \"Markets\"\n\n**Input**: \"War in Ukraine: Latest Updates on Negotiation Status\" \n**Output**: \"World\"\n\n**Input**: \"Microsoft in Talks to Acquire Gaming Company for $2 Billion\" \n**Output**: \"Business\"\n\n**Input**: \"Manchester United Secures Win in Premier League Football Match\" \n**Output**: \"Sports\" \n\n# Notes\n\n- If the headline appears to fit into more than one category, choose the most dominant theme.\n- Keywords or phrases such as \"stocks\", \"company acquisition\", \"match\", or technological brands can be good indicators for classification.\n"} , {"role":"user","content":"{{item.input}}"}]} ,"sampling_params":{"max_completions_tokens":2048},"model":"gpt-6-astra","source":{"type":"file_content","content":[{"item":{"input":"Tech Company Launches Advanced Artificial Intelligence Platform","ground_truth":"Technology"}}]}}}' python: | from openai import OpenAI client = OpenAI() run = client.evals.runs.create( "eval_67e579652b548190aaa83ada4b125f47", - name="gpt-5.6-sol", + name="gpt-6-astra", data_source={ "type": "completions", "input_messages": { @@ -5116,7 +5116,7 @@ paths: "sampling_params": { "max_completions_tokens": 2048 }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "source": { "type": "file_content", "content": [ @@ -5139,7 +5139,7 @@ paths: const run = await openai.evals.runs.create( "eval_67e579652b548190aaa83ada4b125f47", { - name: "gpt-5.6-sol", + name: "gpt-6-astra", data_source: { type: "completions", input_messages: { @@ -5158,7 +5158,7 @@ paths: sampling_params: { max_completions_tokens: 2048 }, - model: "gpt-5.6-sol", + model: "gpt-6-astra", source: { type: "file_content", content: [ @@ -5181,8 +5181,8 @@ paths: "eval_id": "eval_67e579652b548190aaa83ada4b125f47", "report_url": "https://platform.openai.com/evaluations/eval_67e579652b548190aaa83ada4b125f47&run_id=evalrun_67e57965b480819094274e3a32235e4c", "status": "queued", - "model": "gpt-5.6-sol", - "name": "gpt-5.6-sol", + "model": "gpt-6-astra", + "name": "gpt-6-astra", "created_at": 1743092069, "result_counts": { "total": 0, @@ -5226,7 +5226,7 @@ paths: } ] }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "sampling_params": { "max_completions_tokens": 2048 } @@ -5300,8 +5300,8 @@ paths: "eval_id": "eval_67abd54d9b0081909a86353f6fb9317a", "report_url": "https://platform.openai.com/evaluations/eval_67abd54d9b0081909a86353f6fb9317a?run_id=evalrun_67abd54d60ec8190832b46859da808f7", "status": "queued", - "model": "gpt-5.6-sol", - "name": "gpt-5.6-sol", + "model": "gpt-6-astra", + "name": "gpt-6-astra", "created_at": 1743092069, "result_counts": { "total": 0, @@ -5429,7 +5429,7 @@ paths: } ] }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "sampling_params": { "max_completions_tokens": 2048 } @@ -5503,8 +5503,8 @@ paths: "eval_id": "eval_67abd54d9b0081909a86353f6fb9317a", "report_url": "https://platform.openai.com/evaluations/eval_67abd54d9b0081909a86353f6fb9317a?run_id=evalrun_67abd54d60ec8190832b46859da808f7", "status": "canceled", - "model": "gpt-5.6-sol", - "name": "gpt-5.6-sol", + "model": "gpt-6-astra", + "name": "gpt-6-astra", "created_at": 1743092069, "result_counts": { "total": 0, @@ -5632,7 +5632,7 @@ paths: } ] }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "sampling_params": { "max_completions_tokens": 2048 } @@ -5865,7 +5865,7 @@ paths: } ], "finish_reason": "stop", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "usage": { "total_tokens": 325, "completion_tokens": 2, @@ -6001,7 +6001,7 @@ paths: } ], "finish_reason": "stop", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "usage": { "total_tokens": 325, "completion_tokens": 2, @@ -8257,7 +8257,7 @@ paths: required: true schema: type: string - example: gpt-5.6-sol + example: gpt-6-astra description: The ID of the model to use for this request responses: '200': @@ -8272,20 +8272,20 @@ paths: examples: request: curl: | - curl https://api.openai.com/v1/models/gpt-5.6-sol \ + curl https://api.openai.com/v1/models/gpt-6-astra \ -H "Authorization: Bearer $OPENAI_API_KEY" python: | from openai import OpenAI client = OpenAI() - client.models.retrieve("gpt-5.6-sol") + client.models.retrieve("gpt-6-astra") javascript: |- import OpenAI from "openai"; const openai = new OpenAI(); async function main() { - const model = await openai.models.retrieve("gpt-5.6-sol"); + const model = await openai.models.retrieve("gpt-6-astra"); console.log(model); } @@ -8305,7 +8305,7 @@ paths: Console.WriteLine(model.Value.Id); response: | { - "id": "gpt-5.6-sol", + "id": "gpt-6-astra", "object": "model", "created": 1686935002, "owned_by": "openai", @@ -9482,7 +9482,7 @@ paths: type: string - name: line_items in: query - description: Return only costs for these exact line item names. Each value must match the complete `line_item` value, for example `gpt-5.6-sol, input_tokens`. + description: Return only costs for these exact line item names. Each value must match the complete `line_item` value, for example `gpt-6-astra, input_tokens`. required: false schema: type: array @@ -11669,7 +11669,7 @@ paths: "object": "project.model_permissions", "mode": "allow_list", "model_ids": [ - "gpt-5.6-sol", + "gpt-6-astra", "o3" ] } @@ -16532,7 +16532,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Tell me a three sentence bedtime story about a unicorn." }' javascript: | @@ -16541,7 +16541,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "Tell me a three sentence bedtime story about a unicorn." }); @@ -16552,7 +16552,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input="Tell me a three sentence bedtime story about a unicorn." ) @@ -16562,7 +16562,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -16580,7 +16580,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -16635,7 +16635,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -16655,7 +16655,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -16678,7 +16678,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -16701,7 +16701,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -16729,7 +16729,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -16784,7 +16784,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -16805,7 +16805,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -16828,7 +16828,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -16858,7 +16858,7 @@ paths: "instructions": null, "max_output_tokens": null, "max_tool_calls": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "id": "msg_686eef60d3e081a29283bdcbc4322fd90e34c516d176ff86", @@ -16916,7 +16916,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "tools": [{ "type": "web_search_preview" }], "input": "What was a positive news story from today?" }' @@ -16926,7 +16926,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: [{ type: "web_search_preview" }], input: "What was a positive news story from today?", }); @@ -16938,7 +16938,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=[{ "type": "web_search_preview" }], input="What was a positive news story from today?", ) @@ -16950,7 +16950,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -16978,7 +16978,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "web_search_call", @@ -17073,7 +17073,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "tools": [{ "type": "file_search", "vector_store_ids": ["vs_1234567890"], @@ -17087,7 +17087,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: [{ type: "file_search", vector_store_ids: ["vs_1234567890"], @@ -17103,7 +17103,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=[{ "type": "file_search", "vector_store_ids": ["vs_1234567890"], @@ -17119,7 +17119,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -17150,7 +17150,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "file_search_call", @@ -17276,7 +17276,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "instructions": "You are a helpful assistant.", "input": "Hello!", "stream": true @@ -17287,7 +17287,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", instructions="You are a helpful assistant.", input="Hello!", stream=True @@ -17301,7 +17301,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", instructions: "You are a helpful assistant.", input: "Hello!", stream: true, @@ -17318,7 +17318,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -17340,10 +17340,10 @@ paths: } response: | event: response.created - data: {"type":"response.created","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.created","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.in_progress - data: {"type":"response.in_progress","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.in_progress","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.output_item.added data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"in_progress","role":"assistant","content":[]}} @@ -17366,7 +17366,7 @@ paths: data: {"type":"response.output_item.done","output_index":0,"item":{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}} event: response.completed - data: {"type":"response.completed","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"completed","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":37,"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":48},"user":null,"metadata":{}}} + data: {"type":"response.completed","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"completed","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":37,"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":48},"user":null,"metadata":{}}} - title: Functions request: curl: | @@ -17374,7 +17374,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "What is the weather like in Boston today?", "tools": [ { @@ -17424,7 +17424,7 @@ paths: ] response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=tools, input="What is the weather like in Boston today?", tool_choice="auto" @@ -17456,7 +17456,7 @@ paths: ]; const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: tools, input: "What is the weather like in Boston today?", tool_choice: "auto", @@ -17468,7 +17468,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -17514,7 +17514,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "function_call", @@ -17587,7 +17587,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "How much wood would a woodchuck chuck?", "reasoning": { "effort": "high" @@ -17598,7 +17598,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "How much wood would a woodchuck chuck?", reasoning: { effort: "high" @@ -17611,7 +17611,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input="How much wood would a woodchuck chuck?", reasoning={ "effort": "high" @@ -17624,7 +17624,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -17652,7 +17652,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -17799,7 +17799,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -17964,7 +17964,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -22478,6 +22478,48 @@ paths: "metadata": {"topic": "project-x"} } description: Update a conversation + /safety/alerts/{id}: + get: + summary: Retrieve a safety alert + operationId: Getprojectsafetyalert + parameters: + - name: id + in: path + description: Project safety alert ID + required: true + schema: + description: Project safety alert ID + type: string + maxLength: 38 + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/SafetyAlertResource' + x-oaiMeta: + name: Retrieve a safety alert + group: safety-alerts + path: retrieve + examples: + request: + curl: | + curl https://api.openai.com/v1/safety/alerts/alert_0123456789abcdef0123456789abcdef \ + -H "Authorization: Bearer $OPENAI_API_KEY" + response: | + { + "id": "alert_0123456789abcdef0123456789abcdef", + "object": "safety.alert", + "created_at": 1787659200, + "request_id": "req_123", + "response_id": "resp_123", + "model": "gpt-6-astra", + "request_paused": true, + "error_type": "potentially_unintended_data_access", + "reason": "Potentially unintended data access." + } + description: Get a safety alert belonging to the authenticated API project. /organization/spend_limit: get: summary: Retrieve organization spend limit @@ -23556,7 +23598,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Tell me a joke." }' javascript: | @@ -23565,7 +23607,7 @@ paths: const client = new OpenAI(); const response = await client.responses.inputTokens.count({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "Tell me a joke.", }); @@ -23576,7 +23618,7 @@ paths: client = OpenAI() response = client.responses.input_tokens.count( - model="gpt-5.6-sol", + model="gpt-6-astra", input="Tell me a joke." ) print(response.input_tokens) @@ -23594,7 +23636,7 @@ paths: func main() { client := openai.NewClient() response, err := client.Responses.InputTokens.Count(context.TODO(), responses.InputTokenCountParams{ - Model: "gpt-5.6-sol", + Model: "gpt-6-astra", Input: "Tell me a joke.", }) if err != nil { @@ -23607,7 +23649,7 @@ paths: openai = OpenAI::Client.new - response = openai.responses.input_tokens.count(model: "gpt-5.6-sol", input: "Tell me a joke.") + response = openai.responses.input_tokens.count(model: "gpt-6-astra", input: "Tell me a joke.") puts(response) java: | @@ -23625,7 +23667,7 @@ paths: OpenAIClient client = OpenAIOkHttpClient.fromEnv(); InputTokenCountParams params = InputTokenCountParams.builder() - .model("gpt-5.6-sol") + .model("gpt-6-astra") .input("Tell me a joke.") .build(); @@ -23670,7 +23712,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -23699,7 +23741,7 @@ paths: // Compact the previous response if you are running out of tokens const compactedResponse = await openai.responses.compact({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -23731,7 +23773,7 @@ paths: client = OpenAI() compacted_response = client.responses.compact( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -24921,7 +24963,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Tell me a three sentence bedtime story about a unicorn." }' javascript: | @@ -24930,7 +24972,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "Tell me a three sentence bedtime story about a unicorn." }); @@ -24941,7 +24983,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input="Tell me a three sentence bedtime story about a unicorn." ) @@ -24951,7 +24993,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -24969,7 +25011,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -25024,7 +25066,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -25044,7 +25086,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -25067,7 +25109,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -25090,7 +25132,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -25118,7 +25160,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -25173,7 +25215,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -25194,7 +25236,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -25217,7 +25259,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -25247,7 +25289,7 @@ paths: "instructions": null, "max_output_tokens": null, "max_tool_calls": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "id": "msg_686eef60d3e081a29283bdcbc4322fd90e34c516d176ff86", @@ -25305,7 +25347,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "tools": [{ "type": "web_search_preview" }], "input": "What was a positive news story from today?" }' @@ -25315,7 +25357,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: [{ type: "web_search_preview" }], input: "What was a positive news story from today?", }); @@ -25327,7 +25369,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=[{ "type": "web_search_preview" }], input="What was a positive news story from today?", ) @@ -25339,7 +25381,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -25367,7 +25409,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "web_search_call", @@ -25462,7 +25504,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "tools": [{ "type": "file_search", "vector_store_ids": ["vs_1234567890"], @@ -25476,7 +25518,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: [{ type: "file_search", vector_store_ids: ["vs_1234567890"], @@ -25492,7 +25534,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=[{ "type": "file_search", "vector_store_ids": ["vs_1234567890"], @@ -25508,7 +25550,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -25539,7 +25581,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "file_search_call", @@ -25665,7 +25707,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "instructions": "You are a helpful assistant.", "input": "Hello!", "stream": true @@ -25676,7 +25718,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", instructions="You are a helpful assistant.", input="Hello!", stream=True @@ -25690,7 +25732,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", instructions: "You are a helpful assistant.", input: "Hello!", stream: true, @@ -25707,7 +25749,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -25729,10 +25771,10 @@ paths: } response: | event: response.created - data: {"type":"response.created","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.created","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.in_progress - data: {"type":"response.in_progress","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} + data: {"type":"response.in_progress","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"in_progress","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}} event: response.output_item.added data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"in_progress","role":"assistant","content":[]}} @@ -25755,7 +25797,7 @@ paths: data: {"type":"response.output_item.done","output_index":0,"item":{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}} event: response.completed - data: {"type":"response.completed","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"completed","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-5.6-sol","output":[{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":37,"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":48},"user":null,"metadata":{}}} + data: {"type":"response.completed","response":{"id":"resp_67c9fdcecf488190bdd9a0409de3a1ec07b8b0ad4e5eb654","object":"response","created_at":1741290958,"status":"completed","error":null,"incomplete_details":null,"instructions":"You are a helpful assistant.","max_output_tokens":null,"model":"gpt-6-astra","output":[{"id":"msg_67c9fdcf37fc8190ba82116e33fb28c507b8b0ad4e5eb654","type":"message","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":37,"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":48},"user":null,"metadata":{}}} - title: Functions request: curl: | @@ -25763,7 +25805,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "What is the weather like in Boston today?", "tools": [ { @@ -25813,7 +25855,7 @@ paths: ] response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", tools=tools, input="What is the weather like in Boston today?", tool_choice="auto" @@ -25845,7 +25887,7 @@ paths: ]; const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", tools: tools, input: "What is the weather like in Boston today?", tool_choice: "auto", @@ -25857,7 +25899,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -25903,7 +25945,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "function_call", @@ -25976,7 +26018,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "How much wood would a woodchuck chuck?", "reasoning": { "effort": "high" @@ -25987,7 +26029,7 @@ paths: const openai = new OpenAI(); const response = await openai.responses.create({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "How much wood would a woodchuck chuck?", reasoning: { effort: "high" @@ -26000,7 +26042,7 @@ paths: client = OpenAI() response = client.responses.create( - model="gpt-5.6-sol", + model="gpt-6-astra", input="How much wood would a woodchuck chuck?", reasoning={ "effort": "high" @@ -26013,7 +26055,7 @@ paths: using OpenAI.Responses; OpenAIResponseClient client = new( - model: "gpt-5.6-sol", + model: "gpt-6-astra", apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ); @@ -26041,7 +26083,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -26215,7 +26257,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -26406,7 +26448,7 @@ paths: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "type": "message", @@ -26486,7 +26528,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": [ { "role": "user", @@ -26515,7 +26557,7 @@ paths: // Compact the previous response if you are running out of tokens const compactedResponse = await openai.responses.compact({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: [ { role: "user", @@ -26547,7 +26589,7 @@ paths: client = OpenAI() compacted_response = client.responses.compact( - model="gpt-5.6-sol", + model="gpt-6-astra", input=[ { "role": "user", @@ -26767,7 +26809,7 @@ paths: -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Tell me a joke." }' javascript: | @@ -26776,7 +26818,7 @@ paths: const client = new OpenAI(); const response = await client.responses.inputTokens.count({ - model: "gpt-5.6-sol", + model: "gpt-6-astra", input: "Tell me a joke.", }); @@ -26787,7 +26829,7 @@ paths: client = OpenAI() response = client.responses.input_tokens.count( - model="gpt-5.6-sol", + model="gpt-6-astra", input="Tell me a joke." ) print(response.input_tokens) @@ -26805,7 +26847,7 @@ paths: func main() { client := openai.NewClient() response, err := client.Responses.InputTokens.Count(context.TODO(), responses.InputTokenCountParams{ - Model: "gpt-5.6-sol", + Model: "gpt-6-astra", Input: "Tell me a joke.", }) if err != nil { @@ -26818,7 +26860,7 @@ paths: openai = OpenAI::Client.new - response = openai.responses.input_tokens.count(model: "gpt-5.6-sol", input: "Tell me a joke.") + response = openai.responses.input_tokens.count(model: "gpt-6-astra", input: "Tell me a joke.") puts(response) java: | @@ -26836,7 +26878,7 @@ paths: OpenAIClient client = OpenAIOkHttpClient.fromEnv(); InputTokenCountParams params = InputTokenCountParams.builder() - .model("gpt-5.6-sol") + .model("gpt-6-astra") .input("Tell me a joke.") .build(); @@ -27033,6 +27075,28 @@ webhooks: application/json: schema: $ref: '#/components/schemas/WebhookResponseIncomplete' + safety_alert_created: + post: + responses: + '200': + description: Return any 2xx status code to acknowledge receipt. A 410 Gone response also stops retries; other non-2xx responses are retried. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookSafetyAlertCreated' + safety_org_alert_created: + post: + responses: + '200': + description: Return any 2xx status code to acknowledge receipt. A 410 Gone response also stops retries; other non-2xx responses are retried. + requestBody: + description: The event payload sent by the API. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookSafetyOrgAlertCreated' components: schemas: AddUploadPartRequest: @@ -28768,7 +28832,7 @@ components: model: type: string description: | - Model ID used to process the batch, like `gpt-5.6-sol`. OpenAI + Model ID used to process the batch, like `gpt-6-astra`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. @@ -28903,7 +28967,7 @@ components: "id": "batch_abc123", "object": "batch", "endpoint": "/v1/chat/completions", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "errors": null, "input_file_id": "file-abc123", "completion_window": "24h", @@ -29207,7 +29271,7 @@ components: { "object": "chat.completion", "id": "chatcmpl-AyPNinnUqUDYo9SAdA52NobMflmj2", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "created": 1738960610, "request_id": "req_ded8ab984ec4bf840f37566c1011c417", "tool_choice": null, @@ -30913,6 +30977,7 @@ components: - $ref: '#/components/schemas/ToolSearchCall' - $ref: '#/components/schemas/ToolSearchOutput' - $ref: '#/components/schemas/AdditionalTools' + - $ref: '#/components/schemas/ResponseConfigurationUpdate' - $ref: '#/components/schemas/ReasoningItem' - $ref: '#/components/schemas/Program' - $ref: '#/components/schemas/ProgramOutput' @@ -31037,7 +31102,7 @@ components: "value": 0.06, "currency": "usd" }, - "line_item": "gpt-5.6-sol, input_tokens", + "line_item": "gpt-6-astra, input_tokens", "project_id": "proj_abc", "quantity": 10000, "quantity_unit": "tokens" @@ -31268,7 +31333,7 @@ components: $ref: '#/components/schemas/ChatCompletionRequestMessage' model: description: | - Model ID used to generate the response, like `gpt-5.6-sol` or `o3`. OpenAI + Model ID used to generate the response, like `gpt-6-astra` or `o3`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. @@ -31657,7 +31722,7 @@ components: "id": "chatcmpl-B9MHDbslfkBeAs8l4bebGdFOJ6PeG", "object": "chat.completion", "created": 1741570283, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "choices": [ { "index": 0, @@ -31803,13 +31868,13 @@ components: name: The chat completion chunk object group: chat example: | - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"obfuscation":"r4N7vQ2m"} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],"obfuscation":"r4N7vQ2m"} - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"obfuscation":"p9K3xT6w"} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{"content":"Hello"},"logprobs":null,"finish_reason":null}],"obfuscation":"p9K3xT6w"} .... - {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-5.6-sol", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"obfuscation":""} + {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1694268190,"model":"gpt-6-astra", "system_fingerprint": "fp_44709d6fcb", "choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"obfuscation":""} CreateCompletionRequest: type: object properties: @@ -32381,17 +32446,17 @@ components: group: eval runs example: | { - "name": "gpt-5.6-sol", + "name": "gpt-6-astra", "data_source": { "type": "completions", "input_messages": { "type": "item_reference", "item_reference": "item.input" }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "source": { "type": "stored_completions", - "model": "gpt-5.6-sol" + "model": "gpt-6-astra" } } } @@ -32742,17 +32807,17 @@ components: group: eval runs example: | { - "name": "gpt-5.6-sol", + "name": "gpt-6-astra", "data_source": { "type": "responses", "input_messages": { "type": "item_reference", "item_reference": "item.input" }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "source": { "type": "responses", - "model": "gpt-5.6-sol" + "model": "gpt-6-astra" } } } @@ -34987,6 +35052,10 @@ components: type: string description: | The input for the custom tool call generated by the model. + async: + type: boolean + description: | + Whether the custom tool call runs asynchronously. required: - type - call_id @@ -35586,6 +35655,8 @@ components: - type: 'null' type: type: string + misalignment: + $ref: '#/components/schemas/MisalignmentErrorDetailsResource' required: - type - message @@ -35623,7 +35694,7 @@ components: Like: - Improve the quality of my chatbot - See how well my chatbot handles customer support - - Check if o4-mini is better at my usecase than gpt-5.6-sol + - Check if o4-mini is better at my usecase than gpt-6-astra properties: object: type: string @@ -36216,7 +36287,7 @@ components: example: | { "type": "responses", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "users": ["user1", "user2"], "tools": ["tool1", "tool2"], "instructions_search": "You are a coding assistant" @@ -36369,8 +36440,8 @@ components: "eval_id": "eval_67e579652b548190aaa83ada4b125f47", "report_url": "https://platform.openai.com/evaluations/eval_67e579652b548190aaa83ada4b125f47?run_id=evalrun_67e57965b480819094274e3a32235e4c", "status": "queued", - "model": "gpt-5.6-sol", - "name": "gpt-5.6-sol", + "model": "gpt-6-astra", + "name": "gpt-6-astra", "created_at": 1743092069, "result_counts": { "total": 0, @@ -36498,7 +36569,7 @@ components: } ] }, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "sampling_params": { "max_completions_tokens": 2048 } @@ -36784,7 +36855,7 @@ components: } ], "finish_reason": "stop", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "usage": { "total_tokens": 521, "completion_tokens": 2, @@ -36878,7 +36949,7 @@ components: } ], "finish_reason": "stop", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "usage": { "total_tokens": 521, "completion_tokens": 2, @@ -36993,7 +37064,7 @@ components: model: anyOf: - type: string - description: An optional model to filter by (e.g., 'gpt-5.6-sol'). + description: An optional model to filter by (e.g., 'gpt-6-astra'). - type: 'null' created_after: anyOf: @@ -37018,7 +37089,7 @@ components: example: | { "type": "stored_completions", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "created_after": 1668124800, "created_before": 1668124900, "limit": 100, @@ -37897,6 +37968,10 @@ components: - in_progress - completed - incomplete + async: + type: boolean + description: | + Whether the function tool call runs asynchronously. required: - type - call_id @@ -39751,6 +39826,7 @@ components: - $ref: '#/components/schemas/ToolSearchCallItemParam' - $ref: '#/components/schemas/ToolSearchOutputItemParam' - $ref: '#/components/schemas/AdditionalToolsItemParam' + - $ref: '#/components/schemas/ResponseConfigurationUpdateItemParam' - $ref: '#/components/schemas/ReasoningItem' - $ref: '#/components/schemas/CompactionSummaryItemParam' - $ref: '#/components/schemas/ImageGenToolCall' @@ -39784,6 +39860,7 @@ components: - $ref: '#/components/schemas/ToolSearchCall' - $ref: '#/components/schemas/ToolSearchOutput' - $ref: '#/components/schemas/AdditionalTools' + - $ref: '#/components/schemas/ResponseConfigurationUpdate' - $ref: '#/components/schemas/ReasoningItem' - $ref: '#/components/schemas/Program' - $ref: '#/components/schemas/ProgramOutput' @@ -41420,7 +41497,7 @@ components: name: The model object example: | { - "id": "gpt-5.6-sol", + "id": "gpt-6-astra", "object": "model", "created": 1686935002, "owned_by": "openai", @@ -41435,9 +41512,9 @@ components: - $ref: '#/components/schemas/ModelIdsResponses' - type: string - type: 'null' - description: Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. + description: Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. ModelIdsResponses: - example: gpt-5.6-sol + example: gpt-6-astra anyOf: - $ref: '#/components/schemas/ModelIdsShared' - type: string @@ -41463,7 +41540,7 @@ components: - gpt-daybreak-red-latest - gpt-5.6-cyber ModelIdsShared: - example: gpt-5.6-sol + example: gpt-6-astra anyOf: - type: string - $ref: '#/components/schemas/ChatModel' @@ -42773,7 +42850,7 @@ components: "object": "project.model_permissions", "mode": "allow_list", "model_ids": [ - "gpt-5.6-sol", + "gpt-6-astra", "o3" ] } @@ -52128,11 +52205,16 @@ components: properties: reason: type: string - description: The reason why the response is incomplete. + description: | + The reason why the response is incomplete. `steered` means + the response stopped at a safe output boundary after a + WebSocket `response.steer` event. The server can then create + a successor response automatically with the queued input. enum: - max_output_tokens - max_messages - content_filter + - steered - type: 'null' output: type: array @@ -52564,7 +52646,7 @@ components: "input": [], "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "id": "msg_123", @@ -52605,6 +52687,66 @@ components: }, "sequence_number": 1 } + ResponseConfigurationUpdate: + type: object + description: | + A configuration update that applies to subsequent responses until it is + replaced by another configuration update. + properties: + id: + type: string + description: The unique ID of the configuration update item. + example: cnfu_123 + type: + type: string + enum: + - configuration_update + description: The item type. Always `configuration_update`. + default: configuration_update + x-stainless-const: true + reasoning: + type: object + description: The reasoning configuration applied by this update. + properties: + effort: + $ref: '#/components/schemas/ReasoningEffort' + description: | + The reasoning effort used for subsequent responses until another + configuration update replaces it. + required: + - id + - type + ResponseConfigurationUpdateItemParam: + type: object + description: | + An update to the conversation's response configuration. The configuration + remains in effect for subsequent responses until it is replaced by another + configuration update. + properties: + id: + anyOf: + - type: string + description: The unique ID of the configuration update item. + example: cnfu_123 + - type: 'null' + type: + type: string + enum: + - configuration_update + description: The item type. Always `configuration_update`. + default: configuration_update + x-stainless-const: true + reasoning: + type: object + description: Updates to reasoning configuration. Only effort is supported. + properties: + effort: + $ref: '#/components/schemas/ReasoningEffort' + description: | + The reasoning effort to use for subsequent responses until another + configuration update replaces it. + required: + - type ResponseContentPartAddedEvent: type: object description: Emitted when a new content part is added. @@ -52750,7 +52892,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "parallel_tool_calls": true, "previous_response_id": null, @@ -52867,6 +53009,8 @@ components: type: string description: | A human-readable description of the error. + misalignment: + $ref: '#/components/schemas/MisalignmentErrorDetailsResource' required: - code - message @@ -52881,6 +53025,7 @@ components: - invalid_prompt - data_residency_mismatch - bio_policy + - misalignment_policy_violation - vector_store_timeout - invalid_image - invalid_image_format @@ -52985,7 +53130,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "previous_response_id": null, "reasoning_effort": null, @@ -53525,7 +53670,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "parallel_tool_calls": true, "previous_response_id": null, @@ -53554,6 +53699,10 @@ components: type: object description: | An event that is emitted when a response finishes as incomplete. + + Over WebSocket, steering can finish a response with + `response.incomplete_details.reason` set to `steered`, followed automatically + by a successor `response.created` that commits the queued steering input. properties: type: type: string @@ -53591,7 +53740,7 @@ components: }, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "previous_response_id": null, "reasoning_effort": null, @@ -54197,7 +54346,7 @@ components: - type: 'null' model: description: | - Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI + Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. @@ -54699,6 +54848,519 @@ components: "refusal": "final refusal text", "sequence_number": 1 } + ResponseSteerAcceptedEvent: + type: object + title: ResponseSteerAcceptedEvent + description: | + Emitted when steering input has been validated and queued. Acceptance means + the server owns the input, not that it has been applied. The successor's + `response.created` event is the commit point. If accepted input cannot be + committed, `response.steer.failed` returns it with the same steering ID. + + When the response stops for client-owned tool output or approval, the input + remains queued and `response.steer.pending` is emitted after + `response.completed`. Fill the pending event's `required_input` stubs with + saved results and send one matching explicit `response.create` per parent. + Do not resend accepted input while it is still queued. + properties: + type: + type: string + enum: + - response.steer.accepted + description: The event discriminator. Always `response.steer.accepted`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The accepted steering submission. + properties: + id: + type: string + description: The ID assigned to the steering submission. + previous_response_id: + type: string + description: The ID of the response being steered. + required: + - id + - previous_response_id + stream_id: + type: string + description: | + The WebSocket lane that emitted this event. This field is present when + the target response's `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + x-oaiMeta: + name: response.steer.accepted + group: responses + example: | + { + "type": "response.steer.accepted", + "sequence_number": 2, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123" + } + } + ResponseSteerErrorCode: + title: ResponseSteerErrorCode + description: | + A machine-readable steering error code. Clients should handle unknown + values because additional codes may be introduced. Known values include: + - `response_not_found`: The target response is not available on this connection. + - `invalid_input`: The event or input failed validation. + - `steering_not_supported`: The model or response execution mode does not support steering. + - `too_many_pending_steers`: Too much steering input is pending for the response. + - `response_already_completed`: The response completed and is no longer accepting steering input. + - `response_not_active`: The response is no longer accepting steering input. + - `successor_creation_failed`: The successor response could not be created. + anyOf: + - type: string + enum: + - response_not_found + - invalid_input + - steering_not_supported + - too_many_pending_steers + - response_already_completed + - response_not_active + - successor_creation_failed + - type: string + ResponseSteerEvent: + type: object + title: ResponseSteerEvent + additionalProperties: false + description: | + Queues user input to steer a response on this WebSocket connection. Input + can contain text, images, and files. Steering is supported only for + single-agent responses on models and execution modes that support steering. + Responses bound to a conversation or using automatic compaction do not + support steering. + + A `response.steer.accepted` event acknowledges that the server owns the + queued input, not that it has been applied. The successor's `response.created` + event is the commit point. Input that cannot be committed is returned in + `response.steer.failed`. + + Steering may cause the active response to finish at a safe output boundary + with `response.incomplete` and `incomplete_details.reason` set to `steered`, + followed automatically by a successor `response.created`. Normal completion + can also be followed by an automatic successor. Automatic successors inherit + the previous response's settings and continue from it with the queued input. + + If the response stops for client-owned tool output or approval, accepted + steering input remains queued and `response.steer.pending` is emitted after + `response.completed`. Fill the `required_input` stubs from that event with + saved tool results or approval decisions, and send one explicit + `response.create` per parent with the same `previous_response_id` and + WebSocket lane. Do not rerun tools or resend accepted steering input. The + queued input is prepended in submission order to that request's input, and + the explicit request retains its own settings. + + This event accepts only `type`, `previous_response_id`, and `input`. Do not + send `stream_id`; the target response determines the WebSocket lane. + properties: + type: + type: string + enum: + - response.steer + description: The event discriminator. Always `response.steer`. + x-stainless-const: true + previous_response_id: + type: string + description: The ID of the response to steer on this WebSocket connection. + input: + $ref: '#/components/schemas/ResponseSteerInput' + required: + - type + - previous_response_id + - input + x-oaiMeta: + name: response.steer + group: responses + example: | + { + "type": "response.steer", + "previous_response_id": "resp_123", + "input": [ + { + "type": "message", + "role": "user", + "content": [ + { + "type": "input_text", + "text": "Prioritize the database rollout." + } + ] + } + ] + } + ResponseSteerFailedEvent: + type: object + title: ResponseSteerFailedEvent + description: | + Emitted when steering input is rejected or cannot be committed to a + successor response. Returns the original, uncommitted input so the client + can carry it into `response.create` when appropriate. Invalid input must + be corrected before retrying. + + Failures after acceptance include the same steering ID. Failures before an + ID is allocated omit `steer.id`. A lost connection or missing acknowledgement + leaves the outcome unknown; it is not proof that the input was rejected. + properties: + type: + type: string + enum: + - response.steer.failed + description: The event discriminator. Always `response.steer.failed`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The steering submission that could not be committed. + properties: + id: + type: string + description: | + The ID assigned to the steering submission, if one was allocated. + previous_response_id: + type: string + description: The ID of the response that was targeted for steering. + input: + $ref: '#/components/schemas/ResponseSteerInput' + required: + - previous_response_id + - input + error: + type: object + description: Information about why the input could not be committed. + properties: + type: + type: string + enum: + - invalid_request_error + description: The error type. Always `invalid_request_error`. + x-stainless-const: true + code: + $ref: '#/components/schemas/ResponseSteerErrorCode' + message: + type: string + description: A human-readable description of the error. + required: + - type + - code + - message + stream_id: + type: string + description: | + The WebSocket lane that emitted this event, when the target response is + available and its `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + - error + x-oaiMeta: + name: response.steer.failed + group: responses + example: | + { + "type": "response.steer.failed", + "sequence_number": 5, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123", + "input": [ + { + "type": "message", + "role": "user", + "content": [ + { + "type": "input_text", + "text": "Prioritize the database rollout." + } + ] + } + ] + }, + "error": { + "type": "invalid_request_error", + "code": "successor_creation_failed", + "message": "We couldn't start the next response. Send this steering input again with response.create." + } + } + ResponseSteerInput: + title: ResponseSteerInput + description: | + Input to queue for a continuation of the response. Uses the same string or + input-item shape as `response.create.input`, with a non-empty array when + supplying input items. + + Steering accepts only messages with the `user` role. Each message may + contain only `type`, `role`, and `content`, with `content` as a string or an + array of `input_text`, `input_image`, and `input_file` parts. The optional + `type` must be `message`. Other roles, tool outputs, and item types are not + supported for steering. + anyOf: + - type: string + title: Text input + description: A text input, equivalent to a message with the `user` role. + - $ref: '#/components/schemas/ResponseSteerInputItemList' + ResponseSteerInputItem: + title: Response steer input item + anyOf: + - $ref: '#/components/schemas/UserMessageItemParam' + - $ref: '#/components/schemas/FunctionCallOutputItemParam' + discriminator: + propertyName: type + ResponseSteerInputItemList: + type: array + title: Response steer input item list + description: A non-empty list of message inputs to queue for the response. + minItems: 1 + items: + $ref: '#/components/schemas/ResponseSteerInputItem' + ResponseSteerPendingEvent: + type: object + title: ResponseSteerPendingEvent + description: | + Emitted when accepted steering input remains queued after the target + response completes. The server still owns the input. Do not resend it. + The successor's `response.created` event is the commit point. + + When `reason` is `waiting_for_required_input`, this event follows + `response.completed` while the response waits for the tool results or + approval decisions identified by `required_input`. Copy those stubs, fill + their result fields using the ordinary `response.create` input schemas, + and submit one continuation per parent with the same `previous_response_id` + and WebSocket lane. Use saved results without rerunning tools. The queued + steering input is prepended in submission order to the continuation's + input. That explicit request retains its own settings. + + This notification is emitted at most once per steering submission. Multiple + submissions for the same parent can report the same required inputs; they + do not each require a separate continuation. + properties: + type: + type: string + enum: + - response.steer.pending + description: The event discriminator. Always `response.steer.pending`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The steering submission that remains queued. + properties: + id: + type: string + description: The ID assigned to the steering submission. + previous_response_id: + type: string + description: The ID of the response being steered. + required: + - id + - previous_response_id + reason: + $ref: '#/components/schemas/ResponseSteerPendingReason' + required_input: + type: array + minItems: 1 + description: | + Input stubs identifying outstanding client-owned tool results or + approval decisions. Each stub contains identifying fields only; the + client supplies the result before including it in `response.create`. + items: + $ref: '#/components/schemas/ResponseSteerRequiredInput' + stream_id: + type: string + description: | + The WebSocket lane that emitted this event. This field is present when + the target response's `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + - reason + - required_input + x-oaiMeta: + name: response.steer.pending + group: responses + example: | + { + "type": "response.steer.pending", + "sequence_number": 10, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123" + }, + "reason": "waiting_for_required_input", + "required_input": [ + { + "type": "function_call_output", + "call_id": "call_789", + "name": "lookup" + } + ] + } + ResponseSteerPendingReason: + title: ResponseSteerPendingReason + description: | + An extensible enum describing why accepted steering input is still queued. + Clients should handle unknown values because additional reasons may be + introduced. Known values include: + - `waiting_for_required_input`: The response is waiting for the tool results or approval decisions identified by `required_input`. + anyOf: + - type: string + enum: + - waiting_for_required_input + - type: string + ResponseSteerRequiredInput: + title: ResponseSteerRequiredInput + description: | + An input stub identifying an outstanding client-owned tool result or + approval decision. Copy the stub and fill the result fields using the + corresponding `response.create` input schema. Use saved results without + rerunning the tool. The server does not supply results, approval decisions, + or safety acknowledgements in these stubs. + discriminator: + propertyName: type + anyOf: + - type: object + title: Required function tool call output + additionalProperties: false + description: | + Supply `output` using the function tool call output input schema. + properties: + type: + type: string + enum: + - function_call_output + x-stainless-const: true + call_id: + type: string + name: + type: string + required: + - type + - call_id + - name + - type: object + title: Required custom tool call output + additionalProperties: false + description: | + Supply `output` using the custom tool call output input schema. The + original custom tool call supplies the tool's name. + properties: + type: + type: string + enum: + - custom_tool_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required computer tool call output + additionalProperties: false + description: | + Supply `output` using the computer tool call output input schema, + including any required `acknowledged_safety_checks`. + properties: + type: + type: string + enum: + - computer_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required shell tool call output + additionalProperties: false + description: | + Supply `output` using the shell tool call output input schema. Each + output entry includes `stdout`, `stderr`, and `outcome`. + properties: + type: + type: string + enum: + - shell_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required apply patch tool call output + additionalProperties: false + description: | + Supply `status` and optional `output` using the apply patch tool call + output input schema. + properties: + type: + type: string + enum: + - apply_patch_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required tool search output + additionalProperties: false + description: | + Supply `tools` using the tool search output input schema, retaining + `execution: "client"`. + properties: + type: + type: string + enum: + - tool_search_output + x-stainless-const: true + call_id: + type: string + execution: + type: string + enum: + - client + x-stainless-const: true + required: + - type + - call_id + - execution + - type: object + title: Required MCP approval response + additionalProperties: false + description: | + Supply `approve` using the MCP approval response input schema. An + optional `reason` can be supplied when denying the request. The original + approval request identifies the tool and server. + properties: + type: + type: string + enum: + - mcp_approval_response + x-stainless-const: true + approval_request_id: + type: string + required: + - type + - approval_request_id ResponseStreamEvent: description: Event emitted while a response is streamed. anyOf: @@ -55109,6 +55771,7 @@ components: Client events accepted by the Responses WebSocket server. anyOf: - $ref: '#/components/schemas/ResponsesClientEventResponseCreate' + - $ref: '#/components/schemas/ResponseSteerEvent' ResponsesClientEventResponseCreate: allOf: - type: object @@ -55150,7 +55813,7 @@ components: { "type": "response.create", "stream_id": "agent_1", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Say hello." } ResponsesServerEvent: @@ -55466,6 +56129,10 @@ components: - title: ResponseWsIncomplete description: | An event that is emitted when a response finishes as incomplete. + + Over WebSocket, steering can finish a response with + `response.incomplete_details.reason` set to `steered`, followed automatically + by a successor `response.created` that commits the queued steering input. allOf: - $ref: '#/components/schemas/ResponseIncompleteEvent' - type: object @@ -55865,6 +56532,9 @@ components: when the originating `response.create` event supplied a `stream_id`. - $ref: '#/components/schemas/ResponseWsError' + - $ref: '#/components/schemas/ResponseSteerAcceptedEvent' + - $ref: '#/components/schemas/ResponseSteerPendingEvent' + - $ref: '#/components/schemas/ResponseSteerFailedEvent' ResponsesWebSocketStreamEvent: allOf: - anyOf: @@ -58772,7 +59442,7 @@ components: "project_id": "proj_abc", "user_id": "user-abc", "api_key_id": "key_abc", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "batch": false, "service_tier": "default" } @@ -59126,7 +59796,7 @@ components: "project_id": "proj_abc", "user_id": "user-abc", "api_key_id": "key_abc", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "context_level": "medium" } User: @@ -61332,77 +62002,108 @@ components: "id": "resp_abc123" } } - OAuthErrorCode: - anyOf: - - enum: - - invalid_grant - - invalid_subject_token - - type: string - BetaResponseStreamEvent: - description: Event emitted while a response is streamed. - anyOf: - - $ref: '#/components/schemas/BetaResponseAudioDeltaEvent' - - $ref: '#/components/schemas/BetaResponseAudioDoneEvent' - - $ref: '#/components/schemas/BetaResponseAudioTranscriptDeltaEvent' - - $ref: '#/components/schemas/BetaResponseAudioTranscriptDoneEvent' - - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCodeDeltaEvent' - - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCodeDoneEvent' - - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCompletedEvent' - - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallInProgressEvent' - - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallInterpretingEvent' - - $ref: '#/components/schemas/BetaResponseCompletedEvent' - - $ref: '#/components/schemas/BetaResponseContentPartAddedEvent' - - $ref: '#/components/schemas/BetaResponseContentPartDoneEvent' - - $ref: '#/components/schemas/BetaResponseCreatedEvent' - - $ref: '#/components/schemas/BetaResponseErrorEvent' - - $ref: '#/components/schemas/BetaResponseFileSearchCallCompletedEvent' - - $ref: '#/components/schemas/BetaResponseFileSearchCallInProgressEvent' - - $ref: '#/components/schemas/BetaResponseFileSearchCallSearchingEvent' - - $ref: '#/components/schemas/BetaResponseFunctionCallArgumentsDeltaEvent' - - $ref: '#/components/schemas/BetaResponseFunctionCallArgumentsDoneEvent' - - $ref: '#/components/schemas/BetaResponseShellCallCommandAddedStreamingEvent' - - $ref: '#/components/schemas/BetaResponseShellCallCommandDeltaStreamingEvent' - - $ref: '#/components/schemas/BetaResponseShellCallCommandDoneStreamingEvent' - - $ref: '#/components/schemas/BetaResponseShellCallOutputContentDeltaStreamingEvent' - x-stainless-skip: - - go - - $ref: '#/components/schemas/BetaResponseShellCallOutputContentDoneStreamingEvent' - - $ref: '#/components/schemas/BetaResponseInProgressEvent' - - $ref: '#/components/schemas/BetaResponseFailedEvent' - - $ref: '#/components/schemas/BetaResponseIncompleteEvent' - - $ref: '#/components/schemas/BetaResponseOutputItemAddedEvent' - - $ref: '#/components/schemas/BetaResponseOutputItemDoneEvent' - - $ref: '#/components/schemas/BetaResponseReasoningSummaryPartAddedEvent' - - $ref: '#/components/schemas/BetaResponseReasoningSummaryPartDoneEvent' - - $ref: '#/components/schemas/BetaResponseReasoningSummaryTextDeltaEvent' - - $ref: '#/components/schemas/BetaResponseReasoningSummaryTextDoneEvent' - - $ref: '#/components/schemas/BetaResponseReasoningTextDeltaEvent' - - $ref: '#/components/schemas/BetaResponseReasoningTextDoneEvent' - - $ref: '#/components/schemas/BetaResponseRefusalDeltaEvent' - - $ref: '#/components/schemas/BetaResponseRefusalDoneEvent' - - $ref: '#/components/schemas/BetaResponseTextDeltaEvent' - - $ref: '#/components/schemas/BetaResponseTextDoneEvent' - - $ref: '#/components/schemas/BetaResponseWebSearchCallCompletedEvent' - - $ref: '#/components/schemas/BetaResponseWebSearchCallInProgressEvent' - - $ref: '#/components/schemas/BetaResponseWebSearchCallSearchingEvent' - - $ref: '#/components/schemas/BetaResponseImageGenCallCompletedEvent' - - $ref: '#/components/schemas/BetaResponseImageGenCallGeneratingEvent' - - $ref: '#/components/schemas/BetaResponseImageGenCallInProgressEvent' - - $ref: '#/components/schemas/BetaResponseImageGenCallPartialImageEvent' - - $ref: '#/components/schemas/BetaResponseMCPCallArgumentsDeltaEvent' - - $ref: '#/components/schemas/BetaResponseMCPCallArgumentsDoneEvent' - - $ref: '#/components/schemas/BetaResponseMCPCallCompletedEvent' - - $ref: '#/components/schemas/BetaResponseMCPCallFailedEvent' - - $ref: '#/components/schemas/BetaResponseMCPCallInProgressEvent' - - $ref: '#/components/schemas/BetaResponseMCPListToolsCompletedEvent' - - $ref: '#/components/schemas/BetaResponseMCPListToolsFailedEvent' - - $ref: '#/components/schemas/BetaResponseMCPListToolsInProgressEvent' - - $ref: '#/components/schemas/BetaResponseOutputTextAnnotationAddedEvent' - - $ref: '#/components/schemas/BetaResponseQueuedEvent' - - $ref: '#/components/schemas/BetaResponseCustomToolCallInputDeltaEvent' - - $ref: '#/components/schemas/BetaResponseCustomToolCallInputDoneEvent' - discriminator: - propertyName: type + WebhookSafetyAlertCreated: + type: object + title: safety.alert.created + description: Sent when an approved safety alert is available for an API project. + required: + - id + - object + - created_at + - type + - data + properties: + id: + type: string + description: The unique ID of the webhook event. + object: + type: string + enum: + - event + x-stainless-const: true + description: Always `event`. + created_at: + type: integer + format: unixtime + description: The Unix timestamp in seconds when the event was created. + type: + type: string + enum: + - safety.alert.created + x-stainless-const: true + description: Always `safety.alert.created`. + data: + type: object + additionalProperties: false + required: + - id + properties: + id: + type: string + pattern: ^alert_[0-9a-f]{32}$ + description: The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. + x-oaiMeta: + name: safety.alert.created + group: webhook-events + example: | + { + "id": "evt_123", + "object": "event", + "created_at": 1787659200, + "type": "safety.alert.created", + "data": {"id": "alert_0123456789abcdef0123456789abcdef"} + } + WebhookSafetyOrgAlertCreated: + type: object + title: safety.org_alert.created + description: Sent when an approved safety alert is available for an enterprise workspace. + required: + - id + - object + - created_at + - type + - data + properties: + id: + type: string + description: The unique ID of the webhook event. + object: + type: string + enum: + - event + x-stainless-const: true + description: Always `event`. + created_at: + type: integer + format: unixtime + description: The Unix timestamp in seconds when the event was created. + type: + type: string + enum: + - safety.org_alert.created + x-stainless-const: true + description: Always `safety.org_alert.created`. + data: + type: object + additionalProperties: false + required: + - id + properties: + id: + type: string + pattern: ^alert_[0-9a-f]{32}$ + description: The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. + x-oaiMeta: + name: safety.org_alert.created + group: webhook-events + example: | + { + "id": "evt_123", + "object": "event", + "created_at": 1787659200, + "type": "safety.org_alert.created", + "data": {"id": "alert_0123456789abcdef0123456789abcdef"} + } ModerationInputType: type: string enum: @@ -62551,6 +63252,8 @@ components: name: type: string description: The name of the function to call. + async: + type: boolean description: anyOf: - type: string @@ -62939,6 +63642,9 @@ components: name: type: string description: The name of the custom tool, used to identify it in tool calls. + async: + type: boolean + description: Whether the tool response can be returned asynchronously versus immediately returned on next response creation. description: type: string description: Optional description of the custom tool, used to provide more context. @@ -62996,6 +63702,9 @@ components: - function default: function x-stainless-const: true + async: + type: boolean + description: Whether the tool response can be returned asynchronously versus immediately returned on next response creation. output_schema: anyOf: - additionalProperties: {} @@ -64773,6 +65482,36 @@ components: - object - metadata - created_at + _MisalignmentErrorType: + anyOf: + - type: string + - type: string + enum: + - potentially_unintended_data_transfer + - potentially_unintended_data_access + - potentially_unintended_destructive_activity + - other + _MisalignmentSteer: + properties: + message: + type: string + description: The public continuation instruction. + type: object + required: + - message + MisalignmentErrorDetailsResource: + properties: + error_type: + $ref: '#/components/schemas/_MisalignmentErrorType' + description: An optional classification; clients must accept additional values. + detailed_explanation: + type: string + description: The public explanation for this block. + steer: + $ref: '#/components/schemas/_MisalignmentSteer' + description: An optional public continuation instruction. + type: object + required: [] ImageGenOutputTokensDetails: properties: image_tokens: @@ -65200,6 +65939,53 @@ components: - object - deleted - id + SafetyAlertErrorType: + type: string + enum: + - potentially_unintended_data_transfer + - potentially_unintended_data_access + - potentially_unintended_destructive_activity + - other + SafetyAlertResource: + properties: + id: + type: string + object: + type: string + enum: + - safety.alert + default: safety.alert + x-stainless-const: true + created_at: + type: integer + format: unixtime + request_id: + type: string + response_id: + type: string + model: + type: string + request_paused: + type: boolean + description: Whether block registration succeeded for this request. This does not confirm that response execution stopped. + error_type: + $ref: '#/components/schemas/SafetyAlertErrorType' + reason: + anyOf: + - type: string + description: A customer-safe description derived from error_type, or null for zero data retention requests. + - type: 'null' + type: object + required: + - id + - object + - created_at + - request_id + - response_id + - model + - request_paused + - error_type + - reason SpendLimitCurrency: anyOf: - type: string @@ -65562,6 +66348,8 @@ components: message: type: string description: A human-readable description of the error that was returned. + misalignment: + $ref: '#/components/schemas/MisalignmentErrorDetailsResource' type: object required: - code @@ -67432,6 +68220,48 @@ components: - y title: Coordinate description: 'An x/y coordinate pair, e.g. `{ x: 100, y: 200 }`.' + UserMessageItemParam: + properties: + id: + anyOf: + - type: string + description: The unique ID of this message item. + example: msg_123 + - type: 'null' + type: + type: string + enum: + - message + description: The item type. Always `message`. + default: message + x-stainless-const: true + role: + type: string + enum: + - user + description: The message role. Always `user`. + default: user + x-stainless-const: true + content: + description: The message content, as an array of content parts. + anyOf: + - items: + $ref: '#/components/schemas/ResponseSteerInputContent' + description: A piece of message content, such as text, an image, or a file. + type: array + - type: string + maxLength: 10485760 + description: The message content, as a single string. + status: + anyOf: + - type: string + description: The status of the message item. + - type: 'null' + type: object + required: + - type + - role + - content ErrorPayload: properties: type: @@ -67457,6 +68287,8 @@ components: type: object description: The response headers that were emitted with the error, if any. x-oaiTypeLabel: map + misalignment: + $ref: '#/components/schemas/MisalignmentErrorDetailsResource' type: object required: - type @@ -68200,6 +69032,9 @@ components: name: type: string description: The name of the custom tool, used to identify it in tool calls. + async: + type: boolean + description: Whether the tool response can be returned asynchronously versus immediately returned on next response creation. description: type: string description: Optional description of the custom tool, used to provide more context. @@ -68294,6 +69129,9 @@ components: - function default: function x-stainless-const: true + async: + type: boolean + description: Whether the tool response can be returned asynchronously versus immediately returned on next response creation. output_schema: anyOf: - additionalProperties: {} @@ -69240,6 +70078,8 @@ components: name: type: string description: The name of the function to call. + async: + type: boolean description: anyOf: - type: string @@ -69452,6 +70292,7 @@ components: - $ref: '#/components/schemas/BetaToolSearchCallItemParam' - $ref: '#/components/schemas/BetaToolSearchOutputItemParam' - $ref: '#/components/schemas/BetaAdditionalToolsItemParam' + - $ref: '#/components/schemas/BetaResponseConfigurationUpdateItemParam' - $ref: '#/components/schemas/BetaReasoningItem' - $ref: '#/components/schemas/BetaCompactionSummaryItemParam' - $ref: '#/components/schemas/BetaImageGenToolCall' @@ -69510,6 +70351,10 @@ components: type: string description: | The input for the custom tool call generated by the model. + async: + type: boolean + description: | + Whether the custom tool call runs asynchronously. required: - type - call_id @@ -70817,6 +71662,42 @@ components: - text title: Summary text description: A summary text from the model. + BetaResponseConfigurationUpdateItemParam: + type: object + description: | + An update to the conversation's response configuration. The configuration + remains in effect for subsequent responses until it is replaced by another + configuration update. + properties: + agent: + anyOf: + - $ref: '#/components/schemas/Beta_AgentTagParam' + description: The agent that produced this item. + - type: 'null' + id: + anyOf: + - type: string + description: The unique ID of the configuration update item. + example: cnfu_123 + - type: 'null' + type: + type: string + enum: + - configuration_update + description: The item type. Always `configuration_update`. + default: configuration_update + x-stainless-const: true + reasoning: + type: object + description: Updates to reasoning configuration. Only effort is supported. + properties: + effort: + $ref: '#/components/schemas/BetaReasoningEffort' + description: | + The reasoning effort to use for subsequent responses until another + configuration update replaces it. + required: + - type BetaAdditionalToolsItemParam: properties: agent: @@ -71473,6 +72354,10 @@ components: - in_progress - completed - incomplete + async: + type: boolean + description: | + Whether the function tool call runs asynchronously. required: - type - call_id @@ -72605,9 +73490,9 @@ components: - $ref: '#/components/schemas/BetaModelIdsResponses' - type: string - type: 'null' - description: Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. + description: Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. BetaModelIdsResponses: - example: gpt-5.6-sol + example: gpt-6-astra anyOf: - $ref: '#/components/schemas/BetaModelIdsShared' - type: string @@ -72633,7 +73518,7 @@ components: - gpt-daybreak-red-latest - gpt-5.6-cyber BetaModelIdsShared: - example: gpt-5.6-sol + example: gpt-6-astra anyOf: - type: string - $ref: '#/components/schemas/ChatModel' @@ -72652,11 +73537,43 @@ components: - type: 'null' type: type: string + misalignment: + $ref: '#/components/schemas/BetaMisalignmentErrorDetailsResource' required: - type - message - param - code + BetaMisalignmentErrorDetailsResource: + properties: + error_type: + $ref: '#/components/schemas/Beta_MisalignmentErrorType' + description: An optional classification; clients must accept additional values. + detailed_explanation: + type: string + description: The public explanation for this block. + steer: + $ref: '#/components/schemas/Beta_MisalignmentSteer' + description: An optional public continuation instruction. + type: object + required: [] + Beta_MisalignmentSteer: + properties: + message: + type: string + description: The public continuation instruction. + type: object + required: + - message + Beta_MisalignmentErrorType: + anyOf: + - type: string + - type: string + enum: + - potentially_unintended_data_transfer + - potentially_unintended_data_access + - potentially_unintended_destructive_activity + - other BetaResponseItemList: type: object description: A list of Response items. @@ -72728,6 +73645,7 @@ components: - $ref: '#/components/schemas/BetaToolSearchCall' - $ref: '#/components/schemas/BetaToolSearchOutput' - $ref: '#/components/schemas/BetaAdditionalTools' + - $ref: '#/components/schemas/BetaResponseConfigurationUpdate' - $ref: '#/components/schemas/BetaReasoningItem' - $ref: '#/components/schemas/BetaProgram' - $ref: '#/components/schemas/BetaProgramOutput' @@ -73324,6 +74242,38 @@ components: - call_id - code - fingerprint + BetaResponseConfigurationUpdate: + type: object + description: | + A configuration update that applies to subsequent responses until it is + replaced by another configuration update. + properties: + agent: + $ref: '#/components/schemas/BetaAgentTag' + description: The agent that produced this item. + id: + type: string + description: The unique ID of the configuration update item. + example: cnfu_123 + type: + type: string + enum: + - configuration_update + description: The item type. Always `configuration_update`. + default: configuration_update + x-stainless-const: true + reasoning: + type: object + description: The reasoning configuration applied by this update. + properties: + effort: + $ref: '#/components/schemas/BetaReasoningEffort' + description: | + The reasoning effort used for subsequent responses until another + configuration update replaces it. + required: + - id + - type BetaAdditionalTools: properties: agent: @@ -74209,11 +75159,16 @@ components: properties: reason: type: string - description: The reason why the response is incomplete. + description: | + The reason why the response is incomplete. `steered` means + the response stopped at a safe output boundary after a + WebSocket `response.steer` event. The server can then create + a successor response automatically with the queued input. enum: - max_output_tokens - max_messages - content_filter + - steered - type: 'null' output: type: array @@ -74470,6 +75425,8 @@ components: type: string description: | A human-readable description of the error. + misalignment: + $ref: '#/components/schemas/BetaMisalignmentErrorDetailsResource' required: - code - message @@ -74484,6 +75441,7 @@ components: - invalid_prompt - data_residency_mismatch - bio_policy + - misalignment_policy_violation - vector_store_timeout - invalid_image - invalid_image_format @@ -74535,7 +75493,7 @@ components: - type: 'null' model: description: | - Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI + Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models. @@ -76089,7 +77047,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "parallel_tool_calls": true, "previous_response_id": null, @@ -76622,7 +77580,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "parallel_tool_calls": true, "previous_response_id": null, @@ -76814,7 +77772,7 @@ components: "input": [], "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [ { "id": "msg_123", @@ -77205,6 +78163,10 @@ components: type: object description: | An event that is emitted when a response finishes as incomplete. + + Over WebSocket, steering can finish a response with + `response.incomplete_details.reason` set to `steered`, followed automatically + by a successor `response.created` that commits the queued steering input. properties: agent: anyOf: @@ -77247,7 +78209,7 @@ components: }, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "previous_response_id": null, "reasoning_effort": null, @@ -77315,7 +78277,7 @@ components: "incomplete_details": null, "instructions": null, "max_output_tokens": null, - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "output": [], "previous_response_id": null, "reasoning_effort": null, @@ -77461,6 +78423,566 @@ components: "item_id": "ws_123", "sequence_number": 0 } + BetaResponseSteerFailedEvent: + type: object + title: ResponseSteerFailedEvent + description: | + Emitted when steering input is rejected or cannot be committed to a + successor response. Returns the original, uncommitted input so the client + can carry it into `response.create` when appropriate. Invalid input must + be corrected before retrying. + + Failures after acceptance include the same steering ID. Failures before an + ID is allocated omit `steer.id`. A lost connection or missing acknowledgement + leaves the outcome unknown; it is not proof that the input was rejected. + properties: + type: + type: string + enum: + - response.steer.failed + description: The event discriminator. Always `response.steer.failed`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The steering submission that could not be committed. + properties: + id: + type: string + description: | + The ID assigned to the steering submission, if one was allocated. + previous_response_id: + type: string + description: The ID of the response that was targeted for steering. + input: + $ref: '#/components/schemas/BetaResponseSteerInput' + required: + - previous_response_id + - input + error: + type: object + description: Information about why the input could not be committed. + properties: + type: + type: string + enum: + - invalid_request_error + description: The error type. Always `invalid_request_error`. + x-stainless-const: true + code: + $ref: '#/components/schemas/BetaResponseSteerErrorCode' + message: + type: string + description: A human-readable description of the error. + required: + - type + - code + - message + stream_id: + type: string + description: | + The WebSocket lane that emitted this event, when the target response is + available and its `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + - error + x-oaiMeta: + name: response.steer.failed + group: responses + example: | + { + "type": "response.steer.failed", + "sequence_number": 5, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123", + "input": [ + { + "type": "message", + "role": "user", + "content": [ + { + "type": "input_text", + "text": "Prioritize the database rollout." + } + ] + } + ] + }, + "error": { + "type": "invalid_request_error", + "code": "successor_creation_failed", + "message": "We couldn't start the next response. Send this steering input again with response.create." + } + } + BetaResponseSteerErrorCode: + title: ResponseSteerErrorCode + description: | + A machine-readable steering error code. Clients should handle unknown + values because additional codes may be introduced. Known values include: + - `response_not_found`: The target response is not available on this connection. + - `invalid_input`: The event or input failed validation. + - `steering_not_supported`: The model or response execution mode does not support steering. + - `too_many_pending_steers`: Too much steering input is pending for the response. + - `response_already_completed`: The response completed and is no longer accepting steering input. + - `response_not_active`: The response is no longer accepting steering input. + - `successor_creation_failed`: The successor response could not be created. + anyOf: + - type: string + enum: + - response_not_found + - invalid_input + - steering_not_supported + - too_many_pending_steers + - response_already_completed + - response_not_active + - successor_creation_failed + - type: string + BetaResponseSteerInput: + title: ResponseSteerInput + description: | + Input to queue for a continuation of the response. Uses the same string or + input-item shape as `response.create.input`, with a non-empty array when + supplying input items. + + Steering accepts only messages with the `user` role. Each message may + contain only `type`, `role`, and `content`, with `content` as a string or an + array of `input_text`, `input_image`, and `input_file` parts. The optional + `type` must be `message`. Other roles, tool outputs, and item types are not + supported for steering. + anyOf: + - type: string + title: Text input + description: A text input, equivalent to a message with the `user` role. + - $ref: '#/components/schemas/BetaResponseSteerInputItemList' + BetaResponseSteerInputItemList: + type: array + title: Response steer input item list + description: A non-empty list of message inputs to queue for the response. + minItems: 1 + items: + $ref: '#/components/schemas/BetaResponseSteerInputItem' + BetaResponseSteerInputItem: + title: Response steer input item + anyOf: + - $ref: '#/components/schemas/BetaUserMessageItemParam' + - $ref: '#/components/schemas/BetaFunctionCallOutputItemParam' + discriminator: + propertyName: type + BetaUserMessageItemParam: + properties: + agent: + anyOf: + - $ref: '#/components/schemas/Beta_AgentTagParam' + description: The agent that produced this item. + - type: 'null' + id: + anyOf: + - type: string + description: The unique ID of this message item. + example: msg_123 + - type: 'null' + type: + type: string + enum: + - message + description: The item type. Always `message`. + default: message + x-stainless-const: true + role: + type: string + enum: + - user + description: The message role. Always `user`. + default: user + x-stainless-const: true + content: + description: The message content, as an array of content parts. + anyOf: + - items: + $ref: '#/components/schemas/BetaResponseSteerInputContent' + description: A piece of message content, such as text, an image, or a file. + type: array + - type: string + maxLength: 10485760 + description: The message content, as a single string. + status: + anyOf: + - type: string + description: The status of the message item. + - type: 'null' + type: object + required: + - type + - role + - content + BetaResponseSteerPendingEvent: + type: object + title: ResponseSteerPendingEvent + description: | + Emitted when accepted steering input remains queued after the target + response completes. The server still owns the input. Do not resend it. + The successor's `response.created` event is the commit point. + + When `reason` is `waiting_for_required_input`, this event follows + `response.completed` while the response waits for the tool results or + approval decisions identified by `required_input`. Copy those stubs, fill + their result fields using the ordinary `response.create` input schemas, + and submit one continuation per parent with the same `previous_response_id` + and WebSocket lane. Use saved results without rerunning tools. The queued + steering input is prepended in submission order to the continuation's + input. That explicit request retains its own settings. + + This notification is emitted at most once per steering submission. Multiple + submissions for the same parent can report the same required inputs; they + do not each require a separate continuation. + properties: + type: + type: string + enum: + - response.steer.pending + description: The event discriminator. Always `response.steer.pending`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The steering submission that remains queued. + properties: + id: + type: string + description: The ID assigned to the steering submission. + previous_response_id: + type: string + description: The ID of the response being steered. + required: + - id + - previous_response_id + reason: + $ref: '#/components/schemas/BetaResponseSteerPendingReason' + required_input: + type: array + minItems: 1 + description: | + Input stubs identifying outstanding client-owned tool results or + approval decisions. Each stub contains identifying fields only; the + client supplies the result before including it in `response.create`. + items: + $ref: '#/components/schemas/BetaResponseSteerRequiredInput' + stream_id: + type: string + description: | + The WebSocket lane that emitted this event. This field is present when + the target response's `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + - reason + - required_input + x-oaiMeta: + name: response.steer.pending + group: responses + example: | + { + "type": "response.steer.pending", + "sequence_number": 10, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123" + }, + "reason": "waiting_for_required_input", + "required_input": [ + { + "type": "function_call_output", + "call_id": "call_789", + "name": "lookup" + } + ] + } + BetaResponseSteerRequiredInput: + title: ResponseSteerRequiredInput + description: | + An input stub identifying an outstanding client-owned tool result or + approval decision. Copy the stub and fill the result fields using the + corresponding `response.create` input schema. Use saved results without + rerunning the tool. The server does not supply results, approval decisions, + or safety acknowledgements in these stubs. + discriminator: + propertyName: type + anyOf: + - type: object + title: Required function tool call output + additionalProperties: false + description: | + Supply `output` using the function tool call output input schema. + properties: + type: + type: string + enum: + - function_call_output + x-stainless-const: true + call_id: + type: string + name: + type: string + required: + - type + - call_id + - name + - type: object + title: Required custom tool call output + additionalProperties: false + description: | + Supply `output` using the custom tool call output input schema. The + original custom tool call supplies the tool's name. + properties: + type: + type: string + enum: + - custom_tool_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required computer tool call output + additionalProperties: false + description: | + Supply `output` using the computer tool call output input schema, + including any required `acknowledged_safety_checks`. + properties: + type: + type: string + enum: + - computer_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required shell tool call output + additionalProperties: false + description: | + Supply `output` using the shell tool call output input schema. Each + output entry includes `stdout`, `stderr`, and `outcome`. + properties: + type: + type: string + enum: + - shell_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required apply patch tool call output + additionalProperties: false + description: | + Supply `status` and optional `output` using the apply patch tool call + output input schema. + properties: + type: + type: string + enum: + - apply_patch_call_output + x-stainless-const: true + call_id: + type: string + required: + - type + - call_id + - type: object + title: Required tool search output + additionalProperties: false + description: | + Supply `tools` using the tool search output input schema, retaining + `execution: "client"`. + properties: + type: + type: string + enum: + - tool_search_output + x-stainless-const: true + call_id: + type: string + execution: + type: string + enum: + - client + x-stainless-const: true + required: + - type + - call_id + - execution + - type: object + title: Required MCP approval response + additionalProperties: false + description: | + Supply `approve` using the MCP approval response input schema. An + optional `reason` can be supplied when denying the request. The original + approval request identifies the tool and server. + properties: + type: + type: string + enum: + - mcp_approval_response + x-stainless-const: true + approval_request_id: + type: string + required: + - type + - approval_request_id + BetaResponseSteerPendingReason: + title: ResponseSteerPendingReason + description: | + An extensible enum describing why accepted steering input is still queued. + Clients should handle unknown values because additional reasons may be + introduced. Known values include: + - `waiting_for_required_input`: The response is waiting for the tool results or approval decisions identified by `required_input`. + anyOf: + - type: string + enum: + - waiting_for_required_input + - type: string + BetaResponseSteerAcceptedEvent: + type: object + title: ResponseSteerAcceptedEvent + description: | + Emitted when steering input has been validated and queued. Acceptance means + the server owns the input, not that it has been applied. The successor's + `response.created` event is the commit point. If accepted input cannot be + committed, `response.steer.failed` returns it with the same steering ID. + + When the response stops for client-owned tool output or approval, the input + remains queued and `response.steer.pending` is emitted after + `response.completed`. Fill the pending event's `required_input` stubs with + saved results and send one matching explicit `response.create` per parent. + Do not resend accepted input while it is still queued. + properties: + type: + type: string + enum: + - response.steer.accepted + description: The event discriminator. Always `response.steer.accepted`. + x-stainless-const: true + sequence_number: + type: integer + description: The sequence number for this event. + steer: + type: object + description: The accepted steering submission. + properties: + id: + type: string + description: The ID assigned to the steering submission. + previous_response_id: + type: string + description: The ID of the response being steered. + required: + - id + - previous_response_id + stream_id: + type: string + description: | + The WebSocket lane that emitted this event. This field is present when + the target response's `response.create` event supplied a `stream_id`. + required: + - type + - sequence_number + - steer + x-oaiMeta: + name: response.steer.accepted + group: responses + example: | + { + "type": "response.steer.accepted", + "sequence_number": 2, + "steer": { + "id": "steer_456", + "previous_response_id": "resp_123" + } + } + BetaResponseSteerEvent: + type: object + title: ResponseSteerEvent + additionalProperties: false + description: | + Queues user input to steer a response on this WebSocket connection. Input + can contain text, images, and files. Steering is supported only for + single-agent responses on models and execution modes that support steering. + Responses bound to a conversation or using automatic compaction do not + support steering. + + A `response.steer.accepted` event acknowledges that the server owns the + queued input, not that it has been applied. The successor's `response.created` + event is the commit point. Input that cannot be committed is returned in + `response.steer.failed`. + + Steering may cause the active response to finish at a safe output boundary + with `response.incomplete` and `incomplete_details.reason` set to `steered`, + followed automatically by a successor `response.created`. Normal completion + can also be followed by an automatic successor. Automatic successors inherit + the previous response's settings and continue from it with the queued input. + + If the response stops for client-owned tool output or approval, accepted + steering input remains queued and `response.steer.pending` is emitted after + `response.completed`. Fill the `required_input` stubs from that event with + saved tool results or approval decisions, and send one explicit + `response.create` per parent with the same `previous_response_id` and + WebSocket lane. Do not rerun tools or resend accepted steering input. The + queued input is prepended in submission order to that request's input, and + the explicit request retains its own settings. + + This event accepts only `type`, `previous_response_id`, and `input`. Do not + send `stream_id`; the target response determines the WebSocket lane. + properties: + type: + type: string + enum: + - response.steer + description: The event discriminator. Always `response.steer`. + x-stainless-const: true + previous_response_id: + type: string + description: The ID of the response to steer on this WebSocket connection. + input: + $ref: '#/components/schemas/BetaResponseSteerInput' + required: + - type + - previous_response_id + - input + x-oaiMeta: + name: response.steer + group: responses + example: | + { + "type": "response.steer", + "previous_response_id": "resp_123", + "input": [ + { + "type": "message", + "role": "user", + "content": [ + { + "type": "input_text", + "text": "Prioritize the database rollout." + } + ] + } + ] + } BetaOutputAudio: type: object title: Output audio @@ -77885,6 +79407,10 @@ components: - title: BetaResponseWsIncomplete description: | An event that is emitted when a response finishes as incomplete. + + Over WebSocket, steering can finish a response with + `response.incomplete_details.reason` set to `steered`, followed automatically + by a successor `response.created` that commits the queued steering input. allOf: - $ref: '#/components/schemas/BetaResponseIncompleteEvent' - type: object @@ -78284,6 +79810,9 @@ components: when the originating `response.create` event supplied a `stream_id`. - $ref: '#/components/schemas/BetaResponseWsError' + - $ref: '#/components/schemas/BetaResponseSteerAcceptedEvent' + - $ref: '#/components/schemas/BetaResponseSteerPendingEvent' + - $ref: '#/components/schemas/BetaResponseSteerFailedEvent' - $ref: '#/components/schemas/BetaResponseInjectCreatedEvent' - $ref: '#/components/schemas/BetaResponseInjectFailedEvent' BetaResponseInjectFailedEvent: @@ -78466,6 +79995,8 @@ components: type: object description: The response headers that were emitted with the error, if any. x-oaiTypeLabel: map + misalignment: + $ref: '#/components/schemas/BetaMisalignmentErrorDetailsResource' type: object required: - type @@ -78551,6 +80082,7 @@ components: Client events accepted by the Responses WebSocket server. anyOf: - $ref: '#/components/schemas/BetaResponsesClientEventResponseCreate' + - $ref: '#/components/schemas/BetaResponseSteerEvent' - $ref: '#/components/schemas/BetaResponseInjectEvent' BetaResponseInjectEvent: type: object @@ -78634,7 +80166,7 @@ components: { "type": "response.create", "stream_id": "agent_1", - "model": "gpt-5.6-sol", + "model": "gpt-6-astra", "input": "Say hello." } BetaCreateResponse: @@ -78855,6 +80387,93 @@ components: type: integer minimum: 0 maximum: 20 + BetaResponseStreamEvent: + description: Event emitted while a response is streamed. + anyOf: + - $ref: '#/components/schemas/BetaResponseAudioDeltaEvent' + - $ref: '#/components/schemas/BetaResponseAudioDoneEvent' + - $ref: '#/components/schemas/BetaResponseAudioTranscriptDeltaEvent' + - $ref: '#/components/schemas/BetaResponseAudioTranscriptDoneEvent' + - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCodeDeltaEvent' + - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCodeDoneEvent' + - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallCompletedEvent' + - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallInProgressEvent' + - $ref: '#/components/schemas/BetaResponseCodeInterpreterCallInterpretingEvent' + - $ref: '#/components/schemas/BetaResponseCompletedEvent' + - $ref: '#/components/schemas/BetaResponseContentPartAddedEvent' + - $ref: '#/components/schemas/BetaResponseContentPartDoneEvent' + - $ref: '#/components/schemas/BetaResponseCreatedEvent' + - $ref: '#/components/schemas/BetaResponseErrorEvent' + - $ref: '#/components/schemas/BetaResponseFileSearchCallCompletedEvent' + - $ref: '#/components/schemas/BetaResponseFileSearchCallInProgressEvent' + - $ref: '#/components/schemas/BetaResponseFileSearchCallSearchingEvent' + - $ref: '#/components/schemas/BetaResponseFunctionCallArgumentsDeltaEvent' + - $ref: '#/components/schemas/BetaResponseFunctionCallArgumentsDoneEvent' + - $ref: '#/components/schemas/BetaResponseShellCallCommandAddedStreamingEvent' + - $ref: '#/components/schemas/BetaResponseShellCallCommandDeltaStreamingEvent' + - $ref: '#/components/schemas/BetaResponseShellCallCommandDoneStreamingEvent' + - $ref: '#/components/schemas/BetaResponseShellCallOutputContentDeltaStreamingEvent' + x-stainless-skip: + - go + - $ref: '#/components/schemas/BetaResponseShellCallOutputContentDoneStreamingEvent' + - $ref: '#/components/schemas/BetaResponseInProgressEvent' + - $ref: '#/components/schemas/BetaResponseFailedEvent' + - $ref: '#/components/schemas/BetaResponseIncompleteEvent' + - $ref: '#/components/schemas/BetaResponseOutputItemAddedEvent' + - $ref: '#/components/schemas/BetaResponseOutputItemDoneEvent' + - $ref: '#/components/schemas/BetaResponseReasoningSummaryPartAddedEvent' + - $ref: '#/components/schemas/BetaResponseReasoningSummaryPartDoneEvent' + - $ref: '#/components/schemas/BetaResponseReasoningSummaryTextDeltaEvent' + - $ref: '#/components/schemas/BetaResponseReasoningSummaryTextDoneEvent' + - $ref: '#/components/schemas/BetaResponseReasoningTextDeltaEvent' + - $ref: '#/components/schemas/BetaResponseReasoningTextDoneEvent' + - $ref: '#/components/schemas/BetaResponseRefusalDeltaEvent' + - $ref: '#/components/schemas/BetaResponseRefusalDoneEvent' + - $ref: '#/components/schemas/BetaResponseTextDeltaEvent' + - $ref: '#/components/schemas/BetaResponseTextDoneEvent' + - $ref: '#/components/schemas/BetaResponseWebSearchCallCompletedEvent' + - $ref: '#/components/schemas/BetaResponseWebSearchCallInProgressEvent' + - $ref: '#/components/schemas/BetaResponseWebSearchCallSearchingEvent' + - $ref: '#/components/schemas/BetaResponseImageGenCallCompletedEvent' + - $ref: '#/components/schemas/BetaResponseImageGenCallGeneratingEvent' + - $ref: '#/components/schemas/BetaResponseImageGenCallInProgressEvent' + - $ref: '#/components/schemas/BetaResponseImageGenCallPartialImageEvent' + - $ref: '#/components/schemas/BetaResponseMCPCallArgumentsDeltaEvent' + - $ref: '#/components/schemas/BetaResponseMCPCallArgumentsDoneEvent' + - $ref: '#/components/schemas/BetaResponseMCPCallCompletedEvent' + - $ref: '#/components/schemas/BetaResponseMCPCallFailedEvent' + - $ref: '#/components/schemas/BetaResponseMCPCallInProgressEvent' + - $ref: '#/components/schemas/BetaResponseMCPListToolsCompletedEvent' + - $ref: '#/components/schemas/BetaResponseMCPListToolsFailedEvent' + - $ref: '#/components/schemas/BetaResponseMCPListToolsInProgressEvent' + - $ref: '#/components/schemas/BetaResponseOutputTextAnnotationAddedEvent' + - $ref: '#/components/schemas/BetaResponseQueuedEvent' + - $ref: '#/components/schemas/BetaResponseCustomToolCallInputDeltaEvent' + - $ref: '#/components/schemas/BetaResponseCustomToolCallInputDoneEvent' + discriminator: + propertyName: type + OAuthErrorCode: + anyOf: + - enum: + - invalid_grant + - invalid_subject_token + - type: string + ResponseSteerInputContent: + discriminator: + propertyName: type + description: A piece of message content, such as text, an image, or a file. + anyOf: + - $ref: '#/components/schemas/InputTextContentParam' + - $ref: '#/components/schemas/InputImageContentParamAutoParam' + - $ref: '#/components/schemas/InputFileContentParam' + BetaResponseSteerInputContent: + discriminator: + propertyName: type + description: A piece of message content, such as text, an image, or a file. + anyOf: + - $ref: '#/components/schemas/BetaInputTextContentParam' + - $ref: '#/components/schemas/BetaInputImageContentParamAutoParam' + - $ref: '#/components/schemas/BetaInputFileContentParam' RealtimeConnectParams: type: object properties: @@ -78984,6 +80603,7 @@ components: ChatModel: type: string enum: + - gpt-6-astra - gpt-5.6-sol - gpt-5.6-terra - gpt-5.6-luna @@ -79608,11 +81228,24 @@ x-oaiMeta: - type: object key: ResponsesClientEventResponseCreate path: + - type: object + key: ResponseSteerEvent + path: - id: responses-websocket-server-events title: Server events (WebSocket only) description: | Events emitted only over a Responses API WebSocket connection. navigationGroup: responses + sections: + - type: object + key: ResponseSteerAcceptedEvent + path: + - type: object + key: ResponseSteerPendingEvent + path: + - type: object + key: ResponseSteerFailedEvent + path: - id: responses-websocket-shared-events title: Server events description: | @@ -79767,6 +81400,19 @@ x-oaiMeta: - type: object key: ResponseErrorEvent path: + - id: safety-alerts + title: Safety Alerts + description: | + Retrieve approved safety alerts with an API key. Project keys require + `api.safety.alerts.read` and can read alerts from their project. + navigationGroup: endpoints + sections: + - type: endpoint + key: Getprojectsafetyalert + path: retrieve + - type: object + key: SafetyAlertResource + path: object - id: webhook-events title: Webhook Events description: | @@ -79824,6 +81470,12 @@ x-oaiMeta: - type: object key: WebhookLiveCallIncoming path: + - type: object + key: WebhookSafetyAlertCreated + path: + - type: object + key: WebhookSafetyOrgAlertCreated + path: - id: images-streaming title: Image Streaming description: | diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt index d2352b66f..66aedbcde 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClient.kt @@ -22,6 +22,7 @@ import com.openai.services.blocking.ModelService import com.openai.services.blocking.ModerationService import com.openai.services.blocking.RealtimeService import com.openai.services.blocking.ResponseService +import com.openai.services.blocking.SafetyService import com.openai.services.blocking.SkillService import com.openai.services.blocking.UploadService import com.openai.services.blocking.VectorStoreService @@ -104,6 +105,8 @@ interface OpenAIClient { fun vectorStores(): VectorStoreService + fun safety(): SafetyService + fun webhooks(): WebhookService fun beta(): BetaService @@ -194,6 +197,8 @@ interface OpenAIClient { fun vectorStores(): VectorStoreService.WithRawResponse + fun safety(): SafetyService.WithRawResponse + fun webhooks(): WebhookService.WithRawResponse fun beta(): BetaService.WithRawResponse diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt index d4fb531ee..bea9ab2e8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsync.kt @@ -22,6 +22,7 @@ import com.openai.services.async.ModelServiceAsync import com.openai.services.async.ModerationServiceAsync import com.openai.services.async.RealtimeServiceAsync import com.openai.services.async.ResponseServiceAsync +import com.openai.services.async.SafetyServiceAsync import com.openai.services.async.SkillServiceAsync import com.openai.services.async.UploadServiceAsync import com.openai.services.async.VectorStoreServiceAsync @@ -104,6 +105,8 @@ interface OpenAIClientAsync { fun vectorStores(): VectorStoreServiceAsync + fun safety(): SafetyServiceAsync + fun webhooks(): WebhookServiceAsync fun beta(): BetaServiceAsync @@ -196,6 +199,8 @@ interface OpenAIClientAsync { fun vectorStores(): VectorStoreServiceAsync.WithRawResponse + fun safety(): SafetyServiceAsync.WithRawResponse + fun webhooks(): WebhookServiceAsync.WithRawResponse fun beta(): BetaServiceAsync.WithRawResponse diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt index 77c7ddeeb..282b14967 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientAsyncImpl.kt @@ -42,6 +42,8 @@ import com.openai.services.async.RealtimeServiceAsync import com.openai.services.async.RealtimeServiceAsyncImpl import com.openai.services.async.ResponseServiceAsync import com.openai.services.async.ResponseServiceAsyncImpl +import com.openai.services.async.SafetyServiceAsync +import com.openai.services.async.SafetyServiceAsyncImpl import com.openai.services.async.SkillServiceAsync import com.openai.services.async.SkillServiceAsyncImpl import com.openai.services.async.UploadServiceAsync @@ -115,6 +117,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl VectorStoreServiceAsyncImpl(clientOptionsWithUserAgent) } + private val safety: SafetyServiceAsync by lazy { + SafetyServiceAsyncImpl(clientOptionsWithUserAgent) + } + private val webhooks: WebhookServiceAsync by lazy { WebhookServiceAsyncImpl(clientOptionsWithUserAgent) } @@ -206,6 +212,8 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl override fun vectorStores(): VectorStoreServiceAsync = vectorStores + override fun safety(): SafetyServiceAsync = safety + override fun webhooks(): WebhookServiceAsync = webhooks override fun beta(): BetaServiceAsync = beta @@ -288,6 +296,10 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl VectorStoreServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val safety: SafetyServiceAsync.WithRawResponse by lazy { + SafetyServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + private val webhooks: WebhookServiceAsync.WithRawResponse by lazy { WebhookServiceAsyncImpl.WithRawResponseImpl(clientOptions) } @@ -383,6 +395,8 @@ class OpenAIClientAsyncImpl(private val clientOptions: ClientOptions) : OpenAICl override fun vectorStores(): VectorStoreServiceAsync.WithRawResponse = vectorStores + override fun safety(): SafetyServiceAsync.WithRawResponse = safety + override fun webhooks(): WebhookServiceAsync.WithRawResponse = webhooks override fun beta(): BetaServiceAsync.WithRawResponse = beta diff --git a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt index d5e487234..b61366687 100644 --- a/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt +++ b/openai-java-core/src/main/kotlin/com/openai/client/OpenAIClientImpl.kt @@ -42,6 +42,8 @@ import com.openai.services.blocking.RealtimeService import com.openai.services.blocking.RealtimeServiceImpl import com.openai.services.blocking.ResponseService import com.openai.services.blocking.ResponseServiceImpl +import com.openai.services.blocking.SafetyService +import com.openai.services.blocking.SafetyServiceImpl import com.openai.services.blocking.SkillService import com.openai.services.blocking.SkillServiceImpl import com.openai.services.blocking.UploadService @@ -107,6 +109,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient VectorStoreServiceImpl(clientOptionsWithUserAgent) } + private val safety: SafetyService by lazy { SafetyServiceImpl(clientOptionsWithUserAgent) } + private val webhooks: WebhookService by lazy { WebhookServiceImpl(clientOptionsWithUserAgent) } private val beta: BetaService by lazy { BetaServiceImpl(clientOptionsWithUserAgent) } @@ -185,6 +189,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient override fun vectorStores(): VectorStoreService = vectorStores + override fun safety(): SafetyService = safety + override fun webhooks(): WebhookService = webhooks override fun beta(): BetaService = beta @@ -266,6 +272,10 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient VectorStoreServiceImpl.WithRawResponseImpl(clientOptions) } + private val safety: SafetyService.WithRawResponse by lazy { + SafetyServiceImpl.WithRawResponseImpl(clientOptions) + } + private val webhooks: WebhookService.WithRawResponse by lazy { WebhookServiceImpl.WithRawResponseImpl(clientOptions) } @@ -361,6 +371,8 @@ class OpenAIClientImpl(private val clientOptions: ClientOptions) : OpenAIClient override fun vectorStores(): VectorStoreService.WithRawResponse = vectorStores + override fun safety(): SafetyService.WithRawResponse = safety + override fun webhooks(): WebhookService.WithRawResponse = webhooks override fun beta(): BetaService.WithRawResponse = beta diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt b/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt index e583c563a..28eafde75 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/ChatModel.kt @@ -20,6 +20,8 @@ class ChatModel @JsonCreator private constructor(private val value: JsonField Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -480,6 +485,7 @@ class ChatModel @JsonCreator private constructor(private val value: JsonField Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/ErrorObject.kt b/openai-java-core/src/main/kotlin/com/openai/models/ErrorObject.kt index a88950d5c..849ce6140 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/ErrorObject.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/ErrorObject.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -24,6 +25,7 @@ private constructor( private val message: JsonField, private val param: JsonField, private val type: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -33,7 +35,10 @@ private constructor( @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), @JsonProperty("param") @ExcludeMissing param: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(code, message, param, type, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, param, type, misalignment, mutableMapOf()) /** * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the @@ -59,6 +64,12 @@ private constructor( */ fun type(): String = type.getRequired("type") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -87,6 +98,15 @@ private constructor( */ @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -122,6 +142,7 @@ private constructor( private var message: JsonField? = null private var param: JsonField? = null private var type: JsonField? = null + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -130,6 +151,7 @@ private constructor( message = errorObject.message param = errorObject.param type = errorObject.type + misalignment = errorObject.misalignment additionalProperties = errorObject.additionalProperties.toMutableMap() } @@ -179,6 +201,19 @@ private constructor( */ fun type(type: JsonField) = apply { this.type = type } + fun misalignment(misalignment: Misalignment) = misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -219,6 +254,7 @@ private constructor( checkRequired("message", message), checkRequired("param", param), checkRequired("type", type), + misalignment, additionalProperties.toMutableMap(), ) } @@ -242,6 +278,7 @@ private constructor( message() param() type() + misalignment().ifPresent { it.validate() } validated = true } @@ -263,7 +300,594 @@ private constructor( (if (code.asKnown().isPresent) 1 else 0) + (if (message.asKnown().isPresent) 1 else 0) + (if (param.asKnown().isPresent) 1 else 0) + - (if (type.asKnown().isPresent) 1 else 0) + (if (type.asKnown().isPresent) 1 else 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) + + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(errorType: JsonField) = apply { this.errorType = errorType } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer(checkRequired("message", message), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -275,15 +899,16 @@ private constructor( message == other.message && param == other.param && type == other.type && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(code, message, param, type, additionalProperties) + Objects.hash(code, message, param, type, misalignment, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "ErrorObject{code=$code, message=$message, param=$param, type=$type, additionalProperties=$additionalProperties}" + "ErrorObject{code=$code, message=$message, param=$param, type=$type, misalignment=$misalignment, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/admin/organization/usage/UsageCostsParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/admin/organization/usage/UsageCostsParams.kt index d0e8f9bf7..ab590711d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/admin/organization/usage/UsageCostsParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/admin/organization/usage/UsageCostsParams.kt @@ -57,7 +57,7 @@ private constructor( /** * Return only costs for these exact line item names. Each value must match the complete - * `line_item` value, for example `gpt-5.6-sol, input_tokens`. + * `line_item` value, for example `gpt-6-astra, input_tokens`. */ fun lineItems(): Optional> = Optional.ofNullable(lineItems) @@ -198,7 +198,7 @@ private constructor( /** * Return only costs for these exact line item names. Each value must match the complete - * `line_item` value, for example `gpt-5.6-sol, input_tokens`. + * `line_item` value, for example `gpt-6-astra, input_tokens`. */ fun lineItems(lineItems: List?) = apply { this.lineItems = lineItems?.toMutableList() diff --git a/openai-java-core/src/main/kotlin/com/openai/models/batches/Batch.kt b/openai-java-core/src/main/kotlin/com/openai/models/batches/Batch.kt index 18931d524..644af02cd 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/batches/Batch.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/batches/Batch.kt @@ -269,7 +269,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to process the batch, like `gpt-5.6-sol`. OpenAI offers a wide range of models + * Model ID used to process the batch, like `gpt-6-astra`. OpenAI offers a wide range of models * with different capabilities, performance characteristics, and price points. Refer to the * [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -774,7 +774,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to process the batch, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to process the batch, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaCustomTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaCustomTool.kt index 56237cd82..89d62aacd 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaCustomTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaCustomTool.kt @@ -40,6 +40,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val format: JsonField, @@ -53,6 +54,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -60,7 +62,7 @@ private constructor( @ExcludeMissing description: JsonField = JsonMissing.of(), @JsonProperty("format") @ExcludeMissing format: JsonField = JsonMissing.of(), - ) : this(name, type, allowedCallers, deferLoading, description, format, mutableMapOf()) + ) : this(name, type, allowedCallers, async, deferLoading, description, format, mutableMapOf()) /** * The name of the custom tool, used to identify it in tool calls. @@ -92,6 +94,15 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * Whether the tool response can be returned asynchronously versus immediately returned on next + * response creation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this tool should be deferred and discovered via tool search. * @@ -132,6 +143,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -186,6 +204,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("custom") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var format: JsonField = JsonMissing.of() @@ -196,6 +215,7 @@ private constructor( name = betaCustomTool.name type = betaCustomTool.type allowedCallers = betaCustomTool.allowedCallers.map { it.toMutableList() } + async = betaCustomTool.async deferLoading = betaCustomTool.deferLoading description = betaCustomTool.description format = betaCustomTool.format @@ -258,6 +278,20 @@ private constructor( } } + /** + * Whether the tool response can be returned asynchronously versus immediately returned on + * next response creation. + */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this tool should be deferred and discovered via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -337,6 +371,7 @@ private constructor( checkRequired("name", name), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, format, @@ -366,6 +401,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() format().ifPresent { it.validate() } @@ -390,6 +426,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("custom")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (format.asKnown().getOrNull()?.validity() ?: 0) @@ -1163,6 +1200,7 @@ private constructor( name == other.name && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && format == other.format && @@ -1174,6 +1212,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, format, @@ -1184,5 +1223,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BetaCustomTool{name=$name, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, format=$format, additionalProperties=$additionalProperties}" + "BetaCustomTool{name=$name, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, format=$format, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaFunctionTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaFunctionTool.kt index 1d851850c..36439f7cf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaFunctionTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaFunctionTool.kt @@ -32,6 +32,7 @@ private constructor( private val strict: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val outputSchema: JsonField, @@ -49,6 +50,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -64,6 +66,7 @@ private constructor( strict, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -116,6 +119,12 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this function is deferred and loaded via tool search. * @@ -173,6 +182,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -233,6 +249,7 @@ private constructor( private var strict: JsonField? = null private var type: JsonValue = JsonValue.from("function") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var outputSchema: JsonField = JsonMissing.of() @@ -245,6 +262,7 @@ private constructor( strict = betaFunctionTool.strict type = betaFunctionTool.type allowedCallers = betaFunctionTool.allowedCallers.map { it.toMutableList() } + async = betaFunctionTool.async deferLoading = betaFunctionTool.deferLoading description = betaFunctionTool.description outputSchema = betaFunctionTool.outputSchema @@ -343,6 +361,16 @@ private constructor( } } + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this function is deferred and loaded via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -437,6 +465,7 @@ private constructor( checkRequired("strict", strict), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, outputSchema, @@ -468,6 +497,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() outputSchema().ifPresent { it.validate() } @@ -494,6 +524,7 @@ private constructor( (if (strict.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (outputSchema.asKnown().getOrNull()?.validity() ?: 0) @@ -867,6 +898,7 @@ private constructor( strict == other.strict && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && outputSchema == other.outputSchema && @@ -880,6 +912,7 @@ private constructor( strict, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -890,5 +923,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BetaFunctionTool{name=$name, parameters=$parameters, strict=$strict, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, additionalProperties=$additionalProperties}" + "BetaFunctionTool{name=$name, parameters=$parameters, strict=$strict, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaNamespaceTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaNamespaceTool.kt index d5385565c..44b1e7899 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaNamespaceTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaNamespaceTool.kt @@ -553,6 +553,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val outputSchema: JsonField, @@ -568,6 +569,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -587,6 +589,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -622,6 +625,15 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * Whether the tool response can be returned asynchronously versus immediately returned + * on next response creation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this function should be deferred and discovered via tool search. * @@ -681,6 +693,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -749,6 +768,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("function") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var outputSchema: JsonField = JsonMissing.of() @@ -761,6 +781,7 @@ private constructor( name = function.name type = function.type allowedCallers = function.allowedCallers.map { it.toMutableList() } + async = function.async deferLoading = function.deferLoading description = function.description outputSchema = function.outputSchema @@ -827,6 +848,21 @@ private constructor( } } + /** + * Whether the tool response can be returned asynchronously versus immediately + * returned on next response creation. + */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this function should be deferred and discovered via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -948,6 +984,7 @@ private constructor( checkRequired("name", name), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, outputSchema, @@ -981,6 +1018,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() outputSchema().ifPresent { it.validate() } @@ -1007,6 +1045,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (outputSchema.asKnown().getOrNull()?.validity() ?: 0) + @@ -1283,6 +1322,7 @@ private constructor( name == other.name && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && outputSchema == other.outputSchema && @@ -1296,6 +1336,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -1308,7 +1349,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Function{name=$name, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}" + "Function{name=$name, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponse.kt index 3674b59c5..588b0ed9e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponse.kt @@ -256,7 +256,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -1085,7 +1085,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -2317,7 +2317,9 @@ private constructor( ) : this(reason, mutableMapOf()) /** - * The reason why the response is incomplete. + * The reason why the response is incomplete. `steered` means the response stopped at a safe + * output boundary after a WebSocket `response.steer` event. The server can then create a + * successor response automatically with the queued input. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -2361,7 +2363,11 @@ private constructor( additionalProperties = incompleteDetails.additionalProperties.toMutableMap() } - /** The reason why the response is incomplete. */ + /** + * The reason why the response is incomplete. `steered` means the response stopped at a + * safe output boundary after a WebSocket `response.steer` event. The server can then + * create a successor response automatically with the queued input. + */ fun reason(reason: Reason) = reason(JsonField.of(reason)) /** @@ -2437,7 +2443,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = (reason.asKnown().getOrNull()?.validity() ?: 0) - /** The reason why the response is incomplete. */ + /** + * The reason why the response is incomplete. `steered` means the response stopped at a safe + * output boundary after a WebSocket `response.steer` event. The server can then create a + * successor response automatically with the queued input. + */ class Reason @JsonCreator private constructor(private val value: JsonField) : Enum { /** @@ -2458,6 +2468,8 @@ private constructor( @JvmField val CONTENT_FILTER = of("content_filter") + @JvmField val STEERED = of("steered") + @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) } @@ -2466,6 +2478,7 @@ private constructor( MAX_OUTPUT_TOKENS, MAX_MESSAGES, CONTENT_FILTER, + STEERED, } /** @@ -2481,6 +2494,7 @@ private constructor( MAX_OUTPUT_TOKENS, MAX_MESSAGES, CONTENT_FILTER, + STEERED, /** * An enum member indicating that [Reason] was instantiated with an unknown value. */ @@ -2499,6 +2513,7 @@ private constructor( MAX_OUTPUT_TOKENS -> Value.MAX_OUTPUT_TOKENS MAX_MESSAGES -> Value.MAX_MESSAGES CONTENT_FILTER -> Value.CONTENT_FILTER + STEERED -> Value.STEERED else -> Value._UNKNOWN } @@ -2516,6 +2531,7 @@ private constructor( MAX_OUTPUT_TOKENS -> Known.MAX_OUTPUT_TOKENS MAX_MESSAGES -> Known.MAX_MESSAGES CONTENT_FILTER -> Known.CONTENT_FILTER + STEERED -> Known.STEERED else -> throw OpenAIInvalidDataException("Unknown Reason: $value") } @@ -2953,7 +2969,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -2972,6 +2988,8 @@ private constructor( companion object { + @JvmField val GPT_6_ASTRA = of("gpt-6-astra") + @JvmField val GPT_5_6_SOL = of("gpt-5.6-sol") @JvmField val GPT_5_6_TERRA = of("gpt-5.6-terra") @@ -3183,6 +3201,7 @@ private constructor( /** An enum containing [Model]'s known values. */ enum class Known { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -3297,6 +3316,7 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -3412,6 +3432,7 @@ private constructor( */ fun value(): Value = when (this) { + GPT_6_ASTRA -> Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -3528,6 +3549,7 @@ private constructor( */ fun known(): Known = when (this) { + GPT_6_ASTRA -> Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItem.kt new file mode 100644 index 000000000..9f5a58832 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItem.kt @@ -0,0 +1,805 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ +class BetaResponseConfigurationUpdateItem +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val type: JsonValue, + private val agent: JsonField, + private val reasoning: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + ) : this(id, type, agent, reasoning, mutableMapOf()) + + /** + * The unique ID of the configuration update item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The item type. Always `configuration_update`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun agent(): Optional = agent.getOptional("agent") + + /** + * The reasoning configuration applied by this update. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reasoning(): Optional = reasoning.getOptional("reasoning") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [agent]. + * + * Unlike [agent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning") @ExcludeMissing fun _reasoning(): JsonField = reasoning + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BetaResponseConfigurationUpdateItem]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseConfigurationUpdateItem]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var type: JsonValue = JsonValue.from("configuration_update") + private var agent: JsonField = JsonMissing.of() + private var reasoning: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + betaResponseConfigurationUpdateItem: BetaResponseConfigurationUpdateItem + ) = apply { + id = betaResponseConfigurationUpdateItem.id + type = betaResponseConfigurationUpdateItem.type + agent = betaResponseConfigurationUpdateItem.agent + reasoning = betaResponseConfigurationUpdateItem.reasoning + additionalProperties = + betaResponseConfigurationUpdateItem.additionalProperties.toMutableMap() + } + + /** The unique ID of the configuration update item. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The agent that produced this item. */ + fun agent(agent: Agent) = agent(JsonField.of(agent)) + + /** + * Sets [Builder.agent] to an arbitrary JSON value. + * + * You should usually call [Builder.agent] with a well-typed [Agent] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun agent(agent: JsonField) = apply { this.agent = agent } + + /** The reasoning configuration applied by this update. */ + fun reasoning(reasoning: Reasoning) = reasoning(JsonField.of(reasoning)) + + /** + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseConfigurationUpdateItem]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BetaResponseConfigurationUpdateItem = + BetaResponseConfigurationUpdateItem( + checkRequired("id", id), + type, + agent, + reasoning, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseConfigurationUpdateItem = apply { + if (validated) { + return@apply + } + + id() + _type().let { + if (it != JsonValue.from("configuration_update")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + agent().ifPresent { it.validate() } + reasoning().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("configuration_update")) 1 else 0 } + + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (reasoning.asKnown().getOrNull()?.validity() ?: 0) + + /** The agent that produced this item. */ + class Agent + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val agentName: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("agent_name") + @ExcludeMissing + agentName: JsonField = JsonMissing.of() + ) : this(agentName, mutableMapOf()) + + /** + * The canonical name of the agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun agentName(): String = agentName.getRequired("agent_name") + + /** + * Returns the raw JSON value of [agentName]. + * + * Unlike [agentName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent_name") @ExcludeMissing fun _agentName(): JsonField = agentName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Agent]. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Agent]. */ + class Builder internal constructor() { + + private var agentName: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agent: Agent) = apply { + agentName = agent.agentName + additionalProperties = agent.additionalProperties.toMutableMap() + } + + /** The canonical name of the agent that produced this item. */ + fun agentName(agentName: String) = agentName(JsonField.of(agentName)) + + /** + * Sets [Builder.agentName] to an arbitrary JSON value. + * + * You should usually call [Builder.agentName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agentName(agentName: JsonField) = apply { this.agentName = agentName } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Agent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Agent = + Agent(checkRequired("agentName", agentName), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Agent = apply { + if (validated) { + return@apply + } + + agentName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (agentName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Agent && + agentName == other.agentName && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(agentName, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Agent{agentName=$agentName, additionalProperties=$additionalProperties}" + } + + /** The reasoning configuration applied by this update. */ + class Reasoning + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val effort: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("effort") @ExcludeMissing effort: JsonField = JsonMissing.of() + ) : this(effort, mutableMapOf()) + + /** + * The reasoning effort used for subsequent responses until another configuration update + * replaces it. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun effort(): Optional = effort.getOptional("effort") + + /** + * Returns the raw JSON value of [effort]. + * + * Unlike [effort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("effort") @ExcludeMissing fun _effort(): JsonField = effort + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Reasoning]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Reasoning]. */ + class Builder internal constructor() { + + private var effort: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reasoning: Reasoning) = apply { + effort = reasoning.effort + additionalProperties = reasoning.additionalProperties.toMutableMap() + } + + /** + * The reasoning effort used for subsequent responses until another configuration update + * replaces it. + */ + fun effort(effort: Effort?) = effort(JsonField.ofNullable(effort)) + + /** Alias for calling [Builder.effort] with `effort.orElse(null)`. */ + fun effort(effort: Optional) = effort(effort.getOrNull()) + + /** + * Sets [Builder.effort] to an arbitrary JSON value. + * + * You should usually call [Builder.effort] with a well-typed [Effort] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun effort(effort: JsonField) = apply { this.effort = effort } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Reasoning]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Reasoning = Reasoning(effort, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Reasoning = apply { + if (validated) { + return@apply + } + + effort().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (effort.asKnown().getOrNull()?.validity() ?: 0) + + /** + * The reasoning effort used for subsequent responses until another configuration update + * replaces it. + */ + class Effort @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NONE = of("none") + + @JvmField val MINIMAL = of("minimal") + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val XHIGH = of("xhigh") + + @JvmField val MAX = of("max") + + @JvmStatic fun of(value: String) = Effort(JsonField.of(value)) + } + + /** An enum containing [Effort]'s known values. */ + enum class Known { + NONE, + MINIMAL, + LOW, + MEDIUM, + HIGH, + XHIGH, + MAX, + } + + /** + * An enum containing [Effort]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Effort] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NONE, + MINIMAL, + LOW, + MEDIUM, + HIGH, + XHIGH, + MAX, + /** + * An enum member indicating that [Effort] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NONE -> Value.NONE + MINIMAL -> Value.MINIMAL + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + XHIGH -> Value.XHIGH + MAX -> Value.MAX + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NONE -> Known.NONE + MINIMAL -> Known.MINIMAL + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + XHIGH -> Known.XHIGH + MAX -> Known.MAX + else -> throw OpenAIInvalidDataException("Unknown Effort: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Effort = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Effort && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Reasoning && + effort == other.effort && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(effort, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Reasoning{effort=$effort, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseConfigurationUpdateItem && + id == other.id && + type == other.type && + agent == other.agent && + reasoning == other.reasoning && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, type, agent, reasoning, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseConfigurationUpdateItem{id=$id, type=$type, agent=$agent, reasoning=$reasoning, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParam.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParam.kt new file mode 100644 index 000000000..ddfc6724c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParam.kt @@ -0,0 +1,799 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * An update to the conversation's response configuration. The configuration remains in effect for + * subsequent responses until it is replaced by another configuration update. + */ +class BetaResponseConfigurationUpdateItemParam +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val type: JsonValue, + private val id: JsonField, + private val agent: JsonField, + private val reasoning: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + ) : this(type, id, agent, reasoning, mutableMapOf()) + + /** + * The item type. Always `configuration_update`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of the configuration update item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * The agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun agent(): Optional = agent.getOptional("agent") + + /** + * Updates to reasoning configuration. Only effort is supported. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reasoning(): Optional = reasoning.getOptional("reasoning") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [agent]. + * + * Unlike [agent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning") @ExcludeMissing fun _reasoning(): JsonField = reasoning + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BetaResponseConfigurationUpdateItemParam]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseConfigurationUpdateItemParam]. */ + class Builder internal constructor() { + + private var type: JsonValue = JsonValue.from("configuration_update") + private var id: JsonField = JsonMissing.of() + private var agent: JsonField = JsonMissing.of() + private var reasoning: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + betaResponseConfigurationUpdateItemParam: BetaResponseConfigurationUpdateItemParam + ) = apply { + type = betaResponseConfigurationUpdateItemParam.type + id = betaResponseConfigurationUpdateItemParam.id + agent = betaResponseConfigurationUpdateItemParam.agent + reasoning = betaResponseConfigurationUpdateItemParam.reasoning + additionalProperties = + betaResponseConfigurationUpdateItemParam.additionalProperties.toMutableMap() + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The unique ID of the configuration update item. */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The agent that produced this item. */ + fun agent(agent: Agent?) = agent(JsonField.ofNullable(agent)) + + /** Alias for calling [Builder.agent] with `agent.orElse(null)`. */ + fun agent(agent: Optional) = agent(agent.getOrNull()) + + /** + * Sets [Builder.agent] to an arbitrary JSON value. + * + * You should usually call [Builder.agent] with a well-typed [Agent] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun agent(agent: JsonField) = apply { this.agent = agent } + + /** Updates to reasoning configuration. Only effort is supported. */ + fun reasoning(reasoning: Reasoning) = reasoning(JsonField.of(reasoning)) + + /** + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseConfigurationUpdateItemParam]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): BetaResponseConfigurationUpdateItemParam = + BetaResponseConfigurationUpdateItemParam( + type, + id, + agent, + reasoning, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseConfigurationUpdateItemParam = apply { + if (validated) { + return@apply + } + + _type().let { + if (it != JsonValue.from("configuration_update")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + agent().ifPresent { it.validate() } + reasoning().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + type.let { if (it == JsonValue.from("configuration_update")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (reasoning.asKnown().getOrNull()?.validity() ?: 0) + + /** The agent that produced this item. */ + class Agent + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val agentName: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("agent_name") + @ExcludeMissing + agentName: JsonField = JsonMissing.of() + ) : this(agentName, mutableMapOf()) + + /** + * The canonical name of the agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun agentName(): String = agentName.getRequired("agent_name") + + /** + * Returns the raw JSON value of [agentName]. + * + * Unlike [agentName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent_name") @ExcludeMissing fun _agentName(): JsonField = agentName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Agent]. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Agent]. */ + class Builder internal constructor() { + + private var agentName: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agent: Agent) = apply { + agentName = agent.agentName + additionalProperties = agent.additionalProperties.toMutableMap() + } + + /** The canonical name of the agent that produced this item. */ + fun agentName(agentName: String) = agentName(JsonField.of(agentName)) + + /** + * Sets [Builder.agentName] to an arbitrary JSON value. + * + * You should usually call [Builder.agentName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agentName(agentName: JsonField) = apply { this.agentName = agentName } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Agent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Agent = + Agent(checkRequired("agentName", agentName), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Agent = apply { + if (validated) { + return@apply + } + + agentName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (agentName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Agent && + agentName == other.agentName && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(agentName, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Agent{agentName=$agentName, additionalProperties=$additionalProperties}" + } + + /** Updates to reasoning configuration. Only effort is supported. */ + class Reasoning + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val effort: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("effort") @ExcludeMissing effort: JsonField = JsonMissing.of() + ) : this(effort, mutableMapOf()) + + /** + * The reasoning effort to use for subsequent responses until another configuration update + * replaces it. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun effort(): Optional = effort.getOptional("effort") + + /** + * Returns the raw JSON value of [effort]. + * + * Unlike [effort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("effort") @ExcludeMissing fun _effort(): JsonField = effort + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Reasoning]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Reasoning]. */ + class Builder internal constructor() { + + private var effort: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reasoning: Reasoning) = apply { + effort = reasoning.effort + additionalProperties = reasoning.additionalProperties.toMutableMap() + } + + /** + * The reasoning effort to use for subsequent responses until another configuration + * update replaces it. + */ + fun effort(effort: Effort?) = effort(JsonField.ofNullable(effort)) + + /** Alias for calling [Builder.effort] with `effort.orElse(null)`. */ + fun effort(effort: Optional) = effort(effort.getOrNull()) + + /** + * Sets [Builder.effort] to an arbitrary JSON value. + * + * You should usually call [Builder.effort] with a well-typed [Effort] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun effort(effort: JsonField) = apply { this.effort = effort } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Reasoning]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Reasoning = Reasoning(effort, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Reasoning = apply { + if (validated) { + return@apply + } + + effort().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (effort.asKnown().getOrNull()?.validity() ?: 0) + + /** + * The reasoning effort to use for subsequent responses until another configuration update + * replaces it. + */ + class Effort @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val NONE = of("none") + + @JvmField val MINIMAL = of("minimal") + + @JvmField val LOW = of("low") + + @JvmField val MEDIUM = of("medium") + + @JvmField val HIGH = of("high") + + @JvmField val XHIGH = of("xhigh") + + @JvmField val MAX = of("max") + + @JvmStatic fun of(value: String) = Effort(JsonField.of(value)) + } + + /** An enum containing [Effort]'s known values. */ + enum class Known { + NONE, + MINIMAL, + LOW, + MEDIUM, + HIGH, + XHIGH, + MAX, + } + + /** + * An enum containing [Effort]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Effort] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + NONE, + MINIMAL, + LOW, + MEDIUM, + HIGH, + XHIGH, + MAX, + /** + * An enum member indicating that [Effort] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + NONE -> Value.NONE + MINIMAL -> Value.MINIMAL + LOW -> Value.LOW + MEDIUM -> Value.MEDIUM + HIGH -> Value.HIGH + XHIGH -> Value.XHIGH + MAX -> Value.MAX + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + NONE -> Known.NONE + MINIMAL -> Known.MINIMAL + LOW -> Known.LOW + MEDIUM -> Known.MEDIUM + HIGH -> Known.HIGH + XHIGH -> Known.XHIGH + MAX -> Known.MAX + else -> throw OpenAIInvalidDataException("Unknown Effort: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Effort = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Effort && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Reasoning && + effort == other.effort && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(effort, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Reasoning{effort=$effort, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseConfigurationUpdateItemParam && + type == other.type && + id == other.id && + agent == other.agent && + reasoning == other.reasoning && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, id, agent, reasoning, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseConfigurationUpdateItemParam{type=$type, id=$id, agent=$agent, reasoning=$reasoning, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCall.kt index 7fbacb79b..ce01a4eeb 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCall.kt @@ -37,6 +37,7 @@ private constructor( private val type: JsonValue, private val id: JsonField, private val agent: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val additionalProperties: MutableMap, @@ -50,9 +51,10 @@ private constructor( @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @JsonProperty("namespace") @ExcludeMissing namespace: JsonField = JsonMissing.of(), - ) : this(callId, input, name, type, id, agent, caller, namespace, mutableMapOf()) + ) : this(callId, input, name, type, id, agent, async, caller, namespace, mutableMapOf()) /** * An identifier used to map this custom tool call to a tool call output. @@ -107,6 +109,14 @@ private constructor( */ fun agent(): Optional = agent.getOptional("agent") + /** + * Whether the custom tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -158,6 +168,13 @@ private constructor( */ @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -208,6 +225,7 @@ private constructor( private var type: JsonValue = JsonValue.from("custom_tool_call") private var id: JsonField = JsonMissing.of() private var agent: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -220,6 +238,7 @@ private constructor( type = betaResponseCustomToolCall.type id = betaResponseCustomToolCall.id agent = betaResponseCustomToolCall.agent + async = betaResponseCustomToolCall.async caller = betaResponseCustomToolCall.caller namespace = betaResponseCustomToolCall.namespace additionalProperties = betaResponseCustomToolCall.additionalProperties.toMutableMap() @@ -297,6 +316,17 @@ private constructor( */ fun agent(agent: JsonField) = apply { this.agent = agent } + /** Whether the custom tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) @@ -381,6 +411,7 @@ private constructor( type, id, agent, + async, caller, namespace, additionalProperties.toMutableMap(), @@ -412,6 +443,7 @@ private constructor( } id() agent().ifPresent { it.validate() } + async() caller().ifPresent { it.validate() } namespace() validated = true @@ -438,6 +470,7 @@ private constructor( type.let { if (it == JsonValue.from("custom_tool_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) @@ -1046,17 +1079,29 @@ private constructor( type == other.type && id == other.id && agent == other.agent && + async == other.async && caller == other.caller && namespace == other.namespace && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(callId, input, name, type, id, agent, caller, namespace, additionalProperties) + Objects.hash( + callId, + input, + name, + type, + id, + agent, + async, + caller, + namespace, + additionalProperties, + ) } override fun hashCode(): Int = hashCode override fun toString() = - "BetaResponseCustomToolCall{callId=$callId, input=$input, name=$name, type=$type, id=$id, agent=$agent, caller=$caller, namespace=$namespace, additionalProperties=$additionalProperties}" + "BetaResponseCustomToolCall{callId=$callId, input=$input, name=$name, type=$type, id=$id, agent=$agent, async=$async, caller=$caller, namespace=$namespace, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItem.kt index 3adaea2ca..39b2acf06 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItem.kt @@ -28,6 +28,7 @@ private constructor( private val type: JsonValue, private val id: JsonField, private val agent: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -45,6 +46,7 @@ private constructor( @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @@ -58,6 +60,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -73,6 +76,7 @@ private constructor( .type(type) .id(id) .agent(agent) + .async(async) .caller(caller) .namespace(namespace) .build() @@ -130,6 +134,14 @@ private constructor( */ fun agent(): Optional = agent.getOptional("agent") + /** + * Whether the custom tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -200,6 +212,13 @@ private constructor( @ExcludeMissing fun _agent(): JsonField = agent + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -268,6 +287,7 @@ private constructor( private var type: JsonValue = JsonValue.from("custom_tool_call") private var id: JsonField = JsonMissing.of() private var agent: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField? = null @@ -282,6 +302,7 @@ private constructor( type = betaResponseCustomToolCallItem.type id = betaResponseCustomToolCallItem.id agent = betaResponseCustomToolCallItem.agent + async = betaResponseCustomToolCallItem.async caller = betaResponseCustomToolCallItem.caller namespace = betaResponseCustomToolCallItem.namespace status = betaResponseCustomToolCallItem.status @@ -363,6 +384,17 @@ private constructor( */ fun agent(agent: JsonField) = apply { this.agent = agent } + /** Whether the custom tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: BetaResponseCustomToolCall.Caller?) = caller(JsonField.ofNullable(caller)) @@ -481,6 +513,7 @@ private constructor( type, id, agent, + async, caller, namespace, checkRequired("status", status), @@ -514,6 +547,7 @@ private constructor( } id() agent().ifPresent { it.validate() } + async() caller().ifPresent { it.validate() } namespace() status().validate() @@ -542,6 +576,7 @@ private constructor( type.let { if (it == JsonValue.from("custom_tool_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) + @@ -703,6 +738,7 @@ private constructor( type == other.type && id == other.id && agent == other.agent && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -718,6 +754,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -729,5 +766,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BetaResponseCustomToolCallItem{callId=$callId, input=$input, name=$name, type=$type, id=$id, agent=$agent, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" + "BetaResponseCustomToolCallItem{callId=$callId, input=$input, name=$name, type=$type, id=$id, agent=$agent, async=$async, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseError.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseError.kt index 420b92445..1c8ce45cf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseError.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseError.kt @@ -15,6 +15,7 @@ import com.openai.core.checkRequired import com.openai.errors.OpenAIInvalidDataException import java.util.Collections import java.util.Objects +import java.util.Optional import kotlin.jvm.optionals.getOrNull /** An error object returned when the model fails to generate a Response. */ @@ -23,6 +24,7 @@ class BetaResponseError private constructor( private val code: JsonField, private val message: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -30,7 +32,10 @@ private constructor( private constructor( @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), - ) : this(code, message, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, misalignment, mutableMapOf()) /** * The error code for the response. @@ -48,6 +53,12 @@ private constructor( */ fun message(): String = message.getRequired("message") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -62,6 +73,15 @@ private constructor( */ @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -93,12 +113,14 @@ private constructor( private var code: JsonField? = null private var message: JsonField? = null + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(betaResponseError: BetaResponseError) = apply { code = betaResponseError.code message = betaResponseError.message + misalignment = betaResponseError.misalignment additionalProperties = betaResponseError.additionalProperties.toMutableMap() } @@ -124,6 +146,19 @@ private constructor( */ fun message(message: JsonField) = apply { this.message = message } + fun misalignment(misalignment: Misalignment) = misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -160,6 +195,7 @@ private constructor( BetaResponseError( checkRequired("code", code), checkRequired("message", message), + misalignment, additionalProperties.toMutableMap(), ) } @@ -181,6 +217,7 @@ private constructor( code().validate() message() + misalignment().ifPresent { it.validate() } validated = true } @@ -199,7 +236,9 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (code.asKnown().getOrNull()?.validity() ?: 0) + (if (message.asKnown().isPresent) 1 else 0) + (code.asKnown().getOrNull()?.validity() ?: 0) + + (if (message.asKnown().isPresent) 1 else 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) /** The error code for the response. */ class Code @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -226,6 +265,8 @@ private constructor( @JvmField val BIO_POLICY = of("bio_policy") + @JvmField val MISALIGNMENT_POLICY_VIOLATION = of("misalignment_policy_violation") + @JvmField val VECTOR_STORE_TIMEOUT = of("vector_store_timeout") @JvmField val INVALID_IMAGE = of("invalid_image") @@ -266,6 +307,7 @@ private constructor( INVALID_PROMPT, DATA_RESIDENCY_MISMATCH, BIO_POLICY, + MISALIGNMENT_POLICY_VIOLATION, VECTOR_STORE_TIMEOUT, INVALID_IMAGE, INVALID_IMAGE_FORMAT, @@ -298,6 +340,7 @@ private constructor( INVALID_PROMPT, DATA_RESIDENCY_MISMATCH, BIO_POLICY, + MISALIGNMENT_POLICY_VIOLATION, VECTOR_STORE_TIMEOUT, INVALID_IMAGE, INVALID_IMAGE_FORMAT, @@ -331,6 +374,7 @@ private constructor( INVALID_PROMPT -> Value.INVALID_PROMPT DATA_RESIDENCY_MISMATCH -> Value.DATA_RESIDENCY_MISMATCH BIO_POLICY -> Value.BIO_POLICY + MISALIGNMENT_POLICY_VIOLATION -> Value.MISALIGNMENT_POLICY_VIOLATION VECTOR_STORE_TIMEOUT -> Value.VECTOR_STORE_TIMEOUT INVALID_IMAGE -> Value.INVALID_IMAGE INVALID_IMAGE_FORMAT -> Value.INVALID_IMAGE_FORMAT @@ -365,6 +409,7 @@ private constructor( INVALID_PROMPT -> Known.INVALID_PROMPT DATA_RESIDENCY_MISMATCH -> Known.DATA_RESIDENCY_MISMATCH BIO_POLICY -> Known.BIO_POLICY + MISALIGNMENT_POLICY_VIOLATION -> Known.MISALIGNMENT_POLICY_VIOLATION VECTOR_STORE_TIMEOUT -> Known.VECTOR_STORE_TIMEOUT INVALID_IMAGE -> Known.INVALID_IMAGE INVALID_IMAGE_FORMAT -> Known.INVALID_IMAGE_FORMAT @@ -444,6 +489,592 @@ private constructor( override fun toString() = value.toString() } + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(errorType: JsonField) = apply { this.errorType = errorType } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer(checkRequired("message", message), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -452,13 +1083,16 @@ private constructor( return other is BetaResponseError && code == other.code && message == other.message && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(code, message, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(code, message, misalignment, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "BetaResponseError{code=$code, message=$message, additionalProperties=$additionalProperties}" + "BetaResponseError{code=$code, message=$message, misalignment=$misalignment, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCall.kt index a6ce7640e..0e6fb65d5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCall.kt @@ -42,6 +42,7 @@ private constructor( private val type: JsonValue, private val id: JsonField, private val agent: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -56,10 +57,23 @@ private constructor( @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @JsonProperty("namespace") @ExcludeMissing namespace: JsonField = JsonMissing.of(), @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - ) : this(arguments, callId, name, type, id, agent, caller, namespace, status, mutableMapOf()) + ) : this( + arguments, + callId, + name, + type, + id, + agent, + async, + caller, + namespace, + status, + mutableMapOf(), + ) /** * A JSON string of the arguments to pass to the function. @@ -114,6 +128,14 @@ private constructor( */ fun agent(): Optional = agent.getOptional("agent") + /** + * Whether the function tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -174,6 +196,13 @@ private constructor( */ @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -231,6 +260,7 @@ private constructor( private var type: JsonValue = JsonValue.from("function_call") private var id: JsonField = JsonMissing.of() private var agent: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField = JsonMissing.of() @@ -244,6 +274,7 @@ private constructor( type = betaResponseFunctionToolCall.type id = betaResponseFunctionToolCall.id agent = betaResponseFunctionToolCall.agent + async = betaResponseFunctionToolCall.async caller = betaResponseFunctionToolCall.caller namespace = betaResponseFunctionToolCall.namespace status = betaResponseFunctionToolCall.status @@ -323,6 +354,17 @@ private constructor( */ fun agent(agent: JsonField) = apply { this.agent = agent } + /** Whether the function tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) @@ -421,6 +463,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -453,6 +496,7 @@ private constructor( } id() agent().ifPresent { it.validate() } + async() caller().ifPresent { it.validate() } namespace() status().ifPresent { it.validate() } @@ -480,6 +524,7 @@ private constructor( type.let { if (it == JsonValue.from("function_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) @@ -1233,6 +1278,7 @@ private constructor( type == other.type && id == other.id && agent == other.agent && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -1247,6 +1293,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -1257,5 +1304,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BetaResponseFunctionToolCall{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, agent=$agent, caller=$caller, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" + "BetaResponseFunctionToolCall{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, agent=$agent, async=$async, caller=$caller, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItem.kt index d1f83b063..5afe0fd8f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItem.kt @@ -32,6 +32,7 @@ private constructor( private val type: JsonValue, private val id: JsonField, private val agent: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -49,6 +50,7 @@ private constructor( @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @@ -64,6 +66,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -79,6 +82,7 @@ private constructor( .type(type) .id(id) .agent(agent) + .async(async) .caller(caller) .namespace(namespace) .status(status) @@ -137,6 +141,14 @@ private constructor( */ fun agent(): Optional = agent.getOptional("agent") + /** + * Whether the function tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -207,6 +219,13 @@ private constructor( @ExcludeMissing fun _agent(): JsonField = agent + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -276,6 +295,7 @@ private constructor( private var type: JsonValue = JsonValue.from("function_call") private var id: JsonField = JsonMissing.of() private var agent: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField = JsonMissing.of() @@ -291,6 +311,7 @@ private constructor( type = betaResponseFunctionToolCallItem.type id = betaResponseFunctionToolCallItem.id agent = betaResponseFunctionToolCallItem.agent + async = betaResponseFunctionToolCallItem.async caller = betaResponseFunctionToolCallItem.caller namespace = betaResponseFunctionToolCallItem.namespace status = betaResponseFunctionToolCallItem.status @@ -375,6 +396,17 @@ private constructor( this.agent = agent } + /** Whether the function tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: BetaResponseFunctionToolCall.Caller?) = caller(JsonField.ofNullable(caller)) @@ -496,6 +528,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -529,6 +562,7 @@ private constructor( } id() agent().ifPresent { it.validate() } + async() caller().ifPresent { it.validate() } namespace() status().ifPresent { it.validate() } @@ -557,6 +591,7 @@ private constructor( type.let { if (it == JsonValue.from("function_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) + @@ -718,6 +753,7 @@ private constructor( type == other.type && id == other.id && agent == other.agent && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -733,6 +769,7 @@ private constructor( type, id, agent, + async, caller, namespace, status, @@ -744,5 +781,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "BetaResponseFunctionToolCallItem{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, agent=$agent, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" + "BetaResponseFunctionToolCallItem{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, agent=$agent, async=$async, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEvent.kt index 9206b452a..63c5262aa 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEvent.kt @@ -17,7 +17,13 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** An event that is emitted when a response finishes as incomplete. */ +/** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set to + * `steered`, followed automatically by a successor `response.created` that commits the queued + * steering input. + */ class BetaResponseIncompleteEvent @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectEvent.kt index 1ab6c5857..5444da48c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectEvent.kt @@ -321,6 +321,13 @@ private constructor( fun addAdditionalToolsInput(tools: List) = addInput(BetaResponseInputItem.AdditionalTools.builder().tools(tools).build()) + /** + * Alias for calling [addInput] with + * `BetaResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addInput(configurationUpdate: BetaResponseConfigurationUpdateItemParam) = + addInput(BetaResponseInputItem.ofConfigurationUpdate(configurationUpdate)) + /** Alias for calling [addInput] with `BetaResponseInputItem.ofReasoning(reasoning)`. */ fun addInput(reasoning: BetaResponseReasoningItem) = addInput(BetaResponseInputItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectFailedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectFailedEvent.kt index fb7c80d39..659ac23b5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectFailedEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInjectFailedEvent.kt @@ -398,6 +398,13 @@ private constructor( fun addAdditionalToolsInput(tools: List) = addInput(BetaResponseInputItem.AdditionalTools.builder().tools(tools).build()) + /** + * Alias for calling [addInput] with + * `BetaResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addInput(configurationUpdate: BetaResponseConfigurationUpdateItemParam) = + addInput(BetaResponseInputItem.ofConfigurationUpdate(configurationUpdate)) + /** Alias for calling [addInput] with `BetaResponseInputItem.ofReasoning(reasoning)`. */ fun addInput(reasoning: BetaResponseReasoningItem) = addInput(BetaResponseInputItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInputItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInputItem.kt index c56995745..4f8e4ad6d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInputItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseInputItem.kt @@ -56,6 +56,7 @@ private constructor( private val toolSearchCall: ToolSearchCall? = null, private val toolSearchOutput: BetaResponseToolSearchOutputItemParam? = null, private val additionalTools: AdditionalTools? = null, + private val configurationUpdate: BetaResponseConfigurationUpdateItemParam? = null, private val reasoning: BetaResponseReasoningItem? = null, private val compaction: BetaResponseCompactionItemParam? = null, private val imageGenerationCall: ImageGenerationCall? = null, @@ -150,6 +151,13 @@ private constructor( fun additionalTools(): Optional = Optional.ofNullable(additionalTools) + /** + * An update to the conversation's response configuration. The configuration remains in effect + * for subsequent responses until it is replaced by another configuration update. + */ + fun configurationUpdate(): Optional = + Optional.ofNullable(configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -252,6 +260,8 @@ private constructor( fun isAdditionalTools(): Boolean = additionalTools != null + fun isConfigurationUpdate(): Boolean = configurationUpdate != null + fun isReasoning(): Boolean = reasoning != null fun isCompaction(): Boolean = compaction != null @@ -364,6 +374,13 @@ private constructor( fun asAdditionalTools(): AdditionalTools = additionalTools.getOrThrow("additionalTools") + /** + * An update to the conversation's response configuration. The configuration remains in effect + * for subsequent responses until it is replaced by another configuration update. + */ + fun asConfigurationUpdate(): BetaResponseConfigurationUpdateItemParam = + configurationUpdate.getOrThrow("configurationUpdate") + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -486,6 +503,7 @@ private constructor( toolSearchCall != null -> visitor.visitToolSearchCall(toolSearchCall) toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) additionalTools != null -> visitor.visitAdditionalTools(additionalTools) + configurationUpdate != null -> visitor.visitConfigurationUpdate(configurationUpdate) reasoning != null -> visitor.visitReasoning(reasoning) compaction != null -> visitor.visitCompaction(compaction) imageGenerationCall != null -> visitor.visitImageGenerationCall(imageGenerationCall) @@ -590,6 +608,12 @@ private constructor( additionalTools.validate() } + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItemParam + ) { + configurationUpdate.validate() + } + override fun visitReasoning(reasoning: BetaResponseReasoningItem) { reasoning.validate() } @@ -740,6 +764,10 @@ private constructor( override fun visitAdditionalTools(additionalTools: AdditionalTools) = additionalTools.validity() + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItemParam + ) = configurationUpdate.validity() + override fun visitReasoning(reasoning: BetaResponseReasoningItem) = reasoning.validity() @@ -823,6 +851,7 @@ private constructor( toolSearchCall == other.toolSearchCall && toolSearchOutput == other.toolSearchOutput && additionalTools == other.additionalTools && + configurationUpdate == other.configurationUpdate && reasoning == other.reasoning && compaction == other.compaction && imageGenerationCall == other.imageGenerationCall && @@ -862,6 +891,7 @@ private constructor( toolSearchCall, toolSearchOutput, additionalTools, + configurationUpdate, reasoning, compaction, imageGenerationCall, @@ -906,6 +936,8 @@ private constructor( toolSearchCall != null -> "BetaResponseInputItem{toolSearchCall=$toolSearchCall}" toolSearchOutput != null -> "BetaResponseInputItem{toolSearchOutput=$toolSearchOutput}" additionalTools != null -> "BetaResponseInputItem{additionalTools=$additionalTools}" + configurationUpdate != null -> + "BetaResponseInputItem{configurationUpdate=$configurationUpdate}" reasoning != null -> "BetaResponseInputItem{reasoning=$reasoning}" compaction != null -> "BetaResponseInputItem{compaction=$compaction}" imageGenerationCall != null -> @@ -1033,6 +1065,14 @@ private constructor( fun ofAdditionalTools(additionalTools: AdditionalTools) = BetaResponseInputItem(additionalTools = additionalTools) + /** + * An update to the conversation's response configuration. The configuration remains in + * effect for subsequent responses until it is replaced by another configuration update. + */ + @JvmStatic + fun ofConfigurationUpdate(configurationUpdate: BetaResponseConfigurationUpdateItemParam) = + BetaResponseInputItem(configurationUpdate = configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1208,6 +1248,14 @@ private constructor( fun visitAdditionalTools(additionalTools: AdditionalTools): T + /** + * An update to the conversation's response configuration. The configuration remains in + * effect for subsequent responses until it is replaced by another configuration update. + */ + fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItemParam + ): T + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1393,6 +1441,14 @@ private constructor( BetaResponseInputItem(additionalTools = it, _json = json) } ?: BetaResponseInputItem(_json = json) } + "configuration_update" -> { + return tryDeserialize( + node, + jacksonTypeRef(), + ) + ?.let { BetaResponseInputItem(configurationUpdate = it, _json = json) } + ?: BetaResponseInputItem(_json = json) + } "reasoning" -> { return tryDeserialize(node, jacksonTypeRef())?.let { BetaResponseInputItem(reasoning = it, _json = json) @@ -1529,6 +1585,8 @@ private constructor( value.toolSearchCall != null -> generator.writeObject(value.toolSearchCall) value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) value.additionalTools != null -> generator.writeObject(value.additionalTools) + value.configurationUpdate != null -> + generator.writeObject(value.configurationUpdate) value.reasoning != null -> generator.writeObject(value.reasoning) value.compaction != null -> generator.writeObject(value.compaction) value.imageGenerationCall != null -> diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseItem.kt index c62dbc216..5e555fc1f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseItem.kt @@ -50,6 +50,7 @@ private constructor( private val toolSearchCall: BetaResponseToolSearchCall? = null, private val toolSearchOutput: BetaResponseToolSearchOutputItem? = null, private val additionalTools: AdditionalTools? = null, + private val configurationUpdate: BetaResponseConfigurationUpdateItem? = null, private val reasoning: BetaResponseReasoningItem? = null, private val program: Program? = null, private val programOutput: ProgramOutput? = null, @@ -129,6 +130,13 @@ private constructor( fun additionalTools(): Optional = Optional.ofNullable(additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun configurationUpdate(): Optional = + Optional.ofNullable(configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -226,6 +234,8 @@ private constructor( fun isAdditionalTools(): Boolean = additionalTools != null + fun isConfigurationUpdate(): Boolean = configurationUpdate != null + fun isReasoning(): Boolean = reasoning != null fun isProgram(): Boolean = program != null @@ -318,6 +328,13 @@ private constructor( fun asAdditionalTools(): AdditionalTools = additionalTools.getOrThrow("additionalTools") + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun asConfigurationUpdate(): BetaResponseConfigurationUpdateItem = + configurationUpdate.getOrThrow("configurationUpdate") + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -437,6 +454,7 @@ private constructor( toolSearchCall != null -> visitor.visitToolSearchCall(toolSearchCall) toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) additionalTools != null -> visitor.visitAdditionalTools(additionalTools) + configurationUpdate != null -> visitor.visitConfigurationUpdate(configurationUpdate) reasoning != null -> visitor.visitReasoning(reasoning) program != null -> visitor.visitProgram(program) programOutput != null -> visitor.visitProgramOutput(programOutput) @@ -541,6 +559,12 @@ private constructor( additionalTools.validate() } + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItem + ) { + configurationUpdate.validate() + } + override fun visitReasoning(reasoning: BetaResponseReasoningItem) { reasoning.validate() } @@ -688,6 +712,10 @@ private constructor( override fun visitAdditionalTools(additionalTools: AdditionalTools) = additionalTools.validity() + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItem + ) = configurationUpdate.validity() + override fun visitReasoning(reasoning: BetaResponseReasoningItem) = reasoning.validity() @@ -767,6 +795,7 @@ private constructor( toolSearchCall == other.toolSearchCall && toolSearchOutput == other.toolSearchOutput && additionalTools == other.additionalTools && + configurationUpdate == other.configurationUpdate && reasoning == other.reasoning && program == other.program && programOutput == other.programOutput && @@ -803,6 +832,7 @@ private constructor( toolSearchCall, toolSearchOutput, additionalTools, + configurationUpdate, reasoning, program, programOutput, @@ -842,6 +872,8 @@ private constructor( toolSearchCall != null -> "BetaResponseItem{toolSearchCall=$toolSearchCall}" toolSearchOutput != null -> "BetaResponseItem{toolSearchOutput=$toolSearchOutput}" additionalTools != null -> "BetaResponseItem{additionalTools=$additionalTools}" + configurationUpdate != null -> + "BetaResponseItem{configurationUpdate=$configurationUpdate}" reasoning != null -> "BetaResponseItem{reasoning=$reasoning}" program != null -> "BetaResponseItem{program=$program}" programOutput != null -> "BetaResponseItem{programOutput=$programOutput}" @@ -950,6 +982,14 @@ private constructor( fun ofAdditionalTools(additionalTools: AdditionalTools) = BetaResponseItem(additionalTools = additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + @JvmStatic + fun ofConfigurationUpdate(configurationUpdate: BetaResponseConfigurationUpdateItem) = + BetaResponseItem(configurationUpdate = configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1100,6 +1140,12 @@ private constructor( fun visitAdditionalTools(additionalTools: AdditionalTools): T + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + fun visitConfigurationUpdate(configurationUpdate: BetaResponseConfigurationUpdateItem): T + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1280,6 +1326,14 @@ private constructor( BetaResponseItem(additionalTools = it, _json = json) } ?: BetaResponseItem(_json = json) } + "configuration_update" -> { + return tryDeserialize( + node, + jacksonTypeRef(), + ) + ?.let { BetaResponseItem(configurationUpdate = it, _json = json) } + ?: BetaResponseItem(_json = json) + } "reasoning" -> { return tryDeserialize(node, jacksonTypeRef())?.let { BetaResponseItem(reasoning = it, _json = json) @@ -1413,6 +1467,8 @@ private constructor( value.toolSearchCall != null -> generator.writeObject(value.toolSearchCall) value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) value.additionalTools != null -> generator.writeObject(value.additionalTools) + value.configurationUpdate != null -> + generator.writeObject(value.configurationUpdate) value.reasoning != null -> generator.writeObject(value.reasoning) value.program != null -> generator.writeObject(value.program) value.programOutput != null -> generator.writeObject(value.programOutput) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEvent.kt new file mode 100644 index 000000000..6b47fa006 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEvent.kt @@ -0,0 +1,538 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when steering input has been validated and queued. Acceptance means the server owns the + * input, not that it has been applied. The successor's `response.created` event is the commit + * point. If accepted input cannot be committed, `response.steer.failed` returns it with the same + * steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued and + * `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` per + * parent. Do not resend accepted input while it is still queued. + */ +class BetaResponseSteerAcceptedEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The accepted steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.accepted`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.accepted") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event. This field is present when the target response's + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BetaResponseSteerAcceptedEvent]. + * + * The following fields are required: + * ```java + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseSteerAcceptedEvent]. */ + class Builder internal constructor() { + + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.accepted") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(betaResponseSteerAcceptedEvent: BetaResponseSteerAcceptedEvent) = apply { + sequenceNumber = betaResponseSteerAcceptedEvent.sequenceNumber + steer = betaResponseSteerAcceptedEvent.steer + type = betaResponseSteerAcceptedEvent.type + streamId = betaResponseSteerAcceptedEvent.streamId + additionalProperties = + betaResponseSteerAcceptedEvent.additionalProperties.toMutableMap() + } + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The accepted steering submission. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.accepted") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event. This field is present when the target + * response's `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseSteerAcceptedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BetaResponseSteerAcceptedEvent = + BetaResponseSteerAcceptedEvent( + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerAcceptedEvent = apply { + if (validated) { + return@apply + } + + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.accepted")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.accepted")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** The accepted steering submission. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val previousResponseId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + ) : this(id, previousResponseId, mutableMapOf()) + + /** + * The ID assigned to the steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The ID of the response being steered. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var previousResponseId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + id = steer.id + previousResponseId = steer.previousResponseId + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The ID assigned to the steering submission. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The ID of the response being steered. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("id", id), + checkRequired("previousResponseId", previousResponseId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + id() + previousResponseId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + id == other.id && + previousResponseId == other.previousResponseId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, previousResponseId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{id=$id, previousResponseId=$previousResponseId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerAcceptedEvent && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(sequenceNumber, steer, type, streamId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseSteerAcceptedEvent{sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerErrorCode.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerErrorCode.kt new file mode 100644 index 000000000..e1d83df3c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerErrorCode.kt @@ -0,0 +1,186 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.errors.OpenAIInvalidDataException + +/** + * A machine-readable steering error code. Clients should handle unknown values because additional + * codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + */ +class BetaResponseSteerErrorCode +@JsonCreator +private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't match + * any known member, and you want to know that value. For example, if the SDK is on an older + * version than the API, then the API may respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val RESPONSE_NOT_FOUND = of("response_not_found") + + @JvmField val INVALID_INPUT = of("invalid_input") + + @JvmField val STEERING_NOT_SUPPORTED = of("steering_not_supported") + + @JvmField val TOO_MANY_PENDING_STEERS = of("too_many_pending_steers") + + @JvmField val RESPONSE_ALREADY_COMPLETED = of("response_already_completed") + + @JvmField val RESPONSE_NOT_ACTIVE = of("response_not_active") + + @JvmField val SUCCESSOR_CREATION_FAILED = of("successor_creation_failed") + + @JvmStatic fun of(value: String) = BetaResponseSteerErrorCode(JsonField.of(value)) + } + + /** An enum containing [BetaResponseSteerErrorCode]'s known values. */ + enum class Known { + RESPONSE_NOT_FOUND, + INVALID_INPUT, + STEERING_NOT_SUPPORTED, + TOO_MANY_PENDING_STEERS, + RESPONSE_ALREADY_COMPLETED, + RESPONSE_NOT_ACTIVE, + SUCCESSOR_CREATION_FAILED, + } + + /** + * An enum containing [BetaResponseSteerErrorCode]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [BetaResponseSteerErrorCode] can contain an unknown value in a couple of + * cases: + * - It was deserialized from data that doesn't match any known member. For example, if the SDK + * is on an older version than the API, then the API may respond with new members that the SDK + * is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + RESPONSE_NOT_FOUND, + INVALID_INPUT, + STEERING_NOT_SUPPORTED, + TOO_MANY_PENDING_STEERS, + RESPONSE_ALREADY_COMPLETED, + RESPONSE_NOT_ACTIVE, + SUCCESSOR_CREATION_FAILED, + /** + * An enum member indicating that [BetaResponseSteerErrorCode] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] if + * the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want to + * throw for the unknown case. + */ + fun value(): Value = + when (this) { + RESPONSE_NOT_FOUND -> Value.RESPONSE_NOT_FOUND + INVALID_INPUT -> Value.INVALID_INPUT + STEERING_NOT_SUPPORTED -> Value.STEERING_NOT_SUPPORTED + TOO_MANY_PENDING_STEERS -> Value.TOO_MANY_PENDING_STEERS + RESPONSE_ALREADY_COMPLETED -> Value.RESPONSE_ALREADY_COMPLETED + RESPONSE_NOT_ACTIVE -> Value.RESPONSE_NOT_ACTIVE + SUCCESSOR_CREATION_FAILED -> Value.SUCCESSOR_CREATION_FAILED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't want + * to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + RESPONSE_NOT_FOUND -> Known.RESPONSE_NOT_FOUND + INVALID_INPUT -> Known.INVALID_INPUT + STEERING_NOT_SUPPORTED -> Known.STEERING_NOT_SUPPORTED + TOO_MANY_PENDING_STEERS -> Known.TOO_MANY_PENDING_STEERS + RESPONSE_ALREADY_COMPLETED -> Known.RESPONSE_ALREADY_COMPLETED + RESPONSE_NOT_ACTIVE -> Known.RESPONSE_NOT_ACTIVE + SUCCESSOR_CREATION_FAILED -> Known.SUCCESSOR_CREATION_FAILED + else -> throw OpenAIInvalidDataException("Unknown BetaResponseSteerErrorCode: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging and + * generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerErrorCode = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerErrorCode && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerEvent.kt new file mode 100644 index 000000000..dabd12cea --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerEvent.kt @@ -0,0 +1,324 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and execution + * modes that support steering. Responses bound to a conversation or using automatic compaction do + * not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not that it + * has been applied. The successor's `response.created` event is the commit point. Input that cannot + * be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed automatically by + * a successor `response.created`. Normal completion can also be followed by an automatic successor. + * Automatic successors inherit the previous response's settings and continue from it with the + * queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and send + * one explicit `response.create` per parent with the same `previous_response_id` and WebSocket + * lane. Do not rerun tools or resend accepted steering input. The queued input is prepended in + * submission order to that request's input, and the explicit request retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; the + * target response determines the WebSocket lane. + */ +class BetaResponseSteerEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val input: JsonField, + private val previousResponseId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(input, previousResponseId, type, mutableMapOf()) + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item shape + * as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only `type`, + * `role`, and `content`, with `content` as a string or an array of `input_text`, `input_image`, + * and `input_file` parts. The optional `type` must be `message`. Other roles, tool outputs, and + * item types are not supported for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): BetaResponseSteerInput = input.getRequired("input") + + /** + * The ID of the response to steer on this WebSocket connection. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * The event discriminator. Always `response.steer`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BetaResponseSteerEvent]. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseSteerEvent]. */ + class Builder internal constructor() { + + private var input: JsonField? = null + private var previousResponseId: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(betaResponseSteerEvent: BetaResponseSteerEvent) = apply { + input = betaResponseSteerEvent.input + previousResponseId = betaResponseSteerEvent.previousResponseId + type = betaResponseSteerEvent.type + additionalProperties = betaResponseSteerEvent.additionalProperties.toMutableMap() + } + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of `input_text`, + * `input_image`, and `input_file` parts. The optional `type` must be `message`. Other + * roles, tool outputs, and item types are not supported for steering. + */ + fun input(input: BetaResponseSteerInput) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [BetaResponseSteerInput] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** Alias for calling [input] with `BetaResponseSteerInput.ofText(text)`. */ + fun input(text: String) = input(BetaResponseSteerInput.ofText(text)) + + /** + * Alias for calling [input] with + * `BetaResponseSteerInput.ofResponseSteerInputItemList(responseSteerInputItemList)`. + */ + fun inputOfResponseSteerInputItemList( + responseSteerInputItemList: List + ) = input(BetaResponseSteerInput.ofResponseSteerInputItemList(responseSteerInputItemList)) + + /** The ID of the response to steer on this WebSocket connection. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseSteerEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BetaResponseSteerEvent = + BetaResponseSteerEvent( + checkRequired("input", input), + checkRequired("previousResponseId", previousResponseId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerEvent = apply { + if (validated) { + return@apply + } + + input().validate() + previousResponseId() + _type().let { + if (it != JsonValue.from("response.steer")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("response.steer")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerEvent && + input == other.input && + previousResponseId == other.previousResponseId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, previousResponseId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseSteerEvent{input=$input, previousResponseId=$previousResponseId, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEvent.kt new file mode 100644 index 000000000..5a59d95bb --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEvent.kt @@ -0,0 +1,921 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when steering input is rejected or cannot be committed to a successor response. Returns + * the original, uncommitted input so the client can carry it into `response.create` when + * appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated omit + * `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it is not + * proof that the input was rejected. + */ +class BetaResponseSteerFailedEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val error: JsonField, + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(error, sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * Information about why the input could not be committed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun error(): Error = error.getRequired("error") + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The steering submission that could not be committed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.failed`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.failed") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event, when the target response is available and its + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [error]. + * + * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [BetaResponseSteerFailedEvent]. + * + * The following fields are required: + * ```java + * .error() + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseSteerFailedEvent]. */ + class Builder internal constructor() { + + private var error: JsonField? = null + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.failed") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(betaResponseSteerFailedEvent: BetaResponseSteerFailedEvent) = apply { + error = betaResponseSteerFailedEvent.error + sequenceNumber = betaResponseSteerFailedEvent.sequenceNumber + steer = betaResponseSteerFailedEvent.steer + type = betaResponseSteerFailedEvent.type + streamId = betaResponseSteerFailedEvent.streamId + additionalProperties = betaResponseSteerFailedEvent.additionalProperties.toMutableMap() + } + + /** Information about why the input could not be committed. */ + fun error(error: Error) = error(JsonField.of(error)) + + /** + * Sets [Builder.error] to an arbitrary JSON value. + * + * You should usually call [Builder.error] with a well-typed [Error] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun error(error: JsonField) = apply { this.error = error } + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The steering submission that could not be committed. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.failed") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event, when the target response is available and its + * `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseSteerFailedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .error() + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BetaResponseSteerFailedEvent = + BetaResponseSteerFailedEvent( + checkRequired("error", error), + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerFailedEvent = apply { + if (validated) { + return@apply + } + + error().validate() + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.failed")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (error.asKnown().getOrNull()?.validity() ?: 0) + + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.failed")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** Information about why the input could not be committed. */ + class Error + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val code: JsonField, + private val message: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("code") + @ExcludeMissing + code: JsonField = JsonMissing.of(), + @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(code, message, type, mutableMapOf()) + + /** + * A machine-readable steering error code. Clients should handle unknown values because + * additional codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support + * steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting + * steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun code(): BetaResponseSteerErrorCode = code.getRequired("code") + + /** + * A human-readable description of the error. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun message(): String = message.getRequired("message") + + /** + * The error type. Always `invalid_request_error`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("invalid_request_error") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") + @ExcludeMissing + fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Error]. + * + * The following fields are required: + * ```java + * .code() + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Error]. */ + class Builder internal constructor() { + + private var code: JsonField? = null + private var message: JsonField? = null + private var type: JsonValue = JsonValue.from("invalid_request_error") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(error: Error) = apply { + code = error.code + message = error.message + type = error.type + additionalProperties = error.additionalProperties.toMutableMap() + } + + /** + * A machine-readable steering error code. Clients should handle unknown values because + * additional codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support + * steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting + * steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + */ + fun code(code: BetaResponseSteerErrorCode) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [BetaResponseSteerErrorCode] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + /** + * Sets [code] to an arbitrary [String]. + * + * You should usually call [code] with a well-typed [BetaResponseSteerErrorCode] + * constant instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun code(value: String) = code(BetaResponseSteerErrorCode.of(value)) + + /** A human-readable description of the error. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("invalid_request_error") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Error]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Error = + Error( + checkRequired("code", code), + checkRequired("message", message), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Error = apply { + if (validated) { + return@apply + } + + code() + message() + _type().let { + if (it != JsonValue.from("invalid_request_error")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (code.asKnown().isPresent) 1 else 0) + + (if (message.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("invalid_request_error")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Error && + code == other.code && + message == other.message && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(code, message, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Error{code=$code, message=$message, type=$type, additionalProperties=$additionalProperties}" + } + + /** The steering submission that could not be committed. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val input: JsonField, + private val previousResponseId: JsonField, + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + ) : this(input, previousResponseId, id, mutableMapOf()) + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of `input_text`, + * `input_image`, and `input_file` parts. The optional `type` must be `message`. Other + * roles, tool outputs, and item types are not supported for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): BetaResponseSteerInput = input.getRequired("input") + + /** + * The ID of the response that was targeted for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * The ID assigned to the steering submission, if one was allocated. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") + @ExcludeMissing + fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var input: JsonField? = null + private var previousResponseId: JsonField? = null + private var id: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + input = steer.input + previousResponseId = steer.previousResponseId + id = steer.id + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of + * `input_text`, `input_image`, and `input_file` parts. The optional `type` must be + * `message`. Other roles, tool outputs, and item types are not supported for steering. + */ + fun input(input: BetaResponseSteerInput) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [BetaResponseSteerInput] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** Alias for calling [input] with `BetaResponseSteerInput.ofText(text)`. */ + fun input(text: String) = input(BetaResponseSteerInput.ofText(text)) + + /** + * Alias for calling [input] with + * `BetaResponseSteerInput.ofResponseSteerInputItemList(responseSteerInputItemList)`. + */ + fun inputOfResponseSteerInputItemList( + responseSteerInputItemList: List + ) = + input( + BetaResponseSteerInput.ofResponseSteerInputItemList(responseSteerInputItemList) + ) + + /** The ID of the response that was targeted for steering. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + /** The ID assigned to the steering submission, if one was allocated. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("input", input), + checkRequired("previousResponseId", previousResponseId), + id, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + input().validate() + previousResponseId() + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + input == other.input && + previousResponseId == other.previousResponseId && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, previousResponseId, id, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{input=$input, previousResponseId=$previousResponseId, id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerFailedEvent && + error == other.error && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(error, sequenceNumber, steer, type, streamId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseSteerFailedEvent{error=$error, sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInput.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInput.kt new file mode 100644 index 000000000..cd231ec2e --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInput.kt @@ -0,0 +1,2917 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Input to queue for a continuation of the response. Uses the same string or input-item shape as + * `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only `type`, + * `role`, and `content`, with `content` as a string or an array of `input_text`, `input_image`, and + * `input_file` parts. The optional `type` must be `message`. Other roles, tool outputs, and item + * types are not supported for steering. + */ +@JsonDeserialize(using = BetaResponseSteerInput.Deserializer::class) +@JsonSerialize(using = BetaResponseSteerInput.Serializer::class) +class BetaResponseSteerInput +private constructor( + private val text: String? = null, + private val responseSteerInputItemList: List? = null, + private val _json: JsonValue? = null, +) { + + /** A text input, equivalent to a message with the `user` role. */ + fun text(): Optional = Optional.ofNullable(text) + + /** A non-empty list of message inputs to queue for the response. */ + fun responseSteerInputItemList(): Optional> = + Optional.ofNullable(responseSteerInputItemList) + + fun isText(): Boolean = text != null + + fun isResponseSteerInputItemList(): Boolean = responseSteerInputItemList != null + + /** A text input, equivalent to a message with the `user` role. */ + fun asText(): String = text.getOrThrow("text") + + /** A non-empty list of message inputs to queue for the response. */ + fun asResponseSteerInputItemList(): List = + responseSteerInputItemList.getOrThrow("responseSteerInputItemList") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = betaResponseSteerInput.accept(new BetaResponseSteerInput.Visitor>() { + * @Override + * public Optional visitText(String text) { + * return Optional.of(text.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + text != null -> visitor.visitText(text) + responseSteerInputItemList != null -> + visitor.visitResponseSteerInputItemList(responseSteerInputItemList) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerInput = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitText(text: String) {} + + override fun visitResponseSteerInputItemList( + responseSteerInputItemList: List + ) { + responseSteerInputItemList.forEach { it.validate() } + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitText(text: String) = 1 + + override fun visitResponseSteerInputItemList( + responseSteerInputItemList: List + ) = responseSteerInputItemList.sumOf { it.validity().toInt() } + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerInput && + text == other.text && + responseSteerInputItemList == other.responseSteerInputItemList + } + + override fun hashCode(): Int = Objects.hash(text, responseSteerInputItemList) + + override fun toString(): String = + when { + text != null -> "BetaResponseSteerInput{text=$text}" + responseSteerInputItemList != null -> + "BetaResponseSteerInput{responseSteerInputItemList=$responseSteerInputItemList}" + _json != null -> "BetaResponseSteerInput{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BetaResponseSteerInput") + } + + companion object { + + /** A text input, equivalent to a message with the `user` role. */ + @JvmStatic fun ofText(text: String) = BetaResponseSteerInput(text = text) + + /** A non-empty list of message inputs to queue for the response. */ + @JvmStatic + fun ofResponseSteerInputItemList(responseSteerInputItemList: List) = + BetaResponseSteerInput( + responseSteerInputItemList = responseSteerInputItemList.toImmutable() + ) + } + + /** + * An interface that defines how to map each variant of [BetaResponseSteerInput] to a value of + * type [T]. + */ + interface Visitor { + + /** A text input, equivalent to a message with the `user` role. */ + fun visitText(text: String): T + + /** A non-empty list of message inputs to queue for the response. */ + fun visitResponseSteerInputItemList( + responseSteerInputItemList: List + ): T + + /** + * Maps an unknown variant of [BetaResponseSteerInput] to a value of type [T]. + * + * An instance of [BetaResponseSteerInput] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BetaResponseSteerInput: $json") + } + } + + internal class Deserializer : + BaseDeserializer(BetaResponseSteerInput::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BetaResponseSteerInput { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerInput(text = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>())?.let { + BetaResponseSteerInput(responseSteerInputItemList = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> BetaResponseSteerInput(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(BetaResponseSteerInput::class) { + + override fun serialize( + value: BetaResponseSteerInput, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.text != null -> generator.writeObject(value.text) + value.responseSteerInputItemList != null -> + generator.writeObject(value.responseSteerInputItemList) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BetaResponseSteerInput") + } + } + } + + /** The output of a function tool call. */ + @JsonDeserialize(using = ResponseSteerInputItem.Deserializer::class) + @JsonSerialize(using = ResponseSteerInputItem.Serializer::class) + class ResponseSteerInputItem + private constructor( + private val message: Message? = null, + private val functionCallOutput: FunctionCallOutput? = null, + private val _json: JsonValue? = null, + ) { + + fun message(): Optional = Optional.ofNullable(message) + + /** The output of a function tool call. */ + fun functionCallOutput(): Optional = + Optional.ofNullable(functionCallOutput) + + fun isMessage(): Boolean = message != null + + fun isFunctionCallOutput(): Boolean = functionCallOutput != null + + fun asMessage(): Message = message.getOrThrow("message") + + /** The output of a function tool call. */ + fun asFunctionCallOutput(): FunctionCallOutput = + functionCallOutput.getOrThrow("functionCallOutput") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of + * the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = responseSteerInputItem.accept(new ResponseSteerInputItem.Visitor>() { + * @Override + * public Optional visitMessage(Message message) { + * return Optional.of(message.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] + * and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + message != null -> visitor.visitMessage(message) + functionCallOutput != null -> visitor.visitFunctionCallOutput(functionCallOutput) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerInputItem = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitMessage(message: Message) { + message.validate() + } + + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) { + functionCallOutput.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitMessage(message: Message) = message.validity() + + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + functionCallOutput.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerInputItem && + message == other.message && + functionCallOutput == other.functionCallOutput + } + + override fun hashCode(): Int = Objects.hash(message, functionCallOutput) + + override fun toString(): String = + when { + message != null -> "ResponseSteerInputItem{message=$message}" + functionCallOutput != null -> + "ResponseSteerInputItem{functionCallOutput=$functionCallOutput}" + _json != null -> "ResponseSteerInputItem{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseSteerInputItem") + } + + companion object { + + @JvmStatic fun ofMessage(message: Message) = ResponseSteerInputItem(message = message) + + /** The output of a function tool call. */ + @JvmStatic + fun ofFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + ResponseSteerInputItem(functionCallOutput = functionCallOutput) + } + + /** + * An interface that defines how to map each variant of [ResponseSteerInputItem] to a value + * of type [T]. + */ + interface Visitor { + + fun visitMessage(message: Message): T + + /** The output of a function tool call. */ + fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput): T + + /** + * Maps an unknown variant of [ResponseSteerInputItem] to a value of type [T]. + * + * An instance of [ResponseSteerInputItem] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponseSteerInputItem: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ResponseSteerInputItem::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseSteerInputItem { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "message" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputItem(message = it, _json = json) + } ?: ResponseSteerInputItem(_json = json) + } + "function_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputItem(functionCallOutput = it, _json = json) + } ?: ResponseSteerInputItem(_json = json) + } + } + + return ResponseSteerInputItem(_json = json) + } + } + + internal class Serializer : + BaseSerializer(ResponseSteerInputItem::class) { + + override fun serialize( + value: ResponseSteerInputItem, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.message != null -> generator.writeObject(value.message) + value.functionCallOutput != null -> + generator.writeObject(value.functionCallOutput) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseSteerInputItem") + } + } + } + + class Message + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val content: JsonField, + private val role: JsonValue, + private val type: JsonValue, + private val id: JsonField, + private val agent: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("role") @ExcludeMissing role: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(content, role, type, id, agent, status, mutableMapOf()) + + /** + * The message content, as an array of content parts. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun content(): Content = content.getRequired("content") + + /** + * The message role. Always `user`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("user") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonValue = role + + /** + * The item type. Always `message`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("message") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of this message item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * The agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun agent(): Optional = agent.getOptional("agent") + + /** + * The status of the message item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [agent]. + * + * Unlike [agent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Message]. + * + * The following fields are required: + * ```java + * .content() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Message]. */ + class Builder internal constructor() { + + private var content: JsonField? = null + private var role: JsonValue = JsonValue.from("user") + private var type: JsonValue = JsonValue.from("message") + private var id: JsonField = JsonMissing.of() + private var agent: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(message: Message) = apply { + content = message.content + role = message.role + type = message.type + id = message.id + agent = message.agent + status = message.status + additionalProperties = message.additionalProperties.toMutableMap() + } + + /** The message content, as an array of content parts. */ + fun content(content: Content) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** + * Alias for calling [content] with + * `Content.ofBetaResponseSteerInputContents(betaResponseSteerInputContents)`. + */ + fun contentOfBetaResponseSteerInputContents( + betaResponseSteerInputContents: List + ) = + content( + Content.ofBetaResponseSteerInputContents(betaResponseSteerInputContents) + ) + + /** Alias for calling [content] with `Content.ofString(string)`. */ + fun content(string: String) = content(Content.ofString(string)) + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("user") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun role(role: JsonValue) = apply { this.role = role } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("message") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The unique ID of this message item. */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The agent that produced this item. */ + fun agent(agent: Agent?) = agent(JsonField.ofNullable(agent)) + + /** Alias for calling [Builder.agent] with `agent.orElse(null)`. */ + fun agent(agent: Optional) = agent(agent.getOrNull()) + + /** + * Sets [Builder.agent] to an arbitrary JSON value. + * + * You should usually call [Builder.agent] with a well-typed [Agent] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agent(agent: JsonField) = apply { this.agent = agent } + + /** The status of the message item. */ + fun status(status: String?) = status(JsonField.ofNullable(status)) + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional) = status(status.getOrNull()) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Message]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Message = + Message( + checkRequired("content", content), + role, + type, + id, + agent, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Message = apply { + if (validated) { + return@apply + } + + content().validate() + _role().let { + if (it != JsonValue.from("user")) { + throw OpenAIInvalidDataException("'role' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("message")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + agent().ifPresent { it.validate() } + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (content.asKnown().getOrNull()?.validity() ?: 0) + + role.let { if (it == JsonValue.from("user")) 1 else 0 } + + type.let { if (it == JsonValue.from("message")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (status.asKnown().isPresent) 1 else 0) + + /** The message content, as an array of content parts. */ + @JsonDeserialize(using = Content.Deserializer::class) + @JsonSerialize(using = Content.Serializer::class) + class Content + private constructor( + private val betaResponseSteerInputContents: List? = + null, + private val string: String? = null, + private val _json: JsonValue? = null, + ) { + + fun betaResponseSteerInputContents(): + Optional> = + Optional.ofNullable(betaResponseSteerInputContents) + + /** The message content, as a single string. */ + fun string(): Optional = Optional.ofNullable(string) + + fun isBetaResponseSteerInputContents(): Boolean = + betaResponseSteerInputContents != null + + fun isString(): Boolean = string != null + + fun asBetaResponseSteerInputContents(): List = + betaResponseSteerInputContents.getOrThrow("betaResponseSteerInputContents") + + /** The message content, as a single string. */ + fun asString(): String = string.getOrThrow("string") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = content.accept(new Content.Visitor>() { + * @Override + * public Optional visitBetaResponseSteerInputContents(List betaResponseSteerInputContents) { + * return Optional.of(betaResponseSteerInputContents.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + betaResponseSteerInputContents != null -> + visitor.visitBetaResponseSteerInputContents( + betaResponseSteerInputContents + ) + string != null -> visitor.visitString(string) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Content = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitBetaResponseSteerInputContents( + betaResponseSteerInputContents: List + ) { + betaResponseSteerInputContents.forEach { it.validate() } + } + + override fun visitString(string: String) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitBetaResponseSteerInputContents( + betaResponseSteerInputContents: List + ) = betaResponseSteerInputContents.sumOf { it.validity().toInt() } + + override fun visitString(string: String) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + betaResponseSteerInputContents == other.betaResponseSteerInputContents && + string == other.string + } + + override fun hashCode(): Int = Objects.hash(betaResponseSteerInputContents, string) + + override fun toString(): String = + when { + betaResponseSteerInputContents != null -> + "Content{betaResponseSteerInputContents=$betaResponseSteerInputContents}" + string != null -> "Content{string=$string}" + _json != null -> "Content{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Content") + } + + companion object { + + @JvmStatic + fun ofBetaResponseSteerInputContents( + betaResponseSteerInputContents: List + ) = + Content( + betaResponseSteerInputContents = + betaResponseSteerInputContents.toImmutable() + ) + + /** The message content, as a single string. */ + @JvmStatic fun ofString(string: String) = Content(string = string) + } + + /** + * An interface that defines how to map each variant of [Content] to a value of type + * [T]. + */ + interface Visitor { + + fun visitBetaResponseSteerInputContents( + betaResponseSteerInputContents: List + ): T + + /** The message content, as a single string. */ + fun visitString(string: String): T + + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Content: $json") + } + } + + internal class Deserializer : BaseDeserializer(Content::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Content { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Content(string = it, _json = json) + }, + tryDeserialize( + node, + jacksonTypeRef>(), + ) + ?.let { + Content( + betaResponseSteerInputContents = it, + _json = json, + ) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // boolean). + 0 -> Content(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Content::class) { + + override fun serialize( + value: Content, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.betaResponseSteerInputContents != null -> + generator.writeObject(value.betaResponseSteerInputContents) + value.string != null -> generator.writeObject(value.string) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Content") + } + } + } + } + + /** The agent that produced this item. */ + class Agent + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val agentName: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("agent_name") + @ExcludeMissing + agentName: JsonField = JsonMissing.of() + ) : this(agentName, mutableMapOf()) + + /** + * The canonical name of the agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun agentName(): String = agentName.getRequired("agent_name") + + /** + * Returns the raw JSON value of [agentName]. + * + * Unlike [agentName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("agent_name") + @ExcludeMissing + fun _agentName(): JsonField = agentName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Agent]. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Agent]. */ + class Builder internal constructor() { + + private var agentName: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agent: Agent) = apply { + agentName = agent.agentName + additionalProperties = agent.additionalProperties.toMutableMap() + } + + /** The canonical name of the agent that produced this item. */ + fun agentName(agentName: String) = agentName(JsonField.of(agentName)) + + /** + * Sets [Builder.agentName] to an arbitrary JSON value. + * + * You should usually call [Builder.agentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun agentName(agentName: JsonField) = apply { + this.agentName = agentName + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Agent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Agent = + Agent( + checkRequired("agentName", agentName), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Agent = apply { + if (validated) { + return@apply + } + + agentName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (if (agentName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Agent && + agentName == other.agentName && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(agentName, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Agent{agentName=$agentName, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Message && + content == other.content && + role == other.role && + type == other.type && + id == other.id && + agent == other.agent && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(content, role, type, id, agent, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Message{content=$content, role=$role, type=$type, id=$id, agent=$agent, status=$status, additionalProperties=$additionalProperties}" + } + + /** The output of a function tool call. */ + class FunctionCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val output: JsonField, + private val type: JsonValue, + private val id: JsonField, + private val agent: JsonField, + private val callId: JsonField, + private val caller: JsonField, + private val name: JsonField, + private val namespace: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("output") + @ExcludeMissing + output: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("agent") @ExcludeMissing agent: JsonField = JsonMissing.of(), + @JsonProperty("call_id") + @ExcludeMissing + callId: JsonField = JsonMissing.of(), + @JsonProperty("caller") + @ExcludeMissing + caller: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("namespace") + @ExcludeMissing + namespace: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this( + output, + type, + id, + agent, + callId, + caller, + name, + namespace, + status, + mutableMapOf(), + ) + + /** + * Text, image, or file output of the function tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun output(): Output = output.getRequired("output") + + /** + * The type of the function tool call output. Always `function_call_output`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of the function tool call output. Populated when this item is returned + * via API. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * The agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun agent(): Optional = agent.getOptional("agent") + + /** + * The unique ID of the function tool call generated by the model. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callId(): Optional = callId.getOptional("call_id") + + /** + * The execution context that produced this tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun caller(): Optional = caller.getOptional("caller") + + /** + * The name of the tool that produced the output. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * The namespace of the tool that produced the output. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun namespace(): Optional = namespace.getOptional("namespace") + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. Populated + * when items are returned via API. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [output]. + * + * Unlike [output], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output") @ExcludeMissing fun _output(): JsonField = output + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [agent]. + * + * Unlike [agent], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("agent") @ExcludeMissing fun _agent(): JsonField = agent + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + /** + * Returns the raw JSON value of [caller]. + * + * Unlike [caller], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("caller") @ExcludeMissing fun _caller(): JsonField = caller + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [namespace]. + * + * Unlike [namespace], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("namespace") + @ExcludeMissing + fun _namespace(): JsonField = namespace + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [FunctionCallOutput]. + * + * The following fields are required: + * ```java + * .output() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FunctionCallOutput]. */ + class Builder internal constructor() { + + private var output: JsonField? = null + private var type: JsonValue = JsonValue.from("function_call_output") + private var id: JsonField = JsonMissing.of() + private var agent: JsonField = JsonMissing.of() + private var callId: JsonField = JsonMissing.of() + private var caller: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var namespace: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(functionCallOutput: FunctionCallOutput) = apply { + output = functionCallOutput.output + type = functionCallOutput.type + id = functionCallOutput.id + agent = functionCallOutput.agent + callId = functionCallOutput.callId + caller = functionCallOutput.caller + name = functionCallOutput.name + namespace = functionCallOutput.namespace + status = functionCallOutput.status + additionalProperties = functionCallOutput.additionalProperties.toMutableMap() + } + + /** Text, image, or file output of the function tool call. */ + fun output(output: Output) = output(JsonField.of(output)) + + /** + * Sets [Builder.output] to an arbitrary JSON value. + * + * You should usually call [Builder.output] with a well-typed [Output] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun output(output: JsonField) = apply { this.output = output } + + /** Alias for calling [output] with `Output.ofString(string)`. */ + fun output(string: String) = output(Output.ofString(string)) + + /** + * Alias for calling [output] with + * `Output.ofBetaResponseFunctionCallOutputItemList(betaResponseFunctionCallOutputItemList)`. + */ + fun outputOfBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList: List + ) = + output( + Output.ofBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList + ) + ) + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The unique ID of the function tool call output. Populated when this item is + * returned via API. + */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The agent that produced this item. */ + fun agent(agent: Agent?) = agent(JsonField.ofNullable(agent)) + + /** Alias for calling [Builder.agent] with `agent.orElse(null)`. */ + fun agent(agent: Optional) = agent(agent.getOrNull()) + + /** + * Sets [Builder.agent] to an arbitrary JSON value. + * + * You should usually call [Builder.agent] with a well-typed [Agent] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun agent(agent: JsonField) = apply { this.agent = agent } + + /** The unique ID of the function tool call generated by the model. */ + fun callId(callId: String?) = callId(JsonField.ofNullable(callId)) + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** The execution context that produced this tool call. */ + fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) + + /** Alias for calling [Builder.caller] with `caller.orElse(null)`. */ + fun caller(caller: Optional) = caller(caller.getOrNull()) + + /** + * Sets [Builder.caller] to an arbitrary JSON value. + * + * You should usually call [Builder.caller] with a well-typed [Caller] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun caller(caller: JsonField) = apply { this.caller = caller } + + /** Alias for calling [caller] with `Caller.ofDirect()`. */ + fun callerDirect() = caller(Caller.ofDirect()) + + /** Alias for calling [caller] with `Caller.ofProgram(program)`. */ + fun caller(program: Caller.Program) = caller(Caller.ofProgram(program)) + + /** + * Alias for calling [caller] with the following: + * ```java + * Caller.Program.builder() + * .callerId(callerId) + * .build() + * ``` + */ + fun programCaller(callerId: String) = + caller(Caller.Program.builder().callerId(callerId).build()) + + /** The name of the tool that produced the output. */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** The namespace of the tool that produced the output. */ + fun namespace(namespace: String?) = namespace(JsonField.ofNullable(namespace)) + + /** Alias for calling [Builder.namespace] with `namespace.orElse(null)`. */ + fun namespace(namespace: Optional) = namespace(namespace.getOrNull()) + + /** + * Sets [Builder.namespace] to an arbitrary JSON value. + * + * You should usually call [Builder.namespace] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun namespace(namespace: JsonField) = apply { this.namespace = namespace } + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. + * Populated when items are returned via API. + */ + fun status(status: Status?) = status(JsonField.ofNullable(status)) + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional) = status(status.getOrNull()) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [FunctionCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .output() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FunctionCallOutput = + FunctionCallOutput( + checkRequired("output", output), + type, + id, + agent, + callId, + caller, + name, + namespace, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): FunctionCallOutput = apply { + if (validated) { + return@apply + } + + output().validate() + _type().let { + if (it != JsonValue.from("function_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + agent().ifPresent { it.validate() } + callId() + caller().ifPresent { it.validate() } + name() + namespace() + status().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (output.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("function_call_output")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (agent.asKnown().getOrNull()?.validity() ?: 0) + + (if (callId.asKnown().isPresent) 1 else 0) + + (caller.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (namespace.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + /** Text, image, or file output of the function tool call. */ + @JsonDeserialize(using = Output.Deserializer::class) + @JsonSerialize(using = Output.Serializer::class) + class Output + private constructor( + private val string: String? = null, + private val betaResponseFunctionCallOutputItemList: + List? = + null, + private val _json: JsonValue? = null, + ) { + + /** A JSON string of the output of the function tool call. */ + fun string(): Optional = Optional.ofNullable(string) + + /** An array of content outputs (text, image, file) for the function tool call. */ + fun betaResponseFunctionCallOutputItemList(): + Optional> = + Optional.ofNullable(betaResponseFunctionCallOutputItemList) + + fun isString(): Boolean = string != null + + fun isBetaResponseFunctionCallOutputItemList(): Boolean = + betaResponseFunctionCallOutputItemList != null + + /** A JSON string of the output of the function tool call. */ + fun asString(): String = string.getOrThrow("string") + + /** An array of content outputs (text, image, file) for the function tool call. */ + fun asBetaResponseFunctionCallOutputItemList(): + List = + betaResponseFunctionCallOutputItemList.getOrThrow( + "betaResponseFunctionCallOutputItemList" + ) + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = output.accept(new Output.Visitor>() { + * @Override + * public Optional visitString(String string) { + * return Optional.of(string.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + betaResponseFunctionCallOutputItemList != null -> + visitor.visitBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList + ) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Output = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList: + List + ) { + betaResponseFunctionCallOutputItemList.forEach { it.validate() } + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList: + List + ) = + betaResponseFunctionCallOutputItemList.sumOf { + it.validity().toInt() + } + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Output && + string == other.string && + betaResponseFunctionCallOutputItemList == + other.betaResponseFunctionCallOutputItemList + } + + override fun hashCode(): Int = + Objects.hash(string, betaResponseFunctionCallOutputItemList) + + override fun toString(): String = + when { + string != null -> "Output{string=$string}" + betaResponseFunctionCallOutputItemList != null -> + "Output{betaResponseFunctionCallOutputItemList=$betaResponseFunctionCallOutputItemList}" + _json != null -> "Output{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Output") + } + + companion object { + + /** A JSON string of the output of the function tool call. */ + @JvmStatic fun ofString(string: String) = Output(string = string) + + /** + * An array of content outputs (text, image, file) for the function tool call. + */ + @JvmStatic + fun ofBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList: + List + ) = + Output( + betaResponseFunctionCallOutputItemList = + betaResponseFunctionCallOutputItemList.toImmutable() + ) + } + + /** + * An interface that defines how to map each variant of [Output] to a value of type + * [T]. + */ + interface Visitor { + + /** A JSON string of the output of the function tool call. */ + fun visitString(string: String): T + + /** + * An array of content outputs (text, image, file) for the function tool call. + */ + fun visitBetaResponseFunctionCallOutputItemList( + betaResponseFunctionCallOutputItemList: + List + ): T + + /** + * Maps an unknown variant of [Output] to a value of type [T]. + * + * An instance of [Output] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Output: $json") + } + } + + internal class Deserializer : BaseDeserializer(Output::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Output { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Output(string = it, _json = json) + }, + tryDeserialize( + node, + jacksonTypeRef< + List + >(), + ) + ?.let { + Output( + betaResponseFunctionCallOutputItemList = it, + _json = json, + ) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // boolean). + 0 -> Output(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Output::class) { + + override fun serialize( + value: Output, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.betaResponseFunctionCallOutputItemList != null -> + generator.writeObject(value.betaResponseFunctionCallOutputItemList) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Output") + } + } + } + } + + /** The agent that produced this item. */ + class Agent + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val agentName: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("agent_name") + @ExcludeMissing + agentName: JsonField = JsonMissing.of() + ) : this(agentName, mutableMapOf()) + + /** + * The canonical name of the agent that produced this item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun agentName(): String = agentName.getRequired("agent_name") + + /** + * Returns the raw JSON value of [agentName]. + * + * Unlike [agentName], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("agent_name") + @ExcludeMissing + fun _agentName(): JsonField = agentName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Agent]. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Agent]. */ + class Builder internal constructor() { + + private var agentName: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(agent: Agent) = apply { + agentName = agent.agentName + additionalProperties = agent.additionalProperties.toMutableMap() + } + + /** The canonical name of the agent that produced this item. */ + fun agentName(agentName: String) = agentName(JsonField.of(agentName)) + + /** + * Sets [Builder.agentName] to an arbitrary JSON value. + * + * You should usually call [Builder.agentName] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun agentName(agentName: JsonField) = apply { + this.agentName = agentName + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Agent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .agentName() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Agent = + Agent( + checkRequired("agentName", agentName), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Agent = apply { + if (validated) { + return@apply + } + + agentName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (if (agentName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Agent && + agentName == other.agentName && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(agentName, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Agent{agentName=$agentName, additionalProperties=$additionalProperties}" + } + + /** The execution context that produced this tool call. */ + @JsonDeserialize(using = Caller.Deserializer::class) + @JsonSerialize(using = Caller.Serializer::class) + class Caller + private constructor( + private val direct: JsonValue? = null, + private val program: Program? = null, + private val _json: JsonValue? = null, + ) { + + fun direct(): Optional = Optional.ofNullable(direct) + + fun program(): Optional = Optional.ofNullable(program) + + fun isDirect(): Boolean = direct != null + + fun isProgram(): Boolean = program != null + + fun asDirect(): JsonValue = direct.getOrThrow("direct") + + fun asProgram(): Program = program.getOrThrow("program") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = caller.accept(new Caller.Visitor>() { + * @Override + * public Optional visitDirect(JsonValue direct) { + * return Optional.of(direct.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + direct != null -> visitor.visitDirect(direct) + program != null -> visitor.visitProgram(program) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Caller = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitDirect(direct: JsonValue) { + direct.let { + if (it != JsonValue.from(mapOf("type" to "direct"))) { + throw OpenAIInvalidDataException( + "'direct' is invalid, received $it" + ) + } + } + } + + override fun visitProgram(program: Program) { + program.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitDirect(direct: JsonValue) = + direct.let { + if (it == JsonValue.from(mapOf("type" to "direct"))) 1 else 0 + } + + override fun visitProgram(program: Program) = program.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Caller && direct == other.direct && program == other.program + } + + override fun hashCode(): Int = Objects.hash(direct, program) + + override fun toString(): String = + when { + direct != null -> "Caller{direct=$direct}" + program != null -> "Caller{program=$program}" + _json != null -> "Caller{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Caller") + } + + companion object { + + @JvmStatic + fun ofDirect() = Caller(direct = JsonValue.from(mapOf("type" to "direct"))) + + @JvmStatic fun ofProgram(program: Program) = Caller(program = program) + } + + /** + * An interface that defines how to map each variant of [Caller] to a value of type + * [T]. + */ + interface Visitor { + + fun visitDirect(direct: JsonValue): T + + fun visitProgram(program: Program): T + + /** + * Maps an unknown variant of [Caller] to a value of type [T]. + * + * An instance of [Caller] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Caller: $json") + } + } + + internal class Deserializer : BaseDeserializer(Caller::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Caller { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "direct" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { Caller(direct = it, _json = json) } + ?.takeIf { it.isValid() } ?: Caller(_json = json) + } + "program" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Caller(program = it, _json = json) + } ?: Caller(_json = json) + } + } + + return Caller(_json = json) + } + } + + internal class Serializer : BaseSerializer(Caller::class) { + + override fun serialize( + value: Caller, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.direct != null -> generator.writeObject(value.direct) + value.program != null -> generator.writeObject(value.program) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Caller") + } + } + } + + class Program + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callerId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("caller_id") + @ExcludeMissing + callerId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callerId, type, mutableMapOf()) + + /** + * The call ID of the program item that produced this tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun callerId(): String = callerId.getRequired("caller_id") + + /** + * The caller type. Always `program`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("program") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the + * server responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callerId]. + * + * Unlike [callerId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_id") + @ExcludeMissing + fun _callerId(): JsonField = callerId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Program]. + * + * The following fields are required: + * ```java + * .callerId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Program]. */ + class Builder internal constructor() { + + private var callerId: JsonField? = null + private var type: JsonValue = JsonValue.from("program") + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(program: Program) = apply { + callerId = program.callerId + type = program.type + additionalProperties = program.additionalProperties.toMutableMap() + } + + /** The call ID of the program item that produced this tool call. */ + fun callerId(callerId: String) = callerId(JsonField.of(callerId)) + + /** + * Sets [Builder.callerId] to an arbitrary JSON value. + * + * You should usually call [Builder.callerId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun callerId(callerId: JsonField) = apply { + this.callerId = callerId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults + * to the following: + * ```java + * JsonValue.from("program") + * ``` + * + * This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Program]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callerId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Program = + Program( + checkRequired("callerId", callerId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Program = apply { + if (validated) { + return@apply + } + + callerId() + _type().let { + if (it != JsonValue.from("program")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callerId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("program")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Program && + callerId == other.callerId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(callerId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Program{callerId=$callerId, type=$type, additionalProperties=$additionalProperties}" + } + } + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. Populated + * when items are returned via API. + */ + class Status @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val IN_PROGRESS = of("in_progress") + + @JvmField val COMPLETED = of("completed") + + @JvmField val INCOMPLETE = of("incomplete") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + IN_PROGRESS, + COMPLETED, + INCOMPLETE, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + IN_PROGRESS, + COMPLETED, + INCOMPLETE, + /** + * An enum member indicating that [Status] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + IN_PROGRESS -> Value.IN_PROGRESS + COMPLETED -> Value.COMPLETED + INCOMPLETE -> Value.INCOMPLETE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + IN_PROGRESS -> Known.IN_PROGRESS + COMPLETED -> Known.COMPLETED + INCOMPLETE -> Known.INCOMPLETE + else -> throw OpenAIInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FunctionCallOutput && + output == other.output && + type == other.type && + id == other.id && + agent == other.agent && + callId == other.callId && + caller == other.caller && + name == other.name && + namespace == other.namespace && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + output, + type, + id, + agent, + callId, + caller, + name, + namespace, + status, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCallOutput{output=$output, type=$type, id=$id, agent=$agent, callId=$callId, caller=$caller, name=$name, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContent.kt new file mode 100644 index 000000000..4cefec0cc --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContent.kt @@ -0,0 +1,286 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.JsonValue +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A piece of message content, such as text, an image, or a file. */ +@JsonDeserialize(using = BetaResponseSteerInputContent.Deserializer::class) +@JsonSerialize(using = BetaResponseSteerInputContent.Serializer::class) +class BetaResponseSteerInputContent +private constructor( + private val inputText: BetaResponseInputTextContent? = null, + private val inputImage: BetaResponseInputImageContent? = null, + private val inputFile: BetaResponseInputFileContent? = null, + private val _json: JsonValue? = null, +) { + + /** A text input to the model. */ + fun inputText(): Optional = Optional.ofNullable(inputText) + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun inputImage(): Optional = Optional.ofNullable(inputImage) + + /** A file input to the model. */ + fun inputFile(): Optional = Optional.ofNullable(inputFile) + + fun isInputText(): Boolean = inputText != null + + fun isInputImage(): Boolean = inputImage != null + + fun isInputFile(): Boolean = inputFile != null + + /** A text input to the model. */ + fun asInputText(): BetaResponseInputTextContent = inputText.getOrThrow("inputText") + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun asInputImage(): BetaResponseInputImageContent = inputImage.getOrThrow("inputImage") + + /** A file input to the model. */ + fun asInputFile(): BetaResponseInputFileContent = inputFile.getOrThrow("inputFile") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = betaResponseSteerInputContent.accept(new BetaResponseSteerInputContent.Visitor>() { + * @Override + * public Optional visitInputText(BetaResponseInputTextContent inputText) { + * return Optional.of(inputText.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + inputText != null -> visitor.visitInputText(inputText) + inputImage != null -> visitor.visitInputImage(inputImage) + inputFile != null -> visitor.visitInputFile(inputFile) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerInputContent = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitInputText(inputText: BetaResponseInputTextContent) { + inputText.validate() + } + + override fun visitInputImage(inputImage: BetaResponseInputImageContent) { + inputImage.validate() + } + + override fun visitInputFile(inputFile: BetaResponseInputFileContent) { + inputFile.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitInputText(inputText: BetaResponseInputTextContent) = + inputText.validity() + + override fun visitInputImage(inputImage: BetaResponseInputImageContent) = + inputImage.validity() + + override fun visitInputFile(inputFile: BetaResponseInputFileContent) = + inputFile.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerInputContent && + inputText == other.inputText && + inputImage == other.inputImage && + inputFile == other.inputFile + } + + override fun hashCode(): Int = Objects.hash(inputText, inputImage, inputFile) + + override fun toString(): String = + when { + inputText != null -> "BetaResponseSteerInputContent{inputText=$inputText}" + inputImage != null -> "BetaResponseSteerInputContent{inputImage=$inputImage}" + inputFile != null -> "BetaResponseSteerInputContent{inputFile=$inputFile}" + _json != null -> "BetaResponseSteerInputContent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BetaResponseSteerInputContent") + } + + companion object { + + /** A text input to the model. */ + @JvmStatic + fun ofInputText(inputText: BetaResponseInputTextContent) = + BetaResponseSteerInputContent(inputText = inputText) + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + @JvmStatic + fun ofInputImage(inputImage: BetaResponseInputImageContent) = + BetaResponseSteerInputContent(inputImage = inputImage) + + /** A file input to the model. */ + @JvmStatic + fun ofInputFile(inputFile: BetaResponseInputFileContent) = + BetaResponseSteerInputContent(inputFile = inputFile) + } + + /** + * An interface that defines how to map each variant of [BetaResponseSteerInputContent] to a + * value of type [T]. + */ + interface Visitor { + + /** A text input to the model. */ + fun visitInputText(inputText: BetaResponseInputTextContent): T + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun visitInputImage(inputImage: BetaResponseInputImageContent): T + + /** A file input to the model. */ + fun visitInputFile(inputFile: BetaResponseInputFileContent): T + + /** + * Maps an unknown variant of [BetaResponseSteerInputContent] to a value of type [T]. + * + * An instance of [BetaResponseSteerInputContent] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BetaResponseSteerInputContent: $json") + } + } + + internal class Deserializer : + BaseDeserializer(BetaResponseSteerInputContent::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BetaResponseSteerInputContent { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "input_text" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponseSteerInputContent(inputText = it, _json = json) } + ?: BetaResponseSteerInputContent(_json = json) + } + "input_image" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponseSteerInputContent(inputImage = it, _json = json) } + ?: BetaResponseSteerInputContent(_json = json) + } + "input_file" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponseSteerInputContent(inputFile = it, _json = json) } + ?: BetaResponseSteerInputContent(_json = json) + } + } + + return BetaResponseSteerInputContent(_json = json) + } + } + + internal class Serializer : + BaseSerializer(BetaResponseSteerInputContent::class) { + + override fun serialize( + value: BetaResponseSteerInputContent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.inputText != null -> generator.writeObject(value.inputText) + value.inputImage != null -> generator.writeObject(value.inputImage) + value.inputFile != null -> generator.writeObject(value.inputFile) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BetaResponseSteerInputContent") + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEvent.kt new file mode 100644 index 000000000..247ef145d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEvent.kt @@ -0,0 +1,824 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkKnown +import com.openai.core.checkRequired +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is the + * commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while the + * response waits for the tool results or approval decisions identified by `required_input`. Copy + * those stubs, fill their result fields using the ordinary `response.create` input schemas, and + * submit one continuation per parent with the same `previous_response_id` and WebSocket lane. Use + * saved results without rerunning tools. The queued steering input is prepended in submission order + * to the continuation's input. That explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for the + * same parent can report the same required inputs; they do not each require a separate + * continuation. + */ +class BetaResponseSteerPendingEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val reason: JsonField, + private val requiredInput: JsonField>, + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("reason") + @ExcludeMissing + reason: JsonField = JsonMissing.of(), + @JsonProperty("required_input") + @ExcludeMissing + requiredInput: JsonField> = JsonMissing.of(), + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(reason, requiredInput, sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * An extensible enum describing why accepted steering input is still queued. Clients should + * handle unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun reason(): BetaResponseSteerPendingReason = reason.getRequired("reason") + + /** + * Input stubs identifying outstanding client-owned tool results or approval decisions. Each + * stub contains identifying fields only; the client supplies the result before including it in + * `response.create`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun requiredInput(): List = + requiredInput.getRequired("required_input") + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The steering submission that remains queued. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.pending`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.pending") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event. This field is present when the target response's + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") + @ExcludeMissing + fun _reason(): JsonField = reason + + /** + * Returns the raw JSON value of [requiredInput]. + * + * Unlike [requiredInput], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("required_input") + @ExcludeMissing + fun _requiredInput(): JsonField> = requiredInput + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [BetaResponseSteerPendingEvent]. + * + * The following fields are required: + * ```java + * .reason() + * .requiredInput() + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [BetaResponseSteerPendingEvent]. */ + class Builder internal constructor() { + + private var reason: JsonField? = null + private var requiredInput: JsonField>? = null + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.pending") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(betaResponseSteerPendingEvent: BetaResponseSteerPendingEvent) = apply { + reason = betaResponseSteerPendingEvent.reason + requiredInput = betaResponseSteerPendingEvent.requiredInput.map { it.toMutableList() } + sequenceNumber = betaResponseSteerPendingEvent.sequenceNumber + steer = betaResponseSteerPendingEvent.steer + type = betaResponseSteerPendingEvent.type + streamId = betaResponseSteerPendingEvent.streamId + additionalProperties = betaResponseSteerPendingEvent.additionalProperties.toMutableMap() + } + + /** + * An extensible enum describing why accepted steering input is still queued. Clients should + * handle unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + */ + fun reason(reason: BetaResponseSteerPendingReason) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed + * [BetaResponseSteerPendingReason] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun reason(reason: JsonField) = apply { + this.reason = reason + } + + /** + * Sets [reason] to an arbitrary [String]. + * + * You should usually call [reason] with a well-typed [BetaResponseSteerPendingReason] + * constant instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun reason(value: String) = reason(BetaResponseSteerPendingReason.of(value)) + + /** + * Input stubs identifying outstanding client-owned tool results or approval decisions. Each + * stub contains identifying fields only; the client supplies the result before including it + * in `response.create`. + */ + fun requiredInput(requiredInput: List) = + requiredInput(JsonField.of(requiredInput)) + + /** + * Sets [Builder.requiredInput] to an arbitrary JSON value. + * + * You should usually call [Builder.requiredInput] with a well-typed + * `List` value instead. This method is primarily for + * setting the field to an undocumented or not yet supported value. + */ + fun requiredInput(requiredInput: JsonField>) = apply { + this.requiredInput = requiredInput.map { it.toMutableList() } + } + + /** + * Adds a single [BetaResponseSteerRequiredInput] to [Builder.requiredInput]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRequiredInput(requiredInput: BetaResponseSteerRequiredInput) = apply { + this.requiredInput = + (this.requiredInput ?: JsonField.of(mutableListOf())).also { + checkKnown("requiredInput", it).add(requiredInput) + } + } + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput)`. + */ + fun addRequiredInput( + functionCallOutput: BetaResponseSteerRequiredInput.FunctionCallOutput + ) = + addRequiredInput( + BetaResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput)`. + */ + fun addRequiredInput( + customToolCallOutput: BetaResponseSteerRequiredInput.CustomToolCallOutput + ) = + addRequiredInput( + BetaResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.CustomToolCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addCustomToolCallOutputRequiredInput(callId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.CustomToolCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput)`. + */ + fun addRequiredInput( + computerCallOutput: BetaResponseSteerRequiredInput.ComputerCallOutput + ) = + addRequiredInput( + BetaResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.ComputerCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addComputerCallOutputRequiredInput(callId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.ComputerCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput)`. + */ + fun addRequiredInput(shellCallOutput: BetaResponseSteerRequiredInput.ShellCallOutput) = + addRequiredInput(BetaResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.ShellCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addShellCallOutputRequiredInput(callId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.ShellCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput)`. + */ + fun addRequiredInput( + applyPatchCallOutput: BetaResponseSteerRequiredInput.ApplyPatchCallOutput + ) = + addRequiredInput( + BetaResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.ApplyPatchCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addApplyPatchCallOutputRequiredInput(callId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.ApplyPatchCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput)`. + */ + fun addRequiredInput(toolSearchOutput: BetaResponseSteerRequiredInput.ToolSearchOutput) = + addRequiredInput(BetaResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.ToolSearchOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addToolSearchOutputRequiredInput(callId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.ToolSearchOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `BetaResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse)`. + */ + fun addRequiredInput( + mcpApprovalResponse: BetaResponseSteerRequiredInput.McpApprovalResponse + ) = + addRequiredInput( + BetaResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * BetaResponseSteerRequiredInput.McpApprovalResponse.builder() + * .approvalRequestId(approvalRequestId) + * .build() + * ``` + */ + fun addMcpApprovalResponseRequiredInput(approvalRequestId: String) = + addRequiredInput( + BetaResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId(approvalRequestId) + .build() + ) + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The steering submission that remains queued. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.pending") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event. This field is present when the target + * response's `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [BetaResponseSteerPendingEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .reason() + * .requiredInput() + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): BetaResponseSteerPendingEvent = + BetaResponseSteerPendingEvent( + checkRequired("reason", reason), + checkRequired("requiredInput", requiredInput).map { it.toImmutable() }, + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerPendingEvent = apply { + if (validated) { + return@apply + } + + reason() + requiredInput().forEach { it.validate() } + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.pending")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (reason.asKnown().isPresent) 1 else 0) + + (requiredInput.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.pending")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** The steering submission that remains queued. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val previousResponseId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + ) : this(id, previousResponseId, mutableMapOf()) + + /** + * The ID assigned to the steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The ID of the response being steered. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var previousResponseId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + id = steer.id + previousResponseId = steer.previousResponseId + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The ID assigned to the steering submission. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The ID of the response being steered. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("id", id), + checkRequired("previousResponseId", previousResponseId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + id() + previousResponseId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + id == other.id && + previousResponseId == other.previousResponseId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, previousResponseId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{id=$id, previousResponseId=$previousResponseId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerPendingEvent && + reason == other.reason && + requiredInput == other.requiredInput && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + reason, + requiredInput, + sequenceNumber, + steer, + type, + streamId, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "BetaResponseSteerPendingEvent{reason=$reason, requiredInput=$requiredInput, sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingReason.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingReason.kt new file mode 100644 index 000000000..3a5e91c91 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingReason.kt @@ -0,0 +1,146 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.errors.OpenAIInvalidDataException + +/** + * An extensible enum describing why accepted steering input is still queued. Clients should handle + * unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + */ +class BetaResponseSteerPendingReason +@JsonCreator +private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't match + * any known member, and you want to know that value. For example, if the SDK is on an older + * version than the API, then the API may respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val WAITING_FOR_REQUIRED_INPUT = of("waiting_for_required_input") + + @JvmStatic fun of(value: String) = BetaResponseSteerPendingReason(JsonField.of(value)) + } + + /** An enum containing [BetaResponseSteerPendingReason]'s known values. */ + enum class Known { + WAITING_FOR_REQUIRED_INPUT + } + + /** + * An enum containing [BetaResponseSteerPendingReason]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [BetaResponseSteerPendingReason] can contain an unknown value in a couple of + * cases: + * - It was deserialized from data that doesn't match any known member. For example, if the SDK + * is on an older version than the API, then the API may respond with new members that the SDK + * is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + WAITING_FOR_REQUIRED_INPUT, + /** + * An enum member indicating that [BetaResponseSteerPendingReason] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] if + * the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want to + * throw for the unknown case. + */ + fun value(): Value = + when (this) { + WAITING_FOR_REQUIRED_INPUT -> Value.WAITING_FOR_REQUIRED_INPUT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't want + * to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + WAITING_FOR_REQUIRED_INPUT -> Known.WAITING_FOR_REQUIRED_INPUT + else -> + throw OpenAIInvalidDataException("Unknown BetaResponseSteerPendingReason: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging and + * generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerPendingReason = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerPendingReason && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInput.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInput.kt new file mode 100644 index 000000000..fa772ce4a --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInput.kt @@ -0,0 +1,2054 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * An input stub identifying an outstanding client-owned tool result or approval decision. Copy the + * stub and fill the result fields using the corresponding `response.create` input schema. Use saved + * results without rerunning the tool. The server does not supply results, approval decisions, or + * safety acknowledgements in these stubs. + */ +@JsonDeserialize(using = BetaResponseSteerRequiredInput.Deserializer::class) +@JsonSerialize(using = BetaResponseSteerRequiredInput.Serializer::class) +class BetaResponseSteerRequiredInput +private constructor( + private val functionCallOutput: FunctionCallOutput? = null, + private val customToolCallOutput: CustomToolCallOutput? = null, + private val computerCallOutput: ComputerCallOutput? = null, + private val shellCallOutput: ShellCallOutput? = null, + private val applyPatchCallOutput: ApplyPatchCallOutput? = null, + private val toolSearchOutput: ToolSearchOutput? = null, + private val mcpApprovalResponse: McpApprovalResponse? = null, + private val _json: JsonValue? = null, +) { + + /** Supply `output` using the function tool call output input schema. */ + fun functionCallOutput(): Optional = Optional.ofNullable(functionCallOutput) + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + fun customToolCallOutput(): Optional = + Optional.ofNullable(customToolCallOutput) + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun computerCallOutput(): Optional = Optional.ofNullable(computerCallOutput) + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun shellCallOutput(): Optional = Optional.ofNullable(shellCallOutput) + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + fun applyPatchCallOutput(): Optional = + Optional.ofNullable(applyPatchCallOutput) + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + fun toolSearchOutput(): Optional = Optional.ofNullable(toolSearchOutput) + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + fun mcpApprovalResponse(): Optional = + Optional.ofNullable(mcpApprovalResponse) + + fun isFunctionCallOutput(): Boolean = functionCallOutput != null + + fun isCustomToolCallOutput(): Boolean = customToolCallOutput != null + + fun isComputerCallOutput(): Boolean = computerCallOutput != null + + fun isShellCallOutput(): Boolean = shellCallOutput != null + + fun isApplyPatchCallOutput(): Boolean = applyPatchCallOutput != null + + fun isToolSearchOutput(): Boolean = toolSearchOutput != null + + fun isMcpApprovalResponse(): Boolean = mcpApprovalResponse != null + + /** Supply `output` using the function tool call output input schema. */ + fun asFunctionCallOutput(): FunctionCallOutput = + functionCallOutput.getOrThrow("functionCallOutput") + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + fun asCustomToolCallOutput(): CustomToolCallOutput = + customToolCallOutput.getOrThrow("customToolCallOutput") + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun asComputerCallOutput(): ComputerCallOutput = + computerCallOutput.getOrThrow("computerCallOutput") + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun asShellCallOutput(): ShellCallOutput = shellCallOutput.getOrThrow("shellCallOutput") + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + fun asApplyPatchCallOutput(): ApplyPatchCallOutput = + applyPatchCallOutput.getOrThrow("applyPatchCallOutput") + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + fun asToolSearchOutput(): ToolSearchOutput = toolSearchOutput.getOrThrow("toolSearchOutput") + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + fun asMcpApprovalResponse(): McpApprovalResponse = + mcpApprovalResponse.getOrThrow("mcpApprovalResponse") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = betaResponseSteerRequiredInput.accept(new BetaResponseSteerRequiredInput.Visitor>() { + * @Override + * public Optional visitFunctionCallOutput(FunctionCallOutput functionCallOutput) { + * return Optional.of(functionCallOutput.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + functionCallOutput != null -> visitor.visitFunctionCallOutput(functionCallOutput) + customToolCallOutput != null -> visitor.visitCustomToolCallOutput(customToolCallOutput) + computerCallOutput != null -> visitor.visitComputerCallOutput(computerCallOutput) + shellCallOutput != null -> visitor.visitShellCallOutput(shellCallOutput) + applyPatchCallOutput != null -> visitor.visitApplyPatchCallOutput(applyPatchCallOutput) + toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) + mcpApprovalResponse != null -> visitor.visitMcpApprovalResponse(mcpApprovalResponse) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): BetaResponseSteerRequiredInput = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) { + functionCallOutput.validate() + } + + override fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) { + customToolCallOutput.validate() + } + + override fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput) { + computerCallOutput.validate() + } + + override fun visitShellCallOutput(shellCallOutput: ShellCallOutput) { + shellCallOutput.validate() + } + + override fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) { + applyPatchCallOutput.validate() + } + + override fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput) { + toolSearchOutput.validate() + } + + override fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) { + mcpApprovalResponse.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + functionCallOutput.validity() + + override fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) = + customToolCallOutput.validity() + + override fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput) = + computerCallOutput.validity() + + override fun visitShellCallOutput(shellCallOutput: ShellCallOutput) = + shellCallOutput.validity() + + override fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) = + applyPatchCallOutput.validity() + + override fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput) = + toolSearchOutput.validity() + + override fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) = + mcpApprovalResponse.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is BetaResponseSteerRequiredInput && + functionCallOutput == other.functionCallOutput && + customToolCallOutput == other.customToolCallOutput && + computerCallOutput == other.computerCallOutput && + shellCallOutput == other.shellCallOutput && + applyPatchCallOutput == other.applyPatchCallOutput && + toolSearchOutput == other.toolSearchOutput && + mcpApprovalResponse == other.mcpApprovalResponse + } + + override fun hashCode(): Int = + Objects.hash( + functionCallOutput, + customToolCallOutput, + computerCallOutput, + shellCallOutput, + applyPatchCallOutput, + toolSearchOutput, + mcpApprovalResponse, + ) + + override fun toString(): String = + when { + functionCallOutput != null -> + "BetaResponseSteerRequiredInput{functionCallOutput=$functionCallOutput}" + customToolCallOutput != null -> + "BetaResponseSteerRequiredInput{customToolCallOutput=$customToolCallOutput}" + computerCallOutput != null -> + "BetaResponseSteerRequiredInput{computerCallOutput=$computerCallOutput}" + shellCallOutput != null -> + "BetaResponseSteerRequiredInput{shellCallOutput=$shellCallOutput}" + applyPatchCallOutput != null -> + "BetaResponseSteerRequiredInput{applyPatchCallOutput=$applyPatchCallOutput}" + toolSearchOutput != null -> + "BetaResponseSteerRequiredInput{toolSearchOutput=$toolSearchOutput}" + mcpApprovalResponse != null -> + "BetaResponseSteerRequiredInput{mcpApprovalResponse=$mcpApprovalResponse}" + _json != null -> "BetaResponseSteerRequiredInput{_unknown=$_json}" + else -> throw IllegalStateException("Invalid BetaResponseSteerRequiredInput") + } + + companion object { + + /** Supply `output` using the function tool call output input schema. */ + @JvmStatic + fun ofFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + BetaResponseSteerRequiredInput(functionCallOutput = functionCallOutput) + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool + * call supplies the tool's name. + */ + @JvmStatic + fun ofCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) = + BetaResponseSteerRequiredInput(customToolCallOutput = customToolCallOutput) + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + @JvmStatic + fun ofComputerCallOutput(computerCallOutput: ComputerCallOutput) = + BetaResponseSteerRequiredInput(computerCallOutput = computerCallOutput) + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + @JvmStatic + fun ofShellCallOutput(shellCallOutput: ShellCallOutput) = + BetaResponseSteerRequiredInput(shellCallOutput = shellCallOutput) + + /** + * Supply `status` and optional `output` using the apply patch tool call output input + * schema. + */ + @JvmStatic + fun ofApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) = + BetaResponseSteerRequiredInput(applyPatchCallOutput = applyPatchCallOutput) + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: + * "client"`. + */ + @JvmStatic + fun ofToolSearchOutput(toolSearchOutput: ToolSearchOutput) = + BetaResponseSteerRequiredInput(toolSearchOutput = toolSearchOutput) + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can + * be supplied when denying the request. The original approval request identifies the tool + * and server. + */ + @JvmStatic + fun ofMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) = + BetaResponseSteerRequiredInput(mcpApprovalResponse = mcpApprovalResponse) + } + + /** + * An interface that defines how to map each variant of [BetaResponseSteerRequiredInput] to a + * value of type [T]. + */ + interface Visitor { + + /** Supply `output` using the function tool call output input schema. */ + fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput): T + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool + * call supplies the tool's name. + */ + fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput): T + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput): T + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun visitShellCallOutput(shellCallOutput: ShellCallOutput): T + + /** + * Supply `status` and optional `output` using the apply patch tool call output input + * schema. + */ + fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput): T + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: + * "client"`. + */ + fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput): T + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can + * be supplied when denying the request. The original approval request identifies the tool + * and server. + */ + fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse): T + + /** + * Maps an unknown variant of [BetaResponseSteerRequiredInput] to a value of type [T]. + * + * An instance of [BetaResponseSteerRequiredInput] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown BetaResponseSteerRequiredInput: $json") + } + } + + internal class Deserializer : + BaseDeserializer(BetaResponseSteerRequiredInput::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): BetaResponseSteerRequiredInput { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "function_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(functionCallOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "custom_tool_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(customToolCallOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "computer_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(computerCallOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "shell_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(shellCallOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "apply_patch_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(applyPatchCallOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "tool_search_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(toolSearchOutput = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + "mcp_approval_response" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponseSteerRequiredInput(mcpApprovalResponse = it, _json = json) + } ?: BetaResponseSteerRequiredInput(_json = json) + } + } + + return BetaResponseSteerRequiredInput(_json = json) + } + } + + internal class Serializer : + BaseSerializer(BetaResponseSteerRequiredInput::class) { + + override fun serialize( + value: BetaResponseSteerRequiredInput, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.functionCallOutput != null -> generator.writeObject(value.functionCallOutput) + value.customToolCallOutput != null -> + generator.writeObject(value.customToolCallOutput) + value.computerCallOutput != null -> generator.writeObject(value.computerCallOutput) + value.shellCallOutput != null -> generator.writeObject(value.shellCallOutput) + value.applyPatchCallOutput != null -> + generator.writeObject(value.applyPatchCallOutput) + value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) + value.mcpApprovalResponse != null -> + generator.writeObject(value.mcpApprovalResponse) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid BetaResponseSteerRequiredInput") + } + } + } + + /** Supply `output` using the function tool call output input schema. */ + class FunctionCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, name, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [FunctionCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FunctionCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("function_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(functionCallOutput: FunctionCallOutput) = apply { + callId = functionCallOutput.callId + name = functionCallOutput.name + type = functionCallOutput.type + additionalProperties = functionCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [FunctionCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FunctionCallOutput = + FunctionCallOutput( + checkRequired("callId", callId), + checkRequired("name", name), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): FunctionCallOutput = apply { + if (validated) { + return@apply + } + + callId() + name() + _type().let { + if (it != JsonValue.from("function_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("function_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FunctionCallOutput && + callId == other.callId && + name == other.name && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, name, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCallOutput{callId=$callId, name=$name, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + class CustomToolCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("custom_tool_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [CustomToolCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CustomToolCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("custom_tool_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(customToolCallOutput: CustomToolCallOutput) = apply { + callId = customToolCallOutput.callId + type = customToolCallOutput.type + additionalProperties = customToolCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("custom_tool_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [CustomToolCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CustomToolCallOutput = + CustomToolCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): CustomToolCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("custom_tool_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("custom_tool_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CustomToolCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CustomToolCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + class ComputerCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("computer_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ComputerCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ComputerCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("computer_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(computerCallOutput: ComputerCallOutput) = apply { + callId = computerCallOutput.callId + type = computerCallOutput.type + additionalProperties = computerCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("computer_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ComputerCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ComputerCallOutput = + ComputerCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ComputerCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("computer_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("computer_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ComputerCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ComputerCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + class ShellCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("shell_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ShellCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ShellCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("shell_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(shellCallOutput: ShellCallOutput) = apply { + callId = shellCallOutput.callId + type = shellCallOutput.type + additionalProperties = shellCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("shell_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ShellCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ShellCallOutput = + ShellCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ShellCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("shell_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("shell_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ShellCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ShellCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + class ApplyPatchCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("apply_patch_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ApplyPatchCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ApplyPatchCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("apply_patch_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(applyPatchCallOutput: ApplyPatchCallOutput) = apply { + callId = applyPatchCallOutput.callId + type = applyPatchCallOutput.type + additionalProperties = applyPatchCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("apply_patch_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ApplyPatchCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ApplyPatchCallOutput = + ApplyPatchCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ApplyPatchCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("apply_patch_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("apply_patch_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ApplyPatchCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ApplyPatchCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + class ToolSearchOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val execution: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("execution") @ExcludeMissing execution: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, execution, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("client") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("execution") @ExcludeMissing fun _execution(): JsonValue = execution + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("tool_search_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ToolSearchOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ToolSearchOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var execution: JsonValue = JsonValue.from("client") + private var type: JsonValue = JsonValue.from("tool_search_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(toolSearchOutput: ToolSearchOutput) = apply { + callId = toolSearchOutput.callId + execution = toolSearchOutput.execution + type = toolSearchOutput.type + additionalProperties = toolSearchOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("client") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun execution(execution: JsonValue) = apply { this.execution = execution } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("tool_search_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ToolSearchOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ToolSearchOutput = + ToolSearchOutput( + checkRequired("callId", callId), + execution, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ToolSearchOutput = apply { + if (validated) { + return@apply + } + + callId() + _execution().let { + if (it != JsonValue.from("client")) { + throw OpenAIInvalidDataException("'execution' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("tool_search_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + execution.let { if (it == JsonValue.from("client")) 1 else 0 } + + type.let { if (it == JsonValue.from("tool_search_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ToolSearchOutput && + callId == other.callId && + execution == other.execution && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(callId, execution, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ToolSearchOutput{callId=$callId, execution=$execution, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + class McpApprovalResponse + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val approvalRequestId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("approval_request_id") + @ExcludeMissing + approvalRequestId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(approvalRequestId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun approvalRequestId(): String = approvalRequestId.getRequired("approval_request_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("mcp_approval_response") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [approvalRequestId]. + * + * Unlike [approvalRequestId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("approval_request_id") + @ExcludeMissing + fun _approvalRequestId(): JsonField = approvalRequestId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [McpApprovalResponse]. + * + * The following fields are required: + * ```java + * .approvalRequestId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [McpApprovalResponse]. */ + class Builder internal constructor() { + + private var approvalRequestId: JsonField? = null + private var type: JsonValue = JsonValue.from("mcp_approval_response") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(mcpApprovalResponse: McpApprovalResponse) = apply { + approvalRequestId = mcpApprovalResponse.approvalRequestId + type = mcpApprovalResponse.type + additionalProperties = mcpApprovalResponse.additionalProperties.toMutableMap() + } + + fun approvalRequestId(approvalRequestId: String) = + approvalRequestId(JsonField.of(approvalRequestId)) + + /** + * Sets [Builder.approvalRequestId] to an arbitrary JSON value. + * + * You should usually call [Builder.approvalRequestId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun approvalRequestId(approvalRequestId: JsonField) = apply { + this.approvalRequestId = approvalRequestId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("mcp_approval_response") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [McpApprovalResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .approvalRequestId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): McpApprovalResponse = + McpApprovalResponse( + checkRequired("approvalRequestId", approvalRequestId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): McpApprovalResponse = apply { + if (validated) { + return@apply + } + + approvalRequestId() + _type().let { + if (it != JsonValue.from("mcp_approval_response")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (approvalRequestId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("mcp_approval_response")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is McpApprovalResponse && + approvalRequestId == other.approvalRequestId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(approvalRequestId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "McpApprovalResponse{approvalRequestId=$approvalRequestId, type=$type, additionalProperties=$additionalProperties}" + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseStreamEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseStreamEvent.kt index 03ff9f1f1..749419b01 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseStreamEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponseStreamEvent.kt @@ -214,7 +214,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun responseFailed(): Optional = Optional.ofNullable(responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun responseIncomplete(): Optional = Optional.ofNullable(responseIncomplete) @@ -578,7 +584,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun asResponseFailed(): BetaResponseFailedEvent = responseFailed.getOrThrow("responseFailed") - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun asResponseIncomplete(): BetaResponseIncompleteEvent = responseIncomplete.getOrThrow("responseIncomplete") @@ -1924,7 +1936,13 @@ private constructor( fun ofResponseFailed(responseFailed: BetaResponseFailedEvent) = BetaResponseStreamEvent(responseFailed = responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ @JvmStatic fun ofResponseIncomplete(responseIncomplete: BetaResponseIncompleteEvent) = BetaResponseStreamEvent(responseIncomplete = responseIncomplete) @@ -2275,7 +2293,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun visitResponseFailed(responseFailed: BetaResponseFailedEvent): T - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ fun visitResponseIncomplete(responseIncomplete: BetaResponseIncompleteEvent): T /** Emitted when a new output item is added. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesClientEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesClientEvent.kt index 4d32506e9..69c3464cf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesClientEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesClientEvent.kt @@ -37,6 +37,7 @@ import kotlin.jvm.optionals.getOrNull class BetaResponsesClientEvent private constructor( private val responseCreate: ResponseCreate? = null, + private val responseSteer: BetaResponseSteerEvent? = null, private val responseInject: BetaResponseInjectEvent? = null, private val _json: JsonValue? = null, ) { @@ -53,6 +54,35 @@ private constructor( */ fun responseCreate(): Optional = Optional.ofNullable(responseCreate) + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and + * execution modes that support steering. Responses bound to a conversation or using automatic + * compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. Input + * that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed by an + * automatic successor. Automatic successors inherit the previous response's settings and + * continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and + * send one explicit `response.create` per parent with the same `previous_response_id` and + * WebSocket lane. Do not rerun tools or resend accepted steering input. The queued input is + * prepended in submission order to that request's input, and the explicit request retains its + * own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; + * the target response determines the WebSocket lane. + */ + fun responseSteer(): Optional = Optional.ofNullable(responseSteer) + /** * Injects input items into an active response over a WebSocket connection. The items are * validated and committed atomically. Currently, the server accepts client-owned tool outputs @@ -62,6 +92,8 @@ private constructor( fun isResponseCreate(): Boolean = responseCreate != null + fun isResponseSteer(): Boolean = responseSteer != null + fun isResponseInject(): Boolean = responseInject != null /** @@ -76,6 +108,35 @@ private constructor( */ fun asResponseCreate(): ResponseCreate = responseCreate.getOrThrow("responseCreate") + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and + * execution modes that support steering. Responses bound to a conversation or using automatic + * compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. Input + * that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed by an + * automatic successor. Automatic successors inherit the previous response's settings and + * continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and + * send one explicit `response.create` per parent with the same `previous_response_id` and + * WebSocket lane. Do not rerun tools or resend accepted steering input. The queued input is + * prepended in submission order to that request's input, and the explicit request retains its + * own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; + * the target response determines the WebSocket lane. + */ + fun asResponseSteer(): BetaResponseSteerEvent = responseSteer.getOrThrow("responseSteer") + /** * Injects input items into an active response over a WebSocket connection. The items are * validated and committed atomically. Currently, the server accepts client-owned tool outputs @@ -117,6 +178,7 @@ private constructor( fun accept(visitor: Visitor): T = when { responseCreate != null -> visitor.visitResponseCreate(responseCreate) + responseSteer != null -> visitor.visitResponseSteer(responseSteer) responseInject != null -> visitor.visitResponseInject(responseInject) else -> visitor.unknown(_json) } @@ -142,6 +204,10 @@ private constructor( responseCreate.validate() } + override fun visitResponseSteer(responseSteer: BetaResponseSteerEvent) { + responseSteer.validate() + } + override fun visitResponseInject(responseInject: BetaResponseInjectEvent) { responseInject.validate() } @@ -170,6 +236,9 @@ private constructor( override fun visitResponseCreate(responseCreate: ResponseCreate) = responseCreate.validity() + override fun visitResponseSteer(responseSteer: BetaResponseSteerEvent) = + responseSteer.validity() + override fun visitResponseInject(responseInject: BetaResponseInjectEvent) = responseInject.validity() @@ -184,14 +253,16 @@ private constructor( return other is BetaResponsesClientEvent && responseCreate == other.responseCreate && + responseSteer == other.responseSteer && responseInject == other.responseInject } - override fun hashCode(): Int = Objects.hash(responseCreate, responseInject) + override fun hashCode(): Int = Objects.hash(responseCreate, responseSteer, responseInject) override fun toString(): String = when { responseCreate != null -> "BetaResponsesClientEvent{responseCreate=$responseCreate}" + responseSteer != null -> "BetaResponsesClientEvent{responseSteer=$responseSteer}" responseInject != null -> "BetaResponsesClientEvent{responseInject=$responseInject}" _json != null -> "BetaResponsesClientEvent{_unknown=$_json}" else -> throw IllegalStateException("Invalid BetaResponsesClientEvent") @@ -213,6 +284,37 @@ private constructor( fun ofResponseCreate(responseCreate: ResponseCreate) = BetaResponsesClientEvent(responseCreate = responseCreate) + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain + * text, images, and files. Steering is supported only for single-agent responses on models + * and execution modes that support steering. Responses bound to a conversation or using + * automatic compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. + * Input that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed + * by an automatic successor. Automatic successors inherit the previous response's settings + * and continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill + * the `required_input` stubs from that event with saved tool results or approval decisions, + * and send one explicit `response.create` per parent with the same `previous_response_id` + * and WebSocket lane. Do not rerun tools or resend accepted steering input. The queued + * input is prepended in submission order to that request's input, and the explicit request + * retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send + * `stream_id`; the target response determines the WebSocket lane. + */ + @JvmStatic + fun ofResponseSteer(responseSteer: BetaResponseSteerEvent) = + BetaResponsesClientEvent(responseSteer = responseSteer) + /** * Injects input items into an active response over a WebSocket connection. The items are * validated and committed atomically. Currently, the server accepts client-owned tool @@ -241,6 +343,35 @@ private constructor( */ fun visitResponseCreate(responseCreate: ResponseCreate): T + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain + * text, images, and files. Steering is supported only for single-agent responses on models + * and execution modes that support steering. Responses bound to a conversation or using + * automatic compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. + * Input that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed + * by an automatic successor. Automatic successors inherit the previous response's settings + * and continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill + * the `required_input` stubs from that event with saved tool results or approval decisions, + * and send one explicit `response.create` per parent with the same `previous_response_id` + * and WebSocket lane. Do not rerun tools or resend accepted steering input. The queued + * input is prepended in submission order to that request's input, and the explicit request + * retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send + * `stream_id`; the target response determines the WebSocket lane. + */ + fun visitResponseSteer(responseSteer: BetaResponseSteerEvent): T + /** * Injects input items into an active response over a WebSocket connection. The items are * validated and committed atomically. Currently, the server accepts client-owned tool @@ -276,6 +407,11 @@ private constructor( BetaResponsesClientEvent(responseCreate = it, _json = json) } ?: BetaResponsesClientEvent(_json = json) } + "response.steer" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + BetaResponsesClientEvent(responseSteer = it, _json = json) + } ?: BetaResponsesClientEvent(_json = json) + } "response.inject" -> { return tryDeserialize(node, jacksonTypeRef())?.let { BetaResponsesClientEvent(responseInject = it, _json = json) @@ -297,6 +433,7 @@ private constructor( ) { when { value.responseCreate != null -> generator.writeObject(value.responseCreate) + value.responseSteer != null -> generator.writeObject(value.responseSteer) value.responseInject != null -> generator.writeObject(value.responseInject) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid BetaResponsesClientEvent") @@ -606,7 +743,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -1581,7 +1718,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse * and compare available models. @@ -3382,7 +3519,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -3401,6 +3538,8 @@ private constructor( companion object { + @JvmField val GPT_6_ASTRA = of("gpt-6-astra") + @JvmField val GPT_5_6_SOL = of("gpt-5.6-sol") @JvmField val GPT_5_6_TERRA = of("gpt-5.6-terra") @@ -3620,6 +3759,7 @@ private constructor( /** An enum containing [Model]'s known values. */ enum class Known { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -3734,6 +3874,7 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -3851,6 +3992,7 @@ private constructor( */ fun value(): Value = when (this) { + GPT_6_ASTRA -> Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -3969,6 +4111,7 @@ private constructor( */ fun known(): Known = when (this) { + GPT_6_ASTRA -> Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesServerEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesServerEvent.kt index 5b41025bd..269fc54bc 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesServerEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/BetaResponsesServerEvent.kt @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer +import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -112,6 +113,9 @@ private constructor( private val responseCustomToolCallInputDelta: BetaResponseCustomToolCallInputDeltaEvent? = null, private val responseCustomToolCallInputDone: BetaResponseCustomToolCallInputDoneEvent? = null, private val error: BetaResponseWsError? = null, + private val responseSteerAccepted: BetaResponseSteerAcceptedEvent? = null, + private val responseSteerPending: BetaResponseSteerPendingEvent? = null, + private val responseSteerFailed: BetaResponseSteerFailedEvent? = null, private val responseInjectCreated: BetaResponseInjectCreatedEvent? = null, private val responseInjectFailed: BetaResponseInjectFailedEvent? = null, private val _json: JsonValue? = null, @@ -223,7 +227,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun responseFailed(): Optional = Optional.ofNullable(responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun responseIncomplete(): Optional = Optional.ofNullable(responseIncomplete) @@ -359,6 +369,52 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun error(): Optional = Optional.ofNullable(error) + /** + * Emitted when steering input has been validated and queued. Acceptance means the server owns + * the input, not that it has been applied. The successor's `response.created` event is the + * commit point. If accepted input cannot be committed, `response.steer.failed` returns it with + * the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued + * and `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` + * per parent. Do not resend accepted input while it is still queued. + */ + fun responseSteerAccepted(): Optional = + Optional.ofNullable(responseSteerAccepted) + + /** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is + * the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while + * the response waits for the tool results or approval decisions identified by `required_input`. + * Copy those stubs, fill their result fields using the ordinary `response.create` input + * schemas, and submit one continuation per parent with the same `previous_response_id` and + * WebSocket lane. Use saved results without rerunning tools. The queued steering input is + * prepended in submission order to the continuation's input. That explicit request retains its + * own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for + * the same parent can report the same required inputs; they do not each require a separate + * continuation. + */ + fun responseSteerPending(): Optional = + Optional.ofNullable(responseSteerPending) + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated + * omit `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it + * is not proof that the input was rejected. + */ + fun responseSteerFailed(): Optional = + Optional.ofNullable(responseSteerFailed) + /** * Emitted when all injected input items were validated and committed to the active response. */ @@ -599,6 +655,12 @@ private constructor( error != null -> error._streamId() + responseSteerAccepted != null -> responseSteerAccepted._streamId() + + responseSteerPending != null -> responseSteerPending._streamId() + + responseSteerFailed != null -> responseSteerFailed._streamId() + responseInjectCreated != null -> responseInjectCreated._streamId() responseInjectFailed != null -> responseInjectFailed._streamId() @@ -732,6 +794,12 @@ private constructor( fun isError(): Boolean = error != null + fun isResponseSteerAccepted(): Boolean = responseSteerAccepted != null + + fun isResponseSteerPending(): Boolean = responseSteerPending != null + + fun isResponseSteerFailed(): Boolean = responseSteerFailed != null + fun isResponseInjectCreated(): Boolean = responseInjectCreated != null fun isResponseInjectFailed(): Boolean = responseInjectFailed != null @@ -838,7 +906,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun asResponseFailed(): BetaResponseFailedEvent = responseFailed.getOrThrow("responseFailed") - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun asResponseIncomplete(): BetaResponseIncompleteEvent = responseIncomplete.getOrThrow("responseIncomplete") @@ -975,6 +1049,52 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun asError(): BetaResponseWsError = error.getOrThrow("error") + /** + * Emitted when steering input has been validated and queued. Acceptance means the server owns + * the input, not that it has been applied. The successor's `response.created` event is the + * commit point. If accepted input cannot be committed, `response.steer.failed` returns it with + * the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued + * and `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` + * per parent. Do not resend accepted input while it is still queued. + */ + fun asResponseSteerAccepted(): BetaResponseSteerAcceptedEvent = + responseSteerAccepted.getOrThrow("responseSteerAccepted") + + /** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is + * the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while + * the response waits for the tool results or approval decisions identified by `required_input`. + * Copy those stubs, fill their result fields using the ordinary `response.create` input + * schemas, and submit one continuation per parent with the same `previous_response_id` and + * WebSocket lane. Use saved results without rerunning tools. The queued steering input is + * prepended in submission order to the continuation's input. That explicit request retains its + * own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for + * the same parent can report the same required inputs; they do not each require a separate + * continuation. + */ + fun asResponseSteerPending(): BetaResponseSteerPendingEvent = + responseSteerPending.getOrThrow("responseSteerPending") + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated + * omit `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it + * is not proof that the input was rejected. + */ + fun asResponseSteerFailed(): BetaResponseSteerFailedEvent = + responseSteerFailed.getOrThrow("responseSteerFailed") + /** * Emitted when all injected input items were validated and committed to the active response. */ @@ -1146,6 +1266,10 @@ private constructor( responseCustomToolCallInputDone != null -> visitor.visitResponseCustomToolCallInputDone(responseCustomToolCallInputDone) error != null -> visitor.visitError(error) + responseSteerAccepted != null -> + visitor.visitResponseSteerAccepted(responseSteerAccepted) + responseSteerPending != null -> visitor.visitResponseSteerPending(responseSteerPending) + responseSteerFailed != null -> visitor.visitResponseSteerFailed(responseSteerFailed) responseInjectCreated != null -> visitor.visitResponseInjectCreated(responseInjectCreated) responseInjectFailed != null -> visitor.visitResponseInjectFailed(responseInjectFailed) @@ -1512,6 +1636,24 @@ private constructor( error.validate() } + override fun visitResponseSteerAccepted( + responseSteerAccepted: BetaResponseSteerAcceptedEvent + ) { + responseSteerAccepted.validate() + } + + override fun visitResponseSteerPending( + responseSteerPending: BetaResponseSteerPendingEvent + ) { + responseSteerPending.validate() + } + + override fun visitResponseSteerFailed( + responseSteerFailed: BetaResponseSteerFailedEvent + ) { + responseSteerFailed.validate() + } + override fun visitResponseInjectCreated( responseInjectCreated: BetaResponseInjectCreatedEvent ) { @@ -1778,6 +1920,18 @@ private constructor( override fun visitError(error: BetaResponseWsError) = error.validity() + override fun visitResponseSteerAccepted( + responseSteerAccepted: BetaResponseSteerAcceptedEvent + ) = responseSteerAccepted.validity() + + override fun visitResponseSteerPending( + responseSteerPending: BetaResponseSteerPendingEvent + ) = responseSteerPending.validity() + + override fun visitResponseSteerFailed( + responseSteerFailed: BetaResponseSteerFailedEvent + ) = responseSteerFailed.validity() + override fun visitResponseInjectCreated( responseInjectCreated: BetaResponseInjectCreatedEvent ) = responseInjectCreated.validity() @@ -1856,6 +2010,9 @@ private constructor( responseCustomToolCallInputDelta == other.responseCustomToolCallInputDelta && responseCustomToolCallInputDone == other.responseCustomToolCallInputDone && error == other.error && + responseSteerAccepted == other.responseSteerAccepted && + responseSteerPending == other.responseSteerPending && + responseSteerFailed == other.responseSteerFailed && responseInjectCreated == other.responseInjectCreated && responseInjectFailed == other.responseInjectFailed } @@ -1920,6 +2077,9 @@ private constructor( responseCustomToolCallInputDelta, responseCustomToolCallInputDone, error, + responseSteerAccepted, + responseSteerPending, + responseSteerFailed, responseInjectCreated, responseInjectFailed, ) @@ -2038,6 +2198,12 @@ private constructor( responseCustomToolCallInputDone != null -> "BetaResponsesServerEvent{responseCustomToolCallInputDone=$responseCustomToolCallInputDone}" error != null -> "BetaResponsesServerEvent{error=$error}" + responseSteerAccepted != null -> + "BetaResponsesServerEvent{responseSteerAccepted=$responseSteerAccepted}" + responseSteerPending != null -> + "BetaResponsesServerEvent{responseSteerPending=$responseSteerPending}" + responseSteerFailed != null -> + "BetaResponsesServerEvent{responseSteerFailed=$responseSteerFailed}" responseInjectCreated != null -> "BetaResponsesServerEvent{responseInjectCreated=$responseInjectCreated}" responseInjectFailed != null -> @@ -2228,7 +2394,13 @@ private constructor( fun ofResponseFailed(responseFailed: BetaResponseFailedEvent) = BetaResponsesServerEvent(responseFailed = responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ @JvmStatic fun ofResponseIncomplete(responseIncomplete: BetaResponseIncompleteEvent) = BetaResponsesServerEvent(responseIncomplete = responseIncomplete) @@ -2467,6 +2639,55 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ @JvmStatic fun ofError(error: BetaResponseWsError) = BetaResponsesServerEvent(error = error) + /** + * Emitted when steering input has been validated and queued. Acceptance means the server + * owns the input, not that it has been applied. The successor's `response.created` event is + * the commit point. If accepted input cannot be committed, `response.steer.failed` returns + * it with the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * pending event's `required_input` stubs with saved results and send one matching explicit + * `response.create` per parent. Do not resend accepted input while it is still queued. + */ + @JvmStatic + fun ofResponseSteerAccepted(responseSteerAccepted: BetaResponseSteerAcceptedEvent) = + BetaResponsesServerEvent(responseSteerAccepted = responseSteerAccepted) + + /** + * Emitted when accepted steering input remains queued after the target response completes. + * The server still owns the input. Do not resend it. The successor's `response.created` + * event is the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` + * while the response waits for the tool results or approval decisions identified by + * `required_input`. Copy those stubs, fill their result fields using the ordinary + * `response.create` input schemas, and submit one continuation per parent with the same + * `previous_response_id` and WebSocket lane. Use saved results without rerunning tools. The + * queued steering input is prepended in submission order to the continuation's input. That + * explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions + * for the same parent can report the same required inputs; they do not each require a + * separate continuation. + */ + @JvmStatic + fun ofResponseSteerPending(responseSteerPending: BetaResponseSteerPendingEvent) = + BetaResponsesServerEvent(responseSteerPending = responseSteerPending) + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is + * allocated omit `steer.id`. A lost connection or missing acknowledgement leaves the + * outcome unknown; it is not proof that the input was rejected. + */ + @JvmStatic + fun ofResponseSteerFailed(responseSteerFailed: BetaResponseSteerFailedEvent) = + BetaResponsesServerEvent(responseSteerFailed = responseSteerFailed) + /** * Emitted when all injected input items were validated and committed to the active * response. @@ -2604,7 +2825,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun visitResponseFailed(responseFailed: BetaResponseFailedEvent): T - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ fun visitResponseIncomplete(responseIncomplete: BetaResponseIncompleteEvent): T /** Emitted when a new output item is added. */ @@ -2759,6 +2986,49 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun visitError(error: BetaResponseWsError): T + /** + * Emitted when steering input has been validated and queued. Acceptance means the server + * owns the input, not that it has been applied. The successor's `response.created` event is + * the commit point. If accepted input cannot be committed, `response.steer.failed` returns + * it with the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * pending event's `required_input` stubs with saved results and send one matching explicit + * `response.create` per parent. Do not resend accepted input while it is still queued. + */ + fun visitResponseSteerAccepted(responseSteerAccepted: BetaResponseSteerAcceptedEvent): T + + /** + * Emitted when accepted steering input remains queued after the target response completes. + * The server still owns the input. Do not resend it. The successor's `response.created` + * event is the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` + * while the response waits for the tool results or approval decisions identified by + * `required_input`. Copy those stubs, fill their result fields using the ordinary + * `response.create` input schemas, and submit one continuation per parent with the same + * `previous_response_id` and WebSocket lane. Use saved results without rerunning tools. The + * queued steering input is prepended in submission order to the continuation's input. That + * explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions + * for the same parent can report the same required inputs; they do not each require a + * separate continuation. + */ + fun visitResponseSteerPending(responseSteerPending: BetaResponseSteerPendingEvent): T + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is + * allocated omit `steer.id`. A lost connection or missing acknowledgement leaves the + * outcome unknown; it is not proof that the input was rejected. + */ + fun visitResponseSteerFailed(responseSteerFailed: BetaResponseSteerFailedEvent): T + /** * Emitted when all injected input items were validated and committed to the active * response. @@ -3347,6 +3617,21 @@ private constructor( BetaResponsesServerEvent(error = it, _json = json) } ?: BetaResponsesServerEvent(_json = json) } + "response.steer.accepted" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponsesServerEvent(responseSteerAccepted = it, _json = json) } + ?: BetaResponsesServerEvent(_json = json) + } + "response.steer.pending" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponsesServerEvent(responseSteerPending = it, _json = json) } + ?: BetaResponsesServerEvent(_json = json) + } + "response.steer.failed" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { BetaResponsesServerEvent(responseSteerFailed = it, _json = json) } + ?: BetaResponsesServerEvent(_json = json) + } "response.inject.created" -> { return tryDeserialize(node, jacksonTypeRef()) ?.let { BetaResponsesServerEvent(responseInjectCreated = it, _json = json) } @@ -3479,6 +3764,12 @@ private constructor( value.responseCustomToolCallInputDone != null -> generator.writeObject(value.responseCustomToolCallInputDone) value.error != null -> generator.writeObject(value.error) + value.responseSteerAccepted != null -> + generator.writeObject(value.responseSteerAccepted) + value.responseSteerPending != null -> + generator.writeObject(value.responseSteerPending) + value.responseSteerFailed != null -> + generator.writeObject(value.responseSteerFailed) value.responseInjectCreated != null -> generator.writeObject(value.responseInjectCreated) value.responseInjectFailed != null -> @@ -3841,6 +4132,7 @@ private constructor( private val param: JsonField, private val type: JsonField, private val headers: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -3855,7 +4147,10 @@ private constructor( @JsonProperty("headers") @ExcludeMissing headers: JsonField = JsonMissing.of(), - ) : this(code, message, param, type, headers, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, param, type, headers, misalignment, mutableMapOf()) /** * The error code that was emitted, if any. @@ -3899,6 +4194,12 @@ private constructor( */ fun headers(): Optional = headers.getOptional("headers") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -3934,6 +4235,16 @@ private constructor( */ @JsonProperty("headers") @ExcludeMissing fun _headers(): JsonField = headers + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -3970,6 +4281,7 @@ private constructor( private var param: JsonField? = null private var type: JsonField? = null private var headers: JsonField = JsonMissing.of() + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -3979,6 +4291,7 @@ private constructor( param = error.param type = error.type headers = error.headers + misalignment = error.misalignment additionalProperties = error.additionalProperties.toMutableMap() } @@ -4048,6 +4361,20 @@ private constructor( */ fun headers(headers: JsonField) = apply { this.headers = headers } + fun misalignment(misalignment: Misalignment) = + misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -4092,6 +4419,7 @@ private constructor( checkRequired("param", param), checkRequired("type", type), headers, + misalignment, additionalProperties.toMutableMap(), ) } @@ -4118,6 +4446,7 @@ private constructor( param() type() headers().ifPresent { it.validate() } + misalignment().ifPresent { it.validate() } validated = true } @@ -4141,7 +4470,8 @@ private constructor( (if (message.asKnown().isPresent) 1 else 0) + (if (param.asKnown().isPresent) 1 else 0) + (if (type.asKnown().isPresent) 1 else 0) + - (headers.asKnown().getOrNull()?.validity() ?: 0) + (headers.asKnown().getOrNull()?.validity() ?: 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) /** The response headers that were emitted with the error, if any. */ class Headers @@ -4258,6 +4588,619 @@ private constructor( override fun toString() = "Headers{additionalProperties=$additionalProperties}" } + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") + @ExcludeMissing + steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun errorType(errorType: JsonField) = apply { + this.errorType = errorType + } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = + of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> + Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> + Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("message") + @ExcludeMissing + fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("message", message), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(message, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -4269,17 +5212,26 @@ private constructor( param == other.param && type == other.type && headers == other.headers && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(code, message, param, type, headers, additionalProperties) + Objects.hash( + code, + message, + param, + type, + headers, + misalignment, + additionalProperties, + ) } override fun hashCode(): Int = hashCode override fun toString() = - "Error{code=$code, message=$message, param=$param, type=$type, headers=$headers, additionalProperties=$additionalProperties}" + "Error{code=$code, message=$message, param=$param, type=$type, headers=$headers, misalignment=$misalignment, additionalProperties=$additionalProperties}" } /** The agent that owns this multi-agent streaming event. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCompactParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCompactParams.kt index 69c751580..2bb2356e7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCompactParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCompactParams.kt @@ -52,7 +52,7 @@ private constructor( fun betas(): Optional> = Optional.ofNullable(betas) /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -270,7 +270,7 @@ private constructor( fun body(body: Body) = apply { this.body = body.toBuilder() } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -676,7 +676,7 @@ private constructor( ) /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -898,7 +898,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse * and compare available models. @@ -1249,7 +1249,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -1268,6 +1268,8 @@ private constructor( companion object { + @JvmField val GPT_6_ASTRA = of("gpt-6-astra") + @JvmField val GPT_5_6_SOL = of("gpt-5.6-sol") @JvmField val GPT_5_6_TERRA = of("gpt-5.6-terra") @@ -1479,6 +1481,7 @@ private constructor( /** An enum containing [Model]'s known values. */ enum class Known { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -1593,6 +1596,7 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -1708,6 +1712,7 @@ private constructor( */ fun value(): Value = when (this) { + GPT_6_ASTRA -> Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -1824,6 +1829,7 @@ private constructor( */ fun known(): Known = when (this) { + GPT_6_ASTRA -> Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCreateParams.kt index fe655bf59..cfe9eed4e 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/ResponseCreateParams.kt @@ -163,7 +163,7 @@ private constructor( fun metadata(): Optional = body.metadata() /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -968,7 +968,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -2090,7 +2090,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -3006,7 +3006,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse * and compare available models. @@ -4800,7 +4800,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -4819,6 +4819,8 @@ private constructor( companion object { + @JvmField val GPT_6_ASTRA = of("gpt-6-astra") + @JvmField val GPT_5_6_SOL = of("gpt-5.6-sol") @JvmField val GPT_5_6_TERRA = of("gpt-5.6-terra") @@ -5030,6 +5032,7 @@ private constructor( /** An enum containing [Model]'s known values. */ enum class Known { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -5144,6 +5147,7 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -5259,6 +5263,7 @@ private constructor( */ fun value(): Value = when (this) { + GPT_6_ASTRA -> Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -5375,6 +5380,7 @@ private constructor( */ fun known(): Known = when (this) { + GPT_6_ASTRA -> Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/BetaResponseItemList.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/BetaResponseItemList.kt index c96c19377..14fbe685d 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/BetaResponseItemList.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/BetaResponseItemList.kt @@ -20,6 +20,7 @@ import com.openai.models.beta.responses.BetaResponseCodeInterpreterToolCall import com.openai.models.beta.responses.BetaResponseCompactionItem import com.openai.models.beta.responses.BetaResponseComputerToolCall import com.openai.models.beta.responses.BetaResponseComputerToolCallOutputItem +import com.openai.models.beta.responses.BetaResponseConfigurationUpdateItem import com.openai.models.beta.responses.BetaResponseCustomToolCallItem import com.openai.models.beta.responses.BetaResponseCustomToolCallOutputItem import com.openai.models.beta.responses.BetaResponseFileSearchToolCall @@ -283,6 +284,24 @@ private constructor( fun addData(additionalTools: BetaResponseItem.AdditionalTools) = addData(BetaResponseItem.ofAdditionalTools(additionalTools)) + /** + * Alias for calling [addData] with + * `BetaResponseItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addData(configurationUpdate: BetaResponseConfigurationUpdateItem) = + addData(BetaResponseItem.ofConfigurationUpdate(configurationUpdate)) + + /** + * Alias for calling [addData] with the following: + * ```java + * BetaResponseConfigurationUpdateItem.builder() + * .id(id) + * .build() + * ``` + */ + fun addConfigurationUpdateData(id: String) = + addData(BetaResponseConfigurationUpdateItem.builder().id(id).build()) + /** Alias for calling [addData] with `BetaResponseItem.ofReasoning(reasoning)`. */ fun addData(reasoning: BetaResponseReasoningItem) = addData(BetaResponseItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPage.kt index 57abf2c49..050c74c98 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPage.kt @@ -11,6 +11,7 @@ import com.openai.models.beta.responses.BetaResponseCodeInterpreterToolCall import com.openai.models.beta.responses.BetaResponseCompactionItem import com.openai.models.beta.responses.BetaResponseComputerToolCall import com.openai.models.beta.responses.BetaResponseComputerToolCallOutputItem +import com.openai.models.beta.responses.BetaResponseConfigurationUpdateItem import com.openai.models.beta.responses.BetaResponseCustomToolCallItem import com.openai.models.beta.responses.BetaResponseCustomToolCallOutputItem import com.openai.models.beta.responses.BetaResponseFileSearchToolCall @@ -122,6 +123,10 @@ private constructor( additionalTools: BetaResponseItem.AdditionalTools ): Optional = additionalTools._id().getOptional("id") + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItem + ): Optional = configurationUpdate._id().getOptional("id") + override fun visitReasoning( reasoning: BetaResponseReasoningItem ): Optional = reasoning._id().getOptional("id") diff --git a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPageAsync.kt index ad2b70242..fa1a6a8d9 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/beta/responses/inputitems/InputItemListPageAsync.kt @@ -11,6 +11,7 @@ import com.openai.models.beta.responses.BetaResponseCodeInterpreterToolCall import com.openai.models.beta.responses.BetaResponseCompactionItem import com.openai.models.beta.responses.BetaResponseComputerToolCall import com.openai.models.beta.responses.BetaResponseComputerToolCallOutputItem +import com.openai.models.beta.responses.BetaResponseConfigurationUpdateItem import com.openai.models.beta.responses.BetaResponseCustomToolCallItem import com.openai.models.beta.responses.BetaResponseCustomToolCallOutputItem import com.openai.models.beta.responses.BetaResponseFileSearchToolCall @@ -125,6 +126,10 @@ private constructor( additionalTools: BetaResponseItem.AdditionalTools ): Optional = additionalTools._id().getOptional("id") + override fun visitConfigurationUpdate( + configurationUpdate: BetaResponseConfigurationUpdateItem + ): Optional = configurationUpdate._id().getOptional("id") + override fun visitReasoning( reasoning: BetaResponseReasoningItem ): Optional = reasoning._id().getOptional("id") diff --git a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParams.kt index eb1c03ab4..ceaf1d93a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParams.kt @@ -85,7 +85,7 @@ private constructor( fun messages(): List = body.messages() /** - * Model ID used to generate the response, like `gpt-5.6-sol` or `o3`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra` or `o3`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price points. * Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -993,7 +993,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol` or `o3`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra` or `o3`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and * compare available models. @@ -2358,7 +2358,7 @@ private constructor( fun messages(): List = messages.getRequired("messages") /** - * Model ID used to generate the response, like `gpt-5.6-sol` or `o3`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra` or `o3`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and * compare available models. @@ -3439,7 +3439,7 @@ private constructor( addMessage(ChatCompletionMessageParam.ofFunction(function)) /** - * Model ID used to generate the response, like `gpt-5.6-sol` or `o3`. OpenAI offers a + * Model ID used to generate the response, like `gpt-6-astra` or `o3`. OpenAI offers a * wide range of models with different capabilities, performance characteristics, and * price points. Refer to the [model guide](https://platform.openai.com/docs/models) to * browse and compare available models. diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt index d0403f474..0f87e2452 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/ConversationCreateParams.kt @@ -20,6 +20,7 @@ import com.openai.models.responses.EasyInputMessage import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItemParam import com.openai.models.responses.ResponseComputerToolCall +import com.openai.models.responses.ResponseConfigurationUpdateItemParam import com.openai.models.responses.ResponseCustomToolCall import com.openai.models.responses.ResponseCustomToolCallOutput import com.openai.models.responses.ResponseFileSearchToolCall @@ -285,6 +286,14 @@ private constructor( */ fun addAdditionalToolsItem(tools: List) = apply { body.addAdditionalToolsItem(tools) } + /** + * Alias for calling [addItem] with + * `ResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addItem(configurationUpdate: ResponseConfigurationUpdateItemParam) = apply { + body.addItem(configurationUpdate) + } + /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */ fun addItem(reasoning: ResponseReasoningItem) = apply { body.addItem(reasoning) } @@ -844,6 +853,13 @@ private constructor( fun addAdditionalToolsItem(tools: List) = addItem(ResponseInputItem.AdditionalTools.builder().tools(tools).build()) + /** + * Alias for calling [addItem] with + * `ResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addItem(configurationUpdate: ResponseConfigurationUpdateItemParam) = + addItem(ResponseInputItem.ofConfigurationUpdate(configurationUpdate)) + /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */ fun addItem(reasoning: ResponseReasoningItem) = addItem(ResponseInputItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItem.kt index feaa3d39e..1455f3ac7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItem.kt @@ -41,6 +41,7 @@ import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCall import com.openai.models.responses.ResponseCustomToolCallOutput import com.openai.models.responses.ResponseFileSearchToolCall @@ -81,6 +82,7 @@ private constructor( private val toolSearchCall: ResponseToolSearchCall? = null, private val toolSearchOutput: ResponseToolSearchOutputItem? = null, private val additionalTools: AdditionalTools? = null, + private val configurationUpdate: ResponseConfigurationUpdateItem? = null, private val reasoning: ResponseReasoningItem? = null, private val program: Program? = null, private val programOutput: ProgramOutput? = null, @@ -149,6 +151,13 @@ private constructor( fun additionalTools(): Optional = Optional.ofNullable(additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun configurationUpdate(): Optional = + Optional.ofNullable(configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -234,6 +243,8 @@ private constructor( fun isAdditionalTools(): Boolean = additionalTools != null + fun isConfigurationUpdate(): Boolean = configurationUpdate != null + fun isReasoning(): Boolean = reasoning != null fun isProgram(): Boolean = program != null @@ -316,6 +327,13 @@ private constructor( fun asAdditionalTools(): AdditionalTools = additionalTools.getOrThrow("additionalTools") + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun asConfigurationUpdate(): ResponseConfigurationUpdateItem = + configurationUpdate.getOrThrow("configurationUpdate") + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -424,6 +442,7 @@ private constructor( toolSearchCall != null -> visitor.visitToolSearchCall(toolSearchCall) toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) additionalTools != null -> visitor.visitAdditionalTools(additionalTools) + configurationUpdate != null -> visitor.visitConfigurationUpdate(configurationUpdate) reasoning != null -> visitor.visitReasoning(reasoning) program != null -> visitor.visitProgram(program) programOutput != null -> visitor.visitProgramOutput(programOutput) @@ -509,6 +528,12 @@ private constructor( additionalTools.validate() } + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ) { + configurationUpdate.validate() + } + override fun visitReasoning(reasoning: ResponseReasoningItem) { reasoning.validate() } @@ -640,6 +665,10 @@ private constructor( override fun visitAdditionalTools(additionalTools: AdditionalTools) = additionalTools.validity() + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ) = configurationUpdate.validity() + override fun visitReasoning(reasoning: ResponseReasoningItem) = reasoning.validity() override fun visitProgram(program: Program) = program.validity() @@ -712,6 +741,7 @@ private constructor( toolSearchCall == other.toolSearchCall && toolSearchOutput == other.toolSearchOutput && additionalTools == other.additionalTools && + configurationUpdate == other.configurationUpdate && reasoning == other.reasoning && program == other.program && programOutput == other.programOutput && @@ -744,6 +774,7 @@ private constructor( toolSearchCall, toolSearchOutput, additionalTools, + configurationUpdate, reasoning, program, programOutput, @@ -777,6 +808,8 @@ private constructor( toolSearchCall != null -> "ConversationItem{toolSearchCall=$toolSearchCall}" toolSearchOutput != null -> "ConversationItem{toolSearchOutput=$toolSearchOutput}" additionalTools != null -> "ConversationItem{additionalTools=$additionalTools}" + configurationUpdate != null -> + "ConversationItem{configurationUpdate=$configurationUpdate}" reasoning != null -> "ConversationItem{reasoning=$reasoning}" program != null -> "ConversationItem{program=$program}" programOutput != null -> "ConversationItem{programOutput=$programOutput}" @@ -869,6 +902,14 @@ private constructor( fun ofAdditionalTools(additionalTools: AdditionalTools) = ConversationItem(additionalTools = additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + @JvmStatic + fun ofConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItem) = + ConversationItem(configurationUpdate = configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1006,6 +1047,12 @@ private constructor( fun visitAdditionalTools(additionalTools: AdditionalTools): T + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + fun visitConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItem): T + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1146,6 +1193,11 @@ private constructor( ConversationItem(additionalTools = it, _json = json) } ?: ConversationItem(_json = json) } + "configuration_update" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { ConversationItem(configurationUpdate = it, _json = json) } + ?: ConversationItem(_json = json) + } "reasoning" -> { return tryDeserialize(node, jacksonTypeRef())?.let { ConversationItem(reasoning = it, _json = json) @@ -1260,6 +1312,8 @@ private constructor( value.toolSearchCall != null -> generator.writeObject(value.toolSearchCall) value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) value.additionalTools != null -> generator.writeObject(value.additionalTools) + value.configurationUpdate != null -> + generator.writeObject(value.configurationUpdate) value.reasoning != null -> generator.writeObject(value.reasoning) value.program != null -> generator.writeObject(value.program) value.programOutput != null -> generator.writeObject(value.programOutput) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItemList.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItemList.kt index cb95b146d..f953b9d69 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItemList.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ConversationItemList.kt @@ -21,6 +21,7 @@ import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCall import com.openai.models.responses.ResponseCustomToolCallOutput import com.openai.models.responses.ResponseFileSearchToolCall @@ -262,6 +263,24 @@ private constructor( fun addData(additionalTools: ConversationItem.AdditionalTools) = addData(ConversationItem.ofAdditionalTools(additionalTools)) + /** + * Alias for calling [addData] with + * `ConversationItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addData(configurationUpdate: ResponseConfigurationUpdateItem) = + addData(ConversationItem.ofConfigurationUpdate(configurationUpdate)) + + /** + * Alias for calling [addData] with the following: + * ```java + * ResponseConfigurationUpdateItem.builder() + * .id(id) + * .build() + * ``` + */ + fun addConfigurationUpdateData(id: String) = + addData(ResponseConfigurationUpdateItem.builder().id(id).build()) + /** Alias for calling [addData] with `ConversationItem.ofReasoning(reasoning)`. */ fun addData(reasoning: ResponseReasoningItem) = addData(ConversationItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ItemCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ItemCreateParams.kt index 9ed2492f1..41e4c1539 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ItemCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/conversations/items/ItemCreateParams.kt @@ -21,6 +21,7 @@ import com.openai.models.responses.EasyInputMessage import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItemParam import com.openai.models.responses.ResponseComputerToolCall +import com.openai.models.responses.ResponseConfigurationUpdateItemParam import com.openai.models.responses.ResponseCustomToolCall import com.openai.models.responses.ResponseCustomToolCallOutput import com.openai.models.responses.ResponseFileSearchToolCall @@ -307,6 +308,14 @@ private constructor( */ fun addAdditionalToolsItem(tools: List) = apply { body.addAdditionalToolsItem(tools) } + /** + * Alias for calling [addItem] with + * `ResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addItem(configurationUpdate: ResponseConfigurationUpdateItemParam) = apply { + body.addItem(configurationUpdate) + } + /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */ fun addItem(reasoning: ResponseReasoningItem) = apply { body.addItem(reasoning) } @@ -839,6 +848,13 @@ private constructor( fun addAdditionalToolsItem(tools: List) = addItem(ResponseInputItem.AdditionalTools.builder().tools(tools).build()) + /** + * Alias for calling [addItem] with + * `ResponseInputItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addItem(configurationUpdate: ResponseConfigurationUpdateItemParam) = + addItem(ResponseInputItem.ofConfigurationUpdate(configurationUpdate)) + /** Alias for calling [addItem] with `ResponseInputItem.ofReasoning(reasoning)`. */ fun addItem(reasoning: ResponseReasoningItem) = addItem(ResponseInputItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt index 60443c6a8..c0b7c4c9f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalCreateResponse.kt @@ -40,7 +40,7 @@ import kotlin.jvm.optionals.getOrNull * done for your LLM integration. Like: * - Improve the quality of my chatbot * - See how well my chatbot handles customer support - * - Check if o4-mini is better at my usecase than gpt-5.6-sol + * - Check if o4-mini is better at my usecase than gpt-6-astra */ class EvalCreateResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt index d3fea9973..ef467a5b5 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalListResponse.kt @@ -40,7 +40,7 @@ import kotlin.jvm.optionals.getOrNull * done for your LLM integration. Like: * - Improve the quality of my chatbot * - See how well my chatbot handles customer support - * - Check if o4-mini is better at my usecase than gpt-5.6-sol + * - Check if o4-mini is better at my usecase than gpt-6-astra */ class EvalListResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt index fca5d26fa..ad50a2459 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalRetrieveResponse.kt @@ -40,7 +40,7 @@ import kotlin.jvm.optionals.getOrNull * done for your LLM integration. Like: * - Improve the quality of my chatbot * - See how well my chatbot handles customer support - * - Check if o4-mini is better at my usecase than gpt-5.6-sol + * - Check if o4-mini is better at my usecase than gpt-6-astra */ class EvalRetrieveResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt index 3e94cbbcf..323b88117 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/EvalUpdateResponse.kt @@ -40,7 +40,7 @@ import kotlin.jvm.optionals.getOrNull * done for your LLM integration. Like: * - Improve the quality of my chatbot * - See how well my chatbot handles customer support - * - Check if o4-mini is better at my usecase than gpt-5.6-sol + * - Check if o4-mini is better at my usecase than gpt-6-astra */ class EvalUpdateResponse @JsonCreator(mode = JsonCreator.Mode.DISABLED) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt index 0b3628714..84eb9e844 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/evals/runs/CreateEvalCompletionsRunDataSource.kt @@ -1613,7 +1613,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * An optional model to filter by (e.g., 'gpt-5.6-sol'). + * An optional model to filter by (e.g., 'gpt-6-astra'). * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if * the server responded with an unexpected value). @@ -1816,7 +1816,7 @@ private constructor( */ fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - /** An optional model to filter by (e.g., 'gpt-5.6-sol'). */ + /** An optional model to filter by (e.g., 'gpt-6-astra'). */ fun model(model: String?) = model(JsonField.ofNullable(model)) /** Alias for calling [Builder.model] with `model.orElse(null)`. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt index eed10d84d..318a8258a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/CustomTool.kt @@ -31,6 +31,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val format: JsonField, @@ -44,6 +45,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -53,7 +55,7 @@ private constructor( @JsonProperty("format") @ExcludeMissing format: JsonField = JsonMissing.of(), - ) : this(name, type, allowedCallers, deferLoading, description, format, mutableMapOf()) + ) : this(name, type, allowedCallers, async, deferLoading, description, format, mutableMapOf()) /** * The name of the custom tool, used to identify it in tool calls. @@ -85,6 +87,15 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * Whether the tool response can be returned asynchronously versus immediately returned on next + * response creation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this tool should be deferred and discovered via tool search. * @@ -125,6 +136,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -179,6 +197,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("custom") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var format: JsonField = JsonMissing.of() @@ -189,6 +208,7 @@ private constructor( name = customTool.name type = customTool.type allowedCallers = customTool.allowedCallers.map { it.toMutableList() } + async = customTool.async deferLoading = customTool.deferLoading description = customTool.description format = customTool.format @@ -251,6 +271,20 @@ private constructor( } } + /** + * Whether the tool response can be returned asynchronously versus immediately returned on + * next response creation. + */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this tool should be deferred and discovered via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -332,6 +366,7 @@ private constructor( checkRequired("name", name), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, format, @@ -361,6 +396,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() format().ifPresent { it.validate() } @@ -385,6 +421,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("custom")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (format.asKnown().getOrNull()?.validity() ?: 0) @@ -536,6 +573,7 @@ private constructor( name == other.name && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && format == other.format && @@ -547,6 +585,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, format, @@ -557,5 +596,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "CustomTool{name=$name, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, format=$format, additionalProperties=$additionalProperties}" + "CustomTool{name=$name, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, format=$format, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/FunctionTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/FunctionTool.kt index 7e1a48e55..1d236963f 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/FunctionTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/FunctionTool.kt @@ -32,6 +32,7 @@ private constructor( private val strict: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val outputSchema: JsonField, @@ -49,6 +50,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -64,6 +66,7 @@ private constructor( strict, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -116,6 +119,12 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this function is deferred and loaded via tool search. * @@ -173,6 +182,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -233,6 +249,7 @@ private constructor( private var strict: JsonField? = null private var type: JsonValue = JsonValue.from("function") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var outputSchema: JsonField = JsonMissing.of() @@ -245,6 +262,7 @@ private constructor( strict = functionTool.strict type = functionTool.type allowedCallers = functionTool.allowedCallers.map { it.toMutableList() } + async = functionTool.async deferLoading = functionTool.deferLoading description = functionTool.description outputSchema = functionTool.outputSchema @@ -343,6 +361,16 @@ private constructor( } } + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this function is deferred and loaded via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -437,6 +465,7 @@ private constructor( checkRequired("strict", strict), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, outputSchema, @@ -468,6 +497,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() outputSchema().ifPresent { it.validate() } @@ -494,6 +524,7 @@ private constructor( (if (strict.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (outputSchema.asKnown().getOrNull()?.validity() ?: 0) @@ -867,6 +898,7 @@ private constructor( strict == other.strict && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && outputSchema == other.outputSchema && @@ -880,6 +912,7 @@ private constructor( strict, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -890,5 +923,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "FunctionTool{name=$name, parameters=$parameters, strict=$strict, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, additionalProperties=$additionalProperties}" + "FunctionTool{name=$name, parameters=$parameters, strict=$strict, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt index 853833ea7..f25ace1f8 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/NamespaceTool.kt @@ -553,6 +553,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val allowedCallers: JsonField>, + private val async: JsonField, private val deferLoading: JsonField, private val description: JsonField, private val outputSchema: JsonField, @@ -568,6 +569,7 @@ private constructor( @JsonProperty("allowed_callers") @ExcludeMissing allowedCallers: JsonField> = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("defer_loading") @ExcludeMissing deferLoading: JsonField = JsonMissing.of(), @@ -587,6 +589,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -622,6 +625,15 @@ private constructor( fun allowedCallers(): Optional> = allowedCallers.getOptional("allowed_callers") + /** + * Whether the tool response can be returned asynchronously versus immediately returned + * on next response creation. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * Whether this function should be deferred and discovered via tool search. * @@ -681,6 +693,13 @@ private constructor( @ExcludeMissing fun _allowedCallers(): JsonField> = allowedCallers + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [deferLoading]. * @@ -749,6 +768,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("function") private var allowedCallers: JsonField>? = null + private var async: JsonField = JsonMissing.of() private var deferLoading: JsonField = JsonMissing.of() private var description: JsonField = JsonMissing.of() private var outputSchema: JsonField = JsonMissing.of() @@ -761,6 +781,7 @@ private constructor( name = function.name type = function.type allowedCallers = function.allowedCallers.map { it.toMutableList() } + async = function.async deferLoading = function.deferLoading description = function.description outputSchema = function.outputSchema @@ -827,6 +848,21 @@ private constructor( } } + /** + * Whether the tool response can be returned asynchronously versus immediately + * returned on next response creation. + */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** Whether this function should be deferred and discovered via tool search. */ fun deferLoading(deferLoading: Boolean) = deferLoading(JsonField.of(deferLoading)) @@ -948,6 +984,7 @@ private constructor( checkRequired("name", name), type, (allowedCallers ?: JsonMissing.of()).map { it.toImmutable() }, + async, deferLoading, description, outputSchema, @@ -981,6 +1018,7 @@ private constructor( } } allowedCallers().ifPresent { it.forEach { it.validate() } } + async() deferLoading() description() outputSchema().ifPresent { it.validate() } @@ -1007,6 +1045,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function")) 1 else 0 } + (allowedCallers.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (async.asKnown().isPresent) 1 else 0) + (if (deferLoading.asKnown().isPresent) 1 else 0) + (if (description.asKnown().isPresent) 1 else 0) + (outputSchema.asKnown().getOrNull()?.validity() ?: 0) + @@ -1283,6 +1322,7 @@ private constructor( name == other.name && type == other.type && allowedCallers == other.allowedCallers && + async == other.async && deferLoading == other.deferLoading && description == other.description && outputSchema == other.outputSchema && @@ -1296,6 +1336,7 @@ private constructor( name, type, allowedCallers, + async, deferLoading, description, outputSchema, @@ -1308,7 +1349,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Function{name=$name, type=$type, allowedCallers=$allowedCallers, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}" + "Function{name=$name, type=$type, allowedCallers=$allowedCallers, async=$async, deferLoading=$deferLoading, description=$description, outputSchema=$outputSchema, parameters=$parameters, strict=$strict, additionalProperties=$additionalProperties}" } } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/Response.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/Response.kt index f64d8e003..eb8f27bcf 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/Response.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/Response.kt @@ -255,7 +255,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -1084,7 +1084,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -2253,7 +2253,9 @@ private constructor( ) : this(reason, mutableMapOf()) /** - * The reason why the response is incomplete. + * The reason why the response is incomplete. `steered` means the response stopped at a safe + * output boundary after a WebSocket `response.steer` event. The server can then create a + * successor response automatically with the queued input. * * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -2297,7 +2299,11 @@ private constructor( additionalProperties = incompleteDetails.additionalProperties.toMutableMap() } - /** The reason why the response is incomplete. */ + /** + * The reason why the response is incomplete. `steered` means the response stopped at a + * safe output boundary after a WebSocket `response.steer` event. The server can then + * create a successor response automatically with the queued input. + */ fun reason(reason: Reason) = reason(JsonField.of(reason)) /** @@ -2373,7 +2379,11 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = (reason.asKnown().getOrNull()?.validity() ?: 0) - /** The reason why the response is incomplete. */ + /** + * The reason why the response is incomplete. `steered` means the response stopped at a safe + * output boundary after a WebSocket `response.steer` event. The server can then create a + * successor response automatically with the queued input. + */ class Reason @JsonCreator private constructor(private val value: JsonField) : Enum { /** @@ -2394,6 +2404,8 @@ private constructor( @JvmField val CONTENT_FILTER = of("content_filter") + @JvmField val STEERED = of("steered") + @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) } @@ -2402,6 +2414,7 @@ private constructor( MAX_OUTPUT_TOKENS, MAX_MESSAGES, CONTENT_FILTER, + STEERED, } /** @@ -2417,6 +2430,7 @@ private constructor( MAX_OUTPUT_TOKENS, MAX_MESSAGES, CONTENT_FILTER, + STEERED, /** * An enum member indicating that [Reason] was instantiated with an unknown value. */ @@ -2435,6 +2449,7 @@ private constructor( MAX_OUTPUT_TOKENS -> Value.MAX_OUTPUT_TOKENS MAX_MESSAGES -> Value.MAX_MESSAGES CONTENT_FILTER -> Value.CONTENT_FILTER + STEERED -> Value.STEERED else -> Value._UNKNOWN } @@ -2452,6 +2467,7 @@ private constructor( MAX_OUTPUT_TOKENS -> Known.MAX_OUTPUT_TOKENS MAX_MESSAGES -> Known.MAX_MESSAGES CONTENT_FILTER -> Known.CONTENT_FILTER + STEERED -> Known.STEERED else -> throw OpenAIInvalidDataException("Unknown Reason: $value") } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt index 24a1cac3e..722546db7 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCompactParams.kt @@ -49,7 +49,7 @@ private constructor( ) : Params { /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -253,7 +253,7 @@ private constructor( fun body(body: Body) = apply { this.body = body.toBuilder() } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -649,7 +649,7 @@ private constructor( ) /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -871,7 +871,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse * and compare available models. @@ -1219,7 +1219,7 @@ private constructor( } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -1238,6 +1238,8 @@ private constructor( companion object { + @JvmField val GPT_6_ASTRA = of("gpt-6-astra") + @JvmField val GPT_5_6_SOL = of("gpt-5.6-sol") @JvmField val GPT_5_6_TERRA = of("gpt-5.6-terra") @@ -1449,6 +1451,7 @@ private constructor( /** An enum containing [Model]'s known values. */ enum class Known { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -1563,6 +1566,7 @@ private constructor( * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { + GPT_6_ASTRA, GPT_5_6_SOL, GPT_5_6_TERRA, GPT_5_6_LUNA, @@ -1678,6 +1682,7 @@ private constructor( */ fun value(): Value = when (this) { + GPT_6_ASTRA -> Value.GPT_6_ASTRA GPT_5_6_SOL -> Value.GPT_5_6_SOL GPT_5_6_TERRA -> Value.GPT_5_6_TERRA GPT_5_6_LUNA -> Value.GPT_5_6_LUNA @@ -1794,6 +1799,7 @@ private constructor( */ fun known(): Known = when (this) { + GPT_6_ASTRA -> Known.GPT_6_ASTRA GPT_5_6_SOL -> Known.GPT_5_6_SOL GPT_5_6_TERRA -> Known.GPT_5_6_TERRA GPT_5_6_LUNA -> Known.GPT_5_6_LUNA diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItem.kt new file mode 100644 index 000000000..f3cfed7c2 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItem.kt @@ -0,0 +1,429 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.ReasoningEffort +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ +class ResponseConfigurationUpdateItem +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val type: JsonValue, + private val reasoning: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + ) : this(id, type, reasoning, mutableMapOf()) + + /** + * The unique ID of the configuration update item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The item type. Always `configuration_update`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The reasoning configuration applied by this update. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reasoning(): Optional = reasoning.getOptional("reasoning") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning") @ExcludeMissing fun _reasoning(): JsonField = reasoning + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [ResponseConfigurationUpdateItem]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseConfigurationUpdateItem]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var type: JsonValue = JsonValue.from("configuration_update") + private var reasoning: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(responseConfigurationUpdateItem: ResponseConfigurationUpdateItem) = + apply { + id = responseConfigurationUpdateItem.id + type = responseConfigurationUpdateItem.type + reasoning = responseConfigurationUpdateItem.reasoning + additionalProperties = + responseConfigurationUpdateItem.additionalProperties.toMutableMap() + } + + /** The unique ID of the configuration update item. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The reasoning configuration applied by this update. */ + fun reasoning(reasoning: Reasoning) = reasoning(JsonField.of(reasoning)) + + /** + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseConfigurationUpdateItem]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ResponseConfigurationUpdateItem = + ResponseConfigurationUpdateItem( + checkRequired("id", id), + type, + reasoning, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseConfigurationUpdateItem = apply { + if (validated) { + return@apply + } + + id() + _type().let { + if (it != JsonValue.from("configuration_update")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + reasoning().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("configuration_update")) 1 else 0 } + + (reasoning.asKnown().getOrNull()?.validity() ?: 0) + + /** The reasoning configuration applied by this update. */ + class Reasoning + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val effort: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("effort") + @ExcludeMissing + effort: JsonField = JsonMissing.of() + ) : this(effort, mutableMapOf()) + + /** + * The reasoning effort used for subsequent responses until another configuration update + * replaces it. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun effort(): Optional = effort.getOptional("effort") + + /** + * Returns the raw JSON value of [effort]. + * + * Unlike [effort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("effort") @ExcludeMissing fun _effort(): JsonField = effort + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Reasoning]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Reasoning]. */ + class Builder internal constructor() { + + private var effort: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reasoning: Reasoning) = apply { + effort = reasoning.effort + additionalProperties = reasoning.additionalProperties.toMutableMap() + } + + /** + * The reasoning effort used for subsequent responses until another configuration update + * replaces it. + */ + fun effort(effort: ReasoningEffort?) = effort(JsonField.ofNullable(effort)) + + /** Alias for calling [Builder.effort] with `effort.orElse(null)`. */ + fun effort(effort: Optional) = effort(effort.getOrNull()) + + /** + * Sets [Builder.effort] to an arbitrary JSON value. + * + * You should usually call [Builder.effort] with a well-typed [ReasoningEffort] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun effort(effort: JsonField) = apply { this.effort = effort } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Reasoning]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Reasoning = Reasoning(effort, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Reasoning = apply { + if (validated) { + return@apply + } + + effort().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (effort.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Reasoning && + effort == other.effort && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(effort, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Reasoning{effort=$effort, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseConfigurationUpdateItem && + id == other.id && + type == other.type && + reasoning == other.reasoning && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, type, reasoning, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseConfigurationUpdateItem{id=$id, type=$type, reasoning=$reasoning, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParam.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParam.kt new file mode 100644 index 000000000..2fcc0fc25 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParam.kt @@ -0,0 +1,420 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.ReasoningEffort +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * An update to the conversation's response configuration. The configuration remains in effect for + * subsequent responses until it is replaced by another configuration update. + */ +class ResponseConfigurationUpdateItemParam +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val type: JsonValue, + private val id: JsonField, + private val reasoning: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + ) : this(type, id, reasoning, mutableMapOf()) + + /** + * The item type. Always `configuration_update`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of the configuration update item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * Updates to reasoning configuration. Only effort is supported. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reasoning(): Optional = reasoning.getOptional("reasoning") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning") @ExcludeMissing fun _reasoning(): JsonField = reasoning + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [ResponseConfigurationUpdateItemParam]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseConfigurationUpdateItemParam]. */ + class Builder internal constructor() { + + private var type: JsonValue = JsonValue.from("configuration_update") + private var id: JsonField = JsonMissing.of() + private var reasoning: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + responseConfigurationUpdateItemParam: ResponseConfigurationUpdateItemParam + ) = apply { + type = responseConfigurationUpdateItemParam.type + id = responseConfigurationUpdateItemParam.id + reasoning = responseConfigurationUpdateItemParam.reasoning + additionalProperties = + responseConfigurationUpdateItemParam.additionalProperties.toMutableMap() + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("configuration_update") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The unique ID of the configuration update item. */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** Updates to reasoning configuration. Only effort is supported. */ + fun reasoning(reasoning: Reasoning) = reasoning(JsonField.of(reasoning)) + + /** + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseConfigurationUpdateItemParam]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ResponseConfigurationUpdateItemParam = + ResponseConfigurationUpdateItemParam( + type, + id, + reasoning, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseConfigurationUpdateItemParam = apply { + if (validated) { + return@apply + } + + _type().let { + if (it != JsonValue.from("configuration_update")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + reasoning().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + type.let { if (it == JsonValue.from("configuration_update")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (reasoning.asKnown().getOrNull()?.validity() ?: 0) + + /** Updates to reasoning configuration. Only effort is supported. */ + class Reasoning + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val effort: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("effort") + @ExcludeMissing + effort: JsonField = JsonMissing.of() + ) : this(effort, mutableMapOf()) + + /** + * The reasoning effort to use for subsequent responses until another configuration update + * replaces it. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun effort(): Optional = effort.getOptional("effort") + + /** + * Returns the raw JSON value of [effort]. + * + * Unlike [effort], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("effort") @ExcludeMissing fun _effort(): JsonField = effort + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Reasoning]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Reasoning]. */ + class Builder internal constructor() { + + private var effort: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(reasoning: Reasoning) = apply { + effort = reasoning.effort + additionalProperties = reasoning.additionalProperties.toMutableMap() + } + + /** + * The reasoning effort to use for subsequent responses until another configuration + * update replaces it. + */ + fun effort(effort: ReasoningEffort?) = effort(JsonField.ofNullable(effort)) + + /** Alias for calling [Builder.effort] with `effort.orElse(null)`. */ + fun effort(effort: Optional) = effort(effort.getOrNull()) + + /** + * Sets [Builder.effort] to an arbitrary JSON value. + * + * You should usually call [Builder.effort] with a well-typed [ReasoningEffort] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun effort(effort: JsonField) = apply { this.effort = effort } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Reasoning]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Reasoning = Reasoning(effort, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Reasoning = apply { + if (validated) { + return@apply + } + + effort().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (effort.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Reasoning && + effort == other.effort && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(effort, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Reasoning{effort=$effort, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseConfigurationUpdateItemParam && + type == other.type && + id == other.id && + reasoning == other.reasoning && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, id, reasoning, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseConfigurationUpdateItemParam{type=$type, id=$id, reasoning=$reasoning, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt index d00cfddf4..d8aa2ba9b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCreateParams.kt @@ -165,7 +165,7 @@ private constructor( fun metadata(): Optional = body.metadata() /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer to * the [model guide](https://platform.openai.com/docs/models) to browse and compare available * models. @@ -939,7 +939,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { body.metadata(metadata) } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -2049,7 +2049,7 @@ private constructor( fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. @@ -2940,7 +2940,7 @@ private constructor( fun metadata(metadata: JsonField) = apply { this.metadata = metadata } /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide * range of models with different capabilities, performance characteristics, and price * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse * and compare available models. diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCall.kt index e8c158868..2fe46cf5c 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCall.kt @@ -36,6 +36,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val id: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val additionalProperties: MutableMap, @@ -48,9 +49,10 @@ private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @JsonProperty("namespace") @ExcludeMissing namespace: JsonField = JsonMissing.of(), - ) : this(callId, input, name, type, id, caller, namespace, mutableMapOf()) + ) : this(callId, input, name, type, id, async, caller, namespace, mutableMapOf()) /** * An identifier used to map this custom tool call to a tool call output. @@ -97,6 +99,14 @@ private constructor( */ fun id(): Optional = id.getOptional("id") + /** + * Whether the custom tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -141,6 +151,13 @@ private constructor( */ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -190,6 +207,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("custom_tool_call") private var id: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -201,6 +219,7 @@ private constructor( name = responseCustomToolCall.name type = responseCustomToolCall.type id = responseCustomToolCall.id + async = responseCustomToolCall.async caller = responseCustomToolCall.caller namespace = responseCustomToolCall.namespace additionalProperties = responseCustomToolCall.additionalProperties.toMutableMap() @@ -264,6 +283,17 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } + /** Whether the custom tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) @@ -347,6 +377,7 @@ private constructor( checkRequired("name", name), type, id, + async, caller, namespace, additionalProperties.toMutableMap(), @@ -377,6 +408,7 @@ private constructor( } } id() + async() caller().ifPresent { it.validate() } namespace() validated = true @@ -402,6 +434,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("custom_tool_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) @@ -841,17 +874,18 @@ private constructor( name == other.name && type == other.type && id == other.id && + async == other.async && caller == other.caller && namespace == other.namespace && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(callId, input, name, type, id, caller, namespace, additionalProperties) + Objects.hash(callId, input, name, type, id, async, caller, namespace, additionalProperties) } override fun hashCode(): Int = hashCode override fun toString() = - "ResponseCustomToolCall{callId=$callId, input=$input, name=$name, type=$type, id=$id, caller=$caller, namespace=$namespace, additionalProperties=$additionalProperties}" + "ResponseCustomToolCall{callId=$callId, input=$input, name=$name, type=$type, id=$id, async=$async, caller=$caller, namespace=$namespace, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCallItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCallItem.kt index e23720cd2..49308b6ea 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCallItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseCustomToolCallItem.kt @@ -27,6 +27,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val id: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -41,13 +42,26 @@ private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @JsonProperty("namespace") @ExcludeMissing namespace: JsonField = JsonMissing.of(), @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), @JsonProperty("created_by") @ExcludeMissing createdBy: JsonField = JsonMissing.of(), - ) : this(callId, input, name, type, id, caller, namespace, status, createdBy, mutableMapOf()) + ) : this( + callId, + input, + name, + type, + id, + async, + caller, + namespace, + status, + createdBy, + mutableMapOf(), + ) fun toResponseCustomToolCall(): ResponseCustomToolCall = ResponseCustomToolCall.builder() @@ -56,6 +70,7 @@ private constructor( .name(name) .type(type) .id(id) + .async(async) .caller(caller) .namespace(namespace) .build() @@ -105,6 +120,14 @@ private constructor( */ fun id(): Optional = id.getOptional("id") + /** + * Whether the custom tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -166,6 +189,13 @@ private constructor( */ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -232,6 +262,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("custom_tool_call") private var id: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField? = null @@ -245,6 +276,7 @@ private constructor( name = responseCustomToolCallItem.name type = responseCustomToolCallItem.type id = responseCustomToolCallItem.id + async = responseCustomToolCallItem.async caller = responseCustomToolCallItem.caller namespace = responseCustomToolCallItem.namespace status = responseCustomToolCallItem.status @@ -310,6 +342,17 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } + /** Whether the custom tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: ResponseCustomToolCall.Caller?) = caller(JsonField.ofNullable(caller)) @@ -424,6 +467,7 @@ private constructor( checkRequired("name", name), type, id, + async, caller, namespace, checkRequired("status", status), @@ -456,6 +500,7 @@ private constructor( } } id() + async() caller().ifPresent { it.validate() } namespace() status().validate() @@ -483,6 +528,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("custom_tool_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) + @@ -643,6 +689,7 @@ private constructor( name == other.name && type == other.type && id == other.id && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -657,6 +704,7 @@ private constructor( name, type, id, + async, caller, namespace, status, @@ -668,5 +716,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "ResponseCustomToolCallItem{callId=$callId, input=$input, name=$name, type=$type, id=$id, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" + "ResponseCustomToolCallItem{callId=$callId, input=$input, name=$name, type=$type, id=$id, async=$async, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseError.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseError.kt index 96f5e0206..7720e29db 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseError.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseError.kt @@ -15,6 +15,7 @@ import com.openai.core.checkRequired import com.openai.errors.OpenAIInvalidDataException import java.util.Collections import java.util.Objects +import java.util.Optional import kotlin.jvm.optionals.getOrNull /** An error object returned when the model fails to generate a Response. */ @@ -23,6 +24,7 @@ class ResponseError private constructor( private val code: JsonField, private val message: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -30,7 +32,10 @@ private constructor( private constructor( @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), - ) : this(code, message, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, misalignment, mutableMapOf()) /** * The error code for the response. @@ -48,6 +53,12 @@ private constructor( */ fun message(): String = message.getRequired("message") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -62,6 +73,15 @@ private constructor( */ @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -93,12 +113,14 @@ private constructor( private var code: JsonField? = null private var message: JsonField? = null + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(responseError: ResponseError) = apply { code = responseError.code message = responseError.message + misalignment = responseError.misalignment additionalProperties = responseError.additionalProperties.toMutableMap() } @@ -124,6 +146,19 @@ private constructor( */ fun message(message: JsonField) = apply { this.message = message } + fun misalignment(misalignment: Misalignment) = misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -160,6 +195,7 @@ private constructor( ResponseError( checkRequired("code", code), checkRequired("message", message), + misalignment, additionalProperties.toMutableMap(), ) } @@ -181,6 +217,7 @@ private constructor( code().validate() message() + misalignment().ifPresent { it.validate() } validated = true } @@ -199,7 +236,9 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (code.asKnown().getOrNull()?.validity() ?: 0) + (if (message.asKnown().isPresent) 1 else 0) + (code.asKnown().getOrNull()?.validity() ?: 0) + + (if (message.asKnown().isPresent) 1 else 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) /** The error code for the response. */ class Code @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -226,6 +265,8 @@ private constructor( @JvmField val BIO_POLICY = of("bio_policy") + @JvmField val MISALIGNMENT_POLICY_VIOLATION = of("misalignment_policy_violation") + @JvmField val VECTOR_STORE_TIMEOUT = of("vector_store_timeout") @JvmField val INVALID_IMAGE = of("invalid_image") @@ -266,6 +307,7 @@ private constructor( INVALID_PROMPT, DATA_RESIDENCY_MISMATCH, BIO_POLICY, + MISALIGNMENT_POLICY_VIOLATION, VECTOR_STORE_TIMEOUT, INVALID_IMAGE, INVALID_IMAGE_FORMAT, @@ -298,6 +340,7 @@ private constructor( INVALID_PROMPT, DATA_RESIDENCY_MISMATCH, BIO_POLICY, + MISALIGNMENT_POLICY_VIOLATION, VECTOR_STORE_TIMEOUT, INVALID_IMAGE, INVALID_IMAGE_FORMAT, @@ -331,6 +374,7 @@ private constructor( INVALID_PROMPT -> Value.INVALID_PROMPT DATA_RESIDENCY_MISMATCH -> Value.DATA_RESIDENCY_MISMATCH BIO_POLICY -> Value.BIO_POLICY + MISALIGNMENT_POLICY_VIOLATION -> Value.MISALIGNMENT_POLICY_VIOLATION VECTOR_STORE_TIMEOUT -> Value.VECTOR_STORE_TIMEOUT INVALID_IMAGE -> Value.INVALID_IMAGE INVALID_IMAGE_FORMAT -> Value.INVALID_IMAGE_FORMAT @@ -365,6 +409,7 @@ private constructor( INVALID_PROMPT -> Known.INVALID_PROMPT DATA_RESIDENCY_MISMATCH -> Known.DATA_RESIDENCY_MISMATCH BIO_POLICY -> Known.BIO_POLICY + MISALIGNMENT_POLICY_VIOLATION -> Known.MISALIGNMENT_POLICY_VIOLATION VECTOR_STORE_TIMEOUT -> Known.VECTOR_STORE_TIMEOUT INVALID_IMAGE -> Known.INVALID_IMAGE INVALID_IMAGE_FORMAT -> Known.INVALID_IMAGE_FORMAT @@ -444,6 +489,592 @@ private constructor( override fun toString() = value.toString() } + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(errorType: JsonField) = apply { this.errorType = errorType } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer(checkRequired("message", message), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -452,13 +1083,16 @@ private constructor( return other is ResponseError && code == other.code && message == other.message && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(code, message, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(code, message, misalignment, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "ResponseError{code=$code, message=$message, additionalProperties=$additionalProperties}" + "ResponseError{code=$code, message=$message, misalignment=$misalignment, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt index b6e32be12..183c5e060 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCall.kt @@ -42,6 +42,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val id: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -55,10 +56,11 @@ private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @JsonProperty("namespace") @ExcludeMissing namespace: JsonField = JsonMissing.of(), @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), - ) : this(arguments, callId, name, type, id, caller, namespace, status, mutableMapOf()) + ) : this(arguments, callId, name, type, id, async, caller, namespace, status, mutableMapOf()) /** * A JSON string of the arguments to pass to the function. @@ -120,6 +122,14 @@ private constructor( */ fun id(): Optional = id.getOptional("id") + /** + * Whether the function tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -173,6 +183,13 @@ private constructor( */ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -229,6 +246,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("function_call") private var id: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField = JsonMissing.of() @@ -241,6 +259,7 @@ private constructor( name = responseFunctionToolCall.name type = responseFunctionToolCall.type id = responseFunctionToolCall.id + async = responseFunctionToolCall.async caller = responseFunctionToolCall.caller namespace = responseFunctionToolCall.namespace status = responseFunctionToolCall.status @@ -306,6 +325,17 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } + /** Whether the function tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) @@ -403,6 +433,7 @@ private constructor( checkRequired("name", name), type, id, + async, caller, namespace, status, @@ -434,6 +465,7 @@ private constructor( } } id() + async() caller().ifPresent { it.validate() } namespace() status().ifPresent { it.validate() } @@ -460,6 +492,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) @@ -1044,6 +1077,7 @@ private constructor( name == other.name && type == other.type && id == other.id && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -1057,6 +1091,7 @@ private constructor( name, type, id, + async, caller, namespace, status, @@ -1067,5 +1102,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "ResponseFunctionToolCall{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, caller=$caller, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" + "ResponseFunctionToolCall{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, async=$async, caller=$caller, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCallItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCallItem.kt index 44a0a691a..f626e3fea 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCallItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseFunctionToolCallItem.kt @@ -31,6 +31,7 @@ private constructor( private val name: JsonField, private val type: JsonValue, private val id: JsonField, + private val async: JsonField, private val caller: JsonField, private val namespace: JsonField, private val status: JsonField, @@ -45,6 +46,7 @@ private constructor( @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("async") @ExcludeMissing async: JsonField = JsonMissing.of(), @JsonProperty("caller") @ExcludeMissing caller: JsonField = JsonMissing.of(), @@ -59,6 +61,7 @@ private constructor( name, type, id, + async, caller, namespace, status, @@ -73,6 +76,7 @@ private constructor( .name(name) .type(type) .id(id) + .async(async) .caller(caller) .namespace(namespace) .status(status) @@ -123,6 +127,14 @@ private constructor( */ fun id(): Optional = id.getOptional("id") + /** + * Whether the function tool call runs asynchronously. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun async(): Optional = async.getOptional("async") + /** * The execution context that produced this tool call. * @@ -184,6 +196,13 @@ private constructor( */ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + /** + * Returns the raw JSON value of [async]. + * + * Unlike [async], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("async") @ExcludeMissing fun _async(): JsonField = async + /** * Returns the raw JSON value of [caller]. * @@ -251,6 +270,7 @@ private constructor( private var name: JsonField? = null private var type: JsonValue = JsonValue.from("function_call") private var id: JsonField = JsonMissing.of() + private var async: JsonField = JsonMissing.of() private var caller: JsonField = JsonMissing.of() private var namespace: JsonField = JsonMissing.of() private var status: JsonField = JsonMissing.of() @@ -264,6 +284,7 @@ private constructor( name = responseFunctionToolCallItem.name type = responseFunctionToolCallItem.type id = responseFunctionToolCallItem.id + async = responseFunctionToolCallItem.async caller = responseFunctionToolCallItem.caller namespace = responseFunctionToolCallItem.namespace status = responseFunctionToolCallItem.status @@ -330,6 +351,17 @@ private constructor( */ fun id(id: JsonField) = apply { this.id = id } + /** Whether the function tool call runs asynchronously. */ + fun async(async: Boolean) = async(JsonField.of(async)) + + /** + * Sets [Builder.async] to an arbitrary JSON value. + * + * You should usually call [Builder.async] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun async(async: JsonField) = apply { this.async = async } + /** The execution context that produced this tool call. */ fun caller(caller: ResponseFunctionToolCall.Caller?) = caller(JsonField.ofNullable(caller)) @@ -446,6 +478,7 @@ private constructor( checkRequired("name", name), type, id, + async, caller, namespace, status, @@ -478,6 +511,7 @@ private constructor( } } id() + async() caller().ifPresent { it.validate() } namespace() status().ifPresent { it.validate() } @@ -505,6 +539,7 @@ private constructor( (if (name.asKnown().isPresent) 1 else 0) + type.let { if (it == JsonValue.from("function_call")) 1 else 0 } + (if (id.asKnown().isPresent) 1 else 0) + + (if (async.asKnown().isPresent) 1 else 0) + (caller.asKnown().getOrNull()?.validity() ?: 0) + (if (namespace.asKnown().isPresent) 1 else 0) + (status.asKnown().getOrNull()?.validity() ?: 0) + @@ -665,6 +700,7 @@ private constructor( name == other.name && type == other.type && id == other.id && + async == other.async && caller == other.caller && namespace == other.namespace && status == other.status && @@ -679,6 +715,7 @@ private constructor( name, type, id, + async, caller, namespace, status, @@ -690,5 +727,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "ResponseFunctionToolCallItem{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" + "ResponseFunctionToolCallItem{arguments=$arguments, callId=$callId, name=$name, type=$type, id=$id, async=$async, caller=$caller, namespace=$namespace, status=$status, createdBy=$createdBy, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseIncompleteEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseIncompleteEvent.kt index 23aa47bec..627de150b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseIncompleteEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseIncompleteEvent.kt @@ -16,7 +16,13 @@ import java.util.Collections import java.util.Objects import kotlin.jvm.optionals.getOrNull -/** An event that is emitted when a response finishes as incomplete. */ +/** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set to + * `steered`, followed automatically by a successor `response.created` that commits the queued + * steering input. + */ class ResponseIncompleteEvent @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt index 1b30d84bc..3ef35dffe 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseInputItem.kt @@ -54,6 +54,7 @@ private constructor( private val toolSearchCall: ToolSearchCall? = null, private val toolSearchOutput: ResponseToolSearchOutputItemParam? = null, private val additionalTools: AdditionalTools? = null, + private val configurationUpdate: ResponseConfigurationUpdateItemParam? = null, private val reasoning: ResponseReasoningItem? = null, private val compaction: ResponseCompactionItemParam? = null, private val imageGenerationCall: ImageGenerationCall? = null, @@ -137,6 +138,13 @@ private constructor( fun additionalTools(): Optional = Optional.ofNullable(additionalTools) + /** + * An update to the conversation's response configuration. The configuration remains in effect + * for subsequent responses until it is replaced by another configuration update. + */ + fun configurationUpdate(): Optional = + Optional.ofNullable(configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -233,6 +241,8 @@ private constructor( fun isAdditionalTools(): Boolean = additionalTools != null + fun isConfigurationUpdate(): Boolean = configurationUpdate != null + fun isReasoning(): Boolean = reasoning != null fun isCompaction(): Boolean = compaction != null @@ -335,6 +345,13 @@ private constructor( fun asAdditionalTools(): AdditionalTools = additionalTools.getOrThrow("additionalTools") + /** + * An update to the conversation's response configuration. The configuration remains in effect + * for subsequent responses until it is replaced by another configuration update. + */ + fun asConfigurationUpdate(): ResponseConfigurationUpdateItemParam = + configurationUpdate.getOrThrow("configurationUpdate") + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -454,6 +471,7 @@ private constructor( toolSearchCall != null -> visitor.visitToolSearchCall(toolSearchCall) toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) additionalTools != null -> visitor.visitAdditionalTools(additionalTools) + configurationUpdate != null -> visitor.visitConfigurationUpdate(configurationUpdate) reasoning != null -> visitor.visitReasoning(reasoning) compaction != null -> visitor.visitCompaction(compaction) imageGenerationCall != null -> visitor.visitImageGenerationCall(imageGenerationCall) @@ -546,6 +564,12 @@ private constructor( additionalTools.validate() } + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItemParam + ) { + configurationUpdate.validate() + } + override fun visitReasoning(reasoning: ResponseReasoningItem) { reasoning.validate() } @@ -694,6 +718,10 @@ private constructor( override fun visitAdditionalTools(additionalTools: AdditionalTools) = additionalTools.validity() + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItemParam + ) = configurationUpdate.validity() + override fun visitReasoning(reasoning: ResponseReasoningItem) = reasoning.validity() override fun visitCompaction(compaction: ResponseCompactionItemParam) = @@ -775,6 +803,7 @@ private constructor( toolSearchCall == other.toolSearchCall && toolSearchOutput == other.toolSearchOutput && additionalTools == other.additionalTools && + configurationUpdate == other.configurationUpdate && reasoning == other.reasoning && compaction == other.compaction && imageGenerationCall == other.imageGenerationCall && @@ -811,6 +840,7 @@ private constructor( toolSearchCall, toolSearchOutput, additionalTools, + configurationUpdate, reasoning, compaction, imageGenerationCall, @@ -850,6 +880,8 @@ private constructor( toolSearchCall != null -> "ResponseInputItem{toolSearchCall=$toolSearchCall}" toolSearchOutput != null -> "ResponseInputItem{toolSearchOutput=$toolSearchOutput}" additionalTools != null -> "ResponseInputItem{additionalTools=$additionalTools}" + configurationUpdate != null -> + "ResponseInputItem{configurationUpdate=$configurationUpdate}" reasoning != null -> "ResponseInputItem{reasoning=$reasoning}" compaction != null -> "ResponseInputItem{compaction=$compaction}" imageGenerationCall != null -> @@ -963,6 +995,14 @@ private constructor( fun ofAdditionalTools(additionalTools: AdditionalTools) = ResponseInputItem(additionalTools = additionalTools) + /** + * An update to the conversation's response configuration. The configuration remains in + * effect for subsequent responses until it is replaced by another configuration update. + */ + @JvmStatic + fun ofConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItemParam) = + ResponseInputItem(configurationUpdate = configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1131,6 +1171,12 @@ private constructor( fun visitAdditionalTools(additionalTools: AdditionalTools): T + /** + * An update to the conversation's response configuration. The configuration remains in + * effect for subsequent responses until it is replaced by another configuration update. + */ + fun visitConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItemParam): T + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1293,6 +1339,14 @@ private constructor( ResponseInputItem(additionalTools = it, _json = json) } ?: ResponseInputItem(_json = json) } + "configuration_update" -> { + return tryDeserialize( + node, + jacksonTypeRef(), + ) + ?.let { ResponseInputItem(configurationUpdate = it, _json = json) } + ?: ResponseInputItem(_json = json) + } "reasoning" -> { return tryDeserialize(node, jacksonTypeRef())?.let { ResponseInputItem(reasoning = it, _json = json) @@ -1420,6 +1474,8 @@ private constructor( value.toolSearchCall != null -> generator.writeObject(value.toolSearchCall) value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) value.additionalTools != null -> generator.writeObject(value.additionalTools) + value.configurationUpdate != null -> + generator.writeObject(value.configurationUpdate) value.reasoning != null -> generator.writeObject(value.reasoning) value.compaction != null -> generator.writeObject(value.compaction) value.imageGenerationCall != null -> diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseItem.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseItem.kt index 21eae5bf2..f7c9c2ec0 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseItem.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseItem.kt @@ -47,6 +47,7 @@ private constructor( private val toolSearchCall: ResponseToolSearchCall? = null, private val toolSearchOutput: ResponseToolSearchOutputItem? = null, private val additionalTools: AdditionalTools? = null, + private val configurationUpdate: ResponseConfigurationUpdateItem? = null, private val reasoning: ResponseReasoningItem? = null, private val program: Program? = null, private val programOutput: ProgramOutput? = null, @@ -116,6 +117,13 @@ private constructor( fun additionalTools(): Optional = Optional.ofNullable(additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun configurationUpdate(): Optional = + Optional.ofNullable(configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -205,6 +213,8 @@ private constructor( fun isAdditionalTools(): Boolean = additionalTools != null + fun isConfigurationUpdate(): Boolean = configurationUpdate != null + fun isReasoning(): Boolean = reasoning != null fun isProgram(): Boolean = program != null @@ -289,6 +299,13 @@ private constructor( fun asAdditionalTools(): AdditionalTools = additionalTools.getOrThrow("additionalTools") + /** + * A configuration update that applies to subsequent responses until it is replaced by another + * configuration update. + */ + fun asConfigurationUpdate(): ResponseConfigurationUpdateItem = + configurationUpdate.getOrThrow("configurationUpdate") + /** * A description of the chain of thought used by a reasoning model while generating a response. * Be sure to include these items in your `input` to the Responses API for subsequent turns of a @@ -403,6 +420,7 @@ private constructor( toolSearchCall != null -> visitor.visitToolSearchCall(toolSearchCall) toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) additionalTools != null -> visitor.visitAdditionalTools(additionalTools) + configurationUpdate != null -> visitor.visitConfigurationUpdate(configurationUpdate) reasoning != null -> visitor.visitReasoning(reasoning) program != null -> visitor.visitProgram(program) programOutput != null -> visitor.visitProgramOutput(programOutput) @@ -493,6 +511,12 @@ private constructor( additionalTools.validate() } + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ) { + configurationUpdate.validate() + } + override fun visitReasoning(reasoning: ResponseReasoningItem) { reasoning.validate() } @@ -631,6 +655,10 @@ private constructor( override fun visitAdditionalTools(additionalTools: AdditionalTools) = additionalTools.validity() + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ) = configurationUpdate.validity() + override fun visitReasoning(reasoning: ResponseReasoningItem) = reasoning.validity() override fun visitProgram(program: Program) = program.validity() @@ -706,6 +734,7 @@ private constructor( toolSearchCall == other.toolSearchCall && toolSearchOutput == other.toolSearchOutput && additionalTools == other.additionalTools && + configurationUpdate == other.configurationUpdate && reasoning == other.reasoning && program == other.program && programOutput == other.programOutput && @@ -739,6 +768,7 @@ private constructor( toolSearchCall, toolSearchOutput, additionalTools, + configurationUpdate, reasoning, program, programOutput, @@ -774,6 +804,7 @@ private constructor( toolSearchCall != null -> "ResponseItem{toolSearchCall=$toolSearchCall}" toolSearchOutput != null -> "ResponseItem{toolSearchOutput=$toolSearchOutput}" additionalTools != null -> "ResponseItem{additionalTools=$additionalTools}" + configurationUpdate != null -> "ResponseItem{configurationUpdate=$configurationUpdate}" reasoning != null -> "ResponseItem{reasoning=$reasoning}" program != null -> "ResponseItem{program=$program}" programOutput != null -> "ResponseItem{programOutput=$programOutput}" @@ -866,6 +897,14 @@ private constructor( fun ofAdditionalTools(additionalTools: AdditionalTools) = ResponseItem(additionalTools = additionalTools) + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + @JvmStatic + fun ofConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItem) = + ResponseItem(configurationUpdate = configurationUpdate) + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1004,6 +1043,12 @@ private constructor( fun visitAdditionalTools(additionalTools: AdditionalTools): T + /** + * A configuration update that applies to subsequent responses until it is replaced by + * another configuration update. + */ + fun visitConfigurationUpdate(configurationUpdate: ResponseConfigurationUpdateItem): T + /** * A description of the chain of thought used by a reasoning model while generating a * response. Be sure to include these items in your `input` to the Responses API for @@ -1161,6 +1206,11 @@ private constructor( ResponseItem(additionalTools = it, _json = json) } ?: ResponseItem(_json = json) } + "configuration_update" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { ResponseItem(configurationUpdate = it, _json = json) } + ?: ResponseItem(_json = json) + } "reasoning" -> { return tryDeserialize(node, jacksonTypeRef())?.let { ResponseItem(reasoning = it, _json = json) @@ -1281,6 +1331,8 @@ private constructor( value.toolSearchCall != null -> generator.writeObject(value.toolSearchCall) value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) value.additionalTools != null -> generator.writeObject(value.additionalTools) + value.configurationUpdate != null -> + generator.writeObject(value.configurationUpdate) value.reasoning != null -> generator.writeObject(value.reasoning) value.program != null -> generator.writeObject(value.program) value.programOutput != null -> generator.writeObject(value.programOutput) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerAcceptedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerAcceptedEvent.kt new file mode 100644 index 000000000..b9350df74 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerAcceptedEvent.kt @@ -0,0 +1,536 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when steering input has been validated and queued. Acceptance means the server owns the + * input, not that it has been applied. The successor's `response.created` event is the commit + * point. If accepted input cannot be committed, `response.steer.failed` returns it with the same + * steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued and + * `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` per + * parent. Do not resend accepted input while it is still queued. + */ +class ResponseSteerAcceptedEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The accepted steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.accepted`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.accepted") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event. This field is present when the target response's + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ResponseSteerAcceptedEvent]. + * + * The following fields are required: + * ```java + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseSteerAcceptedEvent]. */ + class Builder internal constructor() { + + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.accepted") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(responseSteerAcceptedEvent: ResponseSteerAcceptedEvent) = apply { + sequenceNumber = responseSteerAcceptedEvent.sequenceNumber + steer = responseSteerAcceptedEvent.steer + type = responseSteerAcceptedEvent.type + streamId = responseSteerAcceptedEvent.streamId + additionalProperties = responseSteerAcceptedEvent.additionalProperties.toMutableMap() + } + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The accepted steering submission. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.accepted") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event. This field is present when the target + * response's `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseSteerAcceptedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ResponseSteerAcceptedEvent = + ResponseSteerAcceptedEvent( + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerAcceptedEvent = apply { + if (validated) { + return@apply + } + + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.accepted")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.accepted")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** The accepted steering submission. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val previousResponseId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + ) : this(id, previousResponseId, mutableMapOf()) + + /** + * The ID assigned to the steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The ID of the response being steered. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var previousResponseId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + id = steer.id + previousResponseId = steer.previousResponseId + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The ID assigned to the steering submission. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The ID of the response being steered. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("id", id), + checkRequired("previousResponseId", previousResponseId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + id() + previousResponseId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + id == other.id && + previousResponseId == other.previousResponseId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, previousResponseId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{id=$id, previousResponseId=$previousResponseId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerAcceptedEvent && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(sequenceNumber, steer, type, streamId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseSteerAcceptedEvent{sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerErrorCode.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerErrorCode.kt new file mode 100644 index 000000000..bb6d2f528 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerErrorCode.kt @@ -0,0 +1,184 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.errors.OpenAIInvalidDataException + +/** + * A machine-readable steering error code. Clients should handle unknown values because additional + * codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + */ +class ResponseSteerErrorCode +@JsonCreator +private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't match + * any known member, and you want to know that value. For example, if the SDK is on an older + * version than the API, then the API may respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val RESPONSE_NOT_FOUND = of("response_not_found") + + @JvmField val INVALID_INPUT = of("invalid_input") + + @JvmField val STEERING_NOT_SUPPORTED = of("steering_not_supported") + + @JvmField val TOO_MANY_PENDING_STEERS = of("too_many_pending_steers") + + @JvmField val RESPONSE_ALREADY_COMPLETED = of("response_already_completed") + + @JvmField val RESPONSE_NOT_ACTIVE = of("response_not_active") + + @JvmField val SUCCESSOR_CREATION_FAILED = of("successor_creation_failed") + + @JvmStatic fun of(value: String) = ResponseSteerErrorCode(JsonField.of(value)) + } + + /** An enum containing [ResponseSteerErrorCode]'s known values. */ + enum class Known { + RESPONSE_NOT_FOUND, + INVALID_INPUT, + STEERING_NOT_SUPPORTED, + TOO_MANY_PENDING_STEERS, + RESPONSE_ALREADY_COMPLETED, + RESPONSE_NOT_ACTIVE, + SUCCESSOR_CREATION_FAILED, + } + + /** + * An enum containing [ResponseSteerErrorCode]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ResponseSteerErrorCode] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the SDK + * is on an older version than the API, then the API may respond with new members that the SDK + * is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + RESPONSE_NOT_FOUND, + INVALID_INPUT, + STEERING_NOT_SUPPORTED, + TOO_MANY_PENDING_STEERS, + RESPONSE_ALREADY_COMPLETED, + RESPONSE_NOT_ACTIVE, + SUCCESSOR_CREATION_FAILED, + /** + * An enum member indicating that [ResponseSteerErrorCode] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] if + * the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want to + * throw for the unknown case. + */ + fun value(): Value = + when (this) { + RESPONSE_NOT_FOUND -> Value.RESPONSE_NOT_FOUND + INVALID_INPUT -> Value.INVALID_INPUT + STEERING_NOT_SUPPORTED -> Value.STEERING_NOT_SUPPORTED + TOO_MANY_PENDING_STEERS -> Value.TOO_MANY_PENDING_STEERS + RESPONSE_ALREADY_COMPLETED -> Value.RESPONSE_ALREADY_COMPLETED + RESPONSE_NOT_ACTIVE -> Value.RESPONSE_NOT_ACTIVE + SUCCESSOR_CREATION_FAILED -> Value.SUCCESSOR_CREATION_FAILED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't want + * to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + RESPONSE_NOT_FOUND -> Known.RESPONSE_NOT_FOUND + INVALID_INPUT -> Known.INVALID_INPUT + STEERING_NOT_SUPPORTED -> Known.STEERING_NOT_SUPPORTED + TOO_MANY_PENDING_STEERS -> Known.TOO_MANY_PENDING_STEERS + RESPONSE_ALREADY_COMPLETED -> Known.RESPONSE_ALREADY_COMPLETED + RESPONSE_NOT_ACTIVE -> Known.RESPONSE_NOT_ACTIVE + SUCCESSOR_CREATION_FAILED -> Known.SUCCESSOR_CREATION_FAILED + else -> throw OpenAIInvalidDataException("Unknown ResponseSteerErrorCode: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging and + * generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerErrorCode = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerErrorCode && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerEvent.kt new file mode 100644 index 000000000..1af59653c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerEvent.kt @@ -0,0 +1,320 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and execution + * modes that support steering. Responses bound to a conversation or using automatic compaction do + * not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not that it + * has been applied. The successor's `response.created` event is the commit point. Input that cannot + * be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed automatically by + * a successor `response.created`. Normal completion can also be followed by an automatic successor. + * Automatic successors inherit the previous response's settings and continue from it with the + * queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and send + * one explicit `response.create` per parent with the same `previous_response_id` and WebSocket + * lane. Do not rerun tools or resend accepted steering input. The queued input is prepended in + * submission order to that request's input, and the explicit request retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; the + * target response determines the WebSocket lane. + */ +class ResponseSteerEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val input: JsonField, + private val previousResponseId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(input, previousResponseId, type, mutableMapOf()) + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item shape + * as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only `type`, + * `role`, and `content`, with `content` as a string or an array of `input_text`, `input_image`, + * and `input_file` parts. The optional `type` must be `message`. Other roles, tool outputs, and + * item types are not supported for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): ResponseSteerInput = input.getRequired("input") + + /** + * The ID of the response to steer on this WebSocket connection. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * The event discriminator. Always `response.steer`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ResponseSteerEvent]. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseSteerEvent]. */ + class Builder internal constructor() { + + private var input: JsonField? = null + private var previousResponseId: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(responseSteerEvent: ResponseSteerEvent) = apply { + input = responseSteerEvent.input + previousResponseId = responseSteerEvent.previousResponseId + type = responseSteerEvent.type + additionalProperties = responseSteerEvent.additionalProperties.toMutableMap() + } + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of `input_text`, + * `input_image`, and `input_file` parts. The optional `type` must be `message`. Other + * roles, tool outputs, and item types are not supported for steering. + */ + fun input(input: ResponseSteerInput) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [ResponseSteerInput] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** Alias for calling [input] with `ResponseSteerInput.ofText(text)`. */ + fun input(text: String) = input(ResponseSteerInput.ofText(text)) + + /** Alias for calling [input] with `ResponseSteerInput.ofItemList(itemList)`. */ + fun inputOfItemList(itemList: List) = + input(ResponseSteerInput.ofItemList(itemList)) + + /** The ID of the response to steer on this WebSocket connection. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseSteerEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ResponseSteerEvent = + ResponseSteerEvent( + checkRequired("input", input), + checkRequired("previousResponseId", previousResponseId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerEvent = apply { + if (validated) { + return@apply + } + + input().validate() + previousResponseId() + _type().let { + if (it != JsonValue.from("response.steer")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("response.steer")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerEvent && + input == other.input && + previousResponseId == other.previousResponseId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, previousResponseId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseSteerEvent{input=$input, previousResponseId=$previousResponseId, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerFailedEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerFailedEvent.kt new file mode 100644 index 000000000..6bf04289d --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerFailedEvent.kt @@ -0,0 +1,910 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when steering input is rejected or cannot be committed to a successor response. Returns + * the original, uncommitted input so the client can carry it into `response.create` when + * appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated omit + * `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it is not + * proof that the input was rejected. + */ +class ResponseSteerFailedEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val error: JsonField, + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(), + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(error, sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * Information about why the input could not be committed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun error(): Error = error.getRequired("error") + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The steering submission that could not be committed. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.failed`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.failed") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event, when the target response is available and its + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [error]. + * + * Unlike [error], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ResponseSteerFailedEvent]. + * + * The following fields are required: + * ```java + * .error() + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseSteerFailedEvent]. */ + class Builder internal constructor() { + + private var error: JsonField? = null + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.failed") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(responseSteerFailedEvent: ResponseSteerFailedEvent) = apply { + error = responseSteerFailedEvent.error + sequenceNumber = responseSteerFailedEvent.sequenceNumber + steer = responseSteerFailedEvent.steer + type = responseSteerFailedEvent.type + streamId = responseSteerFailedEvent.streamId + additionalProperties = responseSteerFailedEvent.additionalProperties.toMutableMap() + } + + /** Information about why the input could not be committed. */ + fun error(error: Error) = error(JsonField.of(error)) + + /** + * Sets [Builder.error] to an arbitrary JSON value. + * + * You should usually call [Builder.error] with a well-typed [Error] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun error(error: JsonField) = apply { this.error = error } + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The steering submission that could not be committed. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.failed") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event, when the target response is available and its + * `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseSteerFailedEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .error() + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ResponseSteerFailedEvent = + ResponseSteerFailedEvent( + checkRequired("error", error), + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerFailedEvent = apply { + if (validated) { + return@apply + } + + error().validate() + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.failed")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (error.asKnown().getOrNull()?.validity() ?: 0) + + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.failed")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** Information about why the input could not be committed. */ + class Error + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val code: JsonField, + private val message: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("code") + @ExcludeMissing + code: JsonField = JsonMissing.of(), + @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(code, message, type, mutableMapOf()) + + /** + * A machine-readable steering error code. Clients should handle unknown values because + * additional codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support + * steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting + * steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun code(): ResponseSteerErrorCode = code.getRequired("code") + + /** + * A human-readable description of the error. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun message(): String = message.getRequired("message") + + /** + * The error type. Always `invalid_request_error`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("invalid_request_error") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Error]. + * + * The following fields are required: + * ```java + * .code() + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Error]. */ + class Builder internal constructor() { + + private var code: JsonField? = null + private var message: JsonField? = null + private var type: JsonValue = JsonValue.from("invalid_request_error") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(error: Error) = apply { + code = error.code + message = error.message + type = error.type + additionalProperties = error.additionalProperties.toMutableMap() + } + + /** + * A machine-readable steering error code. Clients should handle unknown values because + * additional codes may be introduced. Known values include: + * - `response_not_found`: The target response is not available on this connection. + * - `invalid_input`: The event or input failed validation. + * - `steering_not_supported`: The model or response execution mode does not support + * steering. + * - `too_many_pending_steers`: Too much steering input is pending for the response. + * - `response_already_completed`: The response completed and is no longer accepting + * steering input. + * - `response_not_active`: The response is no longer accepting steering input. + * - `successor_creation_failed`: The successor response could not be created. + */ + fun code(code: ResponseSteerErrorCode) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [ResponseSteerErrorCode] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + /** + * Sets [code] to an arbitrary [String]. + * + * You should usually call [code] with a well-typed [ResponseSteerErrorCode] constant + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun code(value: String) = code(ResponseSteerErrorCode.of(value)) + + /** A human-readable description of the error. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("invalid_request_error") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Error]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Error = + Error( + checkRequired("code", code), + checkRequired("message", message), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Error = apply { + if (validated) { + return@apply + } + + code() + message() + _type().let { + if (it != JsonValue.from("invalid_request_error")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (code.asKnown().isPresent) 1 else 0) + + (if (message.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("invalid_request_error")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Error && + code == other.code && + message == other.message && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(code, message, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Error{code=$code, message=$message, type=$type, additionalProperties=$additionalProperties}" + } + + /** The steering submission that could not be committed. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val input: JsonField, + private val previousResponseId: JsonField, + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + ) : this(input, previousResponseId, id, mutableMapOf()) + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of `input_text`, + * `input_image`, and `input_file` parts. The optional `type` must be `message`. Other + * roles, tool outputs, and item types are not supported for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun input(): ResponseSteerInput = input.getRequired("input") + + /** + * The ID of the response that was targeted for steering. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * The ID assigned to the steering submission, if one was allocated. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var input: JsonField? = null + private var previousResponseId: JsonField? = null + private var id: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + input = steer.input + previousResponseId = steer.previousResponseId + id = steer.id + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** + * Input to queue for a continuation of the response. Uses the same string or input-item + * shape as `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only + * `type`, `role`, and `content`, with `content` as a string or an array of + * `input_text`, `input_image`, and `input_file` parts. The optional `type` must be + * `message`. Other roles, tool outputs, and item types are not supported for steering. + */ + fun input(input: ResponseSteerInput) = input(JsonField.of(input)) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [ResponseSteerInput] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** Alias for calling [input] with `ResponseSteerInput.ofText(text)`. */ + fun input(text: String) = input(ResponseSteerInput.ofText(text)) + + /** Alias for calling [input] with `ResponseSteerInput.ofItemList(itemList)`. */ + fun inputOfItemList(itemList: List) = + input(ResponseSteerInput.ofItemList(itemList)) + + /** The ID of the response that was targeted for steering. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + /** The ID assigned to the steering submission, if one was allocated. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .input() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("input", input), + checkRequired("previousResponseId", previousResponseId), + id, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + input().validate() + previousResponseId() + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + input == other.input && + previousResponseId == other.previousResponseId && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, previousResponseId, id, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{input=$input, previousResponseId=$previousResponseId, id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerFailedEvent && + error == other.error && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(error, sequenceNumber, steer, type, streamId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseSteerFailedEvent{error=$error, sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInput.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInput.kt new file mode 100644 index 000000000..3438c5bec --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInput.kt @@ -0,0 +1,2429 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.allMaxBy +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Input to queue for a continuation of the response. Uses the same string or input-item shape as + * `response.create.input`, with a non-empty array when supplying input items. + * + * Steering accepts only messages with the `user` role. Each message may contain only `type`, + * `role`, and `content`, with `content` as a string or an array of `input_text`, `input_image`, and + * `input_file` parts. The optional `type` must be `message`. Other roles, tool outputs, and item + * types are not supported for steering. + */ +@JsonDeserialize(using = ResponseSteerInput.Deserializer::class) +@JsonSerialize(using = ResponseSteerInput.Serializer::class) +class ResponseSteerInput +private constructor( + private val text: String? = null, + private val itemList: List? = null, + private val _json: JsonValue? = null, +) { + + /** A text input, equivalent to a message with the `user` role. */ + fun text(): Optional = Optional.ofNullable(text) + + /** A non-empty list of message inputs to queue for the response. */ + fun itemList(): Optional> = Optional.ofNullable(itemList) + + fun isText(): Boolean = text != null + + fun isItemList(): Boolean = itemList != null + + /** A text input, equivalent to a message with the `user` role. */ + fun asText(): String = text.getOrThrow("text") + + /** A non-empty list of message inputs to queue for the response. */ + fun asItemList(): List = itemList.getOrThrow("itemList") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = responseSteerInput.accept(new ResponseSteerInput.Visitor>() { + * @Override + * public Optional visitText(String text) { + * return Optional.of(text.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + text != null -> visitor.visitText(text) + itemList != null -> visitor.visitItemList(itemList) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerInput = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitText(text: String) {} + + override fun visitItemList(itemList: List) { + itemList.forEach { it.validate() } + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitText(text: String) = 1 + + override fun visitItemList(itemList: List) = + itemList.sumOf { it.validity().toInt() } + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerInput && text == other.text && itemList == other.itemList + } + + override fun hashCode(): Int = Objects.hash(text, itemList) + + override fun toString(): String = + when { + text != null -> "ResponseSteerInput{text=$text}" + itemList != null -> "ResponseSteerInput{itemList=$itemList}" + _json != null -> "ResponseSteerInput{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseSteerInput") + } + + companion object { + + /** A text input, equivalent to a message with the `user` role. */ + @JvmStatic fun ofText(text: String) = ResponseSteerInput(text = text) + + /** A non-empty list of message inputs to queue for the response. */ + @JvmStatic + fun ofItemList(itemList: List) = + ResponseSteerInput(itemList = itemList.toImmutable()) + } + + /** + * An interface that defines how to map each variant of [ResponseSteerInput] to a value of type + * [T]. + */ + interface Visitor { + + /** A text input, equivalent to a message with the `user` role. */ + fun visitText(text: String): T + + /** A non-empty list of message inputs to queue for the response. */ + fun visitItemList(itemList: List): T + + /** + * Maps an unknown variant of [ResponseSteerInput] to a value of type [T]. + * + * An instance of [ResponseSteerInput] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is unaware + * of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponseSteerInput: $json") + } + } + + internal class Deserializer : BaseDeserializer(ResponseSteerInput::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseSteerInput { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInput(text = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>())?.let { + ResponseSteerInput(itemList = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> ResponseSteerInput(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ResponseSteerInput::class) { + + override fun serialize( + value: ResponseSteerInput, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.text != null -> generator.writeObject(value.text) + value.itemList != null -> generator.writeObject(value.itemList) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseSteerInput") + } + } + } + + /** The output of a function tool call. */ + @JsonDeserialize(using = ResponseSteerInputItem.Deserializer::class) + @JsonSerialize(using = ResponseSteerInputItem.Serializer::class) + class ResponseSteerInputItem + private constructor( + private val message: Message? = null, + private val functionCallOutput: FunctionCallOutput? = null, + private val _json: JsonValue? = null, + ) { + + fun message(): Optional = Optional.ofNullable(message) + + /** The output of a function tool call. */ + fun functionCallOutput(): Optional = + Optional.ofNullable(functionCallOutput) + + fun isMessage(): Boolean = message != null + + fun isFunctionCallOutput(): Boolean = functionCallOutput != null + + fun asMessage(): Message = message.getOrThrow("message") + + /** The output of a function tool call. */ + fun asFunctionCallOutput(): FunctionCallOutput = + functionCallOutput.getOrThrow("functionCallOutput") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of + * the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = responseSteerInputItem.accept(new ResponseSteerInputItem.Visitor>() { + * @Override + * public Optional visitMessage(Message message) { + * return Optional.of(message.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] + * and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + message != null -> visitor.visitMessage(message) + functionCallOutput != null -> visitor.visitFunctionCallOutput(functionCallOutput) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerInputItem = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitMessage(message: Message) { + message.validate() + } + + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) { + functionCallOutput.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitMessage(message: Message) = message.validity() + + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + functionCallOutput.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerInputItem && + message == other.message && + functionCallOutput == other.functionCallOutput + } + + override fun hashCode(): Int = Objects.hash(message, functionCallOutput) + + override fun toString(): String = + when { + message != null -> "ResponseSteerInputItem{message=$message}" + functionCallOutput != null -> + "ResponseSteerInputItem{functionCallOutput=$functionCallOutput}" + _json != null -> "ResponseSteerInputItem{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseSteerInputItem") + } + + companion object { + + @JvmStatic fun ofMessage(message: Message) = ResponseSteerInputItem(message = message) + + /** The output of a function tool call. */ + @JvmStatic + fun ofFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + ResponseSteerInputItem(functionCallOutput = functionCallOutput) + } + + /** + * An interface that defines how to map each variant of [ResponseSteerInputItem] to a value + * of type [T]. + */ + interface Visitor { + + fun visitMessage(message: Message): T + + /** The output of a function tool call. */ + fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput): T + + /** + * Maps an unknown variant of [ResponseSteerInputItem] to a value of type [T]. + * + * An instance of [ResponseSteerInputItem] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK + * is on an older version than the API, then the API may respond with new variants that + * the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponseSteerInputItem: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ResponseSteerInputItem::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseSteerInputItem { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "message" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputItem(message = it, _json = json) + } ?: ResponseSteerInputItem(_json = json) + } + "function_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputItem(functionCallOutput = it, _json = json) + } ?: ResponseSteerInputItem(_json = json) + } + } + + return ResponseSteerInputItem(_json = json) + } + } + + internal class Serializer : + BaseSerializer(ResponseSteerInputItem::class) { + + override fun serialize( + value: ResponseSteerInputItem, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.message != null -> generator.writeObject(value.message) + value.functionCallOutput != null -> + generator.writeObject(value.functionCallOutput) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseSteerInputItem") + } + } + } + + class Message + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val content: JsonField, + private val role: JsonValue, + private val type: JsonValue, + private val id: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("content") + @ExcludeMissing + content: JsonField = JsonMissing.of(), + @JsonProperty("role") @ExcludeMissing role: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(content, role, type, id, status, mutableMapOf()) + + /** + * The message content, as an array of content parts. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun content(): Content = content.getRequired("content") + + /** + * The message role. Always `user`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("user") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("role") @ExcludeMissing fun _role(): JsonValue = role + + /** + * The item type. Always `message`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("message") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of this message item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * The status of the message item. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [content]. + * + * Unlike [content], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("content") @ExcludeMissing fun _content(): JsonField = content + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Message]. + * + * The following fields are required: + * ```java + * .content() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Message]. */ + class Builder internal constructor() { + + private var content: JsonField? = null + private var role: JsonValue = JsonValue.from("user") + private var type: JsonValue = JsonValue.from("message") + private var id: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(message: Message) = apply { + content = message.content + role = message.role + type = message.type + id = message.id + status = message.status + additionalProperties = message.additionalProperties.toMutableMap() + } + + /** The message content, as an array of content parts. */ + fun content(content: Content) = content(JsonField.of(content)) + + /** + * Sets [Builder.content] to an arbitrary JSON value. + * + * You should usually call [Builder.content] with a well-typed [Content] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun content(content: JsonField) = apply { this.content = content } + + /** + * Alias for calling [content] with + * `Content.ofResponseSteerInputContents(responseSteerInputContents)`. + */ + fun contentOfResponseSteerInputContents( + responseSteerInputContents: List + ) = content(Content.ofResponseSteerInputContents(responseSteerInputContents)) + + /** Alias for calling [content] with `Content.ofString(string)`. */ + fun content(string: String) = content(Content.ofString(string)) + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("user") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun role(role: JsonValue) = apply { this.role = role } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("message") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** The unique ID of this message item. */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The status of the message item. */ + fun status(status: String?) = status(JsonField.ofNullable(status)) + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional) = status(status.getOrNull()) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Message]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .content() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Message = + Message( + checkRequired("content", content), + role, + type, + id, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Message = apply { + if (validated) { + return@apply + } + + content().validate() + _role().let { + if (it != JsonValue.from("user")) { + throw OpenAIInvalidDataException("'role' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("message")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + status() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (content.asKnown().getOrNull()?.validity() ?: 0) + + role.let { if (it == JsonValue.from("user")) 1 else 0 } + + type.let { if (it == JsonValue.from("message")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (if (status.asKnown().isPresent) 1 else 0) + + /** The message content, as an array of content parts. */ + @JsonDeserialize(using = Content.Deserializer::class) + @JsonSerialize(using = Content.Serializer::class) + class Content + private constructor( + private val responseSteerInputContents: List? = null, + private val string: String? = null, + private val _json: JsonValue? = null, + ) { + + fun responseSteerInputContents(): Optional> = + Optional.ofNullable(responseSteerInputContents) + + /** The message content, as a single string. */ + fun string(): Optional = Optional.ofNullable(string) + + fun isResponseSteerInputContents(): Boolean = responseSteerInputContents != null + + fun isString(): Boolean = string != null + + fun asResponseSteerInputContents(): List = + responseSteerInputContents.getOrThrow("responseSteerInputContents") + + /** The message content, as a single string. */ + fun asString(): String = string.getOrThrow("string") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = content.accept(new Content.Visitor>() { + * @Override + * public Optional visitResponseSteerInputContents(List responseSteerInputContents) { + * return Optional.of(responseSteerInputContents.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + responseSteerInputContents != null -> + visitor.visitResponseSteerInputContents(responseSteerInputContents) + string != null -> visitor.visitString(string) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Content = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitResponseSteerInputContents( + responseSteerInputContents: List + ) { + responseSteerInputContents.forEach { it.validate() } + } + + override fun visitString(string: String) {} + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitResponseSteerInputContents( + responseSteerInputContents: List + ) = responseSteerInputContents.sumOf { it.validity().toInt() } + + override fun visitString(string: String) = 1 + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Content && + responseSteerInputContents == other.responseSteerInputContents && + string == other.string + } + + override fun hashCode(): Int = Objects.hash(responseSteerInputContents, string) + + override fun toString(): String = + when { + responseSteerInputContents != null -> + "Content{responseSteerInputContents=$responseSteerInputContents}" + string != null -> "Content{string=$string}" + _json != null -> "Content{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Content") + } + + companion object { + + @JvmStatic + fun ofResponseSteerInputContents( + responseSteerInputContents: List + ) = + Content( + responseSteerInputContents = responseSteerInputContents.toImmutable() + ) + + /** The message content, as a single string. */ + @JvmStatic fun ofString(string: String) = Content(string = string) + } + + /** + * An interface that defines how to map each variant of [Content] to a value of type + * [T]. + */ + interface Visitor { + + fun visitResponseSteerInputContents( + responseSteerInputContents: List + ): T + + /** The message content, as a single string. */ + fun visitString(string: String): T + + /** + * Maps an unknown variant of [Content] to a value of type [T]. + * + * An instance of [Content] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if + * the SDK is on an older version than the API, then the API may respond with + * new variants that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Content: $json") + } + } + + internal class Deserializer : BaseDeserializer(Content::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Content { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Content(string = it, _json = json) + }, + tryDeserialize( + node, + jacksonTypeRef>(), + ) + ?.let { + Content(responseSteerInputContents = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // boolean). + 0 -> Content(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Content::class) { + + override fun serialize( + value: Content, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.responseSteerInputContents != null -> + generator.writeObject(value.responseSteerInputContents) + value.string != null -> generator.writeObject(value.string) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Content") + } + } + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Message && + content == other.content && + role == other.role && + type == other.type && + id == other.id && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(content, role, type, id, status, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Message{content=$content, role=$role, type=$type, id=$id, status=$status, additionalProperties=$additionalProperties}" + } + + /** The output of a function tool call. */ + class FunctionCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val output: JsonField, + private val type: JsonValue, + private val id: JsonField, + private val callId: JsonField, + private val caller: JsonField, + private val name: JsonField, + private val namespace: JsonField, + private val status: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("output") + @ExcludeMissing + output: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("call_id") + @ExcludeMissing + callId: JsonField = JsonMissing.of(), + @JsonProperty("caller") + @ExcludeMissing + caller: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("namespace") + @ExcludeMissing + namespace: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + ) : this(output, type, id, callId, caller, name, namespace, status, mutableMapOf()) + + /** + * Text, image, or file output of the function tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun output(): Output = output.getRequired("output") + + /** + * The type of the function tool call output. Always `function_call_output`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The unique ID of the function tool call output. Populated when this item is returned + * via API. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun id(): Optional = id.getOptional("id") + + /** + * The unique ID of the function tool call generated by the model. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun callId(): Optional = callId.getOptional("call_id") + + /** + * The execution context that produced this tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun caller(): Optional = caller.getOptional("caller") + + /** + * The name of the tool that produced the output. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun name(): Optional = name.getOptional("name") + + /** + * The namespace of the tool that produced the output. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun namespace(): Optional = namespace.getOptional("namespace") + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. Populated + * when items are returned via API. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun status(): Optional = status.getOptional("status") + + /** + * Returns the raw JSON value of [output]. + * + * Unlike [output], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("output") @ExcludeMissing fun _output(): JsonField = output + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + /** + * Returns the raw JSON value of [caller]. + * + * Unlike [caller], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("caller") @ExcludeMissing fun _caller(): JsonField = caller + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + /** + * Returns the raw JSON value of [namespace]. + * + * Unlike [namespace], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("namespace") + @ExcludeMissing + fun _namespace(): JsonField = namespace + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [FunctionCallOutput]. + * + * The following fields are required: + * ```java + * .output() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FunctionCallOutput]. */ + class Builder internal constructor() { + + private var output: JsonField? = null + private var type: JsonValue = JsonValue.from("function_call_output") + private var id: JsonField = JsonMissing.of() + private var callId: JsonField = JsonMissing.of() + private var caller: JsonField = JsonMissing.of() + private var name: JsonField = JsonMissing.of() + private var namespace: JsonField = JsonMissing.of() + private var status: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(functionCallOutput: FunctionCallOutput) = apply { + output = functionCallOutput.output + type = functionCallOutput.type + id = functionCallOutput.id + callId = functionCallOutput.callId + caller = functionCallOutput.caller + name = functionCallOutput.name + namespace = functionCallOutput.namespace + status = functionCallOutput.status + additionalProperties = functionCallOutput.additionalProperties.toMutableMap() + } + + /** Text, image, or file output of the function tool call. */ + fun output(output: Output) = output(JsonField.of(output)) + + /** + * Sets [Builder.output] to an arbitrary JSON value. + * + * You should usually call [Builder.output] with a well-typed [Output] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun output(output: JsonField) = apply { this.output = output } + + /** Alias for calling [output] with `Output.ofString(string)`. */ + fun output(string: String) = output(Output.ofString(string)) + + /** + * Alias for calling [output] with + * `Output.ofResponseFunctionCallOutputItemList(responseFunctionCallOutputItemList)`. + */ + fun outputOfResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList: List + ) = + output( + Output.ofResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList + ) + ) + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The unique ID of the function tool call output. Populated when this item is + * returned via API. + */ + fun id(id: String?) = id(JsonField.ofNullable(id)) + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The unique ID of the function tool call generated by the model. */ + fun callId(callId: String?) = callId(JsonField.ofNullable(callId)) + + /** Alias for calling [Builder.callId] with `callId.orElse(null)`. */ + fun callId(callId: Optional) = callId(callId.getOrNull()) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** The execution context that produced this tool call. */ + fun caller(caller: Caller?) = caller(JsonField.ofNullable(caller)) + + /** Alias for calling [Builder.caller] with `caller.orElse(null)`. */ + fun caller(caller: Optional) = caller(caller.getOrNull()) + + /** + * Sets [Builder.caller] to an arbitrary JSON value. + * + * You should usually call [Builder.caller] with a well-typed [Caller] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun caller(caller: JsonField) = apply { this.caller = caller } + + /** Alias for calling [caller] with `Caller.ofDirect()`. */ + fun callerDirect() = caller(Caller.ofDirect()) + + /** Alias for calling [caller] with `Caller.ofProgram(program)`. */ + fun caller(program: Caller.Program) = caller(Caller.ofProgram(program)) + + /** + * Alias for calling [caller] with the following: + * ```java + * Caller.Program.builder() + * .callerId(callerId) + * .build() + * ``` + */ + fun programCaller(callerId: String) = + caller(Caller.Program.builder().callerId(callerId).build()) + + /** The name of the tool that produced the output. */ + fun name(name: String?) = name(JsonField.ofNullable(name)) + + /** Alias for calling [Builder.name] with `name.orElse(null)`. */ + fun name(name: Optional) = name(name.getOrNull()) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** The namespace of the tool that produced the output. */ + fun namespace(namespace: String?) = namespace(JsonField.ofNullable(namespace)) + + /** Alias for calling [Builder.namespace] with `namespace.orElse(null)`. */ + fun namespace(namespace: Optional) = namespace(namespace.getOrNull()) + + /** + * Sets [Builder.namespace] to an arbitrary JSON value. + * + * You should usually call [Builder.namespace] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun namespace(namespace: JsonField) = apply { this.namespace = namespace } + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. + * Populated when items are returned via API. + */ + fun status(status: Status?) = status(JsonField.ofNullable(status)) + + /** Alias for calling [Builder.status] with `status.orElse(null)`. */ + fun status(status: Optional) = status(status.getOrNull()) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [Status] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun status(status: JsonField) = apply { this.status = status } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [FunctionCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .output() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FunctionCallOutput = + FunctionCallOutput( + checkRequired("output", output), + type, + id, + callId, + caller, + name, + namespace, + status, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): FunctionCallOutput = apply { + if (validated) { + return@apply + } + + output().validate() + _type().let { + if (it != JsonValue.from("function_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + id() + callId() + caller().ifPresent { it.validate() } + name() + namespace() + status().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (output.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("function_call_output")) 1 else 0 } + + (if (id.asKnown().isPresent) 1 else 0) + + (if (callId.asKnown().isPresent) 1 else 0) + + (caller.asKnown().getOrNull()?.validity() ?: 0) + + (if (name.asKnown().isPresent) 1 else 0) + + (if (namespace.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + /** Text, image, or file output of the function tool call. */ + @JsonDeserialize(using = Output.Deserializer::class) + @JsonSerialize(using = Output.Serializer::class) + class Output + private constructor( + private val string: String? = null, + private val responseFunctionCallOutputItemList: + List? = + null, + private val _json: JsonValue? = null, + ) { + + /** A JSON string of the output of the function tool call. */ + fun string(): Optional = Optional.ofNullable(string) + + /** An array of content outputs (text, image, file) for the function tool call. */ + fun responseFunctionCallOutputItemList(): + Optional> = + Optional.ofNullable(responseFunctionCallOutputItemList) + + fun isString(): Boolean = string != null + + fun isResponseFunctionCallOutputItemList(): Boolean = + responseFunctionCallOutputItemList != null + + /** A JSON string of the output of the function tool call. */ + fun asString(): String = string.getOrThrow("string") + + /** An array of content outputs (text, image, file) for the function tool call. */ + fun asResponseFunctionCallOutputItemList(): List = + responseFunctionCallOutputItemList.getOrThrow( + "responseFunctionCallOutputItemList" + ) + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = output.accept(new Output.Visitor>() { + * @Override + * public Optional visitString(String string) { + * return Optional.of(string.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + string != null -> visitor.visitString(string) + responseFunctionCallOutputItemList != null -> + visitor.visitResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList + ) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Output = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitString(string: String) {} + + override fun visitResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList: + List + ) { + responseFunctionCallOutputItemList.forEach { it.validate() } + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitString(string: String) = 1 + + override fun visitResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList: + List + ) = responseFunctionCallOutputItemList.sumOf { it.validity().toInt() } + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Output && + string == other.string && + responseFunctionCallOutputItemList == + other.responseFunctionCallOutputItemList + } + + override fun hashCode(): Int = + Objects.hash(string, responseFunctionCallOutputItemList) + + override fun toString(): String = + when { + string != null -> "Output{string=$string}" + responseFunctionCallOutputItemList != null -> + "Output{responseFunctionCallOutputItemList=$responseFunctionCallOutputItemList}" + _json != null -> "Output{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Output") + } + + companion object { + + /** A JSON string of the output of the function tool call. */ + @JvmStatic fun ofString(string: String) = Output(string = string) + + /** + * An array of content outputs (text, image, file) for the function tool call. + */ + @JvmStatic + fun ofResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList: List + ) = + Output( + responseFunctionCallOutputItemList = + responseFunctionCallOutputItemList.toImmutable() + ) + } + + /** + * An interface that defines how to map each variant of [Output] to a value of type + * [T]. + */ + interface Visitor { + + /** A JSON string of the output of the function tool call. */ + fun visitString(string: String): T + + /** + * An array of content outputs (text, image, file) for the function tool call. + */ + fun visitResponseFunctionCallOutputItemList( + responseFunctionCallOutputItemList: List + ): T + + /** + * Maps an unknown variant of [Output] to a value of type [T]. + * + * An instance of [Output] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Output: $json") + } + } + + internal class Deserializer : BaseDeserializer(Output::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Output { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Output(string = it, _json = json) + }, + tryDeserialize( + node, + jacksonTypeRef>(), + ) + ?.let { + Output( + responseFunctionCallOutputItemList = it, + _json = json, + ) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely + // incompatible with all the possible variants (e.g. deserializing from + // boolean). + 0 -> Output(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use + // the first completely valid match, or simply the first match if none + // are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Output::class) { + + override fun serialize( + value: Output, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.string != null -> generator.writeObject(value.string) + value.responseFunctionCallOutputItemList != null -> + generator.writeObject(value.responseFunctionCallOutputItemList) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Output") + } + } + } + } + + /** The execution context that produced this tool call. */ + @JsonDeserialize(using = Caller.Deserializer::class) + @JsonSerialize(using = Caller.Serializer::class) + class Caller + private constructor( + private val direct: JsonValue? = null, + private val program: Program? = null, + private val _json: JsonValue? = null, + ) { + + fun direct(): Optional = Optional.ofNullable(direct) + + fun program(): Optional = Optional.ofNullable(program) + + fun isDirect(): Boolean = direct != null + + fun isProgram(): Boolean = program != null + + fun asDirect(): JsonValue = direct.getOrThrow("direct") + + fun asProgram(): Program = program.getOrThrow("program") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the + * API, unless [visitor] overrides [Visitor.unknown]. To handle variants not known + * to this version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = caller.accept(new Caller.Visitor>() { + * @Override + * public Optional visitDirect(JsonValue direct) { + * return Optional.of(direct.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + direct != null -> visitor.visitDirect(direct) + program != null -> visitor.visitProgram(program) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Caller = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitDirect(direct: JsonValue) { + direct.let { + if (it != JsonValue.from(mapOf("type" to "direct"))) { + throw OpenAIInvalidDataException( + "'direct' is invalid, received $it" + ) + } + } + } + + override fun visitProgram(program: Program) { + program.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitDirect(direct: JsonValue) = + direct.let { + if (it == JsonValue.from(mapOf("type" to "direct"))) 1 else 0 + } + + override fun visitProgram(program: Program) = program.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Caller && direct == other.direct && program == other.program + } + + override fun hashCode(): Int = Objects.hash(direct, program) + + override fun toString(): String = + when { + direct != null -> "Caller{direct=$direct}" + program != null -> "Caller{program=$program}" + _json != null -> "Caller{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Caller") + } + + companion object { + + @JvmStatic + fun ofDirect() = Caller(direct = JsonValue.from(mapOf("type" to "direct"))) + + @JvmStatic fun ofProgram(program: Program) = Caller(program = program) + } + + /** + * An interface that defines how to map each variant of [Caller] to a value of type + * [T]. + */ + interface Visitor { + + fun visitDirect(direct: JsonValue): T + + fun visitProgram(program: Program): T + + /** + * Maps an unknown variant of [Caller] to a value of type [T]. + * + * An instance of [Caller] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on + * an older version than the API, then the API may respond with new variants + * that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Caller: $json") + } + } + + internal class Deserializer : BaseDeserializer(Caller::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Caller { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "direct" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { Caller(direct = it, _json = json) } + ?.takeIf { it.isValid() } ?: Caller(_json = json) + } + "program" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + Caller(program = it, _json = json) + } ?: Caller(_json = json) + } + } + + return Caller(_json = json) + } + } + + internal class Serializer : BaseSerializer(Caller::class) { + + override fun serialize( + value: Caller, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.direct != null -> generator.writeObject(value.direct) + value.program != null -> generator.writeObject(value.program) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Caller") + } + } + } + + class Program + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callerId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("caller_id") + @ExcludeMissing + callerId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callerId, type, mutableMapOf()) + + /** + * The call ID of the program item that produced this tool call. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun callerId(): String = callerId.getRequired("caller_id") + + /** + * The caller type. Always `program`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("program") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the + * server responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callerId]. + * + * Unlike [callerId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("caller_id") + @ExcludeMissing + fun _callerId(): JsonField = callerId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Program]. + * + * The following fields are required: + * ```java + * .callerId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Program]. */ + class Builder internal constructor() { + + private var callerId: JsonField? = null + private var type: JsonValue = JsonValue.from("program") + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(program: Program) = apply { + callerId = program.callerId + type = program.type + additionalProperties = program.additionalProperties.toMutableMap() + } + + /** The call ID of the program item that produced this tool call. */ + fun callerId(callerId: String) = callerId(JsonField.of(callerId)) + + /** + * Sets [Builder.callerId] to an arbitrary JSON value. + * + * You should usually call [Builder.callerId] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun callerId(callerId: JsonField) = apply { + this.callerId = callerId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults + * to the following: + * ```java + * JsonValue.from("program") + * ``` + * + * This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Program]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callerId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Program = + Program( + checkRequired("callerId", callerId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Program = apply { + if (validated) { + return@apply + } + + callerId() + _type().let { + if (it != JsonValue.from("program")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callerId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("program")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Program && + callerId == other.callerId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(callerId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Program{callerId=$callerId, type=$type, additionalProperties=$additionalProperties}" + } + } + + /** + * The status of the item. One of `in_progress`, `completed`, or `incomplete`. Populated + * when items are returned via API. + */ + class Status @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val IN_PROGRESS = of("in_progress") + + @JvmField val COMPLETED = of("completed") + + @JvmField val INCOMPLETE = of("incomplete") + + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) + } + + /** An enum containing [Status]'s known values. */ + enum class Known { + IN_PROGRESS, + COMPLETED, + INCOMPLETE, + } + + /** + * An enum containing [Status]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Status] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + IN_PROGRESS, + COMPLETED, + INCOMPLETE, + /** + * An enum member indicating that [Status] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + IN_PROGRESS -> Value.IN_PROGRESS + COMPLETED -> Value.COMPLETED + INCOMPLETE -> Value.INCOMPLETE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + IN_PROGRESS -> Known.IN_PROGRESS + COMPLETED -> Known.COMPLETED + INCOMPLETE -> Known.INCOMPLETE + else -> throw OpenAIInvalidDataException("Unknown Status: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Status = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Status && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FunctionCallOutput && + output == other.output && + type == other.type && + id == other.id && + callId == other.callId && + caller == other.caller && + name == other.name && + namespace == other.namespace && + status == other.status && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + output, + type, + id, + callId, + caller, + name, + namespace, + status, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCallOutput{output=$output, type=$type, id=$id, callId=$callId, caller=$caller, name=$name, namespace=$namespace, status=$status, additionalProperties=$additionalProperties}" + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInputContent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInputContent.kt new file mode 100644 index 000000000..d2683ca10 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerInputContent.kt @@ -0,0 +1,286 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.JsonValue +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** A piece of message content, such as text, an image, or a file. */ +@JsonDeserialize(using = ResponseSteerInputContent.Deserializer::class) +@JsonSerialize(using = ResponseSteerInputContent.Serializer::class) +class ResponseSteerInputContent +private constructor( + private val inputText: ResponseInputTextContent? = null, + private val inputImage: ResponseInputImageContent? = null, + private val inputFile: ResponseInputFileContent? = null, + private val _json: JsonValue? = null, +) { + + /** A text input to the model. */ + fun inputText(): Optional = Optional.ofNullable(inputText) + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun inputImage(): Optional = Optional.ofNullable(inputImage) + + /** A file input to the model. */ + fun inputFile(): Optional = Optional.ofNullable(inputFile) + + fun isInputText(): Boolean = inputText != null + + fun isInputImage(): Boolean = inputImage != null + + fun isInputFile(): Boolean = inputFile != null + + /** A text input to the model. */ + fun asInputText(): ResponseInputTextContent = inputText.getOrThrow("inputText") + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun asInputImage(): ResponseInputImageContent = inputImage.getOrThrow("inputImage") + + /** A file input to the model. */ + fun asInputFile(): ResponseInputFileContent = inputFile.getOrThrow("inputFile") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = responseSteerInputContent.accept(new ResponseSteerInputContent.Visitor>() { + * @Override + * public Optional visitInputText(ResponseInputTextContent inputText) { + * return Optional.of(inputText.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + inputText != null -> visitor.visitInputText(inputText) + inputImage != null -> visitor.visitInputImage(inputImage) + inputFile != null -> visitor.visitInputFile(inputFile) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerInputContent = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitInputText(inputText: ResponseInputTextContent) { + inputText.validate() + } + + override fun visitInputImage(inputImage: ResponseInputImageContent) { + inputImage.validate() + } + + override fun visitInputFile(inputFile: ResponseInputFileContent) { + inputFile.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitInputText(inputText: ResponseInputTextContent) = + inputText.validity() + + override fun visitInputImage(inputImage: ResponseInputImageContent) = + inputImage.validity() + + override fun visitInputFile(inputFile: ResponseInputFileContent) = + inputFile.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerInputContent && + inputText == other.inputText && + inputImage == other.inputImage && + inputFile == other.inputFile + } + + override fun hashCode(): Int = Objects.hash(inputText, inputImage, inputFile) + + override fun toString(): String = + when { + inputText != null -> "ResponseSteerInputContent{inputText=$inputText}" + inputImage != null -> "ResponseSteerInputContent{inputImage=$inputImage}" + inputFile != null -> "ResponseSteerInputContent{inputFile=$inputFile}" + _json != null -> "ResponseSteerInputContent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseSteerInputContent") + } + + companion object { + + /** A text input to the model. */ + @JvmStatic + fun ofInputText(inputText: ResponseInputTextContent) = + ResponseSteerInputContent(inputText = inputText) + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + @JvmStatic + fun ofInputImage(inputImage: ResponseInputImageContent) = + ResponseSteerInputContent(inputImage = inputImage) + + /** A file input to the model. */ + @JvmStatic + fun ofInputFile(inputFile: ResponseInputFileContent) = + ResponseSteerInputContent(inputFile = inputFile) + } + + /** + * An interface that defines how to map each variant of [ResponseSteerInputContent] to a value + * of type [T]. + */ + interface Visitor { + + /** A text input to the model. */ + fun visitInputText(inputText: ResponseInputTextContent): T + + /** + * An image input to the model. Learn about + * [image inputs](https://platform.openai.com/docs/guides/vision) + */ + fun visitInputImage(inputImage: ResponseInputImageContent): T + + /** A file input to the model. */ + fun visitInputFile(inputFile: ResponseInputFileContent): T + + /** + * Maps an unknown variant of [ResponseSteerInputContent] to a value of type [T]. + * + * An instance of [ResponseSteerInputContent] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponseSteerInputContent: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ResponseSteerInputContent::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseSteerInputContent { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "input_text" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputContent(inputText = it, _json = json) + } ?: ResponseSteerInputContent(_json = json) + } + "input_image" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputContent(inputImage = it, _json = json) + } ?: ResponseSteerInputContent(_json = json) + } + "input_file" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerInputContent(inputFile = it, _json = json) + } ?: ResponseSteerInputContent(_json = json) + } + } + + return ResponseSteerInputContent(_json = json) + } + } + + internal class Serializer : + BaseSerializer(ResponseSteerInputContent::class) { + + override fun serialize( + value: ResponseSteerInputContent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.inputText != null -> generator.writeObject(value.inputText) + value.inputImage != null -> generator.writeObject(value.inputImage) + value.inputFile != null -> generator.writeObject(value.inputFile) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseSteerInputContent") + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingEvent.kt new file mode 100644 index 000000000..c7a087dd1 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingEvent.kt @@ -0,0 +1,809 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkKnown +import com.openai.core.checkRequired +import com.openai.core.toImmutable +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is the + * commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while the + * response waits for the tool results or approval decisions identified by `required_input`. Copy + * those stubs, fill their result fields using the ordinary `response.create` input schemas, and + * submit one continuation per parent with the same `previous_response_id` and WebSocket lane. Use + * saved results without rerunning tools. The queued steering input is prepended in submission order + * to the continuation's input. That explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for the + * same parent can report the same required inputs; they do not each require a separate + * continuation. + */ +class ResponseSteerPendingEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val reason: JsonField, + private val requiredInput: JsonField>, + private val sequenceNumber: JsonField, + private val steer: JsonField, + private val type: JsonValue, + private val streamId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("reason") + @ExcludeMissing + reason: JsonField = JsonMissing.of(), + @JsonProperty("required_input") + @ExcludeMissing + requiredInput: JsonField> = JsonMissing.of(), + @JsonProperty("sequence_number") + @ExcludeMissing + sequenceNumber: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), + ) : this(reason, requiredInput, sequenceNumber, steer, type, streamId, mutableMapOf()) + + /** + * An extensible enum describing why accepted steering input is still queued. Clients should + * handle unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun reason(): ResponseSteerPendingReason = reason.getRequired("reason") + + /** + * Input stubs identifying outstanding client-owned tool results or approval decisions. Each + * stub contains identifying fields only; the client supplies the result before including it in + * `response.create`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun requiredInput(): List = + requiredInput.getRequired("required_input") + + /** + * The sequence number for this event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun sequenceNumber(): Long = sequenceNumber.getRequired("sequence_number") + + /** + * The steering submission that remains queued. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun steer(): Steer = steer.getRequired("steer") + + /** + * The event discriminator. Always `response.steer.pending`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("response.steer.pending") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * The WebSocket lane that emitted this event. This field is present when the target response's + * `response.create` event supplied a `stream_id`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun streamId(): Optional = streamId.getOptional("stream_id") + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") + @ExcludeMissing + fun _reason(): JsonField = reason + + /** + * Returns the raw JSON value of [requiredInput]. + * + * Unlike [requiredInput], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("required_input") + @ExcludeMissing + fun _requiredInput(): JsonField> = requiredInput + + /** + * Returns the raw JSON value of [sequenceNumber]. + * + * Unlike [sequenceNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("sequence_number") + @ExcludeMissing + fun _sequenceNumber(): JsonField = sequenceNumber + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ResponseSteerPendingEvent]. + * + * The following fields are required: + * ```java + * .reason() + * .requiredInput() + * .sequenceNumber() + * .steer() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ResponseSteerPendingEvent]. */ + class Builder internal constructor() { + + private var reason: JsonField? = null + private var requiredInput: JsonField>? = null + private var sequenceNumber: JsonField? = null + private var steer: JsonField? = null + private var type: JsonValue = JsonValue.from("response.steer.pending") + private var streamId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(responseSteerPendingEvent: ResponseSteerPendingEvent) = apply { + reason = responseSteerPendingEvent.reason + requiredInput = responseSteerPendingEvent.requiredInput.map { it.toMutableList() } + sequenceNumber = responseSteerPendingEvent.sequenceNumber + steer = responseSteerPendingEvent.steer + type = responseSteerPendingEvent.type + streamId = responseSteerPendingEvent.streamId + additionalProperties = responseSteerPendingEvent.additionalProperties.toMutableMap() + } + + /** + * An extensible enum describing why accepted steering input is still queued. Clients should + * handle unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + */ + fun reason(reason: ResponseSteerPendingReason) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [ResponseSteerPendingReason] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + /** + * Sets [reason] to an arbitrary [String]. + * + * You should usually call [reason] with a well-typed [ResponseSteerPendingReason] constant + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun reason(value: String) = reason(ResponseSteerPendingReason.of(value)) + + /** + * Input stubs identifying outstanding client-owned tool results or approval decisions. Each + * stub contains identifying fields only; the client supplies the result before including it + * in `response.create`. + */ + fun requiredInput(requiredInput: List) = + requiredInput(JsonField.of(requiredInput)) + + /** + * Sets [Builder.requiredInput] to an arbitrary JSON value. + * + * You should usually call [Builder.requiredInput] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun requiredInput(requiredInput: JsonField>) = apply { + this.requiredInput = requiredInput.map { it.toMutableList() } + } + + /** + * Adds a single [ResponseSteerRequiredInput] to [Builder.requiredInput]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRequiredInput(requiredInput: ResponseSteerRequiredInput) = apply { + this.requiredInput = + (this.requiredInput ?: JsonField.of(mutableListOf())).also { + checkKnown("requiredInput", it).add(requiredInput) + } + } + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput)`. + */ + fun addRequiredInput(functionCallOutput: ResponseSteerRequiredInput.FunctionCallOutput) = + addRequiredInput(ResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput)) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput)`. + */ + fun addRequiredInput( + customToolCallOutput: ResponseSteerRequiredInput.CustomToolCallOutput + ) = + addRequiredInput( + ResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.CustomToolCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addCustomToolCallOutputRequiredInput(callId: String) = + addRequiredInput( + ResponseSteerRequiredInput.CustomToolCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput)`. + */ + fun addRequiredInput(computerCallOutput: ResponseSteerRequiredInput.ComputerCallOutput) = + addRequiredInput(ResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.ComputerCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addComputerCallOutputRequiredInput(callId: String) = + addRequiredInput( + ResponseSteerRequiredInput.ComputerCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput)`. + */ + fun addRequiredInput(shellCallOutput: ResponseSteerRequiredInput.ShellCallOutput) = + addRequiredInput(ResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.ShellCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addShellCallOutputRequiredInput(callId: String) = + addRequiredInput( + ResponseSteerRequiredInput.ShellCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput)`. + */ + fun addRequiredInput( + applyPatchCallOutput: ResponseSteerRequiredInput.ApplyPatchCallOutput + ) = + addRequiredInput( + ResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput) + ) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.ApplyPatchCallOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addApplyPatchCallOutputRequiredInput(callId: String) = + addRequiredInput( + ResponseSteerRequiredInput.ApplyPatchCallOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput)`. + */ + fun addRequiredInput(toolSearchOutput: ResponseSteerRequiredInput.ToolSearchOutput) = + addRequiredInput(ResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.ToolSearchOutput.builder() + * .callId(callId) + * .build() + * ``` + */ + fun addToolSearchOutputRequiredInput(callId: String) = + addRequiredInput( + ResponseSteerRequiredInput.ToolSearchOutput.builder().callId(callId).build() + ) + + /** + * Alias for calling [addRequiredInput] with + * `ResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse)`. + */ + fun addRequiredInput(mcpApprovalResponse: ResponseSteerRequiredInput.McpApprovalResponse) = + addRequiredInput(ResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse)) + + /** + * Alias for calling [addRequiredInput] with the following: + * ```java + * ResponseSteerRequiredInput.McpApprovalResponse.builder() + * .approvalRequestId(approvalRequestId) + * .build() + * ``` + */ + fun addMcpApprovalResponseRequiredInput(approvalRequestId: String) = + addRequiredInput( + ResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId(approvalRequestId) + .build() + ) + + /** The sequence number for this event. */ + fun sequenceNumber(sequenceNumber: Long) = sequenceNumber(JsonField.of(sequenceNumber)) + + /** + * Sets [Builder.sequenceNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.sequenceNumber] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun sequenceNumber(sequenceNumber: JsonField) = apply { + this.sequenceNumber = sequenceNumber + } + + /** The steering submission that remains queued. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.steer.pending") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + /** + * The WebSocket lane that emitted this event. This field is present when the target + * response's `response.create` event supplied a `stream_id`. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ResponseSteerPendingEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .reason() + * .requiredInput() + * .sequenceNumber() + * .steer() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ResponseSteerPendingEvent = + ResponseSteerPendingEvent( + checkRequired("reason", reason), + checkRequired("requiredInput", requiredInput).map { it.toImmutable() }, + checkRequired("sequenceNumber", sequenceNumber), + checkRequired("steer", steer), + type, + streamId, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerPendingEvent = apply { + if (validated) { + return@apply + } + + reason() + requiredInput().forEach { it.validate() } + sequenceNumber() + steer().validate() + _type().let { + if (it != JsonValue.from("response.steer.pending")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + streamId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (reason.asKnown().isPresent) 1 else 0) + + (requiredInput.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (sequenceNumber.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + type.let { if (it == JsonValue.from("response.steer.pending")) 1 else 0 } + + (if (streamId.asKnown().isPresent) 1 else 0) + + /** The steering submission that remains queued. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val previousResponseId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + ) : this(id, previousResponseId, mutableMapOf()) + + /** + * The ID assigned to the steering submission. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The ID of the response being steered. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun previousResponseId(): String = previousResponseId.getRequired("previous_response_id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var previousResponseId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + id = steer.id + previousResponseId = steer.previousResponseId + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The ID assigned to the steering submission. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The ID of the response being steered. */ + fun previousResponseId(previousResponseId: String) = + previousResponseId(JsonField.of(previousResponseId)) + + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .previousResponseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("id", id), + checkRequired("previousResponseId", previousResponseId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + id() + previousResponseId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + id == other.id && + previousResponseId == other.previousResponseId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, previousResponseId, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{id=$id, previousResponseId=$previousResponseId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerPendingEvent && + reason == other.reason && + requiredInput == other.requiredInput && + sequenceNumber == other.sequenceNumber && + steer == other.steer && + type == other.type && + streamId == other.streamId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + reason, + requiredInput, + sequenceNumber, + steer, + type, + streamId, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ResponseSteerPendingEvent{reason=$reason, requiredInput=$requiredInput, sequenceNumber=$sequenceNumber, steer=$steer, type=$type, streamId=$streamId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingReason.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingReason.kt new file mode 100644 index 000000000..06c03d894 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerPendingReason.kt @@ -0,0 +1,145 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonCreator +import com.openai.core.Enum +import com.openai.core.JsonField +import com.openai.errors.OpenAIInvalidDataException + +/** + * An extensible enum describing why accepted steering input is still queued. Clients should handle + * unknown values because additional reasons may be introduced. Known values include: + * - `waiting_for_required_input`: The response is waiting for the tool results or approval + * decisions identified by `required_input`. + */ +class ResponseSteerPendingReason +@JsonCreator +private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't match + * any known member, and you want to know that value. For example, if the SDK is on an older + * version than the API, then the API may respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val WAITING_FOR_REQUIRED_INPUT = of("waiting_for_required_input") + + @JvmStatic fun of(value: String) = ResponseSteerPendingReason(JsonField.of(value)) + } + + /** An enum containing [ResponseSteerPendingReason]'s known values. */ + enum class Known { + WAITING_FOR_REQUIRED_INPUT + } + + /** + * An enum containing [ResponseSteerPendingReason]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [ResponseSteerPendingReason] can contain an unknown value in a couple of + * cases: + * - It was deserialized from data that doesn't match any known member. For example, if the SDK + * is on an older version than the API, then the API may respond with new members that the SDK + * is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + WAITING_FOR_REQUIRED_INPUT, + /** + * An enum member indicating that [ResponseSteerPendingReason] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] if + * the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want to + * throw for the unknown case. + */ + fun value(): Value = + when (this) { + WAITING_FOR_REQUIRED_INPUT -> Value.WAITING_FOR_REQUIRED_INPUT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't want + * to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known member. + */ + fun known(): Known = + when (this) { + WAITING_FOR_REQUIRED_INPUT -> Known.WAITING_FOR_REQUIRED_INPUT + else -> throw OpenAIInvalidDataException("Unknown ResponseSteerPendingReason: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging and + * generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the expected + * primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerPendingReason = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerPendingReason && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerRequiredInput.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerRequiredInput.kt new file mode 100644 index 000000000..6dbc2d16c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseSteerRequiredInput.kt @@ -0,0 +1,2054 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.BaseDeserializer +import com.openai.core.BaseSerializer +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.core.getOrThrow +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * An input stub identifying an outstanding client-owned tool result or approval decision. Copy the + * stub and fill the result fields using the corresponding `response.create` input schema. Use saved + * results without rerunning the tool. The server does not supply results, approval decisions, or + * safety acknowledgements in these stubs. + */ +@JsonDeserialize(using = ResponseSteerRequiredInput.Deserializer::class) +@JsonSerialize(using = ResponseSteerRequiredInput.Serializer::class) +class ResponseSteerRequiredInput +private constructor( + private val functionCallOutput: FunctionCallOutput? = null, + private val customToolCallOutput: CustomToolCallOutput? = null, + private val computerCallOutput: ComputerCallOutput? = null, + private val shellCallOutput: ShellCallOutput? = null, + private val applyPatchCallOutput: ApplyPatchCallOutput? = null, + private val toolSearchOutput: ToolSearchOutput? = null, + private val mcpApprovalResponse: McpApprovalResponse? = null, + private val _json: JsonValue? = null, +) { + + /** Supply `output` using the function tool call output input schema. */ + fun functionCallOutput(): Optional = Optional.ofNullable(functionCallOutput) + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + fun customToolCallOutput(): Optional = + Optional.ofNullable(customToolCallOutput) + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun computerCallOutput(): Optional = Optional.ofNullable(computerCallOutput) + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun shellCallOutput(): Optional = Optional.ofNullable(shellCallOutput) + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + fun applyPatchCallOutput(): Optional = + Optional.ofNullable(applyPatchCallOutput) + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + fun toolSearchOutput(): Optional = Optional.ofNullable(toolSearchOutput) + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + fun mcpApprovalResponse(): Optional = + Optional.ofNullable(mcpApprovalResponse) + + fun isFunctionCallOutput(): Boolean = functionCallOutput != null + + fun isCustomToolCallOutput(): Boolean = customToolCallOutput != null + + fun isComputerCallOutput(): Boolean = computerCallOutput != null + + fun isShellCallOutput(): Boolean = shellCallOutput != null + + fun isApplyPatchCallOutput(): Boolean = applyPatchCallOutput != null + + fun isToolSearchOutput(): Boolean = toolSearchOutput != null + + fun isMcpApprovalResponse(): Boolean = mcpApprovalResponse != null + + /** Supply `output` using the function tool call output input schema. */ + fun asFunctionCallOutput(): FunctionCallOutput = + functionCallOutput.getOrThrow("functionCallOutput") + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + fun asCustomToolCallOutput(): CustomToolCallOutput = + customToolCallOutput.getOrThrow("customToolCallOutput") + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun asComputerCallOutput(): ComputerCallOutput = + computerCallOutput.getOrThrow("computerCallOutput") + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun asShellCallOutput(): ShellCallOutput = shellCallOutput.getOrThrow("shellCallOutput") + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + fun asApplyPatchCallOutput(): ApplyPatchCallOutput = + applyPatchCallOutput.getOrThrow("applyPatchCallOutput") + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + fun asToolSearchOutput(): ToolSearchOutput = toolSearchOutput.getOrThrow("toolSearchOutput") + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + fun asMcpApprovalResponse(): McpApprovalResponse = + mcpApprovalResponse.getOrThrow("mcpApprovalResponse") + + fun _json(): Optional = Optional.ofNullable(_json) + + /** + * Maps this instance's current variant to a value of type [T] using the given [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = responseSteerRequiredInput.accept(new ResponseSteerRequiredInput.Visitor>() { + * @Override + * public Optional visitFunctionCallOutput(FunctionCallOutput functionCallOutput) { + * return Optional.of(functionCallOutput.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + functionCallOutput != null -> visitor.visitFunctionCallOutput(functionCallOutput) + customToolCallOutput != null -> visitor.visitCustomToolCallOutput(customToolCallOutput) + computerCallOutput != null -> visitor.visitComputerCallOutput(computerCallOutput) + shellCallOutput != null -> visitor.visitShellCallOutput(shellCallOutput) + applyPatchCallOutput != null -> visitor.visitApplyPatchCallOutput(applyPatchCallOutput) + toolSearchOutput != null -> visitor.visitToolSearchOutput(toolSearchOutput) + mcpApprovalResponse != null -> visitor.visitMcpApprovalResponse(mcpApprovalResponse) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ResponseSteerRequiredInput = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) { + functionCallOutput.validate() + } + + override fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) { + customToolCallOutput.validate() + } + + override fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput) { + computerCallOutput.validate() + } + + override fun visitShellCallOutput(shellCallOutput: ShellCallOutput) { + shellCallOutput.validate() + } + + override fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) { + applyPatchCallOutput.validate() + } + + override fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput) { + toolSearchOutput.validate() + } + + override fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) { + mcpApprovalResponse.validate() + } + } + ) + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + functionCallOutput.validity() + + override fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) = + customToolCallOutput.validity() + + override fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput) = + computerCallOutput.validity() + + override fun visitShellCallOutput(shellCallOutput: ShellCallOutput) = + shellCallOutput.validity() + + override fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) = + applyPatchCallOutput.validity() + + override fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput) = + toolSearchOutput.validity() + + override fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) = + mcpApprovalResponse.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ResponseSteerRequiredInput && + functionCallOutput == other.functionCallOutput && + customToolCallOutput == other.customToolCallOutput && + computerCallOutput == other.computerCallOutput && + shellCallOutput == other.shellCallOutput && + applyPatchCallOutput == other.applyPatchCallOutput && + toolSearchOutput == other.toolSearchOutput && + mcpApprovalResponse == other.mcpApprovalResponse + } + + override fun hashCode(): Int = + Objects.hash( + functionCallOutput, + customToolCallOutput, + computerCallOutput, + shellCallOutput, + applyPatchCallOutput, + toolSearchOutput, + mcpApprovalResponse, + ) + + override fun toString(): String = + when { + functionCallOutput != null -> + "ResponseSteerRequiredInput{functionCallOutput=$functionCallOutput}" + customToolCallOutput != null -> + "ResponseSteerRequiredInput{customToolCallOutput=$customToolCallOutput}" + computerCallOutput != null -> + "ResponseSteerRequiredInput{computerCallOutput=$computerCallOutput}" + shellCallOutput != null -> + "ResponseSteerRequiredInput{shellCallOutput=$shellCallOutput}" + applyPatchCallOutput != null -> + "ResponseSteerRequiredInput{applyPatchCallOutput=$applyPatchCallOutput}" + toolSearchOutput != null -> + "ResponseSteerRequiredInput{toolSearchOutput=$toolSearchOutput}" + mcpApprovalResponse != null -> + "ResponseSteerRequiredInput{mcpApprovalResponse=$mcpApprovalResponse}" + _json != null -> "ResponseSteerRequiredInput{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponseSteerRequiredInput") + } + + companion object { + + /** Supply `output` using the function tool call output input schema. */ + @JvmStatic + fun ofFunctionCallOutput(functionCallOutput: FunctionCallOutput) = + ResponseSteerRequiredInput(functionCallOutput = functionCallOutput) + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool + * call supplies the tool's name. + */ + @JvmStatic + fun ofCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput) = + ResponseSteerRequiredInput(customToolCallOutput = customToolCallOutput) + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + @JvmStatic + fun ofComputerCallOutput(computerCallOutput: ComputerCallOutput) = + ResponseSteerRequiredInput(computerCallOutput = computerCallOutput) + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + @JvmStatic + fun ofShellCallOutput(shellCallOutput: ShellCallOutput) = + ResponseSteerRequiredInput(shellCallOutput = shellCallOutput) + + /** + * Supply `status` and optional `output` using the apply patch tool call output input + * schema. + */ + @JvmStatic + fun ofApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput) = + ResponseSteerRequiredInput(applyPatchCallOutput = applyPatchCallOutput) + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: + * "client"`. + */ + @JvmStatic + fun ofToolSearchOutput(toolSearchOutput: ToolSearchOutput) = + ResponseSteerRequiredInput(toolSearchOutput = toolSearchOutput) + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can + * be supplied when denying the request. The original approval request identifies the tool + * and server. + */ + @JvmStatic + fun ofMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse) = + ResponseSteerRequiredInput(mcpApprovalResponse = mcpApprovalResponse) + } + + /** + * An interface that defines how to map each variant of [ResponseSteerRequiredInput] to a value + * of type [T]. + */ + interface Visitor { + + /** Supply `output` using the function tool call output input schema. */ + fun visitFunctionCallOutput(functionCallOutput: FunctionCallOutput): T + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool + * call supplies the tool's name. + */ + fun visitCustomToolCallOutput(customToolCallOutput: CustomToolCallOutput): T + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + fun visitComputerCallOutput(computerCallOutput: ComputerCallOutput): T + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + fun visitShellCallOutput(shellCallOutput: ShellCallOutput): T + + /** + * Supply `status` and optional `output` using the apply patch tool call output input + * schema. + */ + fun visitApplyPatchCallOutput(applyPatchCallOutput: ApplyPatchCallOutput): T + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: + * "client"`. + */ + fun visitToolSearchOutput(toolSearchOutput: ToolSearchOutput): T + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can + * be supplied when denying the request. The original approval request identifies the tool + * and server. + */ + fun visitMcpApprovalResponse(mcpApprovalResponse: McpApprovalResponse): T + + /** + * Maps an unknown variant of [ResponseSteerRequiredInput] to a value of type [T]. + * + * An instance of [ResponseSteerRequiredInput] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponseSteerRequiredInput: $json") + } + } + + internal class Deserializer : + BaseDeserializer(ResponseSteerRequiredInput::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ResponseSteerRequiredInput { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() + + when (type) { + "function_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(functionCallOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "custom_tool_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(customToolCallOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "computer_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(computerCallOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "shell_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(shellCallOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "apply_patch_call_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(applyPatchCallOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "tool_search_output" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(toolSearchOutput = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + "mcp_approval_response" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponseSteerRequiredInput(mcpApprovalResponse = it, _json = json) + } ?: ResponseSteerRequiredInput(_json = json) + } + } + + return ResponseSteerRequiredInput(_json = json) + } + } + + internal class Serializer : + BaseSerializer(ResponseSteerRequiredInput::class) { + + override fun serialize( + value: ResponseSteerRequiredInput, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.functionCallOutput != null -> generator.writeObject(value.functionCallOutput) + value.customToolCallOutput != null -> + generator.writeObject(value.customToolCallOutput) + value.computerCallOutput != null -> generator.writeObject(value.computerCallOutput) + value.shellCallOutput != null -> generator.writeObject(value.shellCallOutput) + value.applyPatchCallOutput != null -> + generator.writeObject(value.applyPatchCallOutput) + value.toolSearchOutput != null -> generator.writeObject(value.toolSearchOutput) + value.mcpApprovalResponse != null -> + generator.writeObject(value.mcpApprovalResponse) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponseSteerRequiredInput") + } + } + } + + /** Supply `output` using the function tool call output input schema. */ + class FunctionCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val name: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, name, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun name(): String = name.getRequired("name") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + /** + * Returns the raw JSON value of [name]. + * + * Unlike [name], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [FunctionCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * .name() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FunctionCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var name: JsonField? = null + private var type: JsonValue = JsonValue.from("function_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(functionCallOutput: FunctionCallOutput) = apply { + callId = functionCallOutput.callId + name = functionCallOutput.name + type = functionCallOutput.type + additionalProperties = functionCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + fun name(name: String) = name(JsonField.of(name)) + + /** + * Sets [Builder.name] to an arbitrary JSON value. + * + * You should usually call [Builder.name] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun name(name: JsonField) = apply { this.name = name } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("function_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [FunctionCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * .name() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FunctionCallOutput = + FunctionCallOutput( + checkRequired("callId", callId), + checkRequired("name", name), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): FunctionCallOutput = apply { + if (validated) { + return@apply + } + + callId() + name() + _type().let { + if (it != JsonValue.from("function_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + (if (name.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("function_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FunctionCallOutput && + callId == other.callId && + name == other.name && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, name, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FunctionCallOutput{callId=$callId, name=$name, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the custom tool call output input schema. The original custom tool call + * supplies the tool's name. + */ + class CustomToolCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("custom_tool_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [CustomToolCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CustomToolCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("custom_tool_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(customToolCallOutput: CustomToolCallOutput) = apply { + callId = customToolCallOutput.callId + type = customToolCallOutput.type + additionalProperties = customToolCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("custom_tool_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [CustomToolCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CustomToolCallOutput = + CustomToolCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): CustomToolCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("custom_tool_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("custom_tool_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CustomToolCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CustomToolCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the computer tool call output input schema, including any required + * `acknowledged_safety_checks`. + */ + class ComputerCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("computer_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ComputerCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ComputerCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("computer_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(computerCallOutput: ComputerCallOutput) = apply { + callId = computerCallOutput.callId + type = computerCallOutput.type + additionalProperties = computerCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("computer_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ComputerCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ComputerCallOutput = + ComputerCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ComputerCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("computer_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("computer_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ComputerCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ComputerCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `output` using the shell tool call output input schema. Each output entry includes + * `stdout`, `stderr`, and `outcome`. + */ + class ShellCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("shell_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ShellCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ShellCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("shell_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(shellCallOutput: ShellCallOutput) = apply { + callId = shellCallOutput.callId + type = shellCallOutput.type + additionalProperties = shellCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("shell_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ShellCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ShellCallOutput = + ShellCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ShellCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("shell_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("shell_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ShellCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ShellCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `status` and optional `output` using the apply patch tool call output input schema. + */ + class ApplyPatchCallOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("apply_patch_call_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ApplyPatchCallOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ApplyPatchCallOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var type: JsonValue = JsonValue.from("apply_patch_call_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(applyPatchCallOutput: ApplyPatchCallOutput) = apply { + callId = applyPatchCallOutput.callId + type = applyPatchCallOutput.type + additionalProperties = applyPatchCallOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("apply_patch_call_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ApplyPatchCallOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ApplyPatchCallOutput = + ApplyPatchCallOutput( + checkRequired("callId", callId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ApplyPatchCallOutput = apply { + if (validated) { + return@apply + } + + callId() + _type().let { + if (it != JsonValue.from("apply_patch_call_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("apply_patch_call_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ApplyPatchCallOutput && + callId == other.callId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(callId, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ApplyPatchCallOutput{callId=$callId, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `tools` using the tool search output input schema, retaining `execution: "client"`. + */ + class ToolSearchOutput + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val callId: JsonField, + private val execution: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("call_id") @ExcludeMissing callId: JsonField = JsonMissing.of(), + @JsonProperty("execution") @ExcludeMissing execution: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(callId, execution, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun callId(): String = callId.getRequired("call_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("client") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("execution") @ExcludeMissing fun _execution(): JsonValue = execution + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("tool_search_output") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [callId]. + * + * Unlike [callId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("call_id") @ExcludeMissing fun _callId(): JsonField = callId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [ToolSearchOutput]. + * + * The following fields are required: + * ```java + * .callId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ToolSearchOutput]. */ + class Builder internal constructor() { + + private var callId: JsonField? = null + private var execution: JsonValue = JsonValue.from("client") + private var type: JsonValue = JsonValue.from("tool_search_output") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(toolSearchOutput: ToolSearchOutput) = apply { + callId = toolSearchOutput.callId + execution = toolSearchOutput.execution + type = toolSearchOutput.type + additionalProperties = toolSearchOutput.additionalProperties.toMutableMap() + } + + fun callId(callId: String) = callId(JsonField.of(callId)) + + /** + * Sets [Builder.callId] to an arbitrary JSON value. + * + * You should usually call [Builder.callId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun callId(callId: JsonField) = apply { this.callId = callId } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("client") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun execution(execution: JsonValue) = apply { this.execution = execution } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("tool_search_output") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [ToolSearchOutput]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .callId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ToolSearchOutput = + ToolSearchOutput( + checkRequired("callId", callId), + execution, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ToolSearchOutput = apply { + if (validated) { + return@apply + } + + callId() + _execution().let { + if (it != JsonValue.from("client")) { + throw OpenAIInvalidDataException("'execution' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("tool_search_output")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (callId.asKnown().isPresent) 1 else 0) + + execution.let { if (it == JsonValue.from("client")) 1 else 0 } + + type.let { if (it == JsonValue.from("tool_search_output")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ToolSearchOutput && + callId == other.callId && + execution == other.execution && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(callId, execution, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ToolSearchOutput{callId=$callId, execution=$execution, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Supply `approve` using the MCP approval response input schema. An optional `reason` can be + * supplied when denying the request. The original approval request identifies the tool and + * server. + */ + class McpApprovalResponse + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val approvalRequestId: JsonField, + private val type: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("approval_request_id") + @ExcludeMissing + approvalRequestId: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(approvalRequestId, type, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun approvalRequestId(): String = approvalRequestId.getRequired("approval_request_id") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("mcp_approval_response") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [approvalRequestId]. + * + * Unlike [approvalRequestId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("approval_request_id") + @ExcludeMissing + fun _approvalRequestId(): JsonField = approvalRequestId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [McpApprovalResponse]. + * + * The following fields are required: + * ```java + * .approvalRequestId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [McpApprovalResponse]. */ + class Builder internal constructor() { + + private var approvalRequestId: JsonField? = null + private var type: JsonValue = JsonValue.from("mcp_approval_response") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(mcpApprovalResponse: McpApprovalResponse) = apply { + approvalRequestId = mcpApprovalResponse.approvalRequestId + type = mcpApprovalResponse.type + additionalProperties = mcpApprovalResponse.additionalProperties.toMutableMap() + } + + fun approvalRequestId(approvalRequestId: String) = + approvalRequestId(JsonField.of(approvalRequestId)) + + /** + * Sets [Builder.approvalRequestId] to an arbitrary JSON value. + * + * You should usually call [Builder.approvalRequestId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun approvalRequestId(approvalRequestId: JsonField) = apply { + this.approvalRequestId = approvalRequestId + } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("mcp_approval_response") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [McpApprovalResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .approvalRequestId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): McpApprovalResponse = + McpApprovalResponse( + checkRequired("approvalRequestId", approvalRequestId), + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): McpApprovalResponse = apply { + if (validated) { + return@apply + } + + approvalRequestId() + _type().let { + if (it != JsonValue.from("mcp_approval_response")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (approvalRequestId.asKnown().isPresent) 1 else 0) + + type.let { if (it == JsonValue.from("mcp_approval_response")) 1 else 0 } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is McpApprovalResponse && + approvalRequestId == other.approvalRequestId && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(approvalRequestId, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "McpApprovalResponse{approvalRequestId=$approvalRequestId, type=$type, additionalProperties=$additionalProperties}" + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseStreamEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseStreamEvent.kt index 26d046522..a628e006b 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseStreamEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponseStreamEvent.kt @@ -182,7 +182,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun failed(): Optional = Optional.ofNullable(failed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun incomplete(): Optional = Optional.ofNullable(incomplete) /** Emitted when a new output item is added. */ @@ -521,7 +527,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun asFailed(): ResponseFailedEvent = failed.getOrThrow("failed") - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun asIncomplete(): ResponseIncompleteEvent = incomplete.getOrThrow("incomplete") /** Emitted when a new output item is added. */ @@ -1707,7 +1719,13 @@ private constructor( /** An event that is emitted when a response fails. */ @JvmStatic fun ofFailed(failed: ResponseFailedEvent) = ResponseStreamEvent(failed = failed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ @JvmStatic fun ofIncomplete(incomplete: ResponseIncompleteEvent) = ResponseStreamEvent(incomplete = incomplete) @@ -1994,7 +2012,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun visitFailed(failed: ResponseFailedEvent): T - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ fun visitIncomplete(incomplete: ResponseIncompleteEvent): T /** Emitted when a new output item is added. */ diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesClientEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesClientEvent.kt index f0156d879..603c1e05a 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesClientEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesClientEvent.kt @@ -34,1035 +34,579 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull +/** Client events accepted by the Responses WebSocket server. */ +@JsonDeserialize(using = ResponsesClientEvent.Deserializer::class) +@JsonSerialize(using = ResponsesClientEvent.Serializer::class) class ResponsesClientEvent -@JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val type: JsonValue, - private val background: JsonField, - private val contextManagement: JsonField>, - private val conversation: JsonField, - private val include: JsonField>, - private val input: JsonField, - private val instructions: JsonField, - private val maxOutputTokens: JsonField, - private val maxToolCalls: JsonField, - private val metadata: JsonField, - private val model: JsonField, - private val moderation: JsonField, - private val parallelToolCalls: JsonField, - private val previousResponseId: JsonField, - private val prompt: JsonField, - private val promptCacheKey: JsonField, - private val promptCacheOptions: JsonField, - private val promptCacheRetention: JsonField, - private val reasoning: JsonField, - private val safetyIdentifier: JsonField, - private val serviceTier: JsonField, - private val store: JsonField, - private val stream: JsonField, - private val streamId: JsonField, - private val streamOptions: JsonField, - private val temperature: JsonField, - private val text: JsonField, - private val toolChoice: JsonField, - private val tools: JsonField>, - private val topLogprobs: JsonField, - private val topP: JsonField, - private val truncation: JsonField, - private val user: JsonField, - private val additionalProperties: MutableMap, + private val responseCreate: ResponseCreate? = null, + private val responseSteer: ResponseSteerEvent? = null, + private val _json: JsonValue? = null, ) { - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), - @JsonProperty("background") - @ExcludeMissing - background: JsonField = JsonMissing.of(), - @JsonProperty("context_management") - @ExcludeMissing - contextManagement: JsonField> = JsonMissing.of(), - @JsonProperty("conversation") - @ExcludeMissing - conversation: JsonField = JsonMissing.of(), - @JsonProperty("include") - @ExcludeMissing - include: JsonField> = JsonMissing.of(), - @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), - @JsonProperty("instructions") - @ExcludeMissing - instructions: JsonField = JsonMissing.of(), - @JsonProperty("max_output_tokens") - @ExcludeMissing - maxOutputTokens: JsonField = JsonMissing.of(), - @JsonProperty("max_tool_calls") - @ExcludeMissing - maxToolCalls: JsonField = JsonMissing.of(), - @JsonProperty("metadata") @ExcludeMissing metadata: JsonField = JsonMissing.of(), - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("moderation") - @ExcludeMissing - moderation: JsonField = JsonMissing.of(), - @JsonProperty("parallel_tool_calls") - @ExcludeMissing - parallelToolCalls: JsonField = JsonMissing.of(), - @JsonProperty("previous_response_id") - @ExcludeMissing - previousResponseId: JsonField = JsonMissing.of(), - @JsonProperty("prompt") - @ExcludeMissing - prompt: JsonField = JsonMissing.of(), - @JsonProperty("prompt_cache_key") - @ExcludeMissing - promptCacheKey: JsonField = JsonMissing.of(), - @JsonProperty("prompt_cache_options") - @ExcludeMissing - promptCacheOptions: JsonField = JsonMissing.of(), - @JsonProperty("prompt_cache_retention") - @ExcludeMissing - promptCacheRetention: JsonField = JsonMissing.of(), - @JsonProperty("reasoning") - @ExcludeMissing - reasoning: JsonField = JsonMissing.of(), - @JsonProperty("safety_identifier") - @ExcludeMissing - safetyIdentifier: JsonField = JsonMissing.of(), - @JsonProperty("service_tier") - @ExcludeMissing - serviceTier: JsonField = JsonMissing.of(), - @JsonProperty("store") @ExcludeMissing store: JsonField = JsonMissing.of(), - @JsonProperty("stream") @ExcludeMissing stream: JsonField = JsonMissing.of(), - @JsonProperty("stream_id") @ExcludeMissing streamId: JsonField = JsonMissing.of(), - @JsonProperty("stream_options") - @ExcludeMissing - streamOptions: JsonField = JsonMissing.of(), - @JsonProperty("temperature") - @ExcludeMissing - temperature: JsonField = JsonMissing.of(), - @JsonProperty("text") - @ExcludeMissing - text: JsonField = JsonMissing.of(), - @JsonProperty("tool_choice") - @ExcludeMissing - toolChoice: JsonField = JsonMissing.of(), - @JsonProperty("tools") @ExcludeMissing tools: JsonField> = JsonMissing.of(), - @JsonProperty("top_logprobs") - @ExcludeMissing - topLogprobs: JsonField = JsonMissing.of(), - @JsonProperty("top_p") @ExcludeMissing topP: JsonField = JsonMissing.of(), - @JsonProperty("truncation") - @ExcludeMissing - truncation: JsonField = JsonMissing.of(), - @JsonProperty("user") @ExcludeMissing user: JsonField = JsonMissing.of(), - ) : this( - type, - background, - contextManagement, - conversation, - include, - input, - instructions, - maxOutputTokens, - maxToolCalls, - metadata, - model, - moderation, - parallelToolCalls, - previousResponseId, - prompt, - promptCacheKey, - promptCacheOptions, - promptCacheRetention, - reasoning, - safetyIdentifier, - serviceTier, - store, - stream, - streamId, - streamOptions, - temperature, - text, - toolChoice, - tools, - topLogprobs, - topP, - truncation, - user, - mutableMapOf(), - ) - - /** - * The type of the client event. Always `response.create`. - * - * Expected to always return the following: - * ```java - * JsonValue.from("response.create") - * ``` - * - * However, this method can be useful for debugging and logging (e.g. if the server responded - * with an unexpected value). - */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type - - /** - * Whether to run the model response in the background. - * [Learn more](https://platform.openai.com/docs/guides/background). - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun background(): Optional = background.getOptional("background") - - /** - * Context management configuration for this request. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun contextManagement(): Optional> = - contextManagement.getOptional("context_management") - - /** - * The conversation that this response belongs to. Items from this conversation are prepended to - * `input_items` for this response request. Input items and output items from this response are - * automatically added to this conversation after this response completes. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun conversation(): Optional = conversation.getOptional("conversation") - - /** - * Specify additional output data to include in the model response. Currently supported values - * are: - * - `web_search_call.action.sources`: Include the sources of the web search tool call. - * - `code_interpreter_call.outputs`: Includes the outputs of python code execution in code - * interpreter tool call items. - * - `computer_call_output.output.image_url`: Include image urls from the computer call output. - * - `file_search_call.results`: Include the search results of the file search tool call. - * - `message.input_image.image_url`: Include image urls from the input message. - * - `message.output_text.logprobs`: Include logprobs with assistant messages. - * - `reasoning.encrypted_content`: Includes an encrypted version of reasoning tokens in - * reasoning item outputs. This enables reasoning items to be used in multi-turn conversations - * when using the Responses API statelessly (like when the `store` parameter is set to - * `false`, or when an organization is enrolled in the zero data retention program). - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun include(): Optional> = include.getOptional("include") - /** - * Text, image, or file inputs to the model, used to generate a response. - * - * Learn more: - * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) - * - [Image inputs](https://platform.openai.com/docs/guides/images) - * - [File inputs](https://platform.openai.com/docs/guides/pdf-files) - * - [Conversation state](https://platform.openai.com/docs/guides/conversation-state) - * - [Function calling](https://platform.openai.com/docs/guides/function-calling) + * Client event for creating a response over a persistent WebSocket connection. This payload + * uses the same top-level fields as `POST /v1/responses`, plus WebSocket-only envelope + * metadata. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * Notes: + * - `stream` is implicit over WebSocket and should not be sent. + * - `background` is not supported over WebSocket. + * - `stream_id` is WebSocket-only and is not part of `POST /v1/responses`. */ - fun input(): Optional = input.getOptional("input") + fun responseCreate(): Optional = Optional.ofNullable(responseCreate) /** - * A system (or developer) message inserted into the model's context. + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and + * execution modes that support steering. Responses bound to a conversation or using automatic + * compaction do not support steering. * - * When using along with `previous_response_id`, the instructions from a previous response will - * not be carried over to the next response. This makes it simple to swap out system (or - * developer) messages in new responses. + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. Input + * that cannot be committed is returned in `response.steer.failed`. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun instructions(): Optional = instructions.getOptional("instructions") - - /** - * An upper bound for the number of tokens that can be generated for a response, including - * visible output tokens and - * [reasoning tokens](https://platform.openai.com/docs/guides/reasoning). + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed by an + * automatic successor. Automatic successors inherit the previous response's settings and + * continue from it with the queued input. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun maxOutputTokens(): Optional = maxOutputTokens.getOptional("max_output_tokens") - - /** - * The maximum number of total calls to built-in tools that can be processed in a response. This - * maximum number applies across all built-in tool calls, not per individual tool. Any further - * attempts to call a tool by the model will be ignored. + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and + * send one explicit `response.create` per parent with the same `previous_response_id` and + * WebSocket lane. Do not rerun tools or resend accepted steering input. The queued input is + * prepended in submission order to that request's input, and the explicit request retains its + * own settings. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; + * the target response determines the WebSocket lane. */ - fun maxToolCalls(): Optional = maxToolCalls.getOptional("max_tool_calls") + fun responseSteer(): Optional = Optional.ofNullable(responseSteer) - /** - * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing - * additional information about the object in a structured format, and querying for objects via - * API or the dashboard. - * - * Keys are strings with a maximum length of 64 characters. Values are strings with a maximum - * length of 512 characters. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun metadata(): Optional = metadata.getOptional("metadata") + fun isResponseCreate(): Boolean = responseCreate != null - /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of - * models with different capabilities, performance characteristics, and price points. Refer to - * the [model guide](https://platform.openai.com/docs/models) to browse and compare available - * models. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun model(): Optional = model.getOptional("model") + fun isResponseSteer(): Boolean = responseSteer != null /** - * Configuration for running moderation on the input and output of this response. + * Client event for creating a response over a persistent WebSocket connection. This payload + * uses the same top-level fields as `POST /v1/responses`, plus WebSocket-only envelope + * metadata. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * Notes: + * - `stream` is implicit over WebSocket and should not be sent. + * - `background` is not supported over WebSocket. + * - `stream_id` is WebSocket-only and is not part of `POST /v1/responses`. */ - fun moderation(): Optional = moderation.getOptional("moderation") + fun asResponseCreate(): ResponseCreate = responseCreate.getOrThrow("responseCreate") /** - * Whether to allow the model to run tool calls in parallel. + * Queues user input to steer a response on this WebSocket connection. Input can contain text, + * images, and files. Steering is supported only for single-agent responses on models and + * execution modes that support steering. Responses bound to a conversation or using automatic + * compaction do not support steering. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun parallelToolCalls(): Optional = - parallelToolCalls.getOptional("parallel_tool_calls") - - /** - * The unique ID of the previous response to the model. Use this to create multi-turn - * conversations. Learn more about - * [conversation state](https://platform.openai.com/docs/guides/conversation-state). Cannot be - * used in conjunction with `conversation`. + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. Input + * that cannot be committed is returned in `response.steer.failed`. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun previousResponseId(): Optional = - previousResponseId.getOptional("previous_response_id") - - /** - * Reference to a prompt template and its variables. - * [Learn more](https://platform.openai.com/docs/guides/text?api-mode=responses#reusable-prompts). + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed by an + * automatic successor. Automatic successors inherit the previous response's settings and + * continue from it with the queued input. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun prompt(): Optional = prompt.getOptional("prompt") - - /** - * Used by OpenAI to cache responses for similar requests to optimize your cache hit rates. - * Replaces the `user` field. - * [Learn more](https://platform.openai.com/docs/guides/prompt-caching). + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * `required_input` stubs from that event with saved tool results or approval decisions, and + * send one explicit `response.create` per parent with the same `previous_response_id` and + * WebSocket lane. Do not rerun tools or resend accepted steering input. The queued input is + * prepended in submission order to that request's input, and the explicit request retains its + * own settings. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send `stream_id`; + * the target response determines the WebSocket lane. */ - fun promptCacheKey(): Optional = promptCacheKey.getOptional("prompt_cache_key") + fun asResponseSteer(): ResponseSteerEvent = responseSteer.getOrThrow("responseSteer") - /** - * Options for prompt caching. Supported for `gpt-5.6` and later models. By default, OpenAI - * automatically chooses one implicit cache breakpoint. You can add explicit breakpoints to - * content blocks with `prompt_cache_breakpoint`. Each request can write up to four breakpoints. - * For cache matching, OpenAI considers up to the latest 80 breakpoints in the conversation, - * without a content-block lookback limit. Set `mode` to `explicit` to disable the implicit - * breakpoint. The `ttl` defaults to `30m`, which is currently the only supported value. See the - * [prompt caching guide](https://platform.openai.com/docs/guides/prompt-caching) for current - * details. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun promptCacheOptions(): Optional = - promptCacheOptions.getOptional("prompt_cache_options") + fun _json(): Optional = Optional.ofNullable(_json) /** - * Deprecated. Use `prompt_cache_options.ttl` instead. + * Maps this instance's current variant to a value of type [T] using the given [visitor]. * - * The retention policy for the prompt cache. Set to `24h` to enable extended prompt caching, - * which keeps cached prefixes active for longer, up to a maximum of 24 hours. - * [Learn more](https://platform.openai.com/docs/guides/prompt-caching#prompt-cache-retention). - * This field expresses a maximum retention policy, while `prompt_cache_options.ttl` expresses a - * minimum cache lifetime. The two fields are independent and do not interact. For `gpt-5.5`, - * `gpt-5.5-pro`, and future models, only `24h` is supported. + * Note that this method is _not_ forwards compatible with new variants from the API, unless + * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of the + * SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; * - * For older models that support both `in_memory` and `24h`, the default depends on your - * organization's data retention policy: - * - Organizations without ZDR enabled default to `24h`. - * - Organizations with ZDR enabled default to `in_memory` when `prompt_cache_retention` is not - * specified. + * Optional result = responsesClientEvent.accept(new ResponsesClientEvent.Visitor>() { + * @Override + * public Optional visitResponseCreate(ResponseCreate responseCreate) { + * return Optional.of(responseCreate.toString()); + * } * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - @Deprecated("deprecated") - fun promptCacheRetention(): Optional = - promptCacheRetention.getOptional("prompt_cache_retention") - - /** - * Configuration options for - * [reasoning models](https://platform.openai.com/docs/guides/reasoning). + * // ... * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun reasoning(): Optional = reasoning.getOptional("reasoning") - - /** - * A stable identifier used to help detect users of your application that may be violating - * OpenAI's usage policies. The IDs should be a string that uniquely identifies each user, with - * a maximum length of 64 characters. We recommend hashing their username or email address, in - * order to avoid sending us any identifying information. - * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] and + * the current variant is unknown. */ - fun safetyIdentifier(): Optional = safetyIdentifier.getOptional("safety_identifier") + fun accept(visitor: Visitor): T = + when { + responseCreate != null -> visitor.visitResponseCreate(responseCreate) + responseSteer != null -> visitor.visitResponseSteer(responseSteer) + else -> visitor.unknown(_json) + } - /** - * Specifies the processing type used for serving the request. - * - If set to 'auto', then the request will be processed with the service tier configured in - * the Project settings. Unless otherwise configured, the Project will use 'default'. - * - If set to 'default', then the request will be processed with the standard pricing and - * performance for the selected model. - * - If set to '[flex](https://platform.openai.com/docs/guides/flex-processing)', then the - * request will be processed with the Flex Processing service tier. - * - To opt-in to [Fast mode](/api/docs/guides/fast-mode) at the request level, include the - * `service_tier=fast` or `service_tier=priority` parameter for Responses or Chat Completions. - * The response will show `service_tier=priority` regardless of if you specify - * `service_tier=fast` or `priority` in your request. - * - If set to 'ultrafast', then the request will be processed with the access-controlled - * Ultrafast Processing service tier. This tier is currently available for `gpt-5.6-sol`; a - * response served through it will show `service_tier=ultrafast`. - * - When not set, the default behavior is 'auto'. - * - * When the `service_tier` parameter is set, the response body will include the `service_tier` - * value based on the processing mode actually used to serve the request. This response value - * may be different from the value set in the parameter. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun serviceTier(): Optional = serviceTier.getOptional("service_tier") + private var validated: Boolean = false /** - * Whether to store the generated model response for later retrieval via API. + * Validates that the types of all values in this object match their expected types recursively. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun store(): Optional = store.getOptional("store") - - /** - * If set to true, the model response data will be streamed to the client as it is generated - * using - * [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format). - * See the - * [Streaming section below](https://platform.openai.com/docs/api-reference/responses-streaming) - * for more information. + * This method is _not_ forwards compatible with new types from the API for existing fields. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. */ - fun stream(): Optional = stream.getOptional("stream") + fun validate(): ResponsesClientEvent = apply { + if (validated) { + return@apply + } - /** - * The WebSocket lane for this response. Requests with the same `stream_id` are processed FIFO, - * and events for the response echo the same `stream_id`. - * - * `stream_id` controls routing; `previous_response_id` controls conversation lineage, so a new - * lane can fork from a response created on another lane. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun streamId(): Optional = streamId.getOptional("stream_id") + accept( + object : Visitor { + override fun visitResponseCreate(responseCreate: ResponseCreate) { + responseCreate.validate() + } - /** - * Options for streaming responses. Only set this when you set `stream: true`. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun streamOptions(): Optional = streamOptions.getOptional("stream_options") + override fun visitResponseSteer(responseSteer: ResponseSteerEvent) { + responseSteer.validate() + } + } + ) + validated = true + } - /** - * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the - * output more random, while lower values like 0.2 will make it more focused and deterministic. - * We generally recommend altering this or `top_p` but not both. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun temperature(): Optional = temperature.getOptional("temperature") + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } /** - * Configuration options for a text response from the model. Can be plain text or structured - * JSON data. Learn more: - * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) - * - [Structured Outputs](https://platform.openai.com/docs/guides/structured-outputs) + * Returns a score indicating how many valid values are contained in this object recursively. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * Used for best match union deserialization. */ - fun text(): Optional = text.getOptional("text") + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitResponseCreate(responseCreate: ResponseCreate) = + responseCreate.validity() - /** - * How the model should select which tool (or tools) to use when generating a response. See the - * `tools` parameter to see how to specify which tools the model can call. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun toolChoice(): Optional = toolChoice.getOptional("tool_choice") + override fun visitResponseSteer(responseSteer: ResponseSteerEvent) = + responseSteer.validity() - /** - * An array of tools the model may call while generating a response. You can specify which tool - * to use by setting the `tool_choice` parameter. - * - * We support the following categories of tools: - * - **Built-in tools**: Tools that are provided by OpenAI that extend the model's capabilities, - * like [web search](https://platform.openai.com/docs/guides/tools-web-search) or - * [file search](https://platform.openai.com/docs/guides/tools-file-search). Learn more about - * [built-in tools](https://platform.openai.com/docs/guides/tools). - * - **MCP Tools**: Integrations with third-party systems via custom MCP servers or predefined - * connectors such as Google Drive and SharePoint. Learn more about - * [MCP Tools](https://platform.openai.com/docs/guides/tools-connectors-mcp). - * - **Function calls (custom tools)**: Functions that are defined by you, enabling the model to - * call your own code with strongly typed arguments and outputs. Learn more about - * [function calling](https://platform.openai.com/docs/guides/function-calling). You can also - * use custom tools to call your own code. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun tools(): Optional> = tools.getOptional("tools") + override fun unknown(json: JsonValue?) = 0 + } + ) - /** - * An integer between 0 and 20 specifying the maximum number of most likely tokens to return at - * each token position, each with an associated log probability. In some cases, the number of - * returned tokens may be fewer than requested. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun topLogprobs(): Optional = topLogprobs.getOptional("top_logprobs") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * An alternative to sampling with temperature, called nucleus sampling, where the model - * considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens - * comprising the top 10% probability mass are considered. - * - * We generally recommend altering this or `temperature` but not both. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun topP(): Optional = topP.getOptional("top_p") + return other is ResponsesClientEvent && + responseCreate == other.responseCreate && + responseSteer == other.responseSteer + } - /** - * The truncation strategy to use for the model response. - * - `auto`: If the input to this Response exceeds the model's context window size, the model - * will truncate the response to fit the context window by dropping items from the beginning - * of the conversation. - * - `disabled` (default): If the input size will exceed the context window size for a model, - * the request will fail with a 400 error. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - @Deprecated("deprecated") - fun truncation(): Optional = truncation.getOptional("truncation") + override fun hashCode(): Int = Objects.hash(responseCreate, responseSteer) - /** - * This field is being replaced by `safety_identifier` and `prompt_cache_key`. Use - * `prompt_cache_key` instead to maintain caching optimizations. A stable identifier for your - * end-users. Used to boost cache hit rates by better bucketing similar requests and to help - * OpenAI detect and prevent abuse. - * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - @Deprecated("deprecated") fun user(): Optional = user.getOptional("user") + override fun toString(): String = + when { + responseCreate != null -> "ResponsesClientEvent{responseCreate=$responseCreate}" + responseSteer != null -> "ResponsesClientEvent{responseSteer=$responseSteer}" + _json != null -> "ResponsesClientEvent{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ResponsesClientEvent") + } - /** - * Returns the raw JSON value of [background]. - * - * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("background") @ExcludeMissing fun _background(): JsonField = background + companion object { - /** - * Returns the raw JSON value of [contextManagement]. - * - * Unlike [contextManagement], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("context_management") - @ExcludeMissing - fun _contextManagement(): JsonField> = contextManagement + /** + * Client event for creating a response over a persistent WebSocket connection. This payload + * uses the same top-level fields as `POST /v1/responses`, plus WebSocket-only envelope + * metadata. + * + * Notes: + * - `stream` is implicit over WebSocket and should not be sent. + * - `background` is not supported over WebSocket. + * - `stream_id` is WebSocket-only and is not part of `POST /v1/responses`. + */ + @JvmStatic + fun ofResponseCreate(responseCreate: ResponseCreate) = + ResponsesClientEvent(responseCreate = responseCreate) - /** - * Returns the raw JSON value of [conversation]. - * - * Unlike [conversation], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("conversation") - @ExcludeMissing - fun _conversation(): JsonField = conversation + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain + * text, images, and files. Steering is supported only for single-agent responses on models + * and execution modes that support steering. Responses bound to a conversation or using + * automatic compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. + * Input that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed + * by an automatic successor. Automatic successors inherit the previous response's settings + * and continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill + * the `required_input` stubs from that event with saved tool results or approval decisions, + * and send one explicit `response.create` per parent with the same `previous_response_id` + * and WebSocket lane. Do not rerun tools or resend accepted steering input. The queued + * input is prepended in submission order to that request's input, and the explicit request + * retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send + * `stream_id`; the target response determines the WebSocket lane. + */ + @JvmStatic + fun ofResponseSteer(responseSteer: ResponseSteerEvent) = + ResponsesClientEvent(responseSteer = responseSteer) + } /** - * Returns the raw JSON value of [include]. - * - * Unlike [include], this method doesn't throw if the JSON field has an unexpected type. + * An interface that defines how to map each variant of [ResponsesClientEvent] to a value of + * type [T]. */ - @JsonProperty("include") - @ExcludeMissing - fun _include(): JsonField> = include + interface Visitor { - /** - * Returns the raw JSON value of [input]. - * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + /** + * Client event for creating a response over a persistent WebSocket connection. This payload + * uses the same top-level fields as `POST /v1/responses`, plus WebSocket-only envelope + * metadata. + * + * Notes: + * - `stream` is implicit over WebSocket and should not be sent. + * - `background` is not supported over WebSocket. + * - `stream_id` is WebSocket-only and is not part of `POST /v1/responses`. + */ + fun visitResponseCreate(responseCreate: ResponseCreate): T - /** - * Returns the raw JSON value of [instructions]. - * - * Unlike [instructions], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("instructions") - @ExcludeMissing - fun _instructions(): JsonField = instructions + /** + * Queues user input to steer a response on this WebSocket connection. Input can contain + * text, images, and files. Steering is supported only for single-agent responses on models + * and execution modes that support steering. Responses bound to a conversation or using + * automatic compaction do not support steering. + * + * A `response.steer.accepted` event acknowledges that the server owns the queued input, not + * that it has been applied. The successor's `response.created` event is the commit point. + * Input that cannot be committed is returned in `response.steer.failed`. + * + * Steering may cause the active response to finish at a safe output boundary with + * `response.incomplete` and `incomplete_details.reason` set to `steered`, followed + * automatically by a successor `response.created`. Normal completion can also be followed + * by an automatic successor. Automatic successors inherit the previous response's settings + * and continue from it with the queued input. + * + * If the response stops for client-owned tool output or approval, accepted steering input + * remains queued and `response.steer.pending` is emitted after `response.completed`. Fill + * the `required_input` stubs from that event with saved tool results or approval decisions, + * and send one explicit `response.create` per parent with the same `previous_response_id` + * and WebSocket lane. Do not rerun tools or resend accepted steering input. The queued + * input is prepended in submission order to that request's input, and the explicit request + * retains its own settings. + * + * This event accepts only `type`, `previous_response_id`, and `input`. Do not send + * `stream_id`; the target response determines the WebSocket lane. + */ + fun visitResponseSteer(responseSteer: ResponseSteerEvent): T - /** - * Returns the raw JSON value of [maxOutputTokens]. - * - * Unlike [maxOutputTokens], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("max_output_tokens") - @ExcludeMissing - fun _maxOutputTokens(): JsonField = maxOutputTokens + /** + * Maps an unknown variant of [ResponsesClientEvent] to a value of type [T]. + * + * An instance of [ResponsesClientEvent] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ResponsesClientEvent: $json") + } + } - /** - * Returns the raw JSON value of [maxToolCalls]. - * - * Unlike [maxToolCalls], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("max_tool_calls") - @ExcludeMissing - fun _maxToolCalls(): JsonField = maxToolCalls + internal class Deserializer : + BaseDeserializer(ResponsesClientEvent::class) { - /** - * Returns the raw JSON value of [metadata]. - * - * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata + override fun ObjectCodec.deserialize(node: JsonNode): ResponsesClientEvent { + val json = JsonValue.fromJsonNode(node) + val type = json.asObject().getOrNull()?.get("type")?.asString()?.getOrNull() - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + when (type) { + "response.create" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponsesClientEvent(responseCreate = it, _json = json) + } ?: ResponsesClientEvent(_json = json) + } + "response.steer" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponsesClientEvent(responseSteer = it, _json = json) + } ?: ResponsesClientEvent(_json = json) + } + } - /** - * Returns the raw JSON value of [moderation]. - * - * Unlike [moderation], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("moderation") - @ExcludeMissing - fun _moderation(): JsonField = moderation + return ResponsesClientEvent(_json = json) + } + } - /** - * Returns the raw JSON value of [parallelToolCalls]. - * - * Unlike [parallelToolCalls], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("parallel_tool_calls") - @ExcludeMissing - fun _parallelToolCalls(): JsonField = parallelToolCalls + internal class Serializer : BaseSerializer(ResponsesClientEvent::class) { - /** - * Returns the raw JSON value of [previousResponseId]. - * - * Unlike [previousResponseId], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("previous_response_id") - @ExcludeMissing - fun _previousResponseId(): JsonField = previousResponseId + override fun serialize( + value: ResponsesClientEvent, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.responseCreate != null -> generator.writeObject(value.responseCreate) + value.responseSteer != null -> generator.writeObject(value.responseSteer) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ResponsesClientEvent") + } + } + } /** - * Returns the raw JSON value of [prompt]. + * Client event for creating a response over a persistent WebSocket connection. This payload + * uses the same top-level fields as `POST /v1/responses`, plus WebSocket-only envelope + * metadata. * - * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. + * Notes: + * - `stream` is implicit over WebSocket and should not be sent. + * - `background` is not supported over WebSocket. + * - `stream_id` is WebSocket-only and is not part of `POST /v1/responses`. */ - @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt + class ResponseCreate + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonValue, + private val background: JsonField, + private val contextManagement: JsonField>, + private val conversation: JsonField, + private val include: JsonField>, + private val input: JsonField, + private val instructions: JsonField, + private val maxOutputTokens: JsonField, + private val maxToolCalls: JsonField, + private val metadata: JsonField, + private val model: JsonField, + private val moderation: JsonField, + private val parallelToolCalls: JsonField, + private val previousResponseId: JsonField, + private val prompt: JsonField, + private val promptCacheKey: JsonField, + private val promptCacheOptions: JsonField, + private val promptCacheRetention: JsonField, + private val reasoning: JsonField, + private val safetyIdentifier: JsonField, + private val serviceTier: JsonField, + private val store: JsonField, + private val stream: JsonField, + private val streamId: JsonField, + private val streamOptions: JsonField, + private val temperature: JsonField, + private val text: JsonField, + private val toolChoice: JsonField, + private val tools: JsonField>, + private val topLogprobs: JsonField, + private val topP: JsonField, + private val truncation: JsonField, + private val user: JsonField, + private val additionalProperties: MutableMap, + ) { - /** - * Returns the raw JSON value of [promptCacheKey]. - * - * Unlike [promptCacheKey], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("prompt_cache_key") - @ExcludeMissing - fun _promptCacheKey(): JsonField = promptCacheKey - - /** - * Returns the raw JSON value of [promptCacheOptions]. - * - * Unlike [promptCacheOptions], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("prompt_cache_options") - @ExcludeMissing - fun _promptCacheOptions(): JsonField = promptCacheOptions - - /** - * Returns the raw JSON value of [promptCacheRetention]. - * - * Unlike [promptCacheRetention], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @Deprecated("deprecated") - @JsonProperty("prompt_cache_retention") - @ExcludeMissing - fun _promptCacheRetention(): JsonField = promptCacheRetention - - /** - * Returns the raw JSON value of [reasoning]. - * - * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("reasoning") @ExcludeMissing fun _reasoning(): JsonField = reasoning - - /** - * Returns the raw JSON value of [safetyIdentifier]. - * - * Unlike [safetyIdentifier], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("safety_identifier") - @ExcludeMissing - fun _safetyIdentifier(): JsonField = safetyIdentifier - - /** - * Returns the raw JSON value of [serviceTier]. - * - * Unlike [serviceTier], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("service_tier") - @ExcludeMissing - fun _serviceTier(): JsonField = serviceTier - - /** - * Returns the raw JSON value of [store]. - * - * Unlike [store], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("store") @ExcludeMissing fun _store(): JsonField = store - - /** - * Returns the raw JSON value of [stream]. - * - * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("stream") @ExcludeMissing fun _stream(): JsonField = stream - - /** - * Returns the raw JSON value of [streamId]. - * - * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId - - /** - * Returns the raw JSON value of [streamOptions]. - * - * Unlike [streamOptions], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("stream_options") - @ExcludeMissing - fun _streamOptions(): JsonField = streamOptions - - /** - * Returns the raw JSON value of [temperature]. - * - * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("temperature") @ExcludeMissing fun _temperature(): JsonField = temperature - - /** - * Returns the raw JSON value of [text]. - * - * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text - - /** - * Returns the raw JSON value of [toolChoice]. - * - * Unlike [toolChoice], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("tool_choice") - @ExcludeMissing - fun _toolChoice(): JsonField = toolChoice - - /** - * Returns the raw JSON value of [tools]. - * - * Unlike [tools], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("tools") @ExcludeMissing fun _tools(): JsonField> = tools - - /** - * Returns the raw JSON value of [topLogprobs]. - * - * Unlike [topLogprobs], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("top_logprobs") @ExcludeMissing fun _topLogprobs(): JsonField = topLogprobs - - /** - * Returns the raw JSON value of [topP]. - * - * Unlike [topP], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("top_p") @ExcludeMissing fun _topP(): JsonField = topP - - /** - * Returns the raw JSON value of [truncation]. - * - * Unlike [truncation], this method doesn't throw if the JSON field has an unexpected type. - */ - @Deprecated("deprecated") - @JsonProperty("truncation") - @ExcludeMissing - fun _truncation(): JsonField = truncation - - /** - * Returns the raw JSON value of [user]. - * - * Unlike [user], this method doesn't throw if the JSON field has an unexpected type. - */ - @Deprecated("deprecated") - @JsonProperty("user") - @ExcludeMissing - fun _user(): JsonField = user - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [ResponsesClientEvent]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [ResponsesClientEvent]. */ - class Builder internal constructor() { - - private var type: JsonValue = JsonValue.from("response.create") - private var background: JsonField = JsonMissing.of() - private var contextManagement: JsonField>? = null - private var conversation: JsonField = JsonMissing.of() - private var include: JsonField>? = null - private var input: JsonField = JsonMissing.of() - private var instructions: JsonField = JsonMissing.of() - private var maxOutputTokens: JsonField = JsonMissing.of() - private var maxToolCalls: JsonField = JsonMissing.of() - private var metadata: JsonField = JsonMissing.of() - private var model: JsonField = JsonMissing.of() - private var moderation: JsonField = JsonMissing.of() - private var parallelToolCalls: JsonField = JsonMissing.of() - private var previousResponseId: JsonField = JsonMissing.of() - private var prompt: JsonField = JsonMissing.of() - private var promptCacheKey: JsonField = JsonMissing.of() - private var promptCacheOptions: JsonField = JsonMissing.of() - private var promptCacheRetention: JsonField = JsonMissing.of() - private var reasoning: JsonField = JsonMissing.of() - private var safetyIdentifier: JsonField = JsonMissing.of() - private var serviceTier: JsonField = JsonMissing.of() - private var store: JsonField = JsonMissing.of() - private var stream: JsonField = JsonMissing.of() - private var streamId: JsonField = JsonMissing.of() - private var streamOptions: JsonField = JsonMissing.of() - private var temperature: JsonField = JsonMissing.of() - private var text: JsonField = JsonMissing.of() - private var toolChoice: JsonField = JsonMissing.of() - private var tools: JsonField>? = null - private var topLogprobs: JsonField = JsonMissing.of() - private var topP: JsonField = JsonMissing.of() - private var truncation: JsonField = JsonMissing.of() - private var user: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(responsesClientEvent: ResponsesClientEvent) = apply { - type = responsesClientEvent.type - background = responsesClientEvent.background - contextManagement = responsesClientEvent.contextManagement.map { it.toMutableList() } - conversation = responsesClientEvent.conversation - include = responsesClientEvent.include.map { it.toMutableList() } - input = responsesClientEvent.input - instructions = responsesClientEvent.instructions - maxOutputTokens = responsesClientEvent.maxOutputTokens - maxToolCalls = responsesClientEvent.maxToolCalls - metadata = responsesClientEvent.metadata - model = responsesClientEvent.model - moderation = responsesClientEvent.moderation - parallelToolCalls = responsesClientEvent.parallelToolCalls - previousResponseId = responsesClientEvent.previousResponseId - prompt = responsesClientEvent.prompt - promptCacheKey = responsesClientEvent.promptCacheKey - promptCacheOptions = responsesClientEvent.promptCacheOptions - promptCacheRetention = responsesClientEvent.promptCacheRetention - reasoning = responsesClientEvent.reasoning - safetyIdentifier = responsesClientEvent.safetyIdentifier - serviceTier = responsesClientEvent.serviceTier - store = responsesClientEvent.store - stream = responsesClientEvent.stream - streamId = responsesClientEvent.streamId - streamOptions = responsesClientEvent.streamOptions - temperature = responsesClientEvent.temperature - text = responsesClientEvent.text - toolChoice = responsesClientEvent.toolChoice - tools = responsesClientEvent.tools.map { it.toMutableList() } - topLogprobs = responsesClientEvent.topLogprobs - topP = responsesClientEvent.topP - truncation = responsesClientEvent.truncation - user = responsesClientEvent.user - additionalProperties = responsesClientEvent.additionalProperties.toMutableMap() - } + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + @JsonProperty("background") + @ExcludeMissing + background: JsonField = JsonMissing.of(), + @JsonProperty("context_management") + @ExcludeMissing + contextManagement: JsonField> = JsonMissing.of(), + @JsonProperty("conversation") + @ExcludeMissing + conversation: JsonField = JsonMissing.of(), + @JsonProperty("include") + @ExcludeMissing + include: JsonField> = JsonMissing.of(), + @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), + @JsonProperty("instructions") + @ExcludeMissing + instructions: JsonField = JsonMissing.of(), + @JsonProperty("max_output_tokens") + @ExcludeMissing + maxOutputTokens: JsonField = JsonMissing.of(), + @JsonProperty("max_tool_calls") + @ExcludeMissing + maxToolCalls: JsonField = JsonMissing.of(), + @JsonProperty("metadata") + @ExcludeMissing + metadata: JsonField = JsonMissing.of(), + @JsonProperty("model") + @ExcludeMissing + model: JsonField = JsonMissing.of(), + @JsonProperty("moderation") + @ExcludeMissing + moderation: JsonField = JsonMissing.of(), + @JsonProperty("parallel_tool_calls") + @ExcludeMissing + parallelToolCalls: JsonField = JsonMissing.of(), + @JsonProperty("previous_response_id") + @ExcludeMissing + previousResponseId: JsonField = JsonMissing.of(), + @JsonProperty("prompt") + @ExcludeMissing + prompt: JsonField = JsonMissing.of(), + @JsonProperty("prompt_cache_key") + @ExcludeMissing + promptCacheKey: JsonField = JsonMissing.of(), + @JsonProperty("prompt_cache_options") + @ExcludeMissing + promptCacheOptions: JsonField = JsonMissing.of(), + @JsonProperty("prompt_cache_retention") + @ExcludeMissing + promptCacheRetention: JsonField = JsonMissing.of(), + @JsonProperty("reasoning") + @ExcludeMissing + reasoning: JsonField = JsonMissing.of(), + @JsonProperty("safety_identifier") + @ExcludeMissing + safetyIdentifier: JsonField = JsonMissing.of(), + @JsonProperty("service_tier") + @ExcludeMissing + serviceTier: JsonField = JsonMissing.of(), + @JsonProperty("store") @ExcludeMissing store: JsonField = JsonMissing.of(), + @JsonProperty("stream") @ExcludeMissing stream: JsonField = JsonMissing.of(), + @JsonProperty("stream_id") + @ExcludeMissing + streamId: JsonField = JsonMissing.of(), + @JsonProperty("stream_options") + @ExcludeMissing + streamOptions: JsonField = JsonMissing.of(), + @JsonProperty("temperature") + @ExcludeMissing + temperature: JsonField = JsonMissing.of(), + @JsonProperty("text") + @ExcludeMissing + text: JsonField = JsonMissing.of(), + @JsonProperty("tool_choice") + @ExcludeMissing + toolChoice: JsonField = JsonMissing.of(), + @JsonProperty("tools") @ExcludeMissing tools: JsonField> = JsonMissing.of(), + @JsonProperty("top_logprobs") + @ExcludeMissing + topLogprobs: JsonField = JsonMissing.of(), + @JsonProperty("top_p") @ExcludeMissing topP: JsonField = JsonMissing.of(), + @JsonProperty("truncation") + @ExcludeMissing + truncation: JsonField = JsonMissing.of(), + @JsonProperty("user") @ExcludeMissing user: JsonField = JsonMissing.of(), + ) : this( + type, + background, + contextManagement, + conversation, + include, + input, + instructions, + maxOutputTokens, + maxToolCalls, + metadata, + model, + moderation, + parallelToolCalls, + previousResponseId, + prompt, + promptCacheKey, + promptCacheOptions, + promptCacheRetention, + reasoning, + safetyIdentifier, + serviceTier, + store, + stream, + streamId, + streamOptions, + temperature, + text, + toolChoice, + tools, + topLogprobs, + topP, + truncation, + user, + mutableMapOf(), + ) /** - * Sets the field to an arbitrary JSON value. + * The type of the client event. Always `response.create`. * - * It is usually unnecessary to call this method because the field defaults to the - * following: + * Expected to always return the following: * ```java * JsonValue.from("response.create") * ``` * - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * However, this method can be useful for debugging and logging (e.g. if the server + * responded with an unexpected value). */ - fun type(type: JsonValue) = apply { this.type = type } + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type /** * Whether to run the model response in the background. * [Learn more](https://platform.openai.com/docs/guides/background). - */ - fun background(background: Boolean?) = background(JsonField.ofNullable(background)) - - /** - * Alias for [Builder.background]. * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun background(background: Boolean) = background(background as Boolean?) - - /** Alias for calling [Builder.background] with `background.orElse(null)`. */ - fun background(background: Optional) = background(background.getOrNull()) - - /** - * Sets [Builder.background] to an arbitrary JSON value. - * - * You should usually call [Builder.background] with a well-typed [Boolean] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun background(background: JsonField) = apply { this.background = background } - - /** Context management configuration for this request. */ - fun contextManagement(contextManagement: List?) = - contextManagement(JsonField.ofNullable(contextManagement)) - - /** Alias for calling [Builder.contextManagement] with `contextManagement.orElse(null)`. */ - fun contextManagement(contextManagement: Optional>) = - contextManagement(contextManagement.getOrNull()) - - /** - * Sets [Builder.contextManagement] to an arbitrary JSON value. - * - * You should usually call [Builder.contextManagement] with a well-typed - * `List` value instead. This method is primarily for setting the field - * to an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun contextManagement(contextManagement: JsonField>) = apply { - this.contextManagement = contextManagement.map { it.toMutableList() } - } + fun background(): Optional = background.getOptional("background") /** - * Adds a single [ContextManagement] to [Builder.contextManagement]. + * Context management configuration for this request. * - * @throws IllegalStateException if the field was previously set to a non-list. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun addContextManagement(contextManagement: ContextManagement) = apply { - this.contextManagement = - (this.contextManagement ?: JsonField.of(mutableListOf())).also { - checkKnown("contextManagement", it).add(contextManagement) - } - } + fun contextManagement(): Optional> = + contextManagement.getOptional("context_management") /** * The conversation that this response belongs to. Items from this conversation are * prepended to `input_items` for this response request. Input items and output items from * this response are automatically added to this conversation after this response completes. - */ - fun conversation(conversation: Conversation?) = - conversation(JsonField.ofNullable(conversation)) - - /** Alias for calling [Builder.conversation] with `conversation.orElse(null)`. */ - fun conversation(conversation: Optional) = - conversation(conversation.getOrNull()) - - /** - * Sets [Builder.conversation] to an arbitrary JSON value. * - * You should usually call [Builder.conversation] with a well-typed [Conversation] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun conversation(conversation: JsonField) = apply { - this.conversation = conversation - } - - /** Alias for calling [conversation] with `Conversation.ofId(id)`. */ - fun conversation(id: String) = conversation(Conversation.ofId(id)) - - /** - * Alias for calling [conversation] with - * `Conversation.ofResponseConversationParam(responseConversationParam)`. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun conversation(responseConversationParam: ResponseConversationParam) = - conversation(Conversation.ofResponseConversationParam(responseConversationParam)) + fun conversation(): Optional = conversation.getOptional("conversation") /** * Specify additional output data to include in the model response. Currently supported @@ -1080,34 +624,11 @@ private constructor( * conversations when using the Responses API statelessly (like when the `store` parameter * is set to `false`, or when an organization is enrolled in the zero data retention * program). - */ - fun include(include: List?) = include(JsonField.ofNullable(include)) - - /** Alias for calling [Builder.include] with `include.orElse(null)`. */ - fun include(include: Optional>) = include(include.getOrNull()) - - /** - * Sets [Builder.include] to an arbitrary JSON value. - * - * You should usually call [Builder.include] with a well-typed `List` - * value instead. This method is primarily for setting the field to an undocumented or not - * yet supported value. - */ - fun include(include: JsonField>) = apply { - this.include = include.map { it.toMutableList() } - } - - /** - * Adds a single [ResponseIncludable] to [Builder.include]. * - * @throws IllegalStateException if the field was previously set to a non-list. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun addInclude(include: ResponseIncludable) = apply { - this.include = - (this.include ?: JsonField.of(mutableListOf())).also { - checkKnown("include", it).add(include) - } - } + fun include(): Optional> = include.getOptional("include") /** * Text, image, or file inputs to the model, used to generate a response. @@ -1118,22 +639,11 @@ private constructor( * - [File inputs](https://platform.openai.com/docs/guides/pdf-files) * - [Conversation state](https://platform.openai.com/docs/guides/conversation-state) * - [Function calling](https://platform.openai.com/docs/guides/function-calling) - */ - fun input(input: Input) = input(JsonField.of(input)) - - /** - * Sets [Builder.input] to an arbitrary JSON value. * - * You should usually call [Builder.input] with a well-typed [Input] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun input(input: JsonField) = apply { this.input = input } - - /** Alias for calling [input] with `Input.ofText(text)`. */ - fun input(text: String) = input(Input.ofText(text)) - - /** Alias for calling [input] with `Input.ofResponse(response)`. */ - fun inputOfResponse(response: List) = input(Input.ofResponse(response)) + fun input(): Optional = input.getOptional("input") /** * A system (or developer) message inserted into the model's context. @@ -1141,78 +651,31 @@ private constructor( * When using along with `previous_response_id`, the instructions from a previous response * will not be carried over to the next response. This makes it simple to swap out system * (or developer) messages in new responses. - */ - fun instructions(instructions: String?) = instructions(JsonField.ofNullable(instructions)) - - /** Alias for calling [Builder.instructions] with `instructions.orElse(null)`. */ - fun instructions(instructions: Optional) = instructions(instructions.getOrNull()) - - /** - * Sets [Builder.instructions] to an arbitrary JSON value. * - * You should usually call [Builder.instructions] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun instructions(instructions: JsonField) = apply { - this.instructions = instructions - } + fun instructions(): Optional = instructions.getOptional("instructions") /** * An upper bound for the number of tokens that can be generated for a response, including * visible output tokens and * [reasoning tokens](https://platform.openai.com/docs/guides/reasoning). - */ - fun maxOutputTokens(maxOutputTokens: Long?) = - maxOutputTokens(JsonField.ofNullable(maxOutputTokens)) - - /** - * Alias for [Builder.maxOutputTokens]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun maxOutputTokens(maxOutputTokens: Long) = maxOutputTokens(maxOutputTokens as Long?) - - /** Alias for calling [Builder.maxOutputTokens] with `maxOutputTokens.orElse(null)`. */ - fun maxOutputTokens(maxOutputTokens: Optional) = - maxOutputTokens(maxOutputTokens.getOrNull()) - - /** - * Sets [Builder.maxOutputTokens] to an arbitrary JSON value. * - * You should usually call [Builder.maxOutputTokens] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun maxOutputTokens(maxOutputTokens: JsonField) = apply { - this.maxOutputTokens = maxOutputTokens - } + fun maxOutputTokens(): Optional = maxOutputTokens.getOptional("max_output_tokens") /** * The maximum number of total calls to built-in tools that can be processed in a response. * This maximum number applies across all built-in tool calls, not per individual tool. Any * further attempts to call a tool by the model will be ignored. - */ - fun maxToolCalls(maxToolCalls: Long?) = maxToolCalls(JsonField.ofNullable(maxToolCalls)) - - /** - * Alias for [Builder.maxToolCalls]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun maxToolCalls(maxToolCalls: Long) = maxToolCalls(maxToolCalls as Long?) - - /** Alias for calling [Builder.maxToolCalls] with `maxToolCalls.orElse(null)`. */ - fun maxToolCalls(maxToolCalls: Optional) = maxToolCalls(maxToolCalls.getOrNull()) - - /** - * Sets [Builder.maxToolCalls] to an arbitrary JSON value. * - * You should usually call [Builder.maxToolCalls] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun maxToolCalls(maxToolCalls: JsonField) = apply { this.maxToolCalls = maxToolCalls } + fun maxToolCalls(): Optional = maxToolCalls.getOptional("max_tool_calls") /** * Set of 16 key-value pairs that can be attached to an object. This can be useful for @@ -1221,155 +684,70 @@ private constructor( * * Keys are strings with a maximum length of 64 characters. Values are strings with a * maximum length of 512 characters. - */ - fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) - - /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ - fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) - - /** - * Sets [Builder.metadata] to an arbitrary JSON value. * - * You should usually call [Builder.metadata] with a well-typed [Metadata] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun metadata(metadata: JsonField) = apply { this.metadata = metadata } + fun metadata(): Optional = metadata.getOptional("metadata") /** - * Model ID used to generate the response, like `gpt-5.6-sol`. OpenAI offers a wide range of + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide range of * models with different capabilities, performance characteristics, and price points. Refer * to the [model guide](https://platform.openai.com/docs/models) to browse and compare * available models. - */ - fun model(model: ResponsesModel) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [ResponsesModel] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** Alias for calling [model] with `ResponsesModel.ofString(string)`. */ - fun model(string: String) = model(ResponsesModel.ofString(string)) - - /** Alias for calling [model] with `ResponsesModel.ofChat(chat)`. */ - fun model(chat: ChatModel) = model(ResponsesModel.ofChat(chat)) - - /** Alias for calling [model] with `ResponsesModel.ofOnly(only)`. */ - fun model(only: ResponsesModel.ResponsesOnlyModel) = model(ResponsesModel.ofOnly(only)) - - /** Configuration for running moderation on the input and output of this response. */ - fun moderation(moderation: Moderation?) = moderation(JsonField.ofNullable(moderation)) - - /** Alias for calling [Builder.moderation] with `moderation.orElse(null)`. */ - fun moderation(moderation: Optional) = moderation(moderation.getOrNull()) - - /** - * Sets [Builder.moderation] to an arbitrary JSON value. * - * You should usually call [Builder.moderation] with a well-typed [Moderation] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun moderation(moderation: JsonField) = apply { this.moderation = moderation } - - /** Whether to allow the model to run tool calls in parallel. */ - fun parallelToolCalls(parallelToolCalls: Boolean?) = - parallelToolCalls(JsonField.ofNullable(parallelToolCalls)) + fun model(): Optional = model.getOptional("model") /** - * Alias for [Builder.parallelToolCalls]. + * Configuration for running moderation on the input and output of this response. * - * This unboxed primitive overload exists for backwards compatibility. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun parallelToolCalls(parallelToolCalls: Boolean) = - parallelToolCalls(parallelToolCalls as Boolean?) - - /** Alias for calling [Builder.parallelToolCalls] with `parallelToolCalls.orElse(null)`. */ - fun parallelToolCalls(parallelToolCalls: Optional) = - parallelToolCalls(parallelToolCalls.getOrNull()) + fun moderation(): Optional = moderation.getOptional("moderation") /** - * Sets [Builder.parallelToolCalls] to an arbitrary JSON value. + * Whether to allow the model to run tool calls in parallel. * - * You should usually call [Builder.parallelToolCalls] with a well-typed [Boolean] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun parallelToolCalls(parallelToolCalls: JsonField) = apply { - this.parallelToolCalls = parallelToolCalls - } + fun parallelToolCalls(): Optional = + parallelToolCalls.getOptional("parallel_tool_calls") /** * The unique ID of the previous response to the model. Use this to create multi-turn * conversations. Learn more about * [conversation state](https://platform.openai.com/docs/guides/conversation-state). Cannot * be used in conjunction with `conversation`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun previousResponseId(previousResponseId: String?) = - previousResponseId(JsonField.ofNullable(previousResponseId)) - - /** - * Alias for calling [Builder.previousResponseId] with `previousResponseId.orElse(null)`. - */ - fun previousResponseId(previousResponseId: Optional) = - previousResponseId(previousResponseId.getOrNull()) - - /** - * Sets [Builder.previousResponseId] to an arbitrary JSON value. - * - * You should usually call [Builder.previousResponseId] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun previousResponseId(previousResponseId: JsonField) = apply { - this.previousResponseId = previousResponseId - } + fun previousResponseId(): Optional = + previousResponseId.getOptional("previous_response_id") /** * Reference to a prompt template and its variables. * [Learn more](https://platform.openai.com/docs/guides/text?api-mode=responses#reusable-prompts). - */ - fun prompt(prompt: ResponsePrompt?) = prompt(JsonField.ofNullable(prompt)) - - /** Alias for calling [Builder.prompt] with `prompt.orElse(null)`. */ - fun prompt(prompt: Optional) = prompt(prompt.getOrNull()) - - /** - * Sets [Builder.prompt] to an arbitrary JSON value. * - * You should usually call [Builder.prompt] with a well-typed [ResponsePrompt] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun prompt(prompt: JsonField) = apply { this.prompt = prompt } + fun prompt(): Optional = prompt.getOptional("prompt") /** * Used by OpenAI to cache responses for similar requests to optimize your cache hit rates. * Replaces the `user` field. * [Learn more](https://platform.openai.com/docs/guides/prompt-caching). - */ - fun promptCacheKey(promptCacheKey: String?) = - promptCacheKey(JsonField.ofNullable(promptCacheKey)) - - /** Alias for calling [Builder.promptCacheKey] with `promptCacheKey.orElse(null)`. */ - fun promptCacheKey(promptCacheKey: Optional) = - promptCacheKey(promptCacheKey.getOrNull()) - - /** - * Sets [Builder.promptCacheKey] to an arbitrary JSON value. * - * You should usually call [Builder.promptCacheKey] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun promptCacheKey(promptCacheKey: JsonField) = apply { - this.promptCacheKey = promptCacheKey - } + fun promptCacheKey(): Optional = promptCacheKey.getOptional("prompt_cache_key") /** * Options for prompt caching. Supported for `gpt-5.6` and later models. By default, OpenAI @@ -1381,20 +759,12 @@ private constructor( * supported value. See the * [prompt caching guide](https://platform.openai.com/docs/guides/prompt-caching) for * current details. - */ - fun promptCacheOptions(promptCacheOptions: PromptCacheOptions) = - promptCacheOptions(JsonField.of(promptCacheOptions)) - - /** - * Sets [Builder.promptCacheOptions] to an arbitrary JSON value. * - * You should usually call [Builder.promptCacheOptions] with a well-typed - * [PromptCacheOptions] value instead. This method is primarily for setting the field to an - * undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun promptCacheOptions(promptCacheOptions: JsonField) = apply { - this.promptCacheOptions = promptCacheOptions - } + fun promptCacheOptions(): Optional = + promptCacheOptions.getOptional("prompt_cache_options") /** * Deprecated. Use `prompt_cache_options.ttl` instead. @@ -1411,48 +781,22 @@ private constructor( * - Organizations without ZDR enabled default to `24h`. * - Organizations with ZDR enabled default to `in_memory` when `prompt_cache_retention` is * not specified. - */ - @Deprecated("deprecated") - fun promptCacheRetention(promptCacheRetention: PromptCacheRetention?) = - promptCacheRetention(JsonField.ofNullable(promptCacheRetention)) - - /** - * Alias for calling [Builder.promptCacheRetention] with - * `promptCacheRetention.orElse(null)`. - */ - @Deprecated("deprecated") - fun promptCacheRetention(promptCacheRetention: Optional) = - promptCacheRetention(promptCacheRetention.getOrNull()) - - /** - * Sets [Builder.promptCacheRetention] to an arbitrary JSON value. * - * You should usually call [Builder.promptCacheRetention] with a well-typed - * [PromptCacheRetention] value instead. This method is primarily for setting the field to - * an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ @Deprecated("deprecated") - fun promptCacheRetention(promptCacheRetention: JsonField) = apply { - this.promptCacheRetention = promptCacheRetention - } + fun promptCacheRetention(): Optional = + promptCacheRetention.getOptional("prompt_cache_retention") /** * Configuration options for * [reasoning models](https://platform.openai.com/docs/guides/reasoning). - */ - fun reasoning(reasoning: Reasoning?) = reasoning(JsonField.ofNullable(reasoning)) - - /** Alias for calling [Builder.reasoning] with `reasoning.orElse(null)`. */ - fun reasoning(reasoning: Optional) = reasoning(reasoning.getOrNull()) - - /** - * Sets [Builder.reasoning] to an arbitrary JSON value. * - * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } + fun reasoning(): Optional = reasoning.getOptional("reasoning") /** * A stable identifier used to help detect users of your application that may be violating @@ -1460,24 +804,11 @@ private constructor( * with a maximum length of 64 characters. We recommend hashing their username or email * address, in order to avoid sending us any identifying information. * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). - */ - fun safetyIdentifier(safetyIdentifier: String?) = - safetyIdentifier(JsonField.ofNullable(safetyIdentifier)) - - /** Alias for calling [Builder.safetyIdentifier] with `safetyIdentifier.orElse(null)`. */ - fun safetyIdentifier(safetyIdentifier: Optional) = - safetyIdentifier(safetyIdentifier.getOrNull()) - - /** - * Sets [Builder.safetyIdentifier] to an arbitrary JSON value. * - * You should usually call [Builder.safetyIdentifier] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun safetyIdentifier(safetyIdentifier: JsonField) = apply { - this.safetyIdentifier = safetyIdentifier - } + fun safetyIdentifier(): Optional = safetyIdentifier.getOptional("safety_identifier") /** * Specifies the processing type used for serving the request. @@ -1499,43 +830,19 @@ private constructor( * When the `service_tier` parameter is set, the response body will include the * `service_tier` value based on the processing mode actually used to serve the request. * This response value may be different from the value set in the parameter. - */ - fun serviceTier(serviceTier: ServiceTier?) = serviceTier(JsonField.ofNullable(serviceTier)) - - /** Alias for calling [Builder.serviceTier] with `serviceTier.orElse(null)`. */ - fun serviceTier(serviceTier: Optional) = serviceTier(serviceTier.getOrNull()) - - /** - * Sets [Builder.serviceTier] to an arbitrary JSON value. - * - * You should usually call [Builder.serviceTier] with a well-typed [ServiceTier] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun serviceTier(serviceTier: JsonField) = apply { - this.serviceTier = serviceTier - } - - /** Whether to store the generated model response for later retrieval via API. */ - fun store(store: Boolean?) = store(JsonField.ofNullable(store)) - - /** - * Alias for [Builder.store]. * - * This unboxed primitive overload exists for backwards compatibility. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun store(store: Boolean) = store(store as Boolean?) - - /** Alias for calling [Builder.store] with `store.orElse(null)`. */ - fun store(store: Optional) = store(store.getOrNull()) + fun serviceTier(): Optional = serviceTier.getOptional("service_tier") /** - * Sets [Builder.store] to an arbitrary JSON value. + * Whether to store the generated model response for later retrieval via API. * - * You should usually call [Builder.store] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun store(store: JsonField) = apply { this.store = store } + fun store(): Optional = store.getOptional("store") /** * If set to true, the model response data will be streamed to the client as it is generated @@ -1544,26 +851,11 @@ private constructor( * See the * [Streaming section below](https://platform.openai.com/docs/api-reference/responses-streaming) * for more information. - */ - fun stream(stream: Boolean?) = stream(JsonField.ofNullable(stream)) - - /** - * Alias for [Builder.stream]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun stream(stream: Boolean) = stream(stream as Boolean?) - - /** Alias for calling [Builder.stream] with `stream.orElse(null)`. */ - fun stream(stream: Optional) = stream(stream.getOrNull()) - - /** - * Sets [Builder.stream] to an arbitrary JSON value. * - * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun stream(stream: JsonField) = apply { this.stream = stream } + fun stream(): Optional = stream.getOptional("stream") /** * The WebSocket lane for this response. Requests with the same `stream_id` are processed @@ -1571,125 +863,49 @@ private constructor( * * `stream_id` controls routing; `previous_response_id` controls conversation lineage, so a * new lane can fork from a response created on another lane. - */ - fun streamId(streamId: String) = streamId(JsonField.of(streamId)) - - /** - * Sets [Builder.streamId] to an arbitrary JSON value. * - * You should usually call [Builder.streamId] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun streamId(streamId: JsonField) = apply { this.streamId = streamId } - - /** Options for streaming responses. Only set this when you set `stream: true`. */ - fun streamOptions(streamOptions: StreamOptions?) = - streamOptions(JsonField.ofNullable(streamOptions)) - - /** Alias for calling [Builder.streamOptions] with `streamOptions.orElse(null)`. */ - fun streamOptions(streamOptions: Optional) = - streamOptions(streamOptions.getOrNull()) + fun streamId(): Optional = streamId.getOptional("stream_id") /** - * Sets [Builder.streamOptions] to an arbitrary JSON value. + * Options for streaming responses. Only set this when you set `stream: true`. * - * You should usually call [Builder.streamOptions] with a well-typed [StreamOptions] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun streamOptions(streamOptions: JsonField) = apply { - this.streamOptions = streamOptions - } + fun streamOptions(): Optional = streamOptions.getOptional("stream_options") /** * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the * output more random, while lower values like 0.2 will make it more focused and * deterministic. We generally recommend altering this or `top_p` but not both. - */ - fun temperature(temperature: Double?) = temperature(JsonField.ofNullable(temperature)) - - /** - * Alias for [Builder.temperature]. - * - * This unboxed primitive overload exists for backwards compatibility. - */ - fun temperature(temperature: Double) = temperature(temperature as Double?) - - /** Alias for calling [Builder.temperature] with `temperature.orElse(null)`. */ - fun temperature(temperature: Optional) = temperature(temperature.getOrNull()) - - /** - * Sets [Builder.temperature] to an arbitrary JSON value. * - * You should usually call [Builder.temperature] with a well-typed [Double] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun temperature(temperature: JsonField) = apply { this.temperature = temperature } + fun temperature(): Optional = temperature.getOptional("temperature") /** * Configuration options for a text response from the model. Can be plain text or structured * JSON data. Learn more: * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) * - [Structured Outputs](https://platform.openai.com/docs/guides/structured-outputs) - */ - fun text(text: ResponseTextConfig) = text(JsonField.of(text)) - - /** - * Sets [Builder.text] to an arbitrary JSON value. * - * You should usually call [Builder.text] with a well-typed [ResponseTextConfig] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun text(text: JsonField) = apply { this.text = text } + fun text(): Optional = text.getOptional("text") /** * How the model should select which tool (or tools) to use when generating a response. See * the `tools` parameter to see how to specify which tools the model can call. - */ - fun toolChoice(toolChoice: ToolChoice) = toolChoice(JsonField.of(toolChoice)) - - /** - * Sets [Builder.toolChoice] to an arbitrary JSON value. * - * You should usually call [Builder.toolChoice] with a well-typed [ToolChoice] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun toolChoice(toolChoice: JsonField) = apply { this.toolChoice = toolChoice } - - /** Alias for calling [toolChoice] with `ToolChoice.ofOptions(options)`. */ - fun toolChoice(options: ToolChoiceOptions) = toolChoice(ToolChoice.ofOptions(options)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofAllowed(allowed)`. */ - fun toolChoice(allowed: ToolChoiceAllowed) = toolChoice(ToolChoice.ofAllowed(allowed)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofTypes(types)`. */ - fun toolChoice(types: ToolChoiceTypes) = toolChoice(ToolChoice.ofTypes(types)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofFunction(function)`. */ - fun toolChoice(function: ToolChoiceFunction) = toolChoice(ToolChoice.ofFunction(function)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofMcp(mcp)`. */ - fun toolChoice(mcp: ToolChoiceMcp) = toolChoice(ToolChoice.ofMcp(mcp)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofCustom(custom)`. */ - fun toolChoice(custom: ToolChoiceCustom) = toolChoice(ToolChoice.ofCustom(custom)) - - /** - * Alias for calling [toolChoice] with - * `ToolChoice.ofSpecificProgrammaticToolCallingParam()`. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun toolChoiceSpecificProgrammaticToolCallingParam() = - toolChoice(ToolChoice.ofSpecificProgrammaticToolCallingParam()) - - /** Alias for calling [toolChoice] with `ToolChoice.ofApplyPatch(applyPatch)`. */ - fun toolChoice(applyPatch: ToolChoiceApplyPatch) = - toolChoice(ToolChoice.ofApplyPatch(applyPatch)) - - /** Alias for calling [toolChoice] with `ToolChoice.ofShell(shell)`. */ - fun toolChoice(shell: ToolChoiceShell) = toolChoice(ToolChoice.ofShell(shell)) + fun toolChoice(): Optional = toolChoice.getOptional("tool_choice") /** * An array of tools the model may call while generating a response. You can specify which @@ -1708,453 +924,342 @@ private constructor( * model to call your own code with strongly typed arguments and outputs. Learn more about * [function calling](https://platform.openai.com/docs/guides/function-calling). You can * also use custom tools to call your own code. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun tools(tools: List) = tools(JsonField.of(tools)) + fun tools(): Optional> = tools.getOptional("tools") /** - * Sets [Builder.tools] to an arbitrary JSON value. + * An integer between 0 and 20 specifying the maximum number of most likely tokens to return + * at each token position, each with an associated log probability. In some cases, the + * number of returned tokens may be fewer than requested. * - * You should usually call [Builder.tools] with a well-typed `List` value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun tools(tools: JsonField>) = apply { - this.tools = tools.map { it.toMutableList() } - } + fun topLogprobs(): Optional = topLogprobs.getOptional("top_logprobs") /** - * Adds a single [Tool] to [tools]. + * An alternative to sampling with temperature, called nucleus sampling, where the model + * considers the results of the tokens with top_p probability mass. So 0.1 means only the + * tokens comprising the top 10% probability mass are considered. + * + * We generally recommend altering this or `temperature` but not both. * - * @throws IllegalStateException if the field was previously set to a non-list. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun addTool(tool: Tool) = apply { - tools = - (tools ?: JsonField.of(mutableListOf())).also { checkKnown("tools", it).add(tool) } - } - - /** Alias for calling [addTool] with `Tool.ofFunction(function)`. */ - fun addTool(function: FunctionTool) = addTool(Tool.ofFunction(function)) - - /** Alias for calling [addTool] with `Tool.ofFileSearch(fileSearch)`. */ - fun addTool(fileSearch: FileSearchTool) = addTool(Tool.ofFileSearch(fileSearch)) + fun topP(): Optional = topP.getOptional("top_p") /** - * Alias for calling [addTool] with the following: - * ```java - * FileSearchTool.builder() - * .vectorStoreIds(vectorStoreIds) - * .build() - * ``` + * The truncation strategy to use for the model response. + * - `auto`: If the input to this Response exceeds the model's context window size, the + * model will truncate the response to fit the context window by dropping items from the + * beginning of the conversation. + * - `disabled` (default): If the input size will exceed the context window size for a + * model, the request will fail with a 400 error. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun addFileSearchTool(vectorStoreIds: List) = - addTool(FileSearchTool.builder().vectorStoreIds(vectorStoreIds).build()) - - /** Alias for calling [addTool] with `Tool.ofComputer(computer)`. */ - fun addTool(computer: ComputerTool) = addTool(Tool.ofComputer(computer)) - - /** Alias for calling [addTool] with `Tool.ofComputerUsePreview(computerUsePreview)`. */ - fun addTool(computerUsePreview: ComputerUsePreviewTool) = - addTool(Tool.ofComputerUsePreview(computerUsePreview)) - - /** Alias for calling [addTool] with `Tool.ofWebSearch(webSearch)`. */ - fun addTool(webSearch: WebSearchTool) = addTool(Tool.ofWebSearch(webSearch)) - - /** Alias for calling [addTool] with `Tool.ofMcp(mcp)`. */ - fun addTool(mcp: Tool.Mcp) = addTool(Tool.ofMcp(mcp)) + @Deprecated("deprecated") + fun truncation(): Optional = truncation.getOptional("truncation") /** - * Alias for calling [addTool] with the following: - * ```java - * Tool.Mcp.builder() - * .serverLabel(serverLabel) - * .build() - * ``` + * This field is being replaced by `safety_identifier` and `prompt_cache_key`. Use + * `prompt_cache_key` instead to maintain caching optimizations. A stable identifier for + * your end-users. Used to boost cache hit rates by better bucketing similar requests and to + * help OpenAI detect and prevent abuse. + * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). */ - fun addMcpTool(serverLabel: String) = - addTool(Tool.Mcp.builder().serverLabel(serverLabel).build()) - - /** Alias for calling [addTool] with `Tool.ofCodeInterpreter(codeInterpreter)`. */ - fun addTool(codeInterpreter: Tool.CodeInterpreter) = - addTool(Tool.ofCodeInterpreter(codeInterpreter)) + @Deprecated("deprecated") fun user(): Optional = user.getOptional("user") /** - * Alias for calling [addTool] with the following: - * ```java - * Tool.CodeInterpreter.builder() - * .container(container) - * .build() - * ``` + * Returns the raw JSON value of [background]. + * + * Unlike [background], this method doesn't throw if the JSON field has an unexpected type. */ - fun addCodeInterpreterTool(container: Tool.CodeInterpreter.Container) = - addTool(Tool.CodeInterpreter.builder().container(container).build()) + @JsonProperty("background") + @ExcludeMissing + fun _background(): JsonField = background /** - * Alias for calling [addCodeInterpreterTool] with - * `Tool.CodeInterpreter.Container.ofString(string)`. + * Returns the raw JSON value of [contextManagement]. + * + * Unlike [contextManagement], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun addCodeInterpreterTool(string: String) = - addCodeInterpreterTool(Tool.CodeInterpreter.Container.ofString(string)) + @JsonProperty("context_management") + @ExcludeMissing + fun _contextManagement(): JsonField> = contextManagement /** - * Alias for calling [addCodeInterpreterTool] with - * `Tool.CodeInterpreter.Container.ofCodeInterpreterToolAuto(codeInterpreterToolAuto)`. + * Returns the raw JSON value of [conversation]. + * + * Unlike [conversation], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun addCodeInterpreterTool( - codeInterpreterToolAuto: Tool.CodeInterpreter.Container.CodeInterpreterToolAuto - ) = - addCodeInterpreterTool( - Tool.CodeInterpreter.Container.ofCodeInterpreterToolAuto(codeInterpreterToolAuto) - ) - - /** Alias for calling [addTool] with `Tool.ofProgrammaticToolCalling()`. */ - fun addToolProgrammaticToolCalling() = addTool(Tool.ofProgrammaticToolCalling()) - - /** Alias for calling [addTool] with `Tool.ofImageGeneration(imageGeneration)`. */ - fun addTool(imageGeneration: Tool.ImageGeneration) = - addTool(Tool.ofImageGeneration(imageGeneration)) - - /** Alias for calling [addTool] with `Tool.ofLocalShell()`. */ - fun addToolLocalShell() = addTool(Tool.ofLocalShell()) - - /** Alias for calling [addTool] with `Tool.ofShell(shell)`. */ - fun addTool(shell: FunctionShellTool) = addTool(Tool.ofShell(shell)) - - /** Alias for calling [addTool] with `Tool.ofCustom(custom)`. */ - fun addTool(custom: CustomTool) = addTool(Tool.ofCustom(custom)) + @JsonProperty("conversation") + @ExcludeMissing + fun _conversation(): JsonField = conversation /** - * Alias for calling [addTool] with the following: - * ```java - * CustomTool.builder() - * .name(name) - * .build() - * ``` + * Returns the raw JSON value of [include]. + * + * Unlike [include], this method doesn't throw if the JSON field has an unexpected type. */ - fun addCustomTool(name: String) = addTool(CustomTool.builder().name(name).build()) - - /** Alias for calling [addTool] with `Tool.ofNamespace(namespace)`. */ - fun addTool(namespace: NamespaceTool) = addTool(Tool.ofNamespace(namespace)) - - /** Alias for calling [addTool] with `Tool.ofSearch(search)`. */ - fun addTool(search: ToolSearchTool) = addTool(Tool.ofSearch(search)) - - /** Alias for calling [addTool] with `Tool.ofWebSearchPreview(webSearchPreview)`. */ - fun addTool(webSearchPreview: WebSearchPreviewTool) = - addTool(Tool.ofWebSearchPreview(webSearchPreview)) - - /** Alias for calling [addTool] with `Tool.ofApplyPatch(applyPatch)`. */ - fun addTool(applyPatch: ApplyPatchTool) = addTool(Tool.ofApplyPatch(applyPatch)) + @JsonProperty("include") + @ExcludeMissing + fun _include(): JsonField> = include /** - * An integer between 0 and 20 specifying the maximum number of most likely tokens to return - * at each token position, each with an associated log probability. In some cases, the - * number of returned tokens may be fewer than requested. + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. */ - fun topLogprobs(topLogprobs: Long?) = topLogprobs(JsonField.ofNullable(topLogprobs)) + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input /** - * Alias for [Builder.topLogprobs]. + * Returns the raw JSON value of [instructions]. * - * This unboxed primitive overload exists for backwards compatibility. + * Unlike [instructions], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun topLogprobs(topLogprobs: Long) = topLogprobs(topLogprobs as Long?) - - /** Alias for calling [Builder.topLogprobs] with `topLogprobs.orElse(null)`. */ - fun topLogprobs(topLogprobs: Optional) = topLogprobs(topLogprobs.getOrNull()) + @JsonProperty("instructions") + @ExcludeMissing + fun _instructions(): JsonField = instructions /** - * Sets [Builder.topLogprobs] to an arbitrary JSON value. + * Returns the raw JSON value of [maxOutputTokens]. * - * You should usually call [Builder.topLogprobs] with a well-typed [Long] value instead. - * This method is primarily for setting the field to an undocumented or not yet supported - * value. + * Unlike [maxOutputTokens], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun topLogprobs(topLogprobs: JsonField) = apply { this.topLogprobs = topLogprobs } + @JsonProperty("max_output_tokens") + @ExcludeMissing + fun _maxOutputTokens(): JsonField = maxOutputTokens /** - * An alternative to sampling with temperature, called nucleus sampling, where the model - * considers the results of the tokens with top_p probability mass. So 0.1 means only the - * tokens comprising the top 10% probability mass are considered. + * Returns the raw JSON value of [maxToolCalls]. * - * We generally recommend altering this or `temperature` but not both. + * Unlike [maxToolCalls], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun topP(topP: Double?) = topP(JsonField.ofNullable(topP)) + @JsonProperty("max_tool_calls") + @ExcludeMissing + fun _maxToolCalls(): JsonField = maxToolCalls /** - * Alias for [Builder.topP]. + * Returns the raw JSON value of [metadata]. * - * This unboxed primitive overload exists for backwards compatibility. + * Unlike [metadata], this method doesn't throw if the JSON field has an unexpected type. */ - fun topP(topP: Double) = topP(topP as Double?) - - /** Alias for calling [Builder.topP] with `topP.orElse(null)`. */ - fun topP(topP: Optional) = topP(topP.getOrNull()) + @JsonProperty("metadata") @ExcludeMissing fun _metadata(): JsonField = metadata /** - * Sets [Builder.topP] to an arbitrary JSON value. + * Returns the raw JSON value of [model]. * - * You should usually call [Builder.topP] with a well-typed [Double] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. */ - fun topP(topP: JsonField) = apply { this.topP = topP } + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model /** - * The truncation strategy to use for the model response. - * - `auto`: If the input to this Response exceeds the model's context window size, the - * model will truncate the response to fit the context window by dropping items from the - * beginning of the conversation. - * - `disabled` (default): If the input size will exceed the context window size for a - * model, the request will fail with a 400 error. + * Returns the raw JSON value of [moderation]. + * + * Unlike [moderation], this method doesn't throw if the JSON field has an unexpected type. */ - @Deprecated("deprecated") - fun truncation(truncation: Truncation?) = truncation(JsonField.ofNullable(truncation)) - - /** Alias for calling [Builder.truncation] with `truncation.orElse(null)`. */ - @Deprecated("deprecated") - fun truncation(truncation: Optional) = truncation(truncation.getOrNull()) + @JsonProperty("moderation") + @ExcludeMissing + fun _moderation(): JsonField = moderation /** - * Sets [Builder.truncation] to an arbitrary JSON value. + * Returns the raw JSON value of [parallelToolCalls]. * - * You should usually call [Builder.truncation] with a well-typed [Truncation] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. + * Unlike [parallelToolCalls], this method doesn't throw if the JSON field has an unexpected + * type. */ - @Deprecated("deprecated") - fun truncation(truncation: JsonField) = apply { this.truncation = truncation } + @JsonProperty("parallel_tool_calls") + @ExcludeMissing + fun _parallelToolCalls(): JsonField = parallelToolCalls /** - * This field is being replaced by `safety_identifier` and `prompt_cache_key`. Use - * `prompt_cache_key` instead to maintain caching optimizations. A stable identifier for - * your end-users. Used to boost cache hit rates by better bucketing similar requests and to - * help OpenAI detect and prevent abuse. - * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). + * Returns the raw JSON value of [previousResponseId]. + * + * Unlike [previousResponseId], this method doesn't throw if the JSON field has an + * unexpected type. */ - @Deprecated("deprecated") fun user(user: String) = user(JsonField.of(user)) + @JsonProperty("previous_response_id") + @ExcludeMissing + fun _previousResponseId(): JsonField = previousResponseId /** - * Sets [Builder.user] to an arbitrary JSON value. + * Returns the raw JSON value of [prompt]. * - * You should usually call [Builder.user] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * Unlike [prompt], this method doesn't throw if the JSON field has an unexpected type. */ - @Deprecated("deprecated") fun user(user: JsonField) = apply { this.user = user } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } + @JsonProperty("prompt") @ExcludeMissing fun _prompt(): JsonField = prompt - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + /** + * Returns the raw JSON value of [promptCacheKey]. + * + * Unlike [promptCacheKey], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("prompt_cache_key") + @ExcludeMissing + fun _promptCacheKey(): JsonField = promptCacheKey - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + /** + * Returns the raw JSON value of [promptCacheOptions]. + * + * Unlike [promptCacheOptions], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("prompt_cache_options") + @ExcludeMissing + fun _promptCacheOptions(): JsonField = promptCacheOptions /** - * Returns an immutable instance of [ResponsesClientEvent]. + * Returns the raw JSON value of [promptCacheRetention]. * - * Further updates to this [Builder] will not mutate the returned instance. + * Unlike [promptCacheRetention], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun build(): ResponsesClientEvent = - ResponsesClientEvent( - type, - background, - (contextManagement ?: JsonMissing.of()).map { it.toImmutable() }, - conversation, - (include ?: JsonMissing.of()).map { it.toImmutable() }, - input, - instructions, - maxOutputTokens, - maxToolCalls, - metadata, - model, - moderation, - parallelToolCalls, - previousResponseId, - prompt, - promptCacheKey, - promptCacheOptions, - promptCacheRetention, - reasoning, - safetyIdentifier, - serviceTier, - store, - stream, - streamId, - streamOptions, - temperature, - text, - toolChoice, - (tools ?: JsonMissing.of()).map { it.toImmutable() }, - topLogprobs, - topP, - truncation, - user, - additionalProperties.toMutableMap(), - ) - } + @Deprecated("deprecated") + @JsonProperty("prompt_cache_retention") + @ExcludeMissing + fun _promptCacheRetention(): JsonField = promptCacheRetention - private var validated: Boolean = false + /** + * Returns the raw JSON value of [reasoning]. + * + * Unlike [reasoning], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reasoning") + @ExcludeMissing + fun _reasoning(): JsonField = reasoning - /** - * Validates that the types of all values in this object match their expected types recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): ResponsesClientEvent = apply { - if (validated) { - return@apply - } + /** + * Returns the raw JSON value of [safetyIdentifier]. + * + * Unlike [safetyIdentifier], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("safety_identifier") + @ExcludeMissing + fun _safetyIdentifier(): JsonField = safetyIdentifier - _type().let { - if (it != JsonValue.from("response.create")) { - throw OpenAIInvalidDataException("'type' is invalid, received $it") - } - } - background() - contextManagement().ifPresent { it.forEach { it.validate() } } - conversation().ifPresent { it.validate() } - include().ifPresent { it.forEach { it.validate() } } - input().ifPresent { it.validate() } - instructions() - maxOutputTokens() - maxToolCalls() - metadata().ifPresent { it.validate() } - model().ifPresent { it.validate() } - moderation().ifPresent { it.validate() } - parallelToolCalls() - previousResponseId() - prompt().ifPresent { it.validate() } - promptCacheKey() - promptCacheOptions().ifPresent { it.validate() } - promptCacheRetention().ifPresent { it.validate() } - reasoning().ifPresent { it.validate() } - safetyIdentifier() - serviceTier().ifPresent { it.validate() } - store() - stream() - streamId() - streamOptions().ifPresent { it.validate() } - temperature() - text().ifPresent { it.validate() } - toolChoice().ifPresent { it.validate() } - tools().ifPresent { it.forEach { it.validate() } } - topLogprobs() - topP() - truncation().ifPresent { it.validate() } - user() - validated = true - } + /** + * Returns the raw JSON value of [serviceTier]. + * + * Unlike [serviceTier], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("service_tier") + @ExcludeMissing + fun _serviceTier(): JsonField = serviceTier - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + /** + * Returns the raw JSON value of [store]. + * + * Unlike [store], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("store") @ExcludeMissing fun _store(): JsonField = store - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - type.let { if (it == JsonValue.from("response.create")) 1 else 0 } + - (if (background.asKnown().isPresent) 1 else 0) + - (contextManagement.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (conversation.asKnown().getOrNull()?.validity() ?: 0) + - (include.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (input.asKnown().getOrNull()?.validity() ?: 0) + - (if (instructions.asKnown().isPresent) 1 else 0) + - (if (maxOutputTokens.asKnown().isPresent) 1 else 0) + - (if (maxToolCalls.asKnown().isPresent) 1 else 0) + - (metadata.asKnown().getOrNull()?.validity() ?: 0) + - (model.asKnown().getOrNull()?.validity() ?: 0) + - (moderation.asKnown().getOrNull()?.validity() ?: 0) + - (if (parallelToolCalls.asKnown().isPresent) 1 else 0) + - (if (previousResponseId.asKnown().isPresent) 1 else 0) + - (prompt.asKnown().getOrNull()?.validity() ?: 0) + - (if (promptCacheKey.asKnown().isPresent) 1 else 0) + - (promptCacheOptions.asKnown().getOrNull()?.validity() ?: 0) + - (promptCacheRetention.asKnown().getOrNull()?.validity() ?: 0) + - (reasoning.asKnown().getOrNull()?.validity() ?: 0) + - (if (safetyIdentifier.asKnown().isPresent) 1 else 0) + - (serviceTier.asKnown().getOrNull()?.validity() ?: 0) + - (if (store.asKnown().isPresent) 1 else 0) + - (if (stream.asKnown().isPresent) 1 else 0) + - (if (streamId.asKnown().isPresent) 1 else 0) + - (streamOptions.asKnown().getOrNull()?.validity() ?: 0) + - (if (temperature.asKnown().isPresent) 1 else 0) + - (text.asKnown().getOrNull()?.validity() ?: 0) + - (toolChoice.asKnown().getOrNull()?.validity() ?: 0) + - (tools.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + - (if (topLogprobs.asKnown().isPresent) 1 else 0) + - (if (topP.asKnown().isPresent) 1 else 0) + - (truncation.asKnown().getOrNull()?.validity() ?: 0) + - (if (user.asKnown().isPresent) 1 else 0) - - class ContextManagement - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val type: JsonField, - private val compactThreshold: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * Returns the raw JSON value of [stream]. + * + * Unlike [stream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream") @ExcludeMissing fun _stream(): JsonField = stream - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("compact_threshold") - @ExcludeMissing - compactThreshold: JsonField = JsonMissing.of(), - ) : this(type, compactThreshold, mutableMapOf()) + /** + * Returns the raw JSON value of [streamId]. + * + * Unlike [streamId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("stream_id") @ExcludeMissing fun _streamId(): JsonField = streamId /** - * The context management entry type. Currently only 'compaction' is supported. + * Returns the raw JSON value of [streamOptions]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + * Unlike [streamOptions], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun type(): String = type.getRequired("type") + @JsonProperty("stream_options") + @ExcludeMissing + fun _streamOptions(): JsonField = streamOptions /** - * Token threshold at which compaction should be triggered for this entry. + * Returns the raw JSON value of [temperature]. * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). + * Unlike [temperature], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("temperature") + @ExcludeMissing + fun _temperature(): JsonField = temperature + + /** + * Returns the raw JSON value of [text]. + * + * Unlike [text], this method doesn't throw if the JSON field has an unexpected type. */ - fun compactThreshold(): Optional = compactThreshold.getOptional("compact_threshold") + @JsonProperty("text") @ExcludeMissing fun _text(): JsonField = text /** - * Returns the raw JSON value of [type]. + * Returns the raw JSON value of [toolChoice]. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * Unlike [toolChoice], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + @JsonProperty("tool_choice") + @ExcludeMissing + fun _toolChoice(): JsonField = toolChoice /** - * Returns the raw JSON value of [compactThreshold]. + * Returns the raw JSON value of [tools]. * - * Unlike [compactThreshold], this method doesn't throw if the JSON field has an unexpected - * type. + * Unlike [tools], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tools") @ExcludeMissing fun _tools(): JsonField> = tools + + /** + * Returns the raw JSON value of [topLogprobs]. + * + * Unlike [topLogprobs], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("top_logprobs") + @ExcludeMissing + fun _topLogprobs(): JsonField = topLogprobs + + /** + * Returns the raw JSON value of [topP]. + * + * Unlike [topP], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("top_p") @ExcludeMissing fun _topP(): JsonField = topP + + /** + * Returns the raw JSON value of [truncation]. + * + * Unlike [truncation], this method doesn't throw if the JSON field has an unexpected type. + */ + @Deprecated("deprecated") + @JsonProperty("truncation") + @ExcludeMissing + fun _truncation(): JsonField = truncation + + /** + * Returns the raw JSON value of [user]. + * + * Unlike [user], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("compact_threshold") + @Deprecated("deprecated") + @JsonProperty("user") @ExcludeMissing - fun _compactThreshold(): JsonField = compactThreshold + fun _user(): JsonField = user @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -2170,679 +1275,1104 @@ private constructor( companion object { - /** - * Returns a mutable builder for constructing an instance of [ContextManagement]. - * - * The following fields are required: - * ```java - * .type() - * ``` - */ + /** Returns a mutable builder for constructing an instance of [ResponseCreate]. */ @JvmStatic fun builder() = Builder() } - /** A builder for [ContextManagement]. */ + /** A builder for [ResponseCreate]. */ class Builder internal constructor() { - private var type: JsonField? = null - private var compactThreshold: JsonField = JsonMissing.of() + private var type: JsonValue = JsonValue.from("response.create") + private var background: JsonField = JsonMissing.of() + private var contextManagement: JsonField>? = null + private var conversation: JsonField = JsonMissing.of() + private var include: JsonField>? = null + private var input: JsonField = JsonMissing.of() + private var instructions: JsonField = JsonMissing.of() + private var maxOutputTokens: JsonField = JsonMissing.of() + private var maxToolCalls: JsonField = JsonMissing.of() + private var metadata: JsonField = JsonMissing.of() + private var model: JsonField = JsonMissing.of() + private var moderation: JsonField = JsonMissing.of() + private var parallelToolCalls: JsonField = JsonMissing.of() + private var previousResponseId: JsonField = JsonMissing.of() + private var prompt: JsonField = JsonMissing.of() + private var promptCacheKey: JsonField = JsonMissing.of() + private var promptCacheOptions: JsonField = JsonMissing.of() + private var promptCacheRetention: JsonField = JsonMissing.of() + private var reasoning: JsonField = JsonMissing.of() + private var safetyIdentifier: JsonField = JsonMissing.of() + private var serviceTier: JsonField = JsonMissing.of() + private var store: JsonField = JsonMissing.of() + private var stream: JsonField = JsonMissing.of() + private var streamId: JsonField = JsonMissing.of() + private var streamOptions: JsonField = JsonMissing.of() + private var temperature: JsonField = JsonMissing.of() + private var text: JsonField = JsonMissing.of() + private var toolChoice: JsonField = JsonMissing.of() + private var tools: JsonField>? = null + private var topLogprobs: JsonField = JsonMissing.of() + private var topP: JsonField = JsonMissing.of() + private var truncation: JsonField = JsonMissing.of() + private var user: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(contextManagement: ContextManagement) = apply { - type = contextManagement.type - compactThreshold = contextManagement.compactThreshold - additionalProperties = contextManagement.additionalProperties.toMutableMap() + internal fun from(responseCreate: ResponseCreate) = apply { + type = responseCreate.type + background = responseCreate.background + contextManagement = responseCreate.contextManagement.map { it.toMutableList() } + conversation = responseCreate.conversation + include = responseCreate.include.map { it.toMutableList() } + input = responseCreate.input + instructions = responseCreate.instructions + maxOutputTokens = responseCreate.maxOutputTokens + maxToolCalls = responseCreate.maxToolCalls + metadata = responseCreate.metadata + model = responseCreate.model + moderation = responseCreate.moderation + parallelToolCalls = responseCreate.parallelToolCalls + previousResponseId = responseCreate.previousResponseId + prompt = responseCreate.prompt + promptCacheKey = responseCreate.promptCacheKey + promptCacheOptions = responseCreate.promptCacheOptions + promptCacheRetention = responseCreate.promptCacheRetention + reasoning = responseCreate.reasoning + safetyIdentifier = responseCreate.safetyIdentifier + serviceTier = responseCreate.serviceTier + store = responseCreate.store + stream = responseCreate.stream + streamId = responseCreate.streamId + streamOptions = responseCreate.streamOptions + temperature = responseCreate.temperature + text = responseCreate.text + toolChoice = responseCreate.toolChoice + tools = responseCreate.tools.map { it.toMutableList() } + topLogprobs = responseCreate.topLogprobs + topP = responseCreate.topP + truncation = responseCreate.truncation + user = responseCreate.user + additionalProperties = responseCreate.additionalProperties.toMutableMap() } - /** The context management entry type. Currently only 'compaction' is supported. */ - fun type(type: String) = type(JsonField.of(type)) - /** - * Sets [Builder.type] to an arbitrary JSON value. + * Sets the field to an arbitrary JSON value. * - * You should usually call [Builder.type] with a well-typed [String] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("response.create") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun type(type: JsonField) = apply { this.type = type } + fun type(type: JsonValue) = apply { this.type = type } - /** Token threshold at which compaction should be triggered for this entry. */ - fun compactThreshold(compactThreshold: Long?) = - compactThreshold(JsonField.ofNullable(compactThreshold)) + /** + * Whether to run the model response in the background. + * [Learn more](https://platform.openai.com/docs/guides/background). + */ + fun background(background: Boolean?) = background(JsonField.ofNullable(background)) /** - * Alias for [Builder.compactThreshold]. + * Alias for [Builder.background]. * * This unboxed primitive overload exists for backwards compatibility. */ - fun compactThreshold(compactThreshold: Long) = - compactThreshold(compactThreshold as Long?) + fun background(background: Boolean) = background(background as Boolean?) - /** - * Alias for calling [Builder.compactThreshold] with `compactThreshold.orElse(null)`. - */ - fun compactThreshold(compactThreshold: Optional) = - compactThreshold(compactThreshold.getOrNull()) + /** Alias for calling [Builder.background] with `background.orElse(null)`. */ + fun background(background: Optional) = background(background.getOrNull()) /** - * Sets [Builder.compactThreshold] to an arbitrary JSON value. + * Sets [Builder.background] to an arbitrary JSON value. * - * You should usually call [Builder.compactThreshold] with a well-typed [Long] value + * You should usually call [Builder.background] with a well-typed [Boolean] value * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun compactThreshold(compactThreshold: JsonField) = apply { - this.compactThreshold = compactThreshold - } + fun background(background: JsonField) = apply { this.background = background } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** Context management configuration for this request. */ + fun contextManagement(contextManagement: List?) = + contextManagement(JsonField.ofNullable(contextManagement)) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Alias for calling [Builder.contextManagement] with `contextManagement.orElse(null)`. + */ + fun contextManagement(contextManagement: Optional>) = + contextManagement(contextManagement.getOrNull()) - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) + /** + * Sets [Builder.contextManagement] to an arbitrary JSON value. + * + * You should usually call [Builder.contextManagement] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun contextManagement(contextManagement: JsonField>) = apply { + this.contextManagement = contextManagement.map { it.toMutableList() } } - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + /** + * Adds a single [ContextManagement] to [Builder.contextManagement]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addContextManagement(contextManagement: ContextManagement) = apply { + this.contextManagement = + (this.contextManagement ?: JsonField.of(mutableListOf())).also { + checkKnown("contextManagement", it).add(contextManagement) + } } /** - * Returns an immutable instance of [ContextManagement]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .type() - * ``` - * - * @throws IllegalStateException if any required field is unset. + * The conversation that this response belongs to. Items from this conversation are + * prepended to `input_items` for this response request. Input items and output items + * from this response are automatically added to this conversation after this response + * completes. */ - fun build(): ContextManagement = - ContextManagement( - checkRequired("type", type), - compactThreshold, - additionalProperties.toMutableMap(), - ) - } + fun conversation(conversation: Conversation?) = + conversation(JsonField.ofNullable(conversation)) - private var validated: Boolean = false + /** Alias for calling [Builder.conversation] with `conversation.orElse(null)`. */ + fun conversation(conversation: Optional) = + conversation(conversation.getOrNull()) - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): ContextManagement = apply { - if (validated) { - return@apply + /** + * Sets [Builder.conversation] to an arbitrary JSON value. + * + * You should usually call [Builder.conversation] with a well-typed [Conversation] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun conversation(conversation: JsonField) = apply { + this.conversation = conversation } - type() - compactThreshold() - validated = true - } + /** Alias for calling [conversation] with `Conversation.ofId(id)`. */ + fun conversation(id: String) = conversation(Conversation.ofId(id)) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + /** + * Alias for calling [conversation] with + * `Conversation.ofResponseConversationParam(responseConversationParam)`. + */ + fun conversation(responseConversationParam: ResponseConversationParam) = + conversation(Conversation.ofResponseConversationParam(responseConversationParam)) - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (type.asKnown().isPresent) 1 else 0) + - (if (compactThreshold.asKnown().isPresent) 1 else 0) + /** + * Specify additional output data to include in the model response. Currently supported + * values are: + * - `web_search_call.action.sources`: Include the sources of the web search tool call. + * - `code_interpreter_call.outputs`: Includes the outputs of python code execution in + * code interpreter tool call items. + * - `computer_call_output.output.image_url`: Include image urls from the computer call + * output. + * - `file_search_call.results`: Include the search results of the file search tool + * call. + * - `message.input_image.image_url`: Include image urls from the input message. + * - `message.output_text.logprobs`: Include logprobs with assistant messages. + * - `reasoning.encrypted_content`: Includes an encrypted version of reasoning tokens in + * reasoning item outputs. This enables reasoning items to be used in multi-turn + * conversations when using the Responses API statelessly (like when the `store` + * parameter is set to `false`, or when an organization is enrolled in the zero data + * retention program). + */ + fun include(include: List?) = include(JsonField.ofNullable(include)) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** Alias for calling [Builder.include] with `include.orElse(null)`. */ + fun include(include: Optional>) = include(include.getOrNull()) + + /** + * Sets [Builder.include] to an arbitrary JSON value. + * + * You should usually call [Builder.include] with a well-typed + * `List` value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun include(include: JsonField>) = apply { + this.include = include.map { it.toMutableList() } } - return other is ContextManagement && - type == other.type && - compactThreshold == other.compactThreshold && - additionalProperties == other.additionalProperties - } + /** + * Adds a single [ResponseIncludable] to [Builder.include]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addInclude(include: ResponseIncludable) = apply { + this.include = + (this.include ?: JsonField.of(mutableListOf())).also { + checkKnown("include", it).add(include) + } + } - private val hashCode: Int by lazy { - Objects.hash(type, compactThreshold, additionalProperties) - } + /** + * Text, image, or file inputs to the model, used to generate a response. + * + * Learn more: + * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) + * - [Image inputs](https://platform.openai.com/docs/guides/images) + * - [File inputs](https://platform.openai.com/docs/guides/pdf-files) + * - [Conversation state](https://platform.openai.com/docs/guides/conversation-state) + * - [Function calling](https://platform.openai.com/docs/guides/function-calling) + */ + fun input(input: Input) = input(JsonField.of(input)) - override fun hashCode(): Int = hashCode + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [Input] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun input(input: JsonField) = apply { this.input = input } - override fun toString() = - "ContextManagement{type=$type, compactThreshold=$compactThreshold, additionalProperties=$additionalProperties}" - } + /** Alias for calling [input] with `Input.ofText(text)`. */ + fun input(text: String) = input(Input.ofText(text)) - /** - * The conversation that this response belongs to. Items from this conversation are prepended to - * `input_items` for this response request. Input items and output items from this response are - * automatically added to this conversation after this response completes. - */ - @JsonDeserialize(using = Conversation.Deserializer::class) - @JsonSerialize(using = Conversation.Serializer::class) - class Conversation - private constructor( - private val id: String? = null, - private val responseConversationParam: ResponseConversationParam? = null, - private val _json: JsonValue? = null, - ) { + /** Alias for calling [input] with `Input.ofResponse(response)`. */ + fun inputOfResponse(response: List) = + input(Input.ofResponse(response)) - /** The unique ID of the conversation. */ - fun id(): Optional = Optional.ofNullable(id) + /** + * A system (or developer) message inserted into the model's context. + * + * When using along with `previous_response_id`, the instructions from a previous + * response will not be carried over to the next response. This makes it simple to swap + * out system (or developer) messages in new responses. + */ + fun instructions(instructions: String?) = + instructions(JsonField.ofNullable(instructions)) - /** The conversation that this response belongs to. */ - fun responseConversationParam(): Optional = - Optional.ofNullable(responseConversationParam) + /** Alias for calling [Builder.instructions] with `instructions.orElse(null)`. */ + fun instructions(instructions: Optional) = + instructions(instructions.getOrNull()) - fun isId(): Boolean = id != null - - fun isResponseConversationParam(): Boolean = responseConversationParam != null - - /** The unique ID of the conversation. */ - fun asId(): String = id.getOrThrow("id") - - /** The conversation that this response belongs to. */ - fun asResponseConversationParam(): ResponseConversationParam = - responseConversationParam.getOrThrow("responseConversationParam") - - fun _json(): Optional = Optional.ofNullable(_json) - - /** - * Maps this instance's current variant to a value of type [T] using the given [visitor]. - * - * Note that this method is _not_ forwards compatible with new variants from the API, unless - * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of - * the SDK gracefully, consider overriding [Visitor.unknown]: - * ```java - * import com.openai.core.JsonValue; - * import java.util.Optional; - * - * Optional result = conversation.accept(new Conversation.Visitor>() { - * @Override - * public Optional visitId(String id) { - * return Optional.of(id.toString()); - * } - * - * // ... - * - * @Override - * public Optional unknown(JsonValue json) { - * // Or inspect the `json`. - * return Optional.empty(); - * } - * }); - * ``` - * - * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] - * and the current variant is unknown. - */ - fun accept(visitor: Visitor): T = - when { - id != null -> visitor.visitId(id) - responseConversationParam != null -> - visitor.visitResponseConversationParam(responseConversationParam) - else -> visitor.unknown(_json) + /** + * Sets [Builder.instructions] to an arbitrary JSON value. + * + * You should usually call [Builder.instructions] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun instructions(instructions: JsonField) = apply { + this.instructions = instructions } - private var validated: Boolean = false - - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): Conversation = apply { - if (validated) { - return@apply - } + /** + * An upper bound for the number of tokens that can be generated for a response, + * including visible output tokens and + * [reasoning tokens](https://platform.openai.com/docs/guides/reasoning). + */ + fun maxOutputTokens(maxOutputTokens: Long?) = + maxOutputTokens(JsonField.ofNullable(maxOutputTokens)) - accept( - object : Visitor { - override fun visitId(id: String) {} + /** + * Alias for [Builder.maxOutputTokens]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxOutputTokens(maxOutputTokens: Long) = maxOutputTokens(maxOutputTokens as Long?) - override fun visitResponseConversationParam( - responseConversationParam: ResponseConversationParam - ) { - responseConversationParam.validate() - } - } - ) - validated = true - } + /** Alias for calling [Builder.maxOutputTokens] with `maxOutputTokens.orElse(null)`. */ + fun maxOutputTokens(maxOutputTokens: Optional) = + maxOutputTokens(maxOutputTokens.getOrNull()) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false + /** + * Sets [Builder.maxOutputTokens] to an arbitrary JSON value. + * + * You should usually call [Builder.maxOutputTokens] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxOutputTokens(maxOutputTokens: JsonField) = apply { + this.maxOutputTokens = maxOutputTokens } - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitId(id: String) = 1 + /** + * The maximum number of total calls to built-in tools that can be processed in a + * response. This maximum number applies across all built-in tool calls, not per + * individual tool. Any further attempts to call a tool by the model will be ignored. + */ + fun maxToolCalls(maxToolCalls: Long?) = maxToolCalls(JsonField.ofNullable(maxToolCalls)) - override fun visitResponseConversationParam( - responseConversationParam: ResponseConversationParam - ) = responseConversationParam.validity() + /** + * Alias for [Builder.maxToolCalls]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxToolCalls(maxToolCalls: Long) = maxToolCalls(maxToolCalls as Long?) - override fun unknown(json: JsonValue?) = 0 - } - ) + /** Alias for calling [Builder.maxToolCalls] with `maxToolCalls.orElse(null)`. */ + fun maxToolCalls(maxToolCalls: Optional) = maxToolCalls(maxToolCalls.getOrNull()) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** + * Sets [Builder.maxToolCalls] to an arbitrary JSON value. + * + * You should usually call [Builder.maxToolCalls] with a well-typed [Long] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun maxToolCalls(maxToolCalls: JsonField) = apply { + this.maxToolCalls = maxToolCalls } - return other is Conversation && - id == other.id && - responseConversationParam == other.responseConversationParam - } + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful for + * storing additional information about the object in a structured format, and querying + * for objects via API or the dashboard. + * + * Keys are strings with a maximum length of 64 characters. Values are strings with a + * maximum length of 512 characters. + */ + fun metadata(metadata: Metadata?) = metadata(JsonField.ofNullable(metadata)) - override fun hashCode(): Int = Objects.hash(id, responseConversationParam) + /** Alias for calling [Builder.metadata] with `metadata.orElse(null)`. */ + fun metadata(metadata: Optional) = metadata(metadata.getOrNull()) - override fun toString(): String = - when { - id != null -> "Conversation{id=$id}" - responseConversationParam != null -> - "Conversation{responseConversationParam=$responseConversationParam}" - _json != null -> "Conversation{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Conversation") - } + /** + * Sets [Builder.metadata] to an arbitrary JSON value. + * + * You should usually call [Builder.metadata] with a well-typed [Metadata] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun metadata(metadata: JsonField) = apply { this.metadata = metadata } - companion object { + /** + * Model ID used to generate the response, like `gpt-6-astra`. OpenAI offers a wide + * range of models with different capabilities, performance characteristics, and price + * points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse + * and compare available models. + */ + fun model(model: ResponsesModel) = model(JsonField.of(model)) - /** The unique ID of the conversation. */ - @JvmStatic fun ofId(id: String) = Conversation(id = id) + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [ResponsesModel] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } - /** The conversation that this response belongs to. */ - @JvmStatic - fun ofResponseConversationParam(responseConversationParam: ResponseConversationParam) = - Conversation(responseConversationParam = responseConversationParam) - } + /** Alias for calling [model] with `ResponsesModel.ofString(string)`. */ + fun model(string: String) = model(ResponsesModel.ofString(string)) - /** - * An interface that defines how to map each variant of [Conversation] to a value of type - * [T]. - */ - interface Visitor { + /** Alias for calling [model] with `ResponsesModel.ofChat(chat)`. */ + fun model(chat: ChatModel) = model(ResponsesModel.ofChat(chat)) - /** The unique ID of the conversation. */ - fun visitId(id: String): T + /** Alias for calling [model] with `ResponsesModel.ofOnly(only)`. */ + fun model(only: ResponsesModel.ResponsesOnlyModel) = model(ResponsesModel.ofOnly(only)) - /** The conversation that this response belongs to. */ - fun visitResponseConversationParam( - responseConversationParam: ResponseConversationParam - ): T + /** Configuration for running moderation on the input and output of this response. */ + fun moderation(moderation: Moderation?) = moderation(JsonField.ofNullable(moderation)) + + /** Alias for calling [Builder.moderation] with `moderation.orElse(null)`. */ + fun moderation(moderation: Optional) = moderation(moderation.getOrNull()) /** - * Maps an unknown variant of [Conversation] to a value of type [T]. + * Sets [Builder.moderation] to an arbitrary JSON value. * - * An instance of [Conversation] can contain an unknown variant if it was deserialized - * from data that doesn't match any known variant. For example, if the SDK is on an - * older version than the API, then the API may respond with new variants that the SDK - * is unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. + * You should usually call [Builder.moderation] with a well-typed [Moderation] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Conversation: $json") + fun moderation(moderation: JsonField) = apply { + this.moderation = moderation } - } - internal class Deserializer : BaseDeserializer(Conversation::class) { + /** Whether to allow the model to run tool calls in parallel. */ + fun parallelToolCalls(parallelToolCalls: Boolean?) = + parallelToolCalls(JsonField.ofNullable(parallelToolCalls)) - override fun ObjectCodec.deserialize(node: JsonNode): Conversation { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - Conversation(responseConversationParam = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Conversation(id = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with - // all the possible variants (e.g. deserializing from boolean). - 0 -> Conversation(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely - // valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } - } - } + /** + * Alias for [Builder.parallelToolCalls]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun parallelToolCalls(parallelToolCalls: Boolean) = + parallelToolCalls(parallelToolCalls as Boolean?) - internal class Serializer : BaseSerializer(Conversation::class) { + /** + * Alias for calling [Builder.parallelToolCalls] with `parallelToolCalls.orElse(null)`. + */ + fun parallelToolCalls(parallelToolCalls: Optional) = + parallelToolCalls(parallelToolCalls.getOrNull()) - override fun serialize( - value: Conversation, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.id != null -> generator.writeObject(value.id) - value.responseConversationParam != null -> - generator.writeObject(value.responseConversationParam) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Conversation") - } + /** + * Sets [Builder.parallelToolCalls] to an arbitrary JSON value. + * + * You should usually call [Builder.parallelToolCalls] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun parallelToolCalls(parallelToolCalls: JsonField) = apply { + this.parallelToolCalls = parallelToolCalls } - } - } - - /** - * Text, image, or file inputs to the model, used to generate a response. - * - * Learn more: - * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) - * - [Image inputs](https://platform.openai.com/docs/guides/images) - * - [File inputs](https://platform.openai.com/docs/guides/pdf-files) - * - [Conversation state](https://platform.openai.com/docs/guides/conversation-state) - * - [Function calling](https://platform.openai.com/docs/guides/function-calling) - */ - @JsonDeserialize(using = Input.Deserializer::class) - @JsonSerialize(using = Input.Serializer::class) - class Input - private constructor( - private val text: String? = null, - private val response: List? = null, - private val _json: JsonValue? = null, - ) { - /** A text input to the model, equivalent to a text input with the `user` role. */ - fun text(): Optional = Optional.ofNullable(text) - - /** A list of one or many input items to the model, containing different content types. */ - fun response(): Optional> = Optional.ofNullable(response) + /** + * The unique ID of the previous response to the model. Use this to create multi-turn + * conversations. Learn more about + * [conversation state](https://platform.openai.com/docs/guides/conversation-state). + * Cannot be used in conjunction with `conversation`. + */ + fun previousResponseId(previousResponseId: String?) = + previousResponseId(JsonField.ofNullable(previousResponseId)) - fun isText(): Boolean = text != null + /** + * Alias for calling [Builder.previousResponseId] with + * `previousResponseId.orElse(null)`. + */ + fun previousResponseId(previousResponseId: Optional) = + previousResponseId(previousResponseId.getOrNull()) - fun isResponse(): Boolean = response != null + /** + * Sets [Builder.previousResponseId] to an arbitrary JSON value. + * + * You should usually call [Builder.previousResponseId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun previousResponseId(previousResponseId: JsonField) = apply { + this.previousResponseId = previousResponseId + } - /** A text input to the model, equivalent to a text input with the `user` role. */ - fun asText(): String = text.getOrThrow("text") + /** + * Reference to a prompt template and its variables. + * [Learn more](https://platform.openai.com/docs/guides/text?api-mode=responses#reusable-prompts). + */ + fun prompt(prompt: ResponsePrompt?) = prompt(JsonField.ofNullable(prompt)) - /** A list of one or many input items to the model, containing different content types. */ - fun asResponse(): List = response.getOrThrow("response") + /** Alias for calling [Builder.prompt] with `prompt.orElse(null)`. */ + fun prompt(prompt: Optional) = prompt(prompt.getOrNull()) - fun _json(): Optional = Optional.ofNullable(_json) + /** + * Sets [Builder.prompt] to an arbitrary JSON value. + * + * You should usually call [Builder.prompt] with a well-typed [ResponsePrompt] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun prompt(prompt: JsonField) = apply { this.prompt = prompt } - /** - * Maps this instance's current variant to a value of type [T] using the given [visitor]. - * - * Note that this method is _not_ forwards compatible with new variants from the API, unless - * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of - * the SDK gracefully, consider overriding [Visitor.unknown]: - * ```java - * import com.openai.core.JsonValue; - * import java.util.Optional; - * - * Optional result = input.accept(new Input.Visitor>() { - * @Override - * public Optional visitText(String text) { - * return Optional.of(text.toString()); - * } - * - * // ... - * - * @Override - * public Optional unknown(JsonValue json) { - * // Or inspect the `json`. - * return Optional.empty(); - * } - * }); - * ``` - * - * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] - * and the current variant is unknown. - */ - fun accept(visitor: Visitor): T = - when { - text != null -> visitor.visitText(text) - response != null -> visitor.visitResponse(response) - else -> visitor.unknown(_json) - } + /** + * Used by OpenAI to cache responses for similar requests to optimize your cache hit + * rates. Replaces the `user` field. + * [Learn more](https://platform.openai.com/docs/guides/prompt-caching). + */ + fun promptCacheKey(promptCacheKey: String?) = + promptCacheKey(JsonField.ofNullable(promptCacheKey)) - private var validated: Boolean = false + /** Alias for calling [Builder.promptCacheKey] with `promptCacheKey.orElse(null)`. */ + fun promptCacheKey(promptCacheKey: Optional) = + promptCacheKey(promptCacheKey.getOrNull()) - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): Input = apply { - if (validated) { - return@apply + /** + * Sets [Builder.promptCacheKey] to an arbitrary JSON value. + * + * You should usually call [Builder.promptCacheKey] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun promptCacheKey(promptCacheKey: JsonField) = apply { + this.promptCacheKey = promptCacheKey } - accept( - object : Visitor { - override fun visitText(text: String) {} - - override fun visitResponse(response: List) { - response.forEach { it.validate() } - } - } - ) - validated = true - } + /** + * Options for prompt caching. Supported for `gpt-5.6` and later models. By default, + * OpenAI automatically chooses one implicit cache breakpoint. You can add explicit + * breakpoints to content blocks with `prompt_cache_breakpoint`. Each request can write + * up to four breakpoints. For cache matching, OpenAI considers up to the latest 80 + * breakpoints in the conversation, without a content-block lookback limit. Set `mode` + * to `explicit` to disable the implicit breakpoint. The `ttl` defaults to `30m`, which + * is currently the only supported value. See the + * [prompt caching guide](https://platform.openai.com/docs/guides/prompt-caching) for + * current details. + */ + fun promptCacheOptions(promptCacheOptions: PromptCacheOptions) = + promptCacheOptions(JsonField.of(promptCacheOptions)) - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false + /** + * Sets [Builder.promptCacheOptions] to an arbitrary JSON value. + * + * You should usually call [Builder.promptCacheOptions] with a well-typed + * [PromptCacheOptions] value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun promptCacheOptions(promptCacheOptions: JsonField) = apply { + this.promptCacheOptions = promptCacheOptions } - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitText(text: String) = 1 + /** + * Deprecated. Use `prompt_cache_options.ttl` instead. + * + * The retention policy for the prompt cache. Set to `24h` to enable extended prompt + * caching, which keeps cached prefixes active for longer, up to a maximum of 24 hours. + * [Learn more](https://platform.openai.com/docs/guides/prompt-caching#prompt-cache-retention). + * This field expresses a maximum retention policy, while `prompt_cache_options.ttl` + * expresses a minimum cache lifetime. The two fields are independent and do not + * interact. For `gpt-5.5`, `gpt-5.5-pro`, and future models, only `24h` is supported. + * + * For older models that support both `in_memory` and `24h`, the default depends on your + * organization's data retention policy: + * - Organizations without ZDR enabled default to `24h`. + * - Organizations with ZDR enabled default to `in_memory` when `prompt_cache_retention` + * is not specified. + */ + @Deprecated("deprecated") + fun promptCacheRetention(promptCacheRetention: PromptCacheRetention?) = + promptCacheRetention(JsonField.ofNullable(promptCacheRetention)) - override fun visitResponse(response: List) = - response.sumOf { it.validity().toInt() } + /** + * Alias for calling [Builder.promptCacheRetention] with + * `promptCacheRetention.orElse(null)`. + */ + @Deprecated("deprecated") + fun promptCacheRetention(promptCacheRetention: Optional) = + promptCacheRetention(promptCacheRetention.getOrNull()) - override fun unknown(json: JsonValue?) = 0 + /** + * Sets [Builder.promptCacheRetention] to an arbitrary JSON value. + * + * You should usually call [Builder.promptCacheRetention] with a well-typed + * [PromptCacheRetention] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + @Deprecated("deprecated") + fun promptCacheRetention(promptCacheRetention: JsonField) = + apply { + this.promptCacheRetention = promptCacheRetention } - ) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Input && text == other.text && response == other.response - } - - override fun hashCode(): Int = Objects.hash(text, response) - - override fun toString(): String = - when { - text != null -> "Input{text=$text}" - response != null -> "Input{response=$response}" - _json != null -> "Input{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Input") - } - companion object { + /** + * Configuration options for + * [reasoning models](https://platform.openai.com/docs/guides/reasoning). + */ + fun reasoning(reasoning: Reasoning?) = reasoning(JsonField.ofNullable(reasoning)) - /** A text input to the model, equivalent to a text input with the `user` role. */ - @JvmStatic fun ofText(text: String) = Input(text = text) + /** Alias for calling [Builder.reasoning] with `reasoning.orElse(null)`. */ + fun reasoning(reasoning: Optional) = reasoning(reasoning.getOrNull()) /** - * A list of one or many input items to the model, containing different content types. + * Sets [Builder.reasoning] to an arbitrary JSON value. + * + * You should usually call [Builder.reasoning] with a well-typed [Reasoning] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - @JvmStatic - fun ofResponse(response: List) = - Input(response = response.toImmutable()) - } - - /** An interface that defines how to map each variant of [Input] to a value of type [T]. */ - interface Visitor { + fun reasoning(reasoning: JsonField) = apply { this.reasoning = reasoning } - /** A text input to the model, equivalent to a text input with the `user` role. */ - fun visitText(text: String): T + /** + * A stable identifier used to help detect users of your application that may be + * violating OpenAI's usage policies. The IDs should be a string that uniquely + * identifies each user, with a maximum length of 64 characters. We recommend hashing + * their username or email address, in order to avoid sending us any identifying + * information. + * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). + */ + fun safetyIdentifier(safetyIdentifier: String?) = + safetyIdentifier(JsonField.ofNullable(safetyIdentifier)) /** - * A list of one or many input items to the model, containing different content types. + * Alias for calling [Builder.safetyIdentifier] with `safetyIdentifier.orElse(null)`. */ - fun visitResponse(response: List): T + fun safetyIdentifier(safetyIdentifier: Optional) = + safetyIdentifier(safetyIdentifier.getOrNull()) /** - * Maps an unknown variant of [Input] to a value of type [T]. + * Sets [Builder.safetyIdentifier] to an arbitrary JSON value. * - * An instance of [Input] can contain an unknown variant if it was deserialized from - * data that doesn't match any known variant. For example, if the SDK is on an older - * version than the API, then the API may respond with new variants that the SDK is - * unaware of. - * - * @throws OpenAIInvalidDataException in the default implementation. + * You should usually call [Builder.safetyIdentifier] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown Input: $json") + fun safetyIdentifier(safetyIdentifier: JsonField) = apply { + this.safetyIdentifier = safetyIdentifier } - } - internal class Deserializer : BaseDeserializer(Input::class) { + /** + * Specifies the processing type used for serving the request. + * - If set to 'auto', then the request will be processed with the service tier + * configured in the Project settings. Unless otherwise configured, the Project will + * use 'default'. + * - If set to 'default', then the request will be processed with the standard pricing + * and performance for the selected model. + * - If set to '[flex](https://platform.openai.com/docs/guides/flex-processing)', then + * the request will be processed with the Flex Processing service tier. + * - To opt-in to [Fast mode](/api/docs/guides/fast-mode) at the request level, include + * the `service_tier=fast` or `service_tier=priority` parameter for Responses or Chat + * Completions. The response will show `service_tier=priority` regardless of if you + * specify `service_tier=fast` or `priority` in your request. + * - If set to 'ultrafast', then the request will be processed with the + * access-controlled Ultrafast Processing service tier. This tier is currently + * available for `gpt-5.6-sol`; a response served through it will show + * `service_tier=ultrafast`. + * - When not set, the default behavior is 'auto'. + * + * When the `service_tier` parameter is set, the response body will include the + * `service_tier` value based on the processing mode actually used to serve the + * request. This response value may be different from the value set in the parameter. + */ + fun serviceTier(serviceTier: ServiceTier?) = + serviceTier(JsonField.ofNullable(serviceTier)) - override fun ObjectCodec.deserialize(node: JsonNode): Input { - val json = JsonValue.fromJsonNode(node) + /** Alias for calling [Builder.serviceTier] with `serviceTier.orElse(null)`. */ + fun serviceTier(serviceTier: Optional) = + serviceTier(serviceTier.getOrNull()) - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef())?.let { - Input(text = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef>())?.let { - Input(response = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with - // all the possible variants (e.g. deserializing from boolean). - 0 -> Input(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely - // valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() - } + /** + * Sets [Builder.serviceTier] to an arbitrary JSON value. + * + * You should usually call [Builder.serviceTier] with a well-typed [ServiceTier] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun serviceTier(serviceTier: JsonField) = apply { + this.serviceTier = serviceTier } - } - internal class Serializer : BaseSerializer(Input::class) { + /** Whether to store the generated model response for later retrieval via API. */ + fun store(store: Boolean?) = store(JsonField.ofNullable(store)) - override fun serialize( - value: Input, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.text != null -> generator.writeObject(value.text) - value.response != null -> generator.writeObject(value.response) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid Input") - } + /** + * Alias for [Builder.store]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun store(store: Boolean) = store(store as Boolean?) + + /** Alias for calling [Builder.store] with `store.orElse(null)`. */ + fun store(store: Optional) = store(store.getOrNull()) + + /** + * Sets [Builder.store] to an arbitrary JSON value. + * + * You should usually call [Builder.store] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun store(store: JsonField) = apply { this.store = store } + + /** + * If set to true, the model response data will be streamed to the client as it is + * generated using + * [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format). + * See the + * [Streaming section below](https://platform.openai.com/docs/api-reference/responses-streaming) + * for more information. + */ + fun stream(stream: Boolean?) = stream(JsonField.ofNullable(stream)) + + /** + * Alias for [Builder.stream]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun stream(stream: Boolean) = stream(stream as Boolean?) + + /** Alias for calling [Builder.stream] with `stream.orElse(null)`. */ + fun stream(stream: Optional) = stream(stream.getOrNull()) + + /** + * Sets [Builder.stream] to an arbitrary JSON value. + * + * You should usually call [Builder.stream] with a well-typed [Boolean] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun stream(stream: JsonField) = apply { this.stream = stream } + + /** + * The WebSocket lane for this response. Requests with the same `stream_id` are + * processed FIFO, and events for the response echo the same `stream_id`. + * + * `stream_id` controls routing; `previous_response_id` controls conversation lineage, + * so a new lane can fork from a response created on another lane. + */ + fun streamId(streamId: String) = streamId(JsonField.of(streamId)) + + /** + * Sets [Builder.streamId] to an arbitrary JSON value. + * + * You should usually call [Builder.streamId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun streamId(streamId: JsonField) = apply { this.streamId = streamId } + + /** Options for streaming responses. Only set this when you set `stream: true`. */ + fun streamOptions(streamOptions: StreamOptions?) = + streamOptions(JsonField.ofNullable(streamOptions)) + + /** Alias for calling [Builder.streamOptions] with `streamOptions.orElse(null)`. */ + fun streamOptions(streamOptions: Optional) = + streamOptions(streamOptions.getOrNull()) + + /** + * Sets [Builder.streamOptions] to an arbitrary JSON value. + * + * You should usually call [Builder.streamOptions] with a well-typed [StreamOptions] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun streamOptions(streamOptions: JsonField) = apply { + this.streamOptions = streamOptions } - } - } - /** - * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing - * additional information about the object in a structured format, and querying for objects via - * API or the dashboard. - * - * Keys are strings with a maximum length of 64 characters. Values are strings with a maximum - * length of 512 characters. - */ - class Metadata - @JsonCreator - private constructor( - @com.fasterxml.jackson.annotation.JsonValue - private val additionalProperties: Map - ) { + /** + * What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make + * the output more random, while lower values like 0.2 will make it more focused and + * deterministic. We generally recommend altering this or `top_p` but not both. + */ + fun temperature(temperature: Double?) = temperature(JsonField.ofNullable(temperature)) - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = additionalProperties + /** + * Alias for [Builder.temperature]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun temperature(temperature: Double) = temperature(temperature as Double?) - fun toBuilder() = Builder().from(this) + /** Alias for calling [Builder.temperature] with `temperature.orElse(null)`. */ + fun temperature(temperature: Optional) = temperature(temperature.getOrNull()) - companion object { + /** + * Sets [Builder.temperature] to an arbitrary JSON value. + * + * You should usually call [Builder.temperature] with a well-typed [Double] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun temperature(temperature: JsonField) = apply { + this.temperature = temperature + } - /** Returns a mutable builder for constructing an instance of [Metadata]. */ - @JvmStatic fun builder() = Builder() - } + /** + * Configuration options for a text response from the model. Can be plain text or + * structured JSON data. Learn more: + * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) + * - [Structured Outputs](https://platform.openai.com/docs/guides/structured-outputs) + */ + fun text(text: ResponseTextConfig) = text(JsonField.of(text)) - /** A builder for [Metadata]. */ - class Builder internal constructor() { + /** + * Sets [Builder.text] to an arbitrary JSON value. + * + * You should usually call [Builder.text] with a well-typed [ResponseTextConfig] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun text(text: JsonField) = apply { this.text = text } - private var additionalProperties: MutableMap = mutableMapOf() + /** + * How the model should select which tool (or tools) to use when generating a response. + * See the `tools` parameter to see how to specify which tools the model can call. + */ + fun toolChoice(toolChoice: ToolChoice) = toolChoice(JsonField.of(toolChoice)) - @JvmSynthetic - internal fun from(metadata: Metadata) = apply { - additionalProperties = metadata.additionalProperties.toMutableMap() + /** + * Sets [Builder.toolChoice] to an arbitrary JSON value. + * + * You should usually call [Builder.toolChoice] with a well-typed [ToolChoice] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun toolChoice(toolChoice: JsonField) = apply { + this.toolChoice = toolChoice + } + + /** Alias for calling [toolChoice] with `ToolChoice.ofOptions(options)`. */ + fun toolChoice(options: ToolChoiceOptions) = toolChoice(ToolChoice.ofOptions(options)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofAllowed(allowed)`. */ + fun toolChoice(allowed: ToolChoiceAllowed) = toolChoice(ToolChoice.ofAllowed(allowed)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofTypes(types)`. */ + fun toolChoice(types: ToolChoiceTypes) = toolChoice(ToolChoice.ofTypes(types)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofFunction(function)`. */ + fun toolChoice(function: ToolChoiceFunction) = + toolChoice(ToolChoice.ofFunction(function)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofMcp(mcp)`. */ + fun toolChoice(mcp: ToolChoiceMcp) = toolChoice(ToolChoice.ofMcp(mcp)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofCustom(custom)`. */ + fun toolChoice(custom: ToolChoiceCustom) = toolChoice(ToolChoice.ofCustom(custom)) + + /** + * Alias for calling [toolChoice] with + * `ToolChoice.ofSpecificProgrammaticToolCallingParam()`. + */ + fun toolChoiceSpecificProgrammaticToolCallingParam() = + toolChoice(ToolChoice.ofSpecificProgrammaticToolCallingParam()) + + /** Alias for calling [toolChoice] with `ToolChoice.ofApplyPatch(applyPatch)`. */ + fun toolChoice(applyPatch: ToolChoiceApplyPatch) = + toolChoice(ToolChoice.ofApplyPatch(applyPatch)) + + /** Alias for calling [toolChoice] with `ToolChoice.ofShell(shell)`. */ + fun toolChoice(shell: ToolChoiceShell) = toolChoice(ToolChoice.ofShell(shell)) + + /** + * An array of tools the model may call while generating a response. You can specify + * which tool to use by setting the `tool_choice` parameter. + * + * We support the following categories of tools: + * - **Built-in tools**: Tools that are provided by OpenAI that extend the model's + * capabilities, like + * [web search](https://platform.openai.com/docs/guides/tools-web-search) or + * [file search](https://platform.openai.com/docs/guides/tools-file-search). Learn + * more about [built-in tools](https://platform.openai.com/docs/guides/tools). + * - **MCP Tools**: Integrations with third-party systems via custom MCP servers or + * predefined connectors such as Google Drive and SharePoint. Learn more about + * [MCP Tools](https://platform.openai.com/docs/guides/tools-connectors-mcp). + * - **Function calls (custom tools)**: Functions that are defined by you, enabling the + * model to call your own code with strongly typed arguments and outputs. Learn more + * about [function calling](https://platform.openai.com/docs/guides/function-calling). + * You can also use custom tools to call your own code. + */ + fun tools(tools: List) = tools(JsonField.of(tools)) + + /** + * Sets [Builder.tools] to an arbitrary JSON value. + * + * You should usually call [Builder.tools] with a well-typed `List` value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tools(tools: JsonField>) = apply { + this.tools = tools.map { it.toMutableList() } + } + + /** + * Adds a single [Tool] to [tools]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addTool(tool: Tool) = apply { + tools = + (tools ?: JsonField.of(mutableListOf())).also { + checkKnown("tools", it).add(tool) + } + } + + /** Alias for calling [addTool] with `Tool.ofFunction(function)`. */ + fun addTool(function: FunctionTool) = addTool(Tool.ofFunction(function)) + + /** Alias for calling [addTool] with `Tool.ofFileSearch(fileSearch)`. */ + fun addTool(fileSearch: FileSearchTool) = addTool(Tool.ofFileSearch(fileSearch)) + + /** + * Alias for calling [addTool] with the following: + * ```java + * FileSearchTool.builder() + * .vectorStoreIds(vectorStoreIds) + * .build() + * ``` + */ + fun addFileSearchTool(vectorStoreIds: List) = + addTool(FileSearchTool.builder().vectorStoreIds(vectorStoreIds).build()) + + /** Alias for calling [addTool] with `Tool.ofComputer(computer)`. */ + fun addTool(computer: ComputerTool) = addTool(Tool.ofComputer(computer)) + + /** Alias for calling [addTool] with `Tool.ofComputerUsePreview(computerUsePreview)`. */ + fun addTool(computerUsePreview: ComputerUsePreviewTool) = + addTool(Tool.ofComputerUsePreview(computerUsePreview)) + + /** Alias for calling [addTool] with `Tool.ofWebSearch(webSearch)`. */ + fun addTool(webSearch: WebSearchTool) = addTool(Tool.ofWebSearch(webSearch)) + + /** Alias for calling [addTool] with `Tool.ofMcp(mcp)`. */ + fun addTool(mcp: Tool.Mcp) = addTool(Tool.ofMcp(mcp)) + + /** + * Alias for calling [addTool] with the following: + * ```java + * Tool.Mcp.builder() + * .serverLabel(serverLabel) + * .build() + * ``` + */ + fun addMcpTool(serverLabel: String) = + addTool(Tool.Mcp.builder().serverLabel(serverLabel).build()) + + /** Alias for calling [addTool] with `Tool.ofCodeInterpreter(codeInterpreter)`. */ + fun addTool(codeInterpreter: Tool.CodeInterpreter) = + addTool(Tool.ofCodeInterpreter(codeInterpreter)) + + /** + * Alias for calling [addTool] with the following: + * ```java + * Tool.CodeInterpreter.builder() + * .container(container) + * .build() + * ``` + */ + fun addCodeInterpreterTool(container: Tool.CodeInterpreter.Container) = + addTool(Tool.CodeInterpreter.builder().container(container).build()) + + /** + * Alias for calling [addCodeInterpreterTool] with + * `Tool.CodeInterpreter.Container.ofString(string)`. + */ + fun addCodeInterpreterTool(string: String) = + addCodeInterpreterTool(Tool.CodeInterpreter.Container.ofString(string)) + + /** + * Alias for calling [addCodeInterpreterTool] with + * `Tool.CodeInterpreter.Container.ofCodeInterpreterToolAuto(codeInterpreterToolAuto)`. + */ + fun addCodeInterpreterTool( + codeInterpreterToolAuto: Tool.CodeInterpreter.Container.CodeInterpreterToolAuto + ) = + addCodeInterpreterTool( + Tool.CodeInterpreter.Container.ofCodeInterpreterToolAuto( + codeInterpreterToolAuto + ) + ) + + /** Alias for calling [addTool] with `Tool.ofProgrammaticToolCalling()`. */ + fun addToolProgrammaticToolCalling() = addTool(Tool.ofProgrammaticToolCalling()) + + /** Alias for calling [addTool] with `Tool.ofImageGeneration(imageGeneration)`. */ + fun addTool(imageGeneration: Tool.ImageGeneration) = + addTool(Tool.ofImageGeneration(imageGeneration)) + + /** Alias for calling [addTool] with `Tool.ofLocalShell()`. */ + fun addToolLocalShell() = addTool(Tool.ofLocalShell()) + + /** Alias for calling [addTool] with `Tool.ofShell(shell)`. */ + fun addTool(shell: FunctionShellTool) = addTool(Tool.ofShell(shell)) + + /** Alias for calling [addTool] with `Tool.ofCustom(custom)`. */ + fun addTool(custom: CustomTool) = addTool(Tool.ofCustom(custom)) + + /** + * Alias for calling [addTool] with the following: + * ```java + * CustomTool.builder() + * .name(name) + * .build() + * ``` + */ + fun addCustomTool(name: String) = addTool(CustomTool.builder().name(name).build()) + + /** Alias for calling [addTool] with `Tool.ofNamespace(namespace)`. */ + fun addTool(namespace: NamespaceTool) = addTool(Tool.ofNamespace(namespace)) + + /** Alias for calling [addTool] with `Tool.ofSearch(search)`. */ + fun addTool(search: ToolSearchTool) = addTool(Tool.ofSearch(search)) + + /** Alias for calling [addTool] with `Tool.ofWebSearchPreview(webSearchPreview)`. */ + fun addTool(webSearchPreview: WebSearchPreviewTool) = + addTool(Tool.ofWebSearchPreview(webSearchPreview)) + + /** Alias for calling [addTool] with `Tool.ofApplyPatch(applyPatch)`. */ + fun addTool(applyPatch: ApplyPatchTool) = addTool(Tool.ofApplyPatch(applyPatch)) + + /** + * An integer between 0 and 20 specifying the maximum number of most likely tokens to + * return at each token position, each with an associated log probability. In some + * cases, the number of returned tokens may be fewer than requested. + */ + fun topLogprobs(topLogprobs: Long?) = topLogprobs(JsonField.ofNullable(topLogprobs)) + + /** + * Alias for [Builder.topLogprobs]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun topLogprobs(topLogprobs: Long) = topLogprobs(topLogprobs as Long?) + + /** Alias for calling [Builder.topLogprobs] with `topLogprobs.orElse(null)`. */ + fun topLogprobs(topLogprobs: Optional) = topLogprobs(topLogprobs.getOrNull()) + + /** + * Sets [Builder.topLogprobs] to an arbitrary JSON value. + * + * You should usually call [Builder.topLogprobs] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun topLogprobs(topLogprobs: JsonField) = apply { this.topLogprobs = topLogprobs } + + /** + * An alternative to sampling with temperature, called nucleus sampling, where the model + * considers the results of the tokens with top_p probability mass. So 0.1 means only + * the tokens comprising the top 10% probability mass are considered. + * + * We generally recommend altering this or `temperature` but not both. + */ + fun topP(topP: Double?) = topP(JsonField.ofNullable(topP)) + + /** + * Alias for [Builder.topP]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun topP(topP: Double) = topP(topP as Double?) + + /** Alias for calling [Builder.topP] with `topP.orElse(null)`. */ + fun topP(topP: Optional) = topP(topP.getOrNull()) + + /** + * Sets [Builder.topP] to an arbitrary JSON value. + * + * You should usually call [Builder.topP] with a well-typed [Double] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun topP(topP: JsonField) = apply { this.topP = topP } + + /** + * The truncation strategy to use for the model response. + * - `auto`: If the input to this Response exceeds the model's context window size, the + * model will truncate the response to fit the context window by dropping items from + * the beginning of the conversation. + * - `disabled` (default): If the input size will exceed the context window size for a + * model, the request will fail with a 400 error. + */ + @Deprecated("deprecated") + fun truncation(truncation: Truncation?) = truncation(JsonField.ofNullable(truncation)) + + /** Alias for calling [Builder.truncation] with `truncation.orElse(null)`. */ + @Deprecated("deprecated") + fun truncation(truncation: Optional) = truncation(truncation.getOrNull()) + + /** + * Sets [Builder.truncation] to an arbitrary JSON value. + * + * You should usually call [Builder.truncation] with a well-typed [Truncation] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + @Deprecated("deprecated") + fun truncation(truncation: JsonField) = apply { + this.truncation = truncation } + /** + * This field is being replaced by `safety_identifier` and `prompt_cache_key`. Use + * `prompt_cache_key` instead to maintain caching optimizations. A stable identifier for + * your end-users. Used to boost cache hit rates by better bucketing similar requests + * and to help OpenAI detect and prevent abuse. + * [Learn more](https://platform.openai.com/docs/guides/safety-best-practices#safety-identifiers). + */ + @Deprecated("deprecated") fun user(user: String) = user(JsonField.of(user)) + + /** + * Sets [Builder.user] to an arbitrary JSON value. + * + * You should usually call [Builder.user] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + @Deprecated("deprecated") fun user(user: JsonField) = apply { this.user = user } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -2863,11 +2393,47 @@ private constructor( } /** - * Returns an immutable instance of [Metadata]. + * Returns an immutable instance of [ResponseCreate]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + fun build(): ResponseCreate = + ResponseCreate( + type, + background, + (contextManagement ?: JsonMissing.of()).map { it.toImmutable() }, + conversation, + (include ?: JsonMissing.of()).map { it.toImmutable() }, + input, + instructions, + maxOutputTokens, + maxToolCalls, + metadata, + model, + moderation, + parallelToolCalls, + previousResponseId, + prompt, + promptCacheKey, + promptCacheOptions, + promptCacheRetention, + reasoning, + safetyIdentifier, + serviceTier, + store, + stream, + streamId, + streamOptions, + temperature, + text, + toolChoice, + (tools ?: JsonMissing.of()).map { it.toImmutable() }, + topLogprobs, + topP, + truncation, + user, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -2881,11 +2447,48 @@ private constructor( * @throws OpenAIInvalidDataException if any value type in this object doesn't match its * expected type. */ - fun validate(): Metadata = apply { + fun validate(): ResponseCreate = apply { if (validated) { return@apply } + _type().let { + if (it != JsonValue.from("response.create")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + background() + contextManagement().ifPresent { it.forEach { it.validate() } } + conversation().ifPresent { it.validate() } + include().ifPresent { it.forEach { it.validate() } } + input().ifPresent { it.validate() } + instructions() + maxOutputTokens() + maxToolCalls() + metadata().ifPresent { it.validate() } + model().ifPresent { it.validate() } + moderation().ifPresent { it.validate() } + parallelToolCalls() + previousResponseId() + prompt().ifPresent { it.validate() } + promptCacheKey() + promptCacheOptions().ifPresent { it.validate() } + promptCacheRetention().ifPresent { it.validate() } + reasoning().ifPresent { it.validate() } + safetyIdentifier() + serviceTier().ifPresent { it.validate() } + store() + stream() + streamId() + streamOptions().ifPresent { it.validate() } + temperature() + text().ifPresent { it.validate() } + toolChoice().ifPresent { it.validate() } + tools().ifPresent { it.forEach { it.validate() } } + topLogprobs() + topP() + truncation().ifPresent { it.validate() } + user() validated = true } @@ -2905,259 +2508,90 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } + type.let { if (it == JsonValue.from("response.create")) 1 else 0 } + + (if (background.asKnown().isPresent) 1 else 0) + + (contextManagement.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (conversation.asKnown().getOrNull()?.validity() ?: 0) + + (include.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (input.asKnown().getOrNull()?.validity() ?: 0) + + (if (instructions.asKnown().isPresent) 1 else 0) + + (if (maxOutputTokens.asKnown().isPresent) 1 else 0) + + (if (maxToolCalls.asKnown().isPresent) 1 else 0) + + (metadata.asKnown().getOrNull()?.validity() ?: 0) + + (model.asKnown().getOrNull()?.validity() ?: 0) + + (moderation.asKnown().getOrNull()?.validity() ?: 0) + + (if (parallelToolCalls.asKnown().isPresent) 1 else 0) + + (if (previousResponseId.asKnown().isPresent) 1 else 0) + + (prompt.asKnown().getOrNull()?.validity() ?: 0) + + (if (promptCacheKey.asKnown().isPresent) 1 else 0) + + (promptCacheOptions.asKnown().getOrNull()?.validity() ?: 0) + + (promptCacheRetention.asKnown().getOrNull()?.validity() ?: 0) + + (reasoning.asKnown().getOrNull()?.validity() ?: 0) + + (if (safetyIdentifier.asKnown().isPresent) 1 else 0) + + (serviceTier.asKnown().getOrNull()?.validity() ?: 0) + + (if (store.asKnown().isPresent) 1 else 0) + + (if (stream.asKnown().isPresent) 1 else 0) + + (if (streamId.asKnown().isPresent) 1 else 0) + + (streamOptions.asKnown().getOrNull()?.validity() ?: 0) + + (if (temperature.asKnown().isPresent) 1 else 0) + + (text.asKnown().getOrNull()?.validity() ?: 0) + + (toolChoice.asKnown().getOrNull()?.validity() ?: 0) + + (tools.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (topLogprobs.asKnown().isPresent) 1 else 0) + + (if (topP.asKnown().isPresent) 1 else 0) + + (truncation.asKnown().getOrNull()?.validity() ?: 0) + + (if (user.asKnown().isPresent) 1 else 0) + + class ContextManagement + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val compactThreshold: JsonField, + private val additionalProperties: MutableMap, + ) { - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("compact_threshold") + @ExcludeMissing + compactThreshold: JsonField = JsonMissing.of(), + ) : this(type, compactThreshold, mutableMapOf()) - return other is Metadata && additionalProperties == other.additionalProperties - } + /** + * The context management entry type. Currently only 'compaction' is supported. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun type(): String = type.getRequired("type") - private val hashCode: Int by lazy { Objects.hash(additionalProperties) } + /** + * Token threshold at which compaction should be triggered for this entry. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun compactThreshold(): Optional = + compactThreshold.getOptional("compact_threshold") - override fun hashCode(): Int = hashCode + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type - override fun toString() = "Metadata{additionalProperties=$additionalProperties}" - } - - /** Configuration for running moderation on the input and output of this response. */ - class Moderation - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val model: JsonField, - private val policy: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), - @JsonProperty("policy") @ExcludeMissing policy: JsonField = JsonMissing.of(), - ) : this(model, policy, mutableMapOf()) - - /** - * The moderation model to use for moderated completions, e.g. 'omni-moderation-latest'. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun model(): String = model.getRequired("model") - - /** - * The policy to apply to moderated response input and output. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun policy(): Optional = policy.getOptional("policy") - - /** - * Returns the raw JSON value of [model]. - * - * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model - - /** - * Returns the raw JSON value of [policy]. - * - * Unlike [policy], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("policy") @ExcludeMissing fun _policy(): JsonField = policy - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Moderation]. - * - * The following fields are required: - * ```java - * .model() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [Moderation]. */ - class Builder internal constructor() { - - private var model: JsonField? = null - private var policy: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(moderation: Moderation) = apply { - model = moderation.model - policy = moderation.policy - additionalProperties = moderation.additionalProperties.toMutableMap() - } - - /** - * The moderation model to use for moderated completions, e.g. 'omni-moderation-latest'. - */ - fun model(model: String) = model(JsonField.of(model)) - - /** - * Sets [Builder.model] to an arbitrary JSON value. - * - * You should usually call [Builder.model] with a well-typed [String] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun model(model: JsonField) = apply { this.model = model } - - /** The policy to apply to moderated response input and output. */ - fun policy(policy: Policy?) = policy(JsonField.ofNullable(policy)) - - /** Alias for calling [Builder.policy] with `policy.orElse(null)`. */ - fun policy(policy: Optional) = policy(policy.getOrNull()) - - /** - * Sets [Builder.policy] to an arbitrary JSON value. - * - * You should usually call [Builder.policy] with a well-typed [Policy] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun policy(policy: JsonField) = apply { this.policy = policy } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [Moderation]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .model() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Moderation = - Moderation( - checkRequired("model", model), - policy, - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): Moderation = apply { - if (validated) { - return@apply - } - - model() - policy().ifPresent { it.validate() } - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (if (model.asKnown().isPresent) 1 else 0) + - (policy.asKnown().getOrNull()?.validity() ?: 0) - - /** The policy to apply to moderated response input and output. */ - class Policy - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val input: JsonField, - private val output: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator - private constructor( - @JsonProperty("input") @ExcludeMissing input: JsonField = JsonMissing.of(), - @JsonProperty("output") @ExcludeMissing output: JsonField = JsonMissing.of(), - ) : this(input, output, mutableMapOf()) - - /** - * The moderation policy for the response input. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun input(): Optional = input.getOptional("input") - - /** - * The moderation policy for the response output. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected value). - */ - fun output(): Optional = output.getOptional("output") - - /** - * Returns the raw JSON value of [input]. - * - * Unlike [input], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input - - /** - * Returns the raw JSON value of [output]. - * - * Unlike [output], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("output") @ExcludeMissing fun _output(): JsonField = output + /** + * Returns the raw JSON value of [compactThreshold]. + * + * Unlike [compactThreshold], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("compact_threshold") + @ExcludeMissing + fun _compactThreshold(): JsonField = compactThreshold @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { @@ -3173,53 +2607,72 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [Policy]. */ + /** + * Returns a mutable builder for constructing an instance of [ContextManagement]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ @JvmStatic fun builder() = Builder() } - /** A builder for [Policy]. */ + /** A builder for [ContextManagement]. */ class Builder internal constructor() { - private var input: JsonField = JsonMissing.of() - private var output: JsonField = JsonMissing.of() + private var type: JsonField? = null + private var compactThreshold: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(policy: Policy) = apply { - input = policy.input - output = policy.output - additionalProperties = policy.additionalProperties.toMutableMap() + internal fun from(contextManagement: ContextManagement) = apply { + type = contextManagement.type + compactThreshold = contextManagement.compactThreshold + additionalProperties = contextManagement.additionalProperties.toMutableMap() } - /** The moderation policy for the response input. */ - fun input(input: Input?) = input(JsonField.ofNullable(input)) - - /** Alias for calling [Builder.input] with `input.orElse(null)`. */ - fun input(input: Optional) = input(input.getOrNull()) + /** The context management entry type. Currently only 'compaction' is supported. */ + fun type(type: String) = type(JsonField.of(type)) /** - * Sets [Builder.input] to an arbitrary JSON value. + * Sets [Builder.type] to an arbitrary JSON value. * - * You should usually call [Builder.input] with a well-typed [Input] value instead. + * You should usually call [Builder.type] with a well-typed [String] value instead. * This method is primarily for setting the field to an undocumented or not yet * supported value. */ - fun input(input: JsonField) = apply { this.input = input } + fun type(type: JsonField) = apply { this.type = type } - /** The moderation policy for the response output. */ - fun output(output: Output?) = output(JsonField.ofNullable(output)) + /** Token threshold at which compaction should be triggered for this entry. */ + fun compactThreshold(compactThreshold: Long?) = + compactThreshold(JsonField.ofNullable(compactThreshold)) - /** Alias for calling [Builder.output] with `output.orElse(null)`. */ - fun output(output: Optional) = output(output.getOrNull()) + /** + * Alias for [Builder.compactThreshold]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun compactThreshold(compactThreshold: Long) = + compactThreshold(compactThreshold as Long?) + + /** + * Alias for calling [Builder.compactThreshold] with + * `compactThreshold.orElse(null)`. + */ + fun compactThreshold(compactThreshold: Optional) = + compactThreshold(compactThreshold.getOrNull()) /** - * Sets [Builder.output] to an arbitrary JSON value. + * Sets [Builder.compactThreshold] to an arbitrary JSON value. * - * You should usually call [Builder.output] with a well-typed [Output] value + * You should usually call [Builder.compactThreshold] with a well-typed [Long] value * instead. This method is primarily for setting the field to an undocumented or not * yet supported value. */ - fun output(output: JsonField) = apply { this.output = output } + fun compactThreshold(compactThreshold: JsonField) = apply { + this.compactThreshold = compactThreshold + } fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() @@ -3244,11 +2697,23 @@ private constructor( } /** - * Returns an immutable instance of [Policy]. + * Returns an immutable instance of [ContextManagement]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ - fun build(): Policy = Policy(input, output, additionalProperties.toMutableMap()) + fun build(): ContextManagement = + ContextManagement( + checkRequired("type", type), + compactThreshold, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false @@ -3263,13 +2728,13 @@ private constructor( * @throws OpenAIInvalidDataException if any value type in this object doesn't match its * expected type. */ - fun validate(): Policy = apply { + fun validate(): ContextManagement = apply { if (validated) { return@apply } - input().ifPresent { it.validate() } - output().ifPresent { it.validate() } + type() + compactThreshold() validated = true } @@ -3289,961 +2754,789 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (input.asKnown().getOrNull()?.validity() ?: 0) + - (output.asKnown().getOrNull()?.validity() ?: 0) + (if (type.asKnown().isPresent) 1 else 0) + + (if (compactThreshold.asKnown().isPresent) 1 else 0) - /** The moderation policy for the response input. */ - class Input - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val mode: JsonField, - private val additionalProperties: MutableMap, - ) { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JsonCreator - private constructor( - @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of() - ) : this(mode, mutableMapOf()) + return other is ContextManagement && + type == other.type && + compactThreshold == other.compactThreshold && + additionalProperties == other.additionalProperties + } - /** - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). - */ - fun mode(): Mode = mode.getRequired("mode") + private val hashCode: Int by lazy { + Objects.hash(type, compactThreshold, additionalProperties) + } - /** - * Returns the raw JSON value of [mode]. - * - * Unlike [mode], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + override fun hashCode(): Int = hashCode - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + override fun toString() = + "ContextManagement{type=$type, compactThreshold=$compactThreshold, additionalProperties=$additionalProperties}" + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + /** + * The conversation that this response belongs to. Items from this conversation are + * prepended to `input_items` for this response request. Input items and output items from + * this response are automatically added to this conversation after this response completes. + */ + @JsonDeserialize(using = Conversation.Deserializer::class) + @JsonSerialize(using = Conversation.Serializer::class) + class Conversation + private constructor( + private val id: String? = null, + private val responseConversationParam: ResponseConversationParam? = null, + private val _json: JsonValue? = null, + ) { - fun toBuilder() = Builder().from(this) + /** The unique ID of the conversation. */ + fun id(): Optional = Optional.ofNullable(id) - companion object { + /** The conversation that this response belongs to. */ + fun responseConversationParam(): Optional = + Optional.ofNullable(responseConversationParam) - /** - * Returns a mutable builder for constructing an instance of [Input]. - * - * The following fields are required: - * ```java - * .mode() - * ``` - */ - @JvmStatic fun builder() = Builder() - } + fun isId(): Boolean = id != null - /** A builder for [Input]. */ - class Builder internal constructor() { + fun isResponseConversationParam(): Boolean = responseConversationParam != null - private var mode: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() + /** The unique ID of the conversation. */ + fun asId(): String = id.getOrThrow("id") - @JvmSynthetic - internal fun from(input: Input) = apply { - mode = input.mode - additionalProperties = input.additionalProperties.toMutableMap() - } + /** The conversation that this response belongs to. */ + fun asResponseConversationParam(): ResponseConversationParam = + responseConversationParam.getOrThrow("responseConversationParam") - fun mode(mode: Mode) = mode(JsonField.of(mode)) + fun _json(): Optional = Optional.ofNullable(_json) - /** - * Sets [Builder.mode] to an arbitrary JSON value. - * - * You should usually call [Builder.mode] with a well-typed [Mode] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun mode(mode: JsonField) = apply { this.mode = mode } + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, + * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this + * version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = conversation.accept(new Conversation.Visitor>() { + * @Override + * public Optional visitId(String id) { + * return Optional.of(id.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + id != null -> visitor.visitId(id) + responseConversationParam != null -> + visitor.visitResponseConversationParam(responseConversationParam) + else -> visitor.unknown(_json) + } - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + private var validated: Boolean = false - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Conversation = apply { + if (validated) { + return@apply + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + accept( + object : Visitor { + override fun visitId(id: String) {} - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + override fun visitResponseConversationParam( + responseConversationParam: ResponseConversationParam + ) { + responseConversationParam.validate() + } } + ) + validated = true + } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitId(id: String) = 1 + + override fun visitResponseConversationParam( + responseConversationParam: ResponseConversationParam + ) = responseConversationParam.validity() + + override fun unknown(json: JsonValue?) = 0 } + ) - /** - * Returns an immutable instance of [Input]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .mode() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Input = - Input(checkRequired("mode", mode), additionalProperties.toMutableMap()) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - private var validated: Boolean = false + return other is Conversation && + id == other.id && + responseConversationParam == other.responseConversationParam + } - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing - * fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match - * its expected type. - */ - fun validate(): Input = apply { - if (validated) { - return@apply - } + override fun hashCode(): Int = Objects.hash(id, responseConversationParam) - mode().validate() - validated = true + override fun toString(): String = + when { + id != null -> "Conversation{id=$id}" + responseConversationParam != null -> + "Conversation{responseConversationParam=$responseConversationParam}" + _json != null -> "Conversation{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Conversation") } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + companion object { - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = (mode.asKnown().getOrNull()?.validity() ?: 0) + /** The unique ID of the conversation. */ + @JvmStatic fun ofId(id: String) = Conversation(id = id) - class Mode @JsonCreator private constructor(private val value: JsonField) : - Enum { + /** The conversation that this response belongs to. */ + @JvmStatic + fun ofResponseConversationParam( + responseConversationParam: ResponseConversationParam + ) = Conversation(responseConversationParam = responseConversationParam) + } - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value + /** + * An interface that defines how to map each variant of [Conversation] to a value of + * type [T]. + */ + interface Visitor { - companion object { + /** The unique ID of the conversation. */ + fun visitId(id: String): T - @JvmField val SCORE = of("score") + /** The conversation that this response belongs to. */ + fun visitResponseConversationParam( + responseConversationParam: ResponseConversationParam + ): T - @JvmField val BLOCK = of("block") + /** + * Maps an unknown variant of [Conversation] to a value of type [T]. + * + * An instance of [Conversation] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the + * SDK is on an older version than the API, then the API may respond with new + * variants that the SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Conversation: $json") + } + } - @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) + internal class Deserializer : BaseDeserializer(Conversation::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Conversation { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { + Conversation(responseConversationParam = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Conversation(id = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> Conversation(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() } + } + } - /** An enum containing [Mode]'s known values. */ - enum class Known { - SCORE, - BLOCK, + internal class Serializer : BaseSerializer(Conversation::class) { + + override fun serialize( + value: Conversation, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.id != null -> generator.writeObject(value.id) + value.responseConversationParam != null -> + generator.writeObject(value.responseConversationParam) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Conversation") } + } + } + } - /** - * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Mode] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - SCORE, - BLOCK, - /** - * An enum member indicating that [Mode] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } + /** + * Text, image, or file inputs to the model, used to generate a response. + * + * Learn more: + * - [Text inputs and outputs](https://platform.openai.com/docs/guides/text) + * - [Image inputs](https://platform.openai.com/docs/guides/images) + * - [File inputs](https://platform.openai.com/docs/guides/pdf-files) + * - [Conversation state](https://platform.openai.com/docs/guides/conversation-state) + * - [Function calling](https://platform.openai.com/docs/guides/function-calling) + */ + @JsonDeserialize(using = Input.Deserializer::class) + @JsonSerialize(using = Input.Serializer::class) + class Input + private constructor( + private val text: String? = null, + private val response: List? = null, + private val _json: JsonValue? = null, + ) { - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - SCORE -> Value.SCORE - BLOCK -> Value.BLOCK - else -> Value._UNKNOWN - } + /** A text input to the model, equivalent to a text input with the `user` role. */ + fun text(): Optional = Optional.ofNullable(text) - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - SCORE -> Known.SCORE - BLOCK -> Known.BLOCK - else -> throw OpenAIInvalidDataException("Unknown Mode: $value") - } + /** + * A list of one or many input items to the model, containing different content types. + */ + fun response(): Optional> = Optional.ofNullable(response) - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } + fun isText(): Boolean = text != null - private var validated: Boolean = false + fun isResponse(): Boolean = response != null - /** - * Validates that the types of all values in this object match their expected - * types recursively. - * - * This method is _not_ forwards compatible with new types from the API for - * existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't - * match its expected type. - */ - fun validate(): Mode = apply { - if (validated) { - return@apply - } + /** A text input to the model, equivalent to a text input with the `user` role. */ + fun asText(): String = text.getOrThrow("text") - known() - validated = true - } + /** + * A list of one or many input items to the model, containing different content types. + */ + fun asResponse(): List = response.getOrThrow("response") - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + fun _json(): Optional = Optional.ofNullable(_json) - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, + * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this + * version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = input.accept(new Input.Visitor>() { + * @Override + * public Optional visitText(String text) { + * return Optional.of(text.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + text != null -> visitor.visitText(text) + response != null -> visitor.visitResponse(response) + else -> visitor.unknown(_json) + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + private var validated: Boolean = false - return other is Mode && value == other.value - } + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Input = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitText(text: String) {} - override fun hashCode() = value.hashCode() + override fun visitResponse(response: List) { + response.forEach { it.validate() } + } + } + ) + validated = true + } - override fun toString() = value.toString() + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitText(text: String) = 1 + + override fun visitResponse(response: List) = + response.sumOf { it.validity().toInt() } + + override fun unknown(json: JsonValue?) = 0 } + ) - return other is Input && - mode == other.mode && - additionalProperties == other.additionalProperties + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - private val hashCode: Int by lazy { Objects.hash(mode, additionalProperties) } + return other is Input && text == other.text && response == other.response + } - override fun hashCode(): Int = hashCode + override fun hashCode(): Int = Objects.hash(text, response) - override fun toString() = - "Input{mode=$mode, additionalProperties=$additionalProperties}" - } + override fun toString(): String = + when { + text != null -> "Input{text=$text}" + response != null -> "Input{response=$response}" + _json != null -> "Input{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Input") + } - /** The moderation policy for the response output. */ - class Output - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val mode: JsonField, - private val additionalProperties: MutableMap, - ) { + companion object { - @JsonCreator - private constructor( - @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of() - ) : this(mode, mutableMapOf()) + /** A text input to the model, equivalent to a text input with the `user` role. */ + @JvmStatic fun ofText(text: String) = Input(text = text) /** - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected - * value). + * A list of one or many input items to the model, containing different content + * types. */ - fun mode(): Mode = mode.getRequired("mode") + @JvmStatic + fun ofResponse(response: List) = + Input(response = response.toImmutable()) + } + + /** + * An interface that defines how to map each variant of [Input] to a value of type [T]. + */ + interface Visitor { + + /** A text input to the model, equivalent to a text input with the `user` role. */ + fun visitText(text: String): T /** - * Returns the raw JSON value of [mode]. - * - * Unlike [mode], this method doesn't throw if the JSON field has an unexpected - * type. + * A list of one or many input items to the model, containing different content + * types. */ - @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + fun visitResponse(response: List): T - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) + /** + * Maps an unknown variant of [Input] to a value of type [T]. + * + * An instance of [Input] can contain an unknown variant if it was deserialized from + * data that doesn't match any known variant. For example, if the SDK is on an older + * version than the API, then the API may respond with new variants that the SDK is + * unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown Input: $json") } + } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [Output]. - * - * The following fields are required: - * ```java - * .mode() - * ``` - */ - @JvmStatic fun builder() = Builder() + internal class Deserializer : BaseDeserializer(Input::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Input { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Input(text = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef>()) + ?.let { Input(response = it, _json = json) }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> Input(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } } + } - /** A builder for [Output]. */ - class Builder internal constructor() { - - private var mode: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(output: Output) = apply { - mode = output.mode - additionalProperties = output.additionalProperties.toMutableMap() + internal class Serializer : BaseSerializer(Input::class) { + + override fun serialize( + value: Input, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.text != null -> generator.writeObject(value.text) + value.response != null -> generator.writeObject(value.response) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Input") } + } + } + } - fun mode(mode: Mode) = mode(JsonField.of(mode)) + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful for + * storing additional information about the object in a structured format, and querying for + * objects via API or the dashboard. + * + * Keys are strings with a maximum length of 64 characters. Values are strings with a + * maximum length of 512 characters. + */ + class Metadata + @JsonCreator + private constructor( + @com.fasterxml.jackson.annotation.JsonValue + private val additionalProperties: Map + ) { - /** - * Sets [Builder.mode] to an arbitrary JSON value. - * - * You should usually call [Builder.mode] with a well-typed [Mode] value - * instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. - */ - fun mode(mode: JsonField) = apply { this.mode = mode } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = additionalProperties - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun toBuilder() = Builder().from(this) - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + companion object { - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** Returns a mutable builder for constructing an instance of [Metadata]. */ + @JvmStatic fun builder() = Builder() + } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + /** A builder for [Metadata]. */ + class Builder internal constructor() { - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Returns an immutable instance of [Output]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .mode() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): Output = - Output(checkRequired("mode", mode), additionalProperties.toMutableMap()) + @JvmSynthetic + internal fun from(metadata: Metadata) = apply { + additionalProperties = metadata.additionalProperties.toMutableMap() } - private var validated: Boolean = false + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing - * fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match - * its expected type. - */ - fun validate(): Output = apply { - if (validated) { - return@apply + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) } - mode().validate() - validated = true + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } /** - * Returns a score indicating how many valid values are contained in this object - * recursively. + * Returns an immutable instance of [Metadata]. * - * Used for best match union deserialization. + * Further updates to this [Builder] will not mutate the returned instance. */ - @JvmSynthetic - internal fun validity(): Int = (mode.asKnown().getOrNull()?.validity() ?: 0) - - class Mode @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that - * doesn't match any known member, and you want to know that value. For example, - * if the SDK is on an older version than the API, then the API may respond with - * new members that the SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue - fun _value(): JsonField = value - - companion object { - - @JvmField val SCORE = of("score") - - @JvmField val BLOCK = of("block") - - @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) - } - - /** An enum containing [Mode]'s known values. */ - enum class Known { - SCORE, - BLOCK, - } - - /** - * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Mode] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For - * example, if the SDK is on an older version than the API, then the API may - * respond with new members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - SCORE, - BLOCK, - /** - * An enum member indicating that [Mode] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or - * if you want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - SCORE -> Value.SCORE - BLOCK -> Value.BLOCK - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known - * and don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a - * known member. - */ - fun known(): Known = - when (this) { - SCORE -> Known.SCORE - BLOCK -> Known.BLOCK - else -> throw OpenAIInvalidDataException("Unknown Mode: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not - * have the expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } - - private var validated: Boolean = false - - /** - * Validates that the types of all values in this object match their expected - * types recursively. - * - * This method is _not_ forwards compatible with new types from the API for - * existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't - * match its expected type. - */ - fun validate(): Mode = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Mode && value == other.value - } + fun build(): Metadata = Metadata(additionalProperties.toImmutable()) + } - override fun hashCode() = value.hashCode() + private var validated: Boolean = false - override fun toString() = value.toString() + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Metadata = apply { + if (validated) { + return@apply } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + validated = true + } - return other is Output && - mode == other.mode && - additionalProperties == other.additionalProperties + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false } - private val hashCode: Int by lazy { Objects.hash(mode, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Output{mode=$mode, additionalProperties=$additionalProperties}" - } + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + additionalProperties.count { (_, value) -> !value.isNull() && !value.isMissing() } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Policy && - input == other.input && - output == other.output && - additionalProperties == other.additionalProperties + return other is Metadata && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(input, output, additionalProperties) } + private val hashCode: Int by lazy { Objects.hash(additionalProperties) } override fun hashCode(): Int = hashCode - override fun toString() = - "Policy{input=$input, output=$output, additionalProperties=$additionalProperties}" + override fun toString() = "Metadata{additionalProperties=$additionalProperties}" } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is Moderation && - model == other.model && - policy == other.policy && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(model, policy, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "Moderation{model=$model, policy=$policy, additionalProperties=$additionalProperties}" - } - - /** - * Options for prompt caching. Supported for `gpt-5.6` and later models. By default, OpenAI - * automatically chooses one implicit cache breakpoint. You can add explicit breakpoints to - * content blocks with `prompt_cache_breakpoint`. Each request can write up to four breakpoints. - * For cache matching, OpenAI considers up to the latest 80 breakpoints in the conversation, - * without a content-block lookback limit. Set `mode` to `explicit` to disable the implicit - * breakpoint. The `ttl` defaults to `30m`, which is currently the only supported value. See the - * [prompt caching guide](https://platform.openai.com/docs/guides/prompt-caching) for current - * details. - */ - class PromptCacheOptions - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val mode: JsonField, - private val ttl: JsonField, - private val additionalProperties: MutableMap, - ) { - - @JsonCreator + /** Configuration for running moderation on the input and output of this response. */ + class Moderation + @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), - @JsonProperty("ttl") @ExcludeMissing ttl: JsonField = JsonMissing.of(), - ) : this(mode, ttl, mutableMapOf()) - - /** - * Controls whether OpenAI automatically creates an implicit cache breakpoint. Defaults to - * `implicit`. With `implicit`, OpenAI creates one implicit breakpoint and writes up to the - * latest three explicit breakpoints in the request. With `explicit`, OpenAI does not create - * an implicit breakpoint and writes up to the latest four explicit breakpoints. If there - * are no explicit breakpoints, the request does not use prompt caching. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun mode(): Optional = mode.getOptional("mode") - - /** - * The minimum lifetime applied to every implicit and explicit cache breakpoint written by - * the request. Defaults to `30m`, which is currently the only supported value. The backend - * may retain cache entries for longer. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun ttl(): Optional = ttl.getOptional("ttl") - - /** - * Returns the raw JSON value of [mode]. - * - * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode - - /** - * Returns the raw JSON value of [ttl]. - * - * Unlike [ttl], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("ttl") @ExcludeMissing fun _ttl(): JsonField = ttl - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** Returns a mutable builder for constructing an instance of [PromptCacheOptions]. */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [PromptCacheOptions]. */ - class Builder internal constructor() { - - private var mode: JsonField = JsonMissing.of() - private var ttl: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + private val model: JsonField, + private val policy: JsonField, + private val additionalProperties: MutableMap, + ) { - @JvmSynthetic - internal fun from(promptCacheOptions: PromptCacheOptions) = apply { - mode = promptCacheOptions.mode - ttl = promptCacheOptions.ttl - additionalProperties = promptCacheOptions.additionalProperties.toMutableMap() - } + @JsonCreator + private constructor( + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("policy") @ExcludeMissing policy: JsonField = JsonMissing.of(), + ) : this(model, policy, mutableMapOf()) /** - * Controls whether OpenAI automatically creates an implicit cache breakpoint. Defaults - * to `implicit`. With `implicit`, OpenAI creates one implicit breakpoint and writes up - * to the latest three explicit breakpoints in the request. With `explicit`, OpenAI does - * not create an implicit breakpoint and writes up to the latest four explicit - * breakpoints. If there are no explicit breakpoints, the request does not use prompt - * caching. + * The moderation model to use for moderated completions, e.g. 'omni-moderation-latest'. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). */ - fun mode(mode: Mode) = mode(JsonField.of(mode)) + fun model(): String = model.getRequired("model") /** - * Sets [Builder.mode] to an arbitrary JSON value. + * The policy to apply to moderated response input and output. * - * You should usually call [Builder.mode] with a well-typed [Mode] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun mode(mode: JsonField) = apply { this.mode = mode } + fun policy(): Optional = policy.getOptional("policy") /** - * The minimum lifetime applied to every implicit and explicit cache breakpoint written - * by the request. Defaults to `30m`, which is currently the only supported value. The - * backend may retain cache entries for longer. + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. */ - fun ttl(ttl: Ttl) = ttl(JsonField.of(ttl)) + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model /** - * Sets [Builder.ttl] to an arbitrary JSON value. + * Returns the raw JSON value of [policy]. * - * You should usually call [Builder.ttl] with a well-typed [Ttl] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported - * value. + * Unlike [policy], this method doesn't throw if the JSON field has an unexpected type. */ - fun ttl(ttl: JsonField) = apply { this.ttl = ttl } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + @JsonProperty("policy") @ExcludeMissing fun _policy(): JsonField = policy - fun putAdditionalProperty(key: String, value: JsonValue) = apply { + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) } - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - /** - * Returns an immutable instance of [PromptCacheOptions]. - * - * Further updates to this [Builder] will not mutate the returned instance. - */ - fun build(): PromptCacheOptions = - PromptCacheOptions(mode, ttl, additionalProperties.toMutableMap()) - } + fun toBuilder() = Builder().from(this) - private var validated: Boolean = false + companion object { - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): PromptCacheOptions = apply { - if (validated) { - return@apply + /** + * Returns a mutable builder for constructing an instance of [Moderation]. + * + * The following fields are required: + * ```java + * .model() + * ``` + */ + @JvmStatic fun builder() = Builder() } - mode().ifPresent { it.validate() } - ttl().ifPresent { it.validate() } - validated = true - } + /** A builder for [Moderation]. */ + class Builder internal constructor() { - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } + private var model: JsonField? = null + private var policy: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (mode.asKnown().getOrNull()?.validity() ?: 0) + - (ttl.asKnown().getOrNull()?.validity() ?: 0) + @JvmSynthetic + internal fun from(moderation: Moderation) = apply { + model = moderation.model + policy = moderation.policy + additionalProperties = moderation.additionalProperties.toMutableMap() + } - /** - * Controls whether OpenAI automatically creates an implicit cache breakpoint. Defaults to - * `implicit`. With `implicit`, OpenAI creates one implicit breakpoint and writes up to the - * latest three explicit breakpoints in the request. With `explicit`, OpenAI does not create - * an implicit breakpoint and writes up to the latest four explicit breakpoints. If there - * are no explicit breakpoints, the request does not use prompt caching. - */ - class Mode @JsonCreator private constructor(private val value: JsonField) : Enum { + /** + * The moderation model to use for moderated completions, e.g. + * 'omni-moderation-latest'. + */ + fun model(model: String) = model(JsonField.of(model)) - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is - * on an older version than the API, then the API may respond with new members that the - * SDK is unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun model(model: JsonField) = apply { this.model = model } - companion object { + /** The policy to apply to moderated response input and output. */ + fun policy(policy: Policy?) = policy(JsonField.ofNullable(policy)) - @JvmField val IMPLICIT = of("implicit") + /** Alias for calling [Builder.policy] with `policy.orElse(null)`. */ + fun policy(policy: Optional) = policy(policy.getOrNull()) - @JvmField val EXPLICIT = of("explicit") + /** + * Sets [Builder.policy] to an arbitrary JSON value. + * + * You should usually call [Builder.policy] with a well-typed [Policy] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun policy(policy: JsonField) = apply { this.policy = policy } - @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) - } + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } - /** An enum containing [Mode]'s known values. */ - enum class Known { - IMPLICIT, - EXPLICIT, - } + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - /** - * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Mode] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if - * the SDK is on an older version than the API, then the API may respond with new - * members that the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - IMPLICIT, - EXPLICIT, - /** An enum member indicating that [Mode] was instantiated with an unknown value. */ - _UNKNOWN, - } + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } - /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you - * want to throw for the unknown case. - */ - fun value(): Value = - when (this) { - IMPLICIT -> Value.IMPLICIT - EXPLICIT -> Value.EXPLICIT - else -> Value._UNKNOWN + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) } - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and - * don't want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - IMPLICIT -> Known.IMPLICIT - EXPLICIT -> Known.EXPLICIT - else -> throw OpenAIInvalidDataException("Unknown Mode: $value") + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) } - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { - OpenAIInvalidDataException("Value is not a String") - } + /** + * Returns an immutable instance of [Moderation]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .model() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Moderation = + Moderation( + checkRequired("model", model), + policy, + additionalProperties.toMutableMap(), + ) + } private var validated: Boolean = false @@ -4257,12 +3550,13 @@ private constructor( * @throws OpenAIInvalidDataException if any value type in this object doesn't match its * expected type. */ - fun validate(): Mode = apply { + fun validate(): Moderation = apply { if (validated) { return@apply } - known() + model() + policy().ifPresent { it.validate() } validated = true } @@ -4280,27 +3574,1400 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JvmSynthetic + internal fun validity(): Int = + (if (model.asKnown().isPresent) 1 else 0) + + (policy.asKnown().getOrNull()?.validity() ?: 0) - return other is Mode && value == other.value - } + /** The policy to apply to moderated response input and output. */ + class Policy + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val input: JsonField, + private val output: JsonField, + private val additionalProperties: MutableMap, + ) { - override fun hashCode() = value.hashCode() + @JsonCreator + private constructor( + @JsonProperty("input") + @ExcludeMissing + input: JsonField = JsonMissing.of(), + @JsonProperty("output") + @ExcludeMissing + output: JsonField = JsonMissing.of(), + ) : this(input, output, mutableMapOf()) + + /** + * The moderation policy for the response input. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun input(): Optional = input.getOptional("input") + + /** + * The moderation policy for the response output. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun output(): Optional = output.getOptional("output") + + /** + * Returns the raw JSON value of [input]. + * + * Unlike [input], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("input") @ExcludeMissing fun _input(): JsonField = input + + /** + * Returns the raw JSON value of [output]. + * + * Unlike [output], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("output") @ExcludeMissing fun _output(): JsonField = output + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Policy]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Policy]. */ + class Builder internal constructor() { + + private var input: JsonField = JsonMissing.of() + private var output: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(policy: Policy) = apply { + input = policy.input + output = policy.output + additionalProperties = policy.additionalProperties.toMutableMap() + } + + /** The moderation policy for the response input. */ + fun input(input: Input?) = input(JsonField.ofNullable(input)) + + /** Alias for calling [Builder.input] with `input.orElse(null)`. */ + fun input(input: Optional) = input(input.getOrNull()) + + /** + * Sets [Builder.input] to an arbitrary JSON value. + * + * You should usually call [Builder.input] with a well-typed [Input] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun input(input: JsonField) = apply { this.input = input } + + /** The moderation policy for the response output. */ + fun output(output: Output?) = output(JsonField.ofNullable(output)) + + /** Alias for calling [Builder.output] with `output.orElse(null)`. */ + fun output(output: Optional) = output(output.getOrNull()) + + /** + * Sets [Builder.output] to an arbitrary JSON value. + * + * You should usually call [Builder.output] with a well-typed [Output] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun output(output: JsonField) = apply { this.output = output } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Policy]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Policy = Policy(input, output, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Policy = apply { + if (validated) { + return@apply + } + + input().ifPresent { it.validate() } + output().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (input.asKnown().getOrNull()?.validity() ?: 0) + + (output.asKnown().getOrNull()?.validity() ?: 0) + + /** The moderation policy for the response input. */ + class Input + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val mode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("mode") + @ExcludeMissing + mode: JsonField = JsonMissing.of() + ) : this(mode, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun mode(): Mode = mode.getRequired("mode") + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Input]. + * + * The following fields are required: + * ```java + * .mode() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Input]. */ + class Builder internal constructor() { + + private var mode: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(input: Input) = apply { + mode = input.mode + additionalProperties = input.additionalProperties.toMutableMap() + } + + fun mode(mode: Mode) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [Mode] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Input]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .mode() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Input = + Input(checkRequired("mode", mode), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Input = apply { + if (validated) { + return@apply + } + + mode().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (mode.asKnown().getOrNull()?.validity() ?: 0) + + class Mode + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val SCORE = of("score") + + @JvmField val BLOCK = of("block") + + @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) + } + + /** An enum containing [Mode]'s known values. */ + enum class Known { + SCORE, + BLOCK, + } + + /** + * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Mode] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + SCORE, + BLOCK, + /** + * An enum member indicating that [Mode] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + SCORE -> Value.SCORE + BLOCK -> Value.BLOCK + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + SCORE -> Known.SCORE + BLOCK -> Known.BLOCK + else -> throw OpenAIInvalidDataException("Unknown Mode: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their + * expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object + * doesn't match its expected type. + */ + fun validate(): Mode = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this + * object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Mode && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Input && + mode == other.mode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(mode, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Input{mode=$mode, additionalProperties=$additionalProperties}" + } + + /** The moderation policy for the response output. */ + class Output + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val mode: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("mode") + @ExcludeMissing + mode: JsonField = JsonMissing.of() + ) : this(mode, mutableMapOf()) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun mode(): Mode = mode.getRequired("mode") + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Output]. + * + * The following fields are required: + * ```java + * .mode() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Output]. */ + class Builder internal constructor() { + + private var mode: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(output: Output) = apply { + mode = output.mode + additionalProperties = output.additionalProperties.toMutableMap() + } + + fun mode(mode: Mode) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [Mode] value + * instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Output]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .mode() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Output = + Output(checkRequired("mode", mode), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Output = apply { + if (validated) { + return@apply + } + + mode().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (mode.asKnown().getOrNull()?.validity() ?: 0) + + class Mode + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data + * that doesn't match any known member, and you want to know that value. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField val SCORE = of("score") + + @JvmField val BLOCK = of("block") + + @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) + } + + /** An enum containing [Mode]'s known values. */ + enum class Known { + SCORE, + BLOCK, + } + + /** + * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [Mode] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API + * may respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + SCORE, + BLOCK, + /** + * An enum member indicating that [Mode] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always + * known or if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + SCORE -> Value.SCORE + BLOCK -> Value.BLOCK + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always + * known and don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a + * not a known member. + */ + fun known(): Known = + when (this) { + SCORE -> Known.SCORE + BLOCK -> Known.BLOCK + else -> throw OpenAIInvalidDataException("Unknown Mode: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily + * for debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does + * not have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their + * expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object + * doesn't match its expected type. + */ + fun validate(): Mode = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this + * object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Mode && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Output && + mode == other.mode && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(mode, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Output{mode=$mode, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Policy && + input == other.input && + output == other.output && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(input, output, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Policy{input=$input, output=$output, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Moderation && + model == other.model && + policy == other.policy && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(model, policy, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Moderation{model=$model, policy=$policy, additionalProperties=$additionalProperties}" + } + + /** + * Options for prompt caching. Supported for `gpt-5.6` and later models. By default, OpenAI + * automatically chooses one implicit cache breakpoint. You can add explicit breakpoints to + * content blocks with `prompt_cache_breakpoint`. Each request can write up to four + * breakpoints. For cache matching, OpenAI considers up to the latest 80 breakpoints in the + * conversation, without a content-block lookback limit. Set `mode` to `explicit` to disable + * the implicit breakpoint. The `ttl` defaults to `30m`, which is currently the only + * supported value. See the + * [prompt caching guide](https://platform.openai.com/docs/guides/prompt-caching) for + * current details. + */ + class PromptCacheOptions + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val mode: JsonField, + private val ttl: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), + @JsonProperty("ttl") @ExcludeMissing ttl: JsonField = JsonMissing.of(), + ) : this(mode, ttl, mutableMapOf()) + + /** + * Controls whether OpenAI automatically creates an implicit cache breakpoint. Defaults + * to `implicit`. With `implicit`, OpenAI creates one implicit breakpoint and writes up + * to the latest three explicit breakpoints in the request. With `explicit`, OpenAI does + * not create an implicit breakpoint and writes up to the latest four explicit + * breakpoints. If there are no explicit breakpoints, the request does not use prompt + * caching. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun mode(): Optional = mode.getOptional("mode") + + /** + * The minimum lifetime applied to every implicit and explicit cache breakpoint written + * by the request. Defaults to `30m`, which is currently the only supported value. The + * backend may retain cache entries for longer. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun ttl(): Optional = ttl.getOptional("ttl") + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [ttl]. + * + * Unlike [ttl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("ttl") @ExcludeMissing fun _ttl(): JsonField = ttl + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PromptCacheOptions]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PromptCacheOptions]. */ + class Builder internal constructor() { + + private var mode: JsonField = JsonMissing.of() + private var ttl: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(promptCacheOptions: PromptCacheOptions) = apply { + mode = promptCacheOptions.mode + ttl = promptCacheOptions.ttl + additionalProperties = promptCacheOptions.additionalProperties.toMutableMap() + } + + /** + * Controls whether OpenAI automatically creates an implicit cache breakpoint. + * Defaults to `implicit`. With `implicit`, OpenAI creates one implicit breakpoint + * and writes up to the latest three explicit breakpoints in the request. With + * `explicit`, OpenAI does not create an implicit breakpoint and writes up to the + * latest four explicit breakpoints. If there are no explicit breakpoints, the + * request does not use prompt caching. + */ + fun mode(mode: Mode) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [Mode] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** + * The minimum lifetime applied to every implicit and explicit cache breakpoint + * written by the request. Defaults to `30m`, which is currently the only supported + * value. The backend may retain cache entries for longer. + */ + fun ttl(ttl: Ttl) = ttl(JsonField.of(ttl)) + + /** + * Sets [Builder.ttl] to an arbitrary JSON value. + * + * You should usually call [Builder.ttl] with a well-typed [Ttl] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun ttl(ttl: JsonField) = apply { this.ttl = ttl } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PromptCacheOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): PromptCacheOptions = + PromptCacheOptions(mode, ttl, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): PromptCacheOptions = apply { + if (validated) { + return@apply + } + + mode().ifPresent { it.validate() } + ttl().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (mode.asKnown().getOrNull()?.validity() ?: 0) + + (ttl.asKnown().getOrNull()?.validity() ?: 0) + + /** + * Controls whether OpenAI automatically creates an implicit cache breakpoint. Defaults + * to `implicit`. With `implicit`, OpenAI creates one implicit breakpoint and writes up + * to the latest three explicit breakpoints in the request. With `explicit`, OpenAI does + * not create an implicit breakpoint and writes up to the latest four explicit + * breakpoints. If there are no explicit breakpoints, the request does not use prompt + * caching. + */ + class Mode @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val IMPLICIT = of("implicit") + + @JvmField val EXPLICIT = of("explicit") + + @JvmStatic fun of(value: String) = Mode(JsonField.of(value)) + } + + /** An enum containing [Mode]'s known values. */ + enum class Known { + IMPLICIT, + EXPLICIT, + } + + /** + * An enum containing [Mode]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Mode] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + IMPLICIT, + EXPLICIT, + /** + * An enum member indicating that [Mode] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + IMPLICIT -> Value.IMPLICIT + EXPLICIT -> Value.EXPLICIT + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + IMPLICIT -> Known.IMPLICIT + EXPLICIT -> Known.EXPLICIT + else -> throw OpenAIInvalidDataException("Unknown Mode: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Mode = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Mode && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** + * The minimum lifetime applied to every implicit and explicit cache breakpoint written + * by the request. Defaults to `30m`, which is currently the only supported value. The + * backend may retain cache entries for longer. + */ + class Ttl @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val _30M = of("30m") + + @JvmStatic fun of(value: String) = Ttl(JsonField.of(value)) + } + + /** An enum containing [Ttl]'s known values. */ + enum class Known { + _30M + } + + /** + * An enum containing [Ttl]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Ttl] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + _30M, + /** + * An enum member indicating that [Ttl] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if + * you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + _30M -> Value._30M + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + _30M -> Known._30M + else -> throw OpenAIInvalidDataException("Unknown Ttl: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have + * the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Ttl = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Ttl && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - override fun toString() = value.toString() + return other is PromptCacheOptions && + mode == other.mode && + ttl == other.ttl && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(mode, ttl, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PromptCacheOptions{mode=$mode, ttl=$ttl, additionalProperties=$additionalProperties}" } /** - * The minimum lifetime applied to every implicit and explicit cache breakpoint written by - * the request. Defaults to `30m`, which is currently the only supported value. The backend - * may retain cache entries for longer. + * Deprecated. Use `prompt_cache_options.ttl` instead. + * + * The retention policy for the prompt cache. Set to `24h` to enable extended prompt + * caching, which keeps cached prefixes active for longer, up to a maximum of 24 hours. + * [Learn more](https://platform.openai.com/docs/guides/prompt-caching#prompt-cache-retention). + * This field expresses a maximum retention policy, while `prompt_cache_options.ttl` + * expresses a minimum cache lifetime. The two fields are independent and do not interact. + * For `gpt-5.5`, `gpt-5.5-pro`, and future models, only `24h` is supported. + * + * For older models that support both `in_memory` and `24h`, the default depends on your + * organization's data retention policy: + * - Organizations without ZDR enabled default to `24h`. + * - Organizations with ZDR enabled default to `in_memory` when `prompt_cache_retention` is + * not specified. */ - class Ttl @JsonCreator private constructor(private val value: JsonField) : Enum { + @Deprecated("deprecated") + class PromptCacheRetention + @JsonCreator + private constructor(private val value: JsonField) : Enum { /** * Returns this class instance's raw value. @@ -4314,28 +4981,37 @@ private constructor( companion object { - @JvmField val _30M = of("30m") + @JvmField val IN_MEMORY = of("in_memory") - @JvmStatic fun of(value: String) = Ttl(JsonField.of(value)) + @JvmField val _24H = of("24h") + + @JvmStatic fun of(value: String) = PromptCacheRetention(JsonField.of(value)) } - /** An enum containing [Ttl]'s known values. */ + /** An enum containing [PromptCacheRetention]'s known values. */ enum class Known { - _30M + IN_MEMORY, + _24H, } /** - * An enum containing [Ttl]'s known values, as well as an [_UNKNOWN] member. + * An enum containing [PromptCacheRetention]'s known values, as well as an [_UNKNOWN] + * member. * - * An instance of [Ttl] can contain an unknown value in a couple of cases: + * An instance of [PromptCacheRetention] can contain an unknown value in a couple of + * cases: * - It was deserialized from data that doesn't match any known member. For example, if * the SDK is on an older version than the API, then the API may respond with new * members that the SDK is unaware of. * - It was constructed with an arbitrary value using the [of] method. */ enum class Value { - _30M, - /** An enum member indicating that [Ttl] was instantiated with an unknown value. */ + IN_MEMORY, + _24H, + /** + * An enum member indicating that [PromptCacheRetention] was instantiated with an + * unknown value. + */ _UNKNOWN, } @@ -4348,7 +5024,8 @@ private constructor( */ fun value(): Value = when (this) { - _30M -> Value._30M + IN_MEMORY -> Value.IN_MEMORY + _24H -> Value._24H else -> Value._UNKNOWN } @@ -4363,8 +5040,9 @@ private constructor( */ fun known(): Known = when (this) { - _30M -> Known._30M - else -> throw OpenAIInvalidDataException("Unknown Ttl: $value") + IN_MEMORY -> Known.IN_MEMORY + _24H -> Known._24H + else -> throw OpenAIInvalidDataException("Unknown PromptCacheRetention: $value") } /** @@ -4393,7 +5071,7 @@ private constructor( * @throws OpenAIInvalidDataException if any value type in this object doesn't match its * expected type. */ - fun validate(): Ttl = apply { + fun validate(): PromptCacheRetention = apply { if (validated) { return@apply } @@ -4423,7 +5101,7 @@ private constructor( return true } - return other is Ttl && value == other.value + return other is PromptCacheRetention && value == other.value } override fun hashCode() = value.hashCode() @@ -4431,438 +5109,212 @@ private constructor( override fun toString() = value.toString() } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptCacheOptions && - mode == other.mode && - ttl == other.ttl && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(mode, ttl, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "PromptCacheOptions{mode=$mode, ttl=$ttl, additionalProperties=$additionalProperties}" - } - - /** - * Deprecated. Use `prompt_cache_options.ttl` instead. - * - * The retention policy for the prompt cache. Set to `24h` to enable extended prompt caching, - * which keeps cached prefixes active for longer, up to a maximum of 24 hours. - * [Learn more](https://platform.openai.com/docs/guides/prompt-caching#prompt-cache-retention). - * This field expresses a maximum retention policy, while `prompt_cache_options.ttl` expresses a - * minimum cache lifetime. The two fields are independent and do not interact. For `gpt-5.5`, - * `gpt-5.5-pro`, and future models, only `24h` is supported. - * - * For older models that support both `in_memory` and `24h`, the default depends on your - * organization's data retention policy: - * - Organizations without ZDR enabled default to `24h`. - * - Organizations with ZDR enabled default to `in_memory` when `prompt_cache_retention` is not - * specified. - */ - @Deprecated("deprecated") - class PromptCacheRetention - @JsonCreator - private constructor(private val value: JsonField) : Enum { - /** - * Returns this class instance's raw value. + * Specifies the processing type used for serving the request. + * - If set to 'auto', then the request will be processed with the service tier configured + * in the Project settings. Unless otherwise configured, the Project will use 'default'. + * - If set to 'default', then the request will be processed with the standard pricing and + * performance for the selected model. + * - If set to '[flex](https://platform.openai.com/docs/guides/flex-processing)', then the + * request will be processed with the Flex Processing service tier. + * - To opt-in to [Fast mode](/api/docs/guides/fast-mode) at the request level, include the + * `service_tier=fast` or `service_tier=priority` parameter for Responses or Chat + * Completions. The response will show `service_tier=priority` regardless of if you + * specify `service_tier=fast` or `priority` in your request. + * - If set to 'ultrafast', then the request will be processed with the access-controlled + * Ultrafast Processing service tier. This tier is currently available for `gpt-5.6-sol`; + * a response served through it will show `service_tier=ultrafast`. + * - When not set, the default behavior is 'auto'. * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. + * When the `service_tier` parameter is set, the response body will include the + * `service_tier` value based on the processing mode actually used to serve the request. + * This response value may be different from the value set in the parameter. */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val IN_MEMORY = of("in_memory") - - @JvmField val _24H = of("24h") + class ServiceTier @JsonCreator private constructor(private val value: JsonField) : + Enum { - @JvmStatic fun of(value: String) = PromptCacheRetention(JsonField.of(value)) - } - - /** An enum containing [PromptCacheRetention]'s known values. */ - enum class Known { - IN_MEMORY, - _24H, - } - - /** - * An enum containing [PromptCacheRetention]'s known values, as well as an [_UNKNOWN] - * member. - * - * An instance of [PromptCacheRetention] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - IN_MEMORY, - _24H, /** - * An enum member indicating that [PromptCacheRetention] was instantiated with an - * unknown value. + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - IN_MEMORY -> Value.IN_MEMORY - _24H -> Value._24H - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - IN_MEMORY -> Known.IN_MEMORY - _24H -> Known._24H - else -> throw OpenAIInvalidDataException("Unknown PromptCacheRetention: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } - - private var validated: Boolean = false - - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): PromptCacheRetention = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PromptCacheRetention && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - /** - * Specifies the processing type used for serving the request. - * - If set to 'auto', then the request will be processed with the service tier configured in - * the Project settings. Unless otherwise configured, the Project will use 'default'. - * - If set to 'default', then the request will be processed with the standard pricing and - * performance for the selected model. - * - If set to '[flex](https://platform.openai.com/docs/guides/flex-processing)', then the - * request will be processed with the Flex Processing service tier. - * - To opt-in to [Fast mode](/api/docs/guides/fast-mode) at the request level, include the - * `service_tier=fast` or `service_tier=priority` parameter for Responses or Chat Completions. - * The response will show `service_tier=priority` regardless of if you specify - * `service_tier=fast` or `priority` in your request. - * - If set to 'ultrafast', then the request will be processed with the access-controlled - * Ultrafast Processing service tier. This tier is currently available for `gpt-5.6-sol`; a - * response served through it will show `service_tier=ultrafast`. - * - When not set, the default behavior is 'auto'. - * - * When the `service_tier` parameter is set, the response body will include the `service_tier` - * value based on the processing mode actually used to serve the request. This response value - * may be different from the value set in the parameter. - */ - class ServiceTier @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val AUTO = of("auto") - - @JvmField val DEFAULT = of("default") - - @JvmField val FLEX = of("flex") - - @JvmField val SCALE = of("scale") - - @JvmField val PRIORITY = of("priority") - - @JvmField val FAST = of("fast") + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - @JvmField val ULTRAFAST = of("ultrafast") + companion object { - @JvmStatic fun of(value: String) = ServiceTier(JsonField.of(value)) - } + @JvmField val AUTO = of("auto") - /** An enum containing [ServiceTier]'s known values. */ - enum class Known { - AUTO, - DEFAULT, - FLEX, - SCALE, - PRIORITY, - FAST, - ULTRAFAST, - } + @JvmField val DEFAULT = of("default") - /** - * An enum containing [ServiceTier]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [ServiceTier] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - AUTO, - DEFAULT, - FLEX, - SCALE, - PRIORITY, - FAST, - ULTRAFAST, - /** - * An enum member indicating that [ServiceTier] was instantiated with an unknown value. - */ - _UNKNOWN, - } + @JvmField val FLEX = of("flex") - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - AUTO -> Value.AUTO - DEFAULT -> Value.DEFAULT - FLEX -> Value.FLEX - SCALE -> Value.SCALE - PRIORITY -> Value.PRIORITY - FAST -> Value.FAST - ULTRAFAST -> Value.ULTRAFAST - else -> Value._UNKNOWN - } + @JvmField val SCALE = of("scale") - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - AUTO -> Known.AUTO - DEFAULT -> Known.DEFAULT - FLEX -> Known.FLEX - SCALE -> Known.SCALE - PRIORITY -> Known.PRIORITY - FAST -> Known.FAST - ULTRAFAST -> Known.ULTRAFAST - else -> throw OpenAIInvalidDataException("Unknown ServiceTier: $value") - } + @JvmField val PRIORITY = of("priority") - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + @JvmField val FAST = of("fast") - private var validated: Boolean = false + @JvmField val ULTRAFAST = of("ultrafast") - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): ServiceTier = apply { - if (validated) { - return@apply + @JvmStatic fun of(value: String) = ServiceTier(JsonField.of(value)) } - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false + /** An enum containing [ServiceTier]'s known values. */ + enum class Known { + AUTO, + DEFAULT, + FLEX, + SCALE, + PRIORITY, + FAST, + ULTRAFAST, } - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** + * An enum containing [ServiceTier]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ServiceTier] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + AUTO, + DEFAULT, + FLEX, + SCALE, + PRIORITY, + FAST, + ULTRAFAST, + /** + * An enum member indicating that [ServiceTier] was instantiated with an unknown + * value. + */ + _UNKNOWN, } - return other is ServiceTier && value == other.value - } + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + AUTO -> Value.AUTO + DEFAULT -> Value.DEFAULT + FLEX -> Value.FLEX + SCALE -> Value.SCALE + PRIORITY -> Value.PRIORITY + FAST -> Value.FAST + ULTRAFAST -> Value.ULTRAFAST + else -> Value._UNKNOWN + } - override fun hashCode() = value.hashCode() + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + AUTO -> Known.AUTO + DEFAULT -> Known.DEFAULT + FLEX -> Known.FLEX + SCALE -> Known.SCALE + PRIORITY -> Known.PRIORITY + FAST -> Known.FAST + ULTRAFAST -> Known.ULTRAFAST + else -> throw OpenAIInvalidDataException("Unknown ServiceTier: $value") + } - override fun toString() = value.toString() - } + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } - /** Options for streaming responses. Only set this when you set `stream: true`. */ - class StreamOptions - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val includeObfuscation: JsonField, - private val additionalProperties: MutableMap, - ) { + private var validated: Boolean = false - @JsonCreator - private constructor( - @JsonProperty("include_obfuscation") - @ExcludeMissing - includeObfuscation: JsonField = JsonMissing.of() - ) : this(includeObfuscation, mutableMapOf()) + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ServiceTier = apply { + if (validated) { + return@apply + } - /** - * When true, stream obfuscation will be enabled. Stream obfuscation adds random characters - * to an `obfuscation` field on streaming delta events to normalize payload sizes as a - * mitigation to certain side-channel attacks. These obfuscation fields are included by - * default, but add a small amount of overhead to the data stream. You can set - * `include_obfuscation` to false to optimize for bandwidth if you trust the network links - * between your application and the OpenAI API. - * - * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the - * server responded with an unexpected value). - */ - fun includeObfuscation(): Optional = - includeObfuscation.getOptional("include_obfuscation") + known() + validated = true + } - /** - * Returns the raw JSON value of [includeObfuscation]. - * - * Unlike [includeObfuscation], this method doesn't throw if the JSON field has an - * unexpected type. - */ - @JsonProperty("include_obfuscation") - @ExcludeMissing - fun _includeObfuscation(): JsonField = includeObfuscation + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun toBuilder() = Builder().from(this) + return other is ServiceTier && value == other.value + } - companion object { + override fun hashCode() = value.hashCode() - /** Returns a mutable builder for constructing an instance of [StreamOptions]. */ - @JvmStatic fun builder() = Builder() + override fun toString() = value.toString() } - /** A builder for [StreamOptions]. */ - class Builder internal constructor() { - - private var includeObfuscation: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + /** Options for streaming responses. Only set this when you set `stream: true`. */ + class StreamOptions + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val includeObfuscation: JsonField, + private val additionalProperties: MutableMap, + ) { - @JvmSynthetic - internal fun from(streamOptions: StreamOptions) = apply { - includeObfuscation = streamOptions.includeObfuscation - additionalProperties = streamOptions.additionalProperties.toMutableMap() - } + @JsonCreator + private constructor( + @JsonProperty("include_obfuscation") + @ExcludeMissing + includeObfuscation: JsonField = JsonMissing.of() + ) : this(includeObfuscation, mutableMapOf()) /** * When true, stream obfuscation will be enabled. Stream obfuscation adds random @@ -4871,853 +5323,936 @@ private constructor( * included by default, but add a small amount of overhead to the data stream. You can * set `include_obfuscation` to false to optimize for bandwidth if you trust the network * links between your application and the OpenAI API. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). */ - fun includeObfuscation(includeObfuscation: Boolean) = - includeObfuscation(JsonField.of(includeObfuscation)) + fun includeObfuscation(): Optional = + includeObfuscation.getOptional("include_obfuscation") /** - * Sets [Builder.includeObfuscation] to an arbitrary JSON value. + * Returns the raw JSON value of [includeObfuscation]. * - * You should usually call [Builder.includeObfuscation] with a well-typed [Boolean] - * value instead. This method is primarily for setting the field to an undocumented or - * not yet supported value. + * Unlike [includeObfuscation], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun includeObfuscation(includeObfuscation: JsonField) = apply { - this.includeObfuscation = includeObfuscation - } + @JsonProperty("include_obfuscation") + @ExcludeMissing + fun _includeObfuscation(): JsonField = includeObfuscation - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [StreamOptions]. */ + @JvmStatic fun builder() = Builder() } - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) + /** A builder for [StreamOptions]. */ + class Builder internal constructor() { + + private var includeObfuscation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(streamOptions: StreamOptions) = apply { + includeObfuscation = streamOptions.includeObfuscation + additionalProperties = streamOptions.additionalProperties.toMutableMap() + } + + /** + * When true, stream obfuscation will be enabled. Stream obfuscation adds random + * characters to an `obfuscation` field on streaming delta events to normalize + * payload sizes as a mitigation to certain side-channel attacks. These obfuscation + * fields are included by default, but add a small amount of overhead to the data + * stream. You can set `include_obfuscation` to false to optimize for bandwidth if + * you trust the network links between your application and the OpenAI API. + */ + fun includeObfuscation(includeObfuscation: Boolean) = + includeObfuscation(JsonField.of(includeObfuscation)) + + /** + * Sets [Builder.includeObfuscation] to an arbitrary JSON value. + * + * You should usually call [Builder.includeObfuscation] with a well-typed [Boolean] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun includeObfuscation(includeObfuscation: JsonField) = apply { + this.includeObfuscation = includeObfuscation + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [StreamOptions]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): StreamOptions = + StreamOptions(includeObfuscation, additionalProperties.toMutableMap()) } - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + private var validated: Boolean = false - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): StreamOptions = apply { + if (validated) { + return@apply + } + + includeObfuscation() + validated = true } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + /** - * Returns an immutable instance of [StreamOptions]. + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * Further updates to this [Builder] will not mutate the returned instance. + * Used for best match union deserialization. */ - fun build(): StreamOptions = - StreamOptions(includeObfuscation, additionalProperties.toMutableMap()) - } + @JvmSynthetic + internal fun validity(): Int = (if (includeObfuscation.asKnown().isPresent) 1 else 0) - private var validated: Boolean = false + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): StreamOptions = apply { - if (validated) { - return@apply + return other is StreamOptions && + includeObfuscation == other.includeObfuscation && + additionalProperties == other.additionalProperties } - includeObfuscation() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false + private val hashCode: Int by lazy { + Objects.hash(includeObfuscation, additionalProperties) } + override fun hashCode(): Int = hashCode + + override fun toString() = + "StreamOptions{includeObfuscation=$includeObfuscation, additionalProperties=$additionalProperties}" + } + /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. + * How the model should select which tool (or tools) to use when generating a response. See + * the `tools` parameter to see how to specify which tools the model can call. */ - @JvmSynthetic - internal fun validity(): Int = (if (includeObfuscation.asKnown().isPresent) 1 else 0) + @JsonDeserialize(using = ToolChoice.Deserializer::class) + @JsonSerialize(using = ToolChoice.Serializer::class) + class ToolChoice + private constructor( + private val options: ToolChoiceOptions? = null, + private val allowed: ToolChoiceAllowed? = null, + private val types: ToolChoiceTypes? = null, + private val function: ToolChoiceFunction? = null, + private val mcp: ToolChoiceMcp? = null, + private val custom: ToolChoiceCustom? = null, + private val specificProgrammaticToolCallingParam: JsonValue? = null, + private val applyPatch: ToolChoiceApplyPatch? = null, + private val shell: ToolChoiceShell? = null, + private val _json: JsonValue? = null, + ) { - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** + * Controls which (if any) tool is called by the model. + * + * `none` means the model will not call any tool and instead generates a message. + * + * `auto` means the model can pick between generating a message or calling one or more + * tools. + * + * `required` means the model must call one or more tools. + */ + fun options(): Optional = Optional.ofNullable(options) - return other is StreamOptions && - includeObfuscation == other.includeObfuscation && - additionalProperties == other.additionalProperties - } + /** Constrains the tools available to the model to a pre-defined set. */ + fun allowed(): Optional = Optional.ofNullable(allowed) + + /** + * Indicates that the model should use a built-in tool to generate a response. + * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). + */ + fun types(): Optional = Optional.ofNullable(types) + + /** Use this option to force the model to call a specific function. */ + fun function(): Optional = Optional.ofNullable(function) + + /** + * Use this option to force the model to call a specific tool on a remote MCP server. + */ + fun mcp(): Optional = Optional.ofNullable(mcp) - private val hashCode: Int by lazy { Objects.hash(includeObfuscation, additionalProperties) } + /** Use this option to force the model to call a specific custom tool. */ + fun custom(): Optional = Optional.ofNullable(custom) - override fun hashCode(): Int = hashCode + fun specificProgrammaticToolCallingParam(): Optional = + Optional.ofNullable(specificProgrammaticToolCallingParam) - override fun toString() = - "StreamOptions{includeObfuscation=$includeObfuscation, additionalProperties=$additionalProperties}" - } + /** Forces the model to call the apply_patch tool when executing a tool call. */ + fun applyPatch(): Optional = Optional.ofNullable(applyPatch) - /** - * How the model should select which tool (or tools) to use when generating a response. See the - * `tools` parameter to see how to specify which tools the model can call. - */ - @JsonDeserialize(using = ToolChoice.Deserializer::class) - @JsonSerialize(using = ToolChoice.Serializer::class) - class ToolChoice - private constructor( - private val options: ToolChoiceOptions? = null, - private val allowed: ToolChoiceAllowed? = null, - private val types: ToolChoiceTypes? = null, - private val function: ToolChoiceFunction? = null, - private val mcp: ToolChoiceMcp? = null, - private val custom: ToolChoiceCustom? = null, - private val specificProgrammaticToolCallingParam: JsonValue? = null, - private val applyPatch: ToolChoiceApplyPatch? = null, - private val shell: ToolChoiceShell? = null, - private val _json: JsonValue? = null, - ) { + /** Forces the model to call the shell tool when a tool call is required. */ + fun shell(): Optional = Optional.ofNullable(shell) - /** - * Controls which (if any) tool is called by the model. - * - * `none` means the model will not call any tool and instead generates a message. - * - * `auto` means the model can pick between generating a message or calling one or more - * tools. - * - * `required` means the model must call one or more tools. - */ - fun options(): Optional = Optional.ofNullable(options) + fun isOptions(): Boolean = options != null - /** Constrains the tools available to the model to a pre-defined set. */ - fun allowed(): Optional = Optional.ofNullable(allowed) + fun isAllowed(): Boolean = allowed != null - /** - * Indicates that the model should use a built-in tool to generate a response. - * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). - */ - fun types(): Optional = Optional.ofNullable(types) + fun isTypes(): Boolean = types != null - /** Use this option to force the model to call a specific function. */ - fun function(): Optional = Optional.ofNullable(function) + fun isFunction(): Boolean = function != null - /** Use this option to force the model to call a specific tool on a remote MCP server. */ - fun mcp(): Optional = Optional.ofNullable(mcp) + fun isMcp(): Boolean = mcp != null - /** Use this option to force the model to call a specific custom tool. */ - fun custom(): Optional = Optional.ofNullable(custom) + fun isCustom(): Boolean = custom != null - fun specificProgrammaticToolCallingParam(): Optional = - Optional.ofNullable(specificProgrammaticToolCallingParam) + fun isSpecificProgrammaticToolCallingParam(): Boolean = + specificProgrammaticToolCallingParam != null - /** Forces the model to call the apply_patch tool when executing a tool call. */ - fun applyPatch(): Optional = Optional.ofNullable(applyPatch) + fun isApplyPatch(): Boolean = applyPatch != null - /** Forces the model to call the shell tool when a tool call is required. */ - fun shell(): Optional = Optional.ofNullable(shell) + fun isShell(): Boolean = shell != null - fun isOptions(): Boolean = options != null + /** + * Controls which (if any) tool is called by the model. + * + * `none` means the model will not call any tool and instead generates a message. + * + * `auto` means the model can pick between generating a message or calling one or more + * tools. + * + * `required` means the model must call one or more tools. + */ + fun asOptions(): ToolChoiceOptions = options.getOrThrow("options") - fun isAllowed(): Boolean = allowed != null + /** Constrains the tools available to the model to a pre-defined set. */ + fun asAllowed(): ToolChoiceAllowed = allowed.getOrThrow("allowed") - fun isTypes(): Boolean = types != null + /** + * Indicates that the model should use a built-in tool to generate a response. + * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). + */ + fun asTypes(): ToolChoiceTypes = types.getOrThrow("types") - fun isFunction(): Boolean = function != null + /** Use this option to force the model to call a specific function. */ + fun asFunction(): ToolChoiceFunction = function.getOrThrow("function") - fun isMcp(): Boolean = mcp != null + /** + * Use this option to force the model to call a specific tool on a remote MCP server. + */ + fun asMcp(): ToolChoiceMcp = mcp.getOrThrow("mcp") - fun isCustom(): Boolean = custom != null + /** Use this option to force the model to call a specific custom tool. */ + fun asCustom(): ToolChoiceCustom = custom.getOrThrow("custom") - fun isSpecificProgrammaticToolCallingParam(): Boolean = - specificProgrammaticToolCallingParam != null + fun asSpecificProgrammaticToolCallingParam(): JsonValue = + specificProgrammaticToolCallingParam.getOrThrow( + "specificProgrammaticToolCallingParam" + ) - fun isApplyPatch(): Boolean = applyPatch != null + /** Forces the model to call the apply_patch tool when executing a tool call. */ + fun asApplyPatch(): ToolChoiceApplyPatch = applyPatch.getOrThrow("applyPatch") - fun isShell(): Boolean = shell != null + /** Forces the model to call the shell tool when a tool call is required. */ + fun asShell(): ToolChoiceShell = shell.getOrThrow("shell") - /** - * Controls which (if any) tool is called by the model. - * - * `none` means the model will not call any tool and instead generates a message. - * - * `auto` means the model can pick between generating a message or calling one or more - * tools. - * - * `required` means the model must call one or more tools. - */ - fun asOptions(): ToolChoiceOptions = options.getOrThrow("options") + fun _json(): Optional = Optional.ofNullable(_json) - /** Constrains the tools available to the model to a pre-defined set. */ - fun asAllowed(): ToolChoiceAllowed = allowed.getOrThrow("allowed") + /** + * Maps this instance's current variant to a value of type [T] using the given + * [visitor]. + * + * Note that this method is _not_ forwards compatible with new variants from the API, + * unless [visitor] overrides [Visitor.unknown]. To handle variants not known to this + * version of the SDK gracefully, consider overriding [Visitor.unknown]: + * ```java + * import com.openai.core.JsonValue; + * import java.util.Optional; + * + * Optional result = toolChoice.accept(new ToolChoice.Visitor>() { + * @Override + * public Optional visitOptions(ToolChoiceOptions options) { + * return Optional.of(options.toString()); + * } + * + * // ... + * + * @Override + * public Optional unknown(JsonValue json) { + * // Or inspect the `json`. + * return Optional.empty(); + * } + * }); + * ``` + * + * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in + * [visitor] and the current variant is unknown. + */ + fun accept(visitor: Visitor): T = + when { + options != null -> visitor.visitOptions(options) + allowed != null -> visitor.visitAllowed(allowed) + types != null -> visitor.visitTypes(types) + function != null -> visitor.visitFunction(function) + mcp != null -> visitor.visitMcp(mcp) + custom != null -> visitor.visitCustom(custom) + specificProgrammaticToolCallingParam != null -> + visitor.visitSpecificProgrammaticToolCallingParam( + specificProgrammaticToolCallingParam + ) + applyPatch != null -> visitor.visitApplyPatch(applyPatch) + shell != null -> visitor.visitShell(shell) + else -> visitor.unknown(_json) + } - /** - * Indicates that the model should use a built-in tool to generate a response. - * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). - */ - fun asTypes(): ToolChoiceTypes = types.getOrThrow("types") + private var validated: Boolean = false - /** Use this option to force the model to call a specific function. */ - fun asFunction(): ToolChoiceFunction = function.getOrThrow("function") + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ToolChoice = apply { + if (validated) { + return@apply + } - /** Use this option to force the model to call a specific tool on a remote MCP server. */ - fun asMcp(): ToolChoiceMcp = mcp.getOrThrow("mcp") + accept( + object : Visitor { + override fun visitOptions(options: ToolChoiceOptions) { + options.validate() + } - /** Use this option to force the model to call a specific custom tool. */ - fun asCustom(): ToolChoiceCustom = custom.getOrThrow("custom") + override fun visitAllowed(allowed: ToolChoiceAllowed) { + allowed.validate() + } - fun asSpecificProgrammaticToolCallingParam(): JsonValue = - specificProgrammaticToolCallingParam.getOrThrow("specificProgrammaticToolCallingParam") + override fun visitTypes(types: ToolChoiceTypes) { + types.validate() + } - /** Forces the model to call the apply_patch tool when executing a tool call. */ - fun asApplyPatch(): ToolChoiceApplyPatch = applyPatch.getOrThrow("applyPatch") + override fun visitFunction(function: ToolChoiceFunction) { + function.validate() + } - /** Forces the model to call the shell tool when a tool call is required. */ - fun asShell(): ToolChoiceShell = shell.getOrThrow("shell") + override fun visitMcp(mcp: ToolChoiceMcp) { + mcp.validate() + } - fun _json(): Optional = Optional.ofNullable(_json) + override fun visitCustom(custom: ToolChoiceCustom) { + custom.validate() + } - /** - * Maps this instance's current variant to a value of type [T] using the given [visitor]. - * - * Note that this method is _not_ forwards compatible with new variants from the API, unless - * [visitor] overrides [Visitor.unknown]. To handle variants not known to this version of - * the SDK gracefully, consider overriding [Visitor.unknown]: - * ```java - * import com.openai.core.JsonValue; - * import java.util.Optional; - * - * Optional result = toolChoice.accept(new ToolChoice.Visitor>() { - * @Override - * public Optional visitOptions(ToolChoiceOptions options) { - * return Optional.of(options.toString()); - * } - * - * // ... - * - * @Override - * public Optional unknown(JsonValue json) { - * // Or inspect the `json`. - * return Optional.empty(); - * } - * }); - * ``` - * - * @throws OpenAIInvalidDataException if [Visitor.unknown] is not overridden in [visitor] - * and the current variant is unknown. - */ - fun accept(visitor: Visitor): T = - when { - options != null -> visitor.visitOptions(options) - allowed != null -> visitor.visitAllowed(allowed) - types != null -> visitor.visitTypes(types) - function != null -> visitor.visitFunction(function) - mcp != null -> visitor.visitMcp(mcp) - custom != null -> visitor.visitCustom(custom) - specificProgrammaticToolCallingParam != null -> - visitor.visitSpecificProgrammaticToolCallingParam( - specificProgrammaticToolCallingParam - ) - applyPatch != null -> visitor.visitApplyPatch(applyPatch) - shell != null -> visitor.visitShell(shell) - else -> visitor.unknown(_json) - } + override fun visitSpecificProgrammaticToolCallingParam( + specificProgrammaticToolCallingParam: JsonValue + ) { + specificProgrammaticToolCallingParam.let { + if ( + it != + JsonValue.from(mapOf("type" to "programmatic_tool_calling")) + ) { + throw OpenAIInvalidDataException( + "'specificProgrammaticToolCallingParam' is invalid, received $it" + ) + } + } + } - private var validated: Boolean = false + override fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch) { + applyPatch.validate() + } - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): ToolChoice = apply { - if (validated) { - return@apply + override fun visitShell(shell: ToolChoiceShell) { + shell.validate() + } + } + ) + validated = true } - accept( - object : Visitor { - override fun visitOptions(options: ToolChoiceOptions) { - options.validate() - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } - override fun visitAllowed(allowed: ToolChoiceAllowed) { - allowed.validate() - } + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitOptions(options: ToolChoiceOptions) = options.validity() - override fun visitTypes(types: ToolChoiceTypes) { - types.validate() - } + override fun visitAllowed(allowed: ToolChoiceAllowed) = allowed.validity() - override fun visitFunction(function: ToolChoiceFunction) { - function.validate() - } + override fun visitTypes(types: ToolChoiceTypes) = types.validity() - override fun visitMcp(mcp: ToolChoiceMcp) { - mcp.validate() - } + override fun visitFunction(function: ToolChoiceFunction) = + function.validity() - override fun visitCustom(custom: ToolChoiceCustom) { - custom.validate() - } + override fun visitMcp(mcp: ToolChoiceMcp) = mcp.validity() - override fun visitSpecificProgrammaticToolCallingParam( - specificProgrammaticToolCallingParam: JsonValue - ) { - specificProgrammaticToolCallingParam.let { - if ( - it != JsonValue.from(mapOf("type" to "programmatic_tool_calling")) - ) { - throw OpenAIInvalidDataException( - "'specificProgrammaticToolCallingParam' is invalid, received $it" + override fun visitCustom(custom: ToolChoiceCustom) = custom.validity() + + override fun visitSpecificProgrammaticToolCallingParam( + specificProgrammaticToolCallingParam: JsonValue + ) = + specificProgrammaticToolCallingParam.let { + if ( + it == + JsonValue.from(mapOf("type" to "programmatic_tool_calling")) ) + 1 + else 0 } - } - } - override fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch) { - applyPatch.validate() - } + override fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch) = + applyPatch.validity() - override fun visitShell(shell: ToolChoiceShell) { - shell.validate() + override fun visitShell(shell: ToolChoiceShell) = shell.validity() + + override fun unknown(json: JsonValue?) = 0 } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - ) - validated = true - } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false + return other is ToolChoice && + options == other.options && + allowed == other.allowed && + types == other.types && + function == other.function && + mcp == other.mcp && + custom == other.custom && + specificProgrammaticToolCallingParam == + other.specificProgrammaticToolCallingParam && + applyPatch == other.applyPatch && + shell == other.shell } - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - accept( - object : Visitor { - override fun visitOptions(options: ToolChoiceOptions) = options.validity() + override fun hashCode(): Int = + Objects.hash( + options, + allowed, + types, + function, + mcp, + custom, + specificProgrammaticToolCallingParam, + applyPatch, + shell, + ) + + override fun toString(): String = + when { + options != null -> "ToolChoice{options=$options}" + allowed != null -> "ToolChoice{allowed=$allowed}" + types != null -> "ToolChoice{types=$types}" + function != null -> "ToolChoice{function=$function}" + mcp != null -> "ToolChoice{mcp=$mcp}" + custom != null -> "ToolChoice{custom=$custom}" + specificProgrammaticToolCallingParam != null -> + "ToolChoice{specificProgrammaticToolCallingParam=$specificProgrammaticToolCallingParam}" + applyPatch != null -> "ToolChoice{applyPatch=$applyPatch}" + shell != null -> "ToolChoice{shell=$shell}" + _json != null -> "ToolChoice{_unknown=$_json}" + else -> throw IllegalStateException("Invalid ToolChoice") + } - override fun visitAllowed(allowed: ToolChoiceAllowed) = allowed.validity() + companion object { - override fun visitTypes(types: ToolChoiceTypes) = types.validity() + /** + * Controls which (if any) tool is called by the model. + * + * `none` means the model will not call any tool and instead generates a message. + * + * `auto` means the model can pick between generating a message or calling one or + * more tools. + * + * `required` means the model must call one or more tools. + */ + @JvmStatic fun ofOptions(options: ToolChoiceOptions) = ToolChoice(options = options) - override fun visitFunction(function: ToolChoiceFunction) = function.validity() + /** Constrains the tools available to the model to a pre-defined set. */ + @JvmStatic fun ofAllowed(allowed: ToolChoiceAllowed) = ToolChoice(allowed = allowed) - override fun visitMcp(mcp: ToolChoiceMcp) = mcp.validity() + /** + * Indicates that the model should use a built-in tool to generate a response. + * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). + */ + @JvmStatic fun ofTypes(types: ToolChoiceTypes) = ToolChoice(types = types) - override fun visitCustom(custom: ToolChoiceCustom) = custom.validity() + /** Use this option to force the model to call a specific function. */ + @JvmStatic + fun ofFunction(function: ToolChoiceFunction) = ToolChoice(function = function) - override fun visitSpecificProgrammaticToolCallingParam( - specificProgrammaticToolCallingParam: JsonValue - ) = - specificProgrammaticToolCallingParam.let { - if (it == JsonValue.from(mapOf("type" to "programmatic_tool_calling"))) - 1 - else 0 - } + /** + * Use this option to force the model to call a specific tool on a remote MCP + * server. + */ + @JvmStatic fun ofMcp(mcp: ToolChoiceMcp) = ToolChoice(mcp = mcp) - override fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch) = - applyPatch.validity() + /** Use this option to force the model to call a specific custom tool. */ + @JvmStatic fun ofCustom(custom: ToolChoiceCustom) = ToolChoice(custom = custom) - override fun visitShell(shell: ToolChoiceShell) = shell.validity() + @JvmStatic + fun ofSpecificProgrammaticToolCallingParam() = + ToolChoice( + specificProgrammaticToolCallingParam = + JsonValue.from(mapOf("type" to "programmatic_tool_calling")) + ) - override fun unknown(json: JsonValue?) = 0 - } - ) + /** Forces the model to call the apply_patch tool when executing a tool call. */ + @JvmStatic + fun ofApplyPatch(applyPatch: ToolChoiceApplyPatch) = + ToolChoice(applyPatch = applyPatch) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** Forces the model to call the shell tool when a tool call is required. */ + @JvmStatic fun ofShell(shell: ToolChoiceShell) = ToolChoice(shell = shell) } - return other is ToolChoice && - options == other.options && - allowed == other.allowed && - types == other.types && - function == other.function && - mcp == other.mcp && - custom == other.custom && - specificProgrammaticToolCallingParam == - other.specificProgrammaticToolCallingParam && - applyPatch == other.applyPatch && - shell == other.shell - } + /** + * An interface that defines how to map each variant of [ToolChoice] to a value of type + * [T]. + */ + interface Visitor { - override fun hashCode(): Int = - Objects.hash( - options, - allowed, - types, - function, - mcp, - custom, - specificProgrammaticToolCallingParam, - applyPatch, - shell, - ) + /** + * Controls which (if any) tool is called by the model. + * + * `none` means the model will not call any tool and instead generates a message. + * + * `auto` means the model can pick between generating a message or calling one or + * more tools. + * + * `required` means the model must call one or more tools. + */ + fun visitOptions(options: ToolChoiceOptions): T - override fun toString(): String = - when { - options != null -> "ToolChoice{options=$options}" - allowed != null -> "ToolChoice{allowed=$allowed}" - types != null -> "ToolChoice{types=$types}" - function != null -> "ToolChoice{function=$function}" - mcp != null -> "ToolChoice{mcp=$mcp}" - custom != null -> "ToolChoice{custom=$custom}" - specificProgrammaticToolCallingParam != null -> - "ToolChoice{specificProgrammaticToolCallingParam=$specificProgrammaticToolCallingParam}" - applyPatch != null -> "ToolChoice{applyPatch=$applyPatch}" - shell != null -> "ToolChoice{shell=$shell}" - _json != null -> "ToolChoice{_unknown=$_json}" - else -> throw IllegalStateException("Invalid ToolChoice") - } + /** Constrains the tools available to the model to a pre-defined set. */ + fun visitAllowed(allowed: ToolChoiceAllowed): T - companion object { + /** + * Indicates that the model should use a built-in tool to generate a response. + * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). + */ + fun visitTypes(types: ToolChoiceTypes): T - /** - * Controls which (if any) tool is called by the model. - * - * `none` means the model will not call any tool and instead generates a message. - * - * `auto` means the model can pick between generating a message or calling one or more - * tools. - * - * `required` means the model must call one or more tools. - */ - @JvmStatic fun ofOptions(options: ToolChoiceOptions) = ToolChoice(options = options) + /** Use this option to force the model to call a specific function. */ + fun visitFunction(function: ToolChoiceFunction): T - /** Constrains the tools available to the model to a pre-defined set. */ - @JvmStatic fun ofAllowed(allowed: ToolChoiceAllowed) = ToolChoice(allowed = allowed) + /** + * Use this option to force the model to call a specific tool on a remote MCP + * server. + */ + fun visitMcp(mcp: ToolChoiceMcp): T - /** - * Indicates that the model should use a built-in tool to generate a response. - * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). - */ - @JvmStatic fun ofTypes(types: ToolChoiceTypes) = ToolChoice(types = types) + /** Use this option to force the model to call a specific custom tool. */ + fun visitCustom(custom: ToolChoiceCustom): T - /** Use this option to force the model to call a specific function. */ - @JvmStatic - fun ofFunction(function: ToolChoiceFunction) = ToolChoice(function = function) + fun visitSpecificProgrammaticToolCallingParam( + specificProgrammaticToolCallingParam: JsonValue + ): T + + /** Forces the model to call the apply_patch tool when executing a tool call. */ + fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch): T + + /** Forces the model to call the shell tool when a tool call is required. */ + fun visitShell(shell: ToolChoiceShell): T + + /** + * Maps an unknown variant of [ToolChoice] to a value of type [T]. + * + * An instance of [ToolChoice] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws OpenAIInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw OpenAIInvalidDataException("Unknown ToolChoice: $json") + } + } + + internal class Deserializer : BaseDeserializer(ToolChoice::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): ToolChoice { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef()) + ?.let { + ToolChoice( + specificProgrammaticToolCallingParam = it, + _json = json, + ) + } + ?.takeIf { it.isValid() }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(options = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(allowed = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(types = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(function = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(mcp = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(custom = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(applyPatch = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + ToolChoice(shell = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> ToolChoice(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(ToolChoice::class) { + + override fun serialize( + value: ToolChoice, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.options != null -> generator.writeObject(value.options) + value.allowed != null -> generator.writeObject(value.allowed) + value.types != null -> generator.writeObject(value.types) + value.function != null -> generator.writeObject(value.function) + value.mcp != null -> generator.writeObject(value.mcp) + value.custom != null -> generator.writeObject(value.custom) + value.specificProgrammaticToolCallingParam != null -> + generator.writeObject(value.specificProgrammaticToolCallingParam) + value.applyPatch != null -> generator.writeObject(value.applyPatch) + value.shell != null -> generator.writeObject(value.shell) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid ToolChoice") + } + } + } + } + + /** + * The truncation strategy to use for the model response. + * - `auto`: If the input to this Response exceeds the model's context window size, the + * model will truncate the response to fit the context window by dropping items from the + * beginning of the conversation. + * - `disabled` (default): If the input size will exceed the context window size for a + * model, the request will fail with a 400 error. + */ + @Deprecated("deprecated") + class Truncation @JsonCreator private constructor(private val value: JsonField) : + Enum { /** - * Use this option to force the model to call a specific tool on a remote MCP server. + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. */ - @JvmStatic fun ofMcp(mcp: ToolChoiceMcp) = ToolChoice(mcp = mcp) + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - /** Use this option to force the model to call a specific custom tool. */ - @JvmStatic fun ofCustom(custom: ToolChoiceCustom) = ToolChoice(custom = custom) + companion object { - @JvmStatic - fun ofSpecificProgrammaticToolCallingParam() = - ToolChoice( - specificProgrammaticToolCallingParam = - JsonValue.from(mapOf("type" to "programmatic_tool_calling")) - ) + @JvmField val AUTO = of("auto") - /** Forces the model to call the apply_patch tool when executing a tool call. */ - @JvmStatic - fun ofApplyPatch(applyPatch: ToolChoiceApplyPatch) = ToolChoice(applyPatch = applyPatch) + @JvmField val DISABLED = of("disabled") - /** Forces the model to call the shell tool when a tool call is required. */ - @JvmStatic fun ofShell(shell: ToolChoiceShell) = ToolChoice(shell = shell) - } + @JvmStatic fun of(value: String) = Truncation(JsonField.of(value)) + } - /** - * An interface that defines how to map each variant of [ToolChoice] to a value of type [T]. - */ - interface Visitor { + /** An enum containing [Truncation]'s known values. */ + enum class Known { + AUTO, + DISABLED, + } /** - * Controls which (if any) tool is called by the model. + * An enum containing [Truncation]'s known values, as well as an [_UNKNOWN] member. * - * `none` means the model will not call any tool and instead generates a message. - * - * `auto` means the model can pick between generating a message or calling one or more - * tools. - * - * `required` means the model must call one or more tools. + * An instance of [Truncation] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. */ - fun visitOptions(options: ToolChoiceOptions): T - - /** Constrains the tools available to the model to a pre-defined set. */ - fun visitAllowed(allowed: ToolChoiceAllowed): T + enum class Value { + AUTO, + DISABLED, + /** + * An enum member indicating that [Truncation] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } /** - * Indicates that the model should use a built-in tool to generate a response. - * [Learn more about built-in tools](https://platform.openai.com/docs/guides/tools). + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. */ - fun visitTypes(types: ToolChoiceTypes): T - - /** Use this option to force the model to call a specific function. */ - fun visitFunction(function: ToolChoiceFunction): T + fun value(): Value = + when (this) { + AUTO -> Value.AUTO + DISABLED -> Value.DISABLED + else -> Value._UNKNOWN + } /** - * Use this option to force the model to call a specific tool on a remote MCP server. + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. */ - fun visitMcp(mcp: ToolChoiceMcp): T - - /** Use this option to force the model to call a specific custom tool. */ - fun visitCustom(custom: ToolChoiceCustom): T - - fun visitSpecificProgrammaticToolCallingParam( - specificProgrammaticToolCallingParam: JsonValue - ): T - - /** Forces the model to call the apply_patch tool when executing a tool call. */ - fun visitApplyPatch(applyPatch: ToolChoiceApplyPatch): T - - /** Forces the model to call the shell tool when a tool call is required. */ - fun visitShell(shell: ToolChoiceShell): T + fun known(): Known = + when (this) { + AUTO -> Known.AUTO + DISABLED -> Known.DISABLED + else -> throw OpenAIInvalidDataException("Unknown Truncation: $value") + } /** - * Maps an unknown variant of [ToolChoice] to a value of type [T]. + * Returns this class instance's primitive wire representation. * - * An instance of [ToolChoice] can contain an unknown variant if it was deserialized - * from data that doesn't match any known variant. For example, if the SDK is on an - * older version than the API, then the API may respond with new variants that the SDK - * is unaware of. + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. * - * @throws OpenAIInvalidDataException in the default implementation. + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. */ - fun unknown(json: JsonValue?): T { - throw OpenAIInvalidDataException("Unknown ToolChoice: $json") - } - } - - internal class Deserializer : BaseDeserializer(ToolChoice::class) { - - override fun ObjectCodec.deserialize(node: JsonNode): ToolChoice { - val json = JsonValue.fromJsonNode(node) - - val bestMatches = - sequenceOf( - tryDeserialize(node, jacksonTypeRef()) - ?.let { - ToolChoice( - specificProgrammaticToolCallingParam = it, - _json = json, - ) - } - ?.takeIf { it.isValid() }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(options = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(allowed = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(types = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(function = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(mcp = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(custom = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(applyPatch = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - ToolChoice(shell = it, _json = json) - }, - ) - .filterNotNull() - .allMaxBy { it.validity() } - .toList() - return when (bestMatches.size) { - // This can happen if what we're deserializing is completely incompatible with - // all the possible variants (e.g. deserializing from boolean). - 0 -> ToolChoice(_json = json) - 1 -> bestMatches.single() - // If there's more than one match with the highest validity, then use the first - // completely valid match, or simply the first match if none are completely - // valid. - else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") } - } - } - internal class Serializer : BaseSerializer(ToolChoice::class) { + private var validated: Boolean = false - override fun serialize( - value: ToolChoice, - generator: JsonGenerator, - provider: SerializerProvider, - ) { - when { - value.options != null -> generator.writeObject(value.options) - value.allowed != null -> generator.writeObject(value.allowed) - value.types != null -> generator.writeObject(value.types) - value.function != null -> generator.writeObject(value.function) - value.mcp != null -> generator.writeObject(value.mcp) - value.custom != null -> generator.writeObject(value.custom) - value.specificProgrammaticToolCallingParam != null -> - generator.writeObject(value.specificProgrammaticToolCallingParam) - value.applyPatch != null -> generator.writeObject(value.applyPatch) - value.shell != null -> generator.writeObject(value.shell) - value._json != null -> generator.writeObject(value._json) - else -> throw IllegalStateException("Invalid ToolChoice") + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Truncation = apply { + if (validated) { + return@apply } - } - } - } - - /** - * The truncation strategy to use for the model response. - * - `auto`: If the input to this Response exceeds the model's context window size, the model - * will truncate the response to fit the context window by dropping items from the beginning - * of the conversation. - * - `disabled` (default): If the input size will exceed the context window size for a model, - * the request will fail with a 400 error. - */ - @Deprecated("deprecated") - class Truncation @JsonCreator private constructor(private val value: JsonField) : Enum { - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val AUTO = of("auto") - - @JvmField val DISABLED = of("disabled") - - @JvmStatic fun of(value: String) = Truncation(JsonField.of(value)) - } + known() + validated = true + } - /** An enum containing [Truncation]'s known values. */ - enum class Known { - AUTO, - DISABLED, - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } - /** - * An enum containing [Truncation]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [Truncation] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - AUTO, - DISABLED, /** - * An enum member indicating that [Truncation] was instantiated with an unknown value. + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. */ - _UNKNOWN, - } + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - AUTO -> Value.AUTO - DISABLED -> Value.DISABLED - else -> Value._UNKNOWN - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws OpenAIInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - AUTO -> Known.AUTO - DISABLED -> Known.DISABLED - else -> throw OpenAIInvalidDataException("Unknown Truncation: $value") + return other is Truncation && value == other.value } - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws OpenAIInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } - - private var validated: Boolean = false - - /** - * Validates that the types of all values in this object match their expected types - * recursively. - * - * This method is _not_ forwards compatible with new types from the API for existing fields. - * - * @throws OpenAIInvalidDataException if any value type in this object doesn't match its - * expected type. - */ - fun validate(): Truncation = apply { - if (validated) { - return@apply - } + override fun hashCode() = value.hashCode() - known() - validated = true + override fun toString() = value.toString() } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: OpenAIInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Truncation && value == other.value + return other is ResponseCreate && + type == other.type && + background == other.background && + contextManagement == other.contextManagement && + conversation == other.conversation && + include == other.include && + input == other.input && + instructions == other.instructions && + maxOutputTokens == other.maxOutputTokens && + maxToolCalls == other.maxToolCalls && + metadata == other.metadata && + model == other.model && + moderation == other.moderation && + parallelToolCalls == other.parallelToolCalls && + previousResponseId == other.previousResponseId && + prompt == other.prompt && + promptCacheKey == other.promptCacheKey && + promptCacheOptions == other.promptCacheOptions && + promptCacheRetention == other.promptCacheRetention && + reasoning == other.reasoning && + safetyIdentifier == other.safetyIdentifier && + serviceTier == other.serviceTier && + store == other.store && + stream == other.stream && + streamId == other.streamId && + streamOptions == other.streamOptions && + temperature == other.temperature && + text == other.text && + toolChoice == other.toolChoice && + tools == other.tools && + topLogprobs == other.topLogprobs && + topP == other.topP && + truncation == other.truncation && + user == other.user && + additionalProperties == other.additionalProperties } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + private val hashCode: Int by lazy { + Objects.hash( + type, + background, + contextManagement, + conversation, + include, + input, + instructions, + maxOutputTokens, + maxToolCalls, + metadata, + model, + moderation, + parallelToolCalls, + previousResponseId, + prompt, + promptCacheKey, + promptCacheOptions, + promptCacheRetention, + reasoning, + safetyIdentifier, + serviceTier, + store, + stream, + streamId, + streamOptions, + temperature, + text, + toolChoice, + tools, + topLogprobs, + topP, + truncation, + user, + additionalProperties, + ) } - return other is ResponsesClientEvent && - type == other.type && - background == other.background && - contextManagement == other.contextManagement && - conversation == other.conversation && - include == other.include && - input == other.input && - instructions == other.instructions && - maxOutputTokens == other.maxOutputTokens && - maxToolCalls == other.maxToolCalls && - metadata == other.metadata && - model == other.model && - moderation == other.moderation && - parallelToolCalls == other.parallelToolCalls && - previousResponseId == other.previousResponseId && - prompt == other.prompt && - promptCacheKey == other.promptCacheKey && - promptCacheOptions == other.promptCacheOptions && - promptCacheRetention == other.promptCacheRetention && - reasoning == other.reasoning && - safetyIdentifier == other.safetyIdentifier && - serviceTier == other.serviceTier && - store == other.store && - stream == other.stream && - streamId == other.streamId && - streamOptions == other.streamOptions && - temperature == other.temperature && - text == other.text && - toolChoice == other.toolChoice && - tools == other.tools && - topLogprobs == other.topLogprobs && - topP == other.topP && - truncation == other.truncation && - user == other.user && - additionalProperties == other.additionalProperties - } + override fun hashCode(): Int = hashCode - private val hashCode: Int by lazy { - Objects.hash( - type, - background, - contextManagement, - conversation, - include, - input, - instructions, - maxOutputTokens, - maxToolCalls, - metadata, - model, - moderation, - parallelToolCalls, - previousResponseId, - prompt, - promptCacheKey, - promptCacheOptions, - promptCacheRetention, - reasoning, - safetyIdentifier, - serviceTier, - store, - stream, - streamId, - streamOptions, - temperature, - text, - toolChoice, - tools, - topLogprobs, - topP, - truncation, - user, - additionalProperties, - ) + override fun toString() = + "ResponseCreate{type=$type, background=$background, contextManagement=$contextManagement, conversation=$conversation, include=$include, input=$input, instructions=$instructions, maxOutputTokens=$maxOutputTokens, maxToolCalls=$maxToolCalls, metadata=$metadata, model=$model, moderation=$moderation, parallelToolCalls=$parallelToolCalls, previousResponseId=$previousResponseId, prompt=$prompt, promptCacheKey=$promptCacheKey, promptCacheOptions=$promptCacheOptions, promptCacheRetention=$promptCacheRetention, reasoning=$reasoning, safetyIdentifier=$safetyIdentifier, serviceTier=$serviceTier, store=$store, stream=$stream, streamId=$streamId, streamOptions=$streamOptions, temperature=$temperature, text=$text, toolChoice=$toolChoice, tools=$tools, topLogprobs=$topLogprobs, topP=$topP, truncation=$truncation, user=$user, additionalProperties=$additionalProperties}" } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "ResponsesClientEvent{type=$type, background=$background, contextManagement=$contextManagement, conversation=$conversation, include=$include, input=$input, instructions=$instructions, maxOutputTokens=$maxOutputTokens, maxToolCalls=$maxToolCalls, metadata=$metadata, model=$model, moderation=$moderation, parallelToolCalls=$parallelToolCalls, previousResponseId=$previousResponseId, prompt=$prompt, promptCacheKey=$promptCacheKey, promptCacheOptions=$promptCacheOptions, promptCacheRetention=$promptCacheRetention, reasoning=$reasoning, safetyIdentifier=$safetyIdentifier, serviceTier=$serviceTier, store=$store, stream=$stream, streamId=$streamId, streamOptions=$streamOptions, temperature=$temperature, text=$text, toolChoice=$toolChoice, tools=$tools, topLogprobs=$topLogprobs, topP=$topP, truncation=$truncation, user=$user, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesServerEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesServerEvent.kt index 77fddaf23..a17972456 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesServerEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/ResponsesServerEvent.kt @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.BaseDeserializer import com.openai.core.BaseSerializer +import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -99,6 +100,9 @@ private constructor( private val responseCustomToolCallInputDelta: ResponseCustomToolCallInputDeltaEvent? = null, private val responseCustomToolCallInputDone: ResponseCustomToolCallInputDoneEvent? = null, private val error: ResponseWsError? = null, + private val responseSteerAccepted: ResponseSteerAcceptedEvent? = null, + private val responseSteerPending: ResponseSteerPendingEvent? = null, + private val responseSteerFailed: ResponseSteerFailedEvent? = null, private val _json: JsonValue? = null, ) { @@ -204,7 +208,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun responseFailed(): Optional = Optional.ofNullable(responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun responseIncomplete(): Optional = Optional.ofNullable(responseIncomplete) @@ -339,6 +349,52 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun error(): Optional = Optional.ofNullable(error) + /** + * Emitted when steering input has been validated and queued. Acceptance means the server owns + * the input, not that it has been applied. The successor's `response.created` event is the + * commit point. If accepted input cannot be committed, `response.steer.failed` returns it with + * the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued + * and `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` + * per parent. Do not resend accepted input while it is still queued. + */ + fun responseSteerAccepted(): Optional = + Optional.ofNullable(responseSteerAccepted) + + /** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is + * the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while + * the response waits for the tool results or approval decisions identified by `required_input`. + * Copy those stubs, fill their result fields using the ordinary `response.create` input + * schemas, and submit one continuation per parent with the same `previous_response_id` and + * WebSocket lane. Use saved results without rerunning tools. The queued steering input is + * prepended in submission order to the continuation's input. That explicit request retains its + * own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for + * the same parent can report the same required inputs; they do not each require a separate + * continuation. + */ + fun responseSteerPending(): Optional = + Optional.ofNullable(responseSteerPending) + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated + * omit `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it + * is not proof that the input was rejected. + */ + fun responseSteerFailed(): Optional = + Optional.ofNullable(responseSteerFailed) + /** * The WebSocket lane that emitted this event. This field is present when the originating * `response.create` event supplied a `stream_id`. @@ -566,6 +622,12 @@ private constructor( error != null -> error._streamId() + responseSteerAccepted != null -> responseSteerAccepted._streamId() + + responseSteerPending != null -> responseSteerPending._streamId() + + responseSteerFailed != null -> responseSteerFailed._streamId() + else -> JsonMissing.of() } @@ -695,6 +757,12 @@ private constructor( fun isError(): Boolean = error != null + fun isResponseSteerAccepted(): Boolean = responseSteerAccepted != null + + fun isResponseSteerPending(): Boolean = responseSteerPending != null + + fun isResponseSteerFailed(): Boolean = responseSteerFailed != null + /** Emitted when there is a partial audio response. */ fun asResponseAudioDelta(): ResponseAudioDeltaEvent = responseAudioDelta.getOrThrow("responseAudioDelta") @@ -795,7 +863,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun asResponseFailed(): ResponseFailedEvent = responseFailed.getOrThrow("responseFailed") - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` set + * to `steered`, followed automatically by a successor `response.created` that commits the + * queued steering input. + */ fun asResponseIncomplete(): ResponseIncompleteEvent = responseIncomplete.getOrThrow("responseIncomplete") @@ -932,6 +1006,52 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun asError(): ResponseWsError = error.getOrThrow("error") + /** + * Emitted when steering input has been validated and queued. Acceptance means the server owns + * the input, not that it has been applied. The successor's `response.created` event is the + * commit point. If accepted input cannot be committed, `response.steer.failed` returns it with + * the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains queued + * and `response.steer.pending` is emitted after `response.completed`. Fill the pending event's + * `required_input` stubs with saved results and send one matching explicit `response.create` + * per parent. Do not resend accepted input while it is still queued. + */ + fun asResponseSteerAccepted(): ResponseSteerAcceptedEvent = + responseSteerAccepted.getOrThrow("responseSteerAccepted") + + /** + * Emitted when accepted steering input remains queued after the target response completes. The + * server still owns the input. Do not resend it. The successor's `response.created` event is + * the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` while + * the response waits for the tool results or approval decisions identified by `required_input`. + * Copy those stubs, fill their result fields using the ordinary `response.create` input + * schemas, and submit one continuation per parent with the same `previous_response_id` and + * WebSocket lane. Use saved results without rerunning tools. The queued steering input is + * prepended in submission order to the continuation's input. That explicit request retains its + * own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions for + * the same parent can report the same required inputs; they do not each require a separate + * continuation. + */ + fun asResponseSteerPending(): ResponseSteerPendingEvent = + responseSteerPending.getOrThrow("responseSteerPending") + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is allocated + * omit `steer.id`. A lost connection or missing acknowledgement leaves the outcome unknown; it + * is not proof that the input was rejected. + */ + fun asResponseSteerFailed(): ResponseSteerFailedEvent = + responseSteerFailed.getOrThrow("responseSteerFailed") + fun _json(): Optional = Optional.ofNullable(_json) /** @@ -1090,6 +1210,10 @@ private constructor( responseCustomToolCallInputDone != null -> visitor.visitResponseCustomToolCallInputDone(responseCustomToolCallInputDone) error != null -> visitor.visitError(error) + responseSteerAccepted != null -> + visitor.visitResponseSteerAccepted(responseSteerAccepted) + responseSteerPending != null -> visitor.visitResponseSteerPending(responseSteerPending) + responseSteerFailed != null -> visitor.visitResponseSteerFailed(responseSteerFailed) else -> visitor.unknown(_json) } @@ -1441,6 +1565,24 @@ private constructor( override fun visitError(error: ResponseWsError) { error.validate() } + + override fun visitResponseSteerAccepted( + responseSteerAccepted: ResponseSteerAcceptedEvent + ) { + responseSteerAccepted.validate() + } + + override fun visitResponseSteerPending( + responseSteerPending: ResponseSteerPendingEvent + ) { + responseSteerPending.validate() + } + + override fun visitResponseSteerFailed( + responseSteerFailed: ResponseSteerFailedEvent + ) { + responseSteerFailed.validate() + } } ) streamId() @@ -1688,6 +1830,18 @@ private constructor( override fun visitError(error: ResponseWsError) = error.validity() + override fun visitResponseSteerAccepted( + responseSteerAccepted: ResponseSteerAcceptedEvent + ) = responseSteerAccepted.validity() + + override fun visitResponseSteerPending( + responseSteerPending: ResponseSteerPendingEvent + ) = responseSteerPending.validity() + + override fun visitResponseSteerFailed( + responseSteerFailed: ResponseSteerFailedEvent + ) = responseSteerFailed.validity() + override fun unknown(json: JsonValue?) = 0 } ) @@ -1757,7 +1911,10 @@ private constructor( responseQueued == other.responseQueued && responseCustomToolCallInputDelta == other.responseCustomToolCallInputDelta && responseCustomToolCallInputDone == other.responseCustomToolCallInputDone && - error == other.error + error == other.error && + responseSteerAccepted == other.responseSteerAccepted && + responseSteerPending == other.responseSteerPending && + responseSteerFailed == other.responseSteerFailed } override fun hashCode(): Int = @@ -1820,6 +1977,9 @@ private constructor( responseCustomToolCallInputDelta, responseCustomToolCallInputDone, error, + responseSteerAccepted, + responseSteerPending, + responseSteerFailed, ) override fun toString(): String = @@ -1936,6 +2096,12 @@ private constructor( responseCustomToolCallInputDone != null -> "ResponsesServerEvent{responseCustomToolCallInputDone=$responseCustomToolCallInputDone}" error != null -> "ResponsesServerEvent{error=$error}" + responseSteerAccepted != null -> + "ResponsesServerEvent{responseSteerAccepted=$responseSteerAccepted}" + responseSteerPending != null -> + "ResponsesServerEvent{responseSteerPending=$responseSteerPending}" + responseSteerFailed != null -> + "ResponsesServerEvent{responseSteerFailed=$responseSteerFailed}" _json != null -> "ResponsesServerEvent{_unknown=$_json}" else -> throw IllegalStateException("Invalid ResponsesServerEvent") } @@ -2114,7 +2280,13 @@ private constructor( fun ofResponseFailed(responseFailed: ResponseFailedEvent) = ResponsesServerEvent(responseFailed = responseFailed) - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ @JvmStatic fun ofResponseIncomplete(responseIncomplete: ResponseIncompleteEvent) = ResponsesServerEvent(responseIncomplete = responseIncomplete) @@ -2334,6 +2506,55 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ @JvmStatic fun ofError(error: ResponseWsError) = ResponsesServerEvent(error = error) + + /** + * Emitted when steering input has been validated and queued. Acceptance means the server + * owns the input, not that it has been applied. The successor's `response.created` event is + * the commit point. If accepted input cannot be committed, `response.steer.failed` returns + * it with the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * pending event's `required_input` stubs with saved results and send one matching explicit + * `response.create` per parent. Do not resend accepted input while it is still queued. + */ + @JvmStatic + fun ofResponseSteerAccepted(responseSteerAccepted: ResponseSteerAcceptedEvent) = + ResponsesServerEvent(responseSteerAccepted = responseSteerAccepted) + + /** + * Emitted when accepted steering input remains queued after the target response completes. + * The server still owns the input. Do not resend it. The successor's `response.created` + * event is the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` + * while the response waits for the tool results or approval decisions identified by + * `required_input`. Copy those stubs, fill their result fields using the ordinary + * `response.create` input schemas, and submit one continuation per parent with the same + * `previous_response_id` and WebSocket lane. Use saved results without rerunning tools. The + * queued steering input is prepended in submission order to the continuation's input. That + * explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions + * for the same parent can report the same required inputs; they do not each require a + * separate continuation. + */ + @JvmStatic + fun ofResponseSteerPending(responseSteerPending: ResponseSteerPendingEvent) = + ResponsesServerEvent(responseSteerPending = responseSteerPending) + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is + * allocated omit `steer.id`. A lost connection or missing acknowledgement leaves the + * outcome unknown; it is not proof that the input was rejected. + */ + @JvmStatic + fun ofResponseSteerFailed(responseSteerFailed: ResponseSteerFailedEvent) = + ResponsesServerEvent(responseSteerFailed = responseSteerFailed) } /** @@ -2453,7 +2674,13 @@ private constructor( /** An event that is emitted when a response fails. */ fun visitResponseFailed(responseFailed: ResponseFailedEvent): T - /** An event that is emitted when a response finishes as incomplete. */ + /** + * An event that is emitted when a response finishes as incomplete. + * + * Over WebSocket, steering can finish a response with `response.incomplete_details.reason` + * set to `steered`, followed automatically by a successor `response.created` that commits + * the queued steering input. + */ fun visitResponseIncomplete(responseIncomplete: ResponseIncompleteEvent): T /** Emitted when a new output item is added. */ @@ -2606,6 +2833,49 @@ private constructor( /** Emitted when an error occurs while processing a Responses WebSocket request. */ fun visitError(error: ResponseWsError): T + /** + * Emitted when steering input has been validated and queued. Acceptance means the server + * owns the input, not that it has been applied. The successor's `response.created` event is + * the commit point. If accepted input cannot be committed, `response.steer.failed` returns + * it with the same steering ID. + * + * When the response stops for client-owned tool output or approval, the input remains + * queued and `response.steer.pending` is emitted after `response.completed`. Fill the + * pending event's `required_input` stubs with saved results and send one matching explicit + * `response.create` per parent. Do not resend accepted input while it is still queued. + */ + fun visitResponseSteerAccepted(responseSteerAccepted: ResponseSteerAcceptedEvent): T + + /** + * Emitted when accepted steering input remains queued after the target response completes. + * The server still owns the input. Do not resend it. The successor's `response.created` + * event is the commit point. + * + * When `reason` is `waiting_for_required_input`, this event follows `response.completed` + * while the response waits for the tool results or approval decisions identified by + * `required_input`. Copy those stubs, fill their result fields using the ordinary + * `response.create` input schemas, and submit one continuation per parent with the same + * `previous_response_id` and WebSocket lane. Use saved results without rerunning tools. The + * queued steering input is prepended in submission order to the continuation's input. That + * explicit request retains its own settings. + * + * This notification is emitted at most once per steering submission. Multiple submissions + * for the same parent can report the same required inputs; they do not each require a + * separate continuation. + */ + fun visitResponseSteerPending(responseSteerPending: ResponseSteerPendingEvent): T + + /** + * Emitted when steering input is rejected or cannot be committed to a successor response. + * Returns the original, uncommitted input so the client can carry it into `response.create` + * when appropriate. Invalid input must be corrected before retrying. + * + * Failures after acceptance include the same steering ID. Failures before an ID is + * allocated omit `steer.id`. A lost connection or missing acknowledgement leaves the + * outcome unknown; it is not proof that the input was rejected. + */ + fun visitResponseSteerFailed(responseSteerFailed: ResponseSteerFailedEvent): T + /** * Maps an unknown variant of [ResponsesServerEvent] to a value of type [T]. * @@ -3109,6 +3379,21 @@ private constructor( ResponsesServerEvent(error = it, _json = json) } ?: ResponsesServerEvent(_json = json) } + "response.steer.accepted" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponsesServerEvent(responseSteerAccepted = it, _json = json) + } ?: ResponsesServerEvent(_json = json) + } + "response.steer.pending" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponsesServerEvent(responseSteerPending = it, _json = json) + } ?: ResponsesServerEvent(_json = json) + } + "response.steer.failed" -> { + return tryDeserialize(node, jacksonTypeRef())?.let { + ResponsesServerEvent(responseSteerFailed = it, _json = json) + } ?: ResponsesServerEvent(_json = json) + } } return ResponsesServerEvent(_json = json) @@ -3230,6 +3515,12 @@ private constructor( value.responseCustomToolCallInputDone != null -> generator.writeObject(value.responseCustomToolCallInputDone) value.error != null -> generator.writeObject(value.error) + value.responseSteerAccepted != null -> + generator.writeObject(value.responseSteerAccepted) + value.responseSteerPending != null -> + generator.writeObject(value.responseSteerPending) + value.responseSteerFailed != null -> + generator.writeObject(value.responseSteerFailed) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid ResponsesServerEvent") } @@ -3551,6 +3842,7 @@ private constructor( private val param: JsonField, private val type: JsonField, private val headers: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -3565,7 +3857,10 @@ private constructor( @JsonProperty("headers") @ExcludeMissing headers: JsonField = JsonMissing.of(), - ) : this(code, message, param, type, headers, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, param, type, headers, misalignment, mutableMapOf()) /** * The error code that was emitted, if any. @@ -3609,6 +3904,12 @@ private constructor( */ fun headers(): Optional = headers.getOptional("headers") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -3644,6 +3945,16 @@ private constructor( */ @JsonProperty("headers") @ExcludeMissing fun _headers(): JsonField = headers + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -3680,6 +3991,7 @@ private constructor( private var param: JsonField? = null private var type: JsonField? = null private var headers: JsonField = JsonMissing.of() + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -3689,6 +4001,7 @@ private constructor( param = error.param type = error.type headers = error.headers + misalignment = error.misalignment additionalProperties = error.additionalProperties.toMutableMap() } @@ -3758,6 +4071,20 @@ private constructor( */ fun headers(headers: JsonField) = apply { this.headers = headers } + fun misalignment(misalignment: Misalignment) = + misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] + * value instead. This method is primarily for setting the field to an undocumented + * or not yet supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -3802,6 +4129,7 @@ private constructor( checkRequired("param", param), checkRequired("type", type), headers, + misalignment, additionalProperties.toMutableMap(), ) } @@ -3828,6 +4156,7 @@ private constructor( param() type() headers().ifPresent { it.validate() } + misalignment().ifPresent { it.validate() } validated = true } @@ -3851,7 +4180,8 @@ private constructor( (if (message.asKnown().isPresent) 1 else 0) + (if (param.asKnown().isPresent) 1 else 0) + (if (type.asKnown().isPresent) 1 else 0) + - (headers.asKnown().getOrNull()?.validity() ?: 0) + (headers.asKnown().getOrNull()?.validity() ?: 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) /** The response headers that were emitted with the error, if any. */ class Headers @@ -3968,6 +4298,619 @@ private constructor( override fun toString() = "Headers{additionalProperties=$additionalProperties}" } + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") + @ExcludeMissing + steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed + * [String] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun errorType(errorType: JsonField) = apply { + this.errorType = errorType + } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match + * its expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType + @JsonCreator + private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that + * doesn't match any known member, and you want to know that value. For example, + * if the SDK is on an older version than the API, then the API may respond with + * new members that the SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue + fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = + of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For + * example, if the SDK is on an older version than the API, then the API may + * respond with new members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an + * unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or + * if you want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> + Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known + * and don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a + * known member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> + Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type + * or is unexpectedly missing or null (e.g. if the server responded with an + * unexpected value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("message") + @ExcludeMissing + fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = + mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties( + additionalProperties: Map + ) = apply { this.additionalProperties.putAll(additionalProperties) } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer( + checkRequired("message", message), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected + * types recursively. + * + * This method is _not_ forwards compatible with new types from the API for + * existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't + * match its expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(message, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -3979,17 +4922,26 @@ private constructor( param == other.param && type == other.type && headers == other.headers && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } private val hashCode: Int by lazy { - Objects.hash(code, message, param, type, headers, additionalProperties) + Objects.hash( + code, + message, + param, + type, + headers, + misalignment, + additionalProperties, + ) } override fun hashCode(): Int = hashCode override fun toString() = - "Error{code=$code, message=$message, param=$param, type=$type, headers=$headers, additionalProperties=$additionalProperties}" + "Error{code=$code, message=$message, param=$param, type=$type, headers=$headers, misalignment=$misalignment, additionalProperties=$additionalProperties}" } override fun equals(other: Any?): Boolean { diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt index 20ed7a940..000c62362 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPage.kt @@ -11,6 +11,7 @@ import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCallItem import com.openai.models.responses.ResponseCustomToolCallOutputItem import com.openai.models.responses.ResponseFileSearchToolCall @@ -108,6 +109,10 @@ private constructor( additionalTools: ResponseItem.AdditionalTools ): Optional = additionalTools._id().getOptional("id") + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ): Optional = configurationUpdate._id().getOptional("id") + override fun visitReasoning( reasoning: ResponseReasoningItem ): Optional = reasoning._id().getOptional("id") diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt index 9454f0803..37a149e77 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/InputItemListPageAsync.kt @@ -11,6 +11,7 @@ import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCallItem import com.openai.models.responses.ResponseCustomToolCallOutputItem import com.openai.models.responses.ResponseFileSearchToolCall @@ -111,6 +112,10 @@ private constructor( additionalTools: ResponseItem.AdditionalTools ): Optional = additionalTools._id().getOptional("id") + override fun visitConfigurationUpdate( + configurationUpdate: ResponseConfigurationUpdateItem + ): Optional = configurationUpdate._id().getOptional("id") + override fun visitReasoning( reasoning: ResponseReasoningItem ): Optional = reasoning._id().getOptional("id") diff --git a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/ResponseItemList.kt b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/ResponseItemList.kt index ab2ed4bb8..38b7fed39 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/ResponseItemList.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/responses/inputitems/ResponseItemList.kt @@ -20,6 +20,7 @@ import com.openai.models.responses.ResponseCodeInterpreterToolCall import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCallItem import com.openai.models.responses.ResponseCustomToolCallOutputItem import com.openai.models.responses.ResponseFileSearchToolCall @@ -262,6 +263,24 @@ private constructor( fun addData(additionalTools: ResponseItem.AdditionalTools) = addData(ResponseItem.ofAdditionalTools(additionalTools)) + /** + * Alias for calling [addData] with + * `ResponseItem.ofConfigurationUpdate(configurationUpdate)`. + */ + fun addData(configurationUpdate: ResponseConfigurationUpdateItem) = + addData(ResponseItem.ofConfigurationUpdate(configurationUpdate)) + + /** + * Alias for calling [addData] with the following: + * ```java + * ResponseConfigurationUpdateItem.builder() + * .id(id) + * .build() + * ``` + */ + fun addConfigurationUpdateData(id: String) = + addData(ResponseConfigurationUpdateItem.builder().id(id).build()) + /** Alias for calling [addData] with `ResponseItem.ofReasoning(reasoning)`. */ fun addData(reasoning: ResponseReasoningItem) = addData(ResponseItem.ofReasoning(reasoning)) diff --git a/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/AlertRetrieveParams.kt b/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/AlertRetrieveParams.kt new file mode 100644 index 000000000..efd8f133c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/AlertRetrieveParams.kt @@ -0,0 +1,191 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.safety.alerts + +import com.openai.core.Params +import com.openai.core.http.Headers +import com.openai.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get a safety alert belonging to the authenticated API project. */ +class AlertRetrieveParams +private constructor( + private val id: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Project safety alert ID */ + fun id(): Optional = Optional.ofNullable(id) + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): AlertRetrieveParams = builder().build() + + /** Returns a mutable builder for constructing an instance of [AlertRetrieveParams]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AlertRetrieveParams]. */ + class Builder internal constructor() { + + private var id: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(alertRetrieveParams: AlertRetrieveParams) = apply { + id = alertRetrieveParams.id + additionalHeaders = alertRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = alertRetrieveParams.additionalQueryParams.toBuilder() + } + + /** Project safety alert ID */ + fun id(id: String?) = apply { this.id = id } + + /** Alias for calling [Builder.id] with `id.orElse(null)`. */ + fun id(id: Optional) = id(id.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [AlertRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AlertRetrieveParams = + AlertRetrieveParams(id, additionalHeaders.build(), additionalQueryParams.build()) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> id ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AlertRetrieveParams && + id == other.id && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = Objects.hash(id, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AlertRetrieveParams{id=$id, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/SafetyAlert.kt b/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/SafetyAlert.kt new file mode 100644 index 000000000..90a0cf8e0 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/safety/alerts/SafetyAlert.kt @@ -0,0 +1,660 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.safety.alerts + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class SafetyAlert +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val errorType: JsonField, + private val model: JsonField, + private val object_: JsonValue, + private val reason: JsonField, + private val requestId: JsonField, + private val requestPaused: JsonField, + private val responseId: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("model") @ExcludeMissing model: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + @JsonProperty("request_id") @ExcludeMissing requestId: JsonField = JsonMissing.of(), + @JsonProperty("request_paused") + @ExcludeMissing + requestPaused: JsonField = JsonMissing.of(), + @JsonProperty("response_id") + @ExcludeMissing + responseId: JsonField = JsonMissing.of(), + ) : this( + id, + createdAt, + errorType, + model, + object_, + reason, + requestId, + requestPaused, + responseId, + mutableMapOf(), + ) + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): Long = createdAt.getRequired("created_at") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun errorType(): ErrorType = errorType.getRequired("error_type") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun model(): String = model.getRequired("model") + + /** + * Expected to always return the following: + * ```java + * JsonValue.from("safety.alert") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * A customer-safe description derived from error_type, or null for zero data retention + * requests. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun reason(): Optional = reason.getOptional("reason") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun requestId(): String = requestId.getRequired("request_id") + + /** + * Whether block registration succeeded for this request. This does not confirm that response + * execution stopped. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun requestPaused(): Boolean = requestPaused.getRequired("request_paused") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun responseId(): String = responseId.getRequired("response_id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error_type") @ExcludeMissing fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [model]. + * + * Unlike [model], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("model") @ExcludeMissing fun _model(): JsonField = model + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + /** + * Returns the raw JSON value of [requestId]. + * + * Unlike [requestId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("request_id") @ExcludeMissing fun _requestId(): JsonField = requestId + + /** + * Returns the raw JSON value of [requestPaused]. + * + * Unlike [requestPaused], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("request_paused") + @ExcludeMissing + fun _requestPaused(): JsonField = requestPaused + + /** + * Returns the raw JSON value of [responseId]. + * + * Unlike [responseId], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("response_id") @ExcludeMissing fun _responseId(): JsonField = responseId + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [SafetyAlert]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .errorType() + * .model() + * .reason() + * .requestId() + * .requestPaused() + * .responseId() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SafetyAlert]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var errorType: JsonField? = null + private var model: JsonField? = null + private var object_: JsonValue = JsonValue.from("safety.alert") + private var reason: JsonField? = null + private var requestId: JsonField? = null + private var requestPaused: JsonField? = null + private var responseId: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(safetyAlert: SafetyAlert) = apply { + id = safetyAlert.id + createdAt = safetyAlert.createdAt + errorType = safetyAlert.errorType + model = safetyAlert.model + object_ = safetyAlert.object_ + reason = safetyAlert.reason + requestId = safetyAlert.requestId + requestPaused = safetyAlert.requestPaused + responseId = safetyAlert.responseId + additionalProperties = safetyAlert.additionalProperties.toMutableMap() + } + + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun errorType(errorType: JsonField) = apply { this.errorType = errorType } + + fun model(model: String) = model(JsonField.of(model)) + + /** + * Sets [Builder.model] to an arbitrary JSON value. + * + * You should usually call [Builder.model] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun model(model: JsonField) = apply { this.model = model } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("safety.alert") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + /** + * A customer-safe description derived from error_type, or null for zero data retention + * requests. + */ + fun reason(reason: String?) = reason(JsonField.ofNullable(reason)) + + /** Alias for calling [Builder.reason] with `reason.orElse(null)`. */ + fun reason(reason: Optional) = reason(reason.getOrNull()) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + fun requestId(requestId: String) = requestId(JsonField.of(requestId)) + + /** + * Sets [Builder.requestId] to an arbitrary JSON value. + * + * You should usually call [Builder.requestId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun requestId(requestId: JsonField) = apply { this.requestId = requestId } + + /** + * Whether block registration succeeded for this request. This does not confirm that + * response execution stopped. + */ + fun requestPaused(requestPaused: Boolean) = requestPaused(JsonField.of(requestPaused)) + + /** + * Sets [Builder.requestPaused] to an arbitrary JSON value. + * + * You should usually call [Builder.requestPaused] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun requestPaused(requestPaused: JsonField) = apply { + this.requestPaused = requestPaused + } + + fun responseId(responseId: String) = responseId(JsonField.of(responseId)) + + /** + * Sets [Builder.responseId] to an arbitrary JSON value. + * + * You should usually call [Builder.responseId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun responseId(responseId: JsonField) = apply { this.responseId = responseId } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SafetyAlert]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .errorType() + * .model() + * .reason() + * .requestId() + * .requestPaused() + * .responseId() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SafetyAlert = + SafetyAlert( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("errorType", errorType), + checkRequired("model", model), + object_, + checkRequired("reason", reason), + checkRequired("requestId", requestId), + checkRequired("requestPaused", requestPaused), + checkRequired("responseId", responseId), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): SafetyAlert = apply { + if (validated) { + return@apply + } + + id() + createdAt() + errorType().validate() + model() + _object_().let { + if (it != JsonValue.from("safety.alert")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + reason() + requestId() + requestPaused() + responseId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (errorType.asKnown().getOrNull()?.validity() ?: 0) + + (if (model.asKnown().isPresent) 1 else 0) + + object_.let { if (it == JsonValue.from("safety.alert")) 1 else 0 } + + (if (reason.asKnown().isPresent) 1 else 0) + + (if (requestId.asKnown().isPresent) 1 else 0) + + (if (requestPaused.asKnown().isPresent) 1 else 0) + + (if (responseId.asKnown().isPresent) 1 else 0) + + class ErrorType @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { OpenAIInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SafetyAlert && + id == other.id && + createdAt == other.createdAt && + errorType == other.errorType && + model == other.model && + object_ == other.object_ && + reason == other.reason && + requestId == other.requestId && + requestPaused == other.requestPaused && + responseId == other.responseId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + id, + createdAt, + errorType, + model, + object_, + reason, + requestId, + requestPaused, + responseId, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SafetyAlert{id=$id, createdAt=$createdAt, errorType=$errorType, model=$model, object_=$object_, reason=$reason, requestId=$requestId, requestPaused=$requestPaused, responseId=$responseId, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/videos/VideoCreateError.kt b/openai-java-core/src/main/kotlin/com/openai/models/videos/VideoCreateError.kt index 99eb3b31d..b5e12a485 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/videos/VideoCreateError.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/videos/VideoCreateError.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonAnyGetter import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonCreator import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.Enum import com.openai.core.ExcludeMissing import com.openai.core.JsonField import com.openai.core.JsonMissing @@ -14,6 +15,8 @@ import com.openai.core.checkRequired import com.openai.errors.OpenAIInvalidDataException import java.util.Collections import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull /** An error that occurred while generating the response. */ class VideoCreateError @@ -21,6 +24,7 @@ class VideoCreateError private constructor( private val code: JsonField, private val message: JsonField, + private val misalignment: JsonField, private val additionalProperties: MutableMap, ) { @@ -28,7 +32,10 @@ private constructor( private constructor( @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), @JsonProperty("message") @ExcludeMissing message: JsonField = JsonMissing.of(), - ) : this(code, message, mutableMapOf()) + @JsonProperty("misalignment") + @ExcludeMissing + misalignment: JsonField = JsonMissing.of(), + ) : this(code, message, misalignment, mutableMapOf()) /** * A machine-readable error code that was returned. @@ -46,6 +53,12 @@ private constructor( */ fun message(): String = message.getRequired("message") + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun misalignment(): Optional = misalignment.getOptional("misalignment") + /** * Returns the raw JSON value of [code]. * @@ -60,6 +73,15 @@ private constructor( */ @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + /** + * Returns the raw JSON value of [misalignment]. + * + * Unlike [misalignment], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("misalignment") + @ExcludeMissing + fun _misalignment(): JsonField = misalignment + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -91,12 +113,14 @@ private constructor( private var code: JsonField? = null private var message: JsonField? = null + private var misalignment: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(videoCreateError: VideoCreateError) = apply { code = videoCreateError.code message = videoCreateError.message + misalignment = videoCreateError.misalignment additionalProperties = videoCreateError.additionalProperties.toMutableMap() } @@ -122,6 +146,19 @@ private constructor( */ fun message(message: JsonField) = apply { this.message = message } + fun misalignment(misalignment: Misalignment) = misalignment(JsonField.of(misalignment)) + + /** + * Sets [Builder.misalignment] to an arbitrary JSON value. + * + * You should usually call [Builder.misalignment] with a well-typed [Misalignment] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun misalignment(misalignment: JsonField) = apply { + this.misalignment = misalignment + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -158,6 +195,7 @@ private constructor( VideoCreateError( checkRequired("code", code), checkRequired("message", message), + misalignment, additionalProperties.toMutableMap(), ) } @@ -179,6 +217,7 @@ private constructor( code() message() + misalignment().ifPresent { it.validate() } validated = true } @@ -197,7 +236,595 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - (if (code.asKnown().isPresent) 1 else 0) + (if (message.asKnown().isPresent) 1 else 0) + (if (code.asKnown().isPresent) 1 else 0) + + (if (message.asKnown().isPresent) 1 else 0) + + (misalignment.asKnown().getOrNull()?.validity() ?: 0) + + class Misalignment + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val detailedExplanation: JsonField, + private val errorType: JsonField, + private val steer: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("detailed_explanation") + @ExcludeMissing + detailedExplanation: JsonField = JsonMissing.of(), + @JsonProperty("error_type") + @ExcludeMissing + errorType: JsonField = JsonMissing.of(), + @JsonProperty("steer") @ExcludeMissing steer: JsonField = JsonMissing.of(), + ) : this(detailedExplanation, errorType, steer, mutableMapOf()) + + /** + * The public explanation for this block. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun detailedExplanation(): Optional = + detailedExplanation.getOptional("detailed_explanation") + + /** + * An optional classification; clients must accept additional values. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun errorType(): Optional = errorType.getOptional("error_type") + + /** + * An optional public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun steer(): Optional = steer.getOptional("steer") + + /** + * Returns the raw JSON value of [detailedExplanation]. + * + * Unlike [detailedExplanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("detailed_explanation") + @ExcludeMissing + fun _detailedExplanation(): JsonField = detailedExplanation + + /** + * Returns the raw JSON value of [errorType]. + * + * Unlike [errorType], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("error_type") + @ExcludeMissing + fun _errorType(): JsonField = errorType + + /** + * Returns the raw JSON value of [steer]. + * + * Unlike [steer], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("steer") @ExcludeMissing fun _steer(): JsonField = steer + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [Misalignment]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Misalignment]. */ + class Builder internal constructor() { + + private var detailedExplanation: JsonField = JsonMissing.of() + private var errorType: JsonField = JsonMissing.of() + private var steer: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(misalignment: Misalignment) = apply { + detailedExplanation = misalignment.detailedExplanation + errorType = misalignment.errorType + steer = misalignment.steer + additionalProperties = misalignment.additionalProperties.toMutableMap() + } + + /** The public explanation for this block. */ + fun detailedExplanation(detailedExplanation: String) = + detailedExplanation(JsonField.of(detailedExplanation)) + + /** + * Sets [Builder.detailedExplanation] to an arbitrary JSON value. + * + * You should usually call [Builder.detailedExplanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun detailedExplanation(detailedExplanation: JsonField) = apply { + this.detailedExplanation = detailedExplanation + } + + /** An optional classification; clients must accept additional values. */ + fun errorType(errorType: ErrorType) = errorType(JsonField.of(errorType)) + + /** + * Sets [Builder.errorType] to an arbitrary JSON value. + * + * You should usually call [Builder.errorType] with a well-typed [ErrorType] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(errorType: JsonField) = apply { this.errorType = errorType } + + /** + * Sets [errorType] to an arbitrary [String]. + * + * You should usually call [errorType] with a well-typed [ErrorType] constant instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun errorType(value: String) = errorType(ErrorType.of(value)) + + /** An optional public continuation instruction. */ + fun steer(steer: Steer) = steer(JsonField.of(steer)) + + /** + * Sets [Builder.steer] to an arbitrary JSON value. + * + * You should usually call [Builder.steer] with a well-typed [Steer] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun steer(steer: JsonField) = apply { this.steer = steer } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Misalignment]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Misalignment = + Misalignment( + detailedExplanation, + errorType, + steer, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Misalignment = apply { + if (validated) { + return@apply + } + + detailedExplanation() + errorType() + steer().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (detailedExplanation.asKnown().isPresent) 1 else 0) + + (if (errorType.asKnown().isPresent) 1 else 0) + + (steer.asKnown().getOrNull()?.validity() ?: 0) + + /** An optional classification; clients must accept additional values. */ + class ErrorType @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_TRANSFER = + of("potentially_unintended_data_transfer") + + @JvmField + val POTENTIALLY_UNINTENDED_DATA_ACCESS = of("potentially_unintended_data_access") + + @JvmField + val POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY = + of("potentially_unintended_destructive_activity") + + @JvmField val OTHER = of("other") + + @JvmStatic fun of(value: String) = ErrorType(JsonField.of(value)) + } + + /** An enum containing [ErrorType]'s known values. */ + enum class Known { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + } + + /** + * An enum containing [ErrorType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ErrorType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + POTENTIALLY_UNINTENDED_DATA_TRANSFER, + POTENTIALLY_UNINTENDED_DATA_ACCESS, + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY, + OTHER, + /** + * An enum member indicating that [ErrorType] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Value.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Value.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Value.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Value.OTHER + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws OpenAIInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + POTENTIALLY_UNINTENDED_DATA_TRANSFER -> + Known.POTENTIALLY_UNINTENDED_DATA_TRANSFER + POTENTIALLY_UNINTENDED_DATA_ACCESS -> Known.POTENTIALLY_UNINTENDED_DATA_ACCESS + POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY -> + Known.POTENTIALLY_UNINTENDED_DESTRUCTIVE_ACTIVITY + OTHER -> Known.OTHER + else -> throw OpenAIInvalidDataException("Unknown ErrorType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws OpenAIInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + OpenAIInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): ErrorType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ErrorType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** An optional public continuation instruction. */ + class Steer + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val message: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("message") + @ExcludeMissing + message: JsonField = JsonMissing.of() + ) : this(message, mutableMapOf()) + + /** + * The public continuation instruction. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected + * value). + */ + fun message(): String = message.getRequired("message") + + /** + * Returns the raw JSON value of [message]. + * + * Unlike [message], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("message") @ExcludeMissing fun _message(): JsonField = message + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Steer]. + * + * The following fields are required: + * ```java + * .message() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Steer]. */ + class Builder internal constructor() { + + private var message: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(steer: Steer) = apply { + message = steer.message + additionalProperties = steer.additionalProperties.toMutableMap() + } + + /** The public continuation instruction. */ + fun message(message: String) = message(JsonField.of(message)) + + /** + * Sets [Builder.message] to an arbitrary JSON value. + * + * You should usually call [Builder.message] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun message(message: JsonField) = apply { this.message = message } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = + apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { + additionalProperties.remove(key) + } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Steer]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .message() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Steer = + Steer(checkRequired("message", message), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing + * fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Steer = apply { + if (validated) { + return@apply + } + + message() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (message.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Steer && + message == other.message && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(message, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Steer{message=$message, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Misalignment && + detailedExplanation == other.detailedExplanation && + errorType == other.errorType && + steer == other.steer && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(detailedExplanation, errorType, steer, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Misalignment{detailedExplanation=$detailedExplanation, errorType=$errorType, steer=$steer, additionalProperties=$additionalProperties}" + } override fun equals(other: Any?): Boolean { if (this === other) { @@ -207,13 +834,16 @@ private constructor( return other is VideoCreateError && code == other.code && message == other.message && + misalignment == other.misalignment && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(code, message, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(code, message, misalignment, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "VideoCreateError{code=$code, message=$message, additionalProperties=$additionalProperties}" + "VideoCreateError{code=$code, message=$message, misalignment=$misalignment, additionalProperties=$additionalProperties}" } diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEvent.kt new file mode 100644 index 000000000..98bcc4e7e --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEvent.kt @@ -0,0 +1,499 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Sent when an approved safety alert is available for an API project. */ +class SafetyAlertCreatedWebhookEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val data: JsonField, + private val object_: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(id, createdAt, data, object_, type, mutableMapOf()) + + /** + * The unique ID of the webhook event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The Unix timestamp in seconds when the event was created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): Long = createdAt.getRequired("created_at") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * Always `event`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("event") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * Always `safety.alert.created`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("safety.alert.created") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [SafetyAlertCreatedWebhookEvent]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SafetyAlertCreatedWebhookEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var data: JsonField? = null + private var object_: JsonValue = JsonValue.from("event") + private var type: JsonValue = JsonValue.from("safety.alert.created") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(safetyAlertCreatedWebhookEvent: SafetyAlertCreatedWebhookEvent) = apply { + id = safetyAlertCreatedWebhookEvent.id + createdAt = safetyAlertCreatedWebhookEvent.createdAt + data = safetyAlertCreatedWebhookEvent.data + object_ = safetyAlertCreatedWebhookEvent.object_ + type = safetyAlertCreatedWebhookEvent.type + additionalProperties = + safetyAlertCreatedWebhookEvent.additionalProperties.toMutableMap() + } + + /** The unique ID of the webhook event. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The Unix timestamp in seconds when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("event") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("safety.alert.created") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SafetyAlertCreatedWebhookEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SafetyAlertCreatedWebhookEvent = + SafetyAlertCreatedWebhookEvent( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("data", data), + object_, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): SafetyAlertCreatedWebhookEvent = apply { + if (validated) { + return@apply + } + + id() + createdAt() + data().validate() + _object_().let { + if (it != JsonValue.from("event")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("safety.alert.created")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + object_.let { if (it == JsonValue.from("event")) 1 else 0 } + + type.let { if (it == JsonValue.from("safety.alert.created")) 1 else 0 } + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = Data(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SafetyAlertCreatedWebhookEvent && + id == other.id && + createdAt == other.createdAt && + data == other.data && + object_ == other.object_ && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, createdAt, data, object_, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SafetyAlertCreatedWebhookEvent{id=$id, createdAt=$createdAt, data=$data, object_=$object_, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEvent.kt new file mode 100644 index 000000000..7ed7cf94c --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEvent.kt @@ -0,0 +1,500 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.openai.core.ExcludeMissing +import com.openai.core.JsonField +import com.openai.core.JsonMissing +import com.openai.core.JsonValue +import com.openai.core.checkRequired +import com.openai.errors.OpenAIInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Sent when an approved safety alert is available for an enterprise workspace. */ +class SafetyOrgAlertCreatedWebhookEvent +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val id: JsonField, + private val createdAt: JsonField, + private val data: JsonField, + private val object_: JsonValue, + private val type: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(), + @JsonProperty("created_at") @ExcludeMissing createdAt: JsonField = JsonMissing.of(), + @JsonProperty("data") @ExcludeMissing data: JsonField = JsonMissing.of(), + @JsonProperty("object") @ExcludeMissing object_: JsonValue = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonValue = JsonMissing.of(), + ) : this(id, createdAt, data, object_, type, mutableMapOf()) + + /** + * The unique ID of the webhook event. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * The Unix timestamp in seconds when the event was created. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): Long = createdAt.getRequired("created_at") + + /** + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): Data = data.getRequired("data") + + /** + * Always `event`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("event") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("object") @ExcludeMissing fun _object_(): JsonValue = object_ + + /** + * Always `safety.org_alert.created`. + * + * Expected to always return the following: + * ```java + * JsonValue.from("safety.org_alert.created") + * ``` + * + * However, this method can be useful for debugging and logging (e.g. if the server responded + * with an unexpected value). + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonValue = type + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") @ExcludeMissing fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField = data + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [SafetyOrgAlertCreatedWebhookEvent]. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [SafetyOrgAlertCreatedWebhookEvent]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var createdAt: JsonField? = null + private var data: JsonField? = null + private var object_: JsonValue = JsonValue.from("event") + private var type: JsonValue = JsonValue.from("safety.org_alert.created") + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(safetyOrgAlertCreatedWebhookEvent: SafetyOrgAlertCreatedWebhookEvent) = + apply { + id = safetyOrgAlertCreatedWebhookEvent.id + createdAt = safetyOrgAlertCreatedWebhookEvent.createdAt + data = safetyOrgAlertCreatedWebhookEvent.data + object_ = safetyOrgAlertCreatedWebhookEvent.object_ + type = safetyOrgAlertCreatedWebhookEvent.type + additionalProperties = + safetyOrgAlertCreatedWebhookEvent.additionalProperties.toMutableMap() + } + + /** The unique ID of the webhook event. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun id(id: JsonField) = apply { this.id = id } + + /** The Unix timestamp in seconds when the event was created. */ + fun createdAt(createdAt: Long) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [Long] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + fun data(data: Data) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed [Data] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun data(data: JsonField) = apply { this.data = data } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("event") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun object_(object_: JsonValue) = apply { this.object_ = object_ } + + /** + * Sets the field to an arbitrary JSON value. + * + * It is usually unnecessary to call this method because the field defaults to the + * following: + * ```java + * JsonValue.from("safety.org_alert.created") + * ``` + * + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun type(type: JsonValue) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [SafetyOrgAlertCreatedWebhookEvent]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * .createdAt() + * .data() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): SafetyOrgAlertCreatedWebhookEvent = + SafetyOrgAlertCreatedWebhookEvent( + checkRequired("id", id), + checkRequired("createdAt", createdAt), + checkRequired("data", data), + object_, + type, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): SafetyOrgAlertCreatedWebhookEvent = apply { + if (validated) { + return@apply + } + + id() + createdAt() + data().validate() + _object_().let { + if (it != JsonValue.from("event")) { + throw OpenAIInvalidDataException("'object_' is invalid, received $it") + } + } + _type().let { + if (it != JsonValue.from("safety.org_alert.created")) { + throw OpenAIInvalidDataException("'type' is invalid, received $it") + } + } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (id.asKnown().isPresent) 1 else 0) + + (if (createdAt.asKnown().isPresent) 1 else 0) + + (data.asKnown().getOrNull()?.validity() ?: 0) + + object_.let { if (it == JsonValue.from("event")) 1 else 0 } + + type.let { if (it == JsonValue.from("safety.org_alert.created")) 1 else 0 } + + class Data + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val id: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of() + ) : this(id, mutableMapOf()) + + /** + * The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. + * + * @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun id(): String = id.getRequired("id") + + /** + * Returns the raw JSON value of [id]. + * + * Unlike [id], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Data]. + * + * The following fields are required: + * ```java + * .id() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Data]. */ + class Builder internal constructor() { + + private var id: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(data: Data) = apply { + id = data.id + additionalProperties = data.additionalProperties.toMutableMap() + } + + /** The safety alert ID to pass to `GET /v1/safety/alerts/{id}`. */ + fun id(id: String) = id(JsonField.of(id)) + + /** + * Sets [Builder.id] to an arbitrary JSON value. + * + * You should usually call [Builder.id] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun id(id: JsonField) = apply { this.id = id } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Data]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .id() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Data = Data(checkRequired("id", id), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + /** + * Validates that the types of all values in this object match their expected types + * recursively. + * + * This method is _not_ forwards compatible with new types from the API for existing fields. + * + * @throws OpenAIInvalidDataException if any value type in this object doesn't match its + * expected type. + */ + fun validate(): Data = apply { + if (validated) { + return@apply + } + + id() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: OpenAIInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (id.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Data && + id == other.id && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(id, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "Data{id=$id, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is SafetyOrgAlertCreatedWebhookEvent && + id == other.id && + createdAt == other.createdAt && + data == other.data && + object_ == other.object_ && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(id, createdAt, data, object_, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "SafetyOrgAlertCreatedWebhookEvent{id=$id, createdAt=$createdAt, data=$data, object_=$object_, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt index 5ec183e51..7c29e95a6 100644 --- a/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt +++ b/openai-java-core/src/main/kotlin/com/openai/models/webhooks/UnwrapWebhookEvent.kt @@ -39,6 +39,8 @@ private constructor( private val responseCompleted: ResponseCompletedWebhookEvent? = null, private val responseFailed: ResponseFailedWebhookEvent? = null, private val responseIncomplete: ResponseIncompleteWebhookEvent? = null, + private val safetyAlertCreated: SafetyAlertCreatedWebhookEvent? = null, + private val safetyOrgAlertCreated: SafetyOrgAlertCreatedWebhookEvent? = null, private val _json: JsonValue? = null, ) { @@ -108,6 +110,14 @@ private constructor( fun responseIncomplete(): Optional = Optional.ofNullable(responseIncomplete) + /** Sent when an approved safety alert is available for an API project. */ + fun safetyAlertCreated(): Optional = + Optional.ofNullable(safetyAlertCreated) + + /** Sent when an approved safety alert is available for an enterprise workspace. */ + fun safetyOrgAlertCreated(): Optional = + Optional.ofNullable(safetyOrgAlertCreated) + fun isBatchCancelled(): Boolean = batchCancelled != null fun isBatchCompleted(): Boolean = batchCompleted != null @@ -140,6 +150,10 @@ private constructor( fun isResponseIncomplete(): Boolean = responseIncomplete != null + fun isSafetyAlertCreated(): Boolean = safetyAlertCreated != null + + fun isSafetyOrgAlertCreated(): Boolean = safetyOrgAlertCreated != null + /** Sent when a batch API request has been cancelled. */ fun asBatchCancelled(): BatchCancelledWebhookEvent = batchCancelled.getOrThrow("batchCancelled") @@ -206,6 +220,14 @@ private constructor( fun asResponseIncomplete(): ResponseIncompleteWebhookEvent = responseIncomplete.getOrThrow("responseIncomplete") + /** Sent when an approved safety alert is available for an API project. */ + fun asSafetyAlertCreated(): SafetyAlertCreatedWebhookEvent = + safetyAlertCreated.getOrThrow("safetyAlertCreated") + + /** Sent when an approved safety alert is available for an enterprise workspace. */ + fun asSafetyOrgAlertCreated(): SafetyOrgAlertCreatedWebhookEvent = + safetyOrgAlertCreated.getOrThrow("safetyOrgAlertCreated") + fun _json(): Optional = Optional.ofNullable(_json) /** @@ -257,6 +279,9 @@ private constructor( responseCompleted != null -> visitor.visitResponseCompleted(responseCompleted) responseFailed != null -> visitor.visitResponseFailed(responseFailed) responseIncomplete != null -> visitor.visitResponseIncomplete(responseIncomplete) + safetyAlertCreated != null -> visitor.visitSafetyAlertCreated(safetyAlertCreated) + safetyOrgAlertCreated != null -> + visitor.visitSafetyOrgAlertCreated(safetyOrgAlertCreated) else -> visitor.unknown(_json) } @@ -354,6 +379,18 @@ private constructor( ) { responseIncomplete.validate() } + + override fun visitSafetyAlertCreated( + safetyAlertCreated: SafetyAlertCreatedWebhookEvent + ) { + safetyAlertCreated.validate() + } + + override fun visitSafetyOrgAlertCreated( + safetyOrgAlertCreated: SafetyOrgAlertCreatedWebhookEvent + ) { + safetyOrgAlertCreated.validate() + } } ) validated = true @@ -431,6 +468,14 @@ private constructor( responseIncomplete: ResponseIncompleteWebhookEvent ) = responseIncomplete.validity() + override fun visitSafetyAlertCreated( + safetyAlertCreated: SafetyAlertCreatedWebhookEvent + ) = safetyAlertCreated.validity() + + override fun visitSafetyOrgAlertCreated( + safetyOrgAlertCreated: SafetyOrgAlertCreatedWebhookEvent + ) = safetyOrgAlertCreated.validity() + override fun unknown(json: JsonValue?) = 0 } ) @@ -456,7 +501,9 @@ private constructor( responseCancelled == other.responseCancelled && responseCompleted == other.responseCompleted && responseFailed == other.responseFailed && - responseIncomplete == other.responseIncomplete + responseIncomplete == other.responseIncomplete && + safetyAlertCreated == other.safetyAlertCreated && + safetyOrgAlertCreated == other.safetyOrgAlertCreated } override fun hashCode(): Int = @@ -477,6 +524,8 @@ private constructor( responseCompleted, responseFailed, responseIncomplete, + safetyAlertCreated, + safetyOrgAlertCreated, ) override fun toString(): String = @@ -502,6 +551,10 @@ private constructor( responseFailed != null -> "UnwrapWebhookEvent{responseFailed=$responseFailed}" responseIncomplete != null -> "UnwrapWebhookEvent{responseIncomplete=$responseIncomplete}" + safetyAlertCreated != null -> + "UnwrapWebhookEvent{safetyAlertCreated=$safetyAlertCreated}" + safetyOrgAlertCreated != null -> + "UnwrapWebhookEvent{safetyOrgAlertCreated=$safetyOrgAlertCreated}" _json != null -> "UnwrapWebhookEvent{_unknown=$_json}" else -> throw IllegalStateException("Invalid UnwrapWebhookEvent") } @@ -595,6 +648,16 @@ private constructor( @JvmStatic fun ofResponseIncomplete(responseIncomplete: ResponseIncompleteWebhookEvent) = UnwrapWebhookEvent(responseIncomplete = responseIncomplete) + + /** Sent when an approved safety alert is available for an API project. */ + @JvmStatic + fun ofSafetyAlertCreated(safetyAlertCreated: SafetyAlertCreatedWebhookEvent) = + UnwrapWebhookEvent(safetyAlertCreated = safetyAlertCreated) + + /** Sent when an approved safety alert is available for an enterprise workspace. */ + @JvmStatic + fun ofSafetyOrgAlertCreated(safetyOrgAlertCreated: SafetyOrgAlertCreatedWebhookEvent) = + UnwrapWebhookEvent(safetyOrgAlertCreated = safetyOrgAlertCreated) } /** @@ -663,6 +726,12 @@ private constructor( /** Sent when a background response has been interrupted. */ fun visitResponseIncomplete(responseIncomplete: ResponseIncompleteWebhookEvent): T + /** Sent when an approved safety alert is available for an API project. */ + fun visitSafetyAlertCreated(safetyAlertCreated: SafetyAlertCreatedWebhookEvent): T + + /** Sent when an approved safety alert is available for an enterprise workspace. */ + fun visitSafetyOrgAlertCreated(safetyOrgAlertCreated: SafetyOrgAlertCreatedWebhookEvent): T + /** * Maps an unknown variant of [UnwrapWebhookEvent] to a value of type [T]. * @@ -771,6 +840,16 @@ private constructor( ?.let { UnwrapWebhookEvent(responseIncomplete = it, _json = json) } ?: UnwrapWebhookEvent(_json = json) } + "safety.alert.created" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { UnwrapWebhookEvent(safetyAlertCreated = it, _json = json) } + ?: UnwrapWebhookEvent(_json = json) + } + "safety.org_alert.created" -> { + return tryDeserialize(node, jacksonTypeRef()) + ?.let { UnwrapWebhookEvent(safetyOrgAlertCreated = it, _json = json) } + ?: UnwrapWebhookEvent(_json = json) + } } return UnwrapWebhookEvent(_json = json) @@ -805,6 +884,9 @@ private constructor( value.responseCompleted != null -> generator.writeObject(value.responseCompleted) value.responseFailed != null -> generator.writeObject(value.responseFailed) value.responseIncomplete != null -> generator.writeObject(value.responseIncomplete) + value.safetyAlertCreated != null -> generator.writeObject(value.safetyAlertCreated) + value.safetyOrgAlertCreated != null -> + generator.writeObject(value.safetyOrgAlertCreated) value._json != null -> generator.writeObject(value._json) else -> throw IllegalStateException("Invalid UnwrapWebhookEvent") } diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsync.kt new file mode 100644 index 000000000..7fbffaeb9 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsync.kt @@ -0,0 +1,41 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.async + +import com.openai.core.ClientOptions +import com.openai.services.async.safety.AlertServiceAsync +import java.util.function.Consumer + +interface SafetyServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): SafetyServiceAsync + + fun alerts(): AlertServiceAsync + + /** + * A view of [SafetyServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): SafetyServiceAsync.WithRawResponse + + fun alerts(): AlertServiceAsync.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsyncImpl.kt new file mode 100644 index 000000000..ce6dd5126 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/SafetyServiceAsyncImpl.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.async + +import com.openai.core.ClientOptions +import com.openai.services.async.safety.AlertServiceAsync +import com.openai.services.async.safety.AlertServiceAsyncImpl +import java.util.function.Consumer + +class SafetyServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + SafetyServiceAsync { + + private val withRawResponse: SafetyServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val alerts: AlertServiceAsync by lazy { AlertServiceAsyncImpl(clientOptions) } + + override fun withRawResponse(): SafetyServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): SafetyServiceAsync = + SafetyServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun alerts(): AlertServiceAsync = alerts + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SafetyServiceAsync.WithRawResponse { + + private val alerts: AlertServiceAsync.WithRawResponse by lazy { + AlertServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): SafetyServiceAsync.WithRawResponse = + SafetyServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun alerts(): AlertServiceAsync.WithRawResponse = alerts + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsync.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsync.kt new file mode 100644 index 000000000..4064ea5a1 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsync.kt @@ -0,0 +1,109 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.async.safety + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponseFor +import com.openai.models.safety.alerts.AlertRetrieveParams +import com.openai.models.safety.alerts.SafetyAlert +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface AlertServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): AlertServiceAsync + + /** Get a safety alert belonging to the authenticated API project. */ + fun retrieve(id: String): CompletableFuture = + retrieve(id, AlertRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + ): CompletableFuture = retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see retrieve */ + fun retrieve(params: AlertRetrieveParams): CompletableFuture = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve(id: String, requestOptions: RequestOptions): CompletableFuture = + retrieve(id, AlertRetrieveParams.none(), requestOptions) + + /** A view of [AlertServiceAsync] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): AlertServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `get /safety/alerts/{id}`, but is otherwise the same as + * [AlertServiceAsync.retrieve]. + */ + fun retrieve(id: String): CompletableFuture> = + retrieve(id, AlertRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + ): CompletableFuture> = + retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see retrieve */ + fun retrieve(params: AlertRetrieveParams): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve(id, AlertRetrieveParams.none(), requestOptions) + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsyncImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsyncImpl.kt new file mode 100644 index 000000000..583e9d80b --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/async/safety/AlertServiceAsyncImpl.kt @@ -0,0 +1,94 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.async.safety + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.SecurityOptions +import com.openai.core.checkRequired +import com.openai.core.handlers.errorBodyHandler +import com.openai.core.handlers.errorHandler +import com.openai.core.handlers.jsonHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.HttpResponseFor +import com.openai.core.http.parseable +import com.openai.core.prepareAsync +import com.openai.models.safety.alerts.AlertRetrieveParams +import com.openai.models.safety.alerts.SafetyAlert +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class AlertServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + AlertServiceAsync { + + private val withRawResponse: AlertServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): AlertServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): AlertServiceAsync = + AlertServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /safety/alerts/{id} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AlertServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): AlertServiceAsync.WithRawResponse = + AlertServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("safety", "alerts", params._pathParam(0)) + .build() + .prepareAsync( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyService.kt new file mode 100644 index 000000000..0e134bfcc --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyService.kt @@ -0,0 +1,37 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.blocking + +import com.openai.core.ClientOptions +import com.openai.services.blocking.safety.AlertService +import java.util.function.Consumer + +interface SafetyService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): SafetyService + + fun alerts(): AlertService + + /** A view of [SafetyService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): SafetyService.WithRawResponse + + fun alerts(): AlertService.WithRawResponse + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyServiceImpl.kt new file mode 100644 index 000000000..afd5b5704 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/SafetyServiceImpl.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.blocking + +import com.openai.core.ClientOptions +import com.openai.services.blocking.safety.AlertService +import com.openai.services.blocking.safety.AlertServiceImpl +import java.util.function.Consumer + +class SafetyServiceImpl internal constructor(private val clientOptions: ClientOptions) : + SafetyService { + + private val withRawResponse: SafetyService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + private val alerts: AlertService by lazy { AlertServiceImpl(clientOptions) } + + override fun withRawResponse(): SafetyService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): SafetyService = + SafetyServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun alerts(): AlertService = alerts + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + SafetyService.WithRawResponse { + + private val alerts: AlertService.WithRawResponse by lazy { + AlertServiceImpl.WithRawResponseImpl(clientOptions) + } + + override fun withOptions( + modifier: Consumer + ): SafetyService.WithRawResponse = + SafetyServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun alerts(): AlertService.WithRawResponse = alerts + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertService.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertService.kt new file mode 100644 index 000000000..877e6bbfe --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertService.kt @@ -0,0 +1,107 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.blocking.safety + +import com.google.errorprone.annotations.MustBeClosed +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.http.HttpResponseFor +import com.openai.models.safety.alerts.AlertRetrieveParams +import com.openai.models.safety.alerts.SafetyAlert +import java.util.function.Consumer + +interface AlertService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): AlertService + + /** Get a safety alert belonging to the authenticated API project. */ + fun retrieve(id: String): SafetyAlert = retrieve(id, AlertRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): SafetyAlert = retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + ): SafetyAlert = retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): SafetyAlert + + /** @see retrieve */ + fun retrieve(params: AlertRetrieveParams): SafetyAlert = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve(id: String, requestOptions: RequestOptions): SafetyAlert = + retrieve(id, AlertRetrieveParams.none(), requestOptions) + + /** A view of [AlertService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): AlertService.WithRawResponse + + /** + * Returns a raw HTTP response for `get /safety/alerts/{id}`, but is otherwise the same as + * [AlertService.retrieve]. + */ + @MustBeClosed + fun retrieve(id: String): HttpResponseFor = + retrieve(id, AlertRetrieveParams.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().id(id).build(), requestOptions) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + id: String, + params: AlertRetrieveParams = AlertRetrieveParams.none(), + ): HttpResponseFor = retrieve(id, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see retrieve */ + @MustBeClosed + fun retrieve(params: AlertRetrieveParams): HttpResponseFor = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve(id: String, requestOptions: RequestOptions): HttpResponseFor = + retrieve(id, AlertRetrieveParams.none(), requestOptions) + } +} diff --git a/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertServiceImpl.kt b/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertServiceImpl.kt new file mode 100644 index 000000000..aaf9eba75 --- /dev/null +++ b/openai-java-core/src/main/kotlin/com/openai/services/blocking/safety/AlertServiceImpl.kt @@ -0,0 +1,90 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.blocking.safety + +import com.openai.core.ClientOptions +import com.openai.core.RequestOptions +import com.openai.core.SecurityOptions +import com.openai.core.checkRequired +import com.openai.core.handlers.errorBodyHandler +import com.openai.core.handlers.errorHandler +import com.openai.core.handlers.jsonHandler +import com.openai.core.http.HttpMethod +import com.openai.core.http.HttpRequest +import com.openai.core.http.HttpResponse +import com.openai.core.http.HttpResponse.Handler +import com.openai.core.http.HttpResponseFor +import com.openai.core.http.parseable +import com.openai.core.prepare +import com.openai.models.safety.alerts.AlertRetrieveParams +import com.openai.models.safety.alerts.SafetyAlert +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class AlertServiceImpl internal constructor(private val clientOptions: ClientOptions) : + AlertService { + + private val withRawResponse: AlertService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): AlertService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): AlertService = + AlertServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions, + ): SafetyAlert = + // get /safety/alerts/{id} + withRawResponse().retrieve(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + AlertService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): AlertService.WithRawResponse = + AlertServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: AlertRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("id", params.id().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("safety", "alerts", params._pathParam(0)) + .build() + .prepare( + clientOptions, + params, + SecurityOptions.builder().bearerAuth(true).build(), + ) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/AllModelsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/AllModelsTest.kt index 53611a94f..c3a18db2b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/AllModelsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/AllModelsTest.kt @@ -41,7 +41,7 @@ internal class AllModelsTest { @Test fun ofChatModel() { - val chatModel = ChatModel.GPT_5_6_SOL + val chatModel = ChatModel.GPT_6_ASTRA val allModels = AllModels.ofChatModel(chatModel) @@ -53,7 +53,7 @@ internal class AllModelsTest { @Test fun ofChatModelRoundtrip() { val jsonMapper = jsonMapper() - val allModels = AllModels.ofChatModel(ChatModel.GPT_5_6_SOL) + val allModels = AllModels.ofChatModel(ChatModel.GPT_6_ASTRA) val roundtrippedAllModels = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/ErrorObjectTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/ErrorObjectTest.kt index 24b736f67..f29e3261e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/ErrorObjectTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/ErrorObjectTest.kt @@ -17,12 +17,31 @@ internal class ErrorObjectTest { .message("message") .param("param") .type("type") + .misalignment( + ErrorObject.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ErrorObject.Misalignment.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer(ErrorObject.Misalignment.Steer.builder().message("message").build()) + .build() + ) .build() assertThat(errorObject.code()).contains("code") assertThat(errorObject.message()).isEqualTo("message") assertThat(errorObject.param()).contains("param") assertThat(errorObject.type()).isEqualTo("type") + assertThat(errorObject.misalignment()) + .contains( + ErrorObject.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ErrorObject.Misalignment.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer(ErrorObject.Misalignment.Steer.builder().message("message").build()) + .build() + ) } @Test @@ -34,6 +53,15 @@ internal class ErrorObjectTest { .message("message") .param("param") .type("type") + .misalignment( + ErrorObject.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ErrorObject.Misalignment.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer(ErrorObject.Misalignment.Steer.builder().message("message").build()) + .build() + ) .build() val roundtrippedErrorObject = diff --git a/openai-java-core/src/test/kotlin/com/openai/models/ResponsesModelTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/ResponsesModelTest.kt index 30ab58da9..fea86fbdf 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/ResponsesModelTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/ResponsesModelTest.kt @@ -41,7 +41,7 @@ internal class ResponsesModelTest { @Test fun ofChat() { - val chat = ChatModel.GPT_5_6_SOL + val chat = ChatModel.GPT_6_ASTRA val responsesModel = ResponsesModel.ofChat(chat) @@ -53,7 +53,7 @@ internal class ResponsesModelTest { @Test fun ofChatRoundtrip() { val jsonMapper = jsonMapper() - val responsesModel = ResponsesModel.ofChat(ChatModel.GPT_5_6_SOL) + val responsesModel = ResponsesModel.ofChat(ChatModel.GPT_6_ASTRA) val roundtrippedResponsesModel = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/assistants/AssistantStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/assistants/AssistantStreamEventTest.kt index 3d13045f8..3f1b5992d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/assistants/AssistantStreamEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/assistants/AssistantStreamEventTest.kt @@ -3570,6 +3570,20 @@ internal class AssistantStreamEventTest { .message("message") .param("param") .type("type") + .misalignment( + ErrorObject.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ErrorObject.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ErrorObject.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .build() @@ -3614,6 +3628,20 @@ internal class AssistantStreamEventTest { .message("message") .param("param") .type("type") + .misalignment( + ErrorObject.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ErrorObject.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ErrorObject.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaCustomToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaCustomToolTest.kt index 674833330..14f21d050 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaCustomToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaCustomToolTest.kt @@ -16,6 +16,7 @@ internal class BetaCustomToolTest { BetaCustomTool.builder() .name("name") .addAllowedCaller(BetaCustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -24,6 +25,7 @@ internal class BetaCustomToolTest { assertThat(betaCustomTool.name()).isEqualTo("name") assertThat(betaCustomTool.allowedCallers().getOrNull()) .containsExactly(BetaCustomTool.AllowedCaller.DIRECT) + assertThat(betaCustomTool.async()).contains(true) assertThat(betaCustomTool.deferLoading()).contains(true) assertThat(betaCustomTool.description()).contains("description") assertThat(betaCustomTool.format()).contains(BetaCustomTool.Format.ofText()) @@ -36,6 +38,7 @@ internal class BetaCustomToolTest { BetaCustomTool.builder() .name("name") .addAllowedCaller(BetaCustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaFunctionToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaFunctionToolTest.kt index a660d6f25..16d01559c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaFunctionToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaFunctionToolTest.kt @@ -23,6 +23,7 @@ internal class BetaFunctionToolTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -42,6 +43,7 @@ internal class BetaFunctionToolTest { assertThat(betaFunctionTool.strict()).contains(true) assertThat(betaFunctionTool.allowedCallers().getOrNull()) .containsExactly(BetaFunctionTool.AllowedCaller.DIRECT) + assertThat(betaFunctionTool.async()).contains(true) assertThat(betaFunctionTool.deferLoading()).contains(true) assertThat(betaFunctionTool.description()).contains("description") assertThat(betaFunctionTool.outputSchema()) @@ -65,6 +67,7 @@ internal class BetaFunctionToolTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaNamespaceToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaNamespaceToolTest.kt index 84c49d1b6..4765b05da 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaNamespaceToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaNamespaceToolTest.kt @@ -20,6 +20,7 @@ internal class BetaNamespaceToolTest { BetaNamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(BetaNamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -41,6 +42,7 @@ internal class BetaNamespaceToolTest { BetaNamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(BetaNamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -66,6 +68,7 @@ internal class BetaNamespaceToolTest { BetaNamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(BetaNamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCompletedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCompletedEventTest.kt index a55442dfa..49e2c69c2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCompletedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCompletedEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseCompletedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseCompletedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseCompletedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParamTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParamTest.kt new file mode 100644 index 000000000..0ef9821aa --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemParamTest.kt @@ -0,0 +1,71 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseConfigurationUpdateItemParamTest { + + @Test + fun create() { + val betaResponseConfigurationUpdateItemParam = + BetaResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItemParam.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItemParam.Reasoning.Effort.NONE) + .build() + ) + .build() + + assertThat(betaResponseConfigurationUpdateItemParam.id()).contains("cnfu_123") + assertThat(betaResponseConfigurationUpdateItemParam.agent()) + .contains( + BetaResponseConfigurationUpdateItemParam.Agent.builder() + .agentName("agent_name") + .build() + ) + assertThat(betaResponseConfigurationUpdateItemParam.reasoning()) + .contains( + BetaResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItemParam.Reasoning.Effort.NONE) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseConfigurationUpdateItemParam = + BetaResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItemParam.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItemParam.Reasoning.Effort.NONE) + .build() + ) + .build() + + val roundtrippedBetaResponseConfigurationUpdateItemParam = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseConfigurationUpdateItemParam), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseConfigurationUpdateItemParam) + .isEqualTo(betaResponseConfigurationUpdateItemParam) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemTest.kt new file mode 100644 index 000000000..37761c8d9 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseConfigurationUpdateItemTest.kt @@ -0,0 +1,69 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseConfigurationUpdateItemTest { + + @Test + fun create() { + val betaResponseConfigurationUpdateItem = + BetaResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItem.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItem.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItem.Reasoning.Effort.NONE) + .build() + ) + .build() + + assertThat(betaResponseConfigurationUpdateItem.id()).isEqualTo("cnfu_123") + assertThat(betaResponseConfigurationUpdateItem.agent()) + .contains( + BetaResponseConfigurationUpdateItem.Agent.builder().agentName("agent_name").build() + ) + assertThat(betaResponseConfigurationUpdateItem.reasoning()) + .contains( + BetaResponseConfigurationUpdateItem.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItem.Reasoning.Effort.NONE) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseConfigurationUpdateItem = + BetaResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItem.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItem.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItem.Reasoning.Effort.NONE) + .build() + ) + .build() + + val roundtrippedBetaResponseConfigurationUpdateItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseConfigurationUpdateItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseConfigurationUpdateItem) + .isEqualTo(betaResponseConfigurationUpdateItem) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCreatedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCreatedEventTest.kt index fd3813c5b..30d552760 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCreatedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCreatedEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseCreatedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseCreatedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseCreatedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItemTest.kt index 5f0e233e6..f2562bf0f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallItemTest.kt @@ -18,6 +18,7 @@ internal class BetaResponseCustomToolCallItemTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -30,6 +31,7 @@ internal class BetaResponseCustomToolCallItemTest { assertThat(betaResponseCustomToolCallItem.id()).contains("id") assertThat(betaResponseCustomToolCallItem.agent()) .contains(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + assertThat(betaResponseCustomToolCallItem.async()).contains(true) assertThat(betaResponseCustomToolCallItem.caller()) .contains(BetaResponseCustomToolCall.Caller.ofDirect()) assertThat(betaResponseCustomToolCallItem.namespace()).contains("namespace") @@ -48,6 +50,7 @@ internal class BetaResponseCustomToolCallItemTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseCustomToolCallItem.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallTest.kt index 877a0e60a..bb275a135 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseCustomToolCallTest.kt @@ -18,6 +18,7 @@ internal class BetaResponseCustomToolCallTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .build() @@ -28,6 +29,7 @@ internal class BetaResponseCustomToolCallTest { assertThat(betaResponseCustomToolCall.id()).contains("id") assertThat(betaResponseCustomToolCall.agent()) .contains(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + assertThat(betaResponseCustomToolCall.async()).contains(true) assertThat(betaResponseCustomToolCall.caller()) .contains(BetaResponseCustomToolCall.Caller.ofDirect()) assertThat(betaResponseCustomToolCall.namespace()).contains("namespace") @@ -43,6 +45,7 @@ internal class BetaResponseCustomToolCallTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseErrorTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseErrorTest.kt index 87f3241d2..d7b9045e1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseErrorTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseErrorTest.kt @@ -15,10 +15,37 @@ internal class BetaResponseErrorTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() assertThat(betaResponseError.code()).isEqualTo(BetaResponseError.Code.SERVER_ERROR) assertThat(betaResponseError.message()).isEqualTo("message") + assertThat(betaResponseError.misalignment()) + .contains( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder().message("message").build() + ) + .build() + ) } @Test @@ -28,6 +55,20 @@ internal class BetaResponseErrorTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() val roundtrippedBetaResponseError = diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFailedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFailedEventTest.kt index 4b3020743..90f51907a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFailedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFailedEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseFailedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseFailedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseFailedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseFailedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseFailedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseFailedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItemTest.kt index 6a53e2174..ce6fc3267 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallItemTest.kt @@ -18,6 +18,7 @@ internal class BetaResponseFunctionToolCallItemTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -30,6 +31,7 @@ internal class BetaResponseFunctionToolCallItemTest { assertThat(betaResponseFunctionToolCallItem.id()).contains("id") assertThat(betaResponseFunctionToolCallItem.agent()) .contains(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + assertThat(betaResponseFunctionToolCallItem.async()).contains(true) assertThat(betaResponseFunctionToolCallItem.caller()) .contains(BetaResponseFunctionToolCall.Caller.ofDirect()) assertThat(betaResponseFunctionToolCallItem.namespace()).contains("namespace") @@ -48,6 +50,7 @@ internal class BetaResponseFunctionToolCallItemTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallTest.kt index 1633dd948..2fb0c9c0a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseFunctionToolCallTest.kt @@ -18,6 +18,7 @@ internal class BetaResponseFunctionToolCallTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -29,6 +30,7 @@ internal class BetaResponseFunctionToolCallTest { assertThat(betaResponseFunctionToolCall.id()).contains("id") assertThat(betaResponseFunctionToolCall.agent()) .contains(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + assertThat(betaResponseFunctionToolCall.async()).contains(true) assertThat(betaResponseFunctionToolCall.caller()) .contains(BetaResponseFunctionToolCall.Caller.ofDirect()) assertThat(betaResponseFunctionToolCall.namespace()).contains("namespace") @@ -46,6 +48,7 @@ internal class BetaResponseFunctionToolCallTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInProgressEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInProgressEventTest.kt index bf5810ed4..d5093b000 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInProgressEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInProgressEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseInProgressEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseInProgressEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseInProgressEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEventTest.kt index de634f0c4..c4ae12fc2 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseIncompleteEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseIncompleteEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseIncompleteEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseIncompleteEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInputItemTest.kt index 75965d79f..ae4c1c392 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseInputItemTest.kt @@ -42,6 +42,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -123,6 +124,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -234,6 +236,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -348,6 +351,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -460,6 +464,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -574,6 +579,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -674,6 +680,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -741,6 +748,7 @@ internal class BetaResponseInputItemTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -763,6 +771,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -798,6 +807,7 @@ internal class BetaResponseInputItemTest { .agent( BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -848,6 +858,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -939,6 +950,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1027,6 +1039,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1122,6 +1135,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1217,6 +1231,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).contains(toolSearchCall) assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1281,6 +1296,7 @@ internal class BetaResponseInputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1318,6 +1334,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).contains(toolSearchOutput) assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1356,6 +1373,7 @@ internal class BetaResponseInputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1400,6 +1418,7 @@ internal class BetaResponseInputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1434,6 +1453,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).contains(additionalTools) + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1472,6 +1492,7 @@ internal class BetaResponseInputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1499,6 +1520,92 @@ internal class BetaResponseInputItemTest { assertThat(roundtrippedBetaResponseInputItem).isEqualTo(betaResponseInputItem) } + @Test + fun ofConfigurationUpdate() { + val configurationUpdate = + BetaResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItemParam.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItemParam.Reasoning.Effort.NONE) + .build() + ) + .build() + + val betaResponseInputItem = BetaResponseInputItem.ofConfigurationUpdate(configurationUpdate) + + assertThat(betaResponseInputItem.betaEasyInputMessage()).isEmpty + assertThat(betaResponseInputItem.message()).isEmpty + assertThat(betaResponseInputItem.betaResponseOutputMessage()).isEmpty + assertThat(betaResponseInputItem.fileSearchCall()).isEmpty + assertThat(betaResponseInputItem.computerCall()).isEmpty + assertThat(betaResponseInputItem.computerCallOutput()).isEmpty + assertThat(betaResponseInputItem.webSearchCall()).isEmpty + assertThat(betaResponseInputItem.functionCall()).isEmpty + assertThat(betaResponseInputItem.functionCallOutput()).isEmpty + assertThat(betaResponseInputItem.agentMessage()).isEmpty + assertThat(betaResponseInputItem.multiAgentCall()).isEmpty + assertThat(betaResponseInputItem.multiAgentCallOutput()).isEmpty + assertThat(betaResponseInputItem.toolSearchCall()).isEmpty + assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty + assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).contains(configurationUpdate) + assertThat(betaResponseInputItem.reasoning()).isEmpty + assertThat(betaResponseInputItem.compaction()).isEmpty + assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty + assertThat(betaResponseInputItem.codeInterpreterCall()).isEmpty + assertThat(betaResponseInputItem.localShellCall()).isEmpty + assertThat(betaResponseInputItem.localShellCallOutput()).isEmpty + assertThat(betaResponseInputItem.shellCall()).isEmpty + assertThat(betaResponseInputItem.shellCallOutput()).isEmpty + assertThat(betaResponseInputItem.applyPatchCall()).isEmpty + assertThat(betaResponseInputItem.applyPatchCallOutput()).isEmpty + assertThat(betaResponseInputItem.mcpListTools()).isEmpty + assertThat(betaResponseInputItem.mcpApprovalRequest()).isEmpty + assertThat(betaResponseInputItem.mcpApprovalResponse()).isEmpty + assertThat(betaResponseInputItem.mcpCall()).isEmpty + assertThat(betaResponseInputItem.customToolCallOutput()).isEmpty + assertThat(betaResponseInputItem.customToolCall()).isEmpty + assertThat(betaResponseInputItem.compactionTrigger()).isEmpty + assertThat(betaResponseInputItem.itemReference()).isEmpty + assertThat(betaResponseInputItem.program()).isEmpty + assertThat(betaResponseInputItem.programOutput()).isEmpty + } + + @Test + fun ofConfigurationUpdateRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseInputItem = + BetaResponseInputItem.ofConfigurationUpdate( + BetaResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItemParam.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItemParam.Reasoning.Effort.NONE) + .build() + ) + .build() + ) + + val roundtrippedBetaResponseInputItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseInputItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseInputItem).isEqualTo(betaResponseInputItem) + } + @Test fun ofReasoning() { val reasoning = @@ -1528,6 +1635,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).contains(reasoning) assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1604,6 +1712,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).contains(compaction) assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1682,6 +1791,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).contains(imageGenerationCall) @@ -1763,6 +1873,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1857,6 +1968,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -1950,6 +2062,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2046,6 +2159,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2153,6 +2267,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2248,6 +2363,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2337,6 +2453,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2426,6 +2543,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2514,6 +2632,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2595,6 +2714,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2683,6 +2803,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2772,6 +2893,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2830,6 +2952,7 @@ internal class BetaResponseInputItemTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2851,6 +2974,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -2886,6 +3010,7 @@ internal class BetaResponseInputItemTest { .agent( BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2928,6 +3053,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -3003,6 +3129,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -3080,6 +3207,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty @@ -3161,6 +3289,7 @@ internal class BetaResponseInputItemTest { assertThat(betaResponseInputItem.toolSearchCall()).isEmpty assertThat(betaResponseInputItem.toolSearchOutput()).isEmpty assertThat(betaResponseInputItem.additionalTools()).isEmpty + assertThat(betaResponseInputItem.configurationUpdate()).isEmpty assertThat(betaResponseInputItem.reasoning()).isEmpty assertThat(betaResponseInputItem.compaction()).isEmpty assertThat(betaResponseInputItem.imageGenerationCall()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseItemTest.kt index 0dd6cd652..7748e8b1a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseItemTest.kt @@ -50,6 +50,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -155,6 +156,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -266,6 +268,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -375,6 +378,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -487,6 +491,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -585,6 +590,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -650,6 +656,7 @@ internal class BetaResponseItemTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -672,6 +679,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -705,6 +713,7 @@ internal class BetaResponseItemTest { .agent( BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -756,6 +765,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -843,6 +853,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -926,6 +937,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1029,6 +1041,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1130,6 +1143,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).contains(toolSearchCall) assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1195,6 +1209,7 @@ internal class BetaResponseItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1226,6 +1241,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).contains(toolSearchOutput) assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1266,6 +1282,7 @@ internal class BetaResponseItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1309,6 +1326,7 @@ internal class BetaResponseItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1339,6 +1357,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).contains(additionalTools) + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1377,6 +1396,7 @@ internal class BetaResponseItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1403,6 +1423,89 @@ internal class BetaResponseItemTest { assertThat(roundtrippedBetaResponseItem).isEqualTo(betaResponseItem) } + @Test + fun ofConfigurationUpdate() { + val configurationUpdate = + BetaResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItem.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItem.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItem.Reasoning.Effort.NONE) + .build() + ) + .build() + + val betaResponseItem = BetaResponseItem.ofConfigurationUpdate(configurationUpdate) + + assertThat(betaResponseItem.betaResponseInputMessageItem()).isEmpty + assertThat(betaResponseItem.betaResponseOutputMessage()).isEmpty + assertThat(betaResponseItem.fileSearchCall()).isEmpty + assertThat(betaResponseItem.computerCall()).isEmpty + assertThat(betaResponseItem.computerCallOutput()).isEmpty + assertThat(betaResponseItem.webSearchCall()).isEmpty + assertThat(betaResponseItem.functionCall()).isEmpty + assertThat(betaResponseItem.functionCallOutput()).isEmpty + assertThat(betaResponseItem.agentMessage()).isEmpty + assertThat(betaResponseItem.multiAgentCall()).isEmpty + assertThat(betaResponseItem.multiAgentCallOutput()).isEmpty + assertThat(betaResponseItem.toolSearchCall()).isEmpty + assertThat(betaResponseItem.toolSearchOutput()).isEmpty + assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).contains(configurationUpdate) + assertThat(betaResponseItem.reasoning()).isEmpty + assertThat(betaResponseItem.program()).isEmpty + assertThat(betaResponseItem.programOutput()).isEmpty + assertThat(betaResponseItem.compaction()).isEmpty + assertThat(betaResponseItem.imageGenerationCall()).isEmpty + assertThat(betaResponseItem.codeInterpreterCall()).isEmpty + assertThat(betaResponseItem.localShellCall()).isEmpty + assertThat(betaResponseItem.localShellCallOutput()).isEmpty + assertThat(betaResponseItem.shellCall()).isEmpty + assertThat(betaResponseItem.shellCallOutput()).isEmpty + assertThat(betaResponseItem.applyPatchCall()).isEmpty + assertThat(betaResponseItem.applyPatchCallOutput()).isEmpty + assertThat(betaResponseItem.mcpListTools()).isEmpty + assertThat(betaResponseItem.mcpApprovalRequest()).isEmpty + assertThat(betaResponseItem.mcpApprovalResponse()).isEmpty + assertThat(betaResponseItem.mcpCall()).isEmpty + assertThat(betaResponseItem.customToolCall()).isEmpty + assertThat(betaResponseItem.customToolCallOutput()).isEmpty + } + + @Test + fun ofConfigurationUpdateRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseItem = + BetaResponseItem.ofConfigurationUpdate( + BetaResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .agent( + BetaResponseConfigurationUpdateItem.Agent.builder() + .agentName("agent_name") + .build() + ) + .reasoning( + BetaResponseConfigurationUpdateItem.Reasoning.builder() + .effort(BetaResponseConfigurationUpdateItem.Reasoning.Effort.NONE) + .build() + ) + .build() + ) + + val roundtrippedBetaResponseItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseItem).isEqualTo(betaResponseItem) + } + @Test fun ofReasoning() { val reasoning = @@ -1431,6 +1534,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).contains(reasoning) assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1504,6 +1608,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).contains(program) assertThat(betaResponseItem.programOutput()).isEmpty @@ -1576,6 +1681,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).contains(programOutput) @@ -1649,6 +1755,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1723,6 +1830,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1801,6 +1909,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1890,6 +1999,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -1979,6 +2089,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2065,6 +2176,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2162,6 +2274,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2255,6 +2368,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2342,6 +2456,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2427,6 +2542,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2512,6 +2628,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2590,6 +2707,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2673,6 +2791,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2734,6 +2853,7 @@ internal class BetaResponseItemTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -2756,6 +2876,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty @@ -2789,6 +2910,7 @@ internal class BetaResponseItemTest { .agent( BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -2836,6 +2958,7 @@ internal class BetaResponseItemTest { assertThat(betaResponseItem.toolSearchCall()).isEmpty assertThat(betaResponseItem.toolSearchOutput()).isEmpty assertThat(betaResponseItem.additionalTools()).isEmpty + assertThat(betaResponseItem.configurationUpdate()).isEmpty assertThat(betaResponseItem.reasoning()).isEmpty assertThat(betaResponseItem.program()).isEmpty assertThat(betaResponseItem.programOutput()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseOutputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseOutputItemTest.kt index 43aed6412..1c1a98032 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseOutputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseOutputItemTest.kt @@ -243,6 +243,7 @@ internal class BetaResponseOutputItemTest { .name("name") .id("id") .agent(BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -296,6 +297,7 @@ internal class BetaResponseOutputItemTest { .agent( BetaResponseFunctionToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .status(BetaResponseFunctionToolCall.Status.IN_PROGRESS) @@ -1323,6 +1325,7 @@ internal class BetaResponseOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1393,6 +1396,7 @@ internal class BetaResponseOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1436,6 +1440,7 @@ internal class BetaResponseOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1505,6 +1510,7 @@ internal class BetaResponseOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2644,6 +2650,7 @@ internal class BetaResponseOutputItemTest { .name("name") .id("id") .agent(BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build()) + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2696,6 +2703,7 @@ internal class BetaResponseOutputItemTest { .agent( BetaResponseCustomToolCall.Agent.builder().agentName("agent_name").build() ) + .async(true) .callerDirect() .namespace("namespace") .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseQueuedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseQueuedEventTest.kt index 76cb6781c..40c28726d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseQueuedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseQueuedEventTest.kt @@ -22,6 +22,20 @@ internal class BetaResponseQueuedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -35,7 +49,7 @@ internal class BetaResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -88,6 +102,7 @@ internal class BetaResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -241,6 +256,20 @@ internal class BetaResponseQueuedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -254,7 +283,7 @@ internal class BetaResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -306,6 +335,7 @@ internal class BetaResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -462,6 +492,20 @@ internal class BetaResponseQueuedEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -475,7 +519,7 @@ internal class BetaResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -528,6 +572,7 @@ internal class BetaResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEventTest.kt new file mode 100644 index 000000000..9a53401df --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerAcceptedEventTest.kt @@ -0,0 +1,61 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseSteerAcceptedEventTest { + + @Test + fun create() { + val betaResponseSteerAcceptedEvent = + BetaResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(betaResponseSteerAcceptedEvent.sequenceNumber()).isEqualTo(0L) + assertThat(betaResponseSteerAcceptedEvent.steer()) + .isEqualTo( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + assertThat(betaResponseSteerAcceptedEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerAcceptedEvent = + BetaResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedBetaResponseSteerAcceptedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerAcceptedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerAcceptedEvent) + .isEqualTo(betaResponseSteerAcceptedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerEventTest.kt new file mode 100644 index 000000000..3c653a52d --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerEventTest.kt @@ -0,0 +1,42 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseSteerEventTest { + + @Test + fun create() { + val betaResponseSteerEvent = + BetaResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + + assertThat(betaResponseSteerEvent.input()) + .isEqualTo(BetaResponseSteerInput.ofText("string")) + assertThat(betaResponseSteerEvent.previousResponseId()).isEqualTo("previous_response_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerEvent = + BetaResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + + val roundtrippedBetaResponseSteerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerEvent).isEqualTo(betaResponseSteerEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEventTest.kt new file mode 100644 index 000000000..002166804 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerFailedEventTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseSteerFailedEventTest { + + @Test + fun create() { + val betaResponseSteerFailedEvent = + BetaResponseSteerFailedEvent.builder() + .error( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(betaResponseSteerFailedEvent.error()) + .isEqualTo( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + assertThat(betaResponseSteerFailedEvent.sequenceNumber()).isEqualTo(0L) + assertThat(betaResponseSteerFailedEvent.steer()) + .isEqualTo( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + assertThat(betaResponseSteerFailedEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerFailedEvent = + BetaResponseSteerFailedEvent.builder() + .error( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedBetaResponseSteerFailedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerFailedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerFailedEvent).isEqualTo(betaResponseSteerFailedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContentTest.kt new file mode 100644 index 000000000..9cf2312d0 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputContentTest.kt @@ -0,0 +1,168 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class BetaResponseSteerInputContentTest { + + @Test + fun ofInputText() { + val inputText = + BetaResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + BetaResponseInputTextContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val betaResponseSteerInputContent = BetaResponseSteerInputContent.ofInputText(inputText) + + assertThat(betaResponseSteerInputContent.inputText()).contains(inputText) + assertThat(betaResponseSteerInputContent.inputImage()).isEmpty + assertThat(betaResponseSteerInputContent.inputFile()).isEmpty + } + + @Test + fun ofInputTextRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerInputContent = + BetaResponseSteerInputContent.ofInputText( + BetaResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + BetaResponseInputTextContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedBetaResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerInputContent) + .isEqualTo(betaResponseSteerInputContent) + } + + @Test + fun ofInputImage() { + val inputImage = + BetaResponseInputImageContent.builder() + .detail(BetaResponseInputImageContent.Detail.LOW) + .fileId("file-123") + .imageUrl("https://example.com") + .promptCacheBreakpoint( + BetaResponseInputImageContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val betaResponseSteerInputContent = BetaResponseSteerInputContent.ofInputImage(inputImage) + + assertThat(betaResponseSteerInputContent.inputText()).isEmpty + assertThat(betaResponseSteerInputContent.inputImage()).contains(inputImage) + assertThat(betaResponseSteerInputContent.inputFile()).isEmpty + } + + @Test + fun ofInputImageRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerInputContent = + BetaResponseSteerInputContent.ofInputImage( + BetaResponseInputImageContent.builder() + .detail(BetaResponseInputImageContent.Detail.LOW) + .fileId("file-123") + .imageUrl("https://example.com") + .promptCacheBreakpoint( + BetaResponseInputImageContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedBetaResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerInputContent) + .isEqualTo(betaResponseSteerInputContent) + } + + @Test + fun ofInputFile() { + val inputFile = + BetaResponseInputFileContent.builder() + .detail(BetaResponseInputFileContent.Detail.AUTO) + .fileData("file_data") + .fileId("file-123") + .fileUrl("https://example.com") + .filename("filename") + .promptCacheBreakpoint( + BetaResponseInputFileContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val betaResponseSteerInputContent = BetaResponseSteerInputContent.ofInputFile(inputFile) + + assertThat(betaResponseSteerInputContent.inputText()).isEmpty + assertThat(betaResponseSteerInputContent.inputImage()).isEmpty + assertThat(betaResponseSteerInputContent.inputFile()).contains(inputFile) + } + + @Test + fun ofInputFileRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerInputContent = + BetaResponseSteerInputContent.ofInputFile( + BetaResponseInputFileContent.builder() + .detail(BetaResponseInputFileContent.Detail.AUTO) + .fileData("file_data") + .fileId("file-123") + .fileUrl("https://example.com") + .filename("filename") + .promptCacheBreakpoint( + BetaResponseInputFileContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedBetaResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerInputContent) + .isEqualTo(betaResponseSteerInputContent) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val betaResponseSteerInputContent = + jsonMapper() + .convertValue(testCase.value, jacksonTypeRef()) + + val e = + assertThrows { betaResponseSteerInputContent.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputTest.kt new file mode 100644 index 000000000..4745243a0 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerInputTest.kt @@ -0,0 +1,140 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class BetaResponseSteerInputTest { + + @Test + fun ofText() { + val text = "string" + + val betaResponseSteerInput = BetaResponseSteerInput.ofText(text) + + assertThat(betaResponseSteerInput.text()).contains(text) + assertThat(betaResponseSteerInput.responseSteerInputItemList()).isEmpty + } + + @Test + fun ofTextRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerInput = BetaResponseSteerInput.ofText("string") + + val roundtrippedBetaResponseSteerInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerInput).isEqualTo(betaResponseSteerInput) + } + + @Test + fun ofResponseSteerInputItemList() { + val responseSteerInputItemList = + listOf( + BetaResponseSteerInput.ResponseSteerInputItem.ofMessage( + BetaResponseSteerInput.ResponseSteerInputItem.Message.builder() + .contentOfBetaResponseSteerInputContents( + listOf( + BetaResponseSteerInputContent.ofInputText( + BetaResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + BetaResponseInputTextContent.PromptCacheBreakpoint + .builder() + .build() + ) + .build() + ) + ) + ) + .id("msg_123") + .agent( + BetaResponseSteerInput.ResponseSteerInputItem.Message.Agent.builder() + .agentName("agent_name") + .build() + ) + .status("status") + .build() + ) + ) + + val betaResponseSteerInput = + BetaResponseSteerInput.ofResponseSteerInputItemList(responseSteerInputItemList) + + assertThat(betaResponseSteerInput.text()).isEmpty + assertThat(betaResponseSteerInput.responseSteerInputItemList()) + .contains(responseSteerInputItemList) + } + + @Test + fun ofResponseSteerInputItemListRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerInput = + BetaResponseSteerInput.ofResponseSteerInputItemList( + listOf( + BetaResponseSteerInput.ResponseSteerInputItem.ofMessage( + BetaResponseSteerInput.ResponseSteerInputItem.Message.builder() + .contentOfBetaResponseSteerInputContents( + listOf( + BetaResponseSteerInputContent.ofInputText( + BetaResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + BetaResponseInputTextContent.PromptCacheBreakpoint + .builder() + .build() + ) + .build() + ) + ) + ) + .id("msg_123") + .agent( + BetaResponseSteerInput.ResponseSteerInputItem.Message.Agent + .builder() + .agentName("agent_name") + .build() + ) + .status("status") + .build() + ) + ) + ) + + val roundtrippedBetaResponseSteerInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerInput).isEqualTo(betaResponseSteerInput) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + OBJECT(JsonValue.from(mapOf("invalid" to "object"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val betaResponseSteerInput = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { betaResponseSteerInput.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEventTest.kt new file mode 100644 index 000000000..abd5aa5c1 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerPendingEventTest.kt @@ -0,0 +1,86 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class BetaResponseSteerPendingEventTest { + + @Test + fun create() { + val betaResponseSteerPendingEvent = + BetaResponseSteerPendingEvent.builder() + .reason(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(betaResponseSteerPendingEvent.reason()) + .isEqualTo(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + assertThat(betaResponseSteerPendingEvent.requiredInput()) + .containsExactly( + BetaResponseSteerRequiredInput.ofFunctionCallOutput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + ) + assertThat(betaResponseSteerPendingEvent.sequenceNumber()).isEqualTo(0L) + assertThat(betaResponseSteerPendingEvent.steer()) + .isEqualTo( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + assertThat(betaResponseSteerPendingEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerPendingEvent = + BetaResponseSteerPendingEvent.builder() + .reason(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedBetaResponseSteerPendingEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerPendingEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerPendingEvent) + .isEqualTo(betaResponseSteerPendingEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInputTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInputTest.kt new file mode 100644 index 000000000..1e7ea2f45 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseSteerRequiredInputTest.kt @@ -0,0 +1,300 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.beta.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class BetaResponseSteerRequiredInputTest { + + @Test + fun ofFunctionCallOutput() { + val functionCallOutput = + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).contains(functionCallOutput) + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofFunctionCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofFunctionCallOutput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofCustomToolCallOutput() { + val customToolCallOutput = + BetaResponseSteerRequiredInput.CustomToolCallOutput.builder().callId("call_id").build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()) + .contains(customToolCallOutput) + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofCustomToolCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofCustomToolCallOutput( + BetaResponseSteerRequiredInput.CustomToolCallOutput.builder() + .callId("call_id") + .build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofComputerCallOutput() { + val computerCallOutput = + BetaResponseSteerRequiredInput.ComputerCallOutput.builder().callId("call_id").build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).contains(computerCallOutput) + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofComputerCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofComputerCallOutput( + BetaResponseSteerRequiredInput.ComputerCallOutput.builder() + .callId("call_id") + .build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofShellCallOutput() { + val shellCallOutput = + BetaResponseSteerRequiredInput.ShellCallOutput.builder().callId("call_id").build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).contains(shellCallOutput) + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofShellCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofShellCallOutput( + BetaResponseSteerRequiredInput.ShellCallOutput.builder().callId("call_id").build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofApplyPatchCallOutput() { + val applyPatchCallOutput = + BetaResponseSteerRequiredInput.ApplyPatchCallOutput.builder().callId("call_id").build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()) + .contains(applyPatchCallOutput) + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofApplyPatchCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofApplyPatchCallOutput( + BetaResponseSteerRequiredInput.ApplyPatchCallOutput.builder() + .callId("call_id") + .build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofToolSearchOutput() { + val toolSearchOutput = + BetaResponseSteerRequiredInput.ToolSearchOutput.builder().callId("call_id").build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).contains(toolSearchOutput) + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofToolSearchOutputRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofToolSearchOutput( + BetaResponseSteerRequiredInput.ToolSearchOutput.builder().callId("call_id").build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + @Test + fun ofMcpApprovalResponse() { + val mcpApprovalResponse = + BetaResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId("approval_request_id") + .build() + + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse) + + assertThat(betaResponseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(betaResponseSteerRequiredInput.mcpApprovalResponse()) + .contains(mcpApprovalResponse) + } + + @Test + fun ofMcpApprovalResponseRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponseSteerRequiredInput = + BetaResponseSteerRequiredInput.ofMcpApprovalResponse( + BetaResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId("approval_request_id") + .build() + ) + + val roundtrippedBetaResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponseSteerRequiredInput) + .isEqualTo(betaResponseSteerRequiredInput) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val betaResponseSteerRequiredInput = + jsonMapper() + .convertValue(testCase.value, jacksonTypeRef()) + + val e = + assertThrows { betaResponseSteerRequiredInput.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseStreamEventTest.kt index d96049361..445d00382 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseStreamEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseStreamEventTest.kt @@ -949,6 +949,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -962,7 +976,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1015,6 +1029,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1235,6 +1250,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1248,7 +1277,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1302,6 +1331,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1790,6 +1820,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1803,7 +1847,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1856,6 +1900,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2076,6 +2121,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -2089,7 +2148,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -2143,6 +2202,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3511,6 +3571,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3524,7 +3598,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -3577,6 +3651,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3798,6 +3873,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3811,7 +3900,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -3865,6 +3954,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4039,6 +4129,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4052,7 +4156,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4105,6 +4209,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4325,6 +4430,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4338,7 +4457,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4392,6 +4511,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4564,6 +4684,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4577,7 +4711,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4630,6 +4764,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4851,6 +4986,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4864,7 +5013,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4918,6 +5067,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -8277,6 +8427,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -8290,7 +8454,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -8343,6 +8507,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -8563,6 +8728,20 @@ internal class BetaResponseStreamEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -8576,7 +8755,7 @@ internal class BetaResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -8630,6 +8809,7 @@ internal class BetaResponseStreamEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseTest.kt index 125bce90b..293905505 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseTest.kt @@ -20,6 +20,20 @@ internal class BetaResponseTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -33,7 +47,7 @@ internal class BetaResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -85,6 +99,7 @@ internal class BetaResponseTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -228,6 +243,20 @@ internal class BetaResponseTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) assertThat(betaResponse.incompleteDetails()) @@ -244,7 +273,7 @@ internal class BetaResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(betaResponse.model()).isEqualTo(BetaResponse.Model.GPT_5_6_SOL) + assertThat(betaResponse.model()).isEqualTo(BetaResponse.Model.GPT_6_ASTRA) assertThat(betaResponse.output()) .containsExactly( BetaResponseOutputItem.ofMessage( @@ -302,6 +331,7 @@ internal class BetaResponseTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class BetaResponseTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class BetaResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -513,6 +557,7 @@ internal class BetaResponseTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemParamTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemParamTest.kt index e32504c43..3a2891e76 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemParamTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemParamTest.kt @@ -24,6 +24,7 @@ internal class BetaResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -56,6 +57,7 @@ internal class BetaResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -95,6 +97,7 @@ internal class BetaResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemTest.kt index 31f2de119..e7d91bb6c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponseToolSearchOutputItemTest.kt @@ -28,6 +28,7 @@ internal class BetaResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -61,6 +62,7 @@ internal class BetaResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -97,6 +99,7 @@ internal class BetaResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesClientEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesClientEventTest.kt index 2af3e6f2d..d5c071f3d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesClientEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesClientEventTest.kt @@ -36,7 +36,7 @@ internal class BetaResponsesClientEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponsesClientEvent.ResponseCreate.Model.GPT_5_6_SOL) + .model(BetaResponsesClientEvent.ResponseCreate.Model.GPT_6_ASTRA) .moderation( BetaResponsesClientEvent.ResponseCreate.Moderation.builder() .model("model") @@ -140,6 +140,7 @@ internal class BetaResponsesClientEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -158,6 +159,7 @@ internal class BetaResponsesClientEventTest { val betaResponsesClientEvent = BetaResponsesClientEvent.ofResponseCreate(responseCreate) assertThat(betaResponsesClientEvent.responseCreate()).contains(responseCreate) + assertThat(betaResponsesClientEvent.responseSteer()).isEmpty assertThat(betaResponsesClientEvent.responseInject()).isEmpty } @@ -185,7 +187,7 @@ internal class BetaResponsesClientEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponsesClientEvent.ResponseCreate.Model.GPT_5_6_SOL) + .model(BetaResponsesClientEvent.ResponseCreate.Model.GPT_6_ASTRA) .moderation( BetaResponsesClientEvent.ResponseCreate.Moderation.builder() .model("model") @@ -295,6 +297,7 @@ internal class BetaResponsesClientEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -320,6 +323,41 @@ internal class BetaResponsesClientEventTest { assertThat(roundtrippedBetaResponsesClientEvent).isEqualTo(betaResponsesClientEvent) } + @Test + fun ofResponseSteer() { + val responseSteer = + BetaResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + + val betaResponsesClientEvent = BetaResponsesClientEvent.ofResponseSteer(responseSteer) + + assertThat(betaResponsesClientEvent.responseCreate()).isEmpty + assertThat(betaResponsesClientEvent.responseSteer()).contains(responseSteer) + assertThat(betaResponsesClientEvent.responseInject()).isEmpty + } + + @Test + fun ofResponseSteerRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponsesClientEvent = + BetaResponsesClientEvent.ofResponseSteer( + BetaResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + ) + + val roundtrippedBetaResponsesClientEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponsesClientEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponsesClientEvent).isEqualTo(betaResponsesClientEvent) + } + @Test fun ofResponseInject() { val responseInject = @@ -338,6 +376,7 @@ internal class BetaResponsesClientEventTest { val betaResponsesClientEvent = BetaResponsesClientEvent.ofResponseInject(responseInject) assertThat(betaResponsesClientEvent.responseCreate()).isEmpty + assertThat(betaResponsesClientEvent.responseSteer()).isEmpty assertThat(betaResponsesClientEvent.responseInject()).contains(responseInject) } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesServerEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesServerEventTest.kt index 616f2cb84..0e407ed3c 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesServerEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaResponsesServerEventTest.kt @@ -84,6 +84,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -235,6 +238,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -336,6 +342,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -439,6 +448,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -546,6 +558,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -656,6 +671,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -765,6 +783,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -873,6 +894,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -981,6 +1005,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -1023,6 +1050,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1036,7 +1077,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1089,6 +1130,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1294,6 +1336,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -1312,6 +1357,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1325,7 +1384,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1379,6 +1438,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1644,6 +1704,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -1802,6 +1865,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -1871,6 +1937,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1884,7 +1964,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -1937,6 +2017,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2141,6 +2222,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -2159,6 +2243,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -2172,7 +2270,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -2226,6 +2324,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2464,6 +2563,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -2572,6 +2674,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -2680,6 +2785,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -2789,6 +2897,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -2900,6 +3011,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3009,6 +3123,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3118,6 +3235,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3227,6 +3347,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3343,6 +3466,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3467,6 +3593,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3518,6 +3647,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3531,7 +3674,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -3584,6 +3727,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3789,6 +3933,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -3807,6 +3954,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3820,7 +3981,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -3874,6 +4035,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4048,6 +4210,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4061,7 +4237,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4114,6 +4290,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4318,6 +4495,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -4336,6 +4516,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4349,7 +4543,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4403,6 +4597,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4575,6 +4770,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4588,7 +4797,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4641,6 +4850,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4846,6 +5056,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -4864,6 +5077,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4877,7 +5104,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -4931,6 +5158,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -5204,6 +5432,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5382,6 +5613,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5531,6 +5765,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5648,6 +5885,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5765,6 +6005,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5877,6 +6120,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -5987,6 +6233,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6097,6 +6346,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6204,6 +6456,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6309,6 +6564,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6425,6 +6683,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6553,6 +6814,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6673,6 +6937,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6781,6 +7048,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6889,6 +7159,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -6997,6 +7270,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7105,6 +7381,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7213,6 +7492,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7327,6 +7609,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7440,6 +7725,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7548,6 +7836,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7655,6 +7946,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7758,6 +8052,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7864,6 +8161,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -7970,6 +8270,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -8076,6 +8379,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -8184,6 +8490,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -8301,6 +8610,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -8352,6 +8664,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -8365,7 +8691,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -8418,6 +8744,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -8622,6 +8949,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -8640,6 +8970,20 @@ internal class BetaResponsesServerEventTest { BetaResponseError.builder() .code(BetaResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + BetaResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -8653,7 +8997,7 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(BetaResponse.Model.GPT_5_6_SOL) + .model(BetaResponse.Model.GPT_6_ASTRA) .addOutput( BetaResponseOutputMessage.builder() .id("id") @@ -8707,6 +9051,7 @@ internal class BetaResponsesServerEventTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -8946,6 +9291,9 @@ internal class BetaResponsesServerEventTest { .contains(responseCustomToolCallInputDelta) assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -9056,6 +9404,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()) .contains(responseCustomToolCallInputDone) assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -9102,6 +9453,24 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + BetaResponsesServerEvent.BetaResponseWsError.Error.Misalignment + .builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponsesServerEvent.BetaResponseWsError.Error.Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponsesServerEvent.BetaResponseWsError.Error.Misalignment + .Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .agent( @@ -9174,6 +9543,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).contains(error) + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -9195,6 +9567,26 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + BetaResponsesServerEvent.BetaResponseWsError.Error.Misalignment + .builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponsesServerEvent.BetaResponseWsError.Error + .Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponsesServerEvent.BetaResponseWsError.Error + .Misalignment + .Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .agent( @@ -9234,6 +9626,26 @@ internal class BetaResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + BetaResponsesServerEvent.BetaResponseWsError.Error.Misalignment + .builder() + .detailedExplanation("detailed_explanation") + .errorType( + BetaResponsesServerEvent.BetaResponseWsError.Error + .Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + BetaResponsesServerEvent.BetaResponseWsError.Error + .Misalignment + .Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .agent( @@ -9288,6 +9700,546 @@ internal class BetaResponsesServerEventTest { } } + @Test + fun ofResponseSteerAccepted() { + val responseSteerAccepted = + BetaResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerAccepted(responseSteerAccepted) + + assertThat(betaResponsesServerEvent.responseAudioDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioDone()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(betaResponsesServerEvent.responseCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(betaResponsesServerEvent.responseInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseIncomplete()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDone()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseQueued()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).contains(responseSteerAccepted) + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty + } + + @Test + fun ofResponseSteerAcceptedRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerAccepted( + BetaResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedBetaResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponsesServerEvent).isEqualTo(betaResponsesServerEvent) + } + + @Test + fun ofResponseSteerAcceptedStreamIdMetadata() { + val mapper = jsonMapper() + val original = + BetaResponsesServerEvent.ofResponseSteerAccepted( + BetaResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + BetaResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + BetaResponsesServerEvent.ofResponseSteerAccepted( + mapper.readValue(json, original.asResponseSteerAccepted().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerAccepted()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + + @Test + fun ofResponseSteerPending() { + val responseSteerPending = + BetaResponseSteerPendingEvent.builder() + .reason(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerPending(responseSteerPending) + + assertThat(betaResponsesServerEvent.responseAudioDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioDone()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(betaResponsesServerEvent.responseCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(betaResponsesServerEvent.responseInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseIncomplete()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDone()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseQueued()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).contains(responseSteerPending) + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty + } + + @Test + fun ofResponseSteerPendingRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerPending( + BetaResponseSteerPendingEvent.builder() + .reason(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedBetaResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponsesServerEvent).isEqualTo(betaResponsesServerEvent) + } + + @Test + fun ofResponseSteerPendingStreamIdMetadata() { + val mapper = jsonMapper() + val original = + BetaResponsesServerEvent.ofResponseSteerPending( + BetaResponseSteerPendingEvent.builder() + .reason(BetaResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + BetaResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + BetaResponsesServerEvent.ofResponseSteerPending( + mapper.readValue(json, original.asResponseSteerPending().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerPending()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + + @Test + fun ofResponseSteerFailed() { + val responseSteerFailed = + BetaResponseSteerFailedEvent.builder() + .error( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerFailed(responseSteerFailed) + + assertThat(betaResponsesServerEvent.responseAudioDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioDone()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(betaResponsesServerEvent.responseCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseContentPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(betaResponsesServerEvent.responseInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseIncomplete()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseRefusalDone()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(betaResponsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(betaResponsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(betaResponsesServerEvent.responseQueued()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).contains(responseSteerFailed) + assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty + assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty + } + + @Test + fun ofResponseSteerFailedRoundtrip() { + val jsonMapper = jsonMapper() + val betaResponsesServerEvent = + BetaResponsesServerEvent.ofResponseSteerFailed( + BetaResponseSteerFailedEvent.builder() + .error( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedBetaResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(betaResponsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedBetaResponsesServerEvent).isEqualTo(betaResponsesServerEvent) + } + + @Test + fun ofResponseSteerFailedStreamIdMetadata() { + val mapper = jsonMapper() + val original = + BetaResponsesServerEvent.ofResponseSteerFailed( + BetaResponseSteerFailedEvent.builder() + .error( + BetaResponseSteerFailedEvent.Error.builder() + .code(BetaResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + BetaResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + BetaResponsesServerEvent.ofResponseSteerFailed( + mapper.readValue(json, original.asResponseSteerFailed().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerFailed()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + @Test fun ofResponseInjectCreated() { val responseInjectCreated = @@ -9358,6 +10310,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).contains(responseInjectCreated) assertThat(betaResponsesServerEvent.responseInjectFailed()).isEmpty } @@ -9520,6 +10475,9 @@ internal class BetaResponsesServerEventTest { assertThat(betaResponsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(betaResponsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(betaResponsesServerEvent.error()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerPending()).isEmpty + assertThat(betaResponsesServerEvent.responseSteerFailed()).isEmpty assertThat(betaResponsesServerEvent.responseInjectCreated()).isEmpty assertThat(betaResponsesServerEvent.responseInjectFailed()).contains(responseInjectFailed) } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaToolTest.kt index 342d4dea1..52071d9a7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/BetaToolTest.kt @@ -26,6 +26,7 @@ internal class BetaToolTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -69,6 +70,7 @@ internal class BetaToolTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -675,6 +677,7 @@ internal class BetaToolTest { BetaCustomTool.builder() .name("name") .addAllowedCaller(BetaCustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -708,6 +711,7 @@ internal class BetaToolTest { BetaCustomTool.builder() .name("name") .addAllowedCaller(BetaCustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -733,6 +737,7 @@ internal class BetaToolTest { BetaNamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(BetaNamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -778,6 +783,7 @@ internal class BetaToolTest { BetaNamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(BetaNamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCompactParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCompactParamsTest.kt index 121b5b776..21dd66b42 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCompactParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCompactParamsTest.kt @@ -12,7 +12,7 @@ internal class ResponseCompactParamsTest { fun create() { ResponseCompactParams.builder() .addBeta(ResponseCompactParams.Beta.RESPONSES_MULTI_AGENT_V1) - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") @@ -33,7 +33,7 @@ internal class ResponseCompactParamsTest { val params = ResponseCompactParams.builder() .addBeta(ResponseCompactParams.Beta.RESPONSES_MULTI_AGENT_V1) - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") @@ -57,7 +57,7 @@ internal class ResponseCompactParamsTest { @Test fun headersWithoutOptionalFields() { val params = - ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_5_6_SOL).build() + ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_6_ASTRA).build() val headers = params._headers() @@ -69,7 +69,7 @@ internal class ResponseCompactParamsTest { val params = ResponseCompactParams.builder() .addBeta(ResponseCompactParams.Beta.RESPONSES_MULTI_AGENT_V1) - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") @@ -86,7 +86,7 @@ internal class ResponseCompactParamsTest { val body = params._body() - assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_5_6_SOL) + assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_6_ASTRA) assertThat(body.input()).contains(ResponseCompactParams.Input.ofString("string")) assertThat(body.instructions()).contains("instructions") assertThat(body.previousResponseId()).contains("resp_123") @@ -106,10 +106,10 @@ internal class ResponseCompactParamsTest { @Test fun bodyWithoutOptionalFields() { val params = - ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_5_6_SOL).build() + ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_6_ASTRA).build() val body = params._body() - assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_5_6_SOL) + assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_6_ASTRA) } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCreateParamsTest.kt index be7b4e91b..534a857ed 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/ResponseCreateParamsTest.kt @@ -32,7 +32,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -112,6 +112,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -151,7 +152,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -235,6 +236,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -288,7 +290,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -372,6 +374,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -410,7 +413,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(body.model()).contains(ResponseCreateParams.Model.GPT_5_6_SOL) + assertThat(body.model()).contains(ResponseCreateParams.Model.GPT_6_ASTRA) assertThat(body.moderation()) .contains( ResponseCreateParams.Moderation.builder() @@ -501,6 +504,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/inputtokens/InputTokenCountParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/inputtokens/InputTokenCountParamsTest.kt index 95a3a0896..eb368c4f9 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/inputtokens/InputTokenCountParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/responses/inputtokens/InputTokenCountParamsTest.kt @@ -50,6 +50,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -101,6 +102,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -166,6 +168,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -220,6 +223,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/ThreadCreateAndRunParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/ThreadCreateAndRunParamsTest.kt index 1df6742e3..fe7331d61 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/ThreadCreateAndRunParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/ThreadCreateAndRunParamsTest.kt @@ -24,7 +24,7 @@ internal class ThreadCreateAndRunParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) @@ -128,7 +128,7 @@ internal class ThreadCreateAndRunParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) @@ -231,7 +231,7 @@ internal class ThreadCreateAndRunParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(body.model()).contains(ChatModel.GPT_5_6_SOL) + assertThat(body.model()).contains(ChatModel.GPT_6_ASTRA) assertThat(body.parallelToolCalls()).contains(true) assertThat(body.responseFormat()).contains(AssistantResponseFormatOption.ofAuto()) assertThat(body.temperature()).contains(1.0) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/runs/RunCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/runs/RunCreateParamsTest.kt index e3916ea3a..8c365e7e6 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/runs/RunCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/beta/threads/runs/RunCreateParamsTest.kt @@ -49,7 +49,7 @@ internal class RunCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() @@ -109,7 +109,7 @@ internal class RunCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() @@ -178,7 +178,7 @@ internal class RunCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() @@ -225,7 +225,7 @@ internal class RunCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(body.model()).contains(ChatModel.GPT_5_6_SOL) + assertThat(body.model()).contains(ChatModel.GPT_6_ASTRA) assertThat(body.parallelToolCalls()).contains(true) assertThat(body.reasoningEffort()).contains(ReasoningEffort.NONE) assertThat(body.responseFormat()).contains(AssistantResponseFormatOption.ofAuto()) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParamsTest.kt index 7a41361b6..b9b6b5f08 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/chat/completions/ChatCompletionCreateParamsTest.kt @@ -20,7 +20,7 @@ internal class ChatCompletionCreateParamsTest { .addMessage( ChatCompletionDeveloperMessageParam.builder().content("string").name("name").build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) @@ -155,7 +155,7 @@ internal class ChatCompletionCreateParamsTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) @@ -291,7 +291,7 @@ internal class ChatCompletionCreateParamsTest { .build() ) ) - assertThat(body.model()).isEqualTo(ChatModel.GPT_5_6_SOL) + assertThat(body.model()).isEqualTo(ChatModel.GPT_6_ASTRA) assertThat(body.audio()) .contains( ChatCompletionAudioParam.builder() @@ -451,7 +451,7 @@ internal class ChatCompletionCreateParamsTest { val params = ChatCompletionCreateParams.builder() .addDeveloperMessage("string") - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .build() val body = params._body() @@ -462,6 +462,6 @@ internal class ChatCompletionCreateParamsTest { ChatCompletionDeveloperMessageParam.builder().content("string").build() ) ) - assertThat(body.model()).isEqualTo(ChatModel.GPT_5_6_SOL) + assertThat(body.model()).isEqualTo(ChatModel.GPT_6_ASTRA) } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt index 19c00c240..f793a72eb 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/conversations/items/ConversationItemTest.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.ReasoningEffort import com.openai.models.conversations.Message import com.openai.models.responses.ComputerAction import com.openai.models.responses.FunctionTool @@ -17,6 +18,7 @@ import com.openai.models.responses.ResponseCompactionItem import com.openai.models.responses.ResponseComputerToolCall import com.openai.models.responses.ResponseComputerToolCallOutputItem import com.openai.models.responses.ResponseComputerToolCallOutputScreenshot +import com.openai.models.responses.ResponseConfigurationUpdateItem import com.openai.models.responses.ResponseCustomToolCall import com.openai.models.responses.ResponseCustomToolCallOutput import com.openai.models.responses.ResponseFileSearchToolCall @@ -70,6 +72,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -127,6 +130,7 @@ internal class ConversationItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -146,6 +150,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -175,6 +180,7 @@ internal class ConversationItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -218,6 +224,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -298,6 +305,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -383,6 +391,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -455,6 +464,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -541,6 +551,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -641,6 +652,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -720,6 +732,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).contains(toolSearchCall) assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -781,6 +794,7 @@ internal class ConversationItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -806,6 +820,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).contains(toolSearchOutput) assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -845,6 +860,7 @@ internal class ConversationItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -883,6 +899,7 @@ internal class ConversationItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -907,6 +924,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).contains(additionalTools) + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -944,6 +962,7 @@ internal class ConversationItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -965,6 +984,75 @@ internal class ConversationItemTest { assertThat(roundtrippedConversationItem).isEqualTo(conversationItem) } + @Test + fun ofConfigurationUpdate() { + val configurationUpdate = + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + val conversationItem = ConversationItem.ofConfigurationUpdate(configurationUpdate) + + assertThat(conversationItem.message()).isEmpty + assertThat(conversationItem.functionCall()).isEmpty + assertThat(conversationItem.functionCallOutput()).isEmpty + assertThat(conversationItem.fileSearchCall()).isEmpty + assertThat(conversationItem.webSearchCall()).isEmpty + assertThat(conversationItem.imageGenerationCall()).isEmpty + assertThat(conversationItem.computerCall()).isEmpty + assertThat(conversationItem.computerCallOutput()).isEmpty + assertThat(conversationItem.toolSearchCall()).isEmpty + assertThat(conversationItem.toolSearchOutput()).isEmpty + assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).contains(configurationUpdate) + assertThat(conversationItem.reasoning()).isEmpty + assertThat(conversationItem.program()).isEmpty + assertThat(conversationItem.programOutput()).isEmpty + assertThat(conversationItem.compaction()).isEmpty + assertThat(conversationItem.codeInterpreterCall()).isEmpty + assertThat(conversationItem.localShellCall()).isEmpty + assertThat(conversationItem.localShellCallOutput()).isEmpty + assertThat(conversationItem.shellCall()).isEmpty + assertThat(conversationItem.shellCallOutput()).isEmpty + assertThat(conversationItem.applyPatchCall()).isEmpty + assertThat(conversationItem.applyPatchCallOutput()).isEmpty + assertThat(conversationItem.mcpListTools()).isEmpty + assertThat(conversationItem.mcpApprovalRequest()).isEmpty + assertThat(conversationItem.mcpApprovalResponse()).isEmpty + assertThat(conversationItem.mcpCall()).isEmpty + assertThat(conversationItem.customToolCall()).isEmpty + assertThat(conversationItem.customToolCallOutput()).isEmpty + } + + @Test + fun ofConfigurationUpdateRoundtrip() { + val jsonMapper = jsonMapper() + val conversationItem = + ConversationItem.ofConfigurationUpdate( + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + ) + + val roundtrippedConversationItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(conversationItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedConversationItem).isEqualTo(conversationItem) + } + @Test fun ofReasoning() { val reasoning = @@ -989,6 +1077,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).contains(reasoning) assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1054,6 +1143,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).contains(program) assertThat(conversationItem.programOutput()).isEmpty @@ -1118,6 +1208,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).contains(programOutput) @@ -1181,6 +1272,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1245,6 +1337,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1322,6 +1415,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1397,6 +1491,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1469,6 +1564,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1552,6 +1648,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1633,6 +1730,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1706,6 +1804,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1779,6 +1878,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1850,6 +1950,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1914,6 +2015,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -1984,6 +2086,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -2042,6 +2145,7 @@ internal class ConversationItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2059,6 +2163,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty @@ -2088,6 +2193,7 @@ internal class ConversationItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2125,6 +2231,7 @@ internal class ConversationItemTest { assertThat(conversationItem.toolSearchCall()).isEmpty assertThat(conversationItem.toolSearchOutput()).isEmpty assertThat(conversationItem.additionalTools()).isEmpty + assertThat(conversationItem.configurationUpdate()).isEmpty assertThat(conversationItem.reasoning()).isEmpty assertThat(conversationItem.program()).isEmpty assertThat(conversationItem.programOutput()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/models/models/ModelRetrieveParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/models/ModelRetrieveParamsTest.kt index 4579ec6d0..1b5983dc1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/models/ModelRetrieveParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/models/ModelRetrieveParamsTest.kt @@ -9,14 +9,14 @@ internal class ModelRetrieveParamsTest { @Test fun create() { - ModelRetrieveParams.builder().model("gpt-5.6-sol").build() + ModelRetrieveParams.builder().model("gpt-6-astra").build() } @Test fun pathParams() { - val params = ModelRetrieveParams.builder().model("gpt-5.6-sol").build() + val params = ModelRetrieveParams.builder().model("gpt-6-astra").build() - assertThat(params._pathParam(0)).isEqualTo("gpt-5.6-sol") + assertThat(params._pathParam(0)).isEqualTo("gpt-6-astra") // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/CustomToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/CustomToolTest.kt index 0125265dc..084a07924 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/CustomToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/CustomToolTest.kt @@ -17,6 +17,7 @@ internal class CustomToolTest { CustomTool.builder() .name("name") .addAllowedCaller(CustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -25,6 +26,7 @@ internal class CustomToolTest { assertThat(customTool.name()).isEqualTo("name") assertThat(customTool.allowedCallers().getOrNull()) .containsExactly(CustomTool.AllowedCaller.DIRECT) + assertThat(customTool.async()).contains(true) assertThat(customTool.deferLoading()).contains(true) assertThat(customTool.description()).contains("description") assertThat(customTool.format()).contains(CustomToolInputFormat.ofText()) @@ -37,6 +39,7 @@ internal class CustomToolTest { CustomTool.builder() .name("name") .addAllowedCaller(CustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/FunctionToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/FunctionToolTest.kt index e28b389c2..7b889d33b 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/FunctionToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/FunctionToolTest.kt @@ -23,6 +23,7 @@ internal class FunctionToolTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -42,6 +43,7 @@ internal class FunctionToolTest { assertThat(functionTool.strict()).contains(true) assertThat(functionTool.allowedCallers().getOrNull()) .containsExactly(FunctionTool.AllowedCaller.DIRECT) + assertThat(functionTool.async()).contains(true) assertThat(functionTool.deferLoading()).contains(true) assertThat(functionTool.description()).contains("description") assertThat(functionTool.outputSchema()) @@ -65,6 +67,7 @@ internal class FunctionToolTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt index 050ba8c7c..cf38b5ddb 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/NamespaceToolTest.kt @@ -20,6 +20,7 @@ internal class NamespaceToolTest { NamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(NamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -41,6 +42,7 @@ internal class NamespaceToolTest { NamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(NamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -66,6 +68,7 @@ internal class NamespaceToolTest { NamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(NamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompactParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompactParamsTest.kt index 0f45f90a6..30e209852 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompactParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompactParamsTest.kt @@ -10,7 +10,7 @@ internal class ResponseCompactParamsTest { @Test fun create() { ResponseCompactParams.builder() - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") @@ -30,7 +30,7 @@ internal class ResponseCompactParamsTest { fun body() { val params = ResponseCompactParams.builder() - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") @@ -47,7 +47,7 @@ internal class ResponseCompactParamsTest { val body = params._body() - assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_5_6_SOL) + assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_6_ASTRA) assertThat(body.input()).contains(ResponseCompactParams.Input.ofString("string")) assertThat(body.instructions()).contains("instructions") assertThat(body.previousResponseId()).contains("resp_123") @@ -67,10 +67,10 @@ internal class ResponseCompactParamsTest { @Test fun bodyWithoutOptionalFields() { val params = - ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_5_6_SOL).build() + ResponseCompactParams.builder().model(ResponseCompactParams.Model.GPT_6_ASTRA).build() val body = params._body() - assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_5_6_SOL) + assertThat(body.model()).contains(ResponseCompactParams.Model.GPT_6_ASTRA) } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt index 2294668a5..b6a51d2a7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCompletedEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseCompletedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseCompletedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseCompletedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseCompletedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseCompletedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParamTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParamTest.kt new file mode 100644 index 000000000..640dcb6e1 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemParamTest.kt @@ -0,0 +1,56 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import com.openai.models.ReasoningEffort +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseConfigurationUpdateItemParamTest { + + @Test + fun create() { + val responseConfigurationUpdateItemParam = + ResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + assertThat(responseConfigurationUpdateItemParam.id()).contains("cnfu_123") + assertThat(responseConfigurationUpdateItemParam.reasoning()) + .contains( + ResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseConfigurationUpdateItemParam = + ResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + val roundtrippedResponseConfigurationUpdateItemParam = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseConfigurationUpdateItemParam), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseConfigurationUpdateItemParam) + .isEqualTo(responseConfigurationUpdateItemParam) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemTest.kt new file mode 100644 index 000000000..5797186d3 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseConfigurationUpdateItemTest.kt @@ -0,0 +1,56 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import com.openai.models.ReasoningEffort +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseConfigurationUpdateItemTest { + + @Test + fun create() { + val responseConfigurationUpdateItem = + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + assertThat(responseConfigurationUpdateItem.id()).isEqualTo("cnfu_123") + assertThat(responseConfigurationUpdateItem.reasoning()) + .contains( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseConfigurationUpdateItem = + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + val roundtrippedResponseConfigurationUpdateItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseConfigurationUpdateItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseConfigurationUpdateItem) + .isEqualTo(responseConfigurationUpdateItem) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreateParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreateParamsTest.kt index ddc3b036a..0980cdcb7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreateParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreateParamsTest.kt @@ -35,7 +35,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -109,6 +109,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -147,7 +148,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -225,6 +226,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -263,7 +265,7 @@ internal class ResponseCreateParamsTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(body.model()).contains(ResponsesModel.ofChat(ChatModel.GPT_5_6_SOL)) + assertThat(body.model()).contains(ResponsesModel.ofChat(ChatModel.GPT_6_ASTRA)) assertThat(body.moderation()) .contains( ResponseCreateParams.Moderation.builder() @@ -345,6 +347,7 @@ internal class ResponseCreateParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt index 8622091ad..19ea6f9bd 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCreatedEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseCreatedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseCreatedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseCreatedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseCreatedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseCreatedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallItemTest.kt index baa9b02d7..87bc1f2e6 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallItemTest.kt @@ -17,6 +17,7 @@ internal class ResponseCustomToolCallItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -27,6 +28,7 @@ internal class ResponseCustomToolCallItemTest { assertThat(responseCustomToolCallItem.input()).isEqualTo("input") assertThat(responseCustomToolCallItem.name()).isEqualTo("name") assertThat(responseCustomToolCallItem.id()).contains("id") + assertThat(responseCustomToolCallItem.async()).contains(true) assertThat(responseCustomToolCallItem.caller()) .contains(ResponseCustomToolCall.Caller.ofDirect()) assertThat(responseCustomToolCallItem.namespace()).contains("namespace") @@ -44,6 +46,7 @@ internal class ResponseCustomToolCallItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseCustomToolCallItem.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallTest.kt index 9e494b9fb..20b23f8a7 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseCustomToolCallTest.kt @@ -17,6 +17,7 @@ internal class ResponseCustomToolCallTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -25,6 +26,7 @@ internal class ResponseCustomToolCallTest { assertThat(responseCustomToolCall.input()).isEqualTo("input") assertThat(responseCustomToolCall.name()).isEqualTo("name") assertThat(responseCustomToolCall.id()).contains("id") + assertThat(responseCustomToolCall.async()).contains(true) assertThat(responseCustomToolCall.caller()) .contains(ResponseCustomToolCall.Caller.ofDirect()) assertThat(responseCustomToolCall.namespace()).contains("namespace") @@ -39,6 +41,7 @@ internal class ResponseCustomToolCallTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseErrorTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseErrorTest.kt index 927f0d252..18eb5ceeb 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseErrorTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseErrorTest.kt @@ -12,17 +12,57 @@ internal class ResponseErrorTest { @Test fun create() { val responseError = - ResponseError.builder().code(ResponseError.Code.SERVER_ERROR).message("message").build() + ResponseError.builder() + .code(ResponseError.Code.SERVER_ERROR) + .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder().message("message").build() + ) + .build() + ) + .build() assertThat(responseError.code()).isEqualTo(ResponseError.Code.SERVER_ERROR) assertThat(responseError.message()).isEqualTo("message") + assertThat(responseError.misalignment()) + .contains( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer(ResponseError.Misalignment.Steer.builder().message("message").build()) + .build() + ) } @Test fun roundtrip() { val jsonMapper = jsonMapper() val responseError = - ResponseError.builder().code(ResponseError.Code.SERVER_ERROR).message("message").build() + ResponseError.builder() + .code(ResponseError.Code.SERVER_ERROR) + .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder().message("message").build() + ) + .build() + ) + .build() val roundtrippedResponseError = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt index 24b3a6130..e408a8082 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFailedEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseFailedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseFailedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseFailedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseFailedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseFailedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseFailedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseFailedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallItemTest.kt index 1a87fcd9f..b95863c65 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallItemTest.kt @@ -17,6 +17,7 @@ internal class ResponseFunctionToolCallItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -27,6 +28,7 @@ internal class ResponseFunctionToolCallItemTest { assertThat(responseFunctionToolCallItem.callId()).isEqualTo("call_id") assertThat(responseFunctionToolCallItem.name()).isEqualTo("name") assertThat(responseFunctionToolCallItem.id()).contains("id") + assertThat(responseFunctionToolCallItem.async()).contains(true) assertThat(responseFunctionToolCallItem.caller()) .contains(ResponseFunctionToolCall.Caller.ofDirect()) assertThat(responseFunctionToolCallItem.namespace()).contains("namespace") @@ -44,6 +46,7 @@ internal class ResponseFunctionToolCallItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallTest.kt index 3d8c26c29..7d98a3c69 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseFunctionToolCallTest.kt @@ -17,6 +17,7 @@ internal class ResponseFunctionToolCallTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -26,6 +27,7 @@ internal class ResponseFunctionToolCallTest { assertThat(responseFunctionToolCall.callId()).isEqualTo("call_id") assertThat(responseFunctionToolCall.name()).isEqualTo("name") assertThat(responseFunctionToolCall.id()).contains("id") + assertThat(responseFunctionToolCall.async()).contains(true) assertThat(responseFunctionToolCall.caller()) .contains(ResponseFunctionToolCall.Caller.ofDirect()) assertThat(responseFunctionToolCall.namespace()).contains("namespace") @@ -42,6 +44,7 @@ internal class ResponseFunctionToolCallTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt index 132ec4518..250065b80 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInProgressEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseInProgressEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseInProgressEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseInProgressEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseInProgressEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseInProgressEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt index 2218e2854..8214a9e9e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseIncompleteEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseIncompleteEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseIncompleteEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseIncompleteEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseIncompleteEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseIncompleteEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt index fca76ee4c..08741ea68 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseInputItemTest.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.ReasoningEffort import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -38,6 +39,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -113,6 +115,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -213,6 +216,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -318,6 +322,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -421,6 +426,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -524,6 +530,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -613,6 +620,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -674,6 +682,7 @@ internal class ResponseInputItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -693,6 +702,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -725,6 +735,7 @@ internal class ResponseInputItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -767,6 +778,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -839,6 +851,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).contains(toolSearchCall) assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -898,6 +911,7 @@ internal class ResponseInputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -927,6 +941,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).contains(toolSearchOutput) assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -965,6 +980,7 @@ internal class ResponseInputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1004,6 +1020,7 @@ internal class ResponseInputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1030,6 +1047,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).contains(additionalTools) + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1068,6 +1086,7 @@ internal class ResponseInputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1090,6 +1109,79 @@ internal class ResponseInputItemTest { assertThat(roundtrippedResponseInputItem).isEqualTo(responseInputItem) } + @Test + fun ofConfigurationUpdate() { + val configurationUpdate = + ResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + val responseInputItem = ResponseInputItem.ofConfigurationUpdate(configurationUpdate) + + assertThat(responseInputItem.easyInputMessage()).isEmpty + assertThat(responseInputItem.message()).isEmpty + assertThat(responseInputItem.responseOutputMessage()).isEmpty + assertThat(responseInputItem.fileSearchCall()).isEmpty + assertThat(responseInputItem.computerCall()).isEmpty + assertThat(responseInputItem.computerCallOutput()).isEmpty + assertThat(responseInputItem.webSearchCall()).isEmpty + assertThat(responseInputItem.functionCall()).isEmpty + assertThat(responseInputItem.functionCallOutput()).isEmpty + assertThat(responseInputItem.toolSearchCall()).isEmpty + assertThat(responseInputItem.toolSearchOutput()).isEmpty + assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).contains(configurationUpdate) + assertThat(responseInputItem.reasoning()).isEmpty + assertThat(responseInputItem.compaction()).isEmpty + assertThat(responseInputItem.imageGenerationCall()).isEmpty + assertThat(responseInputItem.codeInterpreterCall()).isEmpty + assertThat(responseInputItem.localShellCall()).isEmpty + assertThat(responseInputItem.localShellCallOutput()).isEmpty + assertThat(responseInputItem.shellCall()).isEmpty + assertThat(responseInputItem.shellCallOutput()).isEmpty + assertThat(responseInputItem.applyPatchCall()).isEmpty + assertThat(responseInputItem.applyPatchCallOutput()).isEmpty + assertThat(responseInputItem.mcpListTools()).isEmpty + assertThat(responseInputItem.mcpApprovalRequest()).isEmpty + assertThat(responseInputItem.mcpApprovalResponse()).isEmpty + assertThat(responseInputItem.mcpCall()).isEmpty + assertThat(responseInputItem.customToolCallOutput()).isEmpty + assertThat(responseInputItem.customToolCall()).isEmpty + assertThat(responseInputItem.compactionTrigger()).isEmpty + assertThat(responseInputItem.itemReference()).isEmpty + assertThat(responseInputItem.program()).isEmpty + assertThat(responseInputItem.programOutput()).isEmpty + } + + @Test + fun ofConfigurationUpdateRoundtrip() { + val jsonMapper = jsonMapper() + val responseInputItem = + ResponseInputItem.ofConfigurationUpdate( + ResponseConfigurationUpdateItemParam.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItemParam.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + ) + + val roundtrippedResponseInputItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseInputItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseInputItem).isEqualTo(responseInputItem) + } + @Test fun ofReasoning() { val reasoning = @@ -1115,6 +1207,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).contains(reasoning) assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1182,6 +1275,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).contains(compaction) assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1247,6 +1341,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).contains(imageGenerationCall) @@ -1315,6 +1410,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1396,6 +1492,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1475,6 +1572,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1560,6 +1658,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1654,6 +1753,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1736,6 +1836,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1811,6 +1912,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1887,6 +1989,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -1962,6 +2065,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2030,6 +2134,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2104,6 +2209,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2181,6 +2287,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2233,6 +2340,7 @@ internal class ResponseInputItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2251,6 +2359,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2283,6 +2392,7 @@ internal class ResponseInputItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2313,6 +2423,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2372,6 +2483,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2438,6 +2550,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty @@ -2506,6 +2619,7 @@ internal class ResponseInputItemTest { assertThat(responseInputItem.toolSearchCall()).isEmpty assertThat(responseInputItem.toolSearchOutput()).isEmpty assertThat(responseInputItem.additionalTools()).isEmpty + assertThat(responseInputItem.configurationUpdate()).isEmpty assertThat(responseInputItem.reasoning()).isEmpty assertThat(responseInputItem.compaction()).isEmpty assertThat(responseInputItem.imageGenerationCall()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt index 46c1f9a48..f4142d836 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseItemTest.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper import com.openai.errors.OpenAIInvalidDataException +import com.openai.models.ReasoningEffort import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows @@ -44,6 +45,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -141,6 +143,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -243,6 +246,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -343,6 +347,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -444,6 +449,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -531,6 +537,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -590,6 +597,7 @@ internal class ResponseItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -609,6 +617,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -639,6 +648,7 @@ internal class ResponseItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -682,6 +692,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -753,6 +764,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).contains(toolSearchCall) assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -815,6 +827,7 @@ internal class ResponseItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -840,6 +853,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).contains(toolSearchOutput) assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -880,6 +894,7 @@ internal class ResponseItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -918,6 +933,7 @@ internal class ResponseItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -942,6 +958,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).contains(additionalTools) + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -980,6 +997,7 @@ internal class ResponseItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1001,6 +1019,76 @@ internal class ResponseItemTest { assertThat(roundtrippedResponseItem).isEqualTo(responseItem) } + @Test + fun ofConfigurationUpdate() { + val configurationUpdate = + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + + val responseItem = ResponseItem.ofConfigurationUpdate(configurationUpdate) + + assertThat(responseItem.responseInputMessageItem()).isEmpty + assertThat(responseItem.responseOutputMessage()).isEmpty + assertThat(responseItem.fileSearchCall()).isEmpty + assertThat(responseItem.computerCall()).isEmpty + assertThat(responseItem.computerCallOutput()).isEmpty + assertThat(responseItem.webSearchCall()).isEmpty + assertThat(responseItem.functionCall()).isEmpty + assertThat(responseItem.functionCallOutput()).isEmpty + assertThat(responseItem.toolSearchCall()).isEmpty + assertThat(responseItem.toolSearchOutput()).isEmpty + assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).contains(configurationUpdate) + assertThat(responseItem.reasoning()).isEmpty + assertThat(responseItem.program()).isEmpty + assertThat(responseItem.programOutput()).isEmpty + assertThat(responseItem.compaction()).isEmpty + assertThat(responseItem.imageGenerationCall()).isEmpty + assertThat(responseItem.codeInterpreterCall()).isEmpty + assertThat(responseItem.localShellCall()).isEmpty + assertThat(responseItem.localShellCallOutput()).isEmpty + assertThat(responseItem.shellCall()).isEmpty + assertThat(responseItem.shellCallOutput()).isEmpty + assertThat(responseItem.applyPatchCall()).isEmpty + assertThat(responseItem.applyPatchCallOutput()).isEmpty + assertThat(responseItem.mcpListTools()).isEmpty + assertThat(responseItem.mcpApprovalRequest()).isEmpty + assertThat(responseItem.mcpApprovalResponse()).isEmpty + assertThat(responseItem.mcpCall()).isEmpty + assertThat(responseItem.customToolCall()).isEmpty + assertThat(responseItem.customToolCallOutput()).isEmpty + } + + @Test + fun ofConfigurationUpdateRoundtrip() { + val jsonMapper = jsonMapper() + val responseItem = + ResponseItem.ofConfigurationUpdate( + ResponseConfigurationUpdateItem.builder() + .id("cnfu_123") + .reasoning( + ResponseConfigurationUpdateItem.Reasoning.builder() + .effort(ReasoningEffort.NONE) + .build() + ) + .build() + ) + + val roundtrippedResponseItem = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseItem), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseItem).isEqualTo(responseItem) + } + @Test fun ofReasoning() { val reasoning = @@ -1025,6 +1113,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).contains(reasoning) assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1091,6 +1180,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).contains(program) assertThat(responseItem.programOutput()).isEmpty @@ -1156,6 +1246,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).contains(programOutput) @@ -1220,6 +1311,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1283,6 +1375,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1348,6 +1441,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1426,6 +1520,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1502,6 +1597,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1575,6 +1671,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1659,6 +1756,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1741,6 +1839,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1815,6 +1914,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1889,6 +1989,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -1961,6 +2062,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -2026,6 +2128,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -2097,6 +2200,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -2156,6 +2260,7 @@ internal class ResponseItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -2175,6 +2280,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty @@ -2205,6 +2311,7 @@ internal class ResponseItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseCustomToolCallItem.Status.IN_PROGRESS) @@ -2246,6 +2353,7 @@ internal class ResponseItemTest { assertThat(responseItem.toolSearchCall()).isEmpty assertThat(responseItem.toolSearchOutput()).isEmpty assertThat(responseItem.additionalTools()).isEmpty + assertThat(responseItem.configurationUpdate()).isEmpty assertThat(responseItem.reasoning()).isEmpty assertThat(responseItem.program()).isEmpty assertThat(responseItem.programOutput()).isEmpty diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt index 28d530409..85a6709e8 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseOutputItemTest.kt @@ -224,6 +224,7 @@ internal class ResponseOutputItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -271,6 +272,7 @@ internal class ResponseOutputItemTest { .callId("call_id") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .status(ResponseFunctionToolCall.Status.IN_PROGRESS) @@ -920,6 +922,7 @@ internal class ResponseOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -984,6 +987,7 @@ internal class ResponseOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1022,6 +1026,7 @@ internal class ResponseOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1083,6 +1088,7 @@ internal class ResponseOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2049,6 +2055,7 @@ internal class ResponseOutputItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() @@ -2095,6 +2102,7 @@ internal class ResponseOutputItemTest { .input("input") .name("name") .id("id") + .async(true) .callerDirect() .namespace("namespace") .build() diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt index b9141f0ea..239d41fc6 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseQueuedEventTest.kt @@ -26,6 +26,20 @@ internal class ResponseQueuedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -39,7 +53,7 @@ internal class ResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -86,6 +100,7 @@ internal class ResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -236,6 +251,20 @@ internal class ResponseQueuedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -249,7 +278,7 @@ internal class ResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -296,6 +325,7 @@ internal class ResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -448,6 +478,20 @@ internal class ResponseQueuedEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -461,7 +505,7 @@ internal class ResponseQueuedEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -508,6 +552,7 @@ internal class ResponseQueuedEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerAcceptedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerAcceptedEventTest.kt new file mode 100644 index 000000000..a4373ceec --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerAcceptedEventTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseSteerAcceptedEventTest { + + @Test + fun create() { + val responseSteerAcceptedEvent = + ResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(responseSteerAcceptedEvent.sequenceNumber()).isEqualTo(0L) + assertThat(responseSteerAcceptedEvent.steer()) + .isEqualTo( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + assertThat(responseSteerAcceptedEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseSteerAcceptedEvent = + ResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedResponseSteerAcceptedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerAcceptedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerAcceptedEvent).isEqualTo(responseSteerAcceptedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerEventTest.kt new file mode 100644 index 000000000..d2ca96190 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerEventTest.kt @@ -0,0 +1,41 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseSteerEventTest { + + @Test + fun create() { + val responseSteerEvent = + ResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + + assertThat(responseSteerEvent.input()).isEqualTo(ResponseSteerInput.ofText("string")) + assertThat(responseSteerEvent.previousResponseId()).isEqualTo("previous_response_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseSteerEvent = + ResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + + val roundtrippedResponseSteerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerEvent).isEqualTo(responseSteerEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerFailedEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerFailedEventTest.kt new file mode 100644 index 000000000..60bdc5217 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerFailedEventTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseSteerFailedEventTest { + + @Test + fun create() { + val responseSteerFailedEvent = + ResponseSteerFailedEvent.builder() + .error( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(responseSteerFailedEvent.error()) + .isEqualTo( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + assertThat(responseSteerFailedEvent.sequenceNumber()).isEqualTo(0L) + assertThat(responseSteerFailedEvent.steer()) + .isEqualTo( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + assertThat(responseSteerFailedEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseSteerFailedEvent = + ResponseSteerFailedEvent.builder() + .error( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedResponseSteerFailedEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerFailedEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerFailedEvent).isEqualTo(responseSteerFailedEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputContentTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputContentTest.kt new file mode 100644 index 000000000..d011bd7fd --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputContentTest.kt @@ -0,0 +1,163 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ResponseSteerInputContentTest { + + @Test + fun ofInputText() { + val inputText = + ResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + ResponseInputTextContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val responseSteerInputContent = ResponseSteerInputContent.ofInputText(inputText) + + assertThat(responseSteerInputContent.inputText()).contains(inputText) + assertThat(responseSteerInputContent.inputImage()).isEmpty + assertThat(responseSteerInputContent.inputFile()).isEmpty + } + + @Test + fun ofInputTextRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerInputContent = + ResponseSteerInputContent.ofInputText( + ResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + ResponseInputTextContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerInputContent).isEqualTo(responseSteerInputContent) + } + + @Test + fun ofInputImage() { + val inputImage = + ResponseInputImageContent.builder() + .detail(ResponseInputImageContent.Detail.LOW) + .fileId("file-123") + .imageUrl("https://example.com") + .promptCacheBreakpoint( + ResponseInputImageContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val responseSteerInputContent = ResponseSteerInputContent.ofInputImage(inputImage) + + assertThat(responseSteerInputContent.inputText()).isEmpty + assertThat(responseSteerInputContent.inputImage()).contains(inputImage) + assertThat(responseSteerInputContent.inputFile()).isEmpty + } + + @Test + fun ofInputImageRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerInputContent = + ResponseSteerInputContent.ofInputImage( + ResponseInputImageContent.builder() + .detail(ResponseInputImageContent.Detail.LOW) + .fileId("file-123") + .imageUrl("https://example.com") + .promptCacheBreakpoint( + ResponseInputImageContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerInputContent).isEqualTo(responseSteerInputContent) + } + + @Test + fun ofInputFile() { + val inputFile = + ResponseInputFileContent.builder() + .detail(ResponseInputFileContent.Detail.AUTO) + .fileData("file_data") + .fileId("file-123") + .fileUrl("https://example.com") + .filename("filename") + .promptCacheBreakpoint( + ResponseInputFileContent.PromptCacheBreakpoint.builder().build() + ) + .build() + + val responseSteerInputContent = ResponseSteerInputContent.ofInputFile(inputFile) + + assertThat(responseSteerInputContent.inputText()).isEmpty + assertThat(responseSteerInputContent.inputImage()).isEmpty + assertThat(responseSteerInputContent.inputFile()).contains(inputFile) + } + + @Test + fun ofInputFileRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerInputContent = + ResponseSteerInputContent.ofInputFile( + ResponseInputFileContent.builder() + .detail(ResponseInputFileContent.Detail.AUTO) + .fileData("file_data") + .fileId("file-123") + .fileUrl("https://example.com") + .filename("filename") + .promptCacheBreakpoint( + ResponseInputFileContent.PromptCacheBreakpoint.builder().build() + ) + .build() + ) + + val roundtrippedResponseSteerInputContent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerInputContent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerInputContent).isEqualTo(responseSteerInputContent) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val responseSteerInputContent = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { responseSteerInputContent.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputTest.kt new file mode 100644 index 000000000..c935eda79 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerInputTest.kt @@ -0,0 +1,126 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ResponseSteerInputTest { + + @Test + fun ofText() { + val text = "string" + + val responseSteerInput = ResponseSteerInput.ofText(text) + + assertThat(responseSteerInput.text()).contains(text) + assertThat(responseSteerInput.itemList()).isEmpty + } + + @Test + fun ofTextRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerInput = ResponseSteerInput.ofText("string") + + val roundtrippedResponseSteerInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerInput).isEqualTo(responseSteerInput) + } + + @Test + fun ofItemList() { + val itemList = + listOf( + ResponseSteerInput.ResponseSteerInputItem.ofMessage( + ResponseSteerInput.ResponseSteerInputItem.Message.builder() + .contentOfResponseSteerInputContents( + listOf( + ResponseSteerInputContent.ofInputText( + ResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + ResponseInputTextContent.PromptCacheBreakpoint.builder() + .build() + ) + .build() + ) + ) + ) + .id("msg_123") + .status("status") + .build() + ) + ) + + val responseSteerInput = ResponseSteerInput.ofItemList(itemList) + + assertThat(responseSteerInput.text()).isEmpty + assertThat(responseSteerInput.itemList()).contains(itemList) + } + + @Test + fun ofItemListRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerInput = + ResponseSteerInput.ofItemList( + listOf( + ResponseSteerInput.ResponseSteerInputItem.ofMessage( + ResponseSteerInput.ResponseSteerInputItem.Message.builder() + .contentOfResponseSteerInputContents( + listOf( + ResponseSteerInputContent.ofInputText( + ResponseInputTextContent.builder() + .text("text") + .promptCacheBreakpoint( + ResponseInputTextContent.PromptCacheBreakpoint + .builder() + .build() + ) + .build() + ) + ) + ) + .id("msg_123") + .status("status") + .build() + ) + ) + ) + + val roundtrippedResponseSteerInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerInput).isEqualTo(responseSteerInput) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + OBJECT(JsonValue.from(mapOf("invalid" to "object"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val responseSteerInput = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { responseSteerInput.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerPendingEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerPendingEventTest.kt new file mode 100644 index 000000000..b4a034c3f --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerPendingEventTest.kt @@ -0,0 +1,85 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class ResponseSteerPendingEventTest { + + @Test + fun create() { + val responseSteerPendingEvent = + ResponseSteerPendingEvent.builder() + .reason(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + assertThat(responseSteerPendingEvent.reason()) + .isEqualTo(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + assertThat(responseSteerPendingEvent.requiredInput()) + .containsExactly( + ResponseSteerRequiredInput.ofFunctionCallOutput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + ) + assertThat(responseSteerPendingEvent.sequenceNumber()).isEqualTo(0L) + assertThat(responseSteerPendingEvent.steer()) + .isEqualTo( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + assertThat(responseSteerPendingEvent.streamId()).contains("stream_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val responseSteerPendingEvent = + ResponseSteerPendingEvent.builder() + .reason(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val roundtrippedResponseSteerPendingEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerPendingEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerPendingEvent).isEqualTo(responseSteerPendingEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerRequiredInputTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerRequiredInputTest.kt new file mode 100644 index 000000000..c2a3a8008 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseSteerRequiredInputTest.kt @@ -0,0 +1,282 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.responses + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.JsonValue +import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class ResponseSteerRequiredInputTest { + + @Test + fun ofFunctionCallOutput() { + val functionCallOutput = + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofFunctionCallOutput(functionCallOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).contains(functionCallOutput) + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofFunctionCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofFunctionCallOutput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofCustomToolCallOutput() { + val customToolCallOutput = + ResponseSteerRequiredInput.CustomToolCallOutput.builder().callId("call_id").build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofCustomToolCallOutput(customToolCallOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).contains(customToolCallOutput) + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofCustomToolCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofCustomToolCallOutput( + ResponseSteerRequiredInput.CustomToolCallOutput.builder().callId("call_id").build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofComputerCallOutput() { + val computerCallOutput = + ResponseSteerRequiredInput.ComputerCallOutput.builder().callId("call_id").build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofComputerCallOutput(computerCallOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).contains(computerCallOutput) + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofComputerCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofComputerCallOutput( + ResponseSteerRequiredInput.ComputerCallOutput.builder().callId("call_id").build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofShellCallOutput() { + val shellCallOutput = + ResponseSteerRequiredInput.ShellCallOutput.builder().callId("call_id").build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofShellCallOutput(shellCallOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).contains(shellCallOutput) + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofShellCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofShellCallOutput( + ResponseSteerRequiredInput.ShellCallOutput.builder().callId("call_id").build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofApplyPatchCallOutput() { + val applyPatchCallOutput = + ResponseSteerRequiredInput.ApplyPatchCallOutput.builder().callId("call_id").build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofApplyPatchCallOutput(applyPatchCallOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).contains(applyPatchCallOutput) + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofApplyPatchCallOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofApplyPatchCallOutput( + ResponseSteerRequiredInput.ApplyPatchCallOutput.builder().callId("call_id").build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofToolSearchOutput() { + val toolSearchOutput = + ResponseSteerRequiredInput.ToolSearchOutput.builder().callId("call_id").build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofToolSearchOutput(toolSearchOutput) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).contains(toolSearchOutput) + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).isEmpty + } + + @Test + fun ofToolSearchOutputRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofToolSearchOutput( + ResponseSteerRequiredInput.ToolSearchOutput.builder().callId("call_id").build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + @Test + fun ofMcpApprovalResponse() { + val mcpApprovalResponse = + ResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId("approval_request_id") + .build() + + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofMcpApprovalResponse(mcpApprovalResponse) + + assertThat(responseSteerRequiredInput.functionCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.customToolCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.computerCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.shellCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.applyPatchCallOutput()).isEmpty + assertThat(responseSteerRequiredInput.toolSearchOutput()).isEmpty + assertThat(responseSteerRequiredInput.mcpApprovalResponse()).contains(mcpApprovalResponse) + } + + @Test + fun ofMcpApprovalResponseRoundtrip() { + val jsonMapper = jsonMapper() + val responseSteerRequiredInput = + ResponseSteerRequiredInput.ofMcpApprovalResponse( + ResponseSteerRequiredInput.McpApprovalResponse.builder() + .approvalRequestId("approval_request_id") + .build() + ) + + val roundtrippedResponseSteerRequiredInput = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responseSteerRequiredInput), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponseSteerRequiredInput).isEqualTo(responseSteerRequiredInput) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val responseSteerRequiredInput = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { responseSteerRequiredInput.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt index e57ad78b3..f2ceaf889 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseStreamEventTest.kt @@ -841,6 +841,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -854,7 +868,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -901,6 +915,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1118,6 +1133,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1131,7 +1160,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -1179,6 +1208,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1642,6 +1672,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1655,7 +1699,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -1702,6 +1746,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1919,6 +1964,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1932,7 +1991,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -1980,6 +2039,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3223,6 +3283,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3236,7 +3310,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3283,6 +3357,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3500,6 +3575,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3513,7 +3602,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3561,6 +3650,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3732,6 +3822,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3745,7 +3849,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3792,6 +3896,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4009,6 +4114,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4022,7 +4141,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4070,6 +4189,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4241,6 +4361,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4254,7 +4388,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4301,6 +4435,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4518,6 +4653,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4531,7 +4680,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4579,6 +4728,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -7602,6 +7752,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -7615,7 +7779,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -7662,6 +7826,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -7879,6 +8044,20 @@ internal class ResponseStreamEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -7892,7 +8071,7 @@ internal class ResponseStreamEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -7940,6 +8119,7 @@ internal class ResponseStreamEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt index c47e632af..a2c6d412e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseTest.kt @@ -25,6 +25,20 @@ internal class ResponseTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -38,7 +52,7 @@ internal class ResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -85,6 +99,7 @@ internal class ResponseTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -224,6 +239,20 @@ internal class ResponseTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) assertThat(response.incompleteDetails()) @@ -239,7 +268,7 @@ internal class ResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - assertThat(response.model()).isEqualTo(ResponsesModel.ofChat(ChatModel.GPT_5_6_SOL)) + assertThat(response.model()).isEqualTo(ResponsesModel.ofChat(ChatModel.GPT_6_ASTRA)) assertThat(response.output()) .containsExactly( ResponseOutputItem.ofMessage( @@ -292,6 +321,7 @@ internal class ResponseTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -435,6 +465,20 @@ internal class ResponseTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -448,7 +492,7 @@ internal class ResponseTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -495,6 +539,7 @@ internal class ResponseTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemParamTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemParamTest.kt index 5d67fc30b..f5d1f6644 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemParamTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemParamTest.kt @@ -24,6 +24,7 @@ internal class ResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -51,6 +52,7 @@ internal class ResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -84,6 +86,7 @@ internal class ResponseToolSearchOutputItemParamTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemTest.kt index 7025919a3..aa5f6dce6 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponseToolSearchOutputItemTest.kt @@ -28,6 +28,7 @@ internal class ResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -58,6 +59,7 @@ internal class ResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -90,6 +92,7 @@ internal class ResponseToolSearchOutputItemTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesClientEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesClientEventTest.kt index 82b587f05..1533fde16 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesClientEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesClientEventTest.kt @@ -5,24 +5,26 @@ package com.openai.models.responses import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.openai.core.JsonValue import com.openai.core.jsonMapper +import com.openai.errors.OpenAIInvalidDataException import com.openai.models.ChatModel import com.openai.models.Reasoning import com.openai.models.ReasoningEffort import com.openai.models.ResponseFormatText -import com.openai.models.ResponsesModel -import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource internal class ResponsesClientEventTest { @Test - fun create() { - val responsesClientEvent = - ResponsesClientEvent.builder() + fun ofResponseCreate() { + val responseCreate = + ResponsesClientEvent.ResponseCreate.builder() .background(true) .addContextManagement( - ResponsesClientEvent.ContextManagement.builder() + ResponsesClientEvent.ResponseCreate.ContextManagement.builder() .type("type") .compactThreshold(1000L) .build() @@ -34,27 +36,35 @@ internal class ResponsesClientEventTest { .maxOutputTokens(16L) .maxToolCalls(0L) .metadata( - ResponsesClientEvent.Metadata.builder() + ResponsesClientEvent.ResponseCreate.Metadata.builder() .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( - ResponsesClientEvent.Moderation.builder() + ResponsesClientEvent.ResponseCreate.Moderation.builder() .model("model") .policy( - ResponsesClientEvent.Moderation.Policy.builder() + ResponsesClientEvent.ResponseCreate.Moderation.Policy.builder() .input( - ResponsesClientEvent.Moderation.Policy.Input.builder() + ResponsesClientEvent.ResponseCreate.Moderation.Policy.Input + .builder() .mode( - ResponsesClientEvent.Moderation.Policy.Input.Mode.SCORE + ResponsesClientEvent.ResponseCreate.Moderation.Policy + .Input + .Mode + .SCORE ) .build() ) .output( - ResponsesClientEvent.Moderation.Policy.Output.builder() + ResponsesClientEvent.ResponseCreate.Moderation.Policy.Output + .builder() .mode( - ResponsesClientEvent.Moderation.Policy.Output.Mode.SCORE + ResponsesClientEvent.ResponseCreate.Moderation.Policy + .Output + .Mode + .SCORE ) .build() ) @@ -77,12 +87,14 @@ internal class ResponsesClientEventTest { ) .promptCacheKey("prompt-cache-key-1234") .promptCacheOptions( - ResponsesClientEvent.PromptCacheOptions.builder() - .mode(ResponsesClientEvent.PromptCacheOptions.Mode.IMPLICIT) - .ttl(ResponsesClientEvent.PromptCacheOptions.Ttl._30M) + ResponsesClientEvent.ResponseCreate.PromptCacheOptions.builder() + .mode(ResponsesClientEvent.ResponseCreate.PromptCacheOptions.Mode.IMPLICIT) + .ttl(ResponsesClientEvent.ResponseCreate.PromptCacheOptions.Ttl._30M) .build() ) - .promptCacheRetention(ResponsesClientEvent.PromptCacheRetention.IN_MEMORY) + .promptCacheRetention( + ResponsesClientEvent.ResponseCreate.PromptCacheRetention.IN_MEMORY + ) .reasoning( Reasoning.builder() .context(Reasoning.Context.AUTO) @@ -93,12 +105,14 @@ internal class ResponsesClientEventTest { .build() ) .safetyIdentifier("safety-identifier-1234") - .serviceTier(ResponsesClientEvent.ServiceTier.AUTO) + .serviceTier(ResponsesClientEvent.ResponseCreate.ServiceTier.AUTO) .store(true) .stream(true) .streamId("stream_id") .streamOptions( - ResponsesClientEvent.StreamOptions.builder().includeObfuscation(true).build() + ResponsesClientEvent.ResponseCreate.StreamOptions.builder() + .includeObfuscation(true) + .build() ) .temperature(1.0) .text( @@ -118,6 +132,7 @@ internal class ResponsesClientEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -129,253 +144,187 @@ internal class ResponsesClientEventTest { ) .topLogprobs(0L) .topP(1.0) - .truncation(ResponsesClientEvent.Truncation.AUTO) + .truncation(ResponsesClientEvent.ResponseCreate.Truncation.AUTO) .user("user-1234") .build() - assertThat(responsesClientEvent.background()).contains(true) - assertThat(responsesClientEvent.contextManagement().getOrNull()) - .containsExactly( - ResponsesClientEvent.ContextManagement.builder() - .type("type") - .compactThreshold(1000L) - .build() - ) - assertThat(responsesClientEvent.conversation()) - .contains(ResponsesClientEvent.Conversation.ofId("string")) - assertThat(responsesClientEvent.include().getOrNull()) - .containsExactly(ResponseIncludable.FILE_SEARCH_CALL_RESULTS) - assertThat(responsesClientEvent.input()) - .contains(ResponsesClientEvent.Input.ofText("string")) - assertThat(responsesClientEvent.instructions()).contains("instructions") - assertThat(responsesClientEvent.maxOutputTokens()).contains(16L) - assertThat(responsesClientEvent.maxToolCalls()).contains(0L) - assertThat(responsesClientEvent.metadata()) - .contains( - ResponsesClientEvent.Metadata.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - assertThat(responsesClientEvent.model()) - .contains(ResponsesModel.ofChat(ChatModel.GPT_5_6_SOL)) - assertThat(responsesClientEvent.moderation()) - .contains( - ResponsesClientEvent.Moderation.builder() - .model("model") - .policy( - ResponsesClientEvent.Moderation.Policy.builder() - .input( - ResponsesClientEvent.Moderation.Policy.Input.builder() - .mode(ResponsesClientEvent.Moderation.Policy.Input.Mode.SCORE) + val responsesClientEvent = ResponsesClientEvent.ofResponseCreate(responseCreate) + + assertThat(responsesClientEvent.responseCreate()).contains(responseCreate) + assertThat(responsesClientEvent.responseSteer()).isEmpty + } + + @Test + fun ofResponseCreateRoundtrip() { + val jsonMapper = jsonMapper() + val responsesClientEvent = + ResponsesClientEvent.ofResponseCreate( + ResponsesClientEvent.ResponseCreate.builder() + .background(true) + .addContextManagement( + ResponsesClientEvent.ResponseCreate.ContextManagement.builder() + .type("type") + .compactThreshold(1000L) + .build() + ) + .conversation("string") + .addInclude(ResponseIncludable.FILE_SEARCH_CALL_RESULTS) + .input("string") + .instructions("instructions") + .maxOutputTokens(16L) + .maxToolCalls(0L) + .metadata( + ResponsesClientEvent.ResponseCreate.Metadata.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) + .build() + ) + .model(ChatModel.GPT_6_ASTRA) + .moderation( + ResponsesClientEvent.ResponseCreate.Moderation.builder() + .model("model") + .policy( + ResponsesClientEvent.ResponseCreate.Moderation.Policy.builder() + .input( + ResponsesClientEvent.ResponseCreate.Moderation.Policy.Input + .builder() + .mode( + ResponsesClientEvent.ResponseCreate.Moderation + .Policy + .Input + .Mode + .SCORE + ) + .build() + ) + .output( + ResponsesClientEvent.ResponseCreate.Moderation.Policy.Output + .builder() + .mode( + ResponsesClientEvent.ResponseCreate.Moderation + .Policy + .Output + .Mode + .SCORE + ) + .build() + ) .build() ) - .output( - ResponsesClientEvent.Moderation.Policy.Output.builder() - .mode(ResponsesClientEvent.Moderation.Policy.Output.Mode.SCORE) + .build() + ) + .parallelToolCalls(true) + .previousResponseId("previous_response_id") + .prompt( + ResponsePrompt.builder() + .id("id") + .variables( + ResponsePrompt.Variables.builder() + .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .version("version") .build() ) - .build() - ) - assertThat(responsesClientEvent.parallelToolCalls()).contains(true) - assertThat(responsesClientEvent.previousResponseId()).contains("previous_response_id") - assertThat(responsesClientEvent.prompt()) - .contains( - ResponsePrompt.builder() - .id("id") - .variables( - ResponsePrompt.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) + .promptCacheKey("prompt-cache-key-1234") + .promptCacheOptions( + ResponsesClientEvent.ResponseCreate.PromptCacheOptions.builder() + .mode( + ResponsesClientEvent.ResponseCreate.PromptCacheOptions.Mode.IMPLICIT + ) + .ttl(ResponsesClientEvent.ResponseCreate.PromptCacheOptions.Ttl._30M) .build() ) - .version("version") - .build() - ) - assertThat(responsesClientEvent.promptCacheKey()).contains("prompt-cache-key-1234") - assertThat(responsesClientEvent.promptCacheOptions()) - .contains( - ResponsesClientEvent.PromptCacheOptions.builder() - .mode(ResponsesClientEvent.PromptCacheOptions.Mode.IMPLICIT) - .ttl(ResponsesClientEvent.PromptCacheOptions.Ttl._30M) - .build() - ) - assertThat(responsesClientEvent.promptCacheRetention()) - .contains(ResponsesClientEvent.PromptCacheRetention.IN_MEMORY) - assertThat(responsesClientEvent.reasoning()) - .contains( - Reasoning.builder() - .context(Reasoning.Context.AUTO) - .effort(ReasoningEffort.NONE) - .generateSummary(Reasoning.GenerateSummary.AUTO) - .mode(Reasoning.Mode.STANDARD) - .summary(Reasoning.Summary.AUTO) - .build() - ) - assertThat(responsesClientEvent.safetyIdentifier()).contains("safety-identifier-1234") - assertThat(responsesClientEvent.serviceTier()) - .contains(ResponsesClientEvent.ServiceTier.AUTO) - assertThat(responsesClientEvent.store()).contains(true) - assertThat(responsesClientEvent.stream()).contains(true) - assertThat(responsesClientEvent.streamId()).contains("stream_id") - assertThat(responsesClientEvent.streamOptions()) - .contains(ResponsesClientEvent.StreamOptions.builder().includeObfuscation(true).build()) - assertThat(responsesClientEvent.temperature()).contains(1.0) - assertThat(responsesClientEvent.text()) - .contains( - ResponseTextConfig.builder() - .format(ResponseFormatText.builder().build()) - .verbosity(ResponseTextConfig.Verbosity.LOW) + .promptCacheRetention( + ResponsesClientEvent.ResponseCreate.PromptCacheRetention.IN_MEMORY + ) + .reasoning( + Reasoning.builder() + .context(Reasoning.Context.AUTO) + .effort(ReasoningEffort.NONE) + .generateSummary(Reasoning.GenerateSummary.AUTO) + .mode(Reasoning.Mode.STANDARD) + .summary(Reasoning.Summary.AUTO) + .build() + ) + .safetyIdentifier("safety-identifier-1234") + .serviceTier(ResponsesClientEvent.ResponseCreate.ServiceTier.AUTO) + .store(true) + .stream(true) + .streamId("stream_id") + .streamOptions( + ResponsesClientEvent.ResponseCreate.StreamOptions.builder() + .includeObfuscation(true) + .build() + ) + .temperature(1.0) + .text( + ResponseTextConfig.builder() + .format(ResponseFormatText.builder().build()) + .verbosity(ResponseTextConfig.Verbosity.LOW) + .build() + ) + .toolChoice(ToolChoiceOptions.NONE) + .addTool( + FunctionTool.builder() + .name("name") + .parameters( + FunctionTool.Parameters.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .strict(true) + .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) + .deferLoading(true) + .description("description") + .outputSchema( + FunctionTool.OutputSchema.builder() + .putAdditionalProperty("foo", JsonValue.from("bar")) + .build() + ) + .build() + ) + .topLogprobs(0L) + .topP(1.0) + .truncation(ResponsesClientEvent.ResponseCreate.Truncation.AUTO) + .user("user-1234") .build() ) - assertThat(responsesClientEvent.toolChoice()) - .contains(ResponsesClientEvent.ToolChoice.ofOptions(ToolChoiceOptions.NONE)) - assertThat(responsesClientEvent.tools().getOrNull()) - .containsExactly( - Tool.ofFunction( - FunctionTool.builder() - .name("name") - .parameters( - FunctionTool.Parameters.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .strict(true) - .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) - .deferLoading(true) - .description("description") - .outputSchema( - FunctionTool.OutputSchema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - ) + + val roundtrippedResponsesClientEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responsesClientEvent), + jacksonTypeRef(), ) - assertThat(responsesClientEvent.topLogprobs()).contains(0L) - assertThat(responsesClientEvent.topP()).contains(1.0) - assertThat(responsesClientEvent.truncation()).contains(ResponsesClientEvent.Truncation.AUTO) - assertThat(responsesClientEvent.user()).contains("user-1234") + + assertThat(roundtrippedResponsesClientEvent).isEqualTo(responsesClientEvent) } @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val responsesClientEvent = - ResponsesClientEvent.builder() - .background(true) - .addContextManagement( - ResponsesClientEvent.ContextManagement.builder() - .type("type") - .compactThreshold(1000L) - .build() - ) - .conversation("string") - .addInclude(ResponseIncludable.FILE_SEARCH_CALL_RESULTS) + fun ofResponseSteer() { + val responseSteer = + ResponseSteerEvent.builder() .input("string") - .instructions("instructions") - .maxOutputTokens(16L) - .maxToolCalls(0L) - .metadata( - ResponsesClientEvent.Metadata.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .model(ChatModel.GPT_5_6_SOL) - .moderation( - ResponsesClientEvent.Moderation.builder() - .model("model") - .policy( - ResponsesClientEvent.Moderation.Policy.builder() - .input( - ResponsesClientEvent.Moderation.Policy.Input.builder() - .mode( - ResponsesClientEvent.Moderation.Policy.Input.Mode.SCORE - ) - .build() - ) - .output( - ResponsesClientEvent.Moderation.Policy.Output.builder() - .mode( - ResponsesClientEvent.Moderation.Policy.Output.Mode.SCORE - ) - .build() - ) - .build() - ) - .build() - ) - .parallelToolCalls(true) .previousResponseId("previous_response_id") - .prompt( - ResponsePrompt.builder() - .id("id") - .variables( - ResponsePrompt.Variables.builder() - .putAdditionalProperty("foo", JsonValue.from("string")) - .build() - ) - .version("version") - .build() - ) - .promptCacheKey("prompt-cache-key-1234") - .promptCacheOptions( - ResponsesClientEvent.PromptCacheOptions.builder() - .mode(ResponsesClientEvent.PromptCacheOptions.Mode.IMPLICIT) - .ttl(ResponsesClientEvent.PromptCacheOptions.Ttl._30M) - .build() - ) - .promptCacheRetention(ResponsesClientEvent.PromptCacheRetention.IN_MEMORY) - .reasoning( - Reasoning.builder() - .context(Reasoning.Context.AUTO) - .effort(ReasoningEffort.NONE) - .generateSummary(Reasoning.GenerateSummary.AUTO) - .mode(Reasoning.Mode.STANDARD) - .summary(Reasoning.Summary.AUTO) - .build() - ) - .safetyIdentifier("safety-identifier-1234") - .serviceTier(ResponsesClientEvent.ServiceTier.AUTO) - .store(true) - .stream(true) - .streamId("stream_id") - .streamOptions( - ResponsesClientEvent.StreamOptions.builder().includeObfuscation(true).build() - ) - .temperature(1.0) - .text( - ResponseTextConfig.builder() - .format(ResponseFormatText.builder().build()) - .verbosity(ResponseTextConfig.Verbosity.LOW) - .build() - ) - .toolChoice(ToolChoiceOptions.NONE) - .addTool( - FunctionTool.builder() - .name("name") - .parameters( - FunctionTool.Parameters.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .strict(true) - .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) - .deferLoading(true) - .description("description") - .outputSchema( - FunctionTool.OutputSchema.builder() - .putAdditionalProperty("foo", JsonValue.from("bar")) - .build() - ) - .build() - ) - .topLogprobs(0L) - .topP(1.0) - .truncation(ResponsesClientEvent.Truncation.AUTO) - .user("user-1234") .build() + val responsesClientEvent = ResponsesClientEvent.ofResponseSteer(responseSteer) + + assertThat(responsesClientEvent.responseCreate()).isEmpty + assertThat(responsesClientEvent.responseSteer()).contains(responseSteer) + } + + @Test + fun ofResponseSteerRoundtrip() { + val jsonMapper = jsonMapper() + val responsesClientEvent = + ResponsesClientEvent.ofResponseSteer( + ResponseSteerEvent.builder() + .input("string") + .previousResponseId("previous_response_id") + .build() + ) + val roundtrippedResponsesClientEvent = jsonMapper.readValue( jsonMapper.writeValueAsString(responsesClientEvent), @@ -384,4 +333,22 @@ internal class ResponsesClientEventTest { assertThat(roundtrippedResponsesClientEvent).isEqualTo(responsesClientEvent) } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val responsesClientEvent = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { responsesClientEvent.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } } diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesServerEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesServerEventTest.kt index 714353bf6..3edeb5a8f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesServerEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ResponsesServerEventTest.kt @@ -83,6 +83,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -215,6 +218,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -301,6 +307,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -390,6 +399,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -483,6 +495,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -581,6 +596,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -678,6 +696,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -774,6 +795,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -870,6 +894,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -905,6 +932,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -918,7 +959,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -965,6 +1006,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1166,6 +1208,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -1182,6 +1227,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1195,7 +1254,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -1243,6 +1302,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1500,6 +1560,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -1647,6 +1710,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -1709,6 +1775,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1722,7 +1802,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -1769,6 +1849,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -1970,6 +2051,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -1986,6 +2070,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -1999,7 +2097,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -2047,6 +2145,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -2277,6 +2376,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2373,6 +2475,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2467,6 +2572,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2564,6 +2672,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2663,6 +2774,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2760,6 +2874,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2857,6 +2974,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -2954,6 +3074,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -3058,6 +3181,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -3170,6 +3296,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -3214,6 +3343,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3227,7 +3370,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3274,6 +3417,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3475,6 +3619,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -3491,6 +3638,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3504,7 +3665,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3552,6 +3713,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3723,6 +3885,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -3736,7 +3912,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -3783,6 +3959,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -3984,6 +4161,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -4000,6 +4180,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4013,7 +4207,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4061,6 +4255,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4232,6 +4427,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4245,7 +4454,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4292,6 +4501,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4493,6 +4703,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -4509,6 +4722,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -4522,7 +4749,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -4570,6 +4797,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -4831,6 +5059,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -4988,6 +5219,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5118,6 +5352,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5221,6 +5458,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5322,6 +5562,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5422,6 +5665,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5520,6 +5766,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5618,6 +5867,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5714,6 +5966,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5810,6 +6065,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -5919,6 +6177,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6040,6 +6301,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6148,6 +6412,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6242,6 +6509,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6336,6 +6606,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6432,6 +6705,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6528,6 +6804,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6624,6 +6903,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6726,6 +7008,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6827,6 +7112,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -6923,6 +7211,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7018,6 +7309,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7111,6 +7405,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7205,6 +7502,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7299,6 +7599,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7393,6 +7696,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7487,6 +7793,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7592,6 +7901,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7636,6 +7948,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -7649,7 +7975,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -7696,6 +8022,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -7897,6 +8224,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -7913,6 +8243,20 @@ internal class ResponsesServerEventTest { ResponseError.builder() .code(ResponseError.Code.SERVER_ERROR) .message("message") + .misalignment( + ResponseError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponseError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponseError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) .build() ) .incompleteDetails( @@ -7926,7 +8270,7 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .addOutput( ResponseOutputMessage.builder() .id("id") @@ -7974,6 +8318,7 @@ internal class ResponsesServerEventTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -8207,6 +8552,9 @@ internal class ResponsesServerEventTest { .contains(responseCustomToolCallInputDelta) assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -8303,6 +8651,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDone()) .contains(responseCustomToolCallInputDone) assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -8342,6 +8693,22 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + ResponsesServerEvent.ResponseWsError.Error.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponsesServerEvent.ResponseWsError.Error.Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponsesServerEvent.ResponseWsError.Error.Misalignment.Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .sequenceNumber(0L) @@ -8409,6 +8776,9 @@ internal class ResponsesServerEventTest { assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty assertThat(responsesServerEvent.error()).contains(error) + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty } @Test @@ -8428,6 +8798,23 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + ResponsesServerEvent.ResponseWsError.Error.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponsesServerEvent.ResponseWsError.Error.Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponsesServerEvent.ResponseWsError.Error.Misalignment + .Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .sequenceNumber(0L) @@ -8462,6 +8849,23 @@ internal class ResponsesServerEventTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) + .misalignment( + ResponsesServerEvent.ResponseWsError.Error.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + ResponsesServerEvent.ResponseWsError.Error.Misalignment + .ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + ResponsesServerEvent.ResponseWsError.Error.Misalignment + .Steer + .builder() + .message("message") + .build() + ) + .build() + ) .build() ) .sequenceNumber(0L) @@ -8509,6 +8913,538 @@ internal class ResponsesServerEventTest { } } + @Test + fun ofResponseSteerAccepted() { + val responseSteerAccepted = + ResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val responsesServerEvent = + ResponsesServerEvent.ofResponseSteerAccepted(responseSteerAccepted) + + assertThat(responsesServerEvent.responseAudioDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioDone()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(responsesServerEvent.responseCompleted()).isEmpty + assertThat(responsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(responsesServerEvent.responseContentPartDone()).isEmpty + assertThat(responsesServerEvent.responseCreated()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(responsesServerEvent.responseInProgress()).isEmpty + assertThat(responsesServerEvent.responseFailed()).isEmpty + assertThat(responsesServerEvent.responseIncomplete()).isEmpty + assertThat(responsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(responsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(responsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(responsesServerEvent.responseRefusalDone()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(responsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(responsesServerEvent.responseQueued()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).contains(responseSteerAccepted) + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty + } + + @Test + fun ofResponseSteerAcceptedRoundtrip() { + val jsonMapper = jsonMapper() + val responsesServerEvent = + ResponsesServerEvent.ofResponseSteerAccepted( + ResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponsesServerEvent).isEqualTo(responsesServerEvent) + } + + @Test + fun ofResponseSteerAcceptedStreamIdMetadata() { + val mapper = jsonMapper() + val original = + ResponsesServerEvent.ofResponseSteerAccepted( + ResponseSteerAcceptedEvent.builder() + .sequenceNumber(0L) + .steer( + ResponseSteerAcceptedEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + ResponsesServerEvent.ofResponseSteerAccepted( + mapper.readValue(json, original.asResponseSteerAccepted().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerAccepted()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + + @Test + fun ofResponseSteerPending() { + val responseSteerPending = + ResponseSteerPendingEvent.builder() + .reason(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + + val responsesServerEvent = ResponsesServerEvent.ofResponseSteerPending(responseSteerPending) + + assertThat(responsesServerEvent.responseAudioDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioDone()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(responsesServerEvent.responseCompleted()).isEmpty + assertThat(responsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(responsesServerEvent.responseContentPartDone()).isEmpty + assertThat(responsesServerEvent.responseCreated()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(responsesServerEvent.responseInProgress()).isEmpty + assertThat(responsesServerEvent.responseFailed()).isEmpty + assertThat(responsesServerEvent.responseIncomplete()).isEmpty + assertThat(responsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(responsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(responsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(responsesServerEvent.responseRefusalDone()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(responsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(responsesServerEvent.responseQueued()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).contains(responseSteerPending) + assertThat(responsesServerEvent.responseSteerFailed()).isEmpty + } + + @Test + fun ofResponseSteerPendingRoundtrip() { + val jsonMapper = jsonMapper() + val responsesServerEvent = + ResponsesServerEvent.ofResponseSteerPending( + ResponseSteerPendingEvent.builder() + .reason(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponsesServerEvent).isEqualTo(responsesServerEvent) + } + + @Test + fun ofResponseSteerPendingStreamIdMetadata() { + val mapper = jsonMapper() + val original = + ResponsesServerEvent.ofResponseSteerPending( + ResponseSteerPendingEvent.builder() + .reason(ResponseSteerPendingReason.WAITING_FOR_REQUIRED_INPUT) + .addRequiredInput( + ResponseSteerRequiredInput.FunctionCallOutput.builder() + .callId("call_id") + .name("name") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerPendingEvent.Steer.builder() + .id("id") + .previousResponseId("previous_response_id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + ResponsesServerEvent.ofResponseSteerPending( + mapper.readValue(json, original.asResponseSteerPending().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerPending()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + + @Test + fun ofResponseSteerFailed() { + val responseSteerFailed = + ResponseSteerFailedEvent.builder() + .error( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + + val responsesServerEvent = ResponsesServerEvent.ofResponseSteerFailed(responseSteerFailed) + + assertThat(responsesServerEvent.responseAudioDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioDone()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDelta()).isEmpty + assertThat(responsesServerEvent.responseAudioTranscriptDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDelta()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCodeDone()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseCodeInterpreterCallInterpreting()).isEmpty + assertThat(responsesServerEvent.responseCompleted()).isEmpty + assertThat(responsesServerEvent.responseContentPartAdded()).isEmpty + assertThat(responsesServerEvent.responseContentPartDone()).isEmpty + assertThat(responsesServerEvent.responseCreated()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseFileSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseFunctionCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandAdded()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallCommandDone()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDelta()).isEmpty + assertThat(responsesServerEvent.responseShellCallOutputContentDone()).isEmpty + assertThat(responsesServerEvent.responseInProgress()).isEmpty + assertThat(responsesServerEvent.responseFailed()).isEmpty + assertThat(responsesServerEvent.responseIncomplete()).isEmpty + assertThat(responsesServerEvent.responseOutputItemAdded()).isEmpty + assertThat(responsesServerEvent.responseOutputItemDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartAdded()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryPartDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningSummaryTextDone()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDelta()).isEmpty + assertThat(responsesServerEvent.responseReasoningTextDone()).isEmpty + assertThat(responsesServerEvent.responseRefusalDelta()).isEmpty + assertThat(responsesServerEvent.responseRefusalDone()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDelta()).isEmpty + assertThat(responsesServerEvent.responseOutputTextDone()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseWebSearchCallSearching()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallGenerating()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseImageGenerationCallPartialImage()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDelta()).isEmpty + assertThat(responsesServerEvent.responseMcpCallArgumentsDone()).isEmpty + assertThat(responsesServerEvent.responseMcpCallCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpCallFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpCallInProgress()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsCompleted()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsFailed()).isEmpty + assertThat(responsesServerEvent.responseMcpListToolsInProgress()).isEmpty + assertThat(responsesServerEvent.responseOutputTextAnnotationAdded()).isEmpty + assertThat(responsesServerEvent.responseQueued()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDelta()).isEmpty + assertThat(responsesServerEvent.responseCustomToolCallInputDone()).isEmpty + assertThat(responsesServerEvent.error()).isEmpty + assertThat(responsesServerEvent.responseSteerAccepted()).isEmpty + assertThat(responsesServerEvent.responseSteerPending()).isEmpty + assertThat(responsesServerEvent.responseSteerFailed()).contains(responseSteerFailed) + } + + @Test + fun ofResponseSteerFailedRoundtrip() { + val jsonMapper = jsonMapper() + val responsesServerEvent = + ResponsesServerEvent.ofResponseSteerFailed( + ResponseSteerFailedEvent.builder() + .error( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + ) + + val roundtrippedResponsesServerEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(responsesServerEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedResponsesServerEvent).isEqualTo(responsesServerEvent) + } + + @Test + fun ofResponseSteerFailedStreamIdMetadata() { + val mapper = jsonMapper() + val original = + ResponsesServerEvent.ofResponseSteerFailed( + ResponseSteerFailedEvent.builder() + .error( + ResponseSteerFailedEvent.Error.builder() + .code(ResponseSteerErrorCode.RESPONSE_NOT_FOUND) + .message("message") + .build() + ) + .sequenceNumber(0L) + .steer( + ResponseSteerFailedEvent.Steer.builder() + .input("string") + .previousResponseId("previous_response_id") + .id("id") + .build() + ) + .streamId("stream_id") + .build() + ) + val originalIsValid = original.isValid() + val seed = mapper.readTree(mapper.writeValueAsString(original)) + for (value in listOf(null, "null", "\"route\"", "42", "[]", "{}")) { + val node = seed.deepCopy() + node.put("x_castiron_unknown", "preserved") + if (value == null) { + node.remove("stream_id") + } else { + node.set( + "stream_id", + mapper.readTree(value), + ) + } + val json = mapper.writeValueAsString(node) + val deserialized = mapper.readValue(json, jacksonTypeRef()) + val wrapped = + ResponsesServerEvent.ofResponseSteerFailed( + mapper.readValue(json, original.asResponseSteerFailed().javaClass) + ) + for (event in listOf(deserialized, wrapped)) { + assertThat(event.isResponseSteerFailed()).isTrue() + assertThat(mapper.readTree(mapper.writeValueAsString(event))).isEqualTo(node) + when (value) { + null, + "null" -> assertThat(event.streamId()).isEmpty + "\"route\"" -> assertThat(event.streamId()).contains("route") + else -> { + assertThrows { event.streamId() } + assertThrows { event.validate() } + assertThat(event.isValid()).isFalse() + continue + } + } + assertThat(event.isValid()).isEqualTo(originalIsValid) + if (originalIsValid) { + assertThat(event.validate()).isSameAs(event) + assertThat(event.validate()).isSameAs(event) + } + } + } + } + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { BOOLEAN(JsonValue.from(false)), STRING(JsonValue.from("invalid")), diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt index 52ce31cb9..304d928ba 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/ToolTest.kt @@ -27,6 +27,7 @@ internal class ToolTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -70,6 +71,7 @@ internal class ToolTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -641,6 +643,7 @@ internal class ToolTest { CustomTool.builder() .name("name") .addAllowedCaller(CustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -674,6 +677,7 @@ internal class ToolTest { CustomTool.builder() .name("name") .addAllowedCaller(CustomTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .formatText() @@ -696,6 +700,7 @@ internal class ToolTest { NamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(NamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -741,6 +746,7 @@ internal class ToolTest { NamespaceTool.Tool.Function.builder() .name("name") .addAllowedCaller(NamespaceTool.Tool.Function.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/responses/inputtokens/InputTokenCountParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/responses/inputtokens/InputTokenCountParamsTest.kt index 2019219d3..94cb78a3f 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/responses/inputtokens/InputTokenCountParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/responses/inputtokens/InputTokenCountParamsTest.kt @@ -51,6 +51,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -101,6 +102,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -153,6 +155,7 @@ internal class InputTokenCountParamsTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/AlertRetrieveParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/AlertRetrieveParamsTest.kt new file mode 100644 index 000000000..1971b9827 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/AlertRetrieveParamsTest.kt @@ -0,0 +1,23 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.safety.alerts + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AlertRetrieveParamsTest { + + @Test + fun create() { + AlertRetrieveParams.builder().id("id").build() + } + + @Test + fun pathParams() { + val params = AlertRetrieveParams.builder().id("id").build() + + assertThat(params._pathParam(0)).isEqualTo("id") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/SafetyAlertTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/SafetyAlertTest.kt new file mode 100644 index 000000000..ff0768b9f --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/safety/alerts/SafetyAlertTest.kt @@ -0,0 +1,60 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.safety.alerts + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SafetyAlertTest { + + @Test + fun create() { + val safetyAlert = + SafetyAlert.builder() + .id("id") + .createdAt(0L) + .errorType(SafetyAlert.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER) + .model("model") + .reason("reason") + .requestId("request_id") + .requestPaused(true) + .responseId("response_id") + .build() + + assertThat(safetyAlert.id()).isEqualTo("id") + assertThat(safetyAlert.createdAt()).isEqualTo(0L) + assertThat(safetyAlert.errorType()) + .isEqualTo(SafetyAlert.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER) + assertThat(safetyAlert.model()).isEqualTo("model") + assertThat(safetyAlert.reason()).contains("reason") + assertThat(safetyAlert.requestId()).isEqualTo("request_id") + assertThat(safetyAlert.requestPaused()).isEqualTo(true) + assertThat(safetyAlert.responseId()).isEqualTo("response_id") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val safetyAlert = + SafetyAlert.builder() + .id("id") + .createdAt(0L) + .errorType(SafetyAlert.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER) + .model("model") + .reason("reason") + .requestId("request_id") + .requestPaused(true) + .responseId("response_id") + .build() + + val roundtrippedSafetyAlert = + jsonMapper.readValue( + jsonMapper.writeValueAsString(safetyAlert), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSafetyAlert).isEqualTo(safetyAlert) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoCreateErrorTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoCreateErrorTest.kt index 692b3e47b..975810a65 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoCreateErrorTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoCreateErrorTest.kt @@ -11,16 +11,58 @@ internal class VideoCreateErrorTest { @Test fun create() { - val videoCreateError = VideoCreateError.builder().code("code").message("message").build() + val videoCreateError = + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder().message("message").build() + ) + .build() + ) + .build() assertThat(videoCreateError.code()).isEqualTo("code") assertThat(videoCreateError.message()).isEqualTo("message") + assertThat(videoCreateError.misalignment()) + .contains( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType.POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer(VideoCreateError.Misalignment.Steer.builder().message("message").build()) + .build() + ) } @Test fun roundtrip() { val jsonMapper = jsonMapper() - val videoCreateError = VideoCreateError.builder().code("code").message("message").build() + val videoCreateError = + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder().message("message").build() + ) + .build() + ) + .build() val roundtrippedVideoCreateError = jsonMapper.readValue( diff --git a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt index c5731e3e7..64ea9a19d 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoListPageResponseTest.kt @@ -18,7 +18,26 @@ internal class VideoListPageResponseTest { .id("id") .completedAt(0L) .createdAt(0L) - .error(VideoCreateError.builder().code("code").message("message").build()) + .error( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) @@ -40,7 +59,26 @@ internal class VideoListPageResponseTest { .id("id") .completedAt(0L) .createdAt(0L) - .error(VideoCreateError.builder().code("code").message("message").build()) + .error( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) @@ -66,7 +104,26 @@ internal class VideoListPageResponseTest { .id("id") .completedAt(0L) .createdAt(0L) - .error(VideoCreateError.builder().code("code").message("message").build()) + .error( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt index 530cd1e7b..5327995a8 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/videos/VideoTest.kt @@ -16,7 +16,26 @@ internal class VideoTest { .id("id") .completedAt(0L) .createdAt(0L) - .error(VideoCreateError.builder().code("code").message("message").build()) + .error( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) @@ -31,7 +50,26 @@ internal class VideoTest { assertThat(video.completedAt()).contains(0L) assertThat(video.createdAt()).isEqualTo(0L) assertThat(video.error()) - .contains(VideoCreateError.builder().code("code").message("message").build()) + .contains( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) assertThat(video.expiresAt()).contains(0L) assertThat(video.model()).isEqualTo(VideoModel.SORA_2) assertThat(video.progress()).isEqualTo(0L) @@ -50,7 +88,26 @@ internal class VideoTest { .id("id") .completedAt(0L) .createdAt(0L) - .error(VideoCreateError.builder().code("code").message("message").build()) + .error( + VideoCreateError.builder() + .code("code") + .message("message") + .misalignment( + VideoCreateError.Misalignment.builder() + .detailedExplanation("detailed_explanation") + .errorType( + VideoCreateError.Misalignment.ErrorType + .POTENTIALLY_UNINTENDED_DATA_TRANSFER + ) + .steer( + VideoCreateError.Misalignment.Steer.builder() + .message("message") + .build() + ) + .build() + ) + .build() + ) .expiresAt(0L) .model(VideoModel.SORA_2) .progress(0L) diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEventTest.kt new file mode 100644 index 000000000..cc06b96a8 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyAlertCreatedWebhookEventTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SafetyAlertCreatedWebhookEventTest { + + @Test + fun create() { + val safetyAlertCreatedWebhookEvent = + SafetyAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + assertThat(safetyAlertCreatedWebhookEvent.id()).isEqualTo("id") + assertThat(safetyAlertCreatedWebhookEvent.createdAt()).isEqualTo(0L) + assertThat(safetyAlertCreatedWebhookEvent.data()) + .isEqualTo( + SafetyAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val safetyAlertCreatedWebhookEvent = + SafetyAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + val roundtrippedSafetyAlertCreatedWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(safetyAlertCreatedWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSafetyAlertCreatedWebhookEvent) + .isEqualTo(safetyAlertCreatedWebhookEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEventTest.kt new file mode 100644 index 000000000..78cbbb72c --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/SafetyOrgAlertCreatedWebhookEventTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.models.webhooks + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.openai.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class SafetyOrgAlertCreatedWebhookEventTest { + + @Test + fun create() { + val safetyOrgAlertCreatedWebhookEvent = + SafetyOrgAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyOrgAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + assertThat(safetyOrgAlertCreatedWebhookEvent.id()).isEqualTo("id") + assertThat(safetyOrgAlertCreatedWebhookEvent.createdAt()).isEqualTo(0L) + assertThat(safetyOrgAlertCreatedWebhookEvent.data()) + .isEqualTo( + SafetyOrgAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val safetyOrgAlertCreatedWebhookEvent = + SafetyOrgAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyOrgAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + val roundtrippedSafetyOrgAlertCreatedWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(safetyOrgAlertCreatedWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedSafetyOrgAlertCreatedWebhookEvent) + .isEqualTo(safetyOrgAlertCreatedWebhookEvent) + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt index 747cbbf5b..95a6bf4a9 100644 --- a/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/models/webhooks/UnwrapWebhookEventTest.kt @@ -42,6 +42,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -94,6 +96,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -146,6 +150,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -198,6 +204,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -250,6 +258,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -302,6 +312,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -354,6 +366,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -406,6 +420,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -458,6 +474,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -510,6 +528,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -572,6 +592,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -644,6 +666,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -706,6 +730,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -758,6 +784,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).contains(responseCompleted) assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -810,6 +838,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).contains(responseFailed) assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -862,6 +892,8 @@ internal class UnwrapWebhookEventTest { assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty assertThat(unwrapWebhookEvent.responseFailed()).isEmpty assertThat(unwrapWebhookEvent.responseIncomplete()).contains(responseIncomplete) + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty } @Test @@ -886,6 +918,126 @@ internal class UnwrapWebhookEventTest { assertThat(roundtrippedUnwrapWebhookEvent).isEqualTo(unwrapWebhookEvent) } + @Test + fun ofSafetyAlertCreated() { + val safetyAlertCreated = + SafetyAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyAlertCreated(safetyAlertCreated) + + assertThat(unwrapWebhookEvent.batchCancelled()).isEmpty + assertThat(unwrapWebhookEvent.batchCompleted()).isEmpty + assertThat(unwrapWebhookEvent.batchExpired()).isEmpty + assertThat(unwrapWebhookEvent.batchFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunCanceled()).isEmpty + assertThat(unwrapWebhookEvent.evalRunFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobCancelled()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobFailed()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.liveCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.realtimeCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.responseCancelled()).isEmpty + assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty + assertThat(unwrapWebhookEvent.responseFailed()).isEmpty + assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).contains(safetyAlertCreated) + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).isEmpty + } + + @Test + fun ofSafetyAlertCreatedRoundtrip() { + val jsonMapper = jsonMapper() + val unwrapWebhookEvent = + UnwrapWebhookEvent.ofSafetyAlertCreated( + SafetyAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + ) + + val roundtrippedUnwrapWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unwrapWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnwrapWebhookEvent).isEqualTo(unwrapWebhookEvent) + } + + @Test + fun ofSafetyOrgAlertCreated() { + val safetyOrgAlertCreated = + SafetyOrgAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyOrgAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + + val unwrapWebhookEvent = UnwrapWebhookEvent.ofSafetyOrgAlertCreated(safetyOrgAlertCreated) + + assertThat(unwrapWebhookEvent.batchCancelled()).isEmpty + assertThat(unwrapWebhookEvent.batchCompleted()).isEmpty + assertThat(unwrapWebhookEvent.batchExpired()).isEmpty + assertThat(unwrapWebhookEvent.batchFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunCanceled()).isEmpty + assertThat(unwrapWebhookEvent.evalRunFailed()).isEmpty + assertThat(unwrapWebhookEvent.evalRunSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobCancelled()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobFailed()).isEmpty + assertThat(unwrapWebhookEvent.fineTuningJobSucceeded()).isEmpty + assertThat(unwrapWebhookEvent.liveCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.realtimeCallIncoming()).isEmpty + assertThat(unwrapWebhookEvent.responseCancelled()).isEmpty + assertThat(unwrapWebhookEvent.responseCompleted()).isEmpty + assertThat(unwrapWebhookEvent.responseFailed()).isEmpty + assertThat(unwrapWebhookEvent.responseIncomplete()).isEmpty + assertThat(unwrapWebhookEvent.safetyAlertCreated()).isEmpty + assertThat(unwrapWebhookEvent.safetyOrgAlertCreated()).contains(safetyOrgAlertCreated) + } + + @Test + fun ofSafetyOrgAlertCreatedRoundtrip() { + val jsonMapper = jsonMapper() + val unwrapWebhookEvent = + UnwrapWebhookEvent.ofSafetyOrgAlertCreated( + SafetyOrgAlertCreatedWebhookEvent.builder() + .id("id") + .createdAt(0L) + .data( + SafetyOrgAlertCreatedWebhookEvent.Data.builder() + .id("alert_ecc2efdd09bd231a9ad9bd2aada37aa7") + .build() + ) + .build() + ) + + val roundtrippedUnwrapWebhookEvent = + jsonMapper.readValue( + jsonMapper.writeValueAsString(unwrapWebhookEvent), + jacksonTypeRef(), + ) + + assertThat(roundtrippedUnwrapWebhookEvent).isEqualTo(unwrapWebhookEvent) + } + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { BOOLEAN(JsonValue.from(false)), STRING(JsonValue.from("invalid")), diff --git a/openai-java-core/src/test/kotlin/com/openai/services/ServiceParamsTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/ServiceParamsTest.kt index a34595455..9d131f664 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/ServiceParamsTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/ServiceParamsTest.kt @@ -59,7 +59,7 @@ internal class ServiceParamsTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt index 6eb7c73ab..05acb72ba 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/ModelServiceAsyncTest.kt @@ -20,7 +20,7 @@ internal class ModelServiceAsyncTest { .build() val modelServiceAsync = client.models() - val modelFuture = modelServiceAsync.retrieve("gpt-5.6-sol") + val modelFuture = modelServiceAsync.retrieve("gpt-6-astra") val model = modelFuture.get() model.validate() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt index f44c6b33d..da81e0c7a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/ResponseServiceAsyncTest.kt @@ -55,7 +55,7 @@ internal class ResponseServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -137,6 +137,7 @@ internal class ResponseServiceAsyncTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -189,7 +190,7 @@ internal class ResponseServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -271,6 +272,7 @@ internal class ResponseServiceAsyncTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -386,7 +388,7 @@ internal class ResponseServiceAsyncTest { val compactedResponseFuture = responseServiceAsync.compact( ResponseCompactParams.builder() - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ResponseServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ResponseServiceAsyncTest.kt index c93f0ef77..2bb03f2c1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ResponseServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ResponseServiceAsyncTest.kt @@ -53,7 +53,7 @@ internal class ResponseServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -141,6 +141,7 @@ internal class ResponseServiceAsyncTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -193,7 +194,7 @@ internal class ResponseServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -281,6 +282,7 @@ internal class ResponseServiceAsyncTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -411,7 +413,7 @@ internal class ResponseServiceAsyncTest { responseServiceAsync.compact( ResponseCompactParams.builder() .addBeta(ResponseCompactParams.Beta.RESPONSES_MULTI_AGENT_V1) - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt index c749d5025..31579a38e 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/ThreadServiceAsyncTest.kt @@ -186,7 +186,7 @@ internal class ThreadServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) @@ -308,7 +308,7 @@ internal class ThreadServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/responses/InputTokenServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/responses/InputTokenServiceAsyncTest.kt index 9eca1b5eb..fef97315a 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/responses/InputTokenServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/responses/InputTokenServiceAsyncTest.kt @@ -61,6 +61,7 @@ internal class InputTokenServiceAsyncTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt index 7ff0ad04d..78843dca4 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/beta/threads/RunServiceAsyncTest.kt @@ -64,7 +64,7 @@ internal class RunServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() @@ -128,7 +128,7 @@ internal class RunServiceAsyncTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt index eae703ea8..d5fc91aa8 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/chat/ChatCompletionServiceAsyncTest.kt @@ -43,7 +43,7 @@ internal class ChatCompletionServiceAsyncTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) @@ -196,7 +196,7 @@ internal class ChatCompletionServiceAsyncTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputTokenServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputTokenServiceAsyncTest.kt index db3f75111..5f3c523fe 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputTokenServiceAsyncTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/responses/InputTokenServiceAsyncTest.kt @@ -63,6 +63,7 @@ internal class InputTokenServiceAsyncTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/services/async/safety/AlertServiceAsyncTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/async/safety/AlertServiceAsyncTest.kt new file mode 100644 index 000000000..cd1f58985 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/async/safety/AlertServiceAsyncTest.kt @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.async.safety + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClientAsync +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AlertServiceAsyncTest { + + @Test + fun retrieve() { + val client = + OpenAIOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val alertServiceAsync = client.safety().alerts() + + val safetyAlertFuture = alertServiceAsync.retrieve("id") + + val safetyAlert = safetyAlertFuture.get() + safetyAlert.validate() + } +} diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt index 34d85753a..2a95842db 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ModelServiceTest.kt @@ -20,7 +20,7 @@ internal class ModelServiceTest { .build() val modelService = client.models() - val model = modelService.retrieve("gpt-5.6-sol") + val model = modelService.retrieve("gpt-6-astra") model.validate() } diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt index c593ca106..bd3b4e664 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/ResponseServiceTest.kt @@ -55,7 +55,7 @@ internal class ResponseServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -137,6 +137,7 @@ internal class ResponseServiceTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -188,7 +189,7 @@ internal class ResponseServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -270,6 +271,7 @@ internal class ResponseServiceTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -381,7 +383,7 @@ internal class ResponseServiceTest { val compactedResponse = responseService.compact( ResponseCompactParams.builder() - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ResponseServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ResponseServiceTest.kt index 2db574874..afe593c50 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ResponseServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ResponseServiceTest.kt @@ -53,7 +53,7 @@ internal class ResponseServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -141,6 +141,7 @@ internal class ResponseServiceTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -192,7 +193,7 @@ internal class ResponseServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ResponseCreateParams.Model.GPT_5_6_SOL) + .model(ResponseCreateParams.Model.GPT_6_ASTRA) .moderation( ResponseCreateParams.Moderation.builder() .model("model") @@ -280,6 +281,7 @@ internal class ResponseServiceTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( @@ -402,7 +404,7 @@ internal class ResponseServiceTest { responseService.compact( ResponseCompactParams.builder() .addBeta(ResponseCompactParams.Beta.RESPONSES_MULTI_AGENT_V1) - .model(ResponseCompactParams.Model.GPT_5_6_SOL) + .model(ResponseCompactParams.Model.GPT_6_ASTRA) .input("string") .instructions("instructions") .previousResponseId("resp_123") diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt index d4b59df87..7de5048f1 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/ThreadServiceTest.kt @@ -182,7 +182,7 @@ internal class ThreadServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) @@ -303,7 +303,7 @@ internal class ThreadServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .responseFormatAuto() .temperature(1.0) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/responses/InputTokenServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/responses/InputTokenServiceTest.kt index c9a052bea..ebe182bfe 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/responses/InputTokenServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/responses/InputTokenServiceTest.kt @@ -61,6 +61,7 @@ internal class InputTokenServiceTest { ) .strict(true) .addAllowedCaller(BetaFunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt index 08c503bc8..a45dde8d6 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/beta/threads/RunServiceTest.kt @@ -64,7 +64,7 @@ internal class RunServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() @@ -127,7 +127,7 @@ internal class RunServiceTest { .putAdditionalProperty("foo", JsonValue.from("string")) .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .parallelToolCalls(true) .reasoningEffort(ReasoningEffort.NONE) .responseFormatAuto() diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt index a28375bd3..6e22052c9 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/chat/ChatCompletionServiceTest.kt @@ -43,7 +43,7 @@ internal class ChatCompletionServiceTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) @@ -195,7 +195,7 @@ internal class ChatCompletionServiceTest { .name("name") .build() ) - .model(ChatModel.GPT_5_6_SOL) + .model(ChatModel.GPT_6_ASTRA) .audio( ChatCompletionAudioParam.builder() .format(ChatCompletionAudioParam.Format.WAV) diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputTokenServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputTokenServiceTest.kt index 33e76b776..2cedb3bda 100644 --- a/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputTokenServiceTest.kt +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/responses/InputTokenServiceTest.kt @@ -63,6 +63,7 @@ internal class InputTokenServiceTest { ) .strict(true) .addAllowedCaller(FunctionTool.AllowedCaller.DIRECT) + .async(true) .deferLoading(true) .description("description") .outputSchema( diff --git a/openai-java-core/src/test/kotlin/com/openai/services/blocking/safety/AlertServiceTest.kt b/openai-java-core/src/test/kotlin/com/openai/services/blocking/safety/AlertServiceTest.kt new file mode 100644 index 000000000..f29886259 --- /dev/null +++ b/openai-java-core/src/test/kotlin/com/openai/services/blocking/safety/AlertServiceTest.kt @@ -0,0 +1,27 @@ +// File generated from our OpenAPI spec by Castiron. See CONTRIBUTING.md for details. + +package com.openai.services.blocking.safety + +import com.openai.TestServerExtension +import com.openai.client.okhttp.OpenAIOkHttpClient +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class AlertServiceTest { + + @Test + fun retrieve() { + val client = + OpenAIOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .adminApiKey("My Admin API Key") + .build() + val alertService = client.safety().alerts() + + val safetyAlert = alertService.retrieve("id") + + safetyAlert.validate() + } +}