Takeda Voice Agent and native Salesforce Copilot demo¶
Status: Current | Last reviewed: 2026-10-20
For the Genesys AI route, use native Salesforce workflows for the published mapping controls, action logic, completion rule and qualification results. The earlier MCP action reference and field mapping audit remain useful for legacy versions.
Agent 4463, Clearway Support, uses Clearway action names in AI Activity
from version 34: clearway_record_patient_receipt and
clearway_escalate_patient_receipt. See the
naming update for release
ownership and preservation of unpublished edits.
Separate Genesys backup number¶
+1 833 629 4816 routes to Takeda Clearway — Direct Queue Backup in the TrueServe division. Its destination is TrueServe-dev Inbound Queue. The normal +1 804 413 6534 route and agent 4463 remain separate. Use a regular telephone for this backup: dialing it through Telephony Preview still uses Preview's browser, Janus and Asterisk audio path.
Published flow: d04ac70f-f8f8-4a93-ad43-37101dd2f753, version 2.0.
IVR: 7cceeb68-279a-4c83-8c1a-51a680aa43ea. The Read Scenario Data Action
is custom_-_463a8f8b-87c9-4872-a8da-483c600caa52; Create Scenario is
custom_-_9446f7a3-028b-4831-ab39-ea01dddfcd55, both version 1.
The definition is maintained in
apps/ai-manager/scripts/takeda-demo/genesys-backup-definition.ts. Two Genesys
Salesforce Data Actions prepare an explicitly labeled demo fixture directly in
DevSDO, without an AI AudioConnector or a TrueServe case-creation endpoint:
| Record | Initial state |
|---|---|
| Denise's parent Case | New; MultiPatientAccessReview; both Customer Intents |
| Thomas Whitfield's child Case | Closed; StepTherapyAppeal; September 28 approval |
| Ashley Kowalski's child Case | Escalated; PriorAuthorizationFollowUp; September 1 policy/documentation follow-up |
| Inbound Voice Task | In Progress; Denise Contact; parent Case; Genesys conversation ID |
The patient Cases link to both their new parent and their existing CareRequest and source Case. Historical requests and payer submissions are not modified. The summary identifies the prepared scenario; it does not invent a self-service transcript. The parent remains open for the human representative; normal wrap-up proposes Closed when the representative completes the interaction.
The flow first reads all four records by their exact
takeda:<tenant>:genesys:<conversation-id>:<suffix> external keys. Missing
records trigger a single Salesforce Composite transaction with allOrNone.
Every create outcome, including timeout, leads to another read. Existing unique
external IDs prevent duplicate creation; retries never overwrite a completed
Case. Output validation requires all four IDs. An unverified transaction still
routes to the queue with BackupRecordStatus=unavailable and an explicit
record-setup error, without passing unverified Case IDs.
Successful handoff supplies CaseId, parentCaseId, ActivityId,
childCaseIds, escalatedCaseId, Denise's name/account, reason and summary.
It retains human Agent Assist audio monitoring and the existing queue transfer.
The Utility recovery uses the same external-key format to recover the assigned
VoiceCall and parent if the Genesys/Salesforce call creation request times out.
Genesys's Salesforce connection uses TrueServe Self-Service. Assign
Takeda_Backup_Case_Links to that integration user: this permission set grants
read/edit access only to Case.Takeda_Request__c and
Case.Takeda_Source_Case__c, supplementing the connection's existing access.
Without those permissions, Salesforce rolls the composite transaction back.
Before assigning the number, validate both Data Actions, test creation and
duplicate/retry behavior against Salesforce, independently read back all records,
and validate/publish the new flow with the Architect SDK. Recheck that the number
is unassigned before creating its IVR route. Keep provider responses and test
record IDs in private .local-data/takeda-demo/backup-route-2026-10-06/.
Record tests and flow validation do not replace a phone-to-human acceptance
test for audio, Omni caller details and the accepted VoiceCall/Case tabs.
Genesys timeout fallback recovery¶
Genesys can time out creating the Salesforce VoiceCall even though Salesforce
eventually commits it. Its call-resiliency path may create a second VoiceCall
with the same VendorCallKey. In the October 6 incident, the original carried
the caller and parent Case attributes while Omni assigned the empty fallback.
The console subsequently reported VOICECALL_WORK_NOT_FOUND. The parent and
both patient Cases already existed; creating another Case would compound the
problem.
Clear Connect's existing eager Utility item (DCC_UtilityContainer) loads
takedaGenesysRecovery only for the custom permission in Takeda_Clearway_Demo.
Other users retain the existing utility behavior. It listens to Omni assignment, acceptance and closure,
and checks current work when mounted after a console refresh. Assignment
recovers missing context; acceptance opens the assigned VoiceCall and its
existing Case as a subtab. Only one repair and one successful pop run per work
item. Retry delays total at most fifteen seconds; closed work cannot cause a
late pop. Failed repair or navigation exposes Retry call details in Utility.
TakedaGenesysHandoffRecovery requires an AgentWork belonging to the current
user and the requested VoiceCall. It parses only the complete Genesys inbound
key, finds the parent by its exact tenant/conversation external key, and fills
missing VoiceCall fields with user-mode reads and writes. It never chooses a
VoiceCall by latest timestamp or caller phone. An explicit different Case link
is preserved. An interaction Task must match both its external key and
CallObject; missing Tasks do not prevent the existing Case from opening.
Patient names and Case Reason come from saved records. Legacy reason labels
resolve to an active VoiceCall picklist value; an unmapped value is not written
to that restricted field and does not prevent the existing Case from opening.
This component does not change media routing or the vendor's duplicate-record selection. Retain the Genesys timeout correlation ID for provider diagnosis. Controlled rollback inserts during this investigation completed well below the observed gateway timeout, so the timeout's upstream cause was not reproduced. A subsequent beeping call had one correctly linked VoiceCall, demonstrating why record recovery and media diagnosis need separate evidence.
Deploy both Aura bundles, the recovery Apex class and test, its custom permission and class access
in Takeda_Clearway_Demo; retrieve shared source first. Validate the Apex suite
and node --test sfdc/takeda-demo/test/genesys-recovery.test.cjs. Isolated Apex
tests supply immutable AgentWork fixtures because creating work requires a live
Omni presence session. They still perform actual test-transaction VoiceCall,
Case and Task DML. A real-call check must verify the accepted work item,
representative permissions, refreshed Omni details and the resulting tabs.
Genesys caller identity and Salesforce embeds¶
October 6 script and human wrap-up correction¶
The 10:47 AM Eastern test (44cb9973-78b1-42a4-b268-649a12b3325f)
repeated the completed appeal and explained the authorization criteria before
the caller asked. The revised conversation separates these turns: identify the
unique recorded appeal, speak its approval date, finish its inquiry, give the
next patient's short status, explain the recorded policy change on the next
question, then acknowledge frustration and offer a case manager. Acceptance
gets one closing: “Thank you. I’ll connect you now.” Patient identity and facts
remain roster-driven. Tool calls are silent and must not introduce another
spoken answer when their asynchronous acknowledgement arrives.
Version 27, published October 6 at 2:00 PM Eastern, keeps the conversation steps in the backend and removes the duplicate procedural script from the voice instructions. Automatic caller dispatch installs the result reminder once at session start; late answers to an older caller turn remain unspoken when a newer turn has started. Qualification includes the complete two-patient script and a caller interruption, in addition to the runtime tests. Native listening acknowledgements can still occur; the runtime does not guarantee verbatim delivery.
Version 28 assigned the first/next patient questions to the voice layer.
The subsequent native replay exposed a backend decision failure: gpt-4.1-mini
could emit both VOICE_ONLY and an unsolicited patient-record action in the
same response. Stronger waiting instructions alone did not reliably prevent it.
Version 29, published October 7 at 10:02 AM Eastern, gives the backend ownership of all patient questions and actions,
using gpt-5 with delegation_reasoning_effort=medium. The voice reads each
backend answer once and retains brief listening acknowledgements. It never
asks a patient-selection question independently. Native voice, Krisp, SIP and
interruption settings are unchanged. VOICE_ONLY remains the silent final
response for unfinished selections, requests for time or a selection question
already spoken after the latest caller line; it must carry no new patient action.
An identified inquiry gets its record action and answer normally. No patient
names are embedded in these rules. Qualification counts semantic invitations
across the entire caller turn, including speech before and after the backend
completion.
The October 6 candidate missed a completion receipt
on a combined completion/next-patient turn. October 7 checks also exposed
inconsistent question repetition and first-status detail at low reasoning.
The smaller backend also intermittently skipped completion of a patient inquiry
with no historical care request, including in a native replay.
The revised draft makes the opening question conditional on whether it has
already been spoken, preserves both actions on a caller-selected patient change,
and uses the full backend model at medium reasoning. That release published
version 29. Publication checked the exact qualified draft revision and changed
only the patient prompts and decision-backend settings.
The October 7, 9:32 AM Eastern call reproduced the opening failure on version
28: takeda_record_patient_receipt(p2, discussed) ran after the generic
multi-patient request, before the caller supplied a patient. The agent then
started naming that patient over “I lost my notes, but I know…”. The revised
release treats that unfinished phrase as a silent, action-free turn. It also
records both required transitions when the caller finishes one patient and
identifies another in the same utterance. An unknown or ambiguous name gets an
open clarification, never a list of patients from the roster.
Release checks passed: 31 focused unit tests, 15 repeated opening/hesitation
checks, nine backend scenarios, and two native audio replays with Salesforce
readback. The two-patient story and reordered three-patient replay used the same
saved revision, verified no unsolicited patient actions during pauses, completed
each finished inquiry and requested handoff only after acceptance. Three extra
backend repetitions verified the previously missed combined transition.
Configuration backups, rejected candidates and release evidence remain private
under .local-data/takeda-demo/patient-selection-2026-10-07/; the published
candidate and release receipt are in its gpt5/ directory. Published preflight
returned no errors or warnings. These are native-runtime checks, not a fresh
PSTN or human-answer rehearsal.
After updating the draft through a script, refresh its collaborative editor
state and verify the saved configuration before and after the voice replay.
An editor save can otherwise restore older instructions during qualification.
saveRevisionedDraft already calls the tenant-scoped collab reset. Do not
follow it with a room purge: purge is for deletion and closes editor sockets.
An extra purge during this investigation let an old editor snapshot restore
the preceding prompt about twenty seconds after the save. Using the native
reset alone kept the saved text and revision stable across repeated readbacks.
Pin TAKEDA_TEST_EXPECTED_REVISION when rehearsing an authored candidate so a
pre-call reversion fails before another voice session starts.
Controlled patient speech¶
Version 32, published October 7 at 3:03 PM Eastern, uses Deepgram Flux → GPT-5.4 without reasoning → OpenAI GPT-4o Mini TTS (Marin). The patient model owns the complete answer and every selection question; TTS reads that answer directly. Repeated native GPT Live rehearsals showed that prompt-only backchannel changes could still add a question after the backend had selected the right patient, or insert an unfinished clarification before the correct explanation.
cascadedPatientPrompt() adapts the roster backend's question ownership.
It asks for the first patient once, asks for another only after explicit
completion, and keeps the current patient through surprise, explanation,
frustration and thanks. VOICE_ONLY is a silent control response, removed by
the silent-patient-turn response guard before TTS. The Responses stage opts
into deduplicate_response_messages: provider output can contain several
assistant message items, including an answer followed by a silence token.
Preserving those boundaries lets the guard suppress the token, while adjacent
identical complete messages are delivered once.
The conversion preserves the roster tools, bound context, consent-controlled
handoff, lifecycle workflows, turn settings and catalog pin. It removes Live
delegation settings. It does not change Salesforce data or select a patient
at startup. Low reasoning passed the scripted backend checks but failed the
fourth repeated audio call: after the caller hesitated at the next selection,
it silently queued an unrequested patient's discussion. That candidate was
rejected. A GPT-5 medium repeat also silently selected another patient during
an unfinished selection; minimal reasoning failed other qualification checks.
The published configuration pins gpt-5.4-2026-03-05 with reasoning none. It passed
11 backend scenarios and 24 hesitation checks, including the unpunctuated
transcript “The next one is.” The seven-turn backend script's median was
1,657 ms, compared with 4,474 ms for GPT-5 medium; these are individual
scripted observations, not telephone latency guarantees.
All four full native audio calls passed on the same saved revision: both the
three-patient ordering scenario and the appeal-to-authorization response-flow
scenario, each with two caller voices and two concurrent calls. Each also passed
independent semantic review. The checks verified quiet unfinished selections,
one next-patient question after explicit completion, no overlapping or duplicate
answers, consent before handoff and actual Salesforce child records. The release
gate pinned the tested configuration, runtime, harness and reviewer before
publication. With a ten-second startup preparation lead, opening audio began
in 3.0–4.9 seconds. Across 26 spoken exchanges, response audio began a median
3.2 seconds after the caller finished (range 1.1–5.6 seconds). No overlapping
audio frames or response-style failures were recorded. These audio replays
exclude Genesys welcome and PSTN connection time and do not certify a human
answering the transfer. Evidence is retained privately under
.local-data/takeda-demo/response-flow-2026-10-07/.
Fresh published replay a3100afd-dfa7-4875-bf9f-7e8b979ad404 also passed the
complete response-flow scenario, with both patient records verified and an
accepted handoff. Its conversation record confirms config_version=32.
Opening audio began in 2.4 seconds with the same preparation lead.
Version 33, published through Studio on October 7 at 3:18 PM Eastern,
changes the speech stage to ElevenLabs HTTP Streaming (eleven_v4_turbo).
It preserves the patient model, prompt and workflows. The qualification
results above apply to version 32's Marin speech stage. Both versions remain
available in the toolbar's version picker for inspection.
The October 7 19:38 UTC test reached accepted handoff, but ElevenLabs HTTP
raised a lifecycle method-signature error after the closing line and blocked
the end signal. The runtime fix preserves Pipecat's stop dispatcher and closes
the HTTP client after audio drains; it changes no agent configuration.
A fresh full audio rehearsal of v33 passed patient-selection pauses,
both Salesforce outcomes and exactly one gRPC TYPE_DISCONNECT with
session_escalated=true. The 34 targeted speech/end-session tests also pass.
This confirms the native runtime boundary; it is not a new PSTN-to-queue test.
Evidence is retained under .local-data/takeda-demo/end-session-2026-10-07/.
See the failure signature and verification steps.
scripts/takeda-demo/install-controlled-patient-voice.ts prepares a validated
proposal from agent 4463's existing roster draft. Run it without arguments to
review the proposal; --apply requires TAKEDA_TEST_EXPECTED_REVISION matching
that draft. It uses native revisioned draft saving and does not publish.
The builder can reapply to an existing controlled-speech draft without
duplicating stages or guards. The older install-dynamic-patients.ts installs
the historical GPT Live roster configuration; use the controlled installer
for this speech path. Qualify the saved revision with the repeated campaign
below, then publish through the native agent-version flow.
Earlier voice guidance¶
Version 30, published October 7 at 11:49 AM Eastern, adds conversational-flow guidance that removes separate backchannels and uses examples of complete exchanges. Routine questions and answers begin directly, without a separate “Okay,” “Alright,” “Got it” or similar lead-in. Changing the stock word on every turn is not the intended variety. The backend supplies useful empathy together with its answer or next step; the voice must not add an earlier apology and then repeat that empathy when the answer arrives.
Examples cover the first-patient question, a pause while finding notes,
finishing one patient, the next patient's status, a policy explanation,
frustration and accepted transfer. They use placeholders rather than roster
names or new facts. The voice reads the current backend result, not the
examples as a fixed script. Patient names and unfinished selections remain
silent until the caller supplies enough information. Long accounts also receive
quiet listening, with any acknowledgement included in the complete response.
The personalized opening starts with “Hi” instead of “Okay.” This is a prompt
change, not a reduction in backend latency. Native qualification checks the
full two-patient exchange for stock lead-ins, repeated apologies, silence
during unfinished selections, verified patient receipts and one accepted handoff.
The shared automatic-delegation instruction also defers to the authored
backchannel policy: its one-acknowledgement cap applies only when the agent
allows acknowledgements. It must not reintroduce a waiting phrase after
the agent's voice instructions require silence.
The final two-patient replay delivered the complete script without separate
acknowledgements or duplicate apologies. The alternate three-patient replay
removed stock spoken lead-ins but still recorded native [hum] captions
outside selection pauses. A fresh published-version opening also produced
“Okay” before the otherwise correct patient question, failing the strict
style check. The complete replays show improved flow, not reliable elimination
of every acknowledgement. Published patient-selection checks therefore report
style observations separately from the required no-unsolicited-patient gates.
Prompt guidance is not a deterministic audio mute.
Release evidence is retained privately under
.local-data/takeda-demo/conversation-flow-2026-10-07/. The release preserves
the qualified GPT-5/medium backend, tools, patient-selection rules and catalog pin.
The October 6 follow-up reproduced an unsolicited child Case after a generic multi-patient opening, before the caller supplied any patient identity. The selection instructions now require caller evidence before starting another inquiry. A completed inquiry permits only its completion receipt and the backend-owned next-patient question. Roster order, assistant speech and tool acknowledgements cannot select another patient. An unfinished selection such as “the next one is…” or “I lost my notes” alone keeps both layers listening; a subsequent unique name or request description resumes the normal workflow. Ordinary caller text and role-labelled delegation transcripts are both valid input forms. A complete appeal description must still resolve its unique patient even when the caller mentions losing their notes.
scripts/takeda-demo/dynamic-patient-voice-test.ts in ai-manager includes
12-second pauses after the first and next selection questions, plus unfinished
caller phrases. It checks both audible questions and the actual Salesforce
child Account IDs, so a silent unrequested write also fails the replay.
It additionally checks for queued actions during each pause and pins the agent
configuration before and after the call. Startup context comes from the
published lifecycle outputs so the replay works with the native workflow graphs.
It rejects standalone or repeated stock acknowledgements, repeated apologies and selection
questions after a patient has been identified. A new status request may have
one purposeful acknowledgement naming its request type; explanations, selection
questions and handoff get the complete response without that preamble. Silence
is required during selection pauses and after a bare caller acknowledgement.
Set TAKEDA_TEST_EVIDENCE_DIR to retain each qualification in a separate private
directory; the default remains the dynamic-patient evidence directory.
Set TAKEDA_TEST_SCENARIO=response-flow to replay the reported appeal-to-authorization
conversation, including a unique appeal description, surprise about repeated
submissions, a bare thank-you, a frustrated request for help and accepted handoff.
The default scenario retains arbitrary roster ordering and combined patient switches.
Both require actual Salesforce outcomes and an unchanged configuration revision.
Playback checks account for all received PCM, including silence, and wait for
the current caption's audio before starting the caller. A text caption can
precede TTS output, so caption arrival alone is not a completed response.
The harness rejects overlapping speech, a doubled complete answer and leaked
VOICE_ONLY text, and records response onset and within-answer audio gaps.
response-flow-campaign.ts repeats both scenarios with two caller voices and
writes campaign.json; every call must pass against the same revision.
TAKEDA_TEST_CONCURRENCY=2 runs two independent calls at a time with separate
conversations and evidence directories. The default is one; the campaign
records the chosen concurrency because shared provider load can affect latency.
A single stock word joined to a useful status response is recorded as a style
observation; standalone replies, repeated lead-ins and extra waiting phrases fail.
Each successful native run also receives a separate semantic review from
voice-response-quality.ts. The reviewer quotes problematic responses and
checks for abandoned clarification fragments, repeated checking, invented
request types, wrong patient transitions and action announcements. Review
adjacent caption fragments as one response. This supplements the deterministic
audio, tool-count and Salesforce checks; a reviewer cannot override their failure.
The review also receives the exact caller text synthesized and delivered by
the harness, paired with each observed response. Persisted ASR can omit an
earlier sentence or misspell a name; those defects must not be mistaken for
the caller never selecting a patient. The raw transcript is retained alongside
the delivered utterances. A wrong patient, answer or action still fails.
This investigation also fixed the response guard's treatment of caller
transcription frames: it must forward their full text and identity, rather
than sentence-splitting them under the assistant-response policy. Splitting a
caller segment reused its identity and let its second sentence replace the
patient name in the first.
For example:
TAKEDA_TEST_AGENT_ID=4463:draft TAKEDA_TEST_PREPARE_LEAD_MS=10000 \
TAKEDA_TEST_EXPECTED_REVISION='<saved draft revision>' \
TAKEDA_TEST_REPEATS=2 TAKEDA_TEST_EVIDENCE_DIR=/tmp/takeda-voice-campaign \
bash .devcontainer/scripts/with-env.sh \
apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json \
apps/ai-manager/scripts/takeda-demo/response-flow-campaign.ts
Run this against a fixed draft before publishing, then repeat against the
published agent. Retain failed calls as well as passes. The optional
TAKEDA_TEST_RESUME=1 reuses completed native evidence only when its scenario,
caller voice, test-file hash and both configuration revisions match the pinned
TAKEDA_TEST_EXPECTED_REVISION. It reruns the semantic review, which is useful
after a review API error. Review errors are recorded as failures; they never
count as passing calls. Failed native calls require a new evidence directory.
The optional
TAKEDA_TEST_GRPC_ADDRESS selects an isolated runtime for diagnostics; the default
is the running local service at localhost:50051. Diagnostic-runtime success
does not replace a check against the service used by the phone route.
Qualification also covers the two-patient policy follow-up, consent and
backend tool receipts. These instructions guide the model; they do not replace
the existing tool identity checks or guarantee provider behavior on every call.
The roster includes its load date in UTC. “Last week” refers to the preceding
Monday–Sunday calendar week; original RequestedDate and appeal submission
activities are distinct. The October 6 fictional fixture records an appeal
submission on September 28 and retains its existing September 28 approval.
Ashley's CareRequest now records a payer response requiring prior-treatment
documentation under the September 1 policy, replacing the earlier tentative
cause and unverified-receipt story. No approval, clinical treatment or external
payer submission was performed by this fixture change. Maintained seed values
are in scripts/takeda-demo/payer-response-fixture.ts; updating existing demo
records requires a separately reviewed, backed-up change.
The DCC human wrap-up uses a separate summary path from Agent Assist 4465.
Its TakedaMultiPatient branch in dccSummaryNotes previously returned a fixed
Renee summary, an expired follow-up date, empty intents and empty status.
It now calls DCC_CustomWrapUpService.getTakedaSummary for the selected parent,
reading the current child names, reasons, reviewed appeal fields and receipts.
An internal-review receipt is not presented as a confirmed payer submission.
Unrelated children and calls are excluded; record text is escaped in HTML.
An open patient Case with a verified internal-review receipt proposes follow-up
outreach using that patient's name and the current coordinator's name. The
existing Complete action creates the selected Task. A matching Task already
under this interaction suppresses the recommendation on reopening wrap-up.
The review receipt and a recorded FRM note do not replace that outreach Task.
No sample payer names or appointment dates are proposed.
For the verified Genesys interaction parent, the wrap-up controller proposes
Closed and derives Customer Intents from the discussed child reasons
(plus valid selections already saved on the parent). Both the defaults and
summary read are read-only. The existing representative Complete action
saves the reviewed values. This does not close a Case at AI handoff or change
the historical CareRequest. Other applications retain their existing defaults.
Takeda_Clearway_Demo grants the summary method's Apex class access.
Maintain the scoped shared DCC source with this package and deploy it explicitly;
do not replace other applications' summary branches.
The reported test's parent, Case 00022628, already had Closed and both requested intents by 10:55 AM Eastern; the correction addresses future defaults. Its authorization child still has an internal appeal-review receipt and remains Escalated. That child state is separate from closing the parent interaction.
The Vanguard Genesys route uses voice agent 4463:v33 and human assist agent
4465. Agent Studio owns caller resolution and Salesforce writes. Architect
flow 467a7ece-e85b-4c3a-a3db-da45b7355592, Takeda Clearway Flow, ran
version 32.0 in the inspected October 6 calls. Startup preparation was
published as 34.0 on October 7; 35.0 refreshes its IVR recordings.
Both Deloitte Genesys Lab and DCCDev Connect availability entries
on agent 4463 are retained.
| Owner | Published configuration | Responsibility |
|---|---|---|
| Studio conversation start | 1856:v6 — Clearway — Start call, native Salesforce graph | Look up ANI, branch to its matching Account or Denise, create/reuse the Case and call Task, then load patient facts. |
| Studio patient Actions | 1918:v3 — Clearway — Save roster patient, asynchronous native graph | Create or update one child per discussed patient from the returned Salesforce roster; verify the patient outcome and parent summary in the background. |
| Studio conversation end | 1857:v9 — Clearway — Finish call, asynchronous native graph | Wait for queued updates, reconstruct the summary from Salesforce, update the call Task, and link/update the matching VoiceCall. |
| Legacy | 1853 — Legacy — Genesys supplied-Case context (1853), inactive | Earlier startup that expected Genesys to supply a Case. No current agent/workflow references it; its graph and version history are retained. |
| Legacy patient Actions | 1855:v5 — Clearway — Save patient outcome | Retained for earlier agent versions; its fixed patient outcomes are not used by the roster-based agent. |
| Genesys | Flow 35.0, published October 7 | Accept startup preparation, play the welcome, join the prepared Voice Agent context, map returned context to participant attributes, then queue or disconnect. AudioHook monitoring supports human Agent Assist. |
IVR recordings¶
The October 7 recordings match agent 4463:v33: ElevenLabs Josh — Warm,
Smooth and Steady (ZoiZ8fuDWInAcwPXaVeq) through HTTP Streaming with
eleven_v4_turbo, stability 0.5 and similarity boost 0.75, using the
TrueServe ElevenLabs integration. The request uses
/v1/text-to-speech/{voice_id}/stream; v4 requests omit the legacy latency and
WebSocket chunk settings, as the runtime does.
| Prompt | Resource | Use | Recorded duration |
|---|---|---|---|
ClearwayWelcome (cd373426-9ccb-433f-abf5-a389d8f5b057) |
en-us |
Main route welcome | 13.04 seconds |
Clearway_Transfer (d9788f13-e91b-43d5-88ee-b3441a19bb6a) |
en-us |
Main and backup queue transfer | 10.88 seconds |
Both retain the original wording. The welcome had no saved transcript, so its original recording was transcribed before synthesis; the transfer matched its saved text. Generation uses 16 kHz PCM, converted to mono 8 kHz mu-law WAV for Genesys. Checks compare the spoken words, reject clipped source audio and require the downloaded Genesys waveform to match the submitted waveform.
Architect snapshots directly referenced user prompts when publishing a call
flow. Updating the prompt resource alone does not update calls: republish
both consuming flows, Takeda Clearway Flow and Takeda Clearway — Direct
Queue Backup, after both assets report transcoded. Keep the flow definitions
and routing unchanged and verify successful publication. The generic
error-handling TTS message is separate from these two recorded prompts.
The refresh published main flow 35.0 and backup flow 2.0 on October 7.
Both publication operations completed with SUCCESS. Published definitions
match their preceding versions apart from version metadata. Main-flow
publication required several minutes for the final backend acknowledgement;
poll the original operation instead of submitting another publish request.
Original audio, generation settings, upload receipts, waveform comparisons and
flow readbacks are retained privately under
.local-data/takeda-demo/ivr-voice-2026-10-07/. To restore a recording, upload
its backed-up WAV to the same prompt resource and republish its consuming flows.
Startup preparation¶
The early request uses Takeda - Prepare Voice Agent Startup, published
Data Action custom_-_3dfdca56-aec8-4b76-b0ca-82eed7e60656 version 1 on
the TrueServe Vanguard Startup integration. It calls the authenticated
ai-manager preparation API for workflow 1856 and agent 4463. All three outcomes
continue to the original welcome; the connector always sends
startup_preparation=true, so an uncertain response joins the same durable
operation. Queue routing, patient-selection instructions and agent version
remain unchanged. See voice startup preparation.
The native preparation test produced one run, one voice activity and zero patient child Cases under concurrent requests. Its cached join took 8 ms; Genesys accepted the tested request in 845 ms. The final Architect candidate validated with zero errors and warnings. Later prepared openings took 4.3 and 2.6 seconds after the connection began, with a ten-second simulated welcome lead and 13–15 ms prepared-context joins. A cold comparison took 19.9 seconds, including a recovered missing Live startup acknowledgment. These are individual rehearsals with variable provider startup, not a PSTN latency guarantee.
Earlier sessions stalled even when preparation was ready; a direct Live probe also received no startup acknowledgment within 25 seconds. The runtime now allows one bounded reconnect before any caller audio reaches Live or backend work begins. Its recovery preserves the existing audio buffer and does not rerun Salesforce. Full conversation qualification still flags a standalone “Mm-hmm” before the patient-selection question; startup success does not make that separate backchannel check pass.
GPT-5 low reasoning passed nine scripted backend scenarios and reduced the
median response time in one seven-turn script from 5.15 to 3.55 seconds.
Minimal reasoning failed tool-sequencing and duplicate-completion checks.
After startup recovery was added, a fresh low-reasoning draft replay failed
the patient-wait check by announcing a transfer while the caller was choosing
a patient. The draft was restored; version 31 retained medium reasoning. Version
32 subsequently qualified GPT-5.4 without reasoning on the controlled speech
path described above.
Evidence, rollback configuration
and scripts are in .local-data/takeda-demo/startup-2026-10-07/.
The start graph reads from top to bottom: Find Account by ANI → Does ANI match an Account? → Use the matching Account / Use Denise’s configured Account → Create or reuse Case and call activity → Load patient facts once. The branches sit beside one another at the same height. The former 20-node receipt graph is replaced by one Action. Refresh an already-open editor to load these versions.
Lifecycle inputs are the runtime's conversation_id, ani, dnis and
agent_id. On this Genesys route the TrueServe conversation ID is the original
Genesys conversation UUID; it is also the call Task's CallObject. Genesys does
not supply Account IDs, Case IDs or patient JSON. The Actions validate the tenant,
agent 4463 and called number +1 804 413 6534 before identity-dependent work.
A unique normalized ANI match wins; no match selects Denise Warren
(001DW00001ZuvWYYAZ) and her Person Contact (003DW00001ABcFlYAL). Ambiguous
matches fail verification rather than selecting a fallback.
Direct Preview must set dnis=+18044136534 as well as the caller ANI. On
2026-10-02, a read-only Salesforce query and the production lookupCoordinator
function confirmed that ani=+16293034545 matches Denise's Account and
ani=+15550100000 selects the Denise fallback. The 13:00 UTC Preview call
10d00719-797f-48d6-a98e-95e6aecac544 had an empty DNIS: workflow 1856's
lookup step failed with Unexpected called number, its router exited, and
the completed run returned context_status=unavailable. This is an input
validation failure before the ANI/fallback branches, not a missing Salesforce
identity. Do not weaken the destination check to accommodate an unset test
variable.
Telephony Preview was verified on October 2 at 9:51 AM Eastern with Genesys
conversation 9eb0b8e7-af06-4318-8e78-03f5a98d191e. The SIP answer's x-inin-cnv
connected AI Activity to that exact conversation. ANI +16293034545 reached the
start workflow, used the matched-account branch, and returned context_status=ready.
The browser received the complete Denise greeting as audio and transcript;
AI Activity showed both completed start and end workflows. This check used the
published Genesys route, not the open Studio draft. The runtime initial audio
buffer now accounts for lifecycle setup time, and the dialplan sets caller
identity before creating the outbound channel. See
Telephony Preview for the correlation contract.
Parent Case defaults match the prior flow: coordinator Account/Person Contact,
record type 012Kd000000pk1VIAQ, subject Takeda Clearway | Multi-Patient Access
Review, reason Multi-Patient Access Review (Case.Reason=MultiPatientAccessReview),
New, Voice, Medium. Set the reason explicitly in the parent creation
payload; the subject and VoiceCall.DCC_Call_Reason_Display__c do not populate
Case.Reason. A standard Salesforce Composite request
creates that Case and its Inbound Voice Task together with allOrNone.
The Task is In Progress, has type Voice and call type Inbound.
Unique External_ID__c values include the tenant and Genesys conversation UUID.
A per-call database lock, durable keys and independent readback make retries
reuse records. A timed-out acknowledgment is reconciled by reading; it does not
blindly repeat the write. Legacy incomplete parent records can recover their
missing Task after coordinator/relationship verification.
The October 6, 2026 correction restored the explicit parent reason and repaired
47 existing blank parent reasons in DevSDO. The repair was limited to Voice
parents with this record type and the exact tenant/Genesys parent external-ID
pattern; existing nonblank reasons were preserved. Each update checked the
current record and used If-Unmodified-Since, followed by Salesforce readback.
The private plan, before/after records and verification are retained under
.local-data/takeda-demo/triage-2026-10-06/case-reason-repair/.
The workflow has five outputs:
| Output | Use |
|---|---|
context_status |
ready or unavailable; controls greeting and patient Actions. |
coordinator_first_name |
Personalized opening. |
patient_brief |
Plain-text facts for the backend prompt. |
call_context |
Internal Case, Task, coordinator and patient roster, bound into Actions. |
transfer_params |
Internal verified handoff projection, bound to end_session.params. |
Keep context_status as a lifecycle output, without a mutable default of the
same name: a session-variable default shadows lifecycle metadata. Completion
reads updated session_variables.call_context first, then the original
session_metadata.call_context; this covers a caller disconnecting before any
patient save. Both asynchronous save and completion bindings read trigger.*;
the declared Action-input namespace can be empty in a broker execution. Native workflow expressions use
JSONata for the context fallback and tojson for object/boolean merge tokens.
Salesforce calls use fixed REST endpoints and targeted SOQL, without Case schema
lookup or Python sandbox nodes. Patient loading queries the coordinator's care
program enrollees, each patient's latest CareRequest, and only those requests'
linked Case notes/activities. It no longer uses the old Patient Service context
operation, whose broad historical Case scan reached its 500-record limit during
verification. The existing legacy operation remains unchanged for other callers.
Patient IDs remain in the internal roster; the prompt receives readable facts
and a per-call reference such as p1. Each reference maps to one returned
Account ID. The authored prompt, tools and handoff rules contain no patient
names, prescribed order or scenario-specific clinical facts. A renamed Account
therefore retains its identity even when older notes use another spelling.
Unique names or request descriptions can select a patient; ambiguous or unknown
matches require clarification before any child write.
The brief includes the request's RootCauseNotes as recorded cause notes,
alongside its decision notes, policy effective date, prior/current criteria and
linked activity history. A possible cause stays tentative. Unverified receipt
does not establish that a payer is actively checking documents or will approve
the request afterward.
For an unresolved request, the agent first gives the short status and immediate documentation request, then pauses. An explanation question introduces the recorded policy change and an apology. A subsequent frustrated request for help gets a brief acknowledgement and a case-manager offer. The agent must not repeat the status or policy explanation at every turn. A declined offer remains declined across later explanation questions; only a subsequent explicit human request changes that choice. Documentation of a prior treatment is not a recommendation to start treatment. These are generic conversation rules; patient names, requirements and dates come from the current Salesforce records. The voice Actions cannot contact the payer or verify receipt, so the agent must not offer to perform those checks.
The two generic Voice Agent Actions bind call context in host logic.
takeda_record_patient_receipt submits discussed when an identified inquiry
starts and completed when it finishes. takeda_escalate_patient_receipt
requires handoffAccepted=true and applies to any identified roster patient.
Workflow 1918 maps these inputs directly through native Salesforce and Assignment nodes. Each patient
gets one child under the call parent, keyed by Account ID. Status progresses
from New to Closed or Escalated; delayed jobs cannot reopen a child
or undo escalation. Completing an inquiry does not change its historical
CareRequest or submission Tasks.
New children use the linked source Case's Reason, or
MultiPatientAccessReview when there is no source reason. Patient Contact,
CareRequest and source Case links are included when returned. Each save writes
the child and HTML parent summary in one Salesforce Composite transaction.
Readback checks child relationships, state and the persisted summary. Existing
receipts are reused. The voice tools use execution_mode=async and receive
only status=submitted and an execution ID. Submit once per patient/disposition;
the receipt confirms queuing, not persistence. Workflow output verified stays
in run history and is never injected into the voice prompt. A completed run
with verified=false still needs investigation. Caller acceptance is checked
by both the escalation tool schema and the write Action.
end_session.params is bound to transfer_params: CaseId, ActivityId, Name,
parentCaseId, coordinatorAccountId, childCaseIds, escalatedCaseId,
patientAccountId, journeyStatus, transcriptSummarySaved and summary.
childCaseIds is a JSON string for the Genesys consumer. These transport fields
now retain the verified startup identity: journeyStatus=partial,
transcriptSummarySaved=false, and an empty child list. They do not claim that
queued writes have completed. A submitted, accepted patient escalation triggers the
automatic handoff once, without waiting for Salesforce. Genesys routes
session_escalated = "true" to its queue and
"false" to disconnect. Missing escalation data or AudioConnector failure goes
to the queue. It supplies no hardcoded patient summary. The human workspace
reconstructs saved outcomes from the Salesforce parent/child records.
After the voice session, completion checks jobs with the host-bound
_case_write_kind=roster_patient marker, plus legacy workflow 1855 jobs,
scoped by tenant and original conversation ID. It uses the latest run status, since
an execution's terminal status can be resolved. It waits up to 30 seconds
without holding the per-call write lock, then reads the actual Salesforce
receipts and updates the Task summary under that lock. Pending or unverified
updates are reported in the summary and completion outputs. The native finalizer leaves unfinished child inquiries open. It closes the parent only after explicit non-escalated completion, closed saved children and verified background jobs. Repeated finalization repairs summaries and reads back parent, Task and VoiceCall fields. See native action logic and qualification. VoiceCall linking retains its bounded retry. This waiting happens outside the conversation.
The voice, backend and greeting prompts are maintained in
apps/ai-manager/scripts/takeda-demo/genesys-simple-prompts/. Their spoken
opening remains personalized after context loads. The prompts preserve patient
facts, the pause before offering a case manager, explicit acceptance and silent
recordkeeping; they omit internal IDs and raw JSON. The voice prompt favors
direct, complete responses and quiet listening while the backend works.
It no longer asks for an acknowledgement within one second or a stock lead-in
after each request. The backend continues after submission, never polls for
results, and does not repeat empathy already spoken for that caller turn.
Backend/tool progress narration remains off. This guidance does not change
the shared caption-assembly timer or guarantee a response time.
Startup/completion generators live in simple-genesys-workflows.ts; generic
patient tools, workflow and voice configuration live in
dynamic-patient-definition.ts. install-dynamic-patients.ts --apply installs
the workflow/tools and saves the revision-checked agent draft, then runs native
preflight. publish-dynamic-patients.ts publishes the exact qualified draft
through native release gates, rejecting a revision changed after qualification.
The accepted-handoff rule passes session_escalated="true" literally: rule
arguments read a pre-action variable snapshot, so reading a flag set earlier
in that same rule would return its previous false value. Workflow-only Actions live in
lib/takeda-demo/genesys-call.ts, exposed through the existing authenticated
/api/mcp/takeda route. Tool takeda_genesys_call_actions uses the HTTPS
Vanguard endpoint and the encrypted Clearway workflow action authentication
integration; it is not exposed directly to the voice model. This uses the
existing Node HTTP client, without sandbox process startup.
Exact draft/published prompts, agent/workflow version histories, receipt tools
and Genesys configuration were backed up before editing:
.local-data/takeda-demo/backups/2026-10-01T21-01-01.820Z-before-simplification/.
RESTORE.txt describes restoration and manifest.json records SHA-256 checksums.
Backups are private local files; no credentials are included. Restore into a new
draft, validate and publish deliberately; do not overwrite version history.
An additional exact backup precedes the async-save change:
.local-data/takeda-demo/backups/2026-10-01T23-58-51.838Z-before-async-saves/.
It includes the v15 prompts and v4/v6 workflow configurations.
Twenty-nine focused Action/configuration tests cover identity, atomic writes, retries, timeout
reconciliation, partial summaries, explicit acceptance, cross-call rejection and
completion, including pending/failed background jobs and lock-safe reconciliation.
The roster cases include unfamiliar and renamed patients, invalid/ambiguous
references, duplicate display names with separate Account IDs, progressive
child creation and out-of-order background updates. Run
dynamic-patient-voice-test.ts for a native audio replay against agent 4463's
draft and live DevSDO data. It verifies an unknown name creates no child,
then discusses three returned patients in a different order and requests a
handoff for the final patient. This creates synthetic sandbox call records.
Private configuration backups, replay transcripts and Salesforce readback
are under .local-data/takeda-demo/dynamic-patients-2026-10-06/.
Agent 4463:v21 was published on October 6 at 11:18 UTC after native
conversation a93c97d1-a260-430b-bc8b-d8bedabf1884 passed: an unknown name
created no child, the returned roster created exactly three children as each
was discussed, and final statuses were two Closed and one Escalated.
The test used the renamed Account, checked all available patient/source links,
verified parent MultiPatientAccessReview, and returned
session_escalated="true" with zero pending/failed completion updates.
Published runtime preflight passed. This qualification exercises native audio
and DevSDO records; it does not rerun the Genesys telephone leg.
The October 6 Telephony audio correction is 4463:v22. It changes only
pipeline[0].config.turn_control.audio_enhancement.voice_isolation from
krisp_viva to off. The draft had this filter enabled while published v20
did not; publishing the roster change carried that draft setting into v21.
The 08:42 Eastern browser call delivered the greeting and received audio
without connector drops, but Live emitted no caller transcript. A separate
transcription of the saved caller track recovered both spoken requests.
Browser Telephony reproduction against v21 likewise sent a live, unmuted
microphone track with zero reported packet loss but produced no caller turn.
Native replay with the filter disabled detected the quiet speech. This
correction restores the earlier absence of server voice isolation and retains
the roster workflow, prompts, parent reason and all other settings.
Browser capture retains its existing echo cancellation, noise suppression
and automatic gain control. Evidence and exact configuration backups are
under .local-data/takeda-demo/telephony-audio-2026-10-06/.
Replaying the same captured speech through browser Telephony produced zero
caller turns on v21 (5b3091e4-b0e3-4379-9f83-62d7e744b631) and a caller
transcript plus an agent reply on v22
(aaedae6a-2d3a-4b4f-9f8c-4f61305ec25b). The captured sample had already
passed through the old filter, so this comparison establishes recovered
turn detection rather than pristine transcription accuracy.
A fresh speech sample attenuated to RMS 600 PCM16 then passed through the
same browser Telephony path on v22 in conversation
12fde652-2800-4fed-ab09-f10d0119fdca: the full patient-updates request was
transcribed correctly and the agent answered it. The microphone stayed live
and unmuted, and RTP reported zero packet loss. No SIP codec, sample-rate
or gain change was required.
The later October 6 transcription and ending correction combines a runtime change with 4463:v23. The runtime had appended the same delegation policy at the first caller caption, while more caller audio was still arriving. Controlled replays of one human recording at both 20 ms and 200 ms packet sizes changed the recognized request when that instruction was injected. Without the injection, and with the policy in initial session instructions, the request was recovered correctly. The recorded pipeline input correlated 0.9998 with the original replay audio. The fixed policy now lives in startup instructions; per-turn backend dispatch, caption settlement and tool gates remain in place. See GPT-Live turn ownership.
Version 23 changes only the backend and voice ending instructions. Acknowledging
an answer or completing one patient inquiry does not finish the entire call.
Explicit whole-call completion can end normally; an explicit or accepted human
request uses the escalation path. Nine model behavior checks passed. Native
qualification 9172115f-3661-4abd-ac92-a16fdb932f0b recovered the recorded appeal
request and full patient name, stayed connected after “Okay,” then returned
session_escalated="true" on the requested handoff. Salesforce readback verified
one escalated child, the parent reason, source links, and zero pending or failed
completion updates. The 214 focused runtime tests and published preflight passed.
This native qualification verifies the handoff signal, not a human answering.
Second qualification ef2fa518-d9c7-4762-a904-da87123f18d3 replayed the newest
reported recording. All three sampled phrases were recovered, including the
appeal sentence previously rendered as “PO 40” and “Give me just a second,”
previously rendered as a patient name. The acknowledgement, escalation and
Salesforce readback checks passed again.
The 13:32 UTC silent call c93fa013-b37c-43b7-bf1f-f7008572e31d
exposed a separate runtime startup regression. Low-level microphone noise
crossed the energy threshold and marked the first greeting as sent without
issuing it. Its agent recording contained no audible speech (peak 3 PCM16).
The initial connection now drains its buffered input and retains the greeting;
only recovery can suppress a repeated opening based on input activity.
Replaying that call's initial noise succeeded in native conversation
589f7e9f-9c4f-4e45-8f5a-7c5663488e91 and browser Telephony conversation
a41ef1c8-f1ae-4c77-abcc-85094d1c8b17. Both saved agent tracks contain the
spoken opening. The latter also transcribed the controlled patient request.
Paired Genesys/TrueServe recordings for the five earlier calls retained the
reported speech. Controlled browser conversation
7ab12db7-249a-4b66-ad72-8e1637a90813 added a microphone tap before encoding:
independent transcription recovered the same complete request at the browser,
Genesys and TrueServe checkpoints, with less than 1 dB spread in approximate
speech RMS. Live captions still shortened the opening. This test used an audio
file as microphone input and does not rule out the user's device or acoustics.
The private standalone listening report and source recordings are in
.local-data/takeda-demo/genesys-audio-comparison-2026-10-06/.
The same folder contains a Krisp comparison on identical saved audio. Full
strength attenuated the quiet “Are you there?” and the Live replay rendered it
as “be there.” At strength 50, the tested opening and both patient requests
matched the unfiltered replay. Initial background RMS fell by approximately
6 dB across three sampled recordings. Whole-file offline transcription is
retained as supporting evidence but is not treated as a word-loss measurement.
The runtime now accepts the optional advanced node setting
turn_control.krisp_viva.noise_suppression_level (0–100; default 100);
the editor preserves it when changing other turn-control settings.
Agent 4463:v24 was published at 13:44 UTC with voice isolation restored
at strength 50. Only the isolation selection and its strength changed
from v23. Native qualification
f9f8336f-9ddd-42ba-afac-878db0a0f00d delivered the greeting over the original
startup noise, transcribed both quiet test phrases, and answered them.
Published browser Telephony qualification
4641b8de-43b9-4cd7-8bb0-20b405c5a59a confirmed the 16 kHz telephony filter
running at 50, the spoken greeting, the complete controlled caller request,
and an agent reply. Preflight passed; 242 runtime tests passed with one optional
model test skipped, and six editor configuration tests passed. These recorded
and controlled-input checks do not substitute for a fresh physical-microphone
call or establish that every live caption is verbatim.
The October 6 follow-up correction is 4463:v25, published at 9:58 AM
Eastern. The 9:45 AM call
2d4d23f6-25ae-4e10-9e69-5ce63c866217 identified the renamed patient correctly
but repeated the submission status after “What does that mean?” The October 1
calls had progressed from the recorded criteria change to an explanation and
accepted case-manager assistance. The current Salesforce request already held
the policy date, prior/current criteria, likely-cause notes and submission
history. Its Account ID and source request stayed the same through the rename.
No underlying patient, CareRequest, historical Case or submission Task facts
were rewritten. The loader now includes the previously omitted RootCauseNotes,
and v25 restores the generic explanation/offer/acceptance sequence. The voice
and backend preserve historical-work attribution, unverified receipt and
declined offers. Patient-specific facts remain in Salesforce, not the prompt.
Six backend behavior checks included a different patient/requirement, missing
criteria, a declined offer and a direct human request. All 31 focused tests and
published preflight passed. Native voice qualification
665cb3ec-4cb0-4f2a-a502-67630fc70ce2 completed the first patient, explained the
second patient's prior-trial documentation, respected “not yet,” and signalled
escalation only after a later explicit human request. Salesforce readback
verified exactly two children, Closed and Escalated, with the parent
reason, patient/source links and zero pending or failed completion updates.
This qualifies the handoff signal, not a human answering. Before/after source
records, call comparisons and qualification receipts are retained in
.local-data/takeda-demo/second-patient-review-2026-10-06/.
Genesys analytics distinguishes the reported endings. The confirmed
13:00:49–13:02:13 UTC call ended through FLOW_DISCONNECT after the backend
treated “Okay” as caller_finished. The other four inspected calls ended
from the external endpoint; one earlier call recorded SIP 503. No inspected
call entered a human queue. The connector reported no dropped input/output
chunks for these calls. The 13:13 and 13:15 calls still ran v22 and the old
runtime; independent transcription recovered words that the live model had
replaced. These findings do not establish a carrier-side cause for SIP 503
or guarantee all speech recognition. Private recordings, provider analytics,
configuration backups and qualification results are retained in
.local-data/takeda-demo/transcript-accuracy-2026-10-06/.
Async draft submissions returned in 13 ms and 28 ms in one sandbox exercise;
both writes and the reconstructed final summary were subsequently verified.
These submission timings do not measure audible acknowledgement latency.
Async-change evidence is in .local-data/takeda-demo/async-saves/.
Published v16 also passed a native audio replay: both save tools returned
submission receipts in 18 ms and 16 ms, both background saves were verified,
and the final Task summary contained both outcomes. The accepted handoff used
the startup Case/Task IDs without fabricated child receipts. No Salesforce
VoiceCall is created by this native replay, so its completion correctly reported
linked=false. Three acknowledgement samples began 1.135 / 1.512 / 2.263 s
after the test input stream ended. Those are not handset/PSTN measurements and
do not meet the one-second goal; the replay establishes functional behavior,
not a response-time guarantee.
Earlier native workflow exercises against the Salesforce sandbox cover ANI
match, Denise fallback, same-record retries, declined handoff and successful
patient saves. A fresh matched start took 2.598 s in that run; a same-call
retry took 0.716 s and excludes new-record creation. These are workflow-only
measurements, not PSTN or first-speech timing. Published agent v15 passed a native audio replay
through both patient saves and accepted handoff, with first audible speech at
6.839 s. Completion v6 separately passed the actual asynchronous execution
endpoint using that call’s captured ending payload; Salesforce readback verifies
the Task status and summary. Evidence is retained privately in
.local-data/takeda-demo/simplification-review/. Run the focused Action tests:
TSX_TSCONFIG_PATH=apps/ai-manager/tsconfig.json node \
--import ./apps/ai-manager/node_modules/tsx/dist/loader.mjs --test \
apps/ai-manager/lib/takeda-demo/genesys-call.test.ts \
apps/ai-manager/scripts/takeda-demo/dynamic-patient-definition.test.ts
The earlier native Salesforce HTTP-pooling work remains in place: eight paired
read-only requests opened eight connections with the old client and one with
pooling (median 129.3 ms versus 90.9 ms). That is a request-level benchmark, not
an equivalent reduction in total startup. Its 23 focused tests and evidence
are in .local-data/takeda-demo/genesys-http-reuse/. Historical startup probes
are in genesys-fast-start/; do not compare them directly with workflow-only
measurements. Native audio qualification excludes Genesys welcome/PSTN and the
Salesforce screen-pop; those require a fresh telephone call.
genesys-simple-flow.py still prepares the transport flow. Its decision has a
placeholder until compiled by the official Architect SDK; never publish raw
prepared JSON. Compile
If(IsNotSetOrEmpty(Task.isEscalated), true, Task.isEscalated == "true"), validate,
export and decode before publication. SDK 0.69.1 validated deployed flow 25.0.
Use startWithAuthToken and suppress SDK logging; its client-secret startup path
logs the secret. Branches must own separate actions, including failure/timeout
descendants: shared descendants caused the earlier FLOW_ERROR_DISCONNECT,
corrected forward in 23.0. Inspect fresh execution history by ConversationId
through /api/v2/flows/instances/query; poll the actual published version after
checkin/publication rather than assuming they match.
Genesys VoiceCall VendorCallKey uses
vendor-uuid:conversation-uuid:call.inbound. The shared LWC normalizes this
specific format to the middle UUID for session minting, embed URLs and host
events. Bare conversation IDs are preserved. The sandbox takedaMfeBase clone
has the same correction; Apex's record-to-conversation authorization remains
enabled. Completion retries a missing VoiceCall briefly and refuses to overwrite
a link to a different Case. Deploy LWC bundles from freshly retrieved metadata
to preserve other org changes, then verify the dedicated Takeda Clearway
Voice Call page.
Guided sidebar and native appeal stages¶
The Takeda companion uses one case-journey custom worker with the StageAssist
catalog component and one headless patient-appeal extractor. Separate policy,
coaching and post-call cards are disabled for this journey. The guide replaces
its stable surface in place; an older transcript result cannot regress a
receipt-supported stage for the same Case.
The extractor uses layout_region: "context" with no card. Its suggestion
metadata preserves that placement through replay; surface-app omits the generic
form card while the SDK and Salesforce LMS still receive every field event.
Do not rely on prompt text alone to hide an extraction card.
The guide's conditional prompt checks LatestAgentMessage before enabling the
human-acknowledgement rule. An empty human transcript keeps the transfer card
through startup context updates; recorded history is not spoken acknowledgement.
TAKEDA_STARTUP_ONLY=true runs the browser rehearsal's startup stability check.
| Trigger | Sidebar | Native center |
|---|---|---|
Verified context.ready |
AI Transfer Summary with discussed patients | Selected patient's Case History Timeline |
| Human acknowledges the transferred context | Payer Criteria Changed; Start Appeal | Timeline remains |
Start Appeal / appeal.loading, then appeal.opened |
Three-field appeal checklist | Loading state, then full Case-prefilled appeal form |
appeal.progress |
Exact current completion booleans | Caller-confirmed values or representative corrections |
Successful appeal.submitted receipt |
Before Wrapping Up the Call | Refreshed timeline including new submission |
Successful note.sent receipt |
Wrap Up the Call | Salesforce toast and refreshed activities |
The form replaces the inquiry/timeline section while preserving Case details
and the patient tree. Its nine read-only defaults come from the selected child
Case, Person Account, Member Plan and historical source Case. The three editable
requirements use live draft values; Submit Appeal becomes enabled as soon as
all three are nonblank. Save Draft is optional. saveAppeal validates ownership,
locks the child Case, saves the displayed values and creates the requested
submission receipt in one transaction. A retry returns the existing receipt
without replacing the submitted values. Errors retain the draft and do not
emit success events. The sandbox submission and note are demo receipts; they
are not evidence of payer delivery or an external message.
The LWC publishes record-scoped appeal.progress, appeal.submitted and
note.sent messages through LMS and the existing SDK stream-event route.
Progress includes explicit false values for manual clearing. Form extraction
cannot overwrite representative edits or another patient's Case. Success also
refreshes the shared Context Flow, whose patient rows expose saved appeal status,
fields, receipt and note state for reloads.
The DCC Send Outreach action saves dcc:demo-note:<childCaseId> on the
parent Case, while the older native workspace saves
takeda:demo:<childCaseId>:frm on the child. The context reader recognizes both
formats and returns noteRecorded plus the saved noteReceipt per patient.
Only a completed FRM notification with the matching key and Case relationship
can complete outreach. Sibling notes, appeal-review Tasks and unfinished Tasks
cannot advance that patient's guide. This lets a context refresh recover
Wrap Up the Call even when the individual note.sent event is delayed.
The October 7 repair preserves the deployed payer lookup and conversation link;
retrieve the current controller before deploying its scoped change. Regression
coverage is in TakedaVoiceWorkspaceControllerTest, including parent receipts,
legacy child receipts, repeated refreshes and patient isolation.
The case-journey worker uses GPT-4.1 and explicitly copies the selected
patient's saved note receipt into its wrap-up response. Host context and event
bindings use unescaped Mustache interpolation so their structured fields remain
readable. The published StageAssist component retains its existing same-patient
stage memory: a delayed earlier-stage model response cannot replace a displayed
wrap-up. The headless form extractor keeps its existing model and configuration.
The October 7 FRM script update uses catalog takeda-assist@5.0.8, pinned by 4463:v31 and retained in v32. It retains the agent's previously pinned 5.0.3 layout, component schema, actions and receipt-driven stage transitions; the repository catalog source is synchronized with that published layout. The follow-up card asks the representative to request a clinic visit and labels its date Requested Visit. It includes reimbursement support, prior authorization and future billing questions. After the saved outreach receipt advances the guide to wrap-up, the spoken script emphasizes I asked him to go to for Sam. A requested visit is not a confirmed appointment. Dates and recipients still come from the current patient's context; an absent visit date does not become “tomorrow.” The change preserves v30's patient-selection and conversation-flow prompts. Published-bundle browser checks cover the revised copy at 420px and 320px, receipt completion, late-stage updates, patient changes and delivery retries.
Apply and publish through install-staged-journey.ts; use --config-only when
the catalog is unchanged. Run stage-journey-rehearsal.ts for the actual
Salesforce/browser/audio sequence, and live-handoff-rehearsal.ts for native
voice. TAKEDA_TEST_AGENT=4453:draft selects the candidate for voice testing.
Runtime preflight runs before publication. Synthetic rehearsals do not prove
PSTN timing or the presenter's ringing UI.
For Macau, set TAKEDA_TEST_CITY=macau; an expiring, privately transferred
TAKEDA_SF_STORAGE Playwright session can exercise the same Salesforce user.
Delete that temporary session after the rehearsal.
Use this runbook to install and rehearse the Takeda Clearway Voice Agent, human Copilot, custom catalog, and DevSDO Voice Call workspace. The user-supplied scenario is Takeda_Script.md (local source copy in .backup/). The later screen1.svg through screen9.svg are the authoritative visual references for Takeda's human journey only. They supersede the earlier inspiration image. Keep other catalogs and the shared DCC sidebar unchanged.
September 30 script alignment¶
The live route must use the published revision, not just the edited draft. The
September 30 repair publishes native client delegation and verifies the complete
end path with live-handoff-rehearsal.ts: it creates an unlinked VoiceCall,
plays Thomas then Renee through the published agent, and requires the automatic
lifecycle workflow to link the call and write its summary. No manual workflow
execution or pre-created patient children count as that check.
connect-runtime-access.py --apply grants the existing demo host role only
Get/UpdateContactAttributes on dccdev contacts. repair-live-handoff.ts --apply
checks the default AWS credential chain before clearing known-invalid integration
keys, and publishes the field-mapping repair while preserving that city's
Salesforce connection. It finds the VoiceCall by trusted Connect VendorCallKey,
requires a unique matching parent, and sets RelatedRecordId with the preview
fields. The native workspace can also read that exact contact's parent while the
link is pending. DCC_Summary__c has no unrelated demo default. Repeated PA
submissions appear in the compact request only when the source record confirms
multiple submissions. The workflow uses the compact summary for the phone
preview and keeps the full InteractionSummary on the parent Case.
The revised main journey is Thomas's historical appeal lookup followed by Renee's PA. Marisol remains an optional request; neither the Voice Agent nor the workspace introduces her. Thomas's lookup records the interaction without submitting or approving another appeal. Renee's lookup returns recorded history and criteria before an escalation is offered.
GPT-Live's voice instructions address dry praise, repeated submissions and frustration without assigning an emotion label. Its backend explains the recorded issue, reassures within its capabilities, offers one clear human choice, and waits. A direct human request already accepts; a refusal continues the AI conversation without repeated offers on later questions. The direct request branch takes priority over the scripted explanation-and-offer sequence. Policy evidence can suggest a blocker, not prove payer receipt, clinical necessity or approval.
align-script.ts --apply updates only the existing Voice draft, preserving
provider connections and lifecycle mapping. It enables the serialized
client-delegation backend path while retaining GPT-Live audio, and binds
caller_turn to CallerTurn. The authored prompt replaces generic end-session
guidance; the capability and its bound receipt gate remain enabled. This protected
tool-binding JSON contains the publisher's latest genuine caption, the spoken
question captured at caller speech start, and its timestamp. Database transcript
finalization may lag; it is not the source of current consent. Inbound metadata
and model-writable variables cannot replace this binding.
takeda_prepare_handoff performs a bounded semantic check against that evidence,
requires an exact caller quote, and saves only the selected discussed patient
as escalated. Missing or ambiguous evidence leaves the AI conversation open.
Only the tool's escalation_ready receipt sets the sparse, application-owned
flag bound to end_session.session_escalated. The compact phone preview remains
separate from the full parent-Case history and policy summary.
The saved Takeda script Studio suite covers the two-patient journey,
sarcastic acceptance, a declined offer, ambiguous thanks and a direct request.
Seed it with seed.ts takeda-script-voice 4453; run with connected tools and
audio. Superseded immediate-transfer cases remain in history but are disabled.
Read the actual transcript and tool receipts alongside the scorer's result.
The refusal case accepts an explicit finish such as “that is all”; a literal
second goodbye is not required. Its empathy, non-escalation and continued-help
checks remain unchanged.
Coordinator ANI matching accepts either the Person Account's phone or mobile,
while still requiring a unique care-team membership and verified provider
relationship. Denise's primary phone was edited by another Salesforce user on
September 30. Preserve that value; the approved +18042218211 test ANI belongs
in her mobile field. Do not restore an older primary-phone value over a user's
edit or bypass coordinator verification to make a rehearsal pass.
Insurance preparation is a readback stage, not a Salesforce save. Every
correction needs a new complete readback and caller confirmation. A premature
confirmation tool request returns the staged plan as awaiting_confirmation
without writing Salesforce. Invalid dictated fields return bounded
clarification_required guidance; infrastructure errors remain generic.
The draft Voice Agent carries the corresponding separate-turn instructions.
Its save acknowledgment explicitly distinguishes the completed Salesforce
update from pending payer verification. An explicit caller goodbye delegates
silently to the backend; the voice layer gives its single farewell after the
successful end-session result.
Its repeat-run qualification is tracked in demo qualification.
If Salesforce times out acknowledging parent or patient Case creation, the service reads the same unique external key once and validates its relationships. A matching stored Case establishes the outcome without another write. The insurance composite follows the same rule using its unique benefits Task key, then verifies the Task's caller/case links, the exact Member Plan fields and operation ID, and the closed child Case. It never repeats an uncertain composite POST. A missing record, failed readback or rejected request still fails. Startup diagnostics separate JWT session-refresh duration from slow or failed Salesforce request duration. They log only method, status, elapsed milliseconds and error class; record IDs, queries, request bodies and credentials are excluded. The configured synthetic Anthem payer accepts the caller's “Anthem Blue Cross” and “Anthem Blue Cross Blue Shield” wording. Other payer names require clarification before preparation; they are not reported as a Salesforce outage. The complete readback and fresh caller-confirmation gate still apply. Spelled numeric group identifiers accept the transcript tokens “zero,” “oh,” and “o” as zero, preserving every digit including leading zeros. An audio test exposed a partial parse of “six o one four” as “6”; that input must compare as “6014” before the complete readback. Member identifiers remain alphanumeric and are not subject to this numeric-group normalization. The latest correction also accepts punctuation such as “the group number is, six zero one four.” Grouped number words such as “six hundred fourteen” require the caller to read individual digits; they cannot be partially parsed as “6” or cause an older group value to be reused.
The human appeal extractor treats supporting-note confirmation independently
from therapy and outcome confirmation. A question from either speaker does not
confirm a note, and an earlier yes about treatment does not transfer to the note.
refine-takeda-note-consent.ts applies the bounded clarification to an existing
draft while retaining its catalog, integrations and other fields. Requalify that
draft in each environment before publication.
Separate Macau Salesforce app¶
sfdc/takeda-macau defines Takeda Clearway Macau, its
Takeda Macau Voice Call page and Takeda Clearway Macau Demo permission
set. It reuses the Takeda journey components and Salesforce layout. The page's
trueserveConnection is Macau; the existing Vanguard app retains its own
connection.
salesforce-city.py generates this project from the maintained Takeda app/page
and a retrieved Named/External Credential reference. Supply the target surface
config ID and the verified HTTPS service origins. Credential metadata contains
the bearer formula only. Provision BearerToken on
TrueServeMacauCredential / ServiceAccount through Salesforce's credential
API, using a target-city tenant token. Never put its value in metadata or Git.
The API endpoint is /services/data/v66.0/named-credentials/credential.
Deploy the connection Custom Metadata and credentials before the page: its
connection picker validates against records already present in Salesforce.
Then deploy the whole app and assign Takeda_Clearway_Macau_Demo to the demo
user. Allow the exact DevSDO Lightning hostname in the Macau tenant and verify
both a real embed-token mint and a conversation lookup through the Named
Credentials. A health endpoint alone does not prove credential authorization.
The Voice Agent's Salesforce JWT integration must also authenticate from Macau;
an existing integration ID does not establish that its private key is current.
Retain an encrypted backup before repairing an outdated connection.
The separate app does not itself assign a telephone number. Bind a distinct Macau contact flow and published agents after that city's qualification; keep the current Vanguard number routed to Vanguard.
Native human workspace¶
The September 30 architecture uses native LWCs in the center and a Copilot catalog in Agent Assist. The existing Clear Connect Case components are the visual reference. Normal VoiceCall highlights remain above the workspace. The older composed catalog journey below is retained for historical versions.
takedaVoiceWorkspace resolves VoiceCall.RelatedRecordId to its parent Case,
reads child Cases and their linked care records, and selects the escalated child.
takedaCaseSnapshot renders the hierarchy; takedaInquirySummary renders the
patient and submission timeline. Reads use the representative's record and
field permissions. An empty hierarchy stays empty.
TrueServe_Context_Takeda_Call calls TakedaVoiceWorkspaceController.readContext.
Its recordContext JSON output contains the parent, discussed patients and
their policy evidence. Agent Assist sends this as context.ready and subsequent
context.updated events, available to prompts as
{{HostContext.context.recordContext}}. Context never replaces trusted session
identity. RefreshView rereads Salesforce before posting an update.
The Transfer summary worker listens only to those context events. Its
editable prompt selects a multi-patient, single-patient or greeting card from
the supplied records; it contains no patient names. The policy worker uses
the selected or uniquely escalated child's recorded evidence. The
patient-appeal worker emits three extraction groups without a sidebar card.
The LWC receives them, preserves manual edits and saves through Salesforce.
The summary and statistics follow the selected patient. Days use that Case's
snapshot and Care Request date; submission counts include only completed
historical submission Tasks, never interaction or demo receipt Tasks.
Request review remains the default internal workflow. The two Takeda pages
enable Demo actions: Submit appeal and Notify Sam create idempotent,
labelled demo Task receipts after all three fields are saved. FRM recording
requires the appeal receipt first. These actions enforce sandbox, interaction
membership and demo-record scope; they do not call a payer or send a message.
The manager name is configurable in Lightning App Builder.
TrueServeCopilotEvent__c carries record-scoped messages between the wrapper
and LWCs. Every raw SDK event is forwarded, even if a card also consumes it.
Catalog actions such as case.focus and appeal.open reach the LWC through
the same channel. Native selection/save events can trigger configured Copilot
workers; a successful form save also sends targeted form_context confirmation.
See Copilot host events and the
bridge protocol.
Conversation-end field mapping¶
The Voice Agent keeps its existing GPT-Live configuration and adds
Takeda — Voice interaction field mapping to lifecycle.on_complete
(Vanguard 1852, Macau 1755).
The agent prompt adds named properties to end_session.params. Its
merge_bind.params merges the current server-produced takeda_transfer_params
over that object, retaining verified record IDs and canonical outcomes. Ordinary
bind.params would discard the extracted fields and must not be used here.
The prompt requests EscalationReason for an unresolved request, and
builtin_tool_configs.end_session.params_fields describes that string field in
the tool schema. Edit the
workflow's Assignment and Salesforce nodes to map additional properties:
| Lifecycle input | Salesforce destination |
|---|---|
context.session_end_params.InteractionSummary |
Parent Case.Description |
context.session_end_params.summary |
VoiceCall.DCC_Summary__c, with full summary fallback for older agents |
context.session_end_params.CustomerName |
VoiceCall.DCC_Caller_Name__c |
context.session_end_params.EscalationReason (fallback: RequestReason) |
VoiceCall.DCC_Call_Reason_Display__c |
Lifecycle inputs are under context, not directly under trigger.
The Case retains up to 8,000 summary characters; the VoiceCall preview is
bounded to its described 255-character field.
The runtime submits end hooks to the durable workflow queue, so CRM retries
survive the voice session closing. The workflow finds the parent by the trusted initial Connect UUID and its
unique external key. Model-supplied record IDs are not write authority.
It requires a nonempty summary and exactly one parent, then briefly retries
the linked VoiceCall lookup. An interaction ending without transfer can still
save the parent summary. The compact preview is also passed in Connect
attributes before ringing; it does not wait for this post-conversation workflow.
install-native-assist.ts --apply publishes the catalog and mapping workflow,
then saves revision-guarded agent drafts. It does not publish the agents.
The installer purges the two affected collaboration rooms and reads the saved
Voice draft back. Resetting a room alone allowed an open editor to restore an
older end-field configuration during the September 30 rehearsal.
native-workspace-rehearsal.ts uses actual Salesforce records, the mapping
workflow and synthetic stereo through the Connect client. It checks the
pre-speech transfer, LMS actions, extraction and real Case/Task saves.
It does not exercise PSTN. --reuse-fixture retains this script's Case fixture
but creates a fresh VoiceCall because VendorCallKey is create-only.
The current saved Copilot suite is Takeda native: three startup tests with
no patients, one patient and two patients using different synthetic names.
They inject frozen context.ready events and verify that the published
TransferSummary preserves supplied records without introducing the script's
patients. The earlier composed-center suite is disabled, with its history
retained. The native browser rehearsal covers LMS actions, policy evidence,
headless form updates and real Salesforce saves.
The TransferSummary title schema permits only the three designed headings:
Ready to help, Transfer summary, and Transfer summary · Multiple patients.
This keeps the header consistent while caller, organization and patients remain
context-driven; a replay caught an invalid separator in a freeform heading.
The September 30 native rehearsal passed in both cities: pre-speech transfer,
LMS appeal action, all three captured groups, Case save and internal review Task.
The Apex run passed all three workspace-controller tests. Current publications
are Vanguard Copilot 4450:v17 / Voice 4453:v15 and Macau
Copilot 4450:v3 / Voice 4453:v3; the catalogs are 4.1.8 and 3.1.2.
Mapping workflows are Vanguard 1852:v9 and Macau 1755:v3.
All three native Studio startup cases passed in each city.
The first card appeared 6.3 seconds after synthetic Connect startup in Vanguard and 5.7 seconds in the warm Macau published-agent rehearsal, including session setup. Macau's first cold rehearsal after deployment took 53 seconds. Warm the development environment with a rehearsal before presenting; these observations are neither a latency guarantee nor a PSTN/Kinesis measurement.
Historical composed human journey¶
The following describes the earlier catalog-owned center. New native-workspace
releases do not use CaseBrief, PatientJourney, the old center API actions,
or copilot_composed_layout. Their schemas/renderers remain available so
previously published agents and historical replay still resolve.
The takeda-assist catalog composes a persistent CaseBrief workspace and
PatientJourney rail. Native policy, coaching and appeal extraction workers
retain their tools, schemas and timing, but use layout_region: context.
Their output feeds the composition rather than another visible card. Both
components receive the same conversation's relatedSurfaces. The native
appeal form has three independent fields: prior trial, outcome and supporting
note. The trial appears after therapy, dose, route, frequency and dates are
all known. Each group can complete before the others; a representative's
question alone never confirms the supporting note. Legacy seven-field
surfaces remain readable in historical replay.
The opt-in surface flag copilot_composed_layout removes generic card chrome.
| Design | Live behavior |
|---|---|
| 1 | Verified parent/child Case tree, Renee timeline and Voice Agent handoff |
| 2 | Payer criteria evidence and Start Appeal / View Payer Bulletin |
| 3 | Loading state while the Salesforce appeal draft opens |
| 4–7 | Nine Salesforce case fields; prior-trial, outcome and clinical-note capture; synchronized checklist |
| 8 | Salesforce review receipt, pending-review timeline and a stored clinic visit |
| 9 | Actual follow-up Task receipt and wrap-up coaching |
Only patients discussed in this call appear. Preserve all three when Marisol was discussed even though some designs show two. Birth date, payer, owner, counts and clinical fields come from Salesforce; illustrated sample values do not override records.
Surface actions use /api/takeda/interactions/:conversationId, forwarding the
matching embed cookie to ai-manager's
/api/embed/takeda/interactions/:conversationId. The latter validates signature,
tenant, agent, Salesforce audience, conversation, original Connect contact and
parent/child relationships. Shared views cannot use this route. POST requires
same-origin JSON at the BFF. Completed calls load context but reject mutations
as soon as the native conversation ends, even if Salesforce's call-end
timestamp has not arrived.
Save Draft persists three short confirmation fields on the escalated child
Case. DevSDO exhausted its custom long-text allowance, so these fields are 255
characters each; input and server limits agree. Submit Appeal atomically
saves the values and creates a Salesforce internal-review Task. It does not
submit to a payer. Send Note saves a completed Task linked to the clinic
contact; it does not email that contact. Add Follow-Up Task creates a
pending Task. Unique operation keys, case revisions and per-case transaction
locks protect retries and stale edits. Both panels invalidate their read after
an acknowledged write, with a 15-second visible-page refresh for outside edits.
Saved representative corrections take precedence over old extraction on reload.
model-metadata.py owns the additive fields and permissions.
seed-design-context.ts YYYY-MM-DD fills only missing synthetic clinical fields
and creates the dated Sam Fieldmann visit, preserving existing birth dates and
plans. configure-journey.ts --appearance updates the current Copilot draft
without replacing its extraction configuration. Publish after validation.
visual-check.ts renders all nine stages and checks progressive controls plus
narrow-panel overflow. journey-api-check.ts verifies signed-session negative
controls and completed-call reads against DevSDO. Visual fixtures alone do not
prove a PSTN handoff or Salesforce write.
The Voice Agent's end_session.params binds to a server-produced transfer
object captured from Salesforce tools. bind-takeda-transfer.ts uses the native
sparse session-variable contract to preserve JSON without string coercion or a
model-editable typed slot. Undeclared-slot authoring warnings are expected:
a session-start rule seeds a factual empty recap, then tool receipts replace it.
Qualification must inspect the executed transfer payload.
Insurance confirmation is scoped to Marisol's request. Denise may confirm the staged plan and explicitly move to Renee or Thomas in the same reply; “Renee has no PA decision” does not negate the earlier confirmation. Corrections within the confirmation, or an explicit later correction to Marisol, prevent the write.
Installed assets¶
| Asset | Identity |
|---|---|
| Tenant | TrueServe |
| Copilot | 4450 · Takeda Clearway Copilot |
| Voice Agent | 4453 · Takeda Clearway Voice Agent |
| Catalog | takeda-assist · Agent Assist catalog; installation receipt records the current revision |
| Branding | 996c9de8-a2db-49ec-ac8c-8fb84175d0f3 |
| Salesforce app | Takeda_Clearway · Takeda Clearway |
| Voice Call page | Takeda_Voice_Call |
| Demo workspace LWC | takedaVoiceWorkspace |
| Connection | Vanguard |
| CCaaS target | DCCDev Connect · ec667d5f-cb9c-4423-a6d1-0626d1c9ef72 |
| Published agent versions | Vanguard Copilot 4450:v15, GPT-Live Voice Agent 4453:v13; both have Connect availability enabled |
| Salesforce read integration | f28f65a9-0598-47df-8d08-77f7282a8f09 · TrueServe Dev SDO |
| Salesforce context tool | b93eed63-ef0c-4214-aed0-06d389d42490 · takeda_salesforce_context |
| Connect demo number | +17708219161 |
| Inbound flow | ea1f55f1-0eb3-440d-8898-946258e92bd3 · Takeda Clearway - Erik Golden |
| Customer whisper | 942417a1-2dd4-4c46-838b-90bb24f35d07 · Takeda Clearway - Start Copilot on Answer |
| Session Lambda release | trusrv-dev-orch-connect-session-start:takeda-vanguard · published version 5 |
The current installation identifiers and publication results are also written to .local-data/takeda-demo/installed.json and agent-publication.json. These local evidence files are not committed.
The Voice Agent's database classification is pipeline_type=speech_to_speech
and subtype=voice_agents; config.agent_type=voice_ai is a separate runtime
field. install-voice.ts uses the shared pipeline constants for both draft
creation and updates. On September 30, Vanguard agent 4453 had mistakenly
stored voice_ai / voice in its identity and version classification fields,
so Preview showed “Testing is only available for Voice Agents and Chat Agents”
despite a passing runtime preflight. Those metadata fields were corrected on
the identity and all 13 existing versions, preserving configs, publication
state and traffic weights. Reload the editor after a classification repair;
no new publication is needed.
Copilot version 13 was published from the nine-case candidate that passed
90/90 first attempts, batch d0480a27-4f9e-46e5-9b84-17bc5e104c9c.
The September 30 rehearsal then passed against that release: synthetic stereo
human audio drove the real Copilot and Salesforce, including automatic appeal
field capture, failed-save recovery, stale-write rejection, idempotent review
and note actions, and completed-call reload. This rehearsal did not place a
PSTN call. The nine supplied SVGs apply only to this Takeda journey.
journey-rehearsal.ts --environment vanguard|macau checks the effective city's
PUBLIC_FQDN, selects its Salesforce app and DNIS, and verifies the workspace
iframe loads that city's Surface runtime. It uses the configured Salesforce
integration for fixture records. Browser access uses the local devsdo CLI
login, or --storage-state /private/path.json for an already authenticated
Playwright session belonging to the demo user. Keep that session file private,
outside Git, and remove it after the rehearsal. The script does not sign in
the integration user as the human representative. Outputs are separate under
.local-data/takeda-demo and .local-data/takeda-demo-macau. Its synthetic
stereo audio uses the local city's production gRPC client; it does not require
or claim a working PSTN route.
Install Playwright Chromium and its system dependencies in the test container
before running the browser rehearsal. On failure, private evidence includes
panel text and the test Cases' deletion/modification audit. This distinguishes
an application failure from a shared-org edit that removes the parent and
clears its Voice Call/child links. The failed attempt remains recorded; the
rehearsal does not restore deleted Cases.
Voice journey and historical composed behavior¶
The voice phase below remains current. Center catalog controls describe the earlier composed release; use Native human workspace above for the LWC page and its Save draft / Request review controls.
The script has two distinct phases: the Voice Agent handles Thomas and Marisol, then transfers Renee to Marcus, assisted by the Copilot. The previous human-first implementation misread this boundary. The corrected handoff is generated from this call's real Salesforce reads and insurance receipt; gallery examples never become live call context.
| Point in the script | Center workspace | Agent Assist rail |
|---|---|---|
| Flow recognizes ANI | Parent Case linked to coordinator and provider is created before the Voice Agent starts | No patient Cases yet |
| Thomas appeal lookup | Voice Agent reads the unique Salesforce case and relays approval | New child Case records this call’s request; historical appeal is unchanged |
| Marisol plan change | Voice Agent collects, reads back and confirms the four fields | Native Member Plan update, child Case outcome and benefits Task receipt |
| Renee repeated PA issue | Voice Agent saves handoff and ends with escalation | Connect resumes and rings the presenter |
| Human answers | Renee's case, 14-day age, 9-day payer average and three dated submissions | Verified Voice Agent journey and opening coaching |
| Denise asks what changed | Before/after fictional payer criteria and the qualified likely cause | Empathy and next-step cue |
| Prior Renbrivex trial is discussed | Appeal fields appear and update on one stable surface | Next missing question |
| Outcome and existing note are confirmed | Three independent confirmation groups, editable by Marcus | Checklist updates for each confirmed group |
| Marcus selects Submit Appeal | Saved review Task receipt; corrected values reach the native form processor and become Completed | Payer submission remains outstanding |
| Marcus selects Send Note | Saved Salesforce Task receipt for the recorded clinic visit | Wrap-up coaching |
The composed workspace keeps the Case tree and current work together. Save Draft saves the full reviewed snapshot, including intentionally blank fields; a later extraction cannot silently restore a removed saved value. Failed saves retain the edits and show no success receipt. Repeated submissions return the original Task instead of creating duplicates. A stale revision returns a conflict for review.
After a confirmed Salesforce review save, CaseBrief awaits
copilot.form.complete with the exact three reviewed values. If that
acknowledgment fails, the Salesforce receipt remains visible and Retry
confirmation resends only the Copilot event. It does not repeat the
Salesforce write.
The Takeda workspace enables Fit Composed Workspace Content in App Builder. The surface reports its measured content height through the existing origin- and embed-bound bridge; the Salesforce host constrains it to 200–2000 px. Other embeds retain their configured fixed height unless opted in.
CaseBrief now displays the verified Renee handoff in the center, and PatientJourney displays only patients actually read during the Voice Agent conversation. PolicyInsight, AppealDraft, CoachingCue and CallWrapup continue updating during the human conversation. PatientCase remains available for historical replay. The CSS root includes the publisher's tsf-catalog-takeda-assist scope.
The live Salesforce integration reads Care Programs, enrollments, Member Plans, Care Requests, workflow Cases and submission Tasks from DevSDO. These are real API reads of fictional demonstration records. The case timeline uses a fixed September 12, 2026 snapshot so “14 days since August 29” remains coherent. After confirmation, the Voice Agent updates Marisol’s native Member Plan, closes her interaction child Case and creates a benefits Task. No payer API exists: neither benefits eligibility nor appeal submission is claimed complete.
Insurance preparation and confirmation reject a staged numeric group that differs from an explicit caller dictation, including individually spoken digits and leading zeros. A contradiction requires a corrected preparation, readback and fresh confirmation before any write. A plain affirmative still confirms the existing prepared plan; it cannot supply new identifiers.
Salesforce read path¶
POST /api/mcp/takeda requires a tenant API token with agents:run. The installer stores its bearer secret encrypted on the MCP tool, never in the catalog. The endpoint restricts requests to the configured tenant and named Takeda Voice Agent or Copilot 4450. Voice tools bind the current conversation through native MCP parameter bindings, read recorded caller turns for patient selection, and recognize the trusted inbound ANI. Copilot reads resolve the linked VoiceCall by VendorCallKey. Both resolve Denise’s Person Account through her Care Program team membership and active Office Coordinator Account Contact Relationship to Crestview, whose parent Account is Mayo Clinic.
Voice state is stored under conversations.metadata.takeda_voice, with per-patient SQL merges. Insurance preparation is separate from mutation; confirmation must be a newer recorded affirmative caller turn. A per-plan transaction lock and deterministic operation key protect retries. Salesforce Composite allOrNone writes the Member Plan, child Case and Task together; a native-field readback verifies the receipt. Writes require the exact patient and labeled demo plan. Benefits Task External_ID__c is unique, so a retry cannot duplicate the request.
Dictated member/group identifiers normalize grouping whitespace and letter case only. Letters are never guessed from digits or vice versa. A correction requires a new preparation and readback; “That is not correct” and other corrective or negated answers cannot authorize a write. MCP failures record the operation and bounded error reason on the server, without arguments or credentials.
Connect's original contact UUID is persisted from Chime's system metadata on the
voice leg and from InitialContactId through Lambda/KVS on the human leg.
Asterisk supplies the Connect UUIDs as separate Stasis arguments; ARI forwards
validated UUIDs into MediaProxy metadata only after the Connect integration
passes validation. It does not depend on custom SIP headers being present.
Renee’s voice request calls takeda_prepare_handoff directly: it performs patient verification, child creation and escalation in one operation, avoiding a duplicate read/planner round trip. The human handoff reads the parent Case referenced by VoiceCall.RelatedRecordId or trusted Connect metadata, verifies its original contact UUID, coordinator and provider/program, and reads its child Cases. It survives removal of the Voice Agent’s cached handoff. There is no recent-phone-number fallback.
Incoming Omni-Channel preview¶
Every successful Voice Agent tool returns transferParams, built from the
current conversation's saved caller identity, case reads and insurance receipt.
The agent copies the latest snapshot into end_session.params.
ParentCaseId identifies the interaction, PatientCaseIds is a JSON string
mapping each discussed patient key to its actual Salesforce child Case ID,
and EscalatedCaseId identifies the child needing the human. Case numbers and
patients not discussed during this call are excluded from that mapping.
ARI writes these string attributes to the original Connect contact before
ending the AI leg, so the resumed flow can ring the human with the recap.
No additional summarization model or lookup runs in the ringing path.
The compact recap is at most 240 characters and leads with Renee's escalation, then Thomas's recorded appeal status and Marisol's confirmed outcome. An unconfirmed insurance change remains pending even if an earlier demo call already updated the Salesforce case. Patients never read in this call are omitted. Member IDs, group numbers and clinical details stay out of this preview.
CustomerName, CustomerRecordId, CustomerOrganization and the compact
summary also populate the native SCV Contact. Older integrations without a
compact recap fall back to InteractionSummary.
The SalesforceFields JSON string supplies these writable VoiceCall fields:
| Field | Content |
|---|---|
DCC_Caller_Name__c |
Verified caller and organization, e.g. Denise Warren - Mayo Clinic |
DCC_Call_Reason_Display__c |
Current request, e.g. Renee - Prior authorization escalation |
DCC_Summary__c |
Bounded recap of verified outcomes |
RelatedRecordId |
This call’s parent Case; CustomerRecordId remains the coordinator Contact |
DevSDO's DCC_Connect record type uses DCC_Connect_Handoff, with just
DCC_Caller_Name__c and DCC_Summary__c: caller/organization first and the short
recap below. The phone number, duplicate reason and separator are omitted.
The maintained compact-layout metadata is in sfdc/takeda-demo. Assign it to
the Connect record type in new orgs; the existing Genesys layout stays separate.
The original reason/summary formula fields remain available on record layouts;
do not write those formulas.
Refresh Salesforce once to load the updated connector bundle.
The connector must send these fields in the initial CALL_STARTED event's
callAttributes using sfdc- keys. DevSDO's native formatter removes that
prefix before creating the VoiceCall. CallInfo.additionalFields alone does
not reach this creation path. The September 30 incident had the correct Connect
attributes and completed-call fields, but neither proved the incoming card had
received them. A native handleCallEvent check now verifies the name and recap
are saved while disposition is still new, without a lifecycle update.
DCC_Connect_Update_Case_Owner version 3 is maintained in the Takeda Salesforce
project because it repairs DevSDO's existing shared Connect flow. It applies
to all DCC_Connect calls with disposition in-progress and a human owner.
It assigns the directly related Case and preserves the existing Task assignment
when a Task exists. Missing Tasks and missing related records are valid; the
flow never updates a record variable without an Id or creates a dummy Task.
Completed calls keep their Case owner. The prior flow version updated only a
Task despite its label and failed when the lookup returned none.
Run DCCConnectOwnershipFlowTest after deploying this flow. Its four tests
cover missing/existing Tasks, absent/non-Case links and completed calls.
CallDisposition is create-only through ordinary Salesforce DML, so the tests
create an in-progress call and update writable ownership fields to execute
the real flow branch. Attempting to PATCH the disposition silently leaves the
old value and does not test that branch. Confirm the test run's actual count:
the metadata deployment reported zero tests even with RunSpecifiedTests;
the explicit Apex test run executed all four.
Voice lookup uses the latest patient-bearing caller turn, retaining it during field-only answers. Earlier patients cannot contradict a later request. Exactly four spoken or spaced digits in an explicit member/ID-ending phrase are normalized for matching; conflicting identifiers still require clarification.
The native Copilot tool_logic.bind inputs supply the session ID and live utterance/history. Unmatched speech returns JSON null and produces no card or model finalizer. A conflicting known member suffix is not accepted. The descriptive appeal lookup must find exactly one matching case in the snapshot week. Policy lookup requires a relevant question and either a customer mention of Renee or the verified Voice Agent handoff.
The Salesforce integration uses JWT bearer authentication with a short in-memory token cache and one reauthentication on HTTP 401. Caller/practice binding is cached for at most one minute per tenant/conversation; case contents are fetched anew. No-match, ambiguity and API failures never fall back to gallery props or the old handoff tool.
| Patient | Salesforce Case | Case number |
|---|---|---|
| Thomas Whitfield | 500DW00000GaiTxYAJ |
00021125 |
| Marisol Ibarra | 500DW00000Gaih7YAB |
00021139 |
| Renee Catellano | 500DW00000GaiiYYAR |
00021140 |
These are historical workflow Cases, not the new interaction child Cases. Native reads use CareRequest.MemberId and CareRequestCaseId; submission evidence comes from Tasks on the workflow Case. Legacy Description snapshots remain only as fixture migration markers. They are not the runtime data source. Queries are bounded and fail closed on ambiguity.
Native Salesforce care model¶
The supplied Coordinator_Patient_Program_Provider_Data_Model_v2.docx is the model authority. The maintained metadata is under sfdc/takeda-demo.
| Record | Relationship |
|---|---|
| Denise Warren Person Account | Underlying PersonContactId is the coordinator Contact |
| AccountContactRelation | Denise Contact → Crestview business Account; active Office Coordinator |
| HealthcareProvider | AccountId → Crestview; Crestview.ParentId → Mayo Clinic |
| CareProgram | Clearway - Crestview; Provider__c → Crestview |
| CareProgramTeamMember | AccountId → Denise; CareProgramId → Clearway; Care Coordinator role |
| CareProgramEnrollee | AccountId → patient Person Account; CareProgramId → Clearway; PrimaryMemberPlanId → patient plan |
| MemberPlan | MemberId → patient; PayerId, MemberNumber, GroupNumber and EffectiveFrom are native fields |
| CareRequest | MemberId → patient; MemberPrimaryPlanId → plan; CareRequestCaseId → historical workflow Case |
| Call parent Case | ContactId → Denise; AccountId and Takeda_Provider__c → Crestview; Takeda_Program__c → Clearway |
| Patient child Case | ParentId → call Case; AccountId → patient; Takeda_Provider__c, Program, Enrollee, Plan, Request and Source_Case preserve the care graph |
The inbound flow invokes the existing session Lambda with operation=initialize_case before the Voice Agent. CONTEXT_ENDPOINTS and CONTEXT_TOKENS map the flow-owned environment label to the authenticated MCP endpoint. The returned ParentCaseId, caller, provider and program attributes survive the transfer. The same associated Lambda is reused because dccdev’s Lambda association quota is full. A transient service failure or Lambda invocation error retries initialization once using the same InitialContactId. The existing external-ID and transaction guard reuses a Case whose first write finished after the six-second HTTP timeout. An invalid receipt or a second failure routes to the human without claiming verified patient context. Each attempt is bounded by the seven-second flow invocation timeout; there is no retry loop.
The maintained Connect installers accept --environment vanguard|macau.
Macau deployment requires its own E.164 --phone; flow installation also
requires --phone-id, --voice-connector and the migrated --voice-agent.
--copilot-only omits the Voice hop entirely, permitting human testing with
the published Copilot before the Voice Agent is ready. It still initializes
the coordinator Case and starts both audio directions on answer.
Each city receives a separate Lambda alias, ingress group, inbound flow and
whisper. The installer probes the immutable Lambda version before moving its
city alias. Existing environment mappings and ENI security groups are retained.
Set server-side TAKEDA_DEMO_DNIS to the city's number before probing the
initializer; the unset default remains Vanguard's +17708219161.
Macau now uses +1 833 851 8680, repurposed from the retired AutoDesk test
line at the user's request. Its original flow
28bc20f0-d399-460a-a7b2-b685f22a1258 is now Takeda Clearway Macau - Erik Golden.
The published route starts Voice Agent 4453, then transfers Renee's case to
Erik's existing Connect agent and Copilot 4450. Its connected Salesforce
smoke and published flow/authentication checks passed on September 30;
the new number still requires a live PSTN acceptance test.
The former reserved +17708219575 remains unassigned.
connect-voice-connector.py prepares a separate encrypted Macau connector to
macau.trueserve.ai:5065. --reuse-connector-id can adopt an explicitly selected
disabled legacy demo connector, preserving its original settings in a private
backup. The reused connector is f8zxqbwmfsbvkp2bqxlpug, now named
trueserve-takeda-macau; no quota increase is needed for this route.
connect-flow.py --reuse-flow-id requires that flow to be the selected number's
current route and refuses a flow shared by another number. It backs up content,
metadata and phone association before changing them.
The read-only connect-check.py accepts the same city/number/Voice options.
For rollback, restore the backed-up flow content/name/tags, connector
name/origination/tags and phone description, then restore the saved Macau
environment file and restart only its manager. Keep the existing resource IDs.
The dedicated Salesforce TrueServeSurfaceAppMacau trusted site explicitly
enables isApplicableToFrameSrc. An active trusted-site entry alone does not
permit framing: the September 30 browser rehearsal otherwise left both panels
loading while Salesforce blocked the Macau iframe. Refresh the Lightning page
after deployment and verify the embedded Surface hostname and real Case receipts.
The initializer reads the coordinator graph and existing interaction Case in
parallel, retaining the transaction lock and all caller/provider checks before
creating anything. Lambda logs include request duration and error class/status,
without endpoint URLs, tokens or response bodies.
Parent and child Cases use the existing unique External_ID__c: takeda:<tenant>:<original-contact-uuid>:parent and a patient suffix. Repeated initialization returns the same parent without resetting status or outcomes. Each patient child is created only after recorded caller identification. Renee’s child is marked IsEscalated; the parent remains linked to the VoiceCall. Historical CareRequestCaseId links are never moved to a new interaction Case.
Thomas uses the explicitly bound original native Care Request
0UmDW0000004CNZ0A2 after the data owner removed the generated duplicate. Its
workflow Case and request-linked Member Plan must both belong to his verified
patient Account. That request supplies the child-Case plan link when the program
enrolment has no primary plan; the missing enrolment link is not silently repaired.
The existing DCC_HC_Service_Request record type, original dates and decision
remain unchanged. Its explicit September 30 snapshot makes “last week” the
previous UTC calendar week, September 21–28, without drifting between demo runs.
Refresh that binding's snapshot when refreshing the source scenario. Generated
demonstration requests retain their September 12 snapshot window. No deleted record is restored, and plan relationships
remain required for child creation and insurance mutation.
Generated CareRequests and their workflow Cases use matching record types (Takeda_Appeal or Takeda_PA); explicitly bound original requests retain their native record types. CareRequest has no standard Status: workflow state is read from its Case. Tasks require explicit Takeda_Activity_Kind__c=Submission, completed status, Takeda_Submission_Outcome__c=Submitted and Takeda_Submitted_At__c to count as a submission. A completed call is not submission evidence. Open activities awaiting submission remain Not yet submitted; incomplete evidence stays Submission unknown. Sending clinicals does not prove payer receipt.
Renee’s age uses RequestedDate against the fictional September 12 snapshot. Policy evidence is stored on the Care Request. The center displays the parent Case and all child Cases actually discussed, with Renee highlighted as Current focus, followed by her submission timeline and statistics. Native links open the corresponding Salesforce Cases.
Install/update in this order:
- Run
model-metadata.py, deploy the generated objects andTakeda_Data_Model, then rungrant-model-access.py. The integration and presenter use existing Health Cloud Platform entitlements plus scoped Health Cloud feature permissions. - Run
seed-care-model.ts --apply --activate-callerwith the repository’s environment/TypeScript wrapper. It preserves existing plan updates, links the native graph, moves ANI to Denise’s existing Person Account and updates the cached Voice MessagingEndUser. DevSDO requires ten-digit US Account.Phone formatting; ANI resolution checks equivalent E.164 forms. - Stage/deploy the Salesforce wrappers with
salesforce.py, including the dedicated context controller and its tests. - Run
prepare-context.ts, thenconnect-deploy.py --applyusing the dccdev profile. Tokens remain in private local files. The installer probes creation and retry before promoting the Lambda alias; only its security group can reach the private Manager port. - Publish the catalog using
publish-case-catalog.ts, then publish agent changes usinginstall-voice.ts --publish. Runconnect-flow.py --applyto update the owned flow/number association. - Run
verify-care-model.ts,voice-rehearsal.ts,verify-voice-receipt.ts,verify-call-preview.tsandhandoff-rehearsal.ts. The voice rehearsal asserts zero children at call start and progressive counts 1/2/3. The browser rehearsal removes cached voice handoff state and verifies Salesforce reconstruction, patient links, escalation focus, policy and appeal capture.
Native care-model verification — September 29¶
The 4453:v9 voice rehearsal created parent Case 500DW00000Gaj1kYAB before opening audio, then asserted child counts 1/2/3 as Thomas, Marisol and Renee were discussed. The confirmed Member Plan readback matched Anthem / W28841207 / 6014 / October 1. Exactly one benefits Task remained Not Started after two concurrent confirmation retries. The control plane carried the parent Case ID, escalated child ID and exact preview fields.
The 4450:v9 DevSDO browser rehearsal used VoiceCall 0LQDW000001GAIf4AO. It removed the Voice Agent’s cached handoff first, then verified all three Salesforce child Case links and Renee’s highlighted escalation before any human speech. Policy and seven-field appeal capture worked without repeating the patient name. The recorded outcome was captured accurately, representative confirmation succeeded, and confirmed values survived a page reload.
Native preview verification on VoiceCall 0LQDW000001GAIa4AO retained the caller label and recap in the existing compact layout while RelatedRecordId pointed to the parent Case. The original completed call 0LQDW000001GA0C4AW also showed Denise, Crestview and Mayo while the phone was offline, including recovery from an injected initial HTTP 503 and a full reload.
The latest Lambda version 5 probe created a parent in 1,941 ms and returned the same Case on retry in 341 ms. A separate API check created a parent in 1,422 ms and verified two concurrent retries. These are individual observations, not latency guarantees. One earlier cold request exceeded its timeout; failure paths do not fabricate success. The voice rehearsal’s first-audio measurements were 517 / 1,162 / 1,128 / 1,388 / 10,563 ms; the Renee transfer turn was slower. Version 10 removes the repeated patient lookup by calling the verified handoff operation directly; a focused Renee-only speech rehearsal passed with first audio in 1,317 ms. The two inputs differ, so this is not a controlled latency comparison. These do not measure completion of each spoken answer.
Validation includes 107 connector tests, 28 Lambda/flow tests plus 14 subtests, eight native-model/voice unit tests, 14 sidebar tests, successful Manager typecheck and lint without errors. The 30-test Apex run passed. The latest context-controller changes also passed their two focused Apex tests with 92% coverage of that controller. Deployment success alone does not prove tests ran: the initial deployment reported zero tests, so its controller tests were executed separately. Audio and browser rehearsals do not prove the next physical PSTN handoff; inspect that call’s Connect ID and Salesforce hierarchy when testing the number.
Generic placement and historical workspace contract¶
These shared surface options remain available to other agents. Takeda's native release places its catalog cards in the rail and uses LWCs for the center. Host context and event triggers are documented above; the old tool-projected startup handoff below is retained only for previous versions.
Each worker stores layout_region: "rail" or "workspace". The Display in control in the Copilot editor selects it. Custom workers and form workers propagate the region to their A2UI events, including form completion and applicability status.
Card at call start sets initial_response on a custom or coaching worker.
The runtime validates the authored response against the extraction schema and
emits it once after StartFrame, before transcripts. It creates no synthetic
utterance and runs no model or tool. Use this only for non-personal greeting
guidance. Invalid props are skipped.
Load context at session start sets run_on_start on a custom/coaching
worker with tool_result_bindings. After StartFrame, it invokes the configured
tool once and validates the projected fields. It creates no caller utterance or
model-planner turn. Null/invalid/error results cannot produce patient facts.
End/Cancel cancels the lookup; real speech received during it is processed afterward.
The Renee handoff worker also captures the verified patient name into a session
variable, allowing the appeal form to recognize the transferred case without
requiring Denise to repeat her name. Clinical trial fields still require speech.
workspaceOnly=true renders only explicitly workspace-placed Copilot surfaces. railOnly=true renders the assist rail. Both consume the same authenticated conversation SSE and catalog renderer. The workspace wrapper requires an existing conversation; it never launches a second agent as a fallback.
An early SSE subscription can arrive after the native conversation row exists but before its first event. Conversation-api checks the native audio-session metadata before its text-session activation path. It must not start a second agent or overwrite the original contact/handoff metadata during that gap. Workflow-created conversations retain their existing text activation behavior.
Workspace content is also excluded from the ordinary customer canvas. Only the explicit workspace view renders these private representative surfaces.
The form's copilot.form.complete action carries copilot_id, form_id and reviewed confirmed_fields. Surface-app validates this shape and calls the existing setSessionVariables API with form_target, confirmed_fields, and form_control: "complete" in one update. Only an active, attached workspace accepts this action. Transport failures appear on the form and can be retried. Confirmation is separate from payer submission.
Surface-app now provides the missing POST /api/sessions/{sessionId}/variables
SDK bridge. It requires a valid embed session, rejects a mismatched conversation,
bounds the update size and variable count, and signs the upstream conversation-api
request. The SDK method alone did not make this browser route available.
Salesforce appearance¶
Takeda catalogue heading icons use the navy #072142 sampled from the
user-supplied image (16).png reference. This includes the Payer Policy Alert
and clinic follow-up icons in StageAssist, the journey card headings, and
the standalone card headings. The policy alert uses an outline triangle
without a pink override. Status badges, completion checks and action controls
retain their semantic colors.
Apply these stylesheet changes to both the repository's takeda-assist
source and its active catalogue workspace, then publish that catalogue.
Preserve newer workspace edits when syncing individual stylesheets.
takedaCallerContext retains the original dccContextSidebar stylesheet and its
profile/details layout: white container, native caller photo/initials, blue record
links, Personal Details grid and a matching Organization section. It keeps the
record-aware lookup and bounded retry behavior added for this demo. The calling
organization comes from the call’s parent Case and verified Account Contact Relationship. Denise remains a Person Account; Crestview and its Mayo Clinic parent appear alongside her. The dedicated TakedaCallerContextController preserves the shared resolver for older completed records.
Do not reintroduce a separate green sidebar theme.
The app inherits the same org theme as Orchestrator Console
(shouldOverrideOrgTheme=false). The embedded catalog uses Salesforce-style
13 px text, neutral cards, compact table rows, blue controls, 4 px field/card
corners and semantic status badges. Workspace views use an underline for the
selected view. Form values remain mounted while switching views.
appearance.ts is the demo's shared surface appearance definition. Run
publish-appearance.ts through the TypeScript wrapper below to publish catalog
visuals and update only the existing appearance record's color/CSS fields,
without rewriting agent workers or phone routing. appearance-probe.ts checks
the actual Salesforce page, published CSS, all three patient views, retained form
values and desktop/smaller-width layouts. --theme-only on the appearance
publisher updates the existing theme without publishing a new catalog version.
The embed font stack matches the current Lightning page's system font stack.
Screenshots and assertions are saved under .local-data/takeda-demo/.
Measured latency¶
These are local measurements, not provider guarantees or a broad statistical benchmark. Run date: September 29, 2026. Provider networking and load can change them.
| Transcription configuration | Connection | Final after detected speech end, p50 | p95 | Final results |
|---|---|---|---|---|
| Deepgram Nova-3, native stereo, 150 ms endpointing | 273 ms | 462 ms | 517 ms | 16/16 |
| ElevenLabs Scribe v2 realtime, two mono sockets, 300 ms VAD silence | 216 ms | 769 ms | 886 ms | 16/16 |
The same eight synthesized phrases are played on each speaker channel at real-time speed: PCM16, 16 kHz, 20 ms frames, four seconds of prewarm. Scribe uses its provider-native VAD settings; the platform Scribe wrapper does not currently expose that 300 ms option. Final latency is measured from the last 10 ms PCM window exceeding RMS 65; connection setup is reported separately. Audio-pacing maximum lateness was 1.5 ms for Deepgram and 4.8 ms for Scribe.
Both produced transcripts; that count does not mean every word or identifier was correct. Deepgram made numeric member-ID errors, including the new Anthem identifier. Review identifiers against the source record and read them back. Keyword hints are not proof of numeric accuracy.
| Strict JSON extraction model | Trials correct | Median request duration |
|---|---|---|
gpt-4.1-mini |
3/3 | 665 ms |
gpt-4.1-nano |
3/3 | 954 ms |
The human Copilot therefore uses Deepgram Nova-3 and gpt-4.1-mini. Small trial counts cannot establish a general model ranking. The model microbenchmark is a single short extraction; full native form extraction includes a larger schema, context, queueing and debounce.
Patient and policy cards project exact fields from live Salesforce tool results.
Greeting and common coaching cues use approved content. A successful patient
lookup replaces the rail's previous-patient guidance; it does not leave a
speculative missing-field question from the previous patient on screen. Native
forms provide the next missing question. The human appeal worker uses
gpt-4.1-mini with a 0.5-second debounce and no shared model gate.
The presenter selected native OpenAI GPT-Live after the initial cascade
rehearsal. The Voice Agent now has one GPT Live API speech-to-speech stage:
gpt-live-1, voice marin, client delegation to gpt-4.1-mini through Responses.
There are no separate STT or TTS stages in that agent. A brief generic opening
starts immediately; the first caller request delegates ANI recognition and case
work to the backend. The small model owns tools and business rules; Live owns
audio, interruption and spoken delivery. Client delegation waits for the native
caller caption to settle before taking the backend's conversation context, so
a request after Denise's introduction is not dropped. The stereo STT benchmark applies to
the human Copilot, not to GPT-Live latency.
GPT-Live verification¶
The September 29 native rehearsal passed on published 4453:v8, with one
GPT Live API stage and no separate STT/TTS stages. It exercised real audio,
native delegation, live Salesforce reads, a corrected insurance readback,
explicit confirmation, the Case/Task write, Renee's saved handoff, the spoken
transfer message and the native disconnect control. The native transfer
parameters exactly matched the successful handoff tool's transferParams,
including caller name, organization, record ID and every Salesforce preview field.
The first dictation was heard as W2A841207. The rehearsal supplied a real
spoken correction; only the corrected W28841207 plan was confirmed and
written. Formatting normalization never changed the letter into a digit.
Separate Salesforce readback verified the Case fields and exactly one
benefits Task, still Not Started. Two concurrent confirmation retries
returned the same receipt without adding a Task.
The five original caller turns received first audible responses in 621, 1189, 1387, 1000 and 1544 ms. These can be short acknowledgments, not the completed answer. This one direct-gRPC rehearsal does not measure PSTN, Chime or Kinesis latency. Caller speech was synthesized solely as test input; the agent's responses were generated by GPT-Live.
Evidence is in voice-rehearsal.json, per-attempt voice evidence,
voice-receipt-verification.json, and the separate handoff-rehearsal.json.
The latest successful voice source is
5a33ca55-bfca-4704-be2a-3c3dbf242b89.
verify-call-preview.ts feeds those exact parameters through the connector's
Connect Streams attribute mapping and creates a synthetic VoiceCall. DevSDO
accepted and retained all fields on 0LQDW000001GAGU4A4; the call-reason and
AI-summary formulas returned the expected text, and the Connect record type
selected TrueServe_Compact_Layout. A separate describe as the presenter's
erigolden@trueserve.devsdo user confirmed the inputs are writable and the
formula outputs readable. This checks the payload and native layout, not an
incoming phone call or the ringing UI. Evidence: call-preview-verification.json.
The earlier Salesforce browser continuation passed on VoiceCall
0LQDW000001GAF74AO, human conversation
8c7439e3-c79d-4370-98ea-9e42acbae155, using the 4453:v6 GPT-Live handoff
from voice conversation 62a2e84f-805b-4a12-99d6-bbdb7b049205.
Before human speech it loaded Renee's case, all three verified outcomes and
Denise/Mayo context, with no invented appeal fields. A different original
contact UUID was rejected. Policy and appeal fields then appeared without
repeating Renee's name. Representative review corrected “Discontinue” to
“Discontinued”; native confirmation and the reviewed value survived a full
Salesforce page reload. This exercises the production Java audio client and
Salesforce embeds, without traversing Kinesis or placing a phone call.
A fresh physical call is still needed to verify the complete GPT-Live phone-to-human route.
Reproduce¶
For the native workspace, deploy the maintained Salesforce project, run
install-native-assist.ts --apply, then run native-workspace-rehearsal.ts.
The older center/handoff probes below require their corresponding published
agent and Salesforce page; they are not checks of the new LWC architecture.
Run from the repository root with the local stack available:
# Seed/update only the labeled synthetic Salesforce cases and timeline comments.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/seed-patient-cases.ts --apply
# Initial catalog/Copilot bootstrap only; apply install-voice.ts afterward.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/install.ts
# Install/publish the Voice Agent and handoff-aware Copilot through the normal API.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/install-voice.ts --publish
# Real voice providers and real fictional-Salesforce writes, with readback receipts.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/voice-rehearsal.ts
# Verify actual transfer fields and their formulas on a synthetic DevSDO VoiceCall.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/verify-call-preview.ts
# Continue that exact saved handoff in the actual DevSDO browser and native Copilot.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/handoff-rehearsal.ts
# Read back the real Salesforce receipt and verify concurrent retries create no duplicate task.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/verify-voice-receipt.ts
# Real provider comparison; consumes configured TTS/STT/LLM integrations.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/benchmark.ts
# Historical human-first regression: use the corresponding old Copilot version.
# Actual Salesforce page, 8 kHz Connect client and iframe recovery.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/progressive-probe.ts --stall-frame
install-voice.ts prepares drafts; --publish publishes both agents through the normal authenticated API and enables DCCDev Connect. Use --voice-only to change only the Voice Agent. It preserves the Copilot's current catalog and appearance. It does not change the phone route; connect-flow.py --apply publishes that separately after rehearsal. Audio generation, provider calls and catalog publication use integration credentials in memory, without writing them into the catalog or logs.
Evidence lives under .local-data/takeda-demo/: benchmark results, native events,
transcripts, browser assertions and screenshots. The historical human-first
progressive-probe.ts opens the
actual Salesforce page before creating the conversation, waits 25 seconds, and
feeds synthetic audio through the production Java Connect gRPC client. It checks
silence/greetings reveal no patients, then Thomas alone, then Marisol, then Renee.
--stall-frame injects one HTTP 503 on the center iframe and requires automatic
recovery without Retry. This exercises the Connect audio client and Salesforce
embeds; it does not place a PSTN call or traverse Kinesis itself.
The rehearsal also confirms a reviewed form more than 125 seconds after the
greeting. Salesforce mint requests explicitly set ttlSec: 3600: surface-app
stores the signed JWT in its cookie and cannot extend its expiry. The previous
120-second API default caused late-call form requests and reconnects to fail
with 401. The one-hour Salesforce token retains tenant, audience, record binding
and single-use redemption; it is not a perpetual session.
Salesforce deployment and phone routing¶
The Salesforce generator derives a dedicated app/page from retrieved Orchestrator_Console and Voice_Call_Record_Page. It retains the existing phone utility bar and record context. The new app's VoiceCall overrides select Takeda_Voice_Call; other apps keep their existing pages.
Retrieve the reference metadata to /tmp/takeda-sf-reference in a Salesforce DX project. Then:
python apps/ai-manager/scripts/takeda-demo/salesforce.py
cd /tmp/takeda-sf-deploy
sf project deploy start --dry-run --target-org devsdo --source-dir force-app --test-level RunSpecifiedTests --tests TakedaSurfaceControllerTest
sf project deploy start --target-org devsdo --source-dir force-app --test-level RunSpecifiedTests --tests TakedaSurfaceControllerTest
The generator writes reviewable app/page/permission metadata to sfdc/takeda-demo. It stages uniquely named LWC/Apex modules from maintained package sources in /tmp/takeda-sf-deploy. The installed managed controller exposes public rather than global methods, so the demo needs its own generated controller. It retains sharing, VoiceCall record binding, field validation and Named Credential authentication, and reads the managed connection metadata. No existing unmanaged class or managed package is replaced.
Assign Takeda_Clearway_Demo to the presenter, alongside their existing Service Cloud Voice and Agent Studio permissions. Open Takeda Clearway before answering the call.
Current target: Amazon Connect¶
The presenter switched from Genesys to dccdev on September 29. The active
configured connection resolves to AWS account 465572510980, region us-east-1,
instance 9156b961-eb34-4d3a-92ad-f770d8f8b282, alias
dcc-dev-main-connect. The dccdev local AWS profile can inspect the instance.
AWS MCP's host role cannot currently list Connect resources; the inventory
script uses the explicitly selected local profile for read-only inspection.
Verified:
- The instance is active and KINESIS_VIDEO_STREAM media storage is already
configured, with prefix
MediaStreams-connect-dcc-dev-main-connect-contact-, KMS encryption and zero-hour retention. - Vanguard's Java
connect-kvs-connectoris running on port8093;/readyreported ready, zero active sessions and capacity 256. - The connector parses the two MKV audio tracks and sends stereo PCM16 at 8 kHz into the same orchestrator used by the Takeda rehearsal.
- Voice Agent
4453and Copilot4450are published with DCCDev Connect enabled.
The existing trusrv-dev-orch-connect-session-start Lambda now supports
trueserveEnvironment and is deployed with the vanguard endpoint
http://10.120.206.51:8093. Lambda and Vanguard are in the same VPC.
The dedicated security group sg-09005ed6cbb46a2fb is attached to Vanguard's
primary network interface alongside its existing group. Its session ingress
allows only the session Lambda's security group on TCP 8093.
The reader requires a dedicated CONNECT_KVS_INTERNAL_TOKEN, matched by
CONNECTOR_TOKENS.vanguard in the Lambda. Values are private. A deployed
Lambda invocation reached the reader's post-authentication validation with a
deliberately invalid stream ARN, receiving the expected HTTP 400 without
creating a conversation or reading audio. Another invocation rejected an
unknown environment. This proves authenticated private routing, not a
completed live audio call.
Flows without the environment attribute retain
CONNECTOR_URL=https://connect-kvs.dev.orchestrator.trueserve.deloitte.com;
the named dev mapping initially preserves that same endpoint. Its health
was not revalidated. The suggested public Vanguard connect-kvs hostname
reaches an unrelated default web page and fails normal TLS verification.
It is not used by this setup.
Call +1 770 821 9161 for the new demo. It is a newly claimed Connect voice
DID, associated with the published Takeda Clearway - Erik Golden flow.
The existing TakedaDemo donor flow and its numbers remain separate.
The inbound flow uses UpdateContactTargetQueue.AgentId to target Connect user
erigolden@deloitte.com, agent ID 37f110e0-7af3-4191-86dd-9c8d3e7e1b27.
It does not change the shared Basic Routing Profile or route through a shared
standard queue. The presenter's Salesforce user erigolden@trueserve.devsdo
is active and assigned to trueServeContactCenter. The supplied SCV debug
export contains the same Connect agent-queue ARN, confirming that browser
session's provider identity. A live Connect status check reported Available
with no active contacts during setup; availability must still be maintained
for the test.
The published route performs:
- Set
trueserveEnvironment=vanguard.TransferParticipantToThirdPartyconnects the existing Chime connectordkr9dqepmehfq0dpfoy38mtopipeline-4453, with the real customer ANI asFromUserandContinueFlowExecution=True. The Voice Agent'send_sessionwrites its outcome to Connect before SIP BYE. A normalsession_escalated=falsegoodbye disconnects; escalation or connector failure continues to the presenter. Select the customer whisper, set Erik as the target agent and transfer the caller to his agent queue. - After he accepts, the customer whisper starts media streaming in
both directions
(
FromandTo). The current reader waits for both tracks. - Contact attributes
MediaStreamCustomerARNfrom$.MediaStreams.Customer.Audio.StreamARN, andMediaStreamCustomerStartFragmentfrom$.MediaStreams.Customer.Audio.StartFragmentNumber. - Invoke
trusrv-dev-orch-connect-session-start:takeda-vanguardwithagentId=4450,language=en-US,region=us-east-1. The handler reads the contact ID, original contact ID, ANI/DNIS and the two media attributes. Check$.External.statusequalsok; returned error objects do not themselves take the invocation-error branch. Set contact attributetakedaCopilotStatustoreadyorunavailableand connect the caller. A failed assistant startup preserves the human call. The running reader uses the existingdccdevAWS profile. - The existing SCV partner adapter creates the Salesforce VoiceCall using the Connect contact ID. The Takeda app's VoiceCall override selects its dedicated page.
After publication, connect-check.py reads back both flows, the number
association and the authenticated Lambda endpoint. Earlier physical Connect
calls confirmed human-leg media ingestion and automatic panel updates.
The corrected two-agent sequence requires a fresh physical call to verify the
Chime Voice Agent leg, return to Connect, human transfer and Kinesis together.
The installer connect-flow.py
exports reviewable inbound
and customer whisper
flow JSON. Without --apply it prepares a plan; with --apply it creates or
updates only its tagged flows and associates the selected number after checking
its current route. It refuses numbers missing from the Connect voice inventory.
The configuration and publication evidence are in
.local-data/takeda-demo/connect-phone-route.json.
ListPhoneNumbersV2 also returned an imported SMS/MMS-only number with the
instance as its target. It was not voice-capable despite appearing unassigned;
the attempted association was removed and its original description restored.
Do not select a voice demo number solely from the V2 inventory.
AUDIO_TO_CUSTOMER includes prompts and hold audio as well as the representative.
Place session startup at the intended human handoff and verify speaker behavior.
The provider benchmark above used directly paced 16 kHz audio and does not
measure Connect transport delay or its 8 kHz source. Measure that separately
with the actual Connect route before claiming total live latency.
Read-only audit and Connect publication commands:
# Checks the published flow/alias, scoped permission and authenticated reader path.
# The Lambda probe deliberately cannot start audio or create a conversation.
apps/ai-orchestrator/.venv/bin/python apps/ai-manager/scripts/takeda-demo/connect-check.py
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/connect-readiness.ts
apps/ai-orchestrator/.venv/bin/python apps/ai-manager/scripts/takeda-demo/connect-inventory.py --profile dccdev
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/browser-test.ts publish ec667d5f-cb9c-4423-a6d1-0626d1c9ef72
The environment routing deployment is reproducible with
connect-deploy.py --profile dccdev --apply, executed through with-env.sh
using the orchestrator Python environment. Omitting --apply prints the plan.
It validates the account and private address, preserves existing Lambda
settings and network groups, and uses Lambda revision checks. Its dedicated
Vanguard group is managed by that idempotent city setup script, separately
from the KMS cluster's Terraform.
Evidence is saved in connect-deployment.json; the original function ZIP
and Lambda configuration are retained privately for rollback. Terraform's
dev environment map is updated in source. Supply the private
.local-data/takeda-demo/connect-token-inputs.tfvars.json with future Terraform
applies to preserve the per-environment token map. No Terraform apply or
Dev/QA cluster deployment was performed. The Terraform executable was not
available for validation in this workspace.
Previous Genesys preparation¶
The following mapping remains as historical preparation; it is not the current demo route.
+1 617 932 5103 is mapped to Copilot 4450 on Deloitte Genesys Lab
(e76d72fc-e5a0-4389-a6d2-be7f457187b1, organization
590a651f-40df-402d-b97c-9f0f0bc2c38d). Agent version 4450:v2 includes that
integration in its publish availability list. The exact DNIS rule precedes
existing rules; the prior default and unrelated routing are preserved.
The mapping is on the existing platform-scoped integration. The local operator script uses platform context for this explicitly selected shared ingress, and the mapping helper still validates that all target agents belong to the requested tenant. The pre-change mapping is saved locally.
bash .devcontainer/scripts/with-env.sh apps/ai-manager/node_modules/.bin/tsx --tsconfig apps/ai-manager/tsconfig.json apps/ai-manager/scripts/takeda-demo/routing.ts --verify e76d72fc-e5a0-4389-a6d2-be7f457187b1
The live lookup was verified for E.164, formatted and tel: DNIS values. It
requires a private INTERNAL_API_KEY of at least 32 characters configured
consistently in ai-manager and genesys-connector. The demo environment now has
that key; it is not checked into source control. Genesys call-answer testing
was superseded by the Connect switch. An authored component agent ID alone
does not change the active call's Copilot.
Salesforce verification¶
DevSDO's VoiceCall.DCC_Summary__c default contained 290 characters for a
255-character field and prevented new Voice Call creation even when a value
was supplied. The deployment shortens that existing summary to 234 characters
without changing the field type or existing records. This is the one shared
metadata repair accompanying the new app. The original metadata was retrieved
to /tmp/takeda-sf-reference.
The synthetic page-check records are Account 001DW00001ZuwwCYAR, Contact
003DW00001ABd4dYAD, and VoiceCall 0LQDW000001G9x84AC. The call uses fictional
202 numbers and the initial native rehearsal conversation. VendorCallKey is
immutable after insertion; create a new test call to bind a different rehearsal.
First Connect call: startup race and audio negotiation¶
The September 29 call 4e080f9b-3f5d-4f56-90c8-959540f1bd89
created Salesforce VoiceCall 0LQDW000001G9z44AC, owned by the intended
presenter. Connect reported assistant startup as ready, and the KVS
reader emitted 954 stereo frames. Two defects prevented the expected demo:
- Salesforce created the call record while ringing, about 14 seconds before
the answer-time conversation existed. All three initial embed-token
requests returned HTTP 404. The wrappers treated this as a terminal error.
The shared MFE core now waits up to 60 seconds for that exact pending
conversation and cancels on navigation; authorization/configuration failures
remain immediate. The Takeda deployment derives all three wrappers
(
takedaWorkspace,takedaSuggestions,takedaTranscript) from that core. Each attaches only to the record's conversation. - The Connect gRPC client ignored
ServerHello: it sent 8 kHz source bytes even though the runtime negotiated 16 kHz. It now enables assistant voice/text/A2UI modalities, waits for negotiation, and resamples each channel independently with persistent filter history. The converter's filter delay is 2 ms. Socket-level tests verify the wire duration and modality contract; audio tests verify pitch, stereo isolation and chunk continuity at all supported rates.
The phone route, answer-time media startup and environment attribute are
unchanged by these fixes. Use connect-audio-probe.ts for a reproducible test
that opens a synthetic Salesforce record before creating its conversation,
then sends 8 kHz speech through the production Java client. It checks the
actual Salesforce center/rail, extracted appeal and both transcript speakers.
This test excludes the KVS network leg; a fresh physical call verifies that
remaining leg with the corrected client.
Caller and organization context¶
The presenter authorized moving ANI +1 804 221 8211 from the Erik Golden
contact/person account to Denise Warren (003DW00001ABd4dYAD).
Denise belongs to the existing Mayo Clinic business account
001DW00001V3VhUYAV, with the demo role Patient Access Coordinator,
Gastroenterology. The phone was removed from Erik's person account and its
mirrored Contact field; a read-back query confirms Denise is the unique
Contact match.
The Voice MessagingEndUser 0PADW000000gUgf4AE had cached Erik as its
Contact and Account. Both links and its display name now point to Denise and
Mayo Clinic. Updating Contact.Phone alone would have left existing and future
calls attached to the cached old identity. The changes were made atomically
through the Salesforce composite API; the original records are saved in
caller-context-before.json. Reproduce using caller-context.py --apply.
The dedicated takedaCallerContext LWC uses the existing
DccContextSidebarController interaction identity resolution and displays the
returned Contact and its matching business Account together. It shows the native
caller photo/initials, title, department, phone, organization avatar, industry and
website, with record links and refresh support. It does not display the
account owner's branch projection as the calling organization. This is
specific to the Takeda page; the shared DCC sidebar is retained elsewhere.
The resolver is non-cacheable and is called imperatively on mount, record
change and refresh; stale responses are ignored after navigation.
Caller context also works on completed VoiceCalls with the phone offline.
It reads persisted EndUserId → MessagingEndUser → Contact/Account relationships
without a live Copilot session. The completed call 0LQDW000001GA0C4AW retains
Denise and Mayo through these links even though RelatedRecordId and Contact__c
are empty. Do not infer a missing caller from those two fields alone.
A fresh browser read returned the correct context for that call. The sidebar previously left any failed request on an error card until manual Retry. It now retries temporary transport/server failures twice (after 1 and 2.5 seconds), retains a loading state during recovery, and cancels retries on navigation or detachment. Permission, missing-record and explicit Apex exceptions are not retried. The terminal message is Unable to load saved caller details; an empty successful lookup says No caller is linked to this call.
Reproduce the completed-call check with
completed-call-probe.ts --fail-first through the TypeScript wrapper above.
It opens the saved record with the phone offline, injects an initial HTTP 503
on the caller lookup, requires recovery without Retry, then reloads and checks
Denise and Mayo again. Unit regressions run from sfdc/takeda-demo with
../trueserve-scv/node_modules/.bin/jest --config jest.config.cjs --runInBand.
The completed-call recovery deployed as 0AfDW00001NWAxZ0AX. The browser check
passed with the phone offline: the failed first lookup recovered automatically,
then a page reload read Denise and Mayo again (three caller requests total).
Evidence: completed-call-context.json and completed-call-context.png.
All 13 dedicated caller-context LWC tests, lint and formatting checks passed.
The deployment changes only takedaCallerContext; Apex and saved call links
are unchanged.
The earlier page and sidebar deployments succeeded (0AfDW00001NWAx50AH,
followed by 0AfDW00001NWAxA0AX). The LWC compiler and
lint pass. The browser check on the actual call 0LQDW000001GA0C4AW
verified Denise, her phone, role and department, Mayo Clinic and its website,
with no Erik Golden owner data in the sidebar. All three embed frames remained
bound to that call. Evidence is in salesforce-caller-context.json and
salesforce-caller-context.png.
Verification¶
Answered call stuck waiting: environment configuration drift¶
Call 1ab555b6-a511-4ad4-89c7-1c1ce5e12df8, VoiceCall
0LQDW000001GAAR4A4, connected at 19:45:36 UTC on September 29.
Connect captured a media stream, but the session Lambda returned
unknown_environment; takedaCopilotStatus became unavailable.
No reader session or TrueServe conversation was created. The waiting panels
were a consequence of failed server startup, not a missing Salesforce call key.
CloudTrail records a GitHub Actions Terraform UpdateFunctionConfiguration
at 16:15:14 UTC replacing the unqualified function's environment. The endpoint
and token maps installed earlier were absent. Local Terraform changes alone
do not protect a live function from the deployed CI configuration.
The maps were restored and published as version 3. The dedicated alias
takeda-vanguard points to that verified version, with an invocation permission
restricted to the dccdev instance/account and an explicit Connect association.
The published customer whisper calls the alias. Shared $LATEST updates cannot
replace that version's environment.
connect-deploy.py probes the published version before promoting the alias,
then probes the alias. Future endpoint/token changes require a new verified
release; changing $LATEST alone does not update the demo. Keep Terraform's
endpoint map and private token inputs aligned when promoting the infrastructure
changes. connect-check.py checks the actual number association, both published
flows, alias, invocation permission and authenticated private endpoint without
creating a conversation. --contact-id additionally reports the saved call's
startup/media state. A successful probe still requires a physical call to
verify fresh audio and panel updates.
The console's separate /api/call-mapping/register 502 came from an obsolete
POST to a nonexistent conversation-api route. Registration now authorizes
SCRT2 writes and anchors offsets locally; the audio connector creates the
authoritative conversation with the same call ID. The public registration
endpoint returned HTTP 200 after the fix. Its 46 targeted tests, 19 Lambda
routing tests and 3 release-promotion tests passed.
Salesforce appearance correction¶
Catalog 1.1.2 restores neutral Salesforce-style cards and controls. Deployment
0AfDW00001NWAxj0AH restored the sidebar styling and inherited app theme;
0AfDW00001NWAxo0AH preserves the full caller name at narrow widths. The
appearance update leaves Copilot 4450:v5 and its workers unchanged.
appearance-probe.json passed against VoiceCall 0LQDW000001GA2N4AW in the
actual Salesforce app. It verified identical native/embedded font stacks,
white surfaces, blue selected-view underlines, all three patient views and
preserved appeal values at 1720 px and 1366 px widths.
Screenshots: salesforce-restored-style.png, salesforce-restored-form.png
and salesforce-restored-style-1366.png.
The completed-call probe also passed with the restored sidebar on
0LQDW000001GA0C4AW, including an injected initial lookup failure, automatic
recovery, phone offline and page reload. All 13 sidebar regressions, targeted
LWC/React lint and catalog build checks passed.
Historical human-first rehearsal: Copilot 4450:v5¶
The final rehearsal passed in the actual Takeda Clearway Salesforce page:
conversation 24374801-3811-4f5e-aae9-324fea71f1bc, VoiceCall
0LQDW000001GA2N4AW. It used synthetic 8 kHz stereo speech through the production
Connect Java client, which negotiated and resampled to 16 kHz. The test verified:
- All three panels waited through 25 seconds of ringing before the conversation existed. An injected HTTP 503 on the first center iframe navigation recovered automatically without clicking Retry.
- Greeting coaching appeared before speech. Silence, greetings and “a few patients” revealed no patient cards.
- Thomas, Marisol and Renee appeared separately in response to caller speech. Card source IDs matched the live Salesforce Cases listed above; the rail changed to the current patient's guidance.
- Marisol's new insurance came from spoken answers. All seven appeal fields were captured, and a representative's dose correction survived a view switch.
- Confirm details succeeded 130.688 seconds after the greeting, beyond the old 120-second token expiry. The reviewed form became Completed. All three iframes retained the correct conversation binding.
Evidence is in .local-data/takeda-demo/progressive-probe.json, with
progressive-greeting.png, progressive-thomas.png, progressive-renee.png
and progressive-appeal-confirmed.png. This test does not place a PSTN call
or traverse Kinesis.
Salesforce deployment 0AfDW00001NWAxK0AX succeeded. The explicit Apex test run
707DW00002ozVlL passed 28/28 tests. Other current checks passed:
189 Python, 19 Salesforce LWC, 27 surface and 1 patient-mention
test. The broad ai-manager typecheck passed. Targeted lint reported warnings
and no errors.
Earlier integration evidence¶
Before the progressive-patient update, the full native script rehearsal
40574943-c215-4f1b-8bde-69b5e1089e41 verified separate center/rail content,
published CSS, preserved edits, native confirmation and protection against
later speech overwriting confirmed values. Its browser evidence is
salesforce-browser.json and salesforce-takeda.png.
The physical Connect call
867618ef-6c46-487a-a262-408e89a51879 / VoiceCall 0LQDW000001GA0C4AW
used the corrected 8-to-16 kHz negotiation and emitted 4,027 stereo frames
from KVS. A spoken representative turn produced transcripts plus workspace
and rail updates. The earlier synthetic stereo test independently verified
both speaker channels and full appeal extraction.
An earlier synthetic 8 kHz stereo test through the actual Salesforce app used
conversation
02763886-ae3a-48d3-a73d-9105f500a2c8, VoiceCall 0LQDW000001G9zx4AC.
Both center and rail showed the pending-call state before any session existed,
then attached automatically and rendered live case/policy/appeal components.
The appeal captured the dose and outcome; both channels transcribed (4 agent
and 6 caller final messages). Evidence: connect-audio-probe.json and
salesforce-connect-fixed.png. Reopening the presenter's original failed call
also loaded all three panels successfully. DevSDO requires the synthetic call's
end time on insertion and makes it immutable afterward, so the test record
retains its planned window.
The earlier transport changes passed 10 Java KVS checks and 19 Lambda routing checks. Those checks were not rerun for the latest catalog and Salesforce startup changes; the current Salesforce/audio rehearsal exercises the production Java client directly.