[
https://issues.apache.org/jira/browse/CAMEL-24977?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Luigi De Masi updated CAMEL-24977:
----------------------------------
Description:
h2. Motivation
Provide a provider-agnostic semantic evaluation API and Camel language so route
authors can ask named questions about message content and use the resulting
boolean decisions, categories, or scores across EIPs. For example, a support
message can be classified as billing, technical, or other; a separate question
can assess urgency or whether the message contains an actionable request.
CAMEL-24871 added the Jev integration. This proposal builds on that work by
separating the common question/evaluation contract from provider-specific
implementations and adding a generic selector-based Choice capability. Jev can
implement the common SPI, and other hosted or local classifiers can implement
it without requiring Jev wire compatibility.
The desired authoring experience is declarative: named questions in the same
YAML file as routes, automatic provider-adapter discovery, and direct use
through Camel's language integration. Route authors should not need to
instantiate a predicate or adapter bean for the normal case.
This is a design proposal. The syntax below illustrates the intended behavior;
public names, packaging and exact DSL/schema details require community review.
It does not claim that the proposed semantic language or selector-based Choice
is already available.
h2. Common semantic evaluation contract
* Define provider-independent question and result types for categorical Choice,
yes/no judgments (including probability-to-boolean decision policy), and
scoring against descriptive ordered levels. Preserve the useful shape of Jev
Choice/Noul/Score through its adapter; final common type names should not force
other providers to adopt Jev terminology.
* Separate the selected category/value, probabilities, provider confidence,
uncertainty policy and operational errors. A probability, a confidence measure
and a guarantee of correctness are not interchangeable. Preserve provider
metadata where useful without requiring all providers to report the same
optional fields.
* A provider component advertises an adapter implementing the common SPI. The
adapter maps questions/state to its backend, validates supported capabilities,
and maps typed results back to the common contract.
* Expose evaluations through Camel's existing {{Language}}, {{Expression}} and
{{Predicate}} contracts. Predicate use requires a boolean decision or explicit
comparison/threshold policy; a category string is not implicitly a predicate.
* Keep provider credentials, model selection, transport/inference
configuration, and provider-specific resources with the implementing component.
Define thread safety, bounded evaluation, cancellation and lifecycle behavior.
Synchronous Predicate/Expression evaluation must document any blocking
inference call.
h2. Named questions and state in YAML
Support a dedicated top-level {{semantic.question}} declaration from the
initial version, alongside route definitions. The following is proposed syntax:
{code}
- semantic:
question:
department:
type: choice
state: ${header.myState}
instructions: Which department should handle this message?
criteria:
billing: Invoices, payments, and refunds
technical: Bugs, outages, and technical problems
other: Everything else
- route:
id: ticket-routing
from:
uri: direct:tickets
steps:
- choice:
selector:
language:
language: semantic
expression: "ref:department"
when:
- value: billing
steps:
- to: direct:billing
- value: technical
steps:
- to: direct:technical
otherwise:
steps:
- to: direct:general
{code}
Each question owns its input-state selector. An optional language default can
be configured:
{code}
camel.language.semantic.default-state=${body}
{code}
Proposed precedence: question {{state}}, then configured {{default-state}},
then built-in {{${body}}}. Use Camel Simple expressions for these selectors
initially. Compile/initialize selectors during route setup and evaluate against
the current exchange at runtime. Only an absent selector inherits the default:
a malformed selector or an explicitly selected header that evaluates to null
must not silently cause different data to be classified. Input values are data,
not recursively evaluated expressions.
Question declarations need loader, validation, schema and tooling support.
Resolve references before traffic where possible; reject duplicate names,
unknown references and unsupported question capabilities. Define behavior
across multiple route resources and reload without retaining obsolete
definitions. Loading/validating declarations must not perform inference.
h2. Adapter discovery and explicit selection
The language must not require a provider endpoint URI such as
{{jev:decisions}}. With exactly one advertised adapter implementation
available, discover and select it automatically. With none, report a missing
provider; with multiple, report the candidates and require explicit selection.
Do not choose by classpath order or construct every provider during discovery.
Allow an explicit reference to an existing registered instance:
{code}
camel.language.semantic.adapter=#bean:mySemanticAdapter
{code}
Alternatively, accept a fully qualified class name:
{code}
camel.language.semantic.adapter=com.example.MySemanticAdapter
{code}
The example class is illustrative. Support Camel's
{{#class:com.example.MySemanticAdapter}} spelling as an equivalent. For a
class-selected or discovered adapter, the semantic infrastructure should
resolve and type-check the class through Camel, instantiate it using the
context Injector, register it once for the language configuration, and
integrate its lifecycle. Reuse referenced beans without duplicating their
existing lifecycle ownership. Define registry ownership, collision handling and
startup-failure cleanup; binding an object does not itself establish service
lifecycle management.
Provider configuration must remain effective even when the route contains no
provider endpoint. For example, a Jev adapter must honor the configured Jev
component's credentials and connection options. A manually declared adapter
bean is an optional customization path, not a prerequisite for normal operation.
h2. Generic selector-based Choice in Camel core
Extend Choice to evaluate one ordinary Camel Expression and match its result
against literal branch values. Core should know only expression evaluation and
value matching; it must have no dependency on semantic questions, Jev, or a
model runtime.
Proposed Java shape, where {{department}} is a Camel Expression resolving the
named semantic question:
{code:java}
from("direct:tickets")
.choice(department)
.when("billing")
.to("direct:billing")
.when("technical")
.to("direct:technical")
.otherwise()
.to("direct:general")
.end();
{code}
The same extension must work with ordinary expressions such as
{{header("department")}}. Existing predicate-based Choice behavior must remain
unchanged.
* Evaluate the selector once per entry into the Choice block, including when
the first branch does not match. Nested choices have independent evaluation
scopes.
* A later loop/retry entry may evaluate again. Do not introduce an indefinite
exchange-wide semantic-result cache.
* Define literal typing/equality, null/unmatched results, duplicate values, and
whether/how selector branches can coexist with predicate branches.
* A successful unmatched value selects {{otherwise}}. Inference or
invalid-response failures follow Camel error handling; uncertainty requires an
explicit policy.
* Define interaction with Choice precondition mode. Message-dependent inference
must not execute against a dummy startup exchange. CAMEL-17755 concerns startup
preconditions and is distinct from this per-message selector proposal.
* Include model, reifier, runtime, Java DSL, YAML/XML serialization and
generated schema/catalog coverage. A language plugin alone cannot add the
proposed Choice API.
h2. Evaluation across other EIPs
The following are candidate uses, not a requirement to introduce
semantic-specific changes to every EIP.
|| EIP || Example benefit || Integration ||
| Validate | Does this bug report describe an actionable problem? | A boolean
decision supplies the validation predicate; negative decisions use normal
validation failure handling. |
| Set Header / Set Property | Attach department, sentiment or urgency to a
message. | Store a category or score for explicit reuse by subsequent
processors. |
| Aggregate: grouping | Group feedback by delivery, pricing or usability. | Use
a category as part of the correlation key, retaining tenant/case boundaries and
bounded aggregation windows where needed. |
| Aggregate: completion | Does the accumulated conversation contain enough
information to proceed? | Evaluate a boolean completion predicate against
selected aggregate state, alongside a size or timeout completion condition. |
| Recipient List | Send a complaint to support and the relevant product team. |
Map a category, or multiple independent decisions, to configured recipients. |
| Routing Slip | Select a document-processing sequence. | Map a document
category to a predefined sequence of endpoints. |
| Enrich | Choose the appropriate knowledge source for a support request. | Map
a topic to a configured enrichment endpoint; ordinary code retrieves and merges
the additional data. |
| Loop | Continue refinement while the updated output remains incomplete. |
Reevaluate a semantic predicate against current state, with an explicit
iteration/time budget. |
| Sort | Order a batch of tickets by assessed urgency. | Score each item once,
then compare stored scores with a deterministic comparator. |
Validate, metadata assignment and Aggregate can consume Predicate/Expression
results directly. Recipient List, Routing Slip and Enrich require a mapping
from semantic labels to route-author-defined destinations. The classifier does
not invent endpoint addresses or processing steps.
For aggregate completion, the aggregation strategy must expose the relevant
accumulated content; the classifier does not implicitly remember earlier
exchanges. The default completion predicate sees the aggregated exchange, while
{{eagerCheckCompletion}} uses the incoming exchange. State selection must match
that behavior.
For Sort, the EIP expression selects the collection and the comparator
determines ordering. Inference belongs before comparison. For loops or changed
input, explicit result reuse must not hide relevant state changes.
h2. Acceptance criteria and initial coverage
# A common provider-independent question/result contract and adapter SPI
support direct semantic Expression/Predicate use without requiring manual
predicate instances.
# A YAML file can declare named questions under {{semantic.question}} and
reference them from routes. Loader, schema, validation and tooling support
agree on the proposed configuration.
# Adapter discovery, bean-reference override and class-name override are
tested, including missing/ambiguous providers, wrong types, instance reuse,
configuration and lifecycle behavior.
# Question state overrides the language default; omitting both uses the body.
Invalid selectors and missing selected state produce useful errors without
silent input substitution.
# Generic selector-based Choice evaluates once per block entry, works with
semantic and non-semantic expressions, preserves existing predicate-based
Choice, and has nested/looped/error-path coverage and documented precondition
behavior.
# Demonstrate Choice, Filter, Validate, Set Property and Aggregate integration.
Document the other candidate EIPs and their mapping/state requirements without
assuming every EIP needs a core change.
# Provide a Jev adapter and validate the contract with deterministic test
adapters, including a second implementation and capability mismatch cases. Do
not claim interchangeability of model quality, probabilities or calibration.
# Tests cover meaningful result mappings, invocation counts,
threshold/uncertainty policy, explicit result reuse, changed-state
reevaluation, timeouts/failures and preservation of message content. Routine
tests require no live model credentials.
# Document the supported property namespaces and runtime configuration paths.
Coordinate with the generic-language starter work in CAMEL-24913 and
CAMEL-24914 rather than assuming language configuration is generated
automatically.
h2. Boundaries and references
Choosing a local inference runtime (pure JVM/WASM versus native inference),
model weights, or a particular hosted service is outside this proposal's
initial decision. A provider can implement Jev API compatibility, but the
common SPI does not require it and does not imply equivalent proprietary model
behavior or calibration. The SPI's final package, discovery metadata and public
syntax remain open to design review.
Related work:
* CAMEL-24871 — Jev component and semantic EIP integration background.
* CAMEL-24913 — Jev Spring Boot starter configuration.
* CAMEL-24914 — Starter generation for languages backed by the generic model.
* CAMEL-17755 — Existing Choice precondition design.
* [Camel Language
SPI|https://github.com/apache/camel/blob/main/core/camel-api/src/main/java/org/apache/camel/spi/Language.java]
* [Choice
model|https://github.com/apache/camel/blob/main/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java]
* [Aggregate
EIP|https://camel.apache.org/components/next/eips/aggregate-eip.html]
* [System One Models|https://systemonemodels.org/]
_AI-generated by Codex on behalf of
[luigidemasi|https://github.com/luigidemasi]._
was:
h2. Motivation
Provide a provider-agnostic semantic evaluation API and Camel language so route
authors can ask named questions about message content and use the resulting
boolean decisions, categories, or scores across EIPs. For example, a support
message can be classified as billing, technical, or other; a separate question
can assess urgency or whether the message contains an actionable request.
CAMEL-24871 added the Jev integration. This proposal builds on that work by
separating the common question/evaluation contract from provider-specific
implementations and adding a generic selector-based Choice capability. Jev can
implement the common SPI, and other hosted or local classifiers can implement
it without requiring Jev wire compatibility.
The desired authoring experience is declarative: named questions in the same
YAML file as routes, automatic provider-adapter discovery, and direct use
through Camel's language integration. Route authors should not need to
instantiate a predicate or adapter bean for the normal case.
This is a design proposal. The syntax below illustrates the intended behavior;
public names, packaging and exact DSL/schema details require community review.
It does not claim that the proposed semantic language or selector-based Choice
is already available.
h2. Common semantic evaluation contract
* Define provider-independent question and result types for categorical Choice,
yes/no judgments (including probability-to-boolean decision policy), and
scoring against descriptive ordered levels. Preserve the useful shape of Jev
Choice/Noul/Score through its adapter; final common type names should not force
other providers to adopt Jev terminology.
* Separate the selected category/value, probabilities, provider confidence,
uncertainty policy and operational errors. A probability, a confidence measure
and a guarantee of correctness are not interchangeable. Preserve provider
metadata where useful without requiring all providers to report the same
optional fields.
* A provider component advertises an adapter implementing the common SPI. The
adapter maps questions/state to its backend, validates supported capabilities,
and maps typed results back to the common contract.
* Expose evaluations through Camel's existing {{Language}}, {{Expression}} and
{{Predicate}} contracts. Predicate use requires a boolean decision or explicit
comparison/threshold policy; a category string is not implicitly a predicate.
* Keep provider credentials, model selection, transport/inference
configuration, and provider-specific resources with the implementing component.
Define thread safety, bounded evaluation, cancellation and lifecycle behavior.
Synchronous Predicate/Expression evaluation must document any blocking
inference call.
h2. Named questions and state in YAML
Support a dedicated top-level {{semantic.question}} declaration from the
initial version, alongside route definitions. The following is proposed syntax:
{code}
- semantic:
question:
department:
type: choice
state: ${header.myState}
instructions: Which department should handle this message?
criteria:
billing: Invoices, payments, and refunds
technical: Bugs, outages, and technical problems
other: Everything else
- route:
id: ticket-routing
from:
uri: direct:tickets
steps:
- choice:
selector:
language:
language: semantic
expression: "ref:department"
when:
- value: billing
steps:
- to: direct:billing
- value: technical
steps:
- to: direct:technical
otherwise:
steps:
- to: direct:general
{code}
Each question owns its input-state selector. An optional language default can
be configured:
{code:properties}
camel.language.semantic.default-state=${body}
{code}
Proposed precedence: question {{state}}, then configured {{default-state}},
then built-in {{${body}}}. Use Camel Simple expressions for these selectors
initially. Compile/initialize selectors during route setup and evaluate against
the current exchange at runtime. Only an absent selector inherits the default:
a malformed selector or an explicitly selected header that evaluates to null
must not silently cause different data to be classified. Input values are data,
not recursively evaluated expressions.
Question declarations need loader, validation, schema and tooling support.
Resolve references before traffic where possible; reject duplicate names,
unknown references and unsupported question capabilities. Define behavior
across multiple route resources and reload without retaining obsolete
definitions. Loading/validating declarations must not perform inference.
h2. Adapter discovery and explicit selection
The language must not require a provider endpoint URI such as
{{jev:decisions}}. With exactly one advertised adapter implementation
available, discover and select it automatically. With none, report a missing
provider; with multiple, report the candidates and require explicit selection.
Do not choose by classpath order or construct every provider during discovery.
Allow an explicit reference to an existing registered instance:
{code:properties}
camel.language.semantic.adapter=#bean:mySemanticAdapter
{code}
Alternatively, accept a fully qualified class name:
{code:properties}
camel.language.semantic.adapter=com.example.MySemanticAdapter
{code}
The example class is illustrative. Support Camel's
{{#class:com.example.MySemanticAdapter}} spelling as an equivalent. For a
class-selected or discovered adapter, the semantic infrastructure should
resolve and type-check the class through Camel, instantiate it using the
context Injector, register it once for the language configuration, and
integrate its lifecycle. Reuse referenced beans without duplicating their
existing lifecycle ownership. Define registry ownership, collision handling and
startup-failure cleanup; binding an object does not itself establish service
lifecycle management.
Provider configuration must remain effective even when the route contains no
provider endpoint. For example, a Jev adapter must honor the configured Jev
component's credentials and connection options. A manually declared adapter
bean is an optional customization path, not a prerequisite for normal operation.
h2. Generic selector-based Choice in Camel core
Extend Choice to evaluate one ordinary Camel Expression and match its result
against literal branch values. Core should know only expression evaluation and
value matching; it must have no dependency on semantic questions, Jev, or a
model runtime.
Proposed Java shape, where {{department}} is a Camel Expression resolving the
named semantic question:
{code:java}
from("direct:tickets")
.choice(department)
.when("billing")
.to("direct:billing")
.when("technical")
.to("direct:technical")
.otherwise()
.to("direct:general")
.end();
{code}
The same extension must work with ordinary expressions such as
{{header("department")}}. Existing predicate-based Choice behavior must remain
unchanged.
* Evaluate the selector once per entry into the Choice block, including when
the first branch does not match. Nested choices have independent evaluation
scopes.
* A later loop/retry entry may evaluate again. Do not introduce an indefinite
exchange-wide semantic-result cache.
* Define literal typing/equality, null/unmatched results, duplicate values, and
whether/how selector branches can coexist with predicate branches.
* A successful unmatched value selects {{otherwise}}. Inference or
invalid-response failures follow Camel error handling; uncertainty requires an
explicit policy.
* Define interaction with Choice precondition mode. Message-dependent inference
must not execute against a dummy startup exchange. CAMEL-17755 concerns startup
preconditions and is distinct from this per-message selector proposal.
* Include model, reifier, runtime, Java DSL, YAML/XML serialization and
generated schema/catalog coverage. A language plugin alone cannot add the
proposed Choice API.
h2. Evaluation across other EIPs
The following are candidate uses, not a requirement to introduce
semantic-specific changes to every EIP.
|| EIP || Example benefit || Integration ||
| Validate | Does this bug report describe an actionable problem? | A boolean
decision supplies the validation predicate; negative decisions use normal
validation failure handling. |
| Set Header / Set Property | Attach department, sentiment or urgency to a
message. | Store a category or score for explicit reuse by subsequent
processors. |
| Aggregate: grouping | Group feedback by delivery, pricing or usability. | Use
a category as part of the correlation key, retaining tenant/case boundaries and
bounded aggregation windows where needed. |
| Aggregate: completion | Does the accumulated conversation contain enough
information to proceed? | Evaluate a boolean completion predicate against
selected aggregate state, alongside a size or timeout completion condition. |
| Recipient List | Send a complaint to support and the relevant product team. |
Map a category, or multiple independent decisions, to configured recipients. |
| Routing Slip | Select a document-processing sequence. | Map a document
category to a predefined sequence of endpoints. |
| Enrich | Choose the appropriate knowledge source for a support request. | Map
a topic to a configured enrichment endpoint; ordinary code retrieves and merges
the additional data. |
| Loop | Continue refinement while the updated output remains incomplete. |
Reevaluate a semantic predicate against current state, with an explicit
iteration/time budget. |
| Sort | Order a batch of tickets by assessed urgency. | Score each item once,
then compare stored scores with a deterministic comparator. |
Validate, metadata assignment and Aggregate can consume Predicate/Expression
results directly. Recipient List, Routing Slip and Enrich require a mapping
from semantic labels to route-author-defined destinations. The classifier does
not invent endpoint addresses or processing steps.
For aggregate completion, the aggregation strategy must expose the relevant
accumulated content; the classifier does not implicitly remember earlier
exchanges. The default completion predicate sees the aggregated exchange, while
{{eagerCheckCompletion}} uses the incoming exchange. State selection must match
that behavior.
For Sort, the EIP expression selects the collection and the comparator
determines ordering. Inference belongs before comparison. For loops or changed
input, explicit result reuse must not hide relevant state changes.
h2. Acceptance criteria and initial coverage
# A common provider-independent question/result contract and adapter SPI
support direct semantic Expression/Predicate use without requiring manual
predicate instances.
# A YAML file can declare named questions under {{semantic.question}} and
reference them from routes. Loader, schema, validation and tooling support
agree on the proposed configuration.
# Adapter discovery, bean-reference override and class-name override are
tested, including missing/ambiguous providers, wrong types, instance reuse,
configuration and lifecycle behavior.
# Question state overrides the language default; omitting both uses the body.
Invalid selectors and missing selected state produce useful errors without
silent input substitution.
# Generic selector-based Choice evaluates once per block entry, works with
semantic and non-semantic expressions, preserves existing predicate-based
Choice, and has nested/looped/error-path coverage and documented precondition
behavior.
# Demonstrate Choice, Filter, Validate, Set Property and Aggregate integration.
Document the other candidate EIPs and their mapping/state requirements without
assuming every EIP needs a core change.
# Provide a Jev adapter and validate the contract with deterministic test
adapters, including a second implementation and capability mismatch cases. Do
not claim interchangeability of model quality, probabilities or calibration.
# Tests cover meaningful result mappings, invocation counts,
threshold/uncertainty policy, explicit result reuse, changed-state
reevaluation, timeouts/failures and preservation of message content. Routine
tests require no live model credentials.
# Document the supported property namespaces and runtime configuration paths.
Coordinate with the generic-language starter work in CAMEL-24913 and
CAMEL-24914 rather than assuming language configuration is generated
automatically.
h2. Boundaries and references
Choosing a local inference runtime (pure JVM/WASM versus native inference),
model weights, or a particular hosted service is outside this proposal's
initial decision. A provider can implement Jev API compatibility, but the
common SPI does not require it and does not imply equivalent proprietary model
behavior or calibration. The SPI's final package, discovery metadata and public
syntax remain open to design review.
Related work:
* CAMEL-24871 — Jev component and semantic EIP integration background.
* CAMEL-24913 — Jev Spring Boot starter configuration.
* CAMEL-24914 — Starter generation for languages backed by the generic model.
* CAMEL-17755 — Existing Choice precondition design.
* [Camel Language
SPI|https://github.com/apache/camel/blob/main/core/camel-api/src/main/java/org/apache/camel/spi/Language.java]
* [Choice
model|https://github.com/apache/camel/blob/main/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java]
* [Aggregate
EIP|https://camel.apache.org/components/next/eips/aggregate-eip.html]
* [System One Models|https://systemonemodels.org/]
_AI-generated by Codex on behalf of
[luigidemasi|https://github.com/luigidemasi]._
> Add provider-agnostic semantic evaluation across Camel EIPs
> -----------------------------------------------------------
>
> Key: CAMEL-24977
> URL: https://issues.apache.org/jira/browse/CAMEL-24977
> Project: Camel
> Issue Type: New Feature
> Components: camel-ai, camel-core, camel-yaml-dsl, eip
> Reporter: Luigi De Masi
> Assignee: Luigi De Masi
> Priority: Major
>
> h2. Motivation
> Provide a provider-agnostic semantic evaluation API and Camel language so
> route authors can ask named questions about message content and use the
> resulting boolean decisions, categories, or scores across EIPs. For example,
> a support message can be classified as billing, technical, or other; a
> separate question can assess urgency or whether the message contains an
> actionable request.
> CAMEL-24871 added the Jev integration. This proposal builds on that work by
> separating the common question/evaluation contract from provider-specific
> implementations and adding a generic selector-based Choice capability. Jev
> can implement the common SPI, and other hosted or local classifiers can
> implement it without requiring Jev wire compatibility.
> The desired authoring experience is declarative: named questions in the same
> YAML file as routes, automatic provider-adapter discovery, and direct use
> through Camel's language integration. Route authors should not need to
> instantiate a predicate or adapter bean for the normal case.
> This is a design proposal. The syntax below illustrates the intended
> behavior; public names, packaging and exact DSL/schema details require
> community review. It does not claim that the proposed semantic language or
> selector-based Choice is already available.
> h2. Common semantic evaluation contract
> * Define provider-independent question and result types for categorical
> Choice, yes/no judgments (including probability-to-boolean decision policy),
> and scoring against descriptive ordered levels. Preserve the useful shape of
> Jev Choice/Noul/Score through its adapter; final common type names should not
> force other providers to adopt Jev terminology.
> * Separate the selected category/value, probabilities, provider confidence,
> uncertainty policy and operational errors. A probability, a confidence
> measure and a guarantee of correctness are not interchangeable. Preserve
> provider metadata where useful without requiring all providers to report the
> same optional fields.
> * A provider component advertises an adapter implementing the common SPI. The
> adapter maps questions/state to its backend, validates supported
> capabilities, and maps typed results back to the common contract.
> * Expose evaluations through Camel's existing {{Language}}, {{Expression}}
> and {{Predicate}} contracts. Predicate use requires a boolean decision or
> explicit comparison/threshold policy; a category string is not implicitly a
> predicate.
> * Keep provider credentials, model selection, transport/inference
> configuration, and provider-specific resources with the implementing
> component. Define thread safety, bounded evaluation, cancellation and
> lifecycle behavior. Synchronous Predicate/Expression evaluation must document
> any blocking inference call.
> h2. Named questions and state in YAML
> Support a dedicated top-level {{semantic.question}} declaration from the
> initial version, alongside route definitions. The following is proposed
> syntax:
> {code}
> - semantic:
> question:
> department:
> type: choice
> state: ${header.myState}
> instructions: Which department should handle this message?
> criteria:
> billing: Invoices, payments, and refunds
> technical: Bugs, outages, and technical problems
> other: Everything else
> - route:
> id: ticket-routing
> from:
> uri: direct:tickets
> steps:
> - choice:
> selector:
> language:
> language: semantic
> expression: "ref:department"
> when:
> - value: billing
> steps:
> - to: direct:billing
> - value: technical
> steps:
> - to: direct:technical
> otherwise:
> steps:
> - to: direct:general
> {code}
> Each question owns its input-state selector. An optional language default can
> be configured:
> {code}
> camel.language.semantic.default-state=${body}
> {code}
> Proposed precedence: question {{state}}, then configured {{default-state}},
> then built-in {{${body}}}. Use Camel Simple expressions for these selectors
> initially. Compile/initialize selectors during route setup and evaluate
> against the current exchange at runtime. Only an absent selector inherits the
> default: a malformed selector or an explicitly selected header that evaluates
> to null must not silently cause different data to be classified. Input values
> are data, not recursively evaluated expressions.
> Question declarations need loader, validation, schema and tooling support.
> Resolve references before traffic where possible; reject duplicate names,
> unknown references and unsupported question capabilities. Define behavior
> across multiple route resources and reload without retaining obsolete
> definitions. Loading/validating declarations must not perform inference.
> h2. Adapter discovery and explicit selection
> The language must not require a provider endpoint URI such as
> {{jev:decisions}}. With exactly one advertised adapter implementation
> available, discover and select it automatically. With none, report a missing
> provider; with multiple, report the candidates and require explicit
> selection. Do not choose by classpath order or construct every provider
> during discovery.
> Allow an explicit reference to an existing registered instance:
> {code}
> camel.language.semantic.adapter=#bean:mySemanticAdapter
> {code}
> Alternatively, accept a fully qualified class name:
> {code}
> camel.language.semantic.adapter=com.example.MySemanticAdapter
> {code}
> The example class is illustrative. Support Camel's
> {{#class:com.example.MySemanticAdapter}} spelling as an equivalent. For a
> class-selected or discovered adapter, the semantic infrastructure should
> resolve and type-check the class through Camel, instantiate it using the
> context Injector, register it once for the language configuration, and
> integrate its lifecycle. Reuse referenced beans without duplicating their
> existing lifecycle ownership. Define registry ownership, collision handling
> and startup-failure cleanup; binding an object does not itself establish
> service lifecycle management.
> Provider configuration must remain effective even when the route contains no
> provider endpoint. For example, a Jev adapter must honor the configured Jev
> component's credentials and connection options. A manually declared adapter
> bean is an optional customization path, not a prerequisite for normal
> operation.
> h2. Generic selector-based Choice in Camel core
> Extend Choice to evaluate one ordinary Camel Expression and match its result
> against literal branch values. Core should know only expression evaluation
> and value matching; it must have no dependency on semantic questions, Jev, or
> a model runtime.
> Proposed Java shape, where {{department}} is a Camel Expression resolving the
> named semantic question:
> {code:java}
> from("direct:tickets")
> .choice(department)
> .when("billing")
> .to("direct:billing")
> .when("technical")
> .to("direct:technical")
> .otherwise()
> .to("direct:general")
> .end();
> {code}
> The same extension must work with ordinary expressions such as
> {{header("department")}}. Existing predicate-based Choice behavior must
> remain unchanged.
> * Evaluate the selector once per entry into the Choice block, including when
> the first branch does not match. Nested choices have independent evaluation
> scopes.
> * A later loop/retry entry may evaluate again. Do not introduce an indefinite
> exchange-wide semantic-result cache.
> * Define literal typing/equality, null/unmatched results, duplicate values,
> and whether/how selector branches can coexist with predicate branches.
> * A successful unmatched value selects {{otherwise}}. Inference or
> invalid-response failures follow Camel error handling; uncertainty requires
> an explicit policy.
> * Define interaction with Choice precondition mode. Message-dependent
> inference must not execute against a dummy startup exchange. CAMEL-17755
> concerns startup preconditions and is distinct from this per-message selector
> proposal.
> * Include model, reifier, runtime, Java DSL, YAML/XML serialization and
> generated schema/catalog coverage. A language plugin alone cannot add the
> proposed Choice API.
> h2. Evaluation across other EIPs
> The following are candidate uses, not a requirement to introduce
> semantic-specific changes to every EIP.
> || EIP || Example benefit || Integration ||
> | Validate | Does this bug report describe an actionable problem? | A boolean
> decision supplies the validation predicate; negative decisions use normal
> validation failure handling. |
> | Set Header / Set Property | Attach department, sentiment or urgency to a
> message. | Store a category or score for explicit reuse by subsequent
> processors. |
> | Aggregate: grouping | Group feedback by delivery, pricing or usability. |
> Use a category as part of the correlation key, retaining tenant/case
> boundaries and bounded aggregation windows where needed. |
> | Aggregate: completion | Does the accumulated conversation contain enough
> information to proceed? | Evaluate a boolean completion predicate against
> selected aggregate state, alongside a size or timeout completion condition. |
> | Recipient List | Send a complaint to support and the relevant product team.
> | Map a category, or multiple independent decisions, to configured
> recipients. |
> | Routing Slip | Select a document-processing sequence. | Map a document
> category to a predefined sequence of endpoints. |
> | Enrich | Choose the appropriate knowledge source for a support request. |
> Map a topic to a configured enrichment endpoint; ordinary code retrieves and
> merges the additional data. |
> | Loop | Continue refinement while the updated output remains incomplete. |
> Reevaluate a semantic predicate against current state, with an explicit
> iteration/time budget. |
> | Sort | Order a batch of tickets by assessed urgency. | Score each item
> once, then compare stored scores with a deterministic comparator. |
> Validate, metadata assignment and Aggregate can consume Predicate/Expression
> results directly. Recipient List, Routing Slip and Enrich require a mapping
> from semantic labels to route-author-defined destinations. The classifier
> does not invent endpoint addresses or processing steps.
> For aggregate completion, the aggregation strategy must expose the relevant
> accumulated content; the classifier does not implicitly remember earlier
> exchanges. The default completion predicate sees the aggregated exchange,
> while {{eagerCheckCompletion}} uses the incoming exchange. State selection
> must match that behavior.
> For Sort, the EIP expression selects the collection and the comparator
> determines ordering. Inference belongs before comparison. For loops or
> changed input, explicit result reuse must not hide relevant state changes.
> h2. Acceptance criteria and initial coverage
> # A common provider-independent question/result contract and adapter SPI
> support direct semantic Expression/Predicate use without requiring manual
> predicate instances.
> # A YAML file can declare named questions under {{semantic.question}} and
> reference them from routes. Loader, schema, validation and tooling support
> agree on the proposed configuration.
> # Adapter discovery, bean-reference override and class-name override are
> tested, including missing/ambiguous providers, wrong types, instance reuse,
> configuration and lifecycle behavior.
> # Question state overrides the language default; omitting both uses the body.
> Invalid selectors and missing selected state produce useful errors without
> silent input substitution.
> # Generic selector-based Choice evaluates once per block entry, works with
> semantic and non-semantic expressions, preserves existing predicate-based
> Choice, and has nested/looped/error-path coverage and documented precondition
> behavior.
> # Demonstrate Choice, Filter, Validate, Set Property and Aggregate
> integration. Document the other candidate EIPs and their mapping/state
> requirements without assuming every EIP needs a core change.
> # Provide a Jev adapter and validate the contract with deterministic test
> adapters, including a second implementation and capability mismatch cases. Do
> not claim interchangeability of model quality, probabilities or calibration.
> # Tests cover meaningful result mappings, invocation counts,
> threshold/uncertainty policy, explicit result reuse, changed-state
> reevaluation, timeouts/failures and preservation of message content. Routine
> tests require no live model credentials.
> # Document the supported property namespaces and runtime configuration paths.
> Coordinate with the generic-language starter work in CAMEL-24913 and
> CAMEL-24914 rather than assuming language configuration is generated
> automatically.
> h2. Boundaries and references
> Choosing a local inference runtime (pure JVM/WASM versus native inference),
> model weights, or a particular hosted service is outside this proposal's
> initial decision. A provider can implement Jev API compatibility, but the
> common SPI does not require it and does not imply equivalent proprietary
> model behavior or calibration. The SPI's final package, discovery metadata
> and public syntax remain open to design review.
> Related work:
> * CAMEL-24871 — Jev component and semantic EIP integration background.
> * CAMEL-24913 — Jev Spring Boot starter configuration.
> * CAMEL-24914 — Starter generation for languages backed by the generic model.
> * CAMEL-17755 — Existing Choice precondition design.
> * [Camel Language
> SPI|https://github.com/apache/camel/blob/main/core/camel-api/src/main/java/org/apache/camel/spi/Language.java]
> * [Choice
> model|https://github.com/apache/camel/blob/main/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java]
> * [Aggregate
> EIP|https://camel.apache.org/components/next/eips/aggregate-eip.html]
> * [System One Models|https://systemonemodels.org/]
> _AI-generated by Codex on behalf of
> [luigidemasi|https://github.com/luigidemasi]._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)