diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openai.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openai.json index f47aeee9a1558..d83b0bb3991ef 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openai.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openai.json @@ -51,34 +51,37 @@ "CamelOpenAIResponseModel": { "index": 14, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model used for the completion response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE_MODEL" }, "CamelOpenAIResponseId": { "index": 15, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The unique identifier for the completion response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE_ID" }, "CamelOpenAIFinishReason": { "index": 16, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The reason the completion finished (e.g., stop, length, content_filter)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#FINISH_REASON" }, - "CamelOpenAIPromptTokens": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the prompt", "constantName": "org.apache.camel.component.openai.OpenAIConstants#PROMPT_TOKENS" }, - "CamelOpenAICompletionTokens": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the completion", "constantName": "org.apache.camel.component.openai.OpenAIConstants#COMPLETION_TOKENS" }, - "CamelOpenAITotalTokens": { "index": 19, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The total number of tokens used (prompt completion)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOTAL_TOKENS" }, + "CamelOpenAIPromptTokens": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the prompt for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#PROMPT_TOKENS" }, + "CamelOpenAICompletionTokens": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the completion for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#COMPLETION_TOKENS" }, + "CamelOpenAITotalTokens": { "index": 19, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The total number of tokens used (prompt completion) for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOTAL_TOKENS" }, "CamelOpenAIToolIterations": { "index": 20, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of tool call iterations performed in the agentic loop", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOOL_ITERATIONS" }, "CamelOpenAIMcpToolCalls": { "index": 21, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.util.List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "List of tool names called during the agentic loop", "constantName": "org.apache.camel.component.openai.OpenAIConstants#MCP_TOOL_CALLS" }, "CamelOpenAIMcpReturnDirect": { "index": 22, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the response came directly from a tool with returnDirect=true, rather than from the LLM", "constantName": "org.apache.camel.component.openai.OpenAIConstants#MCP_RETURN_DIRECT" }, - "CamelOpenAIResponse": { "index": 23, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "com.openai.models.ChatCompletion", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The complete OpenAI response object", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE" }, - "CamelOpenAIEmbeddingModel": { "index": 24, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_MODEL" }, - "CamelOpenAIEmbeddingDimensions": { "index": 25, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of output dimensions", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_DIMENSIONS" }, - "CamelOpenAIEmbeddingResponseModel": { "index": 26, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The embedding model used in the response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_RESPONSE_MODEL" }, - "CamelOpenAIEmbeddingCount": { "index": 27, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of embeddings returned", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_COUNT" }, - "CamelOpenAIEmbeddingVectorSize": { "index": 28, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Vector dimensions of the embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_VECTOR_SIZE" }, - "CamelOpenAIReferenceEmbedding": { "index": 29, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Reference embedding vector for similarity comparison", "constantName": "org.apache.camel.component.openai.OpenAIConstants#REFERENCE_EMBEDDING" }, - "CamelOpenAISimilarityScore": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Calculated cosine similarity score (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SIMILARITY_SCORE" }, - "CamelOpenAIOriginalText": { "index": 31, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String or List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Original text content when embeddings operation is used", "constantName": "org.apache.camel.component.openai.OpenAIConstants#ORIGINAL_TEXT" }, - "CamelOpenAIAudioModel": { "index": 32, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for audio transcription", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_MODEL" }, - "CamelOpenAIAudioLanguage": { "index": 33, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The language of the input audio (ISO-639-1)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_LANGUAGE" }, - "CamelOpenAIAudioResponseFormat": { "index": 34, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response format for audio transcription (json, text, srt, verbose_json, vtt)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_RESPONSE_FORMAT" }, - "CamelOpenAIAudioTemperature": { "index": 35, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sampling temperature for audio transcription (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TEMPERATURE" }, - "CamelOpenAIAudioPrompt": { "index": 36, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional text to guide the model's style or continue a previous audio segment", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_PROMPT" }, - "CamelOpenAIAudioTimestampGranularities": { "index": 37, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Comma-separated timestamp granularities: word, segment, or word,segment (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TIMESTAMP_GRANULARITIES" }, - "CamelOpenAIAudioDuration": { "index": 38, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Duration of the audio in seconds (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DURATION" }, - "CamelOpenAIAudioDetectedLanguage": { "index": 39, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Language detected in the audio (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DETECTED_LANGUAGE" }, - "CamelOpenAISpeechModel": { "index": 40, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_MODEL" }, - "CamelOpenAISpeechVoice": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The voice to use for the generated audio (e.g., alloy, echo, fable, onyx, nova, shimmer)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_VOICE" }, - "CamelOpenAISpeechResponseFormat": { "index": 42, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The audio format for text-to-speech output (mp3, opus, aac, flac, wav, pcm)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_RESPONSE_FORMAT" }, - "CamelOpenAISpeechSpeed": { "index": 43, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The speed of the generated audio (0.25 to 4.0, where 1.0 is normal speed)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_SPEED" }, - "CamelOpenAISpeechInstructions": { "index": 44, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional instructions to control the voice of the generated audio (does not work with tts-1 or tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_INSTRUCTIONS" } + "CamelOpenAIAgenticPromptTokens": { "index": 23, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative prompt tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_PROMPT_TOKENS" }, + "CamelOpenAIAgenticCompletionTokens": { "index": 24, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative completion tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_COMPLETION_TOKENS" }, + "CamelOpenAIAgenticTotalTokens": { "index": 25, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative total tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_TOTAL_TOKENS" }, + "CamelOpenAIResponse": { "index": 26, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "com.openai.models.ChatCompletion", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The complete OpenAI response object", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE" }, + "CamelOpenAIEmbeddingModel": { "index": 27, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_MODEL" }, + "CamelOpenAIEmbeddingDimensions": { "index": 28, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of output dimensions", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_DIMENSIONS" }, + "CamelOpenAIEmbeddingResponseModel": { "index": 29, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The embedding model used in the response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_RESPONSE_MODEL" }, + "CamelOpenAIEmbeddingCount": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of embeddings returned", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_COUNT" }, + "CamelOpenAIEmbeddingVectorSize": { "index": 31, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Vector dimensions of the embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_VECTOR_SIZE" }, + "CamelOpenAIReferenceEmbedding": { "index": 32, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Reference embedding vector for similarity comparison", "constantName": "org.apache.camel.component.openai.OpenAIConstants#REFERENCE_EMBEDDING" }, + "CamelOpenAISimilarityScore": { "index": 33, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Calculated cosine similarity score (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SIMILARITY_SCORE" }, + "CamelOpenAIOriginalText": { "index": 34, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String or List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Original text content when embeddings operation is used", "constantName": "org.apache.camel.component.openai.OpenAIConstants#ORIGINAL_TEXT" }, + "CamelOpenAIAudioModel": { "index": 35, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for audio transcription", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_MODEL" }, + "CamelOpenAIAudioLanguage": { "index": 36, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The language of the input audio (ISO-639-1)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_LANGUAGE" }, + "CamelOpenAIAudioResponseFormat": { "index": 37, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response format for audio transcription (json, text, srt, verbose_json, vtt)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_RESPONSE_FORMAT" }, + "CamelOpenAIAudioTemperature": { "index": 38, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sampling temperature for audio transcription (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TEMPERATURE" }, + "CamelOpenAIAudioPrompt": { "index": 39, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional text to guide the model's style or continue a previous audio segment", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_PROMPT" }, + "CamelOpenAIAudioTimestampGranularities": { "index": 40, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Comma-separated timestamp granularities: word, segment, or word,segment (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TIMESTAMP_GRANULARITIES" }, + "CamelOpenAIAudioDuration": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Duration of the audio in seconds (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DURATION" }, + "CamelOpenAIAudioDetectedLanguage": { "index": 42, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Language detected in the audio (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DETECTED_LANGUAGE" }, + "CamelOpenAISpeechModel": { "index": 43, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_MODEL" }, + "CamelOpenAISpeechVoice": { "index": 44, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The voice to use for the generated audio (e.g., alloy, echo, fable, onyx, nova, shimmer)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_VOICE" }, + "CamelOpenAISpeechResponseFormat": { "index": 45, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The audio format for text-to-speech output (mp3, opus, aac, flac, wav, pcm)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_RESPONSE_FORMAT" }, + "CamelOpenAISpeechSpeed": { "index": 46, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The speed of the generated audio (0.25 to 4.0, where 1.0 is normal speed)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_SPEED" }, + "CamelOpenAISpeechInstructions": { "index": 47, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional instructions to control the voice of the generated audio (does not work with tts-1 or tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_INSTRUCTIONS" } }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.openai.OpenAIOperations", "enum": [ "chat-completion", "embeddings", "tool-execution", "audio-transcription", "audio-translation", "audio-speech" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform: 'chat-completion', 'embeddings', 'tool-execution', 'audio-transcription', 'audio-translation', or 'audio-speech'" }, @@ -101,43 +104,44 @@ "embeddingModel": { "index": 17, "kind": "parameter", "displayName": "Embedding 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 embeddings" }, "encodingFormat": { "index": 18, "kind": "parameter", "displayName": "Encoding Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "float", "base64" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "base64", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The format for embedding output: 'float' for list of floats, 'base64' for compressed format" }, "jsonSchema": { "index": 19, "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" }, - "maxHistoryMessages": { "index": 20, "kind": "parameter", "displayName": "Max History Messages", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, retain at most this many messages in the exchange conversation history. System and developer messages are prepended separately and are not stored in history. Assistant tool-call blocks are kept intact and may retain slightly more than this limit to preserve tool result pairing. When 0, no message limit is applied." }, - "maxHistoryTokens": { "index": 21, "kind": "parameter", "displayName": "Max History Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, trim conversation history using a token estimate (character count \/ 4, including image payload size for multi-modal user messages). Oldest segments are dropped first until the estimated tokens are within this limit. Assistant tool-call blocks are removed as a unit with their tool results. The most recent segment is always retained, even when it alone exceeds this limit. When 0, no token limit is applied." }, - "maxRetries": { "index": 22, "kind": "parameter", "displayName": "Max Retries", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 2, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of times the OpenAI SDK client retries failed requests. The SDK retry is rate-limit aware (honors Retry-After on 429)." }, - "maxTokens": { "index": 23, "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" }, - "maxToolIterations": { "index": 24, "kind": "parameter", "displayName": "Max Tool Iterations", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 50, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of tool call loop iterations to prevent infinite loops" }, - "mcpProtocolVersions": { "index": 25, "kind": "parameter", "displayName": "Mcp Protocol Versions", "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": "Comma-separated list of MCP protocol versions to advertise when connecting to MCP servers using Streamable HTTP transport. When not set, the SDK default is used. Example: 2024-11-05,2025-03-26,2025-06-18" }, - "mcpReconnect": { "index": 26, "kind": "parameter", "displayName": "Mcp Reconnect", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Automatically reconnect to MCP servers when a tool call fails due to a transport error, and retry the call once." }, - "mcpServer": { "index": 27, "kind": "parameter", "displayName": "Mcp Server", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "java.util.Map", "prefix": "mcpServer.", "multiValue": true, "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "MCP (Model Context Protocol) server configurations. Define servers using prefix notation: mcpServer..transportType=stdiossestreamableHttp, (Note that sse is deprecated) mcpServer..command= (stdio), mcpServer..args= (stdio), mcpServer..url= (sse\/streamableHttp), mcpServer..oauthProfile= (OAuth profile for HTTP auth, requires camel-oauth). This is a multi-value option with prefix: mcpServer." }, - "mcpTimeout": { "index": 28, "kind": "parameter", "displayName": "Mcp Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 20, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Timeout in seconds for MCP tool call requests. Applies to all MCP operations including tool execution and initialization." }, - "model": { "index": 29, "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": 30, "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" }, - "requestTimeout": { "index": 31, "kind": "parameter", "displayName": "Request Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "HTTP request timeout in milliseconds for the OpenAI SDK client. When 0 or negative, the SDK default (10 minutes) is used." }, - "speechInstructions": { "index": 32, "kind": "parameter", "displayName": "Speech Instructions", "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": "Optional instructions to control the voice of the generated audio. Does not work with tts-1 or tts-1-hd." }, - "speechModel": { "index": 33, "kind": "parameter", "displayName": "Speech 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 text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)" }, - "speechResponseFormat": { "index": 34, "kind": "parameter", "displayName": "Speech Response Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "mp3", "opus", "aac", "flac", "wav", "pcm" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "mp3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The audio format for text-to-speech output" }, - "speechSpeed": { "index": 35, "kind": "parameter", "displayName": "Speech Speed", "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": "The speed of the generated audio, from 0.25 to 4.0 where 1.0 is normal speed" }, - "speechVoice": { "index": 36, "kind": "parameter", "displayName": "Speech Voice", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "alloy", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The voice to use for text-to-speech (e.g., alloy, echo, fable, onyx, nova, shimmer). See the OpenAI documentation for the full list of supported voices." }, - "storeFullResponse": { "index": 37, "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 'CamelOpenAIResponse' in non-streaming mode" }, - "streaming": { "index": 38, "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" }, - "stripThinking": { "index": 39, "kind": "parameter", "displayName": "Strip Thinking", "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": "Strip ... blocks from model responses (used by reasoning models like Qwen3, DeepSeek-R1). The thinking content is stored in the CamelOpenAIThinkingContent header." }, - "systemMessage": { "index": 40, "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 conversation history is reset." }, - "temperature": { "index": 41, "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": 42, "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": 43, "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": 44, "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 producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing." }, - "oauthProfile": { "index": 45, "kind": "parameter", "displayName": "Oauth Profile", "group": "security", "label": "security", "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": "OAuth profile name for obtaining an access token via the OAuth 2.0 Client Credentials grant. When set, the token is acquired from the configured identity provider and used instead of apiKey. Requires camel-oauth on the classpath. The profile properties are resolved from camel.oauth..client-id, camel.oauth..client-secret, and camel.oauth..token-endpoint." }, - "sslContextParameters": { "index": 46, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "SSLContextParameters to use for configuring SSL\/TLS. When set, takes precedence over the individual sslTruststore, sslKeystore, and sslProtocol options." }, - "sslEndpointAlgorithm": { "index": 47, "kind": "parameter", "displayName": "Ssl Endpoint Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "security": "insecure:ssl", "insecureValue": "none", "defaultValue": "https", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The endpoint identification algorithm to validate the server hostname using the server certificate. Set to an empty string or 'none' to disable hostname verification" }, - "sslKeymanagerAlgorithm": { "index": 48, "kind": "parameter", "displayName": "Ssl Keymanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "SunX509", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the key manager factory for SSL connections" }, - "sslKeyPassword": { "index": 49, "kind": "parameter", "displayName": "Ssl Key Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password of the private key in the key store file" }, - "sslKeystoreLocation": { "index": 50, "kind": "parameter", "displayName": "Ssl Keystore Location", "group": "security", "label": "security", "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 location of the key store file. This is optional and can be used for two-way authentication for the OpenAI API" }, - "sslKeystorePassword": { "index": 51, "kind": "parameter", "displayName": "Ssl Keystore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The store password for the key store file" }, - "sslKeystoreType": { "index": 52, "kind": "parameter", "displayName": "Ssl Keystore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the key store file" }, - "sslProtocol": { "index": 53, "kind": "parameter", "displayName": "Ssl Protocol", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "TLSv1.3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The SSL protocol used to generate the SSLContext" }, - "sslTrustmanagerAlgorithm": { "index": 54, "kind": "parameter", "displayName": "Ssl Trustmanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "PKIX", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the trust manager factory for SSL connections" }, - "sslTruststoreLocation": { "index": 55, "kind": "parameter", "displayName": "Ssl Truststore Location", "group": "security", "label": "security", "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 location of the trust store file, used to validate the server's certificate" }, - "sslTruststorePassword": { "index": 56, "kind": "parameter", "displayName": "Ssl Truststore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password for the trust store file. If a password is not set, the configured trust store can still be used, but integrity checking is disabled" }, - "sslTruststoreType": { "index": 57, "kind": "parameter", "displayName": "Ssl Truststore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the trust store file" } + "maxAgenticTokens": { "index": 20, "kind": "parameter", "displayName": "Max Agentic Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum cumulative prompt plus completion tokens allowed across the MCP agentic loop. When 0 or negative, no token budget is enforced. Enforcement runs after each API call that requests further tool execution, so actual spend may exceed the configured budget by up to one call (typically the largest, as the prompt grows each iteration). A final text response is returned even when cumulative usage exceeds the budget." }, + "maxHistoryMessages": { "index": 21, "kind": "parameter", "displayName": "Max History Messages", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, retain at most this many messages in the exchange conversation history. System and developer messages are prepended separately and are not stored in history. Assistant tool-call blocks are kept intact and may retain slightly more than this limit to preserve tool result pairing. When 0, no message limit is applied." }, + "maxHistoryTokens": { "index": 22, "kind": "parameter", "displayName": "Max History Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, trim conversation history using a token estimate (character count \/ 4, including image payload size for multi-modal user messages). Oldest segments are dropped first until the estimated tokens are within this limit. Assistant tool-call blocks are removed as a unit with their tool results. The most recent segment is always retained, even when it alone exceeds this limit. When 0, no token limit is applied." }, + "maxRetries": { "index": 23, "kind": "parameter", "displayName": "Max Retries", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 2, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of times the OpenAI SDK client retries failed requests. The SDK retry is rate-limit aware (honors Retry-After on 429)." }, + "maxTokens": { "index": 24, "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" }, + "maxToolIterations": { "index": 25, "kind": "parameter", "displayName": "Max Tool Iterations", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 50, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of tool call loop iterations to prevent infinite loops" }, + "mcpProtocolVersions": { "index": 26, "kind": "parameter", "displayName": "Mcp Protocol Versions", "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": "Comma-separated list of MCP protocol versions to advertise when connecting to MCP servers using Streamable HTTP transport. When not set, the SDK default is used. Example: 2024-11-05,2025-03-26,2025-06-18" }, + "mcpReconnect": { "index": 27, "kind": "parameter", "displayName": "Mcp Reconnect", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Automatically reconnect to MCP servers when a tool call fails due to a transport error, and retry the call once." }, + "mcpServer": { "index": 28, "kind": "parameter", "displayName": "Mcp Server", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "java.util.Map", "prefix": "mcpServer.", "multiValue": true, "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "MCP (Model Context Protocol) server configurations. Define servers using prefix notation: mcpServer..transportType=stdiossestreamableHttp, (Note that sse is deprecated) mcpServer..command= (stdio), mcpServer..args= (stdio), mcpServer..url= (sse\/streamableHttp), mcpServer..oauthProfile= (OAuth profile for HTTP auth, requires camel-oauth). This is a multi-value option with prefix: mcpServer." }, + "mcpTimeout": { "index": 29, "kind": "parameter", "displayName": "Mcp Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 20, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Timeout in seconds for MCP tool call requests. Applies to all MCP operations including tool execution and initialization." }, + "model": { "index": 30, "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": 31, "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" }, + "requestTimeout": { "index": 32, "kind": "parameter", "displayName": "Request Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "HTTP request timeout in milliseconds for the OpenAI SDK client. When 0 or negative, the SDK default (10 minutes) is used." }, + "speechInstructions": { "index": 33, "kind": "parameter", "displayName": "Speech Instructions", "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": "Optional instructions to control the voice of the generated audio. Does not work with tts-1 or tts-1-hd." }, + "speechModel": { "index": 34, "kind": "parameter", "displayName": "Speech 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 text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)" }, + "speechResponseFormat": { "index": 35, "kind": "parameter", "displayName": "Speech Response Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "mp3", "opus", "aac", "flac", "wav", "pcm" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "mp3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The audio format for text-to-speech output" }, + "speechSpeed": { "index": 36, "kind": "parameter", "displayName": "Speech Speed", "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": "The speed of the generated audio, from 0.25 to 4.0 where 1.0 is normal speed" }, + "speechVoice": { "index": 37, "kind": "parameter", "displayName": "Speech Voice", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "alloy", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The voice to use for text-to-speech (e.g., alloy, echo, fable, onyx, nova, shimmer). See the OpenAI documentation for the full list of supported voices." }, + "storeFullResponse": { "index": 38, "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 'CamelOpenAIResponse' in non-streaming mode" }, + "streaming": { "index": 39, "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" }, + "stripThinking": { "index": 40, "kind": "parameter", "displayName": "Strip Thinking", "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": "Strip ... blocks from model responses (used by reasoning models like Qwen3, DeepSeek-R1). The thinking content is stored in the CamelOpenAIThinkingContent header." }, + "systemMessage": { "index": 41, "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 conversation history is reset." }, + "temperature": { "index": 42, "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": 43, "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": 44, "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": 45, "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 producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing." }, + "oauthProfile": { "index": 46, "kind": "parameter", "displayName": "Oauth Profile", "group": "security", "label": "security", "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": "OAuth profile name for obtaining an access token via the OAuth 2.0 Client Credentials grant. When set, the token is acquired from the configured identity provider and used instead of apiKey. Requires camel-oauth on the classpath. The profile properties are resolved from camel.oauth..client-id, camel.oauth..client-secret, and camel.oauth..token-endpoint." }, + "sslContextParameters": { "index": 47, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "SSLContextParameters to use for configuring SSL\/TLS. When set, takes precedence over the individual sslTruststore, sslKeystore, and sslProtocol options." }, + "sslEndpointAlgorithm": { "index": 48, "kind": "parameter", "displayName": "Ssl Endpoint Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "security": "insecure:ssl", "insecureValue": "none", "defaultValue": "https", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The endpoint identification algorithm to validate the server hostname using the server certificate. Set to an empty string or 'none' to disable hostname verification" }, + "sslKeymanagerAlgorithm": { "index": 49, "kind": "parameter", "displayName": "Ssl Keymanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "SunX509", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the key manager factory for SSL connections" }, + "sslKeyPassword": { "index": 50, "kind": "parameter", "displayName": "Ssl Key Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password of the private key in the key store file" }, + "sslKeystoreLocation": { "index": 51, "kind": "parameter", "displayName": "Ssl Keystore Location", "group": "security", "label": "security", "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 location of the key store file. This is optional and can be used for two-way authentication for the OpenAI API" }, + "sslKeystorePassword": { "index": 52, "kind": "parameter", "displayName": "Ssl Keystore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The store password for the key store file" }, + "sslKeystoreType": { "index": 53, "kind": "parameter", "displayName": "Ssl Keystore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the key store file" }, + "sslProtocol": { "index": 54, "kind": "parameter", "displayName": "Ssl Protocol", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "TLSv1.3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The SSL protocol used to generate the SSLContext" }, + "sslTrustmanagerAlgorithm": { "index": 55, "kind": "parameter", "displayName": "Ssl Trustmanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "PKIX", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the trust manager factory for SSL connections" }, + "sslTruststoreLocation": { "index": 56, "kind": "parameter", "displayName": "Ssl Truststore Location", "group": "security", "label": "security", "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 location of the trust store file, used to validate the server's certificate" }, + "sslTruststorePassword": { "index": 57, "kind": "parameter", "displayName": "Ssl Truststore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password for the trust store file. If a password is not set, the configured trust store can still be used, but integrity checking is disabled" }, + "sslTruststoreType": { "index": 58, "kind": "parameter", "displayName": "Ssl Truststore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the trust store file" } } } 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 329e10d77ed9e..25f391b33ff89 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 @@ -62,6 +62,8 @@ public boolean configure(CamelContext camelContext, Object obj, String name, Obj case "jsonSchema": target.getConfiguration().setJsonSchema(property(camelContext, java.lang.String.class, value)); return true; case "lazystartproducer": case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; + case "maxagentictokens": + case "maxAgenticTokens": target.getConfiguration().setMaxAgenticTokens(property(camelContext, long.class, value)); return true; case "maxhistorymessages": case "maxHistoryMessages": target.getConfiguration().setMaxHistoryMessages(property(camelContext, int.class, value)); return true; case "maxhistorytokens": @@ -179,6 +181,8 @@ public Class getOptionType(String name, boolean ignoreCase) { case "jsonSchema": return java.lang.String.class; case "lazystartproducer": case "lazyStartProducer": return boolean.class; + case "maxagentictokens": + case "maxAgenticTokens": return long.class; case "maxhistorymessages": case "maxHistoryMessages": return int.class; case "maxhistorytokens": @@ -297,6 +301,8 @@ public Object getOptionValue(Object obj, String name, boolean ignoreCase) { case "jsonSchema": return target.getConfiguration().getJsonSchema(); case "lazystartproducer": case "lazyStartProducer": return target.isLazyStartProducer(); + case "maxagentictokens": + case "maxAgenticTokens": return target.getConfiguration().getMaxAgenticTokens(); case "maxhistorymessages": case "maxHistoryMessages": return target.getConfiguration().getMaxHistoryMessages(); case "maxhistorytokens": 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 d607a11ea171e..c4e4f3e3fb412 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 @@ -24,7 +24,7 @@ public class OpenAIEndpointUriFactory extends org.apache.camel.support.component private static final Set ENDPOINT_IDENTITY_PROPERTY_NAMES; private static final Map MULTI_VALUE_PREFIXES; static { - Set props = new HashSet<>(58); + Set props = new HashSet<>(59); props.add("additionalBodyProperty"); props.add("additionalHeader"); props.add("additionalResponseHeader"); @@ -45,6 +45,7 @@ public class OpenAIEndpointUriFactory extends org.apache.camel.support.component props.add("encodingFormat"); props.add("jsonSchema"); props.add("lazyStartProducer"); + props.add("maxAgenticTokens"); props.add("maxHistoryMessages"); props.add("maxHistoryTokens"); props.add("maxRetries"); 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 f47aeee9a1558..d83b0bb3991ef 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 @@ -51,34 +51,37 @@ "CamelOpenAIResponseModel": { "index": 14, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model used for the completion response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE_MODEL" }, "CamelOpenAIResponseId": { "index": 15, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The unique identifier for the completion response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE_ID" }, "CamelOpenAIFinishReason": { "index": 16, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The reason the completion finished (e.g., stop, length, content_filter)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#FINISH_REASON" }, - "CamelOpenAIPromptTokens": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the prompt", "constantName": "org.apache.camel.component.openai.OpenAIConstants#PROMPT_TOKENS" }, - "CamelOpenAICompletionTokens": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the completion", "constantName": "org.apache.camel.component.openai.OpenAIConstants#COMPLETION_TOKENS" }, - "CamelOpenAITotalTokens": { "index": 19, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The total number of tokens used (prompt completion)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOTAL_TOKENS" }, + "CamelOpenAIPromptTokens": { "index": 17, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the prompt for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#PROMPT_TOKENS" }, + "CamelOpenAICompletionTokens": { "index": 18, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of tokens used in the completion for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#COMPLETION_TOKENS" }, + "CamelOpenAITotalTokens": { "index": 19, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The total number of tokens used (prompt completion) for the latest API call", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOTAL_TOKENS" }, "CamelOpenAIToolIterations": { "index": 20, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of tool call iterations performed in the agentic loop", "constantName": "org.apache.camel.component.openai.OpenAIConstants#TOOL_ITERATIONS" }, "CamelOpenAIMcpToolCalls": { "index": 21, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.util.List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "List of tool names called during the agentic loop", "constantName": "org.apache.camel.component.openai.OpenAIConstants#MCP_TOOL_CALLS" }, "CamelOpenAIMcpReturnDirect": { "index": 22, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the response came directly from a tool with returnDirect=true, rather than from the LLM", "constantName": "org.apache.camel.component.openai.OpenAIConstants#MCP_RETURN_DIRECT" }, - "CamelOpenAIResponse": { "index": 23, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "com.openai.models.ChatCompletion", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The complete OpenAI response object", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE" }, - "CamelOpenAIEmbeddingModel": { "index": 24, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_MODEL" }, - "CamelOpenAIEmbeddingDimensions": { "index": 25, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of output dimensions", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_DIMENSIONS" }, - "CamelOpenAIEmbeddingResponseModel": { "index": 26, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The embedding model used in the response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_RESPONSE_MODEL" }, - "CamelOpenAIEmbeddingCount": { "index": 27, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of embeddings returned", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_COUNT" }, - "CamelOpenAIEmbeddingVectorSize": { "index": 28, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Vector dimensions of the embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_VECTOR_SIZE" }, - "CamelOpenAIReferenceEmbedding": { "index": 29, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Reference embedding vector for similarity comparison", "constantName": "org.apache.camel.component.openai.OpenAIConstants#REFERENCE_EMBEDDING" }, - "CamelOpenAISimilarityScore": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Calculated cosine similarity score (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SIMILARITY_SCORE" }, - "CamelOpenAIOriginalText": { "index": 31, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String or List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Original text content when embeddings operation is used", "constantName": "org.apache.camel.component.openai.OpenAIConstants#ORIGINAL_TEXT" }, - "CamelOpenAIAudioModel": { "index": 32, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for audio transcription", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_MODEL" }, - "CamelOpenAIAudioLanguage": { "index": 33, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The language of the input audio (ISO-639-1)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_LANGUAGE" }, - "CamelOpenAIAudioResponseFormat": { "index": 34, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response format for audio transcription (json, text, srt, verbose_json, vtt)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_RESPONSE_FORMAT" }, - "CamelOpenAIAudioTemperature": { "index": 35, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sampling temperature for audio transcription (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TEMPERATURE" }, - "CamelOpenAIAudioPrompt": { "index": 36, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional text to guide the model's style or continue a previous audio segment", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_PROMPT" }, - "CamelOpenAIAudioTimestampGranularities": { "index": 37, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Comma-separated timestamp granularities: word, segment, or word,segment (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TIMESTAMP_GRANULARITIES" }, - "CamelOpenAIAudioDuration": { "index": 38, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Duration of the audio in seconds (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DURATION" }, - "CamelOpenAIAudioDetectedLanguage": { "index": 39, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Language detected in the audio (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DETECTED_LANGUAGE" }, - "CamelOpenAISpeechModel": { "index": 40, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_MODEL" }, - "CamelOpenAISpeechVoice": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The voice to use for the generated audio (e.g., alloy, echo, fable, onyx, nova, shimmer)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_VOICE" }, - "CamelOpenAISpeechResponseFormat": { "index": 42, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The audio format for text-to-speech output (mp3, opus, aac, flac, wav, pcm)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_RESPONSE_FORMAT" }, - "CamelOpenAISpeechSpeed": { "index": 43, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The speed of the generated audio (0.25 to 4.0, where 1.0 is normal speed)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_SPEED" }, - "CamelOpenAISpeechInstructions": { "index": 44, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional instructions to control the voice of the generated audio (does not work with tts-1 or tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_INSTRUCTIONS" } + "CamelOpenAIAgenticPromptTokens": { "index": 23, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative prompt tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_PROMPT_TOKENS" }, + "CamelOpenAIAgenticCompletionTokens": { "index": 24, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative completion tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_COMPLETION_TOKENS" }, + "CamelOpenAIAgenticTotalTokens": { "index": 25, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Cumulative total tokens consumed across all agentic loop iterations", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AGENTIC_TOTAL_TOKENS" }, + "CamelOpenAIResponse": { "index": 26, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "com.openai.models.ChatCompletion", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The complete OpenAI response object", "constantName": "org.apache.camel.component.openai.OpenAIConstants#RESPONSE" }, + "CamelOpenAIEmbeddingModel": { "index": 27, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_MODEL" }, + "CamelOpenAIEmbeddingDimensions": { "index": 28, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of output dimensions", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_DIMENSIONS" }, + "CamelOpenAIEmbeddingResponseModel": { "index": 29, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The embedding model used in the response", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_RESPONSE_MODEL" }, + "CamelOpenAIEmbeddingCount": { "index": 30, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Number of embeddings returned", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_COUNT" }, + "CamelOpenAIEmbeddingVectorSize": { "index": 31, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Vector dimensions of the embeddings", "constantName": "org.apache.camel.component.openai.OpenAIConstants#EMBEDDING_VECTOR_SIZE" }, + "CamelOpenAIReferenceEmbedding": { "index": 32, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Reference embedding vector for similarity comparison", "constantName": "org.apache.camel.component.openai.OpenAIConstants#REFERENCE_EMBEDDING" }, + "CamelOpenAISimilarityScore": { "index": 33, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Calculated cosine similarity score (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SIMILARITY_SCORE" }, + "CamelOpenAIOriginalText": { "index": 34, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String or List", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Original text content when embeddings operation is used", "constantName": "org.apache.camel.component.openai.OpenAIConstants#ORIGINAL_TEXT" }, + "CamelOpenAIAudioModel": { "index": 35, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for audio transcription", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_MODEL" }, + "CamelOpenAIAudioLanguage": { "index": 36, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The language of the input audio (ISO-639-1)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_LANGUAGE" }, + "CamelOpenAIAudioResponseFormat": { "index": 37, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response format for audio transcription (json, text, srt, verbose_json, vtt)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_RESPONSE_FORMAT" }, + "CamelOpenAIAudioTemperature": { "index": 38, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sampling temperature for audio transcription (0.0 to 1.0)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TEMPERATURE" }, + "CamelOpenAIAudioPrompt": { "index": 39, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional text to guide the model's style or continue a previous audio segment", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_PROMPT" }, + "CamelOpenAIAudioTimestampGranularities": { "index": 40, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Comma-separated timestamp granularities: word, segment, or word,segment (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_TIMESTAMP_GRANULARITIES" }, + "CamelOpenAIAudioDuration": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Duration of the audio in seconds (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DURATION" }, + "CamelOpenAIAudioDetectedLanguage": { "index": 42, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Language detected in the audio (verbose_json only)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#AUDIO_DETECTED_LANGUAGE" }, + "CamelOpenAISpeechModel": { "index": 43, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The model to use for text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_MODEL" }, + "CamelOpenAISpeechVoice": { "index": 44, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The voice to use for the generated audio (e.g., alloy, echo, fable, onyx, nova, shimmer)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_VOICE" }, + "CamelOpenAISpeechResponseFormat": { "index": 45, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The audio format for text-to-speech output (mp3, opus, aac, flac, wav, pcm)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_RESPONSE_FORMAT" }, + "CamelOpenAISpeechSpeed": { "index": 46, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "Double", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The speed of the generated audio (0.25 to 4.0, where 1.0 is normal speed)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_SPEED" }, + "CamelOpenAISpeechInstructions": { "index": 47, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Optional instructions to control the voice of the generated audio (does not work with tts-1 or tts-1-hd)", "constantName": "org.apache.camel.component.openai.OpenAIConstants#SPEECH_INSTRUCTIONS" } }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.openai.OpenAIOperations", "enum": [ "chat-completion", "embeddings", "tool-execution", "audio-transcription", "audio-translation", "audio-speech" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The operation to perform: 'chat-completion', 'embeddings', 'tool-execution', 'audio-transcription', 'audio-translation', or 'audio-speech'" }, @@ -101,43 +104,44 @@ "embeddingModel": { "index": 17, "kind": "parameter", "displayName": "Embedding 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 embeddings" }, "encodingFormat": { "index": 18, "kind": "parameter", "displayName": "Encoding Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "float", "base64" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "base64", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The format for embedding output: 'float' for list of floats, 'base64' for compressed format" }, "jsonSchema": { "index": 19, "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" }, - "maxHistoryMessages": { "index": 20, "kind": "parameter", "displayName": "Max History Messages", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, retain at most this many messages in the exchange conversation history. System and developer messages are prepended separately and are not stored in history. Assistant tool-call blocks are kept intact and may retain slightly more than this limit to preserve tool result pairing. When 0, no message limit is applied." }, - "maxHistoryTokens": { "index": 21, "kind": "parameter", "displayName": "Max History Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, trim conversation history using a token estimate (character count \/ 4, including image payload size for multi-modal user messages). Oldest segments are dropped first until the estimated tokens are within this limit. Assistant tool-call blocks are removed as a unit with their tool results. The most recent segment is always retained, even when it alone exceeds this limit. When 0, no token limit is applied." }, - "maxRetries": { "index": 22, "kind": "parameter", "displayName": "Max Retries", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 2, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of times the OpenAI SDK client retries failed requests. The SDK retry is rate-limit aware (honors Retry-After on 429)." }, - "maxTokens": { "index": 23, "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" }, - "maxToolIterations": { "index": 24, "kind": "parameter", "displayName": "Max Tool Iterations", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 50, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of tool call loop iterations to prevent infinite loops" }, - "mcpProtocolVersions": { "index": 25, "kind": "parameter", "displayName": "Mcp Protocol Versions", "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": "Comma-separated list of MCP protocol versions to advertise when connecting to MCP servers using Streamable HTTP transport. When not set, the SDK default is used. Example: 2024-11-05,2025-03-26,2025-06-18" }, - "mcpReconnect": { "index": 26, "kind": "parameter", "displayName": "Mcp Reconnect", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Automatically reconnect to MCP servers when a tool call fails due to a transport error, and retry the call once." }, - "mcpServer": { "index": 27, "kind": "parameter", "displayName": "Mcp Server", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "java.util.Map", "prefix": "mcpServer.", "multiValue": true, "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "MCP (Model Context Protocol) server configurations. Define servers using prefix notation: mcpServer..transportType=stdiossestreamableHttp, (Note that sse is deprecated) mcpServer..command= (stdio), mcpServer..args= (stdio), mcpServer..url= (sse\/streamableHttp), mcpServer..oauthProfile= (OAuth profile for HTTP auth, requires camel-oauth). This is a multi-value option with prefix: mcpServer." }, - "mcpTimeout": { "index": 28, "kind": "parameter", "displayName": "Mcp Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 20, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Timeout in seconds for MCP tool call requests. Applies to all MCP operations including tool execution and initialization." }, - "model": { "index": 29, "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": 30, "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" }, - "requestTimeout": { "index": 31, "kind": "parameter", "displayName": "Request Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "HTTP request timeout in milliseconds for the OpenAI SDK client. When 0 or negative, the SDK default (10 minutes) is used." }, - "speechInstructions": { "index": 32, "kind": "parameter", "displayName": "Speech Instructions", "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": "Optional instructions to control the voice of the generated audio. Does not work with tts-1 or tts-1-hd." }, - "speechModel": { "index": 33, "kind": "parameter", "displayName": "Speech 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 text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)" }, - "speechResponseFormat": { "index": 34, "kind": "parameter", "displayName": "Speech Response Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "mp3", "opus", "aac", "flac", "wav", "pcm" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "mp3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The audio format for text-to-speech output" }, - "speechSpeed": { "index": 35, "kind": "parameter", "displayName": "Speech Speed", "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": "The speed of the generated audio, from 0.25 to 4.0 where 1.0 is normal speed" }, - "speechVoice": { "index": 36, "kind": "parameter", "displayName": "Speech Voice", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "alloy", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The voice to use for text-to-speech (e.g., alloy, echo, fable, onyx, nova, shimmer). See the OpenAI documentation for the full list of supported voices." }, - "storeFullResponse": { "index": 37, "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 'CamelOpenAIResponse' in non-streaming mode" }, - "streaming": { "index": 38, "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" }, - "stripThinking": { "index": 39, "kind": "parameter", "displayName": "Strip Thinking", "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": "Strip ... blocks from model responses (used by reasoning models like Qwen3, DeepSeek-R1). The thinking content is stored in the CamelOpenAIThinkingContent header." }, - "systemMessage": { "index": 40, "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 conversation history is reset." }, - "temperature": { "index": 41, "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": 42, "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": 43, "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": 44, "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 producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing." }, - "oauthProfile": { "index": 45, "kind": "parameter", "displayName": "Oauth Profile", "group": "security", "label": "security", "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": "OAuth profile name for obtaining an access token via the OAuth 2.0 Client Credentials grant. When set, the token is acquired from the configured identity provider and used instead of apiKey. Requires camel-oauth on the classpath. The profile properties are resolved from camel.oauth..client-id, camel.oauth..client-secret, and camel.oauth..token-endpoint." }, - "sslContextParameters": { "index": 46, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "SSLContextParameters to use for configuring SSL\/TLS. When set, takes precedence over the individual sslTruststore, sslKeystore, and sslProtocol options." }, - "sslEndpointAlgorithm": { "index": 47, "kind": "parameter", "displayName": "Ssl Endpoint Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "security": "insecure:ssl", "insecureValue": "none", "defaultValue": "https", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The endpoint identification algorithm to validate the server hostname using the server certificate. Set to an empty string or 'none' to disable hostname verification" }, - "sslKeymanagerAlgorithm": { "index": 48, "kind": "parameter", "displayName": "Ssl Keymanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "SunX509", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the key manager factory for SSL connections" }, - "sslKeyPassword": { "index": 49, "kind": "parameter", "displayName": "Ssl Key Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password of the private key in the key store file" }, - "sslKeystoreLocation": { "index": 50, "kind": "parameter", "displayName": "Ssl Keystore Location", "group": "security", "label": "security", "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 location of the key store file. This is optional and can be used for two-way authentication for the OpenAI API" }, - "sslKeystorePassword": { "index": 51, "kind": "parameter", "displayName": "Ssl Keystore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The store password for the key store file" }, - "sslKeystoreType": { "index": 52, "kind": "parameter", "displayName": "Ssl Keystore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the key store file" }, - "sslProtocol": { "index": 53, "kind": "parameter", "displayName": "Ssl Protocol", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "TLSv1.3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The SSL protocol used to generate the SSLContext" }, - "sslTrustmanagerAlgorithm": { "index": 54, "kind": "parameter", "displayName": "Ssl Trustmanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "PKIX", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the trust manager factory for SSL connections" }, - "sslTruststoreLocation": { "index": 55, "kind": "parameter", "displayName": "Ssl Truststore Location", "group": "security", "label": "security", "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 location of the trust store file, used to validate the server's certificate" }, - "sslTruststorePassword": { "index": 56, "kind": "parameter", "displayName": "Ssl Truststore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password for the trust store file. If a password is not set, the configured trust store can still be used, but integrity checking is disabled" }, - "sslTruststoreType": { "index": 57, "kind": "parameter", "displayName": "Ssl Truststore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the trust store file" } + "maxAgenticTokens": { "index": 20, "kind": "parameter", "displayName": "Max Agentic Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum cumulative prompt plus completion tokens allowed across the MCP agentic loop. When 0 or negative, no token budget is enforced. Enforcement runs after each API call that requests further tool execution, so actual spend may exceed the configured budget by up to one call (typically the largest, as the prompt grows each iteration). A final text response is returned even when cumulative usage exceeds the budget." }, + "maxHistoryMessages": { "index": 21, "kind": "parameter", "displayName": "Max History Messages", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, retain at most this many messages in the exchange conversation history. System and developer messages are prepended separately and are not stored in history. Assistant tool-call blocks are kept intact and may retain slightly more than this limit to preserve tool result pairing. When 0, no message limit is applied." }, + "maxHistoryTokens": { "index": 22, "kind": "parameter", "displayName": "Max History Tokens", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "When conversationMemory is enabled, trim conversation history using a token estimate (character count \/ 4, including image payload size for multi-modal user messages). Oldest segments are dropped first until the estimated tokens are within this limit. Assistant tool-call blocks are removed as a unit with their tool results. The most recent segment is always retained, even when it alone exceeds this limit. When 0, no token limit is applied." }, + "maxRetries": { "index": 23, "kind": "parameter", "displayName": "Max Retries", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 2, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of times the OpenAI SDK client retries failed requests. The SDK retry is rate-limit aware (honors Retry-After on 429)." }, + "maxTokens": { "index": 24, "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" }, + "maxToolIterations": { "index": 25, "kind": "parameter", "displayName": "Max Tool Iterations", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 50, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Maximum number of tool call loop iterations to prevent infinite loops" }, + "mcpProtocolVersions": { "index": 26, "kind": "parameter", "displayName": "Mcp Protocol Versions", "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": "Comma-separated list of MCP protocol versions to advertise when connecting to MCP servers using Streamable HTTP transport. When not set, the SDK default is used. Example: 2024-11-05,2025-03-26,2025-06-18" }, + "mcpReconnect": { "index": 27, "kind": "parameter", "displayName": "Mcp Reconnect", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Automatically reconnect to MCP servers when a tool call fails due to a transport error, and retry the call once." }, + "mcpServer": { "index": 28, "kind": "parameter", "displayName": "Mcp Server", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "java.util.Map", "prefix": "mcpServer.", "multiValue": true, "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "MCP (Model Context Protocol) server configurations. Define servers using prefix notation: mcpServer..transportType=stdiossestreamableHttp, (Note that sse is deprecated) mcpServer..command= (stdio), mcpServer..args= (stdio), mcpServer..url= (sse\/streamableHttp), mcpServer..oauthProfile= (OAuth profile for HTTP auth, requires camel-oauth). This is a multi-value option with prefix: mcpServer." }, + "mcpTimeout": { "index": 29, "kind": "parameter", "displayName": "Mcp Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 20, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "Timeout in seconds for MCP tool call requests. Applies to all MCP operations including tool execution and initialization." }, + "model": { "index": 30, "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": 31, "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" }, + "requestTimeout": { "index": 32, "kind": "parameter", "displayName": "Request Timeout", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "HTTP request timeout in milliseconds for the OpenAI SDK client. When 0 or negative, the SDK default (10 minutes) is used." }, + "speechInstructions": { "index": 33, "kind": "parameter", "displayName": "Speech Instructions", "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": "Optional instructions to control the voice of the generated audio. Does not work with tts-1 or tts-1-hd." }, + "speechModel": { "index": 34, "kind": "parameter", "displayName": "Speech 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 text-to-speech (e.g., gpt-4o-mini-tts, tts-1, tts-1-hd)" }, + "speechResponseFormat": { "index": 35, "kind": "parameter", "displayName": "Speech Response Format", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "mp3", "opus", "aac", "flac", "wav", "pcm" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "mp3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The audio format for text-to-speech output" }, + "speechSpeed": { "index": 36, "kind": "parameter", "displayName": "Speech Speed", "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": "The speed of the generated audio, from 0.25 to 4.0 where 1.0 is normal speed" }, + "speechVoice": { "index": 37, "kind": "parameter", "displayName": "Speech Voice", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "alloy", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The voice to use for text-to-speech (e.g., alloy, echo, fable, onyx, nova, shimmer). See the OpenAI documentation for the full list of supported voices." }, + "storeFullResponse": { "index": 38, "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 'CamelOpenAIResponse' in non-streaming mode" }, + "streaming": { "index": 39, "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" }, + "stripThinking": { "index": 40, "kind": "parameter", "displayName": "Strip Thinking", "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": "Strip ... blocks from model responses (used by reasoning models like Qwen3, DeepSeek-R1). The thinking content is stored in the CamelOpenAIThinkingContent header." }, + "systemMessage": { "index": 41, "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 conversation history is reset." }, + "temperature": { "index": 42, "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": 43, "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": 44, "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": 45, "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 producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and starting the producer may take a little time and prolong the total processing time of the processing." }, + "oauthProfile": { "index": 46, "kind": "parameter", "displayName": "Oauth Profile", "group": "security", "label": "security", "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": "OAuth profile name for obtaining an access token via the OAuth 2.0 Client Credentials grant. When set, the token is acquired from the configured identity provider and used instead of apiKey. Requires camel-oauth on the classpath. The profile properties are resolved from camel.oauth..client-id, camel.oauth..client-secret, and camel.oauth..token-endpoint." }, + "sslContextParameters": { "index": 47, "kind": "parameter", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "SSLContextParameters to use for configuring SSL\/TLS. When set, takes precedence over the individual sslTruststore, sslKeystore, and sslProtocol options." }, + "sslEndpointAlgorithm": { "index": 48, "kind": "parameter", "displayName": "Ssl Endpoint Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "security": "insecure:ssl", "insecureValue": "none", "defaultValue": "https", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The endpoint identification algorithm to validate the server hostname using the server certificate. Set to an empty string or 'none' to disable hostname verification" }, + "sslKeymanagerAlgorithm": { "index": 49, "kind": "parameter", "displayName": "Ssl Keymanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "SunX509", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the key manager factory for SSL connections" }, + "sslKeyPassword": { "index": 50, "kind": "parameter", "displayName": "Ssl Key Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password of the private key in the key store file" }, + "sslKeystoreLocation": { "index": 51, "kind": "parameter", "displayName": "Ssl Keystore Location", "group": "security", "label": "security", "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 location of the key store file. This is optional and can be used for two-way authentication for the OpenAI API" }, + "sslKeystorePassword": { "index": 52, "kind": "parameter", "displayName": "Ssl Keystore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The store password for the key store file" }, + "sslKeystoreType": { "index": 53, "kind": "parameter", "displayName": "Ssl Keystore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the key store file" }, + "sslProtocol": { "index": 54, "kind": "parameter", "displayName": "Ssl Protocol", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "TLSv1.3", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The SSL protocol used to generate the SSLContext" }, + "sslTrustmanagerAlgorithm": { "index": 55, "kind": "parameter", "displayName": "Ssl Trustmanager Algorithm", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "PKIX", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The algorithm used by the trust manager factory for SSL connections" }, + "sslTruststoreLocation": { "index": 56, "kind": "parameter", "displayName": "Ssl Truststore Location", "group": "security", "label": "security", "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 location of the trust store file, used to validate the server's certificate" }, + "sslTruststorePassword": { "index": 57, "kind": "parameter", "displayName": "Ssl Truststore Password", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": true, "security": "secret", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The password for the trust store file. If a password is not set, the configured trust store can still be used, but integrity checking is disabled" }, + "sslTruststoreType": { "index": 58, "kind": "parameter", "displayName": "Ssl Truststore Type", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "JKS", "configurationClass": "org.apache.camel.component.openai.OpenAIConfiguration", "configurationField": "configuration", "description": "The file format of the trust store file" } } } diff --git a/components/camel-ai/camel-openai/src/main/docs/openai-mcp.adoc b/components/camel-ai/camel-openai/src/main/docs/openai-mcp.adoc index c5ee338255da0..866621a92f51b 100644 --- a/components/camel-ai/camel-openai/src/main/docs/openai-mcp.adoc +++ b/components/camel-ai/camel-openai/src/main/docs/openai-mcp.adoc @@ -187,6 +187,14 @@ When the model responds with tool calls, the component automatically: The `maxToolIterations` option (default: 50) prevents infinite loops. If exceeded, an `IllegalStateException` is thrown. +The `maxAgenticTokens` option (default: `0`, unlimited) caps cumulative prompt plus completion tokens across the agentic loop. +When the budget is exceeded after an API call that requests further tool execution, an `IllegalStateException` is thrown and no additional API calls are made. +Enforcement is post-call, so actual spend may exceed the configured budget by up to one API call. +A final text response is still returned when cumulative usage exceeds the budget, because no further spend occurs after that point. + +During the agentic loop, `CamelOpenAIAgenticPromptTokens`, `CamelOpenAIAgenticCompletionTokens`, and `CamelOpenAIAgenticTotalTokens` expose cumulative usage across all iterations. +The per-call headers `CamelOpenAIPromptTokens`, `CamelOpenAICompletionTokens`, and `CamelOpenAITotalTokens` reflect only the latest API call. + Set `autoToolExecution=false` to disable the agentic loop and receive raw tool calls in the message body instead: [tabs] diff --git a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIAgenticTokenTracker.java b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIAgenticTokenTracker.java new file mode 100644 index 0000000000000..9103fe1b603ef --- /dev/null +++ b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIAgenticTokenTracker.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.openai; + +import com.openai.models.chat.completions.ChatCompletion; +import com.openai.models.completions.CompletionUsage; + +/** + * Tracks cumulative token usage across the MCP agentic loop. + */ +final class OpenAIAgenticTokenTracker { + + private long promptTokens; + private long completionTokens; + + void addUsage(ChatCompletion response) { + if (response == null) { + return; + } + response.usage().ifPresent(this::addUsage); + } + + void addUsage(CompletionUsage usage) { + promptTokens += usage.promptTokens(); + completionTokens += usage.completionTokens(); + } + + long getPromptTokens() { + return promptTokens; + } + + long getCompletionTokens() { + return completionTokens; + } + + long getTotalTokens() { + return promptTokens + completionTokens; + } +} 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 81c0824f39c0c..383059fd9d623 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 @@ -161,6 +161,14 @@ public class OpenAIConfiguration implements Cloneable { @Metadata(description = "Maximum number of tool call loop iterations to prevent infinite loops") private int maxToolIterations = 50; + @UriParam(defaultValue = "0") + @Metadata(description = "Maximum cumulative prompt plus completion tokens allowed across the MCP agentic loop. " + + "When 0 or negative, no token budget is enforced. Enforcement runs after each API call " + + "that requests further tool execution, so actual spend may exceed the configured budget " + + "by up to one call (typically the largest, as the prompt grows each iteration). " + + "A final text response is returned even when cumulative usage exceeds the budget.") + private long maxAgenticTokens; + @UriParam(defaultValue = "true") @Metadata(description = "When true and MCP servers are configured, automatically execute tool calls " + "and loop back to the model. When false, tool calls are returned as the message body for manual handling.") @@ -622,6 +630,14 @@ public void setMaxToolIterations(int maxToolIterations) { this.maxToolIterations = maxToolIterations; } + public long getMaxAgenticTokens() { + return maxAgenticTokens; + } + + public void setMaxAgenticTokens(long maxAgenticTokens) { + this.maxAgenticTokens = maxAgenticTokens; + } + public boolean isAutoToolExecution() { return autoToolExecution; } diff --git a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConstants.java b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConstants.java index e7924e6c55679..0e4edf922d73a 100644 --- a/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConstants.java +++ b/components/camel-ai/camel-openai/src/main/java/org/apache/camel/component/openai/OpenAIConstants.java @@ -68,11 +68,12 @@ public final class OpenAIConstants { public static final String RESPONSE_ID = "CamelOpenAIResponseId"; @Metadata(description = "The reason the completion finished (e.g., stop, length, content_filter)", javaType = "String") public static final String FINISH_REASON = "CamelOpenAIFinishReason"; - @Metadata(description = "The number of tokens used in the prompt", javaType = "Integer") + @Metadata(description = "The number of tokens used in the prompt for the latest API call", javaType = "Long") public static final String PROMPT_TOKENS = "CamelOpenAIPromptTokens"; - @Metadata(description = "The number of tokens used in the completion", javaType = "Integer") + @Metadata(description = "The number of tokens used in the completion for the latest API call", javaType = "Long") public static final String COMPLETION_TOKENS = "CamelOpenAICompletionTokens"; - @Metadata(description = "The total number of tokens used (prompt + completion)", javaType = "Integer") + @Metadata(description = "The total number of tokens used (prompt + completion) for the latest API call", + javaType = "Long") public static final String TOTAL_TOKENS = "CamelOpenAITotalTokens"; // MCP Tool Call Headers @@ -84,6 +85,12 @@ public final class OpenAIConstants { + "rather than from the LLM", javaType = "Boolean") public static final String MCP_RETURN_DIRECT = "CamelOpenAIMcpReturnDirect"; + @Metadata(description = "Cumulative prompt tokens consumed across all agentic loop iterations", javaType = "Long") + public static final String AGENTIC_PROMPT_TOKENS = "CamelOpenAIAgenticPromptTokens"; + @Metadata(description = "Cumulative completion tokens consumed across all agentic loop iterations", javaType = "Long") + public static final String AGENTIC_COMPLETION_TOKENS = "CamelOpenAIAgenticCompletionTokens"; + @Metadata(description = "Cumulative total tokens consumed across all agentic loop iterations", javaType = "Long") + public static final String AGENTIC_TOTAL_TOKENS = "CamelOpenAIAgenticTotalTokens"; // Output Exchange Properties @Metadata(description = "The complete OpenAI response object", javaType = "com.openai.models.ChatCompletion") 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 a9493c2d50dc9..282e9b0223111 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 @@ -486,10 +486,14 @@ private void processNonStreamingAgentic( List agenticMessages = new ArrayList<>(); List toolCallsLog = new ArrayList<>(); + OpenAIAgenticTokenTracker tokenTracker = new OpenAIAgenticTokenTracker(); int iteration = 0; while (iteration < maxIterations) { ChatCompletion response = getEndpoint().getClient().chat().completions().create(paramsBuilder.build()); + tokenTracker.addUsage(response); + setAgenticTokenHeaders(exchange.getMessage(), tokenTracker); + ChatCompletion.Choice choice = requireFirstChoice(exchange, response); if (!isToolCallsFinishReason(choice)) { @@ -512,6 +516,8 @@ private void processNonStreamingAgentic( return; } + enforceAgenticTokenBudget(config, tokenTracker, iteration); + iteration++; LOG.debug("Iteration {}: model requested {} tool call(s)", iteration, choice.message().toolCalls().map(List::size).orElse(0)); @@ -611,6 +617,24 @@ private void processNonStreamingAgentic( "Max tool iterations (%d) exceeded. Tools called: %s".formatted(maxIterations, toolCallsLog)); } + private void setAgenticTokenHeaders(Message message, OpenAIAgenticTokenTracker tokenTracker) { + message.setHeader(OpenAIConstants.AGENTIC_PROMPT_TOKENS, tokenTracker.getPromptTokens()); + message.setHeader(OpenAIConstants.AGENTIC_COMPLETION_TOKENS, tokenTracker.getCompletionTokens()); + message.setHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, tokenTracker.getTotalTokens()); + } + + private void enforceAgenticTokenBudget( + OpenAIConfiguration config, OpenAIAgenticTokenTracker tokenTracker, int iteration) { + long maxAgenticTokens = config.getMaxAgenticTokens(); + if (maxAgenticTokens <= 0 || tokenTracker.getTotalTokens() <= maxAgenticTokens) { + return; + } + throw new IllegalStateException( + "Max agentic tokens (%d) exceeded at iteration %d. Cumulative usage: prompt=%d, completion=%d, total=%d" + .formatted(maxAgenticTokens, iteration, tokenTracker.getPromptTokens(), + tokenTracker.getCompletionTokens(), tokenTracker.getTotalTokens())); + } + private String extractTextContent(List contents) { if (contents == null || contents.isEmpty()) { return ""; diff --git a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenBudgetTest.java b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenBudgetTest.java new file mode 100644 index 0000000000000..b0d33131d416a --- /dev/null +++ b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenBudgetTest.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.openai; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.modelcontextprotocol.client.McpSyncClient; +import io.modelcontextprotocol.spec.McpSchema; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.test.infra.openai.mock.OpenAIMock; +import org.apache.camel.test.junit6.CamelTestSupport; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class OpenAIAgenticTokenBudgetTest extends CamelTestSupport { + + @RegisterExtension + public OpenAIMock tokenMock = new OpenAIMock().builder() + .when("call one tool") + .invokeTool("get_weather") + .withParam("city", "London") + .replyWith("The weather in London is sunny.") + .end() + .when("expensive tool call") + .withUsage(70, 50) + .invokeTool("get_weather") + .withParam("city", "Paris") + .replyWith("Should not reach this response") + .end() + .when("expensive direct answer") + .withUsage(70, 50) + .replyWith("Direct answer over budget") + .end() + .when("at budget boundary") + .withUsage(60, 40) + .invokeTool("get_weather") + .withParam("city", "London") + .replyWith("The weather in London is sunny.") + .end() + .when("accumulate over budget") + .withUsage(40, 10) + .invokeTool("get_weather") + .withParam("city", "A") + .andThenInvokeTool("get_weather") + .withParam("city", "B") + .replyWith("Should not reach this response") + .end() + .build(); + + @Override + protected RouteBuilder createRouteBuilder() { + String base = tokenMock.getBaseUrl() + "/v1"; + return new RouteBuilder() { + @Override + public void configure() { + from("direct:agentic-tokens") + .to("openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true&baseUrl=" + base); + + from("direct:agentic-token-budget") + .to("openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=100&maxToolIterations=5&baseUrl=" + base); + + from("direct:agentic-token-budget-boundary") + .to("openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=100&maxToolIterations=5&baseUrl=" + base); + + from("direct:agentic-token-budget-multi") + .to("openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=80&maxToolIterations=5&baseUrl=" + base); + } + }; + } + + @Test + void agenticLoopShouldExposeCumulativeTokenHeaders() { + String endpointUri = "openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true&baseUrl=" + + tokenMock.getBaseUrl() + "/v1"; + injectMcpTools(endpointUri, createWeatherToolClients()); + + Exchange result = template.request("direct:agentic-tokens", e -> e.getIn().setBody("call one tool")); + + assertThat(result.getException()).isNull(); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_PROMPT_TOKENS, Long.class)).isEqualTo(20L); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_COMPLETION_TOKENS, Long.class)).isEqualTo(10L); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, Long.class)).isEqualTo(30L); + } + + @Test + void maxAgenticTokensShouldStopLoopWithDescriptiveException() { + String endpointUri = "openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=100&maxToolIterations=5&baseUrl=" + + tokenMock.getBaseUrl() + "/v1"; + injectMcpTools(endpointUri, createWeatherToolClients()); + + Exchange result = template.request("direct:agentic-token-budget", e -> e.getIn().setBody("expensive tool call")); + + assertThat(result.getException()).isNotNull(); + assertThat(result.getException()).isInstanceOf(IllegalStateException.class); + assertThat(result.getException().getMessage()) + .contains("Max agentic tokens (100) exceeded at iteration 0") + .contains("prompt=70") + .contains("completion=50") + .contains("total=120"); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, Long.class)).isEqualTo(120L); + } + + @Test + void finalAnswerOverBudgetShouldStillReturnResponse() { + String endpointUri = "openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=100&maxToolIterations=5&baseUrl=" + + tokenMock.getBaseUrl() + "/v1"; + injectMcpTools(endpointUri, createWeatherToolClients()); + + Exchange result = template.request("direct:agentic-token-budget", + e -> e.getIn().setBody("expensive direct answer")); + + assertThat(result.getException()).isNull(); + assertThat(result.getMessage().getBody(String.class)).isEqualTo("Direct answer over budget"); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, Long.class)).isEqualTo(120L); + } + + @Test + void maxAgenticTokensAtExactBoundaryShouldAllowLoopToContinue() { + String endpointUri = "openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=100&maxToolIterations=5&baseUrl=" + + tokenMock.getBaseUrl() + "/v1"; + injectMcpTools(endpointUri, createWeatherToolClients()); + + Exchange result = template.request("direct:agentic-token-budget-boundary", + e -> e.getIn().setBody("at budget boundary")); + + assertThat(result.getException()).isNull(); + assertThat(result.getMessage().getBody(String.class)).isEqualTo("The weather in London is sunny."); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, Long.class)).isEqualTo(200L); + } + + @Test + void maxAgenticTokensShouldStopAfterMultipleIterations() { + String endpointUri = "openai:chat-completion?model=gpt-5&apiKey=dummy&autoToolExecution=true" + + "&maxAgenticTokens=80&maxToolIterations=5&baseUrl=" + + tokenMock.getBaseUrl() + "/v1"; + McpSyncClient weatherClient = createMockMcpClient("Sunny, 22°C"); + Map toolClients = Map.of("get_weather", weatherClient); + injectMcpTools(endpointUri, toolClients); + + Exchange result = template.request("direct:agentic-token-budget-multi", + e -> e.getIn().setBody("accumulate over budget")); + + assertThat(result.getException()).isNotNull(); + assertThat(result.getException()).isInstanceOf(IllegalStateException.class); + assertThat(result.getException().getMessage()) + .contains("Max agentic tokens (80) exceeded at iteration 1") + .contains("total=100"); + assertThat(result.getMessage().getHeader(OpenAIConstants.AGENTIC_TOTAL_TOKENS, Long.class)).isEqualTo(100L); + verify(weatherClient, times(1)).callTool(any(McpSchema.CallToolRequest.class)); + } + + private Map createWeatherToolClients() { + Map toolClients = new HashMap<>(); + toolClients.put("get_weather", createMockMcpClient("Sunny, 22°C")); + return toolClients; + } + + private McpSyncClient createMockMcpClient(String resultText) { + McpSyncClient client = mock(McpSyncClient.class); + McpSchema.CallToolResult result = McpSchema.CallToolResult.builder() + .content(List.of(new McpSchema.TextContent(null, resultText, null))) + .isError(false) + .build(); + when(client.callTool(any(McpSchema.CallToolRequest.class))).thenReturn(result); + return client; + } + + private void injectMcpTools(String endpointKey, Map toolClients) { + OpenAIEndpoint endpoint = context.getEndpoint(endpointKey, OpenAIEndpoint.class); + List mcpTools = toolClients.keySet().stream() + .map(name -> McpSchema.Tool.builder(name, Map.of("type", "object")) + .description("Mock tool: " + name) + .build()) + .toList(); + endpoint.setMcpToolState(new McpToolState( + McpToolConverter.convert(mcpTools), + toolClients, + Map.of(), + Set.of())); + } +} diff --git a/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenTrackerTest.java b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenTrackerTest.java new file mode 100644 index 0000000000000..f22e6754e5451 --- /dev/null +++ b/components/camel-ai/camel-openai/src/test/java/org/apache/camel/component/openai/OpenAIAgenticTokenTrackerTest.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.openai; + +import com.openai.models.completions.CompletionUsage; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class OpenAIAgenticTokenTrackerTest { + + @Test + void shouldAccumulatePromptAndCompletionTokens() { + OpenAIAgenticTokenTracker tracker = new OpenAIAgenticTokenTracker(); + + tracker.addUsage(CompletionUsage.builder() + .promptTokens(30) + .completionTokens(20) + .totalTokens(50) + .build()); + tracker.addUsage(CompletionUsage.builder() + .promptTokens(10) + .completionTokens(5) + .totalTokens(15) + .build()); + + assertThat(tracker.getPromptTokens()).isEqualTo(40); + assertThat(tracker.getCompletionTokens()).isEqualTo(25); + assertThat(tracker.getTotalTokens()).isEqualTo(65); + } +} diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc index 5737bcc898a82..d230f8fb3c402 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc @@ -197,6 +197,11 @@ Previously the option was accepted on the endpoint but ignored, so `safeSearch=f === camel-openai +The per-call token usage headers `CamelOpenAIPromptTokens`, `CamelOpenAICompletionTokens`, and +`CamelOpenAITotalTokens` now declare `javaType = Long` in component metadata (previously `Integer`). +The OpenAI SDK returns `long` values, so routes that read these headers with `Integer.class` should +switch to `Long.class`. + The `conversationMemory` feature on the `chat-completion` operation has two behavior fixes: * User messages are now stored in the `CamelOpenAIConversationHistory` exchange property (configurable via diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenAIEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenAIEndpointBuilderFactory.java index 7b20deb6f9661..39e084b363744 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenAIEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/OpenAIEndpointBuilderFactory.java @@ -481,6 +481,48 @@ default OpenAIEndpointBuilder jsonSchema(String jsonSchema) { doSetProperty("jsonSchema", jsonSchema); return this; } + /** + * Maximum cumulative prompt plus completion tokens allowed across the + * MCP agentic loop. When 0 or negative, no token budget is enforced. + * Enforcement runs after each API call that requests further tool + * execution, so actual spend may exceed the configured budget by up to + * one call (typically the largest, as the prompt grows each iteration). + * A final text response is returned even when cumulative usage exceeds + * the budget. + * + * The option is a: long type. + * + * Default: 0 + * Group: producer + * + * @param maxAgenticTokens the value to set + * @return the dsl builder + */ + default OpenAIEndpointBuilder maxAgenticTokens(long maxAgenticTokens) { + doSetProperty("maxAgenticTokens", maxAgenticTokens); + return this; + } + /** + * Maximum cumulative prompt plus completion tokens allowed across the + * MCP agentic loop. When 0 or negative, no token budget is enforced. + * Enforcement runs after each API call that requests further tool + * execution, so actual spend may exceed the configured budget by up to + * one call (typically the largest, as the prompt grows each iteration). + * A final text response is returned even when cumulative usage exceeds + * the budget. + * + * The option will be converted to a long type. + * + * Default: 0 + * Group: producer + * + * @param maxAgenticTokens the value to set + * @return the dsl builder + */ + default OpenAIEndpointBuilder maxAgenticTokens(String maxAgenticTokens) { + doSetProperty("maxAgenticTokens", maxAgenticTokens); + return this; + } /** * When conversationMemory is enabled, retain at most this many messages * in the exchange conversation history. System and developer messages @@ -1695,9 +1737,9 @@ public String openAIFinishReason() { return "CamelOpenAIFinishReason"; } /** - * The number of tokens used in the prompt. + * The number of tokens used in the prompt for the latest API call. * - * The option is a: {@code Integer} type. + * The option is a: {@code Long} type. * * Group: producer * @@ -1707,9 +1749,9 @@ public String openAIPromptTokens() { return "CamelOpenAIPromptTokens"; } /** - * The number of tokens used in the completion. + * The number of tokens used in the completion for the latest API call. * - * The option is a: {@code Integer} type. + * The option is a: {@code Long} type. * * Group: producer * @@ -1719,9 +1761,10 @@ public String openAICompletionTokens() { return "CamelOpenAICompletionTokens"; } /** - * The total number of tokens used (prompt completion). + * The total number of tokens used (prompt completion) for the latest + * API call. * - * The option is a: {@code Integer} type. + * The option is a: {@code Long} type. * * Group: producer * @@ -1767,6 +1810,43 @@ public String openAIMcpToolCalls() { public String openAIMcpReturnDirect() { return "CamelOpenAIMcpReturnDirect"; } + /** + * Cumulative prompt tokens consumed across all agentic loop iterations. + * + * The option is a: {@code Long} type. + * + * Group: producer + * + * @return the name of the header {@code OpenAIAgenticPromptTokens}. + */ + public String openAIAgenticPromptTokens() { + return "CamelOpenAIAgenticPromptTokens"; + } + /** + * Cumulative completion tokens consumed across all agentic loop + * iterations. + * + * The option is a: {@code Long} type. + * + * Group: producer + * + * @return the name of the header {@code OpenAIAgenticCompletionTokens}. + */ + public String openAIAgenticCompletionTokens() { + return "CamelOpenAIAgenticCompletionTokens"; + } + /** + * Cumulative total tokens consumed across all agentic loop iterations. + * + * The option is a: {@code Long} type. + * + * Group: producer + * + * @return the name of the header {@code OpenAIAgenticTotalTokens}. + */ + public String openAIAgenticTotalTokens() { + return "CamelOpenAIAgenticTotalTokens"; + } /** * The complete OpenAI response object. * diff --git a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/MockExpectation.java b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/MockExpectation.java index dabb78bf2a0e7..e6d2246cae299 100644 --- a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/MockExpectation.java +++ b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/MockExpectation.java @@ -33,6 +33,8 @@ public class MockExpectation { private String toolContentResponse; private BiFunction customResponseFunction; private Consumer requestAssertion; + private Integer usagePromptTokens; + private Integer usageCompletionTokens; public MockExpectation(String expectedInput) { this.expectedInput = expectedInput; @@ -89,6 +91,19 @@ public void setToolContentResponse(String toolContentResponse) { this.toolContentResponse = toolContentResponse; } + public void setUsage(int promptTokens, int completionTokens) { + this.usagePromptTokens = promptTokens; + this.usageCompletionTokens = completionTokens; + } + + public Integer getUsagePromptTokens() { + return usagePromptTokens; + } + + public Integer getUsageCompletionTokens() { + return usageCompletionTokens; + } + // Tool sequence delegation methods public void addToolExecutionStep(ToolExecutionStep step) { toolSequence.addStep(step); diff --git a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/OpenAIMockBuilder.java b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/OpenAIMockBuilder.java index 5fb1844b1c618..471d380db3ee4 100644 --- a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/OpenAIMockBuilder.java +++ b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/OpenAIMockBuilder.java @@ -105,6 +105,12 @@ public OpenAIMockBuilder andInvokeTool(String toolName) { return this; } + public OpenAIMockBuilder withUsage(int promptTokens, int completionTokens) { + validateCurrentExpectation("withUsage()"); + currentExpectation.setUsage(promptTokens, completionTokens); + return this; + } + public OpenAIMockBuilder withParam(String key, Object value) { validateCurrentExpectation("withParam()"); validateHasToolSteps("withParam()"); diff --git a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/RequestHandler.java b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/RequestHandler.java index b6f350f280b63..2515dd56cd297 100644 --- a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/RequestHandler.java +++ b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/RequestHandler.java @@ -90,7 +90,8 @@ private String handleToolSequenceResponse(RequestContext context, HttpExchange e } else { LOG.debug("Tool sequence completed for expectation: {}", originalInput); return responseBuilder.createFinalToolResponse(context.getMessagesNode(), expectation.getExpectedResponse(), - expectation.getToolContentResponse(), expectation.getReasoningContent()); + expectation.getToolContentResponse(), expectation.getReasoningContent(), + resolvePromptTokens(expectation), resolveCompletionTokens(expectation)); } } @@ -129,7 +130,10 @@ private String createResponse(MockExpectation expectation, String userInput, Htt default: LOG.debug("Creating simple text response"); return responseBuilder.createSimpleTextResponse( - expectation.getExpectedResponse(), expectation.getReasoningContent()); + expectation.getExpectedResponse(), + expectation.getReasoningContent(), + resolvePromptTokens(expectation), + resolveCompletionTokens(expectation)); } } @@ -137,7 +141,21 @@ private String createToolCallResponse(MockExpectation expectation) throws Except ToolExecutionStep currentStep = expectation.getCurrentToolStep(); return responseBuilder.createToolCallResponse( expectation.getExpectedResponse(), - currentStep.getToolCalls()); + currentStep.getToolCalls(), + resolvePromptTokens(expectation), + resolveCompletionTokens(expectation)); + } + + private int resolvePromptTokens(MockExpectation expectation) { + return expectation.getUsagePromptTokens() != null + ? expectation.getUsagePromptTokens() + : ResponseBuilder.DEFAULT_PROMPT_TOKENS; + } + + private int resolveCompletionTokens(MockExpectation expectation) { + return expectation.getUsageCompletionTokens() != null + ? expectation.getUsageCompletionTokens() + : ResponseBuilder.DEFAULT_COMPLETION_TOKENS; } private MockExpectation findExpectationByInput(String input) { diff --git a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/ResponseBuilder.java b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/ResponseBuilder.java index 8fa7bb7f3658d..10861b1ca8059 100644 --- a/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/ResponseBuilder.java +++ b/test-infra/camel-test-infra-openai-mock/src/main/java/org/apache/camel/test/infra/openai/mock/ResponseBuilder.java @@ -34,6 +34,9 @@ * Builder class for creating different types of OpenAI API mock responses. */ public class ResponseBuilder { + static final int DEFAULT_PROMPT_TOKENS = 10; + static final int DEFAULT_COMPLETION_TOKENS = 5; + private final ObjectMapper objectMapper; public ResponseBuilder(ObjectMapper objectMapper) { @@ -45,6 +48,12 @@ public String createSimpleTextResponse(String content) throws Exception { } public String createSimpleTextResponse(String content, String reasoningContent) throws Exception { + return createSimpleTextResponse(content, reasoningContent, DEFAULT_PROMPT_TOKENS, DEFAULT_COMPLETION_TOKENS); + } + + public String createSimpleTextResponse( + String content, String reasoningContent, int promptTokens, int completionTokens) + throws Exception { Map responseMessage = createBaseMessage(); responseMessage.put("content", content); if (reasoningContent != null) { @@ -52,18 +61,24 @@ public String createSimpleTextResponse(String content, String reasoningContent) } Map choice = createBaseChoice("stop", responseMessage); - Map chatCompletion = createBaseChatCompletion(choice); + Map chatCompletion = createBaseChatCompletion(choice, promptTokens, completionTokens); return objectMapper.writeValueAsString(chatCompletion); } public String createToolCallResponse(String content, List toolCalls) throws Exception { + return createToolCallResponse(content, toolCalls, DEFAULT_PROMPT_TOKENS, DEFAULT_COMPLETION_TOKENS); + } + + public String createToolCallResponse( + String content, List toolCalls, int promptTokens, int completionTokens) + throws Exception { Map responseMessage = createBaseMessage(); responseMessage.put("content", content); responseMessage.put("tool_calls", buildToolCallsList(toolCalls)); Map choice = createBaseChoice("tool_calls", responseMessage); - Map chatCompletion = createBaseChatCompletion(choice); + Map chatCompletion = createBaseChatCompletion(choice, promptTokens, completionTokens); return objectMapper.writeValueAsString(chatCompletion); } @@ -72,6 +87,14 @@ public String createFinalToolResponse( JsonNode messagesNode, String fallbackContent, String toolContentResponse, String reasoningContent) throws Exception { + return createFinalToolResponse(messagesNode, fallbackContent, toolContentResponse, reasoningContent, + DEFAULT_PROMPT_TOKENS, DEFAULT_COMPLETION_TOKENS); + } + + public String createFinalToolResponse( + JsonNode messagesNode, String fallbackContent, String toolContentResponse, + String reasoningContent, int promptTokens, int completionTokens) + throws Exception { Map responseMessage = createBaseMessage(); String content; @@ -89,7 +112,7 @@ public String createFinalToolResponse( } Map choice = createBaseChoice("stop", responseMessage); - Map chatCompletion = createBaseChatCompletion(choice); + Map chatCompletion = createBaseChatCompletion(choice, promptTokens, completionTokens); chatCompletion.put("history", messagesNode); return objectMapper.writeValueAsString(chatCompletion); @@ -127,12 +150,22 @@ private Map createBaseChoice(String finishReason, Map createBaseChatCompletion(Map choice) { + return createBaseChatCompletion(choice, DEFAULT_PROMPT_TOKENS, DEFAULT_COMPLETION_TOKENS); + } + + private Map createBaseChatCompletion( + Map choice, int promptTokens, int completionTokens) { Map chatCompletion = new HashMap<>(); chatCompletion.put("id", UUID.randomUUID().toString()); chatCompletion.put("choices", Collections.singletonList(choice)); chatCompletion.put("created", System.currentTimeMillis() / 1000L); chatCompletion.put("model", "openai-mock"); chatCompletion.put("object", "chat.completion"); + Map usage = new HashMap<>(); + usage.put("prompt_tokens", promptTokens); + usage.put("completion_tokens", completionTokens); + usage.put("total_tokens", promptTokens + completionTokens); + chatCompletion.put("usage", usage); return chatCompletion; }