File size: 7,190 Bytes
612e777
5a79992
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612e777
5a79992
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<article class="doc" id="doc-modules-agents" aria-hidden="true"><div class="strip"><span class="path">modules/agents.md</span><span class="tag">Engineering, modules</span><span class="meta">~2 min read</span></div>
<h1>Module: <code>agents</code></h1>
<blockquote>
<p>Part of the Travi AI Agent monolith (<code>app/modules/agents/</code>). Read <code>00-overview.md</code> §3 (hard rules) before changing anything here.</p>
</blockquote>
<div class="tbl-wrap"><table class="plain col-table compact"><colgroup><col class="col-auto"/><col class="col-lg"/></colgroup>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td data-label=""><strong>Purpose</strong></td>
<td data-label="">The six bounded agents, their policy envelopes, evidence records, kill switches, and exception routing. Agents gather evidence; they never set state.</td>
</tr>
<tr>
<td data-label=""><strong>Owns (data)</strong></td>
<td data-label="">agent_action, policy envelopes (versioned)</td>
</tr>
<tr>
<td data-label=""><strong>Public surface</strong></td>
<td data-label="">goal queue (internal), <code>/admin/kill-switches</code> enforcement point</td>
</tr>
<tr>
<td data-label=""><strong>Depends on</strong></td>
<td data-label="">episode (evidence → engine), notification, ehr_adapter, Twilio voice</td>
</tr>
<tr>
<td data-label=""><strong>Requirements owned</strong></td>
<td data-label="">AUT-001/006/009</td>
</tr>
<tr>
<td data-label=""><strong>Constraining ADRs</strong></td>
<td data-label="">ADR-011 (routing targets)</td>
</tr>
<tr>
<td data-label=""><strong>Key references</strong></td>
<td data-label="">modules/episode.md (who actually moves state)</td>
</tr>
</tbody>
</table></div>
<hr/>
<h1>12. Agentic Execution Layer</h1>
<h2 id="doc-modules-agents--h1">12.1 Orchestration Loop (deterministic core)</h2>
<ol>
<li>Workflow engine (episode module) emits a <strong>goal</strong> (e.g., <code>verify_dispense(plan_item)</code>) to the agent queue with the current policy envelope version.</li>
<li>Agent plans with LLM assist (optional) but may only call tools on its allowlist; every call → <code>agent_action</code> row (params redacted, result, evidence).</li>
<li>Agent returns <strong>structured evidence</strong>, never a state: e.g., <code>{dispense_status:"picked_up", source:"pharmacy_phone", confidence:"confirmed"}</code>.</li>
<li>Workflow engine validates evidence against deterministic rules and executes the §7.1 transition (five-element contract).</li>
<li>Retry ladder per envelope; exhaustion → L1 exception route (§12.5); kill switches checked before every tool call (cached ≤10 s).</li>
</ol>
<h2 id="doc-modules-agents--h2">12.2 Agent Catalog &amp; Envelopes</h2>
<div class="tbl-wrap"><table class="col-table compact"><colgroup><col class="col-auto"/><col class="col-lg"/><col class="col-auto"/><col class="col-lg"/></colgroup>
<thead>
<tr>
<th>Agent</th>
<th>Tool Allowlist</th>
<th>Max Retries</th>
<th>Hard Prohibitions</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Agent">Engagement</td>
<td data-label="Tool Allowlist">notification.send, channel.select, schedule.reminder</td>
<td data-label="Max Retries">3/task/day</td>
<td data-label="Hard Prohibitions">No PHI in payloads; no promises of clinician monitoring (CLN-008 language lint).</td>
</tr>
<tr>
<td data-label="Agent">Appointment</td>
<td data-label="Tool Allowlist">ehr.search_slots, ehr.book(with patient authorization token), patient.present_options</td>
<td data-label="Max Retries">3</td>
<td data-label="Hard Prohibitions">Never book/cancel without explicit patient authorization event; never invent availability (APT rules).</td>
</tr>
<tr>
<td data-label="Agent">Med Access</td>
<td data-label="Tool Allowlist">pharmacy.call (Twilio flow), pharmacy.status_form, patient.ask_structured</td>
<td data-label="Max Retries">2/barrier</td>
<td data-label="Hard Prohibitions">No substitutions, dose advice, or clinical guidance, script templates only.</td>
</tr>
<tr>
<td data-label="Agent">Records</td>
<td data-label="Tool Allowlist">ehr.list_documents, ehr.fetch_binary</td>
<td data-label="Max Retries">5</td>
<td data-label="Hard Prohibitions">Approved document types only; read-only.</td>
</tr>
<tr>
<td data-label="Agent">Brief</td>
<td data-label="Tool Allowlist">facts.read(published), brief.render, notify.clinician_link</td>
<td data-label="Max Retries">2</td>
<td data-label="Hard Prohibitions">Assembles <strong>published</strong> facts only; cannot trigger confirmations.</td>
</tr>
<tr>
<td data-label="Agent">Outcome</td>
<td data-label="Tool Allowlist">adt.match, hie.lookup, claims.ingest</td>
<td data-label="Max Retries">5</td>
<td data-label="Hard Prohibitions">Read/match only; flags completeness, never edits episodes.</td>
</tr>
</tbody>
</table></div>
<h2 id="doc-modules-agents--h3">12.3 Policy Envelope (stored, versioned, enforced in code)</h2>
<pre><code>{ "agent": "med_access", "version": 4,
 "tools": ["pharmacy.call","pharmacy.status_form","patient.ask_structured"],
 "max_retries": 2, "retry_backoff_hours": [4, 24],
 "requires_patient_authorization": false,
 "clinical_boundaries": ["no_substitution","no_dose_advice"],
 "cost_caps": {"tokens_per_run": 20000, "voice_minutes_per_run": 6},
 "kill_scopes": ["global","tenant","cohort","agent","tool","integration"],
 "logging": "full_evidence", "pii_redaction": "params_hashed" }
