Skip to content

PinionAI Intent Processing

The intent flow processing of a user message is the central orchestrator in the PinionAI client library. It classifies the incoming message, resolves the appropriate intent, runs any required preprocessing or action steps, and returns the final response for the caller.

Functional Signature

async def process_user_input(self, user_input: str = '', sender: str = "user") -> str:
  • user_input: The text provided by the user.
  • sender: The sender identifier used for live-agent routing and gRPC messaging.
  • Returns: The final assistant response string.

Core Execution Flow

The method now operates in two primary modes:

  • AI agent mode, when no transfer is pending.
  • Live-agent mode, when a transfer has already been requested.

Initialization

  1. The method initializes preprocess_response, subprocess_response, and final_response as empty strings.
  2. It updates self.grpc_sender_id with the incoming sender value.
  3. If a transfer has not been requested, the method proceeds through intent classification and execution.
  4. If a transfer has been requested, it sends the message to the live agent channel and returns a placeholder response.

AI Agent Mode

This is the main path for normal conversation handling. The flow is sequential but can stop early whenever a response is produced.

1. Classification and Intent Resolution

  • If self.next_intent is set, the method uses that as the next intent and treats it as the current classification target.
  • Otherwise, it calls _classify_input(user_input) to determine the intent.
  • If classification does not return a valid intent name, the method returns a fallback response such as a rephrase request.
  • The selected intent is loaded through _get_intent_details(...) and stored as intent_data.

2. Optional AI-Generated Intent Execution

If the intent is marked with aiGenExecution and has a description, the method can dynamically generate execution details by calling _execute_ai_generated_code(...). This allows the intent to be assembled from the description when predefined configuration is incomplete.

3. Intent Context Setup

The method populates the runtime context from the resolved intent, including:

  • intent_type
  • privacy
  • actionKey
  • deliveryMethod
  • language
  • inputVars
  • contextFlow
  • actionFlow

These values are stored in the session variable dictionary and the instance state so downstream steps can use them consistently.

4. Input-Intent Handling

The implementation now handles input-driven intents in a more explicit way:

  • For non-input intents, the method can reset variables flagged for reset and attempt to fill required input slots using _input_variable_filler(...).
  • For input intents, the incoming user input is stored in the configured action variable, including special handling for phone numbers and loop-style input flows.
  • If the intent was triggered as a follow-up from a previous intent, the method restores the original intent context so the parent workflow can continue naturally.
  • The method also supports loop-based input flows using loop_init:, loop_next:, and loop: hints from the expected input context.

5. Required Input Collection

The method now uses a centralized helper, _collect_required_inputs(...), to validate missing variables.

  • Required variables are normalized through _normalize_intent_vars(...).
  • The helper extracts leaf keys through _extract_required_input_keys(...).
  • If required inputs are still missing, the method pauses and returns a prompt message rather than continuing prematurely.

6. Preprocessing

If no final response has been set yet, the intent’s preprocess flow is executed through _process_routing(...).

7. Privacy and Authorization

If the resolved intent is private or highly private and the user is not already authorized, the method performs the privacy flow.

  • It normalizes the phone number and checks the configured privacy action or journey-based authentication path.
  • If the user is not enrolled, it triggers enrollment logic and returns the resulting message.
  • If authentication is pending or fails, that response becomes the final output.

8. Fixed, Action, and Generic Intent Handling

If no response has been produced yet, the method evaluates the intent type:

  • fixed: renders the configured fixed response template.
  • action: standardizes the intent action and then handles one of the following:
  • journey
  • transfer
  • generic action flow
  • For generic actions, the action response message takes precedence; otherwise the routed action response is used.

9. Subprompt and Subprocess Execution

If no response has been set yet, the method executes the intent’s subprompt and subprocess flows.

  • Subprompt responses are handled through _run_prompt_action(...).
  • Subprocess flows are executed through _process_routing(...).

10. Final Prompt Execution

If the intent has a final prompt configuration, the method iterates through the final prompt items and executes them in order.

Supported item types include:

  • prompt
  • mcp
  • a2a

The first successful response from those steps is used as the final response.

11. Final Processing

The intent’s finalprocess stage is executed after the earlier stages, except when an expected input is still active. This gives the workflow a last chance to write data, deliver side effects, or transform the final response before it is returned.


Live Agent Mode

When transfer_requested is true, the method switches to live-agent mode.

  • If the gRPC stub is connected, the message is sent to the live agent.
  • The method returns a placeholder response: “Message sent to live agent. Waiting for reply…”.
  • If the stub is unavailable, it returns an error message and logs a warning.

Chat History and Return

If a final response exists, it is appended to self.chat_messages as an assistant message and then returned to the caller.


Key Internal Components

  • var: The session variable store used throughout the conversation.
  • final_response: The output value that is eventually returned.
  • next_intent: Allows a previously selected follow-up intent to be processed without reclassification.
  • transfer_requested: Switches the method into live-agent mode.
  • privacy_level: Controls whether privacy enforcement or authentication is required.
  • class_intent_data and class_message: Preserve the original intent context when an input-follow-up flow resumes.
  • _process_routing: Central executor for preprocess, subprocess, action-flow, and finalprocess steps.
  • _collect_required_inputs: Centralizes input-slot validation and prompting.

Intent Flow Diagram

graph TD
    A["Start: process_user_input"] --> B{Transfer requested?}
    B -- No --> C[Classify or reuse next intent]
    C --> D[Load intent context]
    D --> E{Input intent?}
    E -- Yes --> E1[Capture input and restore prior intent context]
    E -- No --> E2[Prepare normal intent flow]
    E1 --> F[Collect missing required inputs]
    E2 --> F
    F --> G{Waiting for inputs?}
    G -- Yes --> H[Return prompt and stop]
    G -- No --> I[Run preprocess]
    I --> J{Privacy required?}
    J -- Yes --> K[Run privacy/auth flow]
    J -- No --> L[Run fixed/action/subprompt/subprocess/final prompt steps]
    K --> L
    L --> M[Run finalprocess unless input is still expected]
    M --> N[Append assistant response and return]

    B -- Yes --> O[Send message via gRPC]
    O --> P[Return transfer placeholder response]
    P --> N

This updated flow reflects the current implementation in the client library, including input-slot collection, dynamic intent execution, privacy handling, and final processing behavior.