@ddse/acm-examples 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +113 -0
- package/bin/acm-demo.ts +495 -0
- package/data/coaching/agents.json +16 -0
- package/data/coaching/transcripts.json +37 -0
- package/data/documents.json +72 -0
- package/data/entitlement/customers.json +38 -0
- package/data/entitlement/policies.json +38 -0
- package/data/incidents/incidents.json +30 -0
- package/data/incidents/routing_rules.json +36 -0
- package/data/invoices/invoices.json +38 -0
- package/data/invoices/purchase-orders.json +38 -0
- package/data/issues.json +99 -0
- package/data/knowledge/docs/kb-001.md +7 -0
- package/data/knowledge/docs/kb-002.md +7 -0
- package/data/knowledge/docs/kb-003.md +9 -0
- package/data/knowledge/index.json +25 -0
- package/data/orders.json +106 -0
- package/dist/bin/acm-demo.d.ts +3 -0
- package/dist/bin/acm-demo.d.ts.map +1 -0
- package/dist/bin/acm-demo.js +392 -0
- package/dist/bin/acm-demo.js.map +1 -0
- package/dist/src/context/directives.d.ts +3 -0
- package/dist/src/context/directives.d.ts.map +1 -0
- package/dist/src/context/directives.js +325 -0
- package/dist/src/context/directives.js.map +1 -0
- package/dist/src/context/index.d.ts +2 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +2 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/data/coaching.d.ts +19 -0
- package/dist/src/data/coaching.d.ts.map +1 -0
- package/dist/src/data/coaching.js +22 -0
- package/dist/src/data/coaching.js.map +1 -0
- package/dist/src/data/entitlement.d.ts +25 -0
- package/dist/src/data/entitlement.d.ts.map +1 -0
- package/dist/src/data/entitlement.js +26 -0
- package/dist/src/data/entitlement.js.map +1 -0
- package/dist/src/data/incidents.d.ts +23 -0
- package/dist/src/data/incidents.d.ts.map +1 -0
- package/dist/src/data/incidents.js +37 -0
- package/dist/src/data/incidents.js.map +1 -0
- package/dist/src/data/invoices.d.ts +34 -0
- package/dist/src/data/invoices.d.ts.map +1 -0
- package/dist/src/data/invoices.js +49 -0
- package/dist/src/data/invoices.js.map +1 -0
- package/dist/src/data/knowledge.d.ts +11 -0
- package/dist/src/data/knowledge.d.ts.map +1 -0
- package/dist/src/data/knowledge.js +57 -0
- package/dist/src/data/knowledge.js.map +1 -0
- package/dist/src/data/loader.d.ts +4 -0
- package/dist/src/data/loader.d.ts.map +1 -0
- package/dist/src/data/loader.js +69 -0
- package/dist/src/data/loader.js.map +1 -0
- package/dist/src/examples/scenarios.d.ts +23 -0
- package/dist/src/examples/scenarios.d.ts.map +1 -0
- package/dist/src/examples/scenarios.js +609 -0
- package/dist/src/examples/scenarios.js.map +1 -0
- package/dist/src/goals/index.d.ts +8 -0
- package/dist/src/goals/index.d.ts.map +1 -0
- package/dist/src/goals/index.js +12 -0
- package/dist/src/goals/index.js.map +1 -0
- package/dist/src/policy.d.ts +5 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/policy.js +24 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/registries.d.ts +18 -0
- package/dist/src/registries.d.ts.map +1 -0
- package/dist/src/registries.js +38 -0
- package/dist/src/registries.js.map +1 -0
- package/dist/src/renderer.d.ts +9 -0
- package/dist/src/renderer.d.ts.map +1 -0
- package/dist/src/renderer.js +76 -0
- package/dist/src/renderer.js.map +1 -0
- package/dist/src/search/bm25.d.ts +68 -0
- package/dist/src/search/bm25.d.ts.map +1 -0
- package/dist/src/search/bm25.js +131 -0
- package/dist/src/search/bm25.js.map +1 -0
- package/dist/src/search/index.d.ts +2 -0
- package/dist/src/search/index.d.ts.map +1 -0
- package/dist/src/search/index.js +3 -0
- package/dist/src/search/index.js.map +1 -0
- package/dist/src/tasks/coaching.d.ts +30 -0
- package/dist/src/tasks/coaching.d.ts.map +1 -0
- package/dist/src/tasks/coaching.js +143 -0
- package/dist/src/tasks/coaching.js.map +1 -0
- package/dist/src/tasks/entitlement.d.ts +29 -0
- package/dist/src/tasks/entitlement.d.ts.map +1 -0
- package/dist/src/tasks/entitlement.js +135 -0
- package/dist/src/tasks/entitlement.js.map +1 -0
- package/dist/src/tasks/incidents.d.ts +42 -0
- package/dist/src/tasks/incidents.d.ts.map +1 -0
- package/dist/src/tasks/incidents.js +189 -0
- package/dist/src/tasks/incidents.js.map +1 -0
- package/dist/src/tasks/index.d.ts +7 -0
- package/dist/src/tasks/index.d.ts.map +1 -0
- package/dist/src/tasks/index.js +7 -0
- package/dist/src/tasks/index.js.map +1 -0
- package/dist/src/tasks/invoices.d.ts +40 -0
- package/dist/src/tasks/invoices.d.ts.map +1 -0
- package/dist/src/tasks/invoices.js +180 -0
- package/dist/src/tasks/invoices.js.map +1 -0
- package/dist/src/tasks/knowledge.d.ts +23 -0
- package/dist/src/tasks/knowledge.d.ts.map +1 -0
- package/dist/src/tasks/knowledge.js +115 -0
- package/dist/src/tasks/knowledge.js.map +1 -0
- package/dist/src/tasks/legacy.d.ts +50 -0
- package/dist/src/tasks/legacy.d.ts.map +1 -0
- package/dist/src/tasks/legacy.js +85 -0
- package/dist/src/tasks/legacy.js.map +1 -0
- package/dist/src/tools/coaching/index.d.ts +49 -0
- package/dist/src/tools/coaching/index.d.ts.map +1 -0
- package/dist/src/tools/coaching/index.js +119 -0
- package/dist/src/tools/coaching/index.js.map +1 -0
- package/dist/src/tools/entitlement/index.d.ts +52 -0
- package/dist/src/tools/entitlement/index.d.ts.map +1 -0
- package/dist/src/tools/entitlement/index.js +120 -0
- package/dist/src/tools/entitlement/index.js.map +1 -0
- package/dist/src/tools/incidents/index.d.ts +55 -0
- package/dist/src/tools/incidents/index.d.ts.map +1 -0
- package/dist/src/tools/incidents/index.js +109 -0
- package/dist/src/tools/incidents/index.js.map +1 -0
- package/dist/src/tools/index.d.ts +90 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +109 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/invoices/index.d.ts +56 -0
- package/dist/src/tools/invoices/index.d.ts.map +1 -0
- package/dist/src/tools/invoices/index.js +85 -0
- package/dist/src/tools/invoices/index.js.map +1 -0
- package/dist/src/tools/knowledge/index.d.ts +52 -0
- package/dist/src/tools/knowledge/index.d.ts.map +1 -0
- package/dist/src/tools/knowledge/index.js +120 -0
- package/dist/src/tools/knowledge/index.js.map +1 -0
- package/dist/tests/bm25.test.d.ts +2 -0
- package/dist/tests/bm25.test.d.ts.map +1 -0
- package/dist/tests/bm25.test.js +98 -0
- package/dist/tests/bm25.test.js.map +1 -0
- package/dist/tests/integration.test.d.ts +2 -0
- package/dist/tests/integration.test.d.ts.map +1 -0
- package/dist/tests/integration.test.js +126 -0
- package/dist/tests/integration.test.js.map +1 -0
- package/dist/tests/plan-hydration.test.d.ts +2 -0
- package/dist/tests/plan-hydration.test.d.ts.map +1 -0
- package/dist/tests/plan-hydration.test.js +28 -0
- package/dist/tests/plan-hydration.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/docs/examples-architecture.md +144 -0
- package/docs/successrun.md +1022 -0
- package/package.json +33 -0
- package/src/context/directives.ts +366 -0
- package/src/context/index.ts +1 -0
- package/src/data/coaching.ts +50 -0
- package/src/data/entitlement.ts +60 -0
- package/src/data/incidents.ts +78 -0
- package/src/data/invoices.ts +103 -0
- package/src/data/knowledge.ts +77 -0
- package/src/data/loader.ts +80 -0
- package/src/examples/scenarios.ts +724 -0
- package/src/goals/index.ts +18 -0
- package/src/policy.ts +30 -0
- package/src/registries.ts +48 -0
- package/src/renderer.ts +82 -0
- package/src/search/bm25.ts +173 -0
- package/src/search/index.ts +2 -0
- package/src/tasks/coaching.ts +217 -0
- package/src/tasks/entitlement.ts +197 -0
- package/src/tasks/incidents.ts +277 -0
- package/src/tasks/index.ts +6 -0
- package/src/tasks/invoices.ts +269 -0
- package/src/tasks/knowledge.ts +169 -0
- package/src/tasks/legacy.ts +112 -0
- package/src/tools/coaching/index.ts +197 -0
- package/src/tools/entitlement/index.ts +199 -0
- package/src/tools/incidents/index.ts +185 -0
- package/src/tools/index.ts +192 -0
- package/src/tools/invoices/index.ts +165 -0
- package/src/tools/knowledge/index.ts +203 -0
- package/tests/bm25.test.ts +129 -0
- package/tests/integration.test.ts +163 -0
- package/tests/plan-hydration.test.ts +33 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
import type { Goal, Context, Plan } from '@ddse/acm-sdk';
|
|
2
|
+
import type { ExecutePlanResult } from '@ddse/acm-runtime';
|
|
3
|
+
import { SimpleCapabilityRegistry, SimpleToolRegistry } from '../registries.js';
|
|
4
|
+
import {
|
|
5
|
+
FetchCustomerProfileTool,
|
|
6
|
+
EvaluateEntitlementTool,
|
|
7
|
+
EntitlementNotifySupervisorTool,
|
|
8
|
+
SearchKnowledgeTool,
|
|
9
|
+
SummarizeSnippetTool,
|
|
10
|
+
SuggestFollowupsTool,
|
|
11
|
+
FetchIncidentTool,
|
|
12
|
+
ClassifySeverityTool,
|
|
13
|
+
SelectQueueTool,
|
|
14
|
+
EscalateIncidentTool,
|
|
15
|
+
FetchInvoiceTool,
|
|
16
|
+
FetchPurchaseOrderTool,
|
|
17
|
+
CompareLineItemsTool,
|
|
18
|
+
RecordFindingsTool,
|
|
19
|
+
AnalyzeTranscriptTool,
|
|
20
|
+
GenerateFeedbackTool,
|
|
21
|
+
LogCoachingNoteTool,
|
|
22
|
+
} from '../tools/index.js';
|
|
23
|
+
import { RetrieveCustomerProfileTask, EvaluateEntitlementTask, SupervisorNotificationTask } from '../tasks/entitlement.js';
|
|
24
|
+
import { SearchKnowledgeTask, SummarizeSnippetTask, SuggestFollowupsTask } from '../tasks/knowledge.js';
|
|
25
|
+
import { FetchIncidentTask, ClassifySeverityTask, SelectQueueTask, EscalateIncidentTask as EscalateIncidentTaskClass } from '../tasks/incidents.js';
|
|
26
|
+
import { FetchInvoiceTask, FetchPurchaseOrderTask, CompareLineItemsTask, RecordFindingsTask } from '../tasks/invoices.js';
|
|
27
|
+
import { AnalyzeTranscriptTask, GenerateFeedbackTask, LogCoachingNoteTask } from '../tasks/coaching.js';
|
|
28
|
+
import { getTranscript } from '../data/coaching.js';
|
|
29
|
+
|
|
30
|
+
const capabilityMapVersion = 'v0.5-example-map';
|
|
31
|
+
|
|
32
|
+
export type ScenarioKey = 'entitlement' | 'knowledge' | 'incidents' | 'invoices' | 'coaching';
|
|
33
|
+
|
|
34
|
+
export type ScenarioReference = {
|
|
35
|
+
plan: Plan;
|
|
36
|
+
expectedOutputs: Record<string, any>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ScenarioDefinition = {
|
|
40
|
+
key: ScenarioKey;
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
goal: Goal;
|
|
44
|
+
context: Context;
|
|
45
|
+
registerTools(registry: SimpleToolRegistry): void;
|
|
46
|
+
registerCapabilities(registry: SimpleCapabilityRegistry): void;
|
|
47
|
+
buildReferencePlan(): Promise<ScenarioReference>;
|
|
48
|
+
assertExecution(result: ExecutePlanResult): void;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function extractOutputs(execution: ExecutePlanResult): Record<string, any> {
|
|
52
|
+
const outputs: Record<string, any> = {};
|
|
53
|
+
for (const [taskId, record] of Object.entries(execution.outputsByTask ?? {})) {
|
|
54
|
+
outputs[taskId] = record?.output;
|
|
55
|
+
}
|
|
56
|
+
return outputs;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const entitlementTools = {
|
|
60
|
+
fetch: new FetchCustomerProfileTool(),
|
|
61
|
+
evaluate: new EvaluateEntitlementTool(),
|
|
62
|
+
notify: new EntitlementNotifySupervisorTool(),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const entitlementTasks = {
|
|
66
|
+
fetch: new RetrieveCustomerProfileTask(),
|
|
67
|
+
evaluate: new EvaluateEntitlementTask(),
|
|
68
|
+
notify: new SupervisorNotificationTask(),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const entitlementGoal: Goal = {
|
|
72
|
+
id: 'goal-entitlement-1',
|
|
73
|
+
intent: 'Determine if the customer qualifies for the Analytics Labs benefit and alert the supervisor if action is needed.',
|
|
74
|
+
constraints: {
|
|
75
|
+
responseTimeMinutes: 30,
|
|
76
|
+
notifySupervisorOnDecision: true,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const entitlementContext: Context = {
|
|
81
|
+
id: 'ctx-entitlement-1',
|
|
82
|
+
version: '1.0',
|
|
83
|
+
facts: {
|
|
84
|
+
customerId: 'CUST-104233',
|
|
85
|
+
benefitCode: 'BEN-ANALYTICS-LABS',
|
|
86
|
+
channel: 'email',
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
async function buildEntitlementReferencePlan(): Promise<ScenarioReference> {
|
|
91
|
+
const { customerId, benefitCode, channel } = entitlementContext.facts as {
|
|
92
|
+
customerId: string;
|
|
93
|
+
benefitCode: string;
|
|
94
|
+
channel: 'email' | 'slack';
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const fetchInput = { customerId };
|
|
98
|
+
const fetchOutput = await entitlementTools.fetch.call(fetchInput);
|
|
99
|
+
|
|
100
|
+
const evaluateInput = { customerId, benefitCode };
|
|
101
|
+
const evaluateOutput = await entitlementTools.evaluate.call(evaluateInput);
|
|
102
|
+
|
|
103
|
+
const decisionMessage = evaluateOutput.decision === 'allow'
|
|
104
|
+
? `Approved benefit ${benefitCode} for ${customerId}. SLA ${evaluateOutput.slaMinutes} minutes.`
|
|
105
|
+
: `Denied benefit ${benefitCode} for ${customerId}. Violations: ${evaluateOutput.violations.map(v => v.code).join(', ')}`;
|
|
106
|
+
|
|
107
|
+
const notifyInput = {
|
|
108
|
+
customerId,
|
|
109
|
+
decision: evaluateOutput.decision,
|
|
110
|
+
channel,
|
|
111
|
+
message: decisionMessage,
|
|
112
|
+
};
|
|
113
|
+
const notifyOutput = await entitlementTools.notify.call(notifyInput);
|
|
114
|
+
|
|
115
|
+
const plan: Plan = {
|
|
116
|
+
id: 'plan-entitlement-demo',
|
|
117
|
+
contextRef: entitlementContext.id,
|
|
118
|
+
capabilityMapVersion,
|
|
119
|
+
tasks: [
|
|
120
|
+
{
|
|
121
|
+
id: entitlementTasks.fetch.id,
|
|
122
|
+
capability: entitlementTasks.fetch.capability,
|
|
123
|
+
input: fetchInput,
|
|
124
|
+
verification: entitlementTasks.fetch.verification?.(),
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: entitlementTasks.evaluate.id,
|
|
128
|
+
capability: entitlementTasks.evaluate.capability,
|
|
129
|
+
input: evaluateInput,
|
|
130
|
+
verification: entitlementTasks.evaluate.verification?.(),
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: entitlementTasks.notify.id,
|
|
134
|
+
capability: entitlementTasks.notify.capability,
|
|
135
|
+
input: notifyInput,
|
|
136
|
+
verification: entitlementTasks.notify.verification?.(),
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
edges: [
|
|
140
|
+
{ from: entitlementTasks.fetch.id, to: entitlementTasks.evaluate.id },
|
|
141
|
+
{ from: entitlementTasks.evaluate.id, to: entitlementTasks.notify.id },
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
plan,
|
|
147
|
+
expectedOutputs: {
|
|
148
|
+
[entitlementTasks.fetch.id]: fetchOutput,
|
|
149
|
+
[entitlementTasks.evaluate.id]: evaluateOutput,
|
|
150
|
+
[entitlementTasks.notify.id]: notifyOutput,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const knowledgeTools = {
|
|
156
|
+
search: new SearchKnowledgeTool(),
|
|
157
|
+
summarize: new SummarizeSnippetTool(),
|
|
158
|
+
followups: new SuggestFollowupsTool(),
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const knowledgeTasks = {
|
|
162
|
+
search: new SearchKnowledgeTask(),
|
|
163
|
+
summarize: new SummarizeSnippetTask(),
|
|
164
|
+
followups: new SuggestFollowupsTask(),
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const knowledgeGoal: Goal = {
|
|
168
|
+
id: 'goal-knowledge-1',
|
|
169
|
+
intent: 'Surface relevant mitigation guidance for the API latency regression and propose follow-up actions.',
|
|
170
|
+
constraints: {
|
|
171
|
+
maxSnippets: 3,
|
|
172
|
+
urgency: 'high',
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const knowledgeContext: Context = {
|
|
177
|
+
id: 'ctx-knowledge-1',
|
|
178
|
+
version: '1.0',
|
|
179
|
+
facts: {
|
|
180
|
+
query: 'latency regression mitigation',
|
|
181
|
+
docId: 'KB-003',
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
async function buildKnowledgeReferencePlan(): Promise<ScenarioReference> {
|
|
186
|
+
const { query, docId } = knowledgeContext.facts as { query: string; docId: string };
|
|
187
|
+
|
|
188
|
+
const searchInput = { query, limit: 3 };
|
|
189
|
+
const searchOutput = await knowledgeTools.search.call(searchInput);
|
|
190
|
+
|
|
191
|
+
const summarizeInput = { docId, maxSentences: 3, focus: 'stabilization steps' };
|
|
192
|
+
const summarizeOutput = await knowledgeTools.summarize.call(summarizeInput);
|
|
193
|
+
|
|
194
|
+
const followupInput = { docId, context: { channel: 'slack', urgency: 'high' as const } };
|
|
195
|
+
const followupOutput = await knowledgeTools.followups.call(followupInput);
|
|
196
|
+
|
|
197
|
+
const plan: Plan = {
|
|
198
|
+
id: 'plan-knowledge-demo',
|
|
199
|
+
contextRef: knowledgeContext.id,
|
|
200
|
+
capabilityMapVersion,
|
|
201
|
+
tasks: [
|
|
202
|
+
{
|
|
203
|
+
id: knowledgeTasks.search.id,
|
|
204
|
+
capability: knowledgeTasks.search.capability,
|
|
205
|
+
input: searchInput,
|
|
206
|
+
verification: knowledgeTasks.search.verification?.(),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
id: knowledgeTasks.summarize.id,
|
|
210
|
+
capability: knowledgeTasks.summarize.capability,
|
|
211
|
+
input: summarizeInput,
|
|
212
|
+
verification: knowledgeTasks.summarize.verification?.(),
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: knowledgeTasks.followups.id,
|
|
216
|
+
capability: knowledgeTasks.followups.capability,
|
|
217
|
+
input: followupInput,
|
|
218
|
+
verification: knowledgeTasks.followups.verification?.(),
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
edges: [
|
|
222
|
+
{ from: knowledgeTasks.search.id, to: knowledgeTasks.summarize.id },
|
|
223
|
+
{ from: knowledgeTasks.summarize.id, to: knowledgeTasks.followups.id },
|
|
224
|
+
],
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
plan,
|
|
229
|
+
expectedOutputs: {
|
|
230
|
+
[knowledgeTasks.search.id]: searchOutput,
|
|
231
|
+
[knowledgeTasks.summarize.id]: summarizeOutput,
|
|
232
|
+
[knowledgeTasks.followups.id]: followupOutput,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const incidentTools = {
|
|
238
|
+
fetch: new FetchIncidentTool(),
|
|
239
|
+
classify: new ClassifySeverityTool(),
|
|
240
|
+
selectQueue: new SelectQueueTool(),
|
|
241
|
+
escalate: new EscalateIncidentTool(),
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const incidentTasks = {
|
|
245
|
+
fetch: new FetchIncidentTask(),
|
|
246
|
+
classify: new ClassifySeverityTask(),
|
|
247
|
+
select: new SelectQueueTask(),
|
|
248
|
+
escalate: new EscalateIncidentTaskClass(),
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const incidentGoal: Goal = {
|
|
252
|
+
id: 'goal-incident-1',
|
|
253
|
+
intent: 'Triage the critical checkout outage and trigger the appropriate escalation path.',
|
|
254
|
+
constraints: {
|
|
255
|
+
routeWithinMinutes: 15,
|
|
256
|
+
requireEscalationForCritical: true,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const incidentContext: Context = {
|
|
261
|
+
id: 'ctx-incident-1',
|
|
262
|
+
version: '1.0',
|
|
263
|
+
facts: {
|
|
264
|
+
incidentId: 'INC-2045',
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
async function buildIncidentReferencePlan(): Promise<ScenarioReference> {
|
|
269
|
+
const { incidentId } = incidentContext.facts as { incidentId: string };
|
|
270
|
+
|
|
271
|
+
const fetchInput = { incidentId };
|
|
272
|
+
const fetchOutput = await incidentTools.fetch.call(fetchInput);
|
|
273
|
+
|
|
274
|
+
const classifyInput = { incident: fetchOutput.incident };
|
|
275
|
+
const classifyOutput = await incidentTools.classify.call(classifyInput);
|
|
276
|
+
|
|
277
|
+
const selectInput = {
|
|
278
|
+
incident: fetchOutput.incident,
|
|
279
|
+
severityOverride: classifyOutput.severity,
|
|
280
|
+
};
|
|
281
|
+
const selectOutput = await incidentTools.selectQueue.call(selectInput);
|
|
282
|
+
|
|
283
|
+
const escalateInput = {
|
|
284
|
+
incidentId,
|
|
285
|
+
target: selectOutput.rule.escalatesTo ?? 'incident-manager@northwind.example',
|
|
286
|
+
reason: selectOutput.rationale.join(' '),
|
|
287
|
+
};
|
|
288
|
+
const escalateOutput = selectOutput.escalationRequired
|
|
289
|
+
? await incidentTools.escalate.call(escalateInput)
|
|
290
|
+
: {
|
|
291
|
+
escalated: false,
|
|
292
|
+
ticketId: '',
|
|
293
|
+
target: escalateInput.target,
|
|
294
|
+
reason: escalateInput.reason,
|
|
295
|
+
timestamp: new Date().toISOString(),
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const plan: Plan = {
|
|
299
|
+
id: 'plan-incident-demo',
|
|
300
|
+
contextRef: incidentContext.id,
|
|
301
|
+
capabilityMapVersion,
|
|
302
|
+
tasks: [
|
|
303
|
+
{
|
|
304
|
+
id: incidentTasks.fetch.id,
|
|
305
|
+
capability: incidentTasks.fetch.capability,
|
|
306
|
+
input: fetchInput,
|
|
307
|
+
verification: incidentTasks.fetch.verification?.(),
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
id: incidentTasks.classify.id,
|
|
311
|
+
capability: incidentTasks.classify.capability,
|
|
312
|
+
input: classifyInput,
|
|
313
|
+
verification: incidentTasks.classify.verification?.(),
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: incidentTasks.select.id,
|
|
317
|
+
capability: incidentTasks.select.capability,
|
|
318
|
+
input: selectInput,
|
|
319
|
+
verification: incidentTasks.select.verification?.(),
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
id: incidentTasks.escalate.id,
|
|
323
|
+
capability: incidentTasks.escalate.capability,
|
|
324
|
+
input: escalateInput,
|
|
325
|
+
verification: incidentTasks.escalate.verification?.(),
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
edges: [
|
|
329
|
+
{ from: incidentTasks.fetch.id, to: incidentTasks.classify.id },
|
|
330
|
+
{ from: incidentTasks.classify.id, to: incidentTasks.select.id },
|
|
331
|
+
{ from: incidentTasks.select.id, to: incidentTasks.escalate.id },
|
|
332
|
+
],
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
return {
|
|
336
|
+
plan,
|
|
337
|
+
expectedOutputs: {
|
|
338
|
+
[incidentTasks.fetch.id]: fetchOutput,
|
|
339
|
+
[incidentTasks.classify.id]: classifyOutput,
|
|
340
|
+
[incidentTasks.select.id]: selectOutput,
|
|
341
|
+
[incidentTasks.escalate.id]: escalateOutput,
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const invoiceTools = {
|
|
347
|
+
fetchInvoice: new FetchInvoiceTool(),
|
|
348
|
+
fetchPO: new FetchPurchaseOrderTool(),
|
|
349
|
+
compare: new CompareLineItemsTool(),
|
|
350
|
+
record: new RecordFindingsTool(),
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const invoiceTasks = {
|
|
354
|
+
fetchInvoice: new FetchInvoiceTask(),
|
|
355
|
+
fetchPO: new FetchPurchaseOrderTask(),
|
|
356
|
+
compare: new CompareLineItemsTask(),
|
|
357
|
+
record: new RecordFindingsTask(),
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
const invoiceGoal: Goal = {
|
|
361
|
+
id: 'goal-invoice-1',
|
|
362
|
+
intent: 'Reconcile the Skyline Components invoice against the approved purchase order and log findings.',
|
|
363
|
+
constraints: {
|
|
364
|
+
varianceToleranceUsd: 500,
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const invoiceContext: Context = {
|
|
369
|
+
id: 'ctx-invoice-1',
|
|
370
|
+
version: '1.0',
|
|
371
|
+
facts: {
|
|
372
|
+
invoiceId: 'INV-84721',
|
|
373
|
+
purchaseOrderId: 'PO-99231',
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
async function buildInvoiceReferencePlan(): Promise<ScenarioReference> {
|
|
378
|
+
const { invoiceId, purchaseOrderId } = invoiceContext.facts as {
|
|
379
|
+
invoiceId: string;
|
|
380
|
+
purchaseOrderId: string;
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const fetchInvoiceInput = { invoiceId };
|
|
384
|
+
const fetchInvoiceOutput = await invoiceTools.fetchInvoice.call(fetchInvoiceInput);
|
|
385
|
+
|
|
386
|
+
const fetchPOInput = { purchaseOrderId };
|
|
387
|
+
const fetchPOOutput = await invoiceTools.fetchPO.call(fetchPOInput);
|
|
388
|
+
|
|
389
|
+
const compareInput = { invoice: fetchInvoiceOutput.invoice, purchaseOrder: fetchPOOutput.purchaseOrder };
|
|
390
|
+
const compareOutput = await invoiceTools.compare.call(compareInput);
|
|
391
|
+
|
|
392
|
+
const recordInput = {
|
|
393
|
+
invoice: fetchInvoiceOutput.invoice,
|
|
394
|
+
purchaseOrder: fetchPOOutput.purchaseOrder,
|
|
395
|
+
discrepancies: compareOutput.discrepancies,
|
|
396
|
+
variance: compareOutput.variance,
|
|
397
|
+
};
|
|
398
|
+
const recordOutput = await invoiceTools.record.call(recordInput);
|
|
399
|
+
|
|
400
|
+
const plan: Plan = {
|
|
401
|
+
id: 'plan-invoice-demo',
|
|
402
|
+
contextRef: invoiceContext.id,
|
|
403
|
+
capabilityMapVersion,
|
|
404
|
+
tasks: [
|
|
405
|
+
{
|
|
406
|
+
id: invoiceTasks.fetchInvoice.id,
|
|
407
|
+
capability: invoiceTasks.fetchInvoice.capability,
|
|
408
|
+
input: fetchInvoiceInput,
|
|
409
|
+
verification: invoiceTasks.fetchInvoice.verification?.(),
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
id: invoiceTasks.fetchPO.id,
|
|
413
|
+
capability: invoiceTasks.fetchPO.capability,
|
|
414
|
+
input: fetchPOInput,
|
|
415
|
+
verification: invoiceTasks.fetchPO.verification?.(),
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
id: invoiceTasks.compare.id,
|
|
419
|
+
capability: invoiceTasks.compare.capability,
|
|
420
|
+
input: compareInput,
|
|
421
|
+
verification: invoiceTasks.compare.verification?.(),
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
id: invoiceTasks.record.id,
|
|
425
|
+
capability: invoiceTasks.record.capability,
|
|
426
|
+
input: recordInput,
|
|
427
|
+
verification: invoiceTasks.record.verification?.(),
|
|
428
|
+
},
|
|
429
|
+
],
|
|
430
|
+
edges: [
|
|
431
|
+
{ from: invoiceTasks.fetchInvoice.id, to: invoiceTasks.fetchPO.id },
|
|
432
|
+
{ from: invoiceTasks.fetchPO.id, to: invoiceTasks.compare.id },
|
|
433
|
+
{ from: invoiceTasks.compare.id, to: invoiceTasks.record.id },
|
|
434
|
+
],
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
plan,
|
|
439
|
+
expectedOutputs: {
|
|
440
|
+
[invoiceTasks.fetchInvoice.id]: fetchInvoiceOutput,
|
|
441
|
+
[invoiceTasks.fetchPO.id]: fetchPOOutput,
|
|
442
|
+
[invoiceTasks.compare.id]: compareOutput,
|
|
443
|
+
[invoiceTasks.record.id]: recordOutput,
|
|
444
|
+
},
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const coachingTools = {
|
|
449
|
+
analyze: new AnalyzeTranscriptTool(),
|
|
450
|
+
generate: new GenerateFeedbackTool(),
|
|
451
|
+
log: new LogCoachingNoteTool(),
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const coachingTasks = {
|
|
455
|
+
analyze: new AnalyzeTranscriptTask(),
|
|
456
|
+
generate: new GenerateFeedbackTask(),
|
|
457
|
+
log: new LogCoachingNoteTask(),
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
const coachingGoal: Goal = {
|
|
461
|
+
id: 'goal-coaching-1',
|
|
462
|
+
intent: 'Review the escalated transcript, craft coaching feedback, and log the session for the agent manager.',
|
|
463
|
+
constraints: {
|
|
464
|
+
completionMinutes: 20,
|
|
465
|
+
},
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const coachingContext: Context = {
|
|
469
|
+
id: 'ctx-coaching-1',
|
|
470
|
+
version: '1.0',
|
|
471
|
+
facts: {
|
|
472
|
+
transcriptId: 'TRANS-5540',
|
|
473
|
+
},
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
async function buildCoachingReferencePlan(): Promise<ScenarioReference> {
|
|
477
|
+
const { transcriptId } = coachingContext.facts as { transcriptId: string };
|
|
478
|
+
|
|
479
|
+
const transcript = await getTranscript(transcriptId);
|
|
480
|
+
if (!transcript) {
|
|
481
|
+
throw new Error(`Transcript ${transcriptId} not found for scenario setup`);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const analyzeInput = { transcriptId };
|
|
485
|
+
const analyzeOutput = await coachingTools.analyze.call(analyzeInput);
|
|
486
|
+
|
|
487
|
+
const generateInput = {
|
|
488
|
+
transcriptId,
|
|
489
|
+
metrics: {
|
|
490
|
+
sentimentScore: analyzeOutput.sentimentScore,
|
|
491
|
+
complianceScore: analyzeOutput.complianceScore,
|
|
492
|
+
complianceBreaches: analyzeOutput.complianceBreaches,
|
|
493
|
+
highlights: analyzeOutput.highlights,
|
|
494
|
+
summary: analyzeOutput.summary,
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
const generateOutput = await coachingTools.generate.call(generateInput);
|
|
498
|
+
|
|
499
|
+
const logInput = {
|
|
500
|
+
agentId: transcript.agentId,
|
|
501
|
+
feedbackSummary: generateOutput.feedbackSummary,
|
|
502
|
+
actionItems: generateOutput.actionItems,
|
|
503
|
+
escalationRequired: generateOutput.escalationRequired,
|
|
504
|
+
};
|
|
505
|
+
const logOutput = await coachingTools.log.call(logInput);
|
|
506
|
+
|
|
507
|
+
const plan: Plan = {
|
|
508
|
+
id: 'plan-coaching-demo',
|
|
509
|
+
contextRef: coachingContext.id,
|
|
510
|
+
capabilityMapVersion,
|
|
511
|
+
tasks: [
|
|
512
|
+
{
|
|
513
|
+
id: coachingTasks.analyze.id,
|
|
514
|
+
capability: coachingTasks.analyze.capability,
|
|
515
|
+
input: analyzeInput,
|
|
516
|
+
verification: coachingTasks.analyze.verification?.(),
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
id: coachingTasks.generate.id,
|
|
520
|
+
capability: coachingTasks.generate.capability,
|
|
521
|
+
input: generateInput,
|
|
522
|
+
verification: coachingTasks.generate.verification?.(),
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
id: coachingTasks.log.id,
|
|
526
|
+
capability: coachingTasks.log.capability,
|
|
527
|
+
input: logInput,
|
|
528
|
+
verification: coachingTasks.log.verification?.(),
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
edges: [
|
|
532
|
+
{ from: coachingTasks.analyze.id, to: coachingTasks.generate.id },
|
|
533
|
+
{ from: coachingTasks.generate.id, to: coachingTasks.log.id },
|
|
534
|
+
],
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
plan,
|
|
539
|
+
expectedOutputs: {
|
|
540
|
+
[coachingTasks.analyze.id]: analyzeOutput,
|
|
541
|
+
[coachingTasks.generate.id]: generateOutput,
|
|
542
|
+
[coachingTasks.log.id]: logOutput,
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function registerEntitlementTools(registry: SimpleToolRegistry): void {
|
|
548
|
+
registry.register(entitlementTools.fetch);
|
|
549
|
+
registry.register(entitlementTools.evaluate);
|
|
550
|
+
registry.register(entitlementTools.notify);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function registerEntitlementCapabilities(registry: SimpleCapabilityRegistry): void {
|
|
554
|
+
registry.register({ name: entitlementTasks.fetch.capability, sideEffects: false }, entitlementTasks.fetch);
|
|
555
|
+
registry.register({ name: entitlementTasks.evaluate.capability, sideEffects: false }, entitlementTasks.evaluate);
|
|
556
|
+
registry.register({ name: entitlementTasks.notify.capability, sideEffects: true }, entitlementTasks.notify);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function registerKnowledgeTools(registry: SimpleToolRegistry): void {
|
|
560
|
+
registry.register(knowledgeTools.search);
|
|
561
|
+
registry.register(knowledgeTools.summarize);
|
|
562
|
+
registry.register(knowledgeTools.followups);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function registerKnowledgeCapabilities(registry: SimpleCapabilityRegistry): void {
|
|
566
|
+
registry.register({ name: knowledgeTasks.search.capability, sideEffects: false }, knowledgeTasks.search);
|
|
567
|
+
registry.register({ name: knowledgeTasks.summarize.capability, sideEffects: false }, knowledgeTasks.summarize);
|
|
568
|
+
registry.register({ name: knowledgeTasks.followups.capability, sideEffects: false }, knowledgeTasks.followups);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function registerIncidentTools(registry: SimpleToolRegistry): void {
|
|
572
|
+
registry.register(incidentTools.fetch);
|
|
573
|
+
registry.register(incidentTools.classify);
|
|
574
|
+
registry.register(incidentTools.selectQueue);
|
|
575
|
+
registry.register(incidentTools.escalate);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function registerIncidentCapabilities(registry: SimpleCapabilityRegistry): void {
|
|
579
|
+
registry.register({ name: incidentTasks.fetch.capability, sideEffects: false }, incidentTasks.fetch);
|
|
580
|
+
registry.register({ name: incidentTasks.classify.capability, sideEffects: false }, incidentTasks.classify);
|
|
581
|
+
registry.register({ name: incidentTasks.select.capability, sideEffects: false }, incidentTasks.select);
|
|
582
|
+
registry.register({ name: incidentTasks.escalate.capability, sideEffects: true }, incidentTasks.escalate);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function registerInvoiceTools(registry: SimpleToolRegistry): void {
|
|
586
|
+
registry.register(invoiceTools.fetchInvoice);
|
|
587
|
+
registry.register(invoiceTools.fetchPO);
|
|
588
|
+
registry.register(invoiceTools.compare);
|
|
589
|
+
registry.register(invoiceTools.record);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function registerInvoiceCapabilities(registry: SimpleCapabilityRegistry): void {
|
|
593
|
+
registry.register({ name: invoiceTasks.fetchInvoice.capability, sideEffects: false }, invoiceTasks.fetchInvoice);
|
|
594
|
+
registry.register({ name: invoiceTasks.fetchPO.capability, sideEffects: false }, invoiceTasks.fetchPO);
|
|
595
|
+
registry.register({ name: invoiceTasks.compare.capability, sideEffects: false }, invoiceTasks.compare);
|
|
596
|
+
registry.register({ name: invoiceTasks.record.capability, sideEffects: true }, invoiceTasks.record);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
function registerCoachingTools(registry: SimpleToolRegistry): void {
|
|
600
|
+
registry.register(coachingTools.analyze);
|
|
601
|
+
registry.register(coachingTools.generate);
|
|
602
|
+
registry.register(coachingTools.log);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function registerCoachingCapabilities(registry: SimpleCapabilityRegistry): void {
|
|
606
|
+
registry.register({ name: coachingTasks.analyze.capability, sideEffects: false }, coachingTasks.analyze);
|
|
607
|
+
registry.register({ name: coachingTasks.generate.capability, sideEffects: false }, coachingTasks.generate);
|
|
608
|
+
registry.register({ name: coachingTasks.log.capability, sideEffects: true }, coachingTasks.log);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export const scenarios: Record<ScenarioKey, ScenarioDefinition> = {
|
|
612
|
+
entitlement: {
|
|
613
|
+
key: 'entitlement',
|
|
614
|
+
name: 'Entitlement Decisioning',
|
|
615
|
+
description: 'Evaluate a premium benefit entitlement and notify the supervisor with the decision.',
|
|
616
|
+
goal: entitlementGoal,
|
|
617
|
+
context: entitlementContext,
|
|
618
|
+
registerTools: registerEntitlementTools,
|
|
619
|
+
registerCapabilities: registerEntitlementCapabilities,
|
|
620
|
+
buildReferencePlan: buildEntitlementReferencePlan,
|
|
621
|
+
assertExecution(result) {
|
|
622
|
+
const outputs = extractOutputs(result);
|
|
623
|
+
const notify = outputs[entitlementTasks.notify.id];
|
|
624
|
+
if (!notify?.notified) {
|
|
625
|
+
throw new Error('Entitlement scenario: supervisor notification not sent');
|
|
626
|
+
}
|
|
627
|
+
if (notify.decision && notify.decision !== 'allow' && notify.decision !== 'deny') {
|
|
628
|
+
throw new Error('Entitlement scenario: invalid decision flag');
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
knowledge: {
|
|
633
|
+
key: 'knowledge',
|
|
634
|
+
name: 'Knowledge Acceleration',
|
|
635
|
+
description: 'Retrieve and summarize knowledge for an urgent latency regression and produce follow-up actions.',
|
|
636
|
+
goal: knowledgeGoal,
|
|
637
|
+
context: knowledgeContext,
|
|
638
|
+
registerTools: registerKnowledgeTools,
|
|
639
|
+
registerCapabilities: registerKnowledgeCapabilities,
|
|
640
|
+
buildReferencePlan: buildKnowledgeReferencePlan,
|
|
641
|
+
assertExecution(result) {
|
|
642
|
+
const outputs = extractOutputs(result);
|
|
643
|
+
const summary = outputs[knowledgeTasks.summarize.id];
|
|
644
|
+
if (!summary?.summary) {
|
|
645
|
+
throw new Error('Knowledge scenario: summary missing');
|
|
646
|
+
}
|
|
647
|
+
const followups = outputs[knowledgeTasks.followups.id];
|
|
648
|
+
if (!Array.isArray(followups?.suggestions) || followups.suggestions.length === 0) {
|
|
649
|
+
throw new Error('Knowledge scenario: follow-up suggestions missing');
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
incidents: {
|
|
654
|
+
key: 'incidents',
|
|
655
|
+
name: 'Incident Triage',
|
|
656
|
+
description: 'Classify a critical incident, route it to the correct queue, and escalate if required.',
|
|
657
|
+
goal: incidentGoal,
|
|
658
|
+
context: incidentContext,
|
|
659
|
+
registerTools: registerIncidentTools,
|
|
660
|
+
registerCapabilities: registerIncidentCapabilities,
|
|
661
|
+
buildReferencePlan: buildIncidentReferencePlan,
|
|
662
|
+
assertExecution(result) {
|
|
663
|
+
const outputs = extractOutputs(result);
|
|
664
|
+
const classify = outputs[incidentTasks.classify.id];
|
|
665
|
+
if (!classify?.severity) {
|
|
666
|
+
throw new Error('Incident scenario: severity missing');
|
|
667
|
+
}
|
|
668
|
+
const select = outputs[incidentTasks.select.id];
|
|
669
|
+
if (!select?.queue) {
|
|
670
|
+
throw new Error('Incident scenario: queue not selected');
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
invoices: {
|
|
675
|
+
key: 'invoices',
|
|
676
|
+
name: 'Invoice Reconciliation',
|
|
677
|
+
description: 'Compare invoice line-items against a purchase order and archive the findings report.',
|
|
678
|
+
goal: invoiceGoal,
|
|
679
|
+
context: invoiceContext,
|
|
680
|
+
registerTools: registerInvoiceTools,
|
|
681
|
+
registerCapabilities: registerInvoiceCapabilities,
|
|
682
|
+
buildReferencePlan: buildInvoiceReferencePlan,
|
|
683
|
+
assertExecution(result) {
|
|
684
|
+
const outputs = extractOutputs(result);
|
|
685
|
+
const compare = outputs[invoiceTasks.compare.id];
|
|
686
|
+
if (!compare || typeof compare.variance !== 'number') {
|
|
687
|
+
throw new Error('Invoice scenario: variance missing');
|
|
688
|
+
}
|
|
689
|
+
const record = outputs[invoiceTasks.record.id];
|
|
690
|
+
if (!record?.reportId) {
|
|
691
|
+
throw new Error('Invoice scenario: findings report not produced');
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
coaching: {
|
|
696
|
+
key: 'coaching',
|
|
697
|
+
name: 'Agent Coaching',
|
|
698
|
+
description: 'Analyze a transcript for sentiment, generate coaching feedback, and log the coaching note.',
|
|
699
|
+
goal: coachingGoal,
|
|
700
|
+
context: coachingContext,
|
|
701
|
+
registerTools: registerCoachingTools,
|
|
702
|
+
registerCapabilities: registerCoachingCapabilities,
|
|
703
|
+
buildReferencePlan: buildCoachingReferencePlan,
|
|
704
|
+
assertExecution(result) {
|
|
705
|
+
const outputs = extractOutputs(result);
|
|
706
|
+
const feedback = outputs[coachingTasks.generate.id];
|
|
707
|
+
if (!feedback?.feedbackSummary) {
|
|
708
|
+
throw new Error('Coaching scenario: feedback summary missing');
|
|
709
|
+
}
|
|
710
|
+
const log = outputs[coachingTasks.log.id];
|
|
711
|
+
if (!log?.stored) {
|
|
712
|
+
throw new Error('Coaching scenario: coaching note not stored');
|
|
713
|
+
}
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
export function listScenarioKeys(): ScenarioKey[] {
|
|
719
|
+
return Object.keys(scenarios) as ScenarioKey[];
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
export function getScenario(key: string): ScenarioDefinition | undefined {
|
|
723
|
+
return scenarios[key as ScenarioKey];
|
|
724
|
+
}
|