Skip to content

Conversation History Context & Dynamic Variable Memory ​

Two independent, per-agent features that give a voice agent memory of a contact's earlier calls: Conversation History Context (injects past conversation summaries into the agent's context) and Dynamic Variable Memory (reuses variables such as the caller's name captured on previous outbound calls). Both are OFF by default and fully optional.

Terminology

  • contactUID: identifier of a single call record in the Contact collection. A number called multiple times produces multiple records.
  • conversation_summary: a 3–4 sentence summary of a call produced by the Analysis service and stored on the Contact record.
  • dynamicVariables: per-contact template values (e.g. { name: "Daivik" }) used to render greetings/prompts like Hello {{name}}.
  • E.164: international phone format, e.g. +919876543210 (reference).

Architecture Overview ​

How It Works ​

Conversation History Context ​

  1. Trigger: at call start, if history_context_enabled and a phone number is present.
  2. Match: Contact where phone (last-10-digit match) AND AgentID ∈ {current} ∪ linkedAgentIds, with a non-empty conversation_summary whose call time is within the configured window.
  3. Select: dedup by contactUID (latest per contact), take the most recent maxConversations (1–10), order oldest → newest.
  4. Inject: append a labeled block to agent_meta.Context (knowledge base is preserved, never overwritten). Per-call only; nothing is persisted back.

Dynamic Variable Memory ​

  1. Trigger: at call start, if variable_memory_enabled and a phone number is present.
  2. Match: latest Contact where phone matches AND AgentID ∈ {current} ∪ {variableMemory.linkedAgentId} AND callDirection == "outbound" AND dynamicVariables is non-empty.
  3. Merge: fill only missing/empty keys in the call's dynamic_values (explicit live/campaign values always win). Applied before the greeting is rendered.

Why outbound-only? Only outbound calls carry dynamicVariables. Sourcing exclusively from outbound calls means repeated inbound calls always reach back to the originating outbound call rather than a prior variable-less inbound call so no write-back/persistence is needed and the chain never degrades.

Call-type behavior ​

  • Outbound: has its own variables; memory only fills gaps. History applied before the assistant is built.
  • Inbound: caller phone is only known inside InboundCallHandler, so both features are applied there (before the greeting) and the live session agent is rebuilt.
  • Web: no phone number → neither feature finds anything (no-op).

File Reference ​

FileRoleKey items
backend/Agent/src/schemas/agent_meta_schema.pyRuntime settingshistory_context_*, variable_memory_* fields
backend/Agent/src/services/conversation_history.pyCore logicresolve_history_block, resolve_remembered_variables, maybe_apply_history_context, maybe_apply_variable_memory, _phone_last10, _agent_id_set
backend/Agent/agent.pyEntry point wiring (outbound/web)applies both before VoiceAssistant
backend/Agent/src/handlers/inbound_call_handler.pyInbound wiringapplies both after caller phone resolved; rebuilds session agent
backend/Agent/src/handlers/call_handler.pyHandoff wiringapplies both on agent handoff
backend/client_backend/src/models/Agent.tsMongoose schemahistoryContext sub-document
backend/client_backend/src/types/index.tsTypesIHistoryContext, IVariableMemory
backend/client_backend/src/utils/dispatch.utils.tsValidate + flattenvalidateHistoryContext, buildHistoryContextConfig
backend/client_backend/src/controllers/agent.controller.tsAPIvalidateLinkedAgentOwnership on create/update
app/src/components/features/HistoryContextSettings.tsxUItwo independent sections
app/src/types/campaign.ts, app/src/lib/agentFormUtils.tsFE types/defaultsHistoryContext, VariableMemory

Data Model ​

Stored on the Agent document as historyContext:

historyContext:
  enabled: boolean                 # history feature (default false)
  maxConversations: number         # 1..10 (default 5)
  window:
    type: "days"|"weeks"|"months"|"quarters"|"years"|"custom"  # default "months"
    value: number                  # default 1
    startDate: Date | null         # only for type="custom", ≤ 1 year ago
  linkedAgentIds: string[]         # extra agents whose history is pooled
  variableMemory:                  # independent sub-feature
    enabled: boolean               # default false
    linkedAgentId: string | null   # a SINGLE extra agent

Flattened into agent_config for the Agent runtime: history_context_enabled, history_context_max, history_context_window_type, history_context_window_value, history_context_window_start, history_context_linked_agent_ids, variable_memory_enabled, variable_memory_linked_agent_id.

Read from Contact: phone / originalPhone, AgentID, callDirection, conversation_summary, dynamicVariables, callStartedAt / createdAt.

API Endpoints ​

Handled by the existing agent endpoints (no new routes):

  • Create: POST /api/v2/agents accepts historyContext; validates ranges and linked-agent ownership.
  • Update: PUT /api/v2/agents/:agentId same validation.

Validation rejects: maxConversations outside 1–10; custom startDate in the future or > 1 year ago; non-array linkedAgentIds; non-string variableMemory.linkedAgentId; and any linked agent not owned by the requester.

How to Test (End-to-End) ​

Prerequisites: an agent, a phone number, and a contact with a completed conversation_summary (let the Analysis service finish after a prior call).

  1. In the agent editor, enable Use previous conversation history (set max + window; optionally link the outbound agent). Optionally enable Remember caller details and pick a linked agent. Save.
  2. Place an outbound call to a number, converse, and hang up. Wait for analysis to store conversation_summary and confirm the contact has dynamicVariables (e.g. name).
  3. Call the inbound number from the same phone. Verify in the Agent logs:
    • Injecting N prior conversation summary(ies) into agent Context.
    • Applied N remembered dynamic variable(s) from prior calls. (if variable memory is on and the greeting uses {{name}}).
  4. Confirm the greeting renders the remembered name and the agent references prior context. Confirm the knowledge base text in Context is unchanged (history is appended under ## Previous Conversation History with This Contact).

Troubleshooting ​

SymptomCauseFix
Log: No eligible conversation history foundPrior call's summary not generated yet, or outside windowWait for analysis to finish; widen the window
Log: No usable phone number for history lookupWeb call or missing caller numberExpected for web; for phone calls verify SIP caller number
Greeting still shows raw {{name}}Variable memory off, first-time caller, or no prior outbound contact with variablesEnable variable memory; ensure a prior outbound call captured the variable
Inbound doesn't match outbound (different agents)Agents not linkedAdd the outbound agent to the inbound agent's linked list (history and/or variable)
Save rejected: "Invalid linked agents"A linked agent id isn't owned by the customerOnly link your own agents

Changelog ​

  • Initial: conversation history context (per phone + agent, windowed, top-N, appended to Context).
  • Enhancement: linked agents (pool history across agents), and Dynamic Variable Memory (single linked agent, outbound-only source, fills only missing keys).

Last updated: