Order-Support Workflow Example

This example shows how several node types cooperate in one business workflow. An online store receives a customer request, determines the type of assistance required, performs the applicable work, and returns one response.

The example separates three concerns:

  • The Flow controls which processing path can execute.
  • Data-flow edges supply the values required by each processing node.
  • The selected processing node performs the business operation and supplies the result returned by the Flow.

The workflow supports three request types:

Request typeProcessing path
where_is_orderExecutes a reusable order-lookup subflow through a FlowNode.
start_returnInvokes a return-eligibility operation through a ToolNode.
otherExecutes an order-support Agent through an AgentNode.

Workflow at a Glance

The caller supplies request, request_type, and order_id. The StartNode exposes those values as named outputs. The BranchingNode reads request_type and selects one of three control-flow branches. The selected branch leads to a FlowNode, ToolNode, or AgentNode. After that node finishes, its result is transferred to the EndNode for that path and returned as the Flow output named response.

The diagram represents the following sequence:

  1. Execution begins at the StartNode.
  2. The BranchingNode examines request_type and selects one branch.
  3. The control-flow edge for that branch identifies the processing node that can execute next.
  4. Data-flow edges supply the values required by that processing node.
  5. The processing node produces a result.
  6. The result is transferred to an EndNode and returned through the Flow output contract.

Only the processing path associated with the selected branch executes. Data-flow connections make values available to their destinations, but they do not cause those destinations to run.

Role of Each Component

ComponentRole in this workflow
StartNodeMakes the three execution inputs available to the Flow.
BranchingNodeConverts the request_type value into one declared branch name.
Order-lookup FlowNodeRuns an existing order-lookup Flow and returns its result to the enclosing Flow.
Return-eligibility ToolNodeInvokes one predetermined return-eligibility operation.
Order-support AgentNodeRuns an Agent that can decide whether an available tool is needed to answer the request.
EndNodeMaps the result from one completed path to the Flow output named response.

Public Input and Output Contract

The caller supplies the customer request, its classification, and the applicable order identifier:

DirectionNameTypeDescription
InputrequeststringCustomer's order-support question.
Inputrequest_typestringClassification used to select a processing branch.
Inputorder_idstringOrder identifier used by the order-specific paths.
OutputresponsestringResult returned by the selected path.

For example, a return request can supply these execution inputs:

[
  {
    "name": "request",
    "value": "Can I return order 7812?"
  },
  {
    "name": "request_type",
    "value": "start_return"
  },
  {
    "name": "order_id",
    "value": "7812"
  }
]

The runtime matches the three name values to the corresponding Flow inputs. The values then become available through StartNode.request, StartNode.request_type, and StartNode.order_id. They are not passed automatically to every node; the data-flow edges shown later define where each value can be consumed.

Control Flow

The BranchingNode maps each supported request_type value to a declared branch. The outgoing control-flow edge with the corresponding from_branch identifies the processing node that can execute next. This decision controls execution only; it does not transfer request, request_type, or order_id to that node.

The mapping is:

request_type valueSelected branchPossible next node
where_is_orderorder_statusOrder-lookup FlowNode.
start_returnreturn_requestReturn-eligibility ToolNode.
othergeneral_questionOrder-support AgentNode.

Data Flow

Data-flow edges identify how StartNode outputs map to the inputs of nodes on each branch. The branch decision determines which path executes. A node on an unselected path does not execute and therefore does not consume or process the values identified by its data-flow edges.

The Flow declares data-flow edges to all three processing paths because each path has a different input requirement:

  • The BranchingNode needs request_type to make the decision.
  • The FlowNode and ToolNode need order_id for their order-specific operations.
  • The AgentNode needs the complete customer request.

These connections do not mean that all three processing nodes execute. The selected control-flow branch determines which path continues. The data-flow edge for that path supplies the value already associated with its destination input.

How the Request Paths Execute

The following sections trace the work performed after each possible branch is selected.

