Decision Branch Node

Applies to: ChengOS v0.2.0+ | Last verified: 2026-09-25 | Source: crates/cheng-nodes/src/nodes/builtin/ai/decision_branch.rs, config/decision_providers.toml, config/decision_calibration.toml

ai/decision_branch routes a conversation turn to exactly one of the routes you declare, using a typed decision provider rather than a chat model: TypeSafe Jev (hosted, calibrated probabilities), Laya (a local model the operator runs), or a connected LLM as an uncalibrated baseline. The provider sees only the latest request, the route descriptions, the routing instruction, and in sticky mode the previous route ID — never history, tools, or credentials. The context itself is delivered unchanged to route_<id>; anything ordinary, ambiguous, multi-intent, low-confidence, or failed goes to fallback_out, so a misroute or an outage degrades to what the workflow did without the router. Authoring guidance, thresholds, and the two-stage cascade are in Semantic Routing; provider setup is in Decision Providers & TypeSafe Jev.

Decision Branch — ai/decision_branch

Route the request to exactly one declared route with a typed decision model (Jev or an LLM baseline); anything unclear goes to fallback_out with the context unchanged

Inputs

FieldTypeRequiredDefaultDescription
contextobject (port)—nullInput AgentContext; the latest user request is routed and the context is delivered unchanged. Connection port, not a form field. Control: code-editor
providerenum—jevJev: hosted typed decision model (the routed request is sent to TypeSafe). LLM: a connected chat model as an uncalibrated baseline. Laya: the installation's own local model, when the operator has enabled it (at most 15 routes; uncalibrated unless the operator pins the served artifact). Control: select. Options: jev (TypeSafe Jev (hosted; calibrated probabilities).), llm (A connected chat model with constrained output (uncalibrated).), laya (The installation's own Laya deployment (local; enabled by the operator).)
credential_idstring—nullTypeSafe Jev credential. Leave empty to use the deployment's JEV_API_KEY, if configured. Control: credential-select
decision_modelstring—""Decision model; empty uses the credential's pin, then the provider default. Wins over the legacy jev_model when set. Control: decision-model-select
llm_modelstring—nullChat model for the LLM baseline provider. Control: llm-model-select
routing_instructionstring—""How to interpret the request and when to choose each route. Route IDs come from the route list; keep tool-operation instructions on the focused LLMs. Control: textarea
routesarray<object>—[]Declared routes (keyed output ports). Control: route-list
route_memoryenum—stickySticky: send the previous route as context; in calibrated mode it is also held for a referential follow-up (in none mode there are no hold thresholds, so only the context applies). Remembered per conversation in this server process. Off: route every turn on its own. Control: select. Options: off (Every turn is routed on its own.), sticky (The previous turn's route is sent as context, and may be held for a referential follow-up ("reply to him and say yes").)
threshold_modeenum—calibratedCalibrated: apply the measured profile for this provider/model/language, or fall back when none exists; providers that report no probabilities (LLM baseline) cannot use it. None (uncalibrated): route on the raw answer. Control: select. Options: calibrated (Apply the measured calibration profile; without one, fall back.), none (Uncalibrated: route on the raw answer; only invalid, out-of-set, timed-out, or failed decisions fall back.)
failure_modeenum—fallbackFallback: provider errors and missing configuration go to fallback_out. Fail closed: they fail the node. Control: select. Options: fallback (Failures and missing configuration go to fallback_out.), fail_closed (Failures and missing configuration fail the node with a typed error.)
uncertain_routingenum—fallbackFallback: low-confidence decisions go to fallback_out with everything else. Separate port: in calibrated mode they go to uncertain_out (below the threshold, or no profile for this model/language), so a second-stage arbiter can decide them; confident fallbacks and provider failures still go to fallback_out. Control: select. Options: fallback (Together with every other non-route outcome, to fallback_out.), separate (To uncertain_out, so a second-stage arbiter can decide it while confident fallbacks (ordinary conversation) go straight to fallback_out.)
timeout_msinteger—nullDecision deadline; empty uses the provider's default (Jev and Laya: 1500 ms). For the LLM baseline an empty timeout adapts to the chosen chat model from its observed decisions, so a reasoning model gets the time it needs. A miss follows the failure mode and never stalls the turn. Values above the provider's maximum are capped.

Outputs

FieldTypeDescription
fallback_outobject (port)Unchanged context when no route was selected. Connection port, not a form field.
uncertain_outobject (port)Unchanged context for a low-confidence decision, when separated. Connection port, not a form field.
decisionobject (port)Bounded decision summary (no user text). Connection port, not a form field.

Next steps