Skip to content

Takeda native Salesforce workflows

Status: Current | Last reviewed: 2026-10-20

Use this reference to edit and review the native replacement for agent 4463's call-start, patient-save and call-finish actions. Queries, Salesforce writes, validation, summary formatting and branching live in published workflow configuration. The replacement graphs contain no MCP Action or sandboxed Code nodes.

Hosting and version ownership

The graphs run in async-agent. Its native Salesforce nodes use the TrueServe Dev SDO connection (f28f65a9-0598-47df-8d08-77f7282a8f09) and the connection's JWT credentials. The current connection uses API v62.0; Composite subrequest paths use that same version. A different subrequest version can return NOT_FOUND and roll back the transaction.

The retired active path was async-agent → takeda_genesys_call_actions → ai-manager /api/mcp/takeda → Salesforce. The MCP endpoint remains available for older workflow versions and legacy workflow 1855. Its implementation and earlier audit are documented in call action logic and field mappings.

Native workflow definitions build the three graphs. JSONata source files are embedded in their Assignment configuration when generated; runtime does not read those repository files. Publishing a workflow therefore pins its queries, field mappings and summary expression. Editing the repository alone does not change a published graph.

Published configuration

Vanguard currently uses 1856:v6 (start), 1918:v3 (patient save) and 1857:v9 (finish). The October 12 summary-expression repair published the patient and finish versions together, retaining agent 4463:v33 and its record/escalate wrapper tools. The legacy MCP is no longer in these three active graphs. See caller selection and qualification for the separate voice releases.

The October 20 naming update advances the agent to 4463:v34. Its patient actions are clearway_record_patient_receipt and clearway_escalate_patient_receipt. They retain the same schemas, parameter bindings and workflow 1918 target. The release changes only the two tool references and names in prompts, tool logic and the accepted-handoff trigger. Existing unpublished prompt edits remain in the draft. Earlier agent versions retain their original tool records and configuration.

The revision is installed by rename-clearway-actions.ts. Run it through the devcontainer environment loader from apps/ai-manager. The default runs native release validation inside a rolled-back transaction; --apply saves pending collaboration edits, publishes the naming-only revision, restores the edited draft and refreshes the collaboration/tool-reference caches. Private before/after evidence is written beneath apps/ai-manager/.local-data/clearway-action-names/.

Find each mapping in Studio

Open the workflow, create or edit its draft, enter its serialized subworkflow, and select the named node. Salesforce Composite requests accepts a JSON request array or a whole JSONata expression that returns an array. Expressions inside request bodies retain object, number and boolean types.

Workflow / node Values you control
Start 1856 / normalize Permitted tenant, agent, called number, conversation UUID and external-key prefix
Start / lookup, coordinator ANI comparison and fallback coordinator Account
Start / records_transaction → create_records Parent RecordTypeId, Subject, Reason, Status, Origin, Priority, AccountId, ContactId; Task Subject, Type, CallType, Status, Priority, WhatId, WhoId, CallObject and external keys
Start / enrollees, roster Care-program selection, roster limit, Account sorting and stable p1, p2 references
Start / patient_requests → request Latest CareRequest query and concurrent request limit
Start / source_cases, ready Historical Case/activity query, patient facts and returned context
Patient 1918 / patient_transaction → plan_patient Accepted dispositions, monotonic rank, status/description wording, identity checks and caller-acceptance requirement
Patient / save_patient Child Case fields, patient/source links and parent HTML destination
Patient and finish / render_summary HTML structure, badge text/colors, coaching and handoff wording
Finish 1857 / jobs Background-job marker, legacy workflow IDs and maximum wait
Finish / finish_transaction → plan_finish Parent closure rule, Task state, plain summary and ending reason
Finish / finish_records Task Description/Status and parent HTML/Status destinations
Finish / link_voice VoiceCall parent link, 255-character summary, ending reason and coordinator display name
Each workflow / output parameters Values returned to the lifecycle or patient tool

Changing a destination also requires reviewing its readback query and assertion. A mapping that writes a different field but still checks the old field must not be published as successful.

Salesforce-owned Case titles

The workflow supplies an initial Subject, but Salesforce overwrites the displayed parent and child titles. The final readback confirmed CaseNumber - Origin - Reason label, for example 00022894 - Voice - Multi-Patient Access Review. This is existing org behavior, not a failed native write.

Control it in Salesforce Setup → Flows → DCC_Construct_and_update_Case_subject, formula caseSubject. Active flows DCC_Update_Case_Subject (Case after-save) and DCC_Update_case_subject_on_task_update invoke that subflow. Changing only the workflow's Subject mapping will not override this automation.