Order-Status Request

For request_type = "where_is_order", the BranchingNode selects the order_status branch. The matching control-flow edge leads to the order-lookup FlowNode. A data-flow edge supplies StartNode.order_id to FlowNode.order_id.

The FlowNode then executes the referenced order-lookup subflow. That subflow has its own control graph and can contain its own StartNode, ToolNode, and EndNode. When the subflow finishes, its order_status output becomes FlowNode.order_status. A data-flow edge transfers that value to the status EndNode input named response.

The enclosing Flow interacts with the subflow only through the FlowNode input and output contract. Changes to the internal lookup graph do not require changes to the enclosing Flow while that contract remains compatible.

Return Request

For request_type = "start_return", the BranchingNode selects the return_request branch. The matching control-flow edge leads to the return-eligibility ToolNode, and a data-flow edge supplies StartNode.order_id to ToolNode.order_id.

When the ToolNode executes, it resolves its Tool reference and invokes the configured return-eligibility operation. The operation result becomes ToolNode.response. A data-flow edge transfers that value to the return EndNode input named response.

This path is predetermined by the Flow. No model chooses whether the return-eligibility operation runs.

General Support Request

For request_type = "other", the BranchingNode selects the general_question branch. The matching control-flow edge leads to the order-support AgentNode, and a data-flow edge supplies StartNode.request to AgentNode.request.

The AgentNode executes its referenced Agent. The Agent uses its instructions, configured model, and available tools during its model-and-tool loop. When the Agent produces its final result, that value becomes AgentNode.response. A data-flow edge transfers it to the general EndNode input named response.

The Flow determines when the Agent runs. The Agent determines whether its model-and-tool loop requires an available tool before producing the response.

Completion Behavior

Each processing path reaches a separate EndNode. Separate completion nodes make it explicit which processing node supplies the result for each path. All three EndNodes map their input named response to the same Flow output contract:

{
  "response": "Order 7812 is eligible for return within 30 days of delivery."
}

Regardless of the selected path, the API caller therefore receives one string named response.

Follow One Request End to End

For the earlier request, request_type is start_return. The execution proceeds as follows:

  1. The runtime maps the three supplied values to the Flow inputs.
  2. The StartNode exposes those values as request, request_type, and order_id outputs.
  3. A data-flow edge supplies request_type = "start_return" to the BranchingNode.
  4. The BranchingNode maps start_return to the return_request branch.
  5. The control-flow edge for return_request identifies the return-eligibility ToolNode as the next possible node.
  6. A data-flow edge supplies order_id = "7812" to the ToolNode.
  7. The ToolNode invokes the referenced return-eligibility operation and produces a response.
  8. A data-flow edge transfers that response to the return EndNode.
  9. The EndNode maps the value to the Flow output named response, which the runtime returns to the caller.

The order-lookup FlowNode and general-support AgentNode do not execute for this request because their control-flow branches were not selected.

Complete Runnable Agent Spec

The example requires:

  • A database credential and the network access required for the configured model endpoint.
  • Permission to execute the ORDER_SUPPORT_TOOLS package.
  • Provider, URL, model, and credential values that are valid for the target environment.

Create the Example Operations

The following package supplies the database operations used by the FlowNode, ToolNode, and Agent:

CREATE OR REPLACE PACKAGE ORDER_SUPPORT_TOOLS AS
  PROCEDURE LOOKUP_ORDER (
    ORDER_ID     IN  VARCHAR2,
    ORDER_STATUS OUT VARCHAR2
  );

  PROCEDURE CHECK_RETURN_ELIGIBILITY (
    ORDER_ID IN  VARCHAR2,
    RESPONSE OUT VARCHAR2
  );
END ORDER_SUPPORT_TOOLS;
/

