Skip to main content
Version: Latest
Technical ManualLooking for step-by-step instructions? In the User Manual: Automate AI Conversations with Workflows

AI Conversations and Workflows

Website chats, automated text threads and AI phone calls are all AI conversations. This page describes how code and workflows take part in them. How to build the workflows in the admin is in the User Manual under Automate AI conversations.

The conversation scope​

AIConversationScope (in CrestApps.OrchardCore.AI.Core.Conversations) holds the AIConversationContext of the conversation the current code runs for. It flows with the async call, so a tool the model calls, the system message rendered while the request is built, and a workflow a tool starts all read the same conversation.

PropertyMeaning
ChannelChat, Sms, Phone or Email (AIConversationChannels)
DirectionInbound or Outbound (AIConversationDirections)
SessionThe AIChatSession, when it exists
ProfileThe AIProfile answering
ActivityIdThe omnichannel activity, for calls and texts
ContactThe contact content item, when known
CustomerAddress, BusinessAddressThe customer's number and ours
ValuesExtra template values: Activity, Subject, Campaign, Endpoint

Text threads and phone calls (both the turn-based engine and the realtime engine) begin a scope for each turn or call with IOmnichannelConversationContextFactory. A website or admin chat has no channel scope; AIConversationScope.Resolve() then describes it from the chat session in AIInvocationScope.

Conversation variables​

Variables are text values kept on the session as AIConversationVariablesMetadata. Before a session exists (an outbound call not yet dialed), they are kept on the activity and carried into the conversation from there.

session.SetConversationVariable("tier", "gold");
var tier = session.GetConversationVariables()["tier"];

They are set by the Set Conversation Variables task, by a starting handler, by the Create AI Activity task and by data extraction (each extracted field is also stored as a variable).

Liquid in the system message​

AIConversationLiquidCompletionContextBuilderHandler renders the composed system message as Liquid when it contains Liquid markup. The template values are Variables, Conversation (an AIConversationTemplateModel), Session, Profile, Contact and each entry of Values. A template that fails to render is logged and used as written.

Tools on automated conversations​

Automated text threads and turn-based calls call the completion service directly. AIConversationTools.AttachAsync gives them the profile's tools from IToolRegistry (tools, tool instances, MCP connections and agents) plus the channel's system tools (end call, transfer to a person), the same set the orchestrator offers a chat.

AIConversationToolParameterContextResolver fills tool-instance parameters bound to these context keys:

KeyValue
conversation.channel, conversation.direction, conversation.session_idThe conversation
conversation.customer_address, conversation.business_addressThe customer's number and ours
activity.id, contact.id, contact.nameThe records the conversation is about
variables.<name>Any conversation variable

On turn-based calls, AIConversationTools.LimitRunTime wraps every tool but the system tools in a TimeLimitedAIFunction. A tool gets 8 seconds (AIConversationTools.DefaultCallToolTimeout) unless its function sets the CrestApps.TimeoutSeconds additional property (TimeLimitedAIFunction.TimeoutSecondsProperty; zero means no limit). When the limit passes, the tool's token is cancelled and the model receives a result telling it the tool did not answer, so it can tell the caller. When a tool runs longer than 1.5 seconds, the caller hears one short filler line per turn ("One moment, please.", in the call's language), and the end of that line does not restart listening.

Before the conversation starts​

IAIConversationStartingService runs every IAIConversationStartingHandler before a conversation's first message, within a budget of 3 seconds for inbound conversations and 30 seconds for outbound ones. Each handler adds to an AIConversationStartingResult: Variables, a ProfileId, or Declined with a DeclineReason. Failures and timeouts are logged and the conversation starts anyway.

It runs for inbound AI calls before the call is answered, inbound texts to an AI number before the conversation is created, automated activities before they are placed (by the background pass and by Place Call or Send Message), and website chats before their first answer (variables only).

The Workflows feature registers a handler that triggers the AI Conversation Starting event (AIConversationStartingEvent). Its tasks write to the result in Workflow.Input.StartingResult.

Workflow tools​

The Workflow tool-instance source (WorkflowToolConstants.SourceName) runs a workflow type that starts with the AI Tool Called event (AIToolCalledEvent). The function:

  1. resolves the instance's declared parameters with AIToolParameterBinder (an instance without parameters exposes one request string);
  2. starts the workflow in the current request with IWorkflowManager.StartWorkflowAsync, correlated to the session;
  3. sets CrestApps.TimeoutSeconds from the instance's Time limit on calls (WorkflowToolSettings.TimeoutSeconds), when set;
  4. returns the workflow's Output as JSON, {"status":"accepted"} when the workflow halted on a blocking activity, or {"status":"error","message":...} when it faulted.

Workflow input​

Every AI conversation workflow receives AIConversationWorkflowInput.Build(conversation):

KeyValue
Channel, Direction, SessionId, ProfileId, ActivityIdThe conversation
ContactId, ContactName, ContactThe contact
CustomerAddress, BusinessAddressThe numbers
VariablesThe conversation variables
Arguments, ToolNameAI Tool Called only
StartingResultAI Conversation Starting only

The AI session events (Field Extracted, Closed, Post-Processed) also carry Variables, and Closed and Post-Processed carry Transcript (one Customer: or Assistant: line per turn) and Turns (AIConversationTurn records), built by AIConversationTranscript.