The formula uses the Reason's display label. Other uses Task DCC_Activity_Type_Detail__c when present, otherwise Other. The org also has an outbound title variant for Account 001DW00001Zors8YAB and excludes RecordType 012DW000003lfE3YAI from the subject update. The configured Takeda coordinator/patients and parent record type use the normal title branch. These Salesforce flows were inspected through Tooling API and were not modified.

Start call logic

  1. Validate the bound tenant, agent 4463, called number and original Genesys conversation UUID. Normalize ANI to ten digits when it has a US country prefix.
  2. Query candidate person Accounts and the configured fallback. Use one exact normalized ANI match; reject ambiguous matches; otherwise use Denise's configured Account.
  3. Acquire the tenant/call serialization lock. Find the parent by its unique external key. Reject incompatible, duplicate or closed parents.
  4. Create a missing parent and inbound Task in one Salesforce Composite transaction with allOrNone=true. If an existing compatible parent has no Task, recover the Task through its unique external key. Read the parent and Task back and validate their relationship and identity.
  5. Release the lock. Load and deduplicate the coordinator's care-program patients, sort by Account ID and bind per-call patient references. Read the latest request for each patient with concurrency four, then the linked historical Cases and recent activities.
  6. Return the same five lifecycle outputs: context_status, coordinator_first_name, patient_brief, call_context, transfer_params.

The parent represents this call. Historical requests and source Cases supply context and are never mutated. Initial transfer parameters still describe startup state; they are not a live rollup of later background saves.

Save patient logic

  1. Validate the host-bound conversation and context. Acquire the call lock and reread the parent, Task and children.
  2. Verify every existing child belongs to the bound roster and has consistent links, reason and status flags. Resolve the requested patientRef to one Account. Require explicit handoffAccepted=true for escalation.
  3. Apply monotonic progression: discussed → completed → escalated. A late discussed save cannot reopen completed work or undo an accepted escalation.
  4. Render HTML from the proposed verified children. Atomically create/update the patient's child and update the parent HTML. If the outcome already matches, repair stale HTML only when needed.
  5. Reread Salesforce. Return verified=true only when child state, relationships and parent HTML match. An exact retry on a closed parent is allowed; a new outcome on a closed parent is rejected.

A network error after Salesforce commits is reconciled by readback. An atomic failure cannot return verified success. The client does not blindly retry uncertain writes.

Finish call logic

  1. Wait up to 30 seconds for this tenant/conversation's marked patient saves and legacy workflow 1855 executions. Completed jobs without verified=true count as unverified. This wait occurs outside the call lock so saves can finish.
  2. Acquire the lock and reread the call records. Validate every child before writing anything. Rebuild both HTML and the plain Task summary from saved child states.
  3. Keep unfinished inquiry Cases open. The finalizer never closes a child. Close the parent and complete the Task only when the end explicitly says session_escalated=false, every saved child is closed, and no pending, failed or unverified save remains. An accepted escalation, disconnect without explicit completion, or unfinished child keeps the parent open. A parent already completed retains its completed Task on retry.
  4. Atomically save Task and parent fields, then read them back. Repeated finalization can repair summaries and does not require the parent to remain open.
  5. Find the Genesys VoiceCall by the original conversation UUID. Retry an empty lookup four times with 1/2/4-second waits. Reject ambiguous matches or a conflicting existing parent link. Write and read back all four mapped fields.

If no parent exists, return a reason without creating records. If the VoiceCall is still absent after retries, return linked=false and a reason; this is not evidence that linking succeeded. Pending or failed job counts remain visible in outputs and the Task summary. A delayed save can still complete while its parent remains open; automatic re-finalization after that delayed save is not added by this migration.

Generic runtime additions

These capabilities are reusable and contain no Takeda field mappings:

  • Salesforce Composite: 1–25 GET/POST/PATCH requests, data-resource paths only, unique reference IDs, atomic writes by default, and explicit checking of every subresponse. See client and node.
  • Serialized subworkflow: PostgreSQL transaction advisory lock scoped by tenant and rendered key. Waiters release their connection before sleeping. Only an inline graph of supported non-suspending nodes is allowed; Wait, nested locks and Salesforce Bulk queries are rejected. The lock wait is bounded; graph execution remains subject to the caller's timeout. See serialization.
  • Strict Assignment: fail_on_error=true makes assertion/expression errors fail the workflow instead of assigning None.
  • Background workflow status: tenant/conversation-scoped job lookup with optional bounded polling and separate pending/unverified counts. See node.

Native transactions require the updated async-agent runtime before these workflow versions are published. Ordinary field or expression changes after that are workflow configuration changes.

Qualification and performance

Qualification uses the actual graph builder and native handlers, a transactional Salesforce test fixture for injected failures, and synthetic call records in the configured Salesforce sandbox. The live comparison executes the previous MCP graphs and the candidate native graphs from the same host. Timings include Salesforce calls and expression evaluation; they are small-sample observations, not an SLA or a phone-audio latency measurement.

The final checks passed:

  • 15 graph scenarios, including rollback, acknowledgement loss, concurrent saves, monotonic outcomes, one-patient rosters, foreign children, conflicting VoiceCalls, failed/pending saves, disconnects and repeat finalization. Summary HTML matches the earlier renderer for zero/one/multiple verified patients, including escaped names.
  • Real Salesforce completed, unfinished/disconnected and escalated calls. Parent/child/Task/VoiceCall readback passed; historical source Cases were unchanged. A separate full-field comparison confirmed record types, priorities, reasons, external keys and all parent/patient/source links, with the Salesforce-owned title transformation accounted for.
  • Published API startup, three simultaneous broker saves, immediate queued finalization, and repeat finalization. All four broker jobs completed on versions 2/8, with zero pending or failed updates at completion and a closed parent containing the three completed children.
  • The queue check exposed a pre-existing race during concurrent first-use checkpoint initialization. A shared initialization lock and regression test now prevent one job from closing another job's checkpoint connection. The final queue check passed after a fresh runtime restart.
  • Schema/graph validation, TypeScript type checking and targeted lint passed. Existing lint/deprecation warnings remain outside the changed behavior. Publishing preserved both separately authored wrapper tools in a real database check.
Measurement Previous MCP graphs Final native graphs
Start, three calls 3.97–6.58 s 4.29–6.44 s
Serial new-child saves 2.38–3.89 s (nine saves) 2.48–3.05 s (four saves)
Finalization 2.78–3.39 s (three calls) 3.26–3.55 s (four runs, including retry)

Native finalization adds field readback that the old finalizer lacked, so this is not a uniform speedup. It keeps CRM work out of the live voice turn: the published API accepted patient jobs in 11–118 ms; its synchronous startup completed in 5.84 s, within the configured 45-second startup timeout. Concurrent writes for the same call intentionally wait for the call lock (one measured save took 5.93 s including that wait). In the published queue test, three same-call jobs finished in 3.07/5.73/8.66 seconds and the finalizer in 12.35 seconds including its wait. The earlier sandboxed-renderer candidate was replaced with native expressions before final qualification.

These are small sandbox samples, not a load-test SLA. Phone audio and carrier routing were not changed or replayed in this migration; the published agent's preflight passed with no errors or warnings. Private record-level evidence is stored under .local-data/takeda-demo/native-migration-2026-10-07/; it is not committed.

October 12 summary-expression repair

The Vanguard call at 10:13 AM Eastern exposed S0202: Expected ")", got "," in render_summary. All four patient-save jobs (1918:v2) and conversation end (1857:v8) failed. Startup succeeded, so the human handoff had the call identity but no saved patient outcomes.

The shared native/summary.jsonata expression contained an extra backslash before embedded double quotes. It relied on the Python binding consuming that escape. The October 8 runtime correction now preserves authored JSONata characters, exposing this invalid expression. Store ordinary JSONata escapes in the source and published graph; workflow_expressions.py alone owns the binding's JavaScript transport escaping. Do not remove that runtime protection.

The correction changes only the render_summary Assignment expression in the patient-save and finish-call graphs. Published versions 1918:v3 and 1857:v9 contain that correction. All 15 native graph tests passed, including HTML escaping, retries, concurrent saves, unfinished calls, escalation, and VoiceCall linking. Three synthetic Salesforce scenarios verified completed, unfinished and escalated records, including repeated finalization and unchanged historical source Cases. After publication, the running service accepted three concurrent patient saves and immediate finalization; all four broker jobs completed on versions 3/9 with verified outputs, zero pending or failed updates, and successful Salesforce readback. Repeated finalization also passed. A fresh phone-to-human acceptance call remains separate from these backend checks. Private release evidence and configuration backups are under .local-data/takeda-demo/conversation-end-2026-10-12/.

Publishing corrected versions does not replay failed patient saves or repair historical call records. A failed call requires its own reviewed recovery.

Review and rollback

Back up published graphs and drafts before release. Validate schemas and graph structure, qualify the exact candidate, then publish all three workflow versions in one database transaction. Keep agent 4463 and its tool bindings unchanged. Publishing API-triggered graphs preserves independently authored workflow wrapper tools; trigger synchronization removes only registrations owned by an Agent Tool trigger, identified by their registration marker or version history. Check the published versions through the service API and background execution history.

Migration rollback uses the saved pre-native versions (1856:v5, 1918:v1, 1857:v7). It restores the old finalizer's behavior, including its automatic closure of New child Cases, so review that consequence before reverting. The native versions 1918:v2 and 1857:v8 contain the invalid escaping and must not be restored on the corrected runtime. Restoring workflow configuration does not undo Salesforce records written during qualification or live calls.