CREATE OR REPLACE PACKAGE BODY ORDER_SUPPORT_TOOLS AS
  PROCEDURE LOOKUP_ORDER (
    ORDER_ID     IN  VARCHAR2,
    ORDER_STATUS OUT VARCHAR2
  ) IS
  BEGIN
    IF ORDER_ID = '7812' THEN
      ORDER_STATUS := 'OUT_FOR_DELIVERY';
    ELSE
      ORDER_STATUS := 'PROCESSING';
    END IF;
  END LOOKUP_ORDER;

  PROCEDURE CHECK_RETURN_ELIGIBILITY (
    ORDER_ID IN  VARCHAR2,
    RESPONSE OUT VARCHAR2
  ) IS
  BEGIN
    IF ORDER_ID = '7812' THEN
      RESPONSE := 'Order 7812 is eligible for return within 30 days of delivery.';
    ELSE
      RESPONSE := 'Return eligibility requires additional review.';
    END IF;
  END CHECK_RETURN_ELIGIBILITY;
END ORDER_SUPPORT_TOOLS;
/

Execute the Complete Agent Spec

The following block executes the start_return path. Change request_type to where_is_order to execute the nested Flow or to other to execute the Agent.

SET SERVEROUTPUT ON SIZE UNLIMITED
SET DEFINE OFF

DECLARE
  L_AGENT_SPEC CLOB := q'~
{
  "component_type": "Flow",
  "agentspec_version": "25.4.1",
  "id": "order-support-workflow",
  "name": "order_support_workflow",
  "inputs": [
    {
      "title": "request",
      "type": "string"
    },
    {
      "title": "request_type",
      "type": "string"
    },
    {
      "title": "order_id",
      "type": "string"
    }
  ],
  "outputs": [
    {
      "title": "response",
      "type": "string"
    }
  ],
  "start_node": {
    "$component_ref": "start"
  },
  "nodes": [
    {
      "$component_ref": "start"
    },
    {
      "$component_ref": "route-support-request"
    },
    {
      "$component_ref": "run-order-lookup"
    },
    {
      "$component_ref": "check-return"
    },
    {
      "$component_ref": "answer-general-question"
    },
    {
      "$component_ref": "order-status-end"
    },
    {
      "$component_ref": "return-end"
    },
    {
      "$component_ref": "general-question-end"
    }
  ],
  "control_flow_connections": [
    {
      "component_type": "ControlFlowEdge",
      "id": "start-to-router",
      "name": "start_to_router",
      "from_node": {
        "$component_ref": "start"
      },
      "to_node": {
        "$component_ref": "route-support-request"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "route-to-order-lookup",
      "name": "route_to_order_lookup",
      "from_node": {
        "$component_ref": "route-support-request"
      },
      "from_branch": "order_status",
      "to_node": {
        "$component_ref": "run-order-lookup"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "route-to-return-check",
      "name": "route_to_return_check",
      "from_node": {
        "$component_ref": "route-support-request"
      },
      "from_branch": "return_request",
      "to_node": {
        "$component_ref": "check-return"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "route-to-general-question",
      "name": "route_to_general_question",
      "from_node": {
        "$component_ref": "route-support-request"
      },
      "from_branch": "general_question",
      "to_node": {
        "$component_ref": "answer-general-question"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "default-to-general-question",
      "name": "default_to_general_question",
      "from_node": {
        "$component_ref": "route-support-request"
      },
      "from_branch": "default",
      "to_node": {
        "$component_ref": "answer-general-question"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "order-lookup-to-end",
      "name": "order_lookup_to_end",
      "from_node": {
        "$component_ref": "run-order-lookup"
      },
      "from_branch": "next",
      "to_node": {
        "$component_ref": "order-status-end"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "return-check-to-end",
      "name": "return_check_to_end",
      "from_node": {
        "$component_ref": "check-return"
      },
      "to_node": {
        "$component_ref": "return-end"
      }
    },
    {
      "component_type": "ControlFlowEdge",
      "id": "general-question-to-end",
      "name": "general_question_to_end",
      "from_node": {
        "$component_ref": "answer-general-question"
      },
      "to_node": {
        "$component_ref": "general-question-end"
      }
    }
  ],
  "data_flow_connections": [
    {
      "component_type": "DataFlowEdge",
      "id": "request-type-to-router",
      "name": "request_type_to_router",
      "source_node": {
        "$component_ref": "start"
      },
      "source_output": "request_type",
      "destination_node": {
        "$component_ref": "route-support-request"
      },
      "destination_input": "request_type"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "order-id-to-flow-node",
      "name": "order_id_to_flow_node",
      "source_node": {
        "$component_ref": "start"
      },
      "source_output": "order_id",
      "destination_node": {
        "$component_ref": "run-order-lookup"
      },
      "destination_input": "order_id"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "order-id-to-return-check",
      "name": "order_id_to_return_check",
      "source_node": {
        "$component_ref": "start"
      },
      "source_output": "order_id",
      "destination_node": {
        "$component_ref": "check-return"
      },
      "destination_input": "order_id"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "request-to-agent-node",
      "name": "request_to_agent_node",
      "source_node": {
        "$component_ref": "start"
      },
      "source_output": "request",
      "destination_node": {
        "$component_ref": "answer-general-question"
      },
      "destination_input": "request"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "order-status-to-end",
      "name": "order_status_to_end",
      "source_node": {
        "$component_ref": "run-order-lookup"
      },
      "source_output": "order_status",
      "destination_node": {
        "$component_ref": "order-status-end"
      },
      "destination_input": "response"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "return-response-to-end",
      "name": "return_response_to_end",
      "source_node": {
        "$component_ref": "check-return"
      },
      "source_output": "response",
      "destination_node": {
        "$component_ref": "return-end"
      },
      "destination_input": "response"
    },
    {
      "component_type": "DataFlowEdge",
      "id": "agent-response-to-end",
      "name": "agent_response_to_end",
      "source_node": {
        "$component_ref": "answer-general-question"
      },
      "source_output": "response",
      "destination_node": {
        "$component_ref": "general-question-end"
      },
      "destination_input": "response"
    }
  ],
  "$referenced_components": {
    "start": {
      "component_type": "StartNode",
      "id": "start",
      "name": "start",
      "inputs": [
        {
          "title": "request",
          "type": "string"
        },
        {
          "title": "request_type",
          "type": "string"
        },
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "request",
          "type": "string"
        },
        {
          "title": "request_type",
          "type": "string"
        },
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "branches": [
        "next"
      ]
    },
    "route-support-request": {
      "component_type": "BranchingNode",
      "id": "route-support-request",
      "name": "route_support_request",
      "inputs": [
        {
          "title": "request_type",
          "type": "string"
        }
      ],
      "outputs": [],
      "branches": [
        "order_status",
        "return_request",
        "general_question",
        "default"
      ],
      "mapping": {
        "where_is_order": "order_status",
        "start_return": "return_request",
        "other": "general_question"
      }
    },
    "run-order-lookup": {
      "component_type": "FlowNode",
      "id": "run-order-lookup",
      "name": "run_order_lookup",
      "inputs": [
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "order_status",
          "type": "string"
        }
      ],
      "branches": [
        "next"
      ],
      "subflow": {
        "$component_ref": "order-lookup-flow"
      }
    },
    "check-return": {
      "component_type": "ToolNode",
      "id": "check-return",
      "name": "check_return",
      "inputs": [
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "branches": [
        "next"
      ],
      "tool": {
        "$component_ref": "return-eligibility-tool"
      }
    },
    "answer-general-question": {
      "component_type": "AgentNode",
      "id": "answer-general-question",
      "name": "answer_general_question",
      "inputs": [
        {
          "title": "request",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string",
          "default": ""
        }
      ],
      "branches": [
        "next"
      ],
      "agent": {
        "$component_ref": "order-support-agent"
      }
    },
    "order-status-end": {
      "component_type": "EndNode",
      "id": "order-status-end",
      "name": "order_status_end",
      "inputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "branches": [],
      "branch_name": "next"
    },
    "return-end": {
      "component_type": "EndNode",
      "id": "return-end",
      "name": "return_end",
      "inputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "branches": [],
      "branch_name": "next"
    },
    "general-question-end": {
      "component_type": "EndNode",
      "id": "general-question-end",
      "name": "general_question_end",
      "inputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "branches": [],
      "branch_name": "next"
    },
    "order-lookup-flow": {
      "component_type": "Flow",
      "id": "order-lookup-flow",
      "name": "order_lookup_flow",
      "inputs": [
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "order_status",
          "type": "string"
        }
      ],
      "start_node": {
        "$component_ref": "order-lookup-start"
      },
      "nodes": [
        {
          "$component_ref": "order-lookup-start"
        },
        {
          "$component_ref": "lookup-order"
        },
        {
          "$component_ref": "order-lookup-end"
        }
      ],
      "control_flow_connections": [
        {
          "component_type": "ControlFlowEdge",
          "id": "order-lookup-start-to-tool",
          "name": "order_lookup_start_to_tool",
          "from_node": {
            "$component_ref": "order-lookup-start"
          },
          "to_node": {
            "$component_ref": "lookup-order"
          }
        },
        {
          "component_type": "ControlFlowEdge",
          "id": "order-lookup-tool-to-end",
          "name": "order_lookup_tool_to_end",
          "from_node": {
            "$component_ref": "lookup-order"
          },
          "to_node": {
            "$component_ref": "order-lookup-end"
          }
        }
      ],
      "data_flow_connections": [
        {
          "component_type": "DataFlowEdge",
          "id": "order-id-to-lookup-tool",
          "name": "order_id_to_lookup_tool",
          "source_node": {
            "$component_ref": "order-lookup-start"
          },
          "source_output": "order_id",
          "destination_node": {
            "$component_ref": "lookup-order"
          },
          "destination_input": "order_id"
        },
        {
          "component_type": "DataFlowEdge",
          "id": "order-status-to-lookup-end",
          "name": "order_status_to_lookup_end",
          "source_node": {
            "$component_ref": "lookup-order"
          },
          "source_output": "order_status",
          "destination_node": {
            "$component_ref": "order-lookup-end"
          },
          "destination_input": "order_status"
        }
      ],
      "$referenced_components": {
        "order-lookup-start": {
          "component_type": "StartNode",
          "id": "order-lookup-start",
          "name": "order_lookup_start",
          "inputs": [
            {
              "title": "order_id",
              "type": "string"
            }
          ],
          "outputs": [
            {
              "title": "order_id",
              "type": "string"
            }
          ],
          "branches": [
            "next"
          ]
        },
        "lookup-order": {
          "component_type": "ToolNode",
          "id": "lookup-order",
          "name": "lookup_order",
          "inputs": [
            {
              "title": "order_id",
              "type": "string"
            }
          ],
          "outputs": [
            {
              "title": "order_status",
              "type": "string"
            }
          ],
          "branches": [
            "next"
          ],
          "tool": {
            "$component_ref": "lookup-orders-tool"
          }
        },
        "order-lookup-end": {
          "component_type": "EndNode",
          "id": "order-lookup-end",
          "name": "order_lookup_end",
          "inputs": [
            {
              "title": "order_status",
              "type": "string"
            }
          ],
          "outputs": [
            {
              "title": "order_status",
              "type": "string"
            }
          ],
          "branches": [],
          "branch_name": "next"
        },
        "lookup-orders-tool": {
          "component_type": "BuiltinTool",
          "id": "lookup-orders-tool",
          "name": "lookup_order",
          "description": "Return the current status of an order.",
          "inputs": [
            {
              "title": "order_id",
              "type": "string"
            }
          ],
          "outputs": [
            {
              "title": "order_status",
              "type": "string"
            }
          ],
          "requires_confirmation": false,
          "executor_name": "Oracle In-DB Agent Executor",
          "tool_version": "1.0",
          "tool_type": "plsql_exec",
          "configuration": {
            "package_name": "ORDER_SUPPORT_TOOLS",
            "procedure_name": "LOOKUP_ORDER"
          }
        }
      },
      "agentspec_version": "25.4.1"
    },
    "return-eligibility-tool": {
      "component_type": "BuiltinTool",
      "id": "return-eligibility-tool",
      "name": "check_return_eligibility",
      "description": "Return a customer-facing return-eligibility response.",
      "inputs": [
        {
          "title": "order_id",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string"
        }
      ],
      "requires_confirmation": false,
      "executor_name": "Oracle In-DB Agent Executor",
      "tool_version": "1.0",
      "tool_type": "plsql_exec",
      "configuration": {
        "package_name": "ORDER_SUPPORT_TOOLS",
        "procedure_name": "CHECK_RETURN_ELIGIBILITY"
      }
    },
    "order-support-agent": {
      "component_type": "Agent",
      "id": "order-support-agent",
      "name": "order_support_agent",
      "inputs": [
        {
          "title": "request",
          "type": "string"
        }
      ],
      "outputs": [
        {
          "title": "response",
          "type": "string",
          "default": ""
        }
      ],
      "llm_config": {
        "$component_ref": "application-llm-config"
      },
      "system_prompt": "Answer general order-support questions. For current order status, invoke lookup_order instead of inferring a value. Use only the tools available to you.",
      "tools": [
        {
          "$component_ref": "agent-lookup-orders-tool"
        }
      ],
      "$referenced_components": {
        "agent-lookup-orders-tool": {
          "component_type": "BuiltinTool",
          "id": "agent-lookup-orders-tool",
          "name": "lookup_order",
          "description": "Return the current status of an order.",
          "inputs": [
            {
              "title": "order_id",
              "type": "string"
            }
          ],
          "outputs": [
            {
              "title": "order_status",
              "type": "string"
            }
          ],
          "requires_confirmation": false,
          "executor_name": "Oracle In-DB Agent Executor",
          "tool_version": "1.0",
          "tool_type": "plsql_exec",
          "configuration": {
            "package_name": "ORDER_SUPPORT_TOOLS",
            "procedure_name": "LOOKUP_ORDER"
          }
        }
      }
    },
    "application-llm-config": {
      "component_type": "DbmsVectorChainLlmConfig",
      "id": "application-llm-config",
      "name": "application_llm_config",
      "provider": "openai",
      "url": "https://api.openai.com/v1/chat/completions",
      "model": "gpt-4.1-mini",
      "credential_name": "AI_PROVIDER_CREDENTIAL",
      "transfer_timeout": 120,
      "default_generation_parameters": {
        "max_tokens": 300,
        "temperature": 0,
        "top_p": 1
      }
    }
  }
}
~';

  L_INPUTS CLOB := TO_CLOB (
    '[{"name":"request","value":"Can I return order 7812?"},'
    || '{"name":"request_type","value":"start_return"},'
    || '{"name":"order_id","value":"7812"}]'
  );
  L_OUTPUTS CLOB;
BEGIN
  L_OUTPUTS := DBMS_AI_AGENT.EXECUTE_IMMEDIATE (
    AGENT_SPEC => L_AGENT_SPEC,
    INPUTS     => L_INPUTS
  );

  DBMS_OUTPUT.PUT_LINE (
    DBMS_LOB.SUBSTR (L_OUTPUTS, 32767, 1)
  );
END;
/

Expected Output

For the supplied inputs, the returned JSON has the following form:

{
  "response": "Order 7812 is eligible for return within 30 days of delivery."
}

The BranchingNode selects the return_request branch, the ToolNode invokes ORDER_SUPPORT_TOOLS.CHECK_RETURN_ELIGIBILITY, and the return EndNode maps the Tool result to the Flow output named response.