</code></pre>
<h2 id="doc-modules-agents--h4">12.4 Kill Switches (AUT-009)</h2>
<p>Six scopes resolve most-specific-wins; state lives in <code>tenant_config</code> with Redis cache TTL 10 s; the admin endpoint requires reason + role and takes effect before the next tool call. Read-only surfaces (Today, brief) are never disabled by agent kills.</p>
<h2 id="doc-modules-agents--h5">12.5 Exception Routing (PRD §8.1)</h2>
<div class="tbl-wrap"><table class="col-table compact"><colgroup><col class="col-xs"/><col class="col-md"/><col class="col-lg"/></colgroup>
<thead>
<tr>
<th>Level</th>
<th>Trigger</th>
<th>Terminal Route (MVP)</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Level">L1</td>
<td data-label="Trigger">Retry exhaustion on operational tasks (unreachable, scheduling fail, stock-out)</td>
<td data-label="Terminal Route (MVP)">Caregiver prompt (if consented) → <code>blocked</code> persists → weekly exception report; hospital queue only if <code>ops.tier=2</code> (AUT-006 keeps routine ops out of hospital queues).</td>
</tr>
<tr>
<td data-label="Level">L2</td>
<td data-label="Trigger">Conflicting sources; transcript vs order; uncertain material fact</td>
<td data-label="Terminal Route (MVP)"><code>pending_clinical_decision</code> → previsit brief open-questions; if no appointment within window → configured transition-team endpoint digest.</td>
</tr>
<tr>
<td data-label="Level">L3</td>
<td data-label="Trigger">Severe symptom report / explicit help request</td>
<td data-label="Terminal Route (MVP)">Immediate approved emergency instructions (911/ED language, versioned per EDU-007) + alert to configured clinical endpoint; never an improvised agent reply.</td>
</tr>
</tbody>
</table></div>
<div class="pn"><a class="pn-prev" href="#"></a><a class="pn-next" href="#"></a></div></article>