@ddse/acm-examples 0.5.0 → 0.5.2
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/dist/src/examples/entitlement/tasks.d.ts +44 -0
- package/dist/src/examples/entitlement/tasks.d.ts.map +1 -0
- package/dist/src/examples/entitlement/tasks.js +27 -0
- package/dist/src/examples/entitlement/tasks.js.map +1 -0
- package/dist/src/examples/entitlement/tools.d.ts +74 -0
- package/dist/src/examples/entitlement/tools.d.ts.map +1 -0
- package/dist/src/examples/entitlement/tools.js +63 -0
- package/dist/src/examples/entitlement/tools.js.map +1 -0
- package/dist/src/framework.d.ts +19 -0
- package/dist/src/framework.d.ts.map +1 -0
- package/dist/src/framework.js +42 -0
- package/dist/src/framework.js.map +1 -0
- package/dist/src/registries.d.ts +3 -0
- package/dist/src/registries.d.ts.map +1 -1
- package/dist/src/registries.js +11 -0
- package/dist/src/registries.js.map +1 -1
- package/dist/tests/entitlement.test.d.ts +2 -0
- package/dist/tests/entitlement.test.d.ts.map +1 -0
- package/dist/tests/entitlement.test.js +30 -0
- package/dist/tests/entitlement.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -9
- package/bin/acm-demo.ts +0 -495
- package/data/coaching/agents.json +0 -16
- package/data/coaching/transcripts.json +0 -37
- package/data/documents.json +0 -72
- package/data/entitlement/customers.json +0 -38
- package/data/entitlement/policies.json +0 -38
- package/data/incidents/incidents.json +0 -30
- package/data/incidents/routing_rules.json +0 -36
- package/data/invoices/invoices.json +0 -38
- package/data/invoices/purchase-orders.json +0 -38
- package/data/issues.json +0 -99
- package/data/knowledge/docs/kb-001.md +0 -7
- package/data/knowledge/docs/kb-002.md +0 -7
- package/data/knowledge/docs/kb-003.md +0 -9
- package/data/knowledge/index.json +0 -25
- package/data/orders.json +0 -106
- package/docs/examples-architecture.md +0 -144
- package/docs/successrun.md +0 -1022
- package/src/context/directives.ts +0 -366
- package/src/context/index.ts +0 -1
- package/src/data/coaching.ts +0 -50
- package/src/data/entitlement.ts +0 -60
- package/src/data/incidents.ts +0 -78
- package/src/data/invoices.ts +0 -103
- package/src/data/knowledge.ts +0 -77
- package/src/data/loader.ts +0 -80
- package/src/examples/scenarios.ts +0 -724
- package/src/goals/index.ts +0 -18
- package/src/policy.ts +0 -30
- package/src/registries.ts +0 -48
- package/src/renderer.ts +0 -82
- package/src/search/bm25.ts +0 -173
- package/src/search/index.ts +0 -2
- package/src/tasks/coaching.ts +0 -217
- package/src/tasks/entitlement.ts +0 -197
- package/src/tasks/incidents.ts +0 -277
- package/src/tasks/index.ts +0 -6
- package/src/tasks/invoices.ts +0 -269
- package/src/tasks/knowledge.ts +0 -169
- package/src/tasks/legacy.ts +0 -112
- package/src/tools/coaching/index.ts +0 -197
- package/src/tools/entitlement/index.ts +0 -199
- package/src/tools/incidents/index.ts +0 -185
- package/src/tools/index.ts +0 -192
- package/src/tools/invoices/index.ts +0 -165
- package/src/tools/knowledge/index.ts +0 -203
- package/tests/bm25.test.ts +0 -129
- package/tests/integration.test.ts +0 -163
- package/tests/plan-hydration.test.ts +0 -33
- package/tsconfig.json +0 -18
package/bin/acm-demo.ts
DELETED
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { parseArgs } from 'node:util';
|
|
4
|
-
import { createInterface } from 'node:readline/promises';
|
|
5
|
-
import { stdin as input, stdout as output, exit } from 'node:process';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
DefaultStreamSink,
|
|
9
|
-
ExternalContextProviderAdapter,
|
|
10
|
-
type LLMCallFn,
|
|
11
|
-
type Plan,
|
|
12
|
-
normalizePlan,
|
|
13
|
-
normalizePlannerResult,
|
|
14
|
-
type NormalizedPlannerResult,
|
|
15
|
-
} from '@ddse/acm-sdk';
|
|
16
|
-
import { MemoryLedger, FileCheckpointStore } from '@ddse/acm-runtime';
|
|
17
|
-
import { createOllamaClient, createVLLMClient } from '@ddse/acm-llm';
|
|
18
|
-
import type { LLM, ToolCall } from '@ddse/acm-llm';
|
|
19
|
-
import { ACMFramework, ExecutionEngine } from '@ddse/acm-framework';
|
|
20
|
-
import { ReplayBundleExporter, type TaskIORecord } from '@ddse/acm-replay';
|
|
21
|
-
|
|
22
|
-
import { SimpleCapabilityRegistry, SimpleToolRegistry } from '../src/registries.js';
|
|
23
|
-
import { SimplePolicyEngine } from '../src/policy.js';
|
|
24
|
-
import { CLIRenderer } from '../src/renderer.js';
|
|
25
|
-
import { registerExampleContextProviders } from '../src/context/index.js';
|
|
26
|
-
import { getScenario, listScenarioKeys, scenarios, type ScenarioDefinition } from '../src/examples/scenarios.js';
|
|
27
|
-
|
|
28
|
-
type LLMProvider = 'ollama' | 'vllm';
|
|
29
|
-
|
|
30
|
-
type CLIOptions = {
|
|
31
|
-
scenarioKey?: string;
|
|
32
|
-
provider: LLMProvider;
|
|
33
|
-
model: string;
|
|
34
|
-
baseUrl?: string;
|
|
35
|
-
engine: ExecutionEngine;
|
|
36
|
-
stream: boolean;
|
|
37
|
-
resume?: string;
|
|
38
|
-
checkpointDir: string;
|
|
39
|
-
saveBundle: boolean;
|
|
40
|
-
listOnly: boolean;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
type RawCLIArgs = {
|
|
44
|
-
scenario?: string;
|
|
45
|
-
goal?: string;
|
|
46
|
-
provider?: string;
|
|
47
|
-
model?: string;
|
|
48
|
-
'base-url'?: string;
|
|
49
|
-
engine?: string;
|
|
50
|
-
stream?: boolean;
|
|
51
|
-
resume?: string;
|
|
52
|
-
'checkpoint-dir'?: string;
|
|
53
|
-
'save-bundle'?: boolean;
|
|
54
|
-
list?: boolean;
|
|
55
|
-
help?: boolean;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
type PlanTask = NonNullable<Plan['tasks']>[number];
|
|
59
|
-
|
|
60
|
-
const defaultModelByProvider: Record<LLMProvider, string> = {
|
|
61
|
-
ollama: 'llama3.1',
|
|
62
|
-
vllm: 'qwen2.5:7b',
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
function printHelp(): void {
|
|
66
|
-
console.log(
|
|
67
|
-
`ACM Demo CLI\n\n` +
|
|
68
|
-
`Usage:\n` +
|
|
69
|
-
` acm-demo [options]\n\n` +
|
|
70
|
-
`Options:\n` +
|
|
71
|
-
` --scenario <key> Scenario key to execute (${listScenarioKeys().join(', ')})\n` +
|
|
72
|
-
` --list List available scenarios and exit\n` +
|
|
73
|
-
` --provider <ollama|vllm> LLM provider (default: ollama)\n` +
|
|
74
|
-
` --model <name> Model identifier (defaults per provider)\n` +
|
|
75
|
-
` --base-url <url> Override LLM endpoint\n` +
|
|
76
|
-
` --engine <acm|langgraph|msaf> Execution engine (default: acm)\n` +
|
|
77
|
-
` --resume <runId> Resume a prior ACM engine run\n` +
|
|
78
|
-
` --checkpoint-dir <dir> Directory for checkpoints (default: ./checkpoints)\n` +
|
|
79
|
-
` --no-stream Disable streaming updates\n` +
|
|
80
|
-
` --save-bundle Export a replay bundle to ./replay/<runId>/\n` +
|
|
81
|
-
` -h, --help Show this help message\n`
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function mapLegacyGoal(goal?: string): string | undefined {
|
|
86
|
-
if (!goal) return undefined;
|
|
87
|
-
switch (goal.toLowerCase()) {
|
|
88
|
-
case 'refund':
|
|
89
|
-
return 'entitlement';
|
|
90
|
-
case 'issues':
|
|
91
|
-
return 'knowledge';
|
|
92
|
-
default:
|
|
93
|
-
return goal;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function resolveExecutionEngine(engine?: string): ExecutionEngine {
|
|
98
|
-
if (!engine) {
|
|
99
|
-
return ExecutionEngine.ACM;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const normalized = engine.toUpperCase();
|
|
103
|
-
switch (normalized) {
|
|
104
|
-
case 'ACM':
|
|
105
|
-
return ExecutionEngine.ACM;
|
|
106
|
-
case 'LANGGRAPH':
|
|
107
|
-
case 'LANG-GRAPH':
|
|
108
|
-
case 'LANG_GRAPH':
|
|
109
|
-
return ExecutionEngine.LANGGRAPH;
|
|
110
|
-
case 'MSAF':
|
|
111
|
-
case 'MS_AGENT_FRAMEWORK':
|
|
112
|
-
case 'MS-AGENT-FRAMEWORK':
|
|
113
|
-
return ExecutionEngine.MSAF;
|
|
114
|
-
default:
|
|
115
|
-
throw new Error(`Unsupported execution engine: ${engine}`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function parseCliOptions(): { options: CLIOptions; showHelp: boolean } {
|
|
120
|
-
const { values } = parseArgs({
|
|
121
|
-
options: {
|
|
122
|
-
scenario: { type: 'string' },
|
|
123
|
-
goal: { type: 'string' },
|
|
124
|
-
provider: { type: 'string' },
|
|
125
|
-
model: { type: 'string' },
|
|
126
|
-
'base-url': { type: 'string' },
|
|
127
|
-
engine: { type: 'string' },
|
|
128
|
-
stream: { type: 'boolean', default: true },
|
|
129
|
-
resume: { type: 'string' },
|
|
130
|
-
'checkpoint-dir': { type: 'string' },
|
|
131
|
-
'save-bundle': { type: 'boolean', default: false },
|
|
132
|
-
list: { type: 'boolean', default: false },
|
|
133
|
-
help: { type: 'boolean', default: false },
|
|
134
|
-
},
|
|
135
|
-
allowPositionals: false,
|
|
136
|
-
}) as { values: RawCLIArgs };
|
|
137
|
-
|
|
138
|
-
const provider = (values.provider ?? 'ollama').toLowerCase();
|
|
139
|
-
if (provider !== 'ollama' && provider !== 'vllm') {
|
|
140
|
-
throw new Error(`Unsupported provider: ${values.provider}`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const engine = resolveExecutionEngine(values.engine);
|
|
144
|
-
|
|
145
|
-
const scenarioKey = values.scenario ?? mapLegacyGoal(values.goal);
|
|
146
|
-
const model = values.model ?? defaultModelByProvider[provider as LLMProvider];
|
|
147
|
-
return {
|
|
148
|
-
options: {
|
|
149
|
-
scenarioKey,
|
|
150
|
-
provider: provider as LLMProvider,
|
|
151
|
-
model,
|
|
152
|
-
baseUrl: values['base-url'],
|
|
153
|
-
engine,
|
|
154
|
-
stream: values.stream ?? true,
|
|
155
|
-
resume: values.resume,
|
|
156
|
-
checkpointDir: values['checkpoint-dir'] ?? './checkpoints',
|
|
157
|
-
saveBundle: values['save-bundle'] ?? false,
|
|
158
|
-
listOnly: values.list ?? false,
|
|
159
|
-
},
|
|
160
|
-
showHelp: Boolean(values.help),
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
async function resolveScenario(options: CLIOptions): Promise<ScenarioDefinition> {
|
|
165
|
-
if (options.scenarioKey) {
|
|
166
|
-
const direct = getScenario(options.scenarioKey);
|
|
167
|
-
if (!direct) {
|
|
168
|
-
throw new Error(`Unknown scenario: ${options.scenarioKey}`);
|
|
169
|
-
}
|
|
170
|
-
return direct;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (!output.isTTY) {
|
|
174
|
-
throw new Error('No scenario provided and terminal is non-interactive. Use --scenario <key>.');
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
console.log('Please choose a scenario to run:\n');
|
|
178
|
-
const keys = listScenarioKeys();
|
|
179
|
-
keys.forEach((key, index) => {
|
|
180
|
-
const scenario = scenarios[key];
|
|
181
|
-
console.log(` [${index + 1}] ${scenario.name} (${key})`);
|
|
182
|
-
console.log(` ${scenario.description}`);
|
|
183
|
-
});
|
|
184
|
-
console.log();
|
|
185
|
-
|
|
186
|
-
const rl = createInterface({ input, output });
|
|
187
|
-
try {
|
|
188
|
-
while (true) {
|
|
189
|
-
const answer = (await rl.question('Enter scenario number or key: ')).trim();
|
|
190
|
-
if (!answer) {
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const numeric = Number.parseInt(answer, 10);
|
|
195
|
-
if (!Number.isNaN(numeric) && numeric >= 1 && numeric <= keys.length) {
|
|
196
|
-
return scenarios[keys[numeric - 1]];
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const byKey = getScenario(answer);
|
|
200
|
-
if (byKey) {
|
|
201
|
-
return byKey;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
console.log(`Invalid selection: ${answer}`);
|
|
205
|
-
}
|
|
206
|
-
} finally {
|
|
207
|
-
rl.close();
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function createLLMClient(provider: LLMProvider, model: string, baseUrl?: string): LLM {
|
|
212
|
-
switch (provider) {
|
|
213
|
-
case 'ollama':
|
|
214
|
-
return createOllamaClient(model, baseUrl);
|
|
215
|
-
case 'vllm':
|
|
216
|
-
return createVLLMClient(model, baseUrl);
|
|
217
|
-
default:
|
|
218
|
-
throw new Error(`Unsupported provider: ${provider satisfies never}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function attachStreaming(renderer: CLIRenderer, stream: DefaultStreamSink): void {
|
|
223
|
-
stream.attach('planner', chunk => renderer.renderPlannerToken(chunk));
|
|
224
|
-
stream.attach('task', update => renderer.renderTaskUpdate(update));
|
|
225
|
-
stream.attach('checkpoint', update => {
|
|
226
|
-
if (typeof update?.checkpointId === 'string') {
|
|
227
|
-
console.log(`💾 Checkpoint created: ${update.checkpointId} (${update.tasksCompleted} tasks completed)`);
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
async function main(): Promise<void> {
|
|
234
|
-
const { options, showHelp } = parseCliOptions();
|
|
235
|
-
|
|
236
|
-
if (showHelp) {
|
|
237
|
-
printHelp();
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (options.listOnly) {
|
|
242
|
-
console.log('Available scenarios:\n');
|
|
243
|
-
listScenarioKeys().forEach(key => {
|
|
244
|
-
const scenario = scenarios[key];
|
|
245
|
-
console.log(`- ${key}: ${scenario.name}`);
|
|
246
|
-
console.log(` ${scenario.description}`);
|
|
247
|
-
});
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const scenario = await resolveScenario(options);
|
|
252
|
-
|
|
253
|
-
console.log(`\n🎯 Scenario: ${scenario.name}`);
|
|
254
|
-
console.log(` Key: ${scenario.key}`);
|
|
255
|
-
console.log(` Description: ${scenario.description}\n`);
|
|
256
|
-
|
|
257
|
-
const toolRegistry = new SimpleToolRegistry();
|
|
258
|
-
const capabilityRegistry = new SimpleCapabilityRegistry();
|
|
259
|
-
scenario.registerTools(toolRegistry);
|
|
260
|
-
scenario.registerCapabilities(capabilityRegistry);
|
|
261
|
-
|
|
262
|
-
const adapter = new ExternalContextProviderAdapter();
|
|
263
|
-
registerExampleContextProviders(adapter);
|
|
264
|
-
|
|
265
|
-
const llm = createLLMClient(options.provider, options.model, options.baseUrl);
|
|
266
|
-
const stream = new DefaultStreamSink();
|
|
267
|
-
const renderer = new CLIRenderer();
|
|
268
|
-
|
|
269
|
-
if (options.stream) {
|
|
270
|
-
attachStreaming(renderer, stream);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const verify = async (taskId: string, output: any, expressions: string[]): Promise<boolean> => {
|
|
274
|
-
for (const expr of expressions) {
|
|
275
|
-
try {
|
|
276
|
-
const fn = new Function('output', `return ${expr};`);
|
|
277
|
-
const result = fn(output);
|
|
278
|
-
if (!result) {
|
|
279
|
-
console.error(`Verification failed for ${taskId}: ${expr}`);
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
} catch (error) {
|
|
283
|
-
console.error(`Verification error for ${taskId}: ${expr}`, error);
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return true;
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const nucleusLLMCall: LLMCallFn = async (prompt, tools, callConfig) => {
|
|
291
|
-
const toolDefs = tools.map(tool => ({
|
|
292
|
-
name: tool.name,
|
|
293
|
-
description: tool.description ?? 'Nucleus tool',
|
|
294
|
-
inputSchema: tool.inputSchema ?? { type: 'object', properties: {} },
|
|
295
|
-
}));
|
|
296
|
-
|
|
297
|
-
const response = await llm.generateWithTools!(
|
|
298
|
-
[
|
|
299
|
-
{
|
|
300
|
-
role: 'system',
|
|
301
|
-
content: prompt,
|
|
302
|
-
},
|
|
303
|
-
],
|
|
304
|
-
toolDefs,
|
|
305
|
-
{
|
|
306
|
-
temperature: callConfig.temperature,
|
|
307
|
-
seed: callConfig.seed,
|
|
308
|
-
maxTokens: callConfig.maxTokens,
|
|
309
|
-
}
|
|
310
|
-
);
|
|
311
|
-
|
|
312
|
-
const responseToolCalls = (response.toolCalls ?? []) as ToolCall[];
|
|
313
|
-
const toolCalls = responseToolCalls.map(tc => ({
|
|
314
|
-
id: tc.id,
|
|
315
|
-
name: tc.name,
|
|
316
|
-
input: tc.arguments,
|
|
317
|
-
}));
|
|
318
|
-
|
|
319
|
-
return {
|
|
320
|
-
reasoning: response.text,
|
|
321
|
-
toolCalls,
|
|
322
|
-
raw: response.raw,
|
|
323
|
-
};
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const nucleusConfig = {
|
|
327
|
-
llmCall: {
|
|
328
|
-
provider: llm.name(),
|
|
329
|
-
model: options.model,
|
|
330
|
-
temperature: 0.5,
|
|
331
|
-
maxTokens: 8096,
|
|
332
|
-
},
|
|
333
|
-
hooks: {
|
|
334
|
-
preflight: false,
|
|
335
|
-
postcheck: false,
|
|
336
|
-
},
|
|
337
|
-
} as const;
|
|
338
|
-
|
|
339
|
-
const framework = ACMFramework.create({
|
|
340
|
-
capabilityRegistry,
|
|
341
|
-
toolRegistry,
|
|
342
|
-
policyEngine: new SimplePolicyEngine(),
|
|
343
|
-
nucleus: {
|
|
344
|
-
call: nucleusLLMCall,
|
|
345
|
-
llmConfig: nucleusConfig.llmCall,
|
|
346
|
-
hooks: nucleusConfig.hooks,
|
|
347
|
-
},
|
|
348
|
-
verify,
|
|
349
|
-
defaultStream: options.stream ? stream : undefined,
|
|
350
|
-
contextProvider: adapter,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
const ledger = new MemoryLedger();
|
|
354
|
-
const checkpointStore = new FileCheckpointStore(options.checkpointDir);
|
|
355
|
-
const runId = options.resume ?? `run-${Date.now()}`;
|
|
356
|
-
const startedAt = new Date().toISOString();
|
|
357
|
-
|
|
358
|
-
console.log('📋 Planning...\n');
|
|
359
|
-
const planResponse = await framework.plan({
|
|
360
|
-
goal: scenario.goal,
|
|
361
|
-
context: scenario.context,
|
|
362
|
-
stream: options.stream ? stream : undefined,
|
|
363
|
-
ledger,
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
const rawPlannerResult = planResponse.result;
|
|
367
|
-
const rawPlan = planResponse.selectedPlan;
|
|
368
|
-
|
|
369
|
-
if (!rawPlan) {
|
|
370
|
-
throw new Error('Structured planner did not return a plan');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const normalizeOptions = {
|
|
374
|
-
capabilityRegistry,
|
|
375
|
-
defaultContextRef: scenario.context.id ?? scenario.key,
|
|
376
|
-
planIdPrefix: `${scenario.key}-plan`,
|
|
377
|
-
} as const;
|
|
378
|
-
|
|
379
|
-
const plan = normalizePlan(rawPlan, normalizeOptions);
|
|
380
|
-
const plannerResult: NormalizedPlannerResult = normalizePlannerResult(
|
|
381
|
-
rawPlannerResult,
|
|
382
|
-
plan,
|
|
383
|
-
normalizeOptions
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
if (plannerResult?.rationale) {
|
|
387
|
-
console.log('🧠 Planner rationale:\n');
|
|
388
|
-
console.log(plannerResult.rationale);
|
|
389
|
-
console.log();
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (plannerResult?.plans?.length) {
|
|
393
|
-
console.log('📝 Planner plan summary (first plan):');
|
|
394
|
-
const firstPlan = plannerResult.plans[0];
|
|
395
|
-
console.log(JSON.stringify({
|
|
396
|
-
id: firstPlan.id,
|
|
397
|
-
contextRef: firstPlan.contextRef,
|
|
398
|
-
tasks: (firstPlan.tasks ?? []).map((task: PlanTask) => ({
|
|
399
|
-
id: task.id,
|
|
400
|
-
capability: task.capability ?? task.capabilityRef,
|
|
401
|
-
hasInput: Boolean(task.input && Object.keys(task.input).length > 0),
|
|
402
|
-
inputPreview: task.input ?? null,
|
|
403
|
-
})),
|
|
404
|
-
}, null, 2));
|
|
405
|
-
console.log();
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
console.log(`\n✅ Plans generated: ${plannerResult?.plans?.length ?? 0}`);
|
|
409
|
-
if (plan.id) {
|
|
410
|
-
console.log(`Executing plan ${plan.id}`);
|
|
411
|
-
}
|
|
412
|
-
console.log(`Context Ref: ${plan.contextRef ?? 'n/a'}`);
|
|
413
|
-
console.log('Tasks:');
|
|
414
|
-
plan.tasks?.forEach((task: PlanTask, index: number) => {
|
|
415
|
-
console.log(` ${index + 1}. ${task.id} -> ${task.capability ?? task.capabilityRef ?? 'unknown'}`);
|
|
416
|
-
});
|
|
417
|
-
console.log();
|
|
418
|
-
|
|
419
|
-
const executionEngine = options.engine;
|
|
420
|
-
if (executionEngine !== ExecutionEngine.ACM && options.resume) {
|
|
421
|
-
console.warn('⚠️ Resume is only supported with the ACM engine. Ignoring --resume.');
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
const executeResult = await framework.execute({
|
|
425
|
-
goal: scenario.goal,
|
|
426
|
-
context: scenario.context,
|
|
427
|
-
stream: options.stream ? stream : undefined,
|
|
428
|
-
engine: executionEngine,
|
|
429
|
-
ledger,
|
|
430
|
-
existingPlan: {
|
|
431
|
-
plan,
|
|
432
|
-
plannerResult,
|
|
433
|
-
},
|
|
434
|
-
resumeFrom: executionEngine === ExecutionEngine.ACM ? options.resume : undefined,
|
|
435
|
-
checkpointStore: executionEngine === ExecutionEngine.ACM ? checkpointStore : undefined,
|
|
436
|
-
checkpointInterval: executionEngine === ExecutionEngine.ACM ? 1 : undefined,
|
|
437
|
-
runId,
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
const completedAt = new Date().toISOString();
|
|
441
|
-
|
|
442
|
-
renderer.renderSummary(executeResult.execution);
|
|
443
|
-
scenario.assertExecution(executeResult.execution);
|
|
444
|
-
|
|
445
|
-
if (options.saveBundle) {
|
|
446
|
-
console.log('\n💾 Saving replay bundle...');
|
|
447
|
-
const taskIO: TaskIORecord[] = [];
|
|
448
|
-
for (const taskSpec of plan.tasks as PlanTask[]) {
|
|
449
|
-
const record = executeResult.execution.outputsByTask?.[taskSpec.id];
|
|
450
|
-
if (record?.output !== undefined) {
|
|
451
|
-
taskIO.push({
|
|
452
|
-
taskId: taskSpec.id,
|
|
453
|
-
capability: taskSpec.capabilityRef || taskSpec.capability || 'unknown',
|
|
454
|
-
input: taskSpec.input || {},
|
|
455
|
-
output: record.output,
|
|
456
|
-
ts: new Date().toISOString(),
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const bundlePath = await ReplayBundleExporter.export({
|
|
462
|
-
outputDir: `./replay/${runId}`,
|
|
463
|
-
goal: scenario.goal,
|
|
464
|
-
context: scenario.context,
|
|
465
|
-
plans: plannerResult.plans,
|
|
466
|
-
selectedPlanId: plan.id,
|
|
467
|
-
ledger: Array.from(executeResult.execution.ledger) as any[],
|
|
468
|
-
taskIO,
|
|
469
|
-
engineTrace: {
|
|
470
|
-
runId,
|
|
471
|
-
engine: executionEngine,
|
|
472
|
-
startedAt,
|
|
473
|
-
completedAt,
|
|
474
|
-
status: 'success',
|
|
475
|
-
tasks: (plan.tasks as PlanTask[]).map(task => ({
|
|
476
|
-
taskId: task.id,
|
|
477
|
-
status: executeResult.execution.outputsByTask?.[task.id] ? 'completed' : 'skipped',
|
|
478
|
-
startedAt,
|
|
479
|
-
completedAt,
|
|
480
|
-
})),
|
|
481
|
-
},
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
console.log(` ✅ Bundle saved to: ${bundlePath}`);
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
console.log('\n✅ Demo completed successfully!');
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
491
|
-
main().catch(error => {
|
|
492
|
-
console.error('Fatal error:', error);
|
|
493
|
-
exit(1);
|
|
494
|
-
});
|
|
495
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "AG-883",
|
|
4
|
-
"name": "Priya Singh",
|
|
5
|
-
"region": "AMER",
|
|
6
|
-
"tenureMonths": 28,
|
|
7
|
-
"managerEmail": "luis.mendez@northwind.example"
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"id": "AG-905",
|
|
11
|
-
"name": "Jordan Lee",
|
|
12
|
-
"region": "EMEA",
|
|
13
|
-
"tenureMonths": 14,
|
|
14
|
-
"managerEmail": "ella.thompson@northwind.example"
|
|
15
|
-
}
|
|
16
|
-
]
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "TRANS-5540",
|
|
4
|
-
"agentId": "AG-883",
|
|
5
|
-
"customerSentiment": "NEGATIVE",
|
|
6
|
-
"complianceFlags": ["DISCLOSURE_MISSED", "CALL_TAG_MISSING"],
|
|
7
|
-
"transcript": [
|
|
8
|
-
"Agent: Thank you for calling Northwind Support, this is Priya.",
|
|
9
|
-
"Customer: I've been waiting three days for someone to unblock my fulfillment feed.",
|
|
10
|
-
"Agent: I can see the backlog and I'm escalating to our ops team right now.",
|
|
11
|
-
"Customer: This is costing me money every hour.",
|
|
12
|
-
"Agent: I completely understand how frustrating that is and I'm logging an urgent ticket.",
|
|
13
|
-
"Agent: You'll get an update within the next two hours and I'll follow up personally.",
|
|
14
|
-
"Customer: Please make sure someone actually reaches out this time.",
|
|
15
|
-
"Agent: Absolutely, I'll send you confirmation as soon as I have it."
|
|
16
|
-
],
|
|
17
|
-
"callDurationSeconds": 780,
|
|
18
|
-
"followUpRequired": true
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "TRANS-5581",
|
|
22
|
-
"agentId": "AG-905",
|
|
23
|
-
"customerSentiment": "NEUTRAL",
|
|
24
|
-
"complianceFlags": [],
|
|
25
|
-
"transcript": [
|
|
26
|
-
"Agent: Hi, this is Jordan with Northwind Coaching Desk.",
|
|
27
|
-
"Customer: I'm double-checking the renewal timeline for our premium license.",
|
|
28
|
-
"Agent: Happy to help—your renewal is scheduled for next month on the 18th.",
|
|
29
|
-
"Customer: Great, can you send me the quote details?",
|
|
30
|
-
"Agent: I'll email them right away and flag your account manager to follow up.",
|
|
31
|
-
"Customer: Perfect, thanks for the quick support.",
|
|
32
|
-
"Agent: Anytime! Let me know if there's anything else."
|
|
33
|
-
],
|
|
34
|
-
"callDurationSeconds": 360,
|
|
35
|
-
"followUpRequired": false
|
|
36
|
-
}
|
|
37
|
-
]
|
package/data/documents.json
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "doc-001",
|
|
4
|
-
"title": "Product Returns Policy",
|
|
5
|
-
"content": "Our returns policy allows customers to return items within 30 days of purchase. Refunds are processed within 5-7 business days after receiving the returned item. Items must be in original condition with tags attached. Digital products are non-refundable.",
|
|
6
|
-
"category": "policy",
|
|
7
|
-
"tags": ["returns", "refunds", "policy"]
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"id": "doc-002",
|
|
11
|
-
"title": "Shipping Information",
|
|
12
|
-
"content": "We offer standard and express shipping options. Standard shipping takes 5-7 business days, while express shipping takes 2-3 business days. Free shipping is available on orders over $50. International shipping is available to select countries.",
|
|
13
|
-
"category": "shipping",
|
|
14
|
-
"tags": ["shipping", "delivery", "logistics"]
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"id": "doc-003",
|
|
18
|
-
"title": "Customer Support Hours",
|
|
19
|
-
"content": "Our customer support team is available Monday through Friday, 9 AM to 6 PM EST. Weekend support is available for urgent issues. You can reach us via email, phone, or live chat. Average response time is under 2 hours during business hours.",
|
|
20
|
-
"category": "support",
|
|
21
|
-
"tags": ["support", "hours", "contact"]
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"id": "doc-004",
|
|
25
|
-
"title": "Payment Methods",
|
|
26
|
-
"content": "We accept major credit cards including Visa, Mastercard, American Express, and Discover. PayPal and Apple Pay are also accepted. For enterprise customers, we offer invoice payment with NET30 terms. All transactions are secured with SSL encryption.",
|
|
27
|
-
"category": "payment",
|
|
28
|
-
"tags": ["payment", "billing", "finance"]
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": "doc-005",
|
|
32
|
-
"title": "Data Privacy Policy",
|
|
33
|
-
"content": "We are committed to protecting your personal data. We collect only essential information needed to process orders. Data is encrypted at rest and in transit. We never sell customer data to third parties. GDPR compliant for EU customers.",
|
|
34
|
-
"category": "privacy",
|
|
35
|
-
"tags": ["privacy", "data", "security", "gdpr"]
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"id": "doc-006",
|
|
39
|
-
"title": "Product Warranty",
|
|
40
|
-
"content": "All products come with a 1-year manufacturer warranty covering defects in materials and workmanship. Extended warranty options are available at checkout. Warranty claims can be submitted through our support portal. Turnaround time is typically 7-14 days.",
|
|
41
|
-
"category": "warranty",
|
|
42
|
-
"tags": ["warranty", "coverage", "guarantee"]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"id": "doc-007",
|
|
46
|
-
"title": "Account Management",
|
|
47
|
-
"content": "Create an account to track orders, save payment methods, and manage your profile. Two-factor authentication is available for enhanced security. Password must be at least 8 characters with uppercase, lowercase, and numbers. Account can be deleted at any time.",
|
|
48
|
-
"category": "account",
|
|
49
|
-
"tags": ["account", "profile", "security"]
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"id": "doc-008",
|
|
53
|
-
"title": "Bulk Ordering",
|
|
54
|
-
"content": "Bulk discounts are available for orders of 100 units or more. Volume pricing tiers range from 10% to 30% off retail price. Custom packaging and branding options available for bulk orders. Contact sales team for quote and delivery timeline.",
|
|
55
|
-
"category": "sales",
|
|
56
|
-
"tags": ["bulk", "wholesale", "volume"]
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"id": "doc-009",
|
|
60
|
-
"title": "Product Specifications",
|
|
61
|
-
"content": "All products include detailed specifications including dimensions, weight, materials, and technical requirements. Safety certifications and compliance information available on request. Product manuals can be downloaded from the support portal.",
|
|
62
|
-
"category": "product",
|
|
63
|
-
"tags": ["specifications", "technical", "details"]
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"id": "doc-010",
|
|
67
|
-
"title": "Loyalty Program",
|
|
68
|
-
"content": "Join our loyalty program to earn points on every purchase. Points can be redeemed for discounts on future orders. Tier benefits include free shipping, early access to sales, and birthday rewards. No membership fee required.",
|
|
69
|
-
"category": "rewards",
|
|
70
|
-
"tags": ["loyalty", "rewards", "points"]
|
|
71
|
-
}
|
|
72
|
-
]
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "CUST-104233",
|
|
4
|
-
"name": "Sofia Anders",
|
|
5
|
-
"tier": "PLATINUM",
|
|
6
|
-
"accountAgeDays": 2190,
|
|
7
|
-
"complianceFlags": [],
|
|
8
|
-
"benefits": ["BEN-TRAVEL-PLUS", "BEN-PRIORITY-SUPPORT", "BEN-ANALYTICS-LABS"],
|
|
9
|
-
"supervisor": {
|
|
10
|
-
"name": "Dylan Mistry",
|
|
11
|
-
"email": "dylan.mistry@northwind.example"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"id": "CUST-204918",
|
|
16
|
-
"name": "Jacob Martinez",
|
|
17
|
-
"tier": "GOLD",
|
|
18
|
-
"accountAgeDays": 980,
|
|
19
|
-
"complianceFlags": ["ATTESTATION_PENDING"],
|
|
20
|
-
"benefits": ["BEN-PRIORITY-SUPPORT"],
|
|
21
|
-
"supervisor": {
|
|
22
|
-
"name": "Nina Patel",
|
|
23
|
-
"email": "nina.patel@northwind.example"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "CUST-552144",
|
|
28
|
-
"name": "Li Wei",
|
|
29
|
-
"tier": "STANDARD",
|
|
30
|
-
"accountAgeDays": 320,
|
|
31
|
-
"complianceFlags": [],
|
|
32
|
-
"benefits": ["BEN-INSIGHTS-LITE"],
|
|
33
|
-
"supervisor": {
|
|
34
|
-
"name": "Marcus Lee",
|
|
35
|
-
"email": "marcus.lee@northwind.example"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
]
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "POL-TRAVEL-PLUS",
|
|
4
|
-
"benefitCode": "BEN-TRAVEL-PLUS",
|
|
5
|
-
"description": "Provides global lounge access and concierge booking support.",
|
|
6
|
-
"requiredTier": "PLATINUM",
|
|
7
|
-
"minAccountAgeDays": 730,
|
|
8
|
-
"requiresComplianceClearance": false,
|
|
9
|
-
"slaMinutes": 30
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"id": "POL-PRIORITY-SUPPORT",
|
|
13
|
-
"benefitCode": "BEN-PRIORITY-SUPPORT",
|
|
14
|
-
"description": "24/7 engineer escalation with one-hour SLA.",
|
|
15
|
-
"requiredTier": "GOLD",
|
|
16
|
-
"minAccountAgeDays": 180,
|
|
17
|
-
"requiresComplianceClearance": false,
|
|
18
|
-
"slaMinutes": 60
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "POL-ANALYTICS-LABS",
|
|
22
|
-
"benefitCode": "BEN-ANALYTICS-LABS",
|
|
23
|
-
"description": "Early access to analytics beta features.",
|
|
24
|
-
"requiredTier": "PLATINUM",
|
|
25
|
-
"minAccountAgeDays": 1460,
|
|
26
|
-
"requiresComplianceClearance": true,
|
|
27
|
-
"slaMinutes": 120
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"id": "POL-INSIGHTS-LITE",
|
|
31
|
-
"benefitCode": "BEN-INSIGHTS-LITE",
|
|
32
|
-
"description": "Baseline insights and monthly reporting package.",
|
|
33
|
-
"requiredTier": "STANDARD",
|
|
34
|
-
"minAccountAgeDays": 90,
|
|
35
|
-
"requiresComplianceClearance": false,
|
|
36
|
-
"slaMinutes": 240
|
|
37
|
-
}
|
|
38
|
-
]
|