跳到主要内容
印格

Logical routes

Logical route JSON reference

The console "Logic JSON" is the single source of truth (logic_json / RouteLogicV2). The flow diagram is a visual mapping of flowNodes; every apply or canvas edit runs parseRouteLogic + syncLogicFromFlowNodes, then the same validateRouteLogic pipeline (including Gateway Endpoint context).

Top-level fields

routingMode: single | byInputFormat | conditional | flow. operation is always "generate" (embedding uses flowNodes with kind: embed).

PathTypeDescription
versionnumberMust be 2
operationstringAlways "generate"
routingModestringsingle | byInputFormat | conditional | flow
input.promptTemplatestringPrompt template, e.g. {{prompt}}
defaultBranchobjectDefault branch: providerId, model or nodeKey (Endpoint), generation
branches[]arrayConditional branches (synced with flowNodes)
flowChain[]arrayFallback steps (routingMode: flow)
flowNodes[]arrayFlow canvas source; apply runs syncLogicFromFlowNodes
protocolFlowNodesobjectPer access-protocol flowNodes buckets (split editor view)
embedBranchobjectCompiled from kind: embed nodes

Branch condition when

Used on branches[].when, deny.when, and nested branches. First match wins.

format

Input shape: text | chat_content | image | image_text | multimodal | file | audio | video | openapi_json | any

{ "type": "format", "format": "image_text" }

modelId

Caller upstream model (Header x-gateway-model or metadata.model)

{
  "when": { "type": "modelId", "op": "eq", "value": "gemini-2.5-flash" }
}

fileSize

Total inlineData byte threshold

{ "type": "fileSize", "op": "gt", "value": 1, "unit": "MB" }

metadata

Match header / metadata / body field

{ "type": "metadata", "source": "metadata", "key": "user_id", "op": "exists" }

messageType

Message role or part type (text / image / audio / video / file)

{ "type": "messageType", "variant": "role", "role": "system", "scope": "any" }

messageContent

Match text in messages (concatenated text parts in contents / messages)

{ "type": "messageContent", "scope": "last_user", "op": "contains", "value": "summarize" }

messageParts

Multiple part types in contents[] / messages[]; match all (across messages), any, only, or all in same message

{ "type": "messageParts", "parts": ["text", "image"], "match": "same_message", "scope": "last_user" }

flowNodes.kind

  • singleSingle upstream Endpoint
  • conditionalIF / ELSE
  • switchMulti-case + DEFAULT
  • fallbackOrdered fallback steps[]
  • denyReject when when matches
  • embedVector embed embedContent

Examples

Single Endpoint

{
  "version": 2,
  "operation": "generate",
  "routingMode": "single",
  "input": { "promptTemplate": "{{prompt}}" },
  "defaultBranch": {
    "providerId": "gemini",
    "model": "",
    "nodeKey": "your-endpoint-node-key",
    "generation": { "temperature": 0.7 }
  },
  "flowNodes": [
    {
      "id": "single-1",
      "kind": "single",
      "providerId": "gemini",
      "model": "",
      "nodeKey": "your-endpoint-node-key"
    }
  ]
}

Conditional (image+text / text)

{
  "version": 2,
  "operation": "generate",
  "routingMode": "byInputFormat",
  "input": { "promptTemplate": "{{prompt}}" },
  "defaultBranch": { "providerId": "gemini", "model": "", "nodeKey": "default-node" },
  "flowNodes": [
    {
      "id": "if-1",
      "kind": "conditional",
      "branches": [
        {
          "id": "image",
          "label": "图文",
          "when": { "type": "format", "format": "image_text" },
          "providerId": "gemini",
          "model": "",
          "nodeKey": "vision-node"
        }
      ],
      "elseBranch": {
        "providerId": "openai",
        "model": "",
        "nodeKey": "text-node"
      }
    }
  ]
}

Ctrl+Enter applies JSON; after apply the flow canvas and runtime registry share the same logic_json.

→ Console