This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 274f656b69a7 camel-openai: remove temperature default and add extra 
request params (#20735)
274f656b69a7 is described below

commit 274f656b69a7afea51346775cd62e35360a58daf
Author: loop9x <[email protected]>
AuthorDate: Sun Jan 11 10:56:42 2026 +0100

    camel-openai: remove temperature default and add extra request params 
(#20735)
    
    Co-authored-by: Ivo Bek <[email protected]>
---
 .../component/openai/OpenAIEndpointConfigurer.java | 15 ++++++++++
 .../component/openai/OpenAIEndpointUriFactory.java |  7 +++--
 .../org/apache/camel/component/openai/openai.json  | 33 +++++++++++-----------
 .../component/openai/OpenAIConfiguration.java      | 22 ++++++++++++---
 .../camel/component/openai/OpenAIProducer.java     | 30 ++++++++++++++++++++
 .../component/openai/OpenAIProducerMockTest.java   | 26 +++++++++++++++++
 6 files changed, 111 insertions(+), 22 deletions(-)

diff --git 
a/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointConfigurer.java
 
b/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointConfigurer.java
index 810e34fa7413..fafbf343f9ec 100644
--- 
a/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointConfigurer.java
+++ 
b/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointConfigurer.java
@@ -23,6 +23,8 @@ public class OpenAIEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         OpenAIEndpoint target = (OpenAIEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalbodyproperty":
+        case "additionalBodyProperty": 
target.getConfiguration().setAdditionalBodyProperty(property(camelContext, 
java.util.Map.class, value)); return true;
         case "apikey":
         case "apiKey": 
target.getConfiguration().setApiKey(property(camelContext, 
java.lang.String.class, value)); return true;
         case "baseurl":
@@ -59,6 +61,8 @@ public class OpenAIEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalbodyproperty":
+        case "additionalBodyProperty": return java.util.Map.class;
         case "apikey":
         case "apiKey": return java.lang.String.class;
         case "baseurl":
@@ -96,6 +100,8 @@ public class OpenAIEndpointConfigurer extends 
PropertyConfigurerSupport implemen
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         OpenAIEndpoint target = (OpenAIEndpoint) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalbodyproperty":
+        case "additionalBodyProperty": return 
target.getConfiguration().getAdditionalBodyProperty();
         case "apikey":
         case "apiKey": return target.getConfiguration().getApiKey();
         case "baseurl":
@@ -128,5 +134,14 @@ public class OpenAIEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         default: return null;
         }
     }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean 
ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "additionalbodyproperty":
+        case "additionalBodyProperty": return java.lang.Object.class;
+        default: return null;
+        }
+    }
 }
 
diff --git 
a/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointUriFactory.java
 
b/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointUriFactory.java
index 43a2de620e74..bf1692e86f54 100644
--- 
a/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointUriFactory.java
+++ 
b/components/camel-ai/camel-openai/src/generated/java/org/apache/camel/component/openai/OpenAIEndpointUriFactory.java
@@ -23,7 +23,8 @@ public class OpenAIEndpointUriFactory extends 
org.apache.camel.support.component
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(17);
+        Set<String> props = new HashSet<>(18);
+        props.add("additionalBodyProperty");
         props.add("apiKey");
         props.add("baseUrl");
         props.add("conversationHistoryProperty");
@@ -45,7 +46,9 @@ public class OpenAIEndpointUriFactory extends 
org.apache.camel.support.component
         Set<String> secretProps = new HashSet<>(1);
         secretProps.add("apiKey");
         SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
-        MULTI_VALUE_PREFIXES = Collections.emptyMap();
+        Map<String, String> prefixes = new HashMap<>(1);
+        prefixes.put("additionalBodyProperty", "additionalBodyProperty.");
+        MULTI_VALUE_PREFIXES = Collections.unmodifiableMap(prefixes);
     }
 
     @Override
diff --git 
a/components/camel-ai/camel-openai/src/generated/resources/META-INF/org/apache/camel/component/openai/openai.json
 
