@chanl/eval-cli 0.4.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/dist/agent-loader.d.ts +39 -0
- package/dist/agent-loader.d.ts.map +1 -0
- package/dist/agent-loader.js +166 -0
- package/dist/agent-loader.js.map +1 -0
- package/dist/analytics.d.ts +15 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +94 -0
- package/dist/analytics.js.map +1 -0
- package/dist/assertions.d.ts +73 -0
- package/dist/assertions.d.ts.map +1 -0
- package/dist/assertions.js +282 -0
- package/dist/assertions.js.map +1 -0
- package/dist/baseline.d.ts +100 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +327 -0
- package/dist/baseline.js.map +1 -0
- package/dist/bin/chanl.d.ts +3 -0
- package/dist/bin/chanl.d.ts.map +1 -0
- package/dist/bin/chanl.js +11 -0
- package/dist/bin/chanl.js.map +1 -0
- package/dist/client.d.ts +40 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +99 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/analytics.d.ts +3 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +44 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/compare.d.ts +51 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +429 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +94 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dataset.d.ts +6 -0
- package/dist/commands/dataset.d.ts.map +1 -0
- package/dist/commands/dataset.js +225 -0
- package/dist/commands/dataset.js.map +1 -0
- package/dist/commands/executions.d.ts +3 -0
- package/dist/commands/executions.d.ts.map +1 -0
- package/dist/commands/executions.js +249 -0
- package/dist/commands/executions.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +159 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +29 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +545 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +65 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/personas.d.ts +3 -0
- package/dist/commands/personas.d.ts.map +1 -0
- package/dist/commands/personas.js +269 -0
- package/dist/commands/personas.js.map +1 -0
- package/dist/commands/scenarios.d.ts +16 -0
- package/dist/commands/scenarios.d.ts.map +1 -0
- package/dist/commands/scenarios.js +755 -0
- package/dist/commands/scenarios.js.map +1 -0
- package/dist/commands/scorecards.d.ts +3 -0
- package/dist/commands/scorecards.d.ts.map +1 -0
- package/dist/commands/scorecards.js +220 -0
- package/dist/commands/scorecards.js.map +1 -0
- package/dist/commands/server.d.ts +8 -0
- package/dist/commands/server.d.ts.map +1 -0
- package/dist/commands/server.js +357 -0
- package/dist/commands/server.js.map +1 -0
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +410 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/tool-fixtures.d.ts +3 -0
- package/dist/commands/tool-fixtures.d.ts.map +1 -0
- package/dist/commands/tool-fixtures.js +324 -0
- package/dist/commands/tool-fixtures.js.map +1 -0
- package/dist/config.d.ts +32 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +132 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +146 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +30 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +77 -0
- package/dist/output.js.map +1 -0
- package/dist/update-check.d.ts +6 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +50 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.scaffoldProject = scaffoldProject;
|
|
40
|
+
exports.getTemplateList = getTemplateList;
|
|
41
|
+
exports.registerInitCommand = registerInitCommand;
|
|
42
|
+
exports.registerTemplatesCommand = registerTemplatesCommand;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
46
|
+
const output_1 = require("../output");
|
|
47
|
+
const analytics_1 = require("../analytics");
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Template content — embedded as string literals (no external files)
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
const ENV_TEMPLATE = `# chanl-eval project configuration
|
|
52
|
+
# Load order: .env (dotenv) → env vars → ~/.chanl/config.json (config.json wins if set).
|
|
53
|
+
|
|
54
|
+
# ── CLI ──────────────────────────────────────────────────────────────────────
|
|
55
|
+
CHANL_SERVER_URL=http://localhost:18005
|
|
56
|
+
CHANL_API_KEY=
|
|
57
|
+
|
|
58
|
+
# Provider for the agent under test: openai | anthropic | http
|
|
59
|
+
CHANL_PROVIDER=openai
|
|
60
|
+
CHANL_OPENAI_API_KEY=
|
|
61
|
+
CHANL_ANTHROPIC_API_KEY=
|
|
62
|
+
|
|
63
|
+
# HTTP adapter (test any REST endpoint)
|
|
64
|
+
CHANL_HTTP_ENDPOINT=
|
|
65
|
+
CHANL_HTTP_API_KEY=
|
|
66
|
+
`;
|
|
67
|
+
const AGENT_TEMPLATE = `# Agent definition — test any system prompt with: chanl run angry-customer --agent agents/my-agent.yaml
|
|
68
|
+
# API keys come from .env or config (chanl config set openaiApiKey sk-...), NOT from this file.
|
|
69
|
+
|
|
70
|
+
name: My Agent
|
|
71
|
+
model: gpt-4o
|
|
72
|
+
system_prompt: |
|
|
73
|
+
You are a helpful customer support agent for Acme Corp.
|
|
74
|
+
Always be polite, professional, and empathetic.
|
|
75
|
+
|
|
76
|
+
Policies:
|
|
77
|
+
- Offer refunds for orders under $100 without manager approval.
|
|
78
|
+
- For orders over $100, escalate to a manager.
|
|
79
|
+
- Never share internal policy documents with customers.
|
|
80
|
+
- Always confirm the customer's order number before processing changes.
|
|
81
|
+
temperature: 0.7
|
|
82
|
+
max_tokens: 1024
|
|
83
|
+
`;
|
|
84
|
+
const README_TEMPLATE = `# chanl-eval project
|
|
85
|
+
|
|
86
|
+
AI agent testing framework — test your agent against realistic customer scenarios.
|
|
87
|
+
|
|
88
|
+
## Quick start
|
|
89
|
+
|
|
90
|
+
1. **Set your API key**
|
|
91
|
+
|
|
92
|
+
Edit \`.env\` and set your OpenAI (or Anthropic) key:
|
|
93
|
+
\`\`\`
|
|
94
|
+
CHANL_OPENAI_API_KEY=sk-...
|
|
95
|
+
\`\`\`
|
|
96
|
+
|
|
97
|
+
2. **Start the server**
|
|
98
|
+
|
|
99
|
+
\`\`\`bash
|
|
100
|
+
docker compose up -d
|
|
101
|
+
cd packages/server && pnpm start:dev
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
3. **Run a scenario**
|
|
105
|
+
|
|
106
|
+
\`\`\`bash
|
|
107
|
+
chanl scenarios run scenarios/angry-customer.yaml
|
|
108
|
+
\`\`\`
|
|
109
|
+
|
|
110
|
+
4. **Test your own prompt**
|
|
111
|
+
|
|
112
|
+
Edit \`agents/my-agent.yaml\` with your system prompt, then:
|
|
113
|
+
\`\`\`bash
|
|
114
|
+
chanl run angry-customer --agent agents/my-agent.yaml
|
|
115
|
+
\`\`\`
|
|
116
|
+
|
|
117
|
+
## Project structure
|
|
118
|
+
|
|
119
|
+
\`\`\`
|
|
120
|
+
agents/ # Agent definitions (system prompts, model config)
|
|
121
|
+
scenarios/ # Scenario YAML files (persona + prompt + assertions)
|
|
122
|
+
.env # API keys and config
|
|
123
|
+
\`\`\`
|
|
124
|
+
|
|
125
|
+
## Docs
|
|
126
|
+
|
|
127
|
+
- [chanl-eval on GitHub](https://github.com/chanl-ai/chanl-eval)
|
|
128
|
+
- \`chanl --help\` for all commands
|
|
129
|
+
`;
|
|
130
|
+
const BASE_SCENARIOS = [
|
|
131
|
+
{
|
|
132
|
+
filename: 'angry-customer.yaml',
|
|
133
|
+
content: `name: Angry Customer Refund
|
|
134
|
+
description: Frustrated customer demanding a refund for a broken laptop
|
|
135
|
+
prompt: >-
|
|
136
|
+
I bought a laptop two weeks ago and it's already broken. I want a full refund NOW.
|
|
137
|
+
category: support
|
|
138
|
+
difficulty: hard
|
|
139
|
+
persona:
|
|
140
|
+
name: Frustrated Karen
|
|
141
|
+
emotion: frustrated
|
|
142
|
+
speechStyle: fast
|
|
143
|
+
intentClarity: very clear
|
|
144
|
+
behavior:
|
|
145
|
+
cooperationLevel: hostile
|
|
146
|
+
patience: impatient
|
|
147
|
+
assertions:
|
|
148
|
+
- type: keyword
|
|
149
|
+
must_include: ["refund", "policy"]
|
|
150
|
+
- type: response_time
|
|
151
|
+
max_seconds: 5
|
|
152
|
+
tags:
|
|
153
|
+
- refund
|
|
154
|
+
- support
|
|
155
|
+
- escalation
|
|
156
|
+
`,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
filename: 'billing-dispute.yaml',
|
|
160
|
+
content: `name: Billing Dispute
|
|
161
|
+
description: Customer questioning an unexpected charge on their account
|
|
162
|
+
prompt: >-
|
|
163
|
+
I just noticed a charge of $49.99 on my credit card from your company.
|
|
164
|
+
I never authorized this. What is going on?
|
|
165
|
+
category: support
|
|
166
|
+
difficulty: medium
|
|
167
|
+
persona:
|
|
168
|
+
name: Concerned Account Holder
|
|
169
|
+
emotion: worried
|
|
170
|
+
speechStyle: normal
|
|
171
|
+
intentClarity: clear
|
|
172
|
+
behavior:
|
|
173
|
+
cooperationLevel: neutral
|
|
174
|
+
patience: moderate
|
|
175
|
+
assertions:
|
|
176
|
+
- type: keyword
|
|
177
|
+
must_include: ["credit", "charge"]
|
|
178
|
+
- type: response_time
|
|
179
|
+
max_seconds: 5
|
|
180
|
+
tags:
|
|
181
|
+
- billing
|
|
182
|
+
- support
|
|
183
|
+
- dispute
|
|
184
|
+
`,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
filename: 'product-inquiry.yaml',
|
|
188
|
+
content: `name: Product Inquiry
|
|
189
|
+
description: Friendly customer asking about product features and pricing
|
|
190
|
+
prompt: >-
|
|
191
|
+
Hi! I'm looking at the Pro plan on your website. Can you tell me what's
|
|
192
|
+
included and whether there's a free trial?
|
|
193
|
+
category: sales
|
|
194
|
+
difficulty: easy
|
|
195
|
+
persona:
|
|
196
|
+
name: Curious Prospect
|
|
197
|
+
emotion: neutral
|
|
198
|
+
speechStyle: normal
|
|
199
|
+
intentClarity: clear
|
|
200
|
+
behavior:
|
|
201
|
+
cooperationLevel: cooperative
|
|
202
|
+
patience: patient
|
|
203
|
+
assertions:
|
|
204
|
+
- type: keyword
|
|
205
|
+
must_include: ["plan", "features"]
|
|
206
|
+
- type: response_time
|
|
207
|
+
max_seconds: 5
|
|
208
|
+
tags:
|
|
209
|
+
- sales
|
|
210
|
+
- inquiry
|
|
211
|
+
- pricing
|
|
212
|
+
`,
|
|
213
|
+
},
|
|
214
|
+
];
|
|
215
|
+
// -- customer-support template scenarios ------------------------------------
|
|
216
|
+
const CUSTOMER_SUPPORT_SCENARIOS = [
|
|
217
|
+
...BASE_SCENARIOS,
|
|
218
|
+
{
|
|
219
|
+
filename: 'technical-issue.yaml',
|
|
220
|
+
content: `name: Technical Issue
|
|
221
|
+
description: Customer struggling with a technical problem and getting frustrated
|
|
222
|
+
prompt: >-
|
|
223
|
+
Your app keeps crashing every time I try to upload a file. I've tried
|
|
224
|
+
restarting my phone three times. This is ridiculous.
|
|
225
|
+
category: support
|
|
226
|
+
difficulty: medium
|
|
227
|
+
persona:
|
|
228
|
+
name: Confused Elderly Customer
|
|
229
|
+
emotion: confused
|
|
230
|
+
speechStyle: slow
|
|
231
|
+
intentClarity: vague
|
|
232
|
+
behavior:
|
|
233
|
+
cooperationLevel: cooperative
|
|
234
|
+
patience: patient
|
|
235
|
+
assertions:
|
|
236
|
+
- type: keyword
|
|
237
|
+
must_include: ["troubleshoot", "steps"]
|
|
238
|
+
- type: response_time
|
|
239
|
+
max_seconds: 5
|
|
240
|
+
tags:
|
|
241
|
+
- technical
|
|
242
|
+
- support
|
|
243
|
+
- app-issue
|
|
244
|
+
`,
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
filename: 'escalation-request.yaml',
|
|
248
|
+
content: `name: Escalation Request
|
|
249
|
+
description: Impatient executive demanding to speak with a manager immediately
|
|
250
|
+
prompt: >-
|
|
251
|
+
I've been a premium customer for five years and this is the third time
|
|
252
|
+
I'm calling about the same issue. I want to speak with a manager RIGHT NOW.
|
|
253
|
+
category: support
|
|
254
|
+
difficulty: hard
|
|
255
|
+
persona:
|
|
256
|
+
name: Impatient Executive
|
|
257
|
+
emotion: angry
|
|
258
|
+
speechStyle: fast
|
|
259
|
+
intentClarity: very clear
|
|
260
|
+
behavior:
|
|
261
|
+
cooperationLevel: hostile
|
|
262
|
+
patience: none
|
|
263
|
+
assertions:
|
|
264
|
+
- type: keyword
|
|
265
|
+
must_include: ["manager", "escalate"]
|
|
266
|
+
- type: response_time
|
|
267
|
+
max_seconds: 5
|
|
268
|
+
tags:
|
|
269
|
+
- escalation
|
|
270
|
+
- support
|
|
271
|
+
- vip
|
|
272
|
+
`,
|
|
273
|
+
},
|
|
274
|
+
];
|
|
275
|
+
// -- sales template scenarios -----------------------------------------------
|
|
276
|
+
const SALES_SCENARIOS = [
|
|
277
|
+
{
|
|
278
|
+
filename: 'cold-outreach.yaml',
|
|
279
|
+
content: `name: Cold Outreach Response
|
|
280
|
+
description: Prospect responding to a cold email with mild interest
|
|
281
|
+
prompt: >-
|
|
282
|
+
I got your email about your analytics platform. We're currently using
|
|
283
|
+
a competitor but our contract is up in two months. What makes you different?
|
|
284
|
+
category: sales
|
|
285
|
+
difficulty: medium
|
|
286
|
+
persona:
|
|
287
|
+
name: Skeptical Buyer
|
|
288
|
+
emotion: neutral
|
|
289
|
+
speechStyle: normal
|
|
290
|
+
intentClarity: clear
|
|
291
|
+
behavior:
|
|
292
|
+
cooperationLevel: neutral
|
|
293
|
+
patience: moderate
|
|
294
|
+
assertions:
|
|
295
|
+
- type: keyword
|
|
296
|
+
must_include: ["differentiate", "value"]
|
|
297
|
+
- type: response_time
|
|
298
|
+
max_seconds: 5
|
|
299
|
+
tags:
|
|
300
|
+
- sales
|
|
301
|
+
- outreach
|
|
302
|
+
- comparison
|
|
303
|
+
`,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
filename: 'pricing-negotiation.yaml',
|
|
307
|
+
content: `name: Pricing Negotiation
|
|
308
|
+
description: Budget-conscious buyer pushing back on pricing
|
|
309
|
+
prompt: >-
|
|
310
|
+
We like the product but the pricing is way above our budget. Our team
|
|
311
|
+
is only 5 people. Is there a startup discount or a smaller plan?
|
|
312
|
+
category: sales
|
|
313
|
+
difficulty: medium
|
|
314
|
+
persona:
|
|
315
|
+
name: Budget-Conscious Startup Founder
|
|
316
|
+
emotion: neutral
|
|
317
|
+
speechStyle: normal
|
|
318
|
+
intentClarity: clear
|
|
319
|
+
behavior:
|
|
320
|
+
cooperationLevel: cooperative
|
|
321
|
+
patience: moderate
|
|
322
|
+
assertions:
|
|
323
|
+
- type: keyword
|
|
324
|
+
must_include: ["pricing", "plan"]
|
|
325
|
+
- type: response_time
|
|
326
|
+
max_seconds: 5
|
|
327
|
+
tags:
|
|
328
|
+
- sales
|
|
329
|
+
- pricing
|
|
330
|
+
- negotiation
|
|
331
|
+
`,
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
filename: 'demo-request.yaml',
|
|
335
|
+
content: `name: Demo Request
|
|
336
|
+
description: Enthusiastic prospect requesting a product demo
|
|
337
|
+
prompt: >-
|
|
338
|
+
I saw your product on Product Hunt and I'm really interested.
|
|
339
|
+
Can we schedule a demo this week? We need something like this for our team.
|
|
340
|
+
category: sales
|
|
341
|
+
difficulty: easy
|
|
342
|
+
persona:
|
|
343
|
+
name: Eager Early Adopter
|
|
344
|
+
emotion: excited
|
|
345
|
+
speechStyle: fast
|
|
346
|
+
intentClarity: very clear
|
|
347
|
+
behavior:
|
|
348
|
+
cooperationLevel: cooperative
|
|
349
|
+
patience: patient
|
|
350
|
+
assertions:
|
|
351
|
+
- type: keyword
|
|
352
|
+
must_include: ["demo", "schedule"]
|
|
353
|
+
- type: response_time
|
|
354
|
+
max_seconds: 5
|
|
355
|
+
tags:
|
|
356
|
+
- sales
|
|
357
|
+
- demo
|
|
358
|
+
- inbound
|
|
359
|
+
`,
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
filename: 'competitor-comparison.yaml',
|
|
363
|
+
content: `name: Competitor Comparison
|
|
364
|
+
description: Prospect actively comparing your product against a known competitor
|
|
365
|
+
prompt: >-
|
|
366
|
+
We've been evaluating both your platform and Competitor X. They offer
|
|
367
|
+
a similar feature set at a lower price point. Can you walk me through
|
|
368
|
+
why we should choose you instead?
|
|
369
|
+
category: sales
|
|
370
|
+
difficulty: hard
|
|
371
|
+
persona:
|
|
372
|
+
name: Analytical Decision Maker
|
|
373
|
+
emotion: neutral
|
|
374
|
+
speechStyle: normal
|
|
375
|
+
intentClarity: very clear
|
|
376
|
+
behavior:
|
|
377
|
+
cooperationLevel: neutral
|
|
378
|
+
patience: moderate
|
|
379
|
+
assertions:
|
|
380
|
+
- type: keyword
|
|
381
|
+
must_include: ["advantage", "compare"]
|
|
382
|
+
- type: response_time
|
|
383
|
+
max_seconds: 5
|
|
384
|
+
tags:
|
|
385
|
+
- sales
|
|
386
|
+
- competitor
|
|
387
|
+
- comparison
|
|
388
|
+
`,
|
|
389
|
+
},
|
|
390
|
+
];
|
|
391
|
+
const TEMPLATE_MAP = {
|
|
392
|
+
'customer-support': CUSTOMER_SUPPORT_SCENARIOS,
|
|
393
|
+
'sales': SALES_SCENARIOS,
|
|
394
|
+
};
|
|
395
|
+
const AVAILABLE_TEMPLATES = Object.keys(TEMPLATE_MAP);
|
|
396
|
+
/**
|
|
397
|
+
* Scaffold a chanl-eval project directory.
|
|
398
|
+
*
|
|
399
|
+
* @param targetDir - Absolute path to the directory to scaffold into
|
|
400
|
+
* @param options - Template selection
|
|
401
|
+
* @returns Object describing created files (for testing)
|
|
402
|
+
*/
|
|
403
|
+
function scaffoldProject(targetDir, options = {}) {
|
|
404
|
+
const createdFiles = [];
|
|
405
|
+
const createdDirs = [];
|
|
406
|
+
// Resolve scenario set
|
|
407
|
+
const scenarios = options.template
|
|
408
|
+
? TEMPLATE_MAP[options.template] || BASE_SCENARIOS
|
|
409
|
+
: BASE_SCENARIOS;
|
|
410
|
+
// Create directories
|
|
411
|
+
const agentsDir = path.join(targetDir, 'agents');
|
|
412
|
+
const scenariosDir = path.join(targetDir, 'scenarios');
|
|
413
|
+
for (const dir of [targetDir, agentsDir, scenariosDir]) {
|
|
414
|
+
if (!fs.existsSync(dir)) {
|
|
415
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
416
|
+
createdDirs.push(dir);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
// Write files (skip if they already exist to avoid overwriting user work)
|
|
420
|
+
const filesToWrite = [
|
|
421
|
+
{ rel: '.env', content: ENV_TEMPLATE },
|
|
422
|
+
{ rel: 'agents/my-agent.yaml', content: AGENT_TEMPLATE },
|
|
423
|
+
{ rel: 'README.md', content: README_TEMPLATE },
|
|
424
|
+
...scenarios.map((s) => ({
|
|
425
|
+
rel: `scenarios/${s.filename}`,
|
|
426
|
+
content: s.content,
|
|
427
|
+
})),
|
|
428
|
+
];
|
|
429
|
+
for (const { rel, content } of filesToWrite) {
|
|
430
|
+
const abs = path.join(targetDir, rel);
|
|
431
|
+
if (!fs.existsSync(abs)) {
|
|
432
|
+
fs.writeFileSync(abs, content, 'utf-8');
|
|
433
|
+
createdFiles.push(rel);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return { files: createdFiles, dirs: createdDirs };
|
|
437
|
+
}
|
|
438
|
+
const TEMPLATE_INFO = {
|
|
439
|
+
'customer-support': {
|
|
440
|
+
name: 'customer-support',
|
|
441
|
+
description: 'Support scenarios: refunds, billing, technical issues, escalations',
|
|
442
|
+
scenarioCount: CUSTOMER_SUPPORT_SCENARIOS.length,
|
|
443
|
+
categories: ['support', 'sales'],
|
|
444
|
+
},
|
|
445
|
+
'sales': {
|
|
446
|
+
name: 'sales',
|
|
447
|
+
description: 'Sales scenarios: outreach, pricing objections, demos, competitor comparison',
|
|
448
|
+
scenarioCount: SALES_SCENARIOS.length,
|
|
449
|
+
categories: ['sales'],
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* Get metadata about all available templates.
|
|
454
|
+
*/
|
|
455
|
+
function getTemplateList() {
|
|
456
|
+
return Object.values(TEMPLATE_INFO);
|
|
457
|
+
}
|
|
458
|
+
// ---------------------------------------------------------------------------
|
|
459
|
+
// CLI command registration
|
|
460
|
+
// ---------------------------------------------------------------------------
|
|
461
|
+
function registerInitCommand(program) {
|
|
462
|
+
program
|
|
463
|
+
.command('init [directory]')
|
|
464
|
+
.description('Scaffold a chanl-eval project with agent and scenario files')
|
|
465
|
+
.option('-t, --template <name>', `Industry template: ${AVAILABLE_TEMPLATES.join(', ')}`)
|
|
466
|
+
.action(async (directory, options) => {
|
|
467
|
+
try {
|
|
468
|
+
runInit(directory, options);
|
|
469
|
+
}
|
|
470
|
+
catch (err) {
|
|
471
|
+
(0, output_1.printError)(err.message);
|
|
472
|
+
process.exit(1);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function registerTemplatesCommand(program) {
|
|
477
|
+
const templates = program
|
|
478
|
+
.command('templates')
|
|
479
|
+
.description('Manage scenario template packs');
|
|
480
|
+
templates
|
|
481
|
+
.command('list')
|
|
482
|
+
.description('List available scenario template packs')
|
|
483
|
+
.action(() => {
|
|
484
|
+
const list = getTemplateList();
|
|
485
|
+
console.log('');
|
|
486
|
+
console.log(chalk_1.default.bold('Available template packs:'));
|
|
487
|
+
console.log('');
|
|
488
|
+
for (const tpl of list) {
|
|
489
|
+
console.log(` ${chalk_1.default.green(tpl.name)}` +
|
|
490
|
+
chalk_1.default.dim(` (${tpl.scenarioCount} scenarios)`));
|
|
491
|
+
console.log(` ${chalk_1.default.dim(tpl.description)}`);
|
|
492
|
+
console.log('');
|
|
493
|
+
}
|
|
494
|
+
console.log(chalk_1.default.dim(' Usage: chanl init --template <name>'));
|
|
495
|
+
console.log(chalk_1.default.dim(' Example: chanl init --template customer-support'));
|
|
496
|
+
console.log('');
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
function runInit(directory, options) {
|
|
500
|
+
// Validate template name
|
|
501
|
+
if (options.template && !TEMPLATE_MAP[options.template]) {
|
|
502
|
+
(0, output_1.printError)(`Unknown template "${options.template}". Available: ${AVAILABLE_TEMPLATES.join(', ')}`);
|
|
503
|
+
process.exit(1);
|
|
504
|
+
}
|
|
505
|
+
// Resolve target directory
|
|
506
|
+
const targetDir = directory
|
|
507
|
+
? path.resolve(process.cwd(), directory)
|
|
508
|
+
: process.cwd();
|
|
509
|
+
const { files } = scaffoldProject(targetDir, options);
|
|
510
|
+
if (files.length === 0) {
|
|
511
|
+
console.log(chalk_1.default.yellow('Project already initialized') +
|
|
512
|
+
' — all files already exist.');
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
// Print success
|
|
516
|
+
console.log('');
|
|
517
|
+
console.log(chalk_1.default.green('\u2713') + chalk_1.default.bold(' Created chanl-eval project'));
|
|
518
|
+
console.log('');
|
|
519
|
+
// List created files
|
|
520
|
+
const displayDir = directory || '.';
|
|
521
|
+
for (const f of files) {
|
|
522
|
+
console.log(chalk_1.default.dim(` ${displayDir}/${f}`));
|
|
523
|
+
}
|
|
524
|
+
// Next steps
|
|
525
|
+
console.log('');
|
|
526
|
+
console.log(chalk_1.default.bold(' Next steps:'));
|
|
527
|
+
console.log(` 1. Set your API key: Edit .env \u2192 set CHANL_OPENAI_API_KEY=sk-...`);
|
|
528
|
+
console.log(` 2. Start the server: docker compose up -d && cd packages/server && pnpm start:dev`);
|
|
529
|
+
console.log(` 3. Run a scenario: chanl scenarios run scenarios/angry-customer.yaml`);
|
|
530
|
+
console.log('');
|
|
531
|
+
console.log(' Or test a prompt directly:');
|
|
532
|
+
console.log(` 4. Edit agents/my-agent.yaml with your system prompt`);
|
|
533
|
+
console.log(` 5. chanl run angry-customer --agent agents/my-agent.yaml`);
|
|
534
|
+
console.log('');
|
|
535
|
+
console.log(chalk_1.default.dim(' \uD83D\uDCDA Docs: https://github.com/chanl-ai/chanl-eval'));
|
|
536
|
+
// Track analytics
|
|
537
|
+
(0, analytics_1.track)('cli_init', {
|
|
538
|
+
os: process.platform,
|
|
539
|
+
node_version: process.version,
|
|
540
|
+
template: options.template || 'none',
|
|
541
|
+
files_created: files.length,
|
|
542
|
+
directory: directory ? 'custom' : 'cwd',
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyD3D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerLoginCommand = registerLoginCommand;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const config_1 = require("../config");
|
|
11
|
+
const client_1 = require("../client");
|
|
12
|
+
const output_1 = require("../output");
|
|
13
|
+
function registerLoginCommand(program) {
|
|
14
|
+
program
|
|
15
|
+
.command('login')
|
|
16
|
+
.description('Authenticate with the chanl-eval server')
|
|
17
|
+
.option('-k, --key <apiKey>', 'API key to store')
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
try {
|
|
20
|
+
let apiKey = options.key;
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
const answers = await inquirer_1.default.prompt([
|
|
23
|
+
{
|
|
24
|
+
type: 'password',
|
|
25
|
+
name: 'apiKey',
|
|
26
|
+
message: 'Enter your API key:',
|
|
27
|
+
mask: '*',
|
|
28
|
+
validate: (input) => {
|
|
29
|
+
if (!input || input.trim().length === 0) {
|
|
30
|
+
return 'API key is required';
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
]);
|
|
36
|
+
apiKey = answers.apiKey;
|
|
37
|
+
}
|
|
38
|
+
if (!apiKey) {
|
|
39
|
+
(0, output_1.printError)('No API key provided');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// Store the key
|
|
43
|
+
(0, config_1.setConfig)('apiKey', apiKey);
|
|
44
|
+
// Verify the key works by hitting the health endpoint (root path, no /api/v1 prefix)
|
|
45
|
+
const server = (0, config_1.getConfig)('server');
|
|
46
|
+
try {
|
|
47
|
+
const res = await axios_1.default.get(`${server}/health`, { timeout: 3000 });
|
|
48
|
+
const health = res.data;
|
|
49
|
+
(0, output_1.printSuccess)(`Authenticated with ${server} (server v${health.version || 'unknown'})`);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
// Key is stored but server might not be available
|
|
53
|
+
console.log(chalk_1.default.yellow('Warning:') +
|
|
54
|
+
` API key saved, but could not verify with server: ${(0, client_1.formatError)(err)}`);
|
|
55
|
+
console.log(`Server: ${server}`);
|
|
56
|
+
console.log('The key is stored and will be used for future requests.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
(0, output_1.printError)((0, client_1.formatError)(err));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";;;;;AAQA,oDAyDC;AAhED,wDAAgC;AAChC,kDAA0B;AAC1B,kDAA0B;AAC1B,sCAAiD;AACjD,sCAAwC;AACxC,sCAAqD;AAErD,SAAgB,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;SAChD,MAAM,CAAC,KAAK,EAAE,OAAyB,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;YAEzB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,OAAO,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;oBACpC;wBACE,IAAI,EAAE,UAAU;wBAChB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,qBAAqB;wBAC9B,IAAI,EAAE,GAAG;wBACT,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;4BAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gCACxC,OAAO,qBAAqB,CAAC;4BAC/B,CAAC;4BACD,OAAO,IAAI,CAAC;wBACd,CAAC;qBACF;iBACF,CAAC,CAAC;gBACH,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC1B,CAAC;YAED,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAA,mBAAU,EAAC,qBAAqB,CAAC,CAAC;gBAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,gBAAgB;YAChB,IAAA,kBAAS,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAE5B,qFAAqF;YACrF,MAAM,MAAM,GAAG,IAAA,kBAAS,EAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,MAAM,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC;gBACxB,IAAA,qBAAY,EACV,sBAAsB,MAAM,aAAa,MAAM,CAAC,OAAO,IAAI,SAAS,GAAG,CACxE,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,kDAAkD;gBAClD,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,MAAM,CAAC,UAAU,CAAC;oBACtB,qDAAqD,IAAA,oBAAW,EAAC,GAAG,CAAC,EAAE,CAC1E,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,mBAAU,EAAC,IAAA,oBAAW,EAAC,GAAG,CAAC,CAAC,CAAC;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personas.d.ts","sourceRoot":"","sources":["../../src/commands/personas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyP9D"}
|