b/components/camel-ai/camel-openai/src/generated/resources/META-INF/org/apache/camel/component/openai/openai.json
index d018ffaa223a..a091fe5a9b02 100644
--- 
a/components/camel-ai/camel-openai/src/generated/resources/META-INF/org/apache/camel/component/openai/openai.json
+++ 
b/components/camel-ai/camel-openai/src/generated/resources/META-INF/org/apache/camel/component/openai/openai.json
@@ -32,21 +32,22 @@
   },
   "properties": {
     "operation": { "index": 0, "kind": "path", "displayName": "Operation", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The operation to perform 
(currently only chat-completion is supported)" },
-    "apiKey": { "index": 1, "kind": "parameter", "displayName": "Api Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "OpenAI API key. Can also be set via 
OPENAI_API_KEY environment variable." },
-    "baseUrl": { "index": 2, "kind": "parameter", "displayName": "Base Url", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Base URL for OpenAI API. Defaults to OpenAI's 
official endpoint. Can be used for local or third-p [...]
-    "conversationHistoryProperty": { "index": 3, "kind": "parameter", 
"displayName": "Conversation History Property", "group": "producer", "label": 
"", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": "CamelOpenAIConversationHistory", "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Exchan [...]
-    "conversationMemory": { "index": 4, "kind": "parameter", "displayName": 
"Conversation Memory", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Enable conversation memory per Exchange" },
-    "developerMessage": { "index": 5, "kind": "parameter", "displayName": 
"Developer Message", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Developer message to 
prepend before user messages" },
-    "jsonSchema": { "index": 6, "kind": "parameter", "displayName": "Json 
Schema", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "JSON schema for 
structured output validation" },
-    "maxTokens": { "index": 7, "kind": "parameter", "displayName": "Max 
Tokens", "group": "producer", "label": "", "required": false, "type": 
"integer", "javaType": "java.lang.Integer", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Maximum number of tokens 
to generate" },
-    "model": { "index": 8, "kind": "parameter", "displayName": "Model", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": "gpt-5", 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "The model to use for 
chat completion" },
-    "outputClass": { "index": 9, "kind": "parameter", "displayName": "Output 
Class", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Fully qualified class name for structured 
output using response format" },
-    "storeFullResponse": { "index": 10, "kind": "parameter", "displayName": 
"Store Full Response", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Store the full response in the exchange 
property 'CamelOpenA [...]
-    "streaming": { "index": 11, "kind": "parameter", "displayName": 
"Streaming", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Enable streaming 
responses" },
-    "systemMessage": { "index": 12, "kind": "parameter", "displayName": 
"System Message", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "System message to 
prepend. When set and conversationMemory is enabled, the conversat [...]
-    "temperature": { "index": 13, "kind": "parameter", "displayName": 
"Temperature", "group": "producer", "label": "", "required": false, "type": 
"number", "javaType": "java.lang.Double", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
"1.0", "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Temperature for response generation (0.0 to 
2.0)" },
-    "topP": { "index": 14, "kind": "parameter", "displayName": "Top P", 
"group": "producer", "label": "", "required": false, "type": "number", 
"javaType": "java.lang.Double", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Top P for response generation (0.0 to 1.0)" },
-    "userMessage": { "index": 15, "kind": "parameter", "displayName": "User 
Message", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Default user message 
text to use when no prompt is provided" },
-    "lazyStartProducer": { "index": 16, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
+    "additionalBodyProperty": { "index": 1, "kind": "parameter", 
"displayName": "Additional Body Property", "group": "producer", "label": "", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": 
"additionalBodyProperty.", "multiValue": true, "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configur [...]
+    "apiKey": { "index": 2, "kind": "parameter", "displayName": "Api Key", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": true, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "OpenAI API key. Can also be set via 
OPENAI_API_KEY environment variable." },
+    "baseUrl": { "index": 3, "kind": "parameter", "displayName": "Base Url", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Base URL for OpenAI API. Defaults to OpenAI's 
official endpoint. Can be used for local or third-p [...]
+    "conversationHistoryProperty": { "index": 4, "kind": "parameter", 
"displayName": "Conversation History Property", "group": "producer", "label": 
"", "required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "defaultValue": "CamelOpenAIConversationHistory", "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Exchan [...]
+    "conversationMemory": { "index": 5, "kind": "parameter", "displayName": 
"Conversation Memory", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Enable conversation memory per Exchange" },
+    "developerMessage": { "index": 6, "kind": "parameter", "displayName": 
"Developer Message", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Developer message to 
prepend before user messages" },
+    "jsonSchema": { "index": 7, "kind": "parameter", "displayName": "Json 
Schema", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "JSON schema for 
structured output validation" },
+    "maxTokens": { "index": 8, "kind": "parameter", "displayName": "Max 
Tokens", "group": "producer", "label": "", "required": false, "type": 
"integer", "javaType": "java.lang.Integer", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Maximum number of tokens 
to generate" },
+    "model": { "index": 9, "kind": "parameter", "displayName": "Model", 
"group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "The model to use for chat completion" },
+    "outputClass": { "index": 10, "kind": "parameter", "displayName": "Output 
Class", "group": "producer", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Fully qualified class name for structured 
output using response format" },
+    "storeFullResponse": { "index": 11, "kind": "parameter", "displayName": 
"Store Full Response", "group": "producer", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 
false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Store the full response in the exchange 
property 'CamelOpenA [...]
+    "streaming": { "index": 12, "kind": "parameter", "displayName": 
"Streaming", "group": "producer", "label": "", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Enable streaming 
responses" },
+    "systemMessage": { "index": 13, "kind": "parameter", "displayName": 
"System Message", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "System message to 
prepend. When set and conversationMemory is enabled, the conversat [...]
+    "temperature": { "index": 14, "kind": "parameter", "displayName": 
"Temperature", "group": "producer", "label": "", "required": false, "type": 
"number", "javaType": "java.lang.Double", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Temperature for response 
generation (0.0 to 2.0)" },
+    "topP": { "index": 15, "kind": "parameter", "displayName": "Top P", 
"group": "producer", "label": "", "required": false, "type": "number", 
"javaType": "java.lang.Double", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": 
"configuration", "description": "Top P for response generation (0.0 to 1.0)" },
+    "userMessage": { "index": 16, "kind": "parameter", "displayName": "User 
Message", "group": "producer", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, 
"configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", 
"configurationField": "configuration", "description": "Default user message 
text to use when no prompt is provided" },
+    "lazyStartProducer": { "index": 17, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
   }
 }
diff --git 
a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConfiguration.java
 
b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConfiguration.java
index e09948a9616e..6e076149a944 100644
--- 
a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConfiguration.java
+++ 
b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConfiguration.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.openai;
 
+import java.util.Map;
+
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriParams;
@@ -34,13 +36,13 @@ public class OpenAIConfiguration implements Cloneable {
     @Metadata(description = "Base URL for OpenAI API. Defaults to OpenAI's 
official endpoint. Can be used for local or third-party providers.")
     private String baseUrl;
 
-    @UriParam(defaultValue = "gpt-5")
+    @UriParam
     @Metadata(description = "The model to use for chat completion")
-    private String model = "gpt-5";
+    private String model;
 
-    @UriParam(defaultValue = "1.0")
+    @UriParam
     @Metadata(description = "Temperature for response generation (0.0 to 2.0)")
-    private Double temperature = 1.0;
+    private Double temperature;
 
     @UriParam
     @Metadata(description = "Top P for response generation (0.0 to 1.0)")
@@ -88,6 +90,10 @@ public class OpenAIConfiguration implements Cloneable {
     @Metadata(description = "Store the full response in the exchange property 
'CamelOpenAIResponse' in non-streaming mode")
     private boolean storeFullResponse = false;
 
+    @UriParam(prefix = "additionalBodyProperty.", multiValue = true)
+    @Metadata(description = "Additional JSON properties to include in the 
request body (e.g. additionalBodyProperty.traceId=123)")
+    private Map<String, Object> additionalBodyProperty;
+
     public String getApiKey() {
         return apiKey;
     }
@@ -208,6 +214,14 @@ public class OpenAIConfiguration implements Cloneable {
         this.storeFullResponse = storeFullResponse;
     }
 
+    public Map<String, Object> getAdditionalBodyProperty() {
+        return additionalBodyProperty;
+    }
+
+    public void setAdditionalBodyProperty(Map<String, Object> 
additionalBodyProperty) {
+        this.additionalBodyProperty = additionalBodyProperty;
+    }
+
     public OpenAIConfiguration copy() {
         try {
             return (OpenAIConfiguration) clone();
diff --git 
a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIProducer.java
 
b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIProducer.java
index 5cbe1350bbbc..3aa022c5b295 100644
--- 
a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIProducer.java
+++ 
b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIProducer.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Base64;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.openai.core.JsonValue;
@@ -165,6 +166,8 @@ public class OpenAIProducer extends DefaultAsyncProducer {
             }
         }
 
+        applyAdditionalBodyProperties(paramsBuilder, config);
+
         ChatCompletionCreateParams params = paramsBuilder.build();
 
         if (Boolean.TRUE.equals(streaming)) {
@@ -448,6 +451,33 @@ public class OpenAIProducer extends DefaultAsyncProducer {
         return sb.build();
     }
 
+    private void 
applyAdditionalBodyProperties(ChatCompletionCreateParams.Builder paramsBuilder, 
OpenAIConfiguration config) {
+        Map<String, Object> additional = config.getAdditionalBodyProperty();
+        if (additional == null || additional.isEmpty()) {
+            return;
+        }
+
+        for (Map.Entry<String, Object> e : additional.entrySet()) {
+            String key = e.getKey();
+            Object rawValue = e.getValue();
+            Object valueToUse = rawValue;
+            if (rawValue instanceof String s) {
+                valueToUse = parseJsonOrString(s);
+            }
+
+            paramsBuilder.putAdditionalBodyProperty(key, 
JsonValue.from((Object) valueToUse));
+        }
+    }
+
+    private Object parseJsonOrString(String value) {
+        try {
+            return OBJECT_MAPPER.readValue(value, Object.class);
+        } catch (Exception e) {
+            // treat as literal string
+            return value;
+        }
+    }
+
     private <T> T resolveParameter(Message message, String headerName, T 
defaultValue, Class<T> type) {
         T headerValue = message.getHeader(headerName, type);
         return ObjectHelper.isNotEmpty(headerValue) ? headerValue : 
defaultValue;
diff --git 
a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIProducerMockTest.java
 
b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIProducerMockTest.java
index 2054c6ebb6c7..3dc7822c3376 100644
--- 
a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIProducerMockTest.java
+++ 
b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIProducerMockTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.openai;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.test.infra.openai.mock.OpenAIMock;
@@ -29,11 +31,25 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class OpenAIProducerMockTest extends CamelTestSupport {
 
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
     @RegisterExtension
     public OpenAIMock openAIMock = new OpenAIMock().builder()
             .when("hello")
             .replyWith("Hi from mock")
             .end()
+            .when("hello-extra")
+            .assertRequest(request -> {
+                try {
+                    JsonNode root = OBJECT_MAPPER.readTree(request);
+                    assertTrue(root.has("traceId"), "Expected traceId in 
request body");
+                    assertEquals(123, root.get("traceId").asInt());
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            })
+            .replyWith("Hi from mock")
+            .end()
             .when("json please")
             .replyWith("{\"ok\":true}")
             .end()
@@ -49,6 +65,10 @@ public class OpenAIProducerMockTest extends CamelTestSupport 
{
                         
.to("openai:chat-completion?model=gpt-5&apiKey=dummy&baseUrl=" + 
openAIMock.getBaseUrl()
                             + "/v1");
 
+                from("direct:chat-extra")
+                        
.to("openai:chat-completion?model=gpt-5&apiKey=dummy&baseUrl=" + 
openAIMock.getBaseUrl()
+                            + "/v1&additionalBodyProperty.traceId=123");
+
                 // Streaming chat route using the mock server
                 from("direct:chat-stream")
                         
.to("openai:chat-completion?model=gpt-5&apiKey=dummy&streaming=true&baseUrl="
@@ -86,4 +106,10 @@ public class OpenAIProducerMockTest extends 
CamelTestSupport {
         assertTrue(body instanceof java.util.Iterator);
     }
 
+    @Test
+    void additionalBodyPropertyIsIncludedInRequestBody() {
+        Exchange result = template.request("direct:chat-extra", e -> 
e.getIn().setBody("hello-extra"));
+        assertEquals("Hi from mock", 
result.getMessage().getBody(String.class));
+    }
+
 }

Reply via email to