eqho-eval 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.
Files changed (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +552 -0
  3. package/dist/cli/auth-store.d.ts +5 -0
  4. package/dist/cli/auth-store.d.ts.map +1 -0
  5. package/dist/cli/auth-store.js +39 -0
  6. package/dist/cli/auth-store.js.map +1 -0
  7. package/dist/cli/banner.d.ts +3 -0
  8. package/dist/cli/banner.d.ts.map +1 -0
  9. package/dist/cli/banner.js +38 -0
  10. package/dist/cli/banner.js.map +1 -0
  11. package/dist/cli/commands/action-eval.d.ts +3 -0
  12. package/dist/cli/commands/action-eval.d.ts.map +1 -0
  13. package/dist/cli/commands/action-eval.js +133 -0
  14. package/dist/cli/commands/action-eval.js.map +1 -0
  15. package/dist/cli/commands/auth.d.ts +3 -0
  16. package/dist/cli/commands/auth.d.ts.map +1 -0
  17. package/dist/cli/commands/auth.js +156 -0
  18. package/dist/cli/commands/auth.js.map +1 -0
  19. package/dist/cli/commands/cache.d.ts +3 -0
  20. package/dist/cli/commands/cache.d.ts.map +1 -0
  21. package/dist/cli/commands/cache.js +43 -0
  22. package/dist/cli/commands/cache.js.map +1 -0
  23. package/dist/cli/commands/ci.d.ts +3 -0
  24. package/dist/cli/commands/ci.d.ts.map +1 -0
  25. package/dist/cli/commands/ci.js +124 -0
  26. package/dist/cli/commands/ci.js.map +1 -0
  27. package/dist/cli/commands/conversations.d.ts +3 -0
  28. package/dist/cli/commands/conversations.d.ts.map +1 -0
  29. package/dist/cli/commands/conversations.js +89 -0
  30. package/dist/cli/commands/conversations.js.map +1 -0
  31. package/dist/cli/commands/diff.d.ts +3 -0
  32. package/dist/cli/commands/diff.d.ts.map +1 -0
  33. package/dist/cli/commands/diff.js +122 -0
  34. package/dist/cli/commands/diff.js.map +1 -0
  35. package/dist/cli/commands/doctor.d.ts +11 -0
  36. package/dist/cli/commands/doctor.d.ts.map +1 -0
  37. package/dist/cli/commands/doctor.js +308 -0
  38. package/dist/cli/commands/doctor.js.map +1 -0
  39. package/dist/cli/commands/eval.d.ts +3 -0
  40. package/dist/cli/commands/eval.d.ts.map +1 -0
  41. package/dist/cli/commands/eval.js +101 -0
  42. package/dist/cli/commands/eval.js.map +1 -0
  43. package/dist/cli/commands/init.d.ts +3 -0
  44. package/dist/cli/commands/init.d.ts.map +1 -0
  45. package/dist/cli/commands/init.js +182 -0
  46. package/dist/cli/commands/init.js.map +1 -0
  47. package/dist/cli/commands/list.d.ts +3 -0
  48. package/dist/cli/commands/list.d.ts.map +1 -0
  49. package/dist/cli/commands/list.js +80 -0
  50. package/dist/cli/commands/list.js.map +1 -0
  51. package/dist/cli/commands/mentions.d.ts +3 -0
  52. package/dist/cli/commands/mentions.d.ts.map +1 -0
  53. package/dist/cli/commands/mentions.js +125 -0
  54. package/dist/cli/commands/mentions.js.map +1 -0
  55. package/dist/cli/commands/org.d.ts +3 -0
  56. package/dist/cli/commands/org.d.ts.map +1 -0
  57. package/dist/cli/commands/org.js +196 -0
  58. package/dist/cli/commands/org.js.map +1 -0
  59. package/dist/cli/commands/postcall-eval.d.ts +3 -0
  60. package/dist/cli/commands/postcall-eval.d.ts.map +1 -0
  61. package/dist/cli/commands/postcall-eval.js +188 -0
  62. package/dist/cli/commands/postcall-eval.js.map +1 -0
  63. package/dist/cli/commands/render.d.ts +3 -0
  64. package/dist/cli/commands/render.d.ts.map +1 -0
  65. package/dist/cli/commands/render.js +223 -0
  66. package/dist/cli/commands/render.js.map +1 -0
  67. package/dist/cli/commands/results.d.ts +3 -0
  68. package/dist/cli/commands/results.d.ts.map +1 -0
  69. package/dist/cli/commands/results.js +128 -0
  70. package/dist/cli/commands/results.js.map +1 -0
  71. package/dist/cli/commands/scenarios.d.ts +3 -0
  72. package/dist/cli/commands/scenarios.d.ts.map +1 -0
  73. package/dist/cli/commands/scenarios.js +57 -0
  74. package/dist/cli/commands/scenarios.js.map +1 -0
  75. package/dist/cli/commands/start.d.ts +3 -0
  76. package/dist/cli/commands/start.d.ts.map +1 -0
  77. package/dist/cli/commands/start.js +260 -0
  78. package/dist/cli/commands/start.js.map +1 -0
  79. package/dist/cli/commands/status.d.ts +3 -0
  80. package/dist/cli/commands/status.d.ts.map +1 -0
  81. package/dist/cli/commands/status.js +133 -0
  82. package/dist/cli/commands/status.js.map +1 -0
  83. package/dist/cli/commands/sync.d.ts +3 -0
  84. package/dist/cli/commands/sync.d.ts.map +1 -0
  85. package/dist/cli/commands/sync.js +80 -0
  86. package/dist/cli/commands/sync.js.map +1 -0
  87. package/dist/cli/commands/view.d.ts +3 -0
  88. package/dist/cli/commands/view.d.ts.map +1 -0
  89. package/dist/cli/commands/view.js +29 -0
  90. package/dist/cli/commands/view.js.map +1 -0
  91. package/dist/cli/error-handler.d.ts +8 -0
  92. package/dist/cli/error-handler.d.ts.map +1 -0
  93. package/dist/cli/error-handler.js +133 -0
  94. package/dist/cli/error-handler.js.map +1 -0
  95. package/dist/cli/gateway.d.ts +14 -0
  96. package/dist/cli/gateway.d.ts.map +1 -0
  97. package/dist/cli/gateway.js +222 -0
  98. package/dist/cli/gateway.js.map +1 -0
  99. package/dist/cli/index.d.ts +3 -0
  100. package/dist/cli/index.d.ts.map +1 -0
  101. package/dist/cli/index.js +194 -0
  102. package/dist/cli/index.js.map +1 -0
  103. package/dist/core/action-eval-builder.d.ts +20 -0
  104. package/dist/core/action-eval-builder.d.ts.map +1 -0
  105. package/dist/core/action-eval-builder.js +276 -0
  106. package/dist/core/action-eval-builder.js.map +1 -0
  107. package/dist/core/agent-fetcher.d.ts +35 -0
  108. package/dist/core/agent-fetcher.d.ts.map +1 -0
  109. package/dist/core/agent-fetcher.js +81 -0
  110. package/dist/core/agent-fetcher.js.map +1 -0
  111. package/dist/core/api-cache.d.ts +11 -0
  112. package/dist/core/api-cache.d.ts.map +1 -0
  113. package/dist/core/api-cache.js +89 -0
  114. package/dist/core/api-cache.js.map +1 -0
  115. package/dist/core/config-generator.d.ts +26 -0
  116. package/dist/core/config-generator.d.ts.map +1 -0
  117. package/dist/core/config-generator.js +457 -0
  118. package/dist/core/config-generator.js.map +1 -0
  119. package/dist/core/conversation-loader.d.ts +21 -0
  120. package/dist/core/conversation-loader.d.ts.map +1 -0
  121. package/dist/core/conversation-loader.js +74 -0
  122. package/dist/core/conversation-loader.js.map +1 -0
  123. package/dist/core/dataset-loader.d.ts +26 -0
  124. package/dist/core/dataset-loader.d.ts.map +1 -0
  125. package/dist/core/dataset-loader.js +121 -0
  126. package/dist/core/dataset-loader.js.map +1 -0
  127. package/dist/core/disposition-builder.d.ts +38 -0
  128. package/dist/core/disposition-builder.d.ts.map +1 -0
  129. package/dist/core/disposition-builder.js +270 -0
  130. package/dist/core/disposition-builder.js.map +1 -0
  131. package/dist/core/eqho-client.d.ts +45 -0
  132. package/dist/core/eqho-client.d.ts.map +1 -0
  133. package/dist/core/eqho-client.js +154 -0
  134. package/dist/core/eqho-client.js.map +1 -0
  135. package/dist/core/greeting-builder.d.ts +18 -0
  136. package/dist/core/greeting-builder.d.ts.map +1 -0
  137. package/dist/core/greeting-builder.js +83 -0
  138. package/dist/core/greeting-builder.js.map +1 -0
  139. package/dist/core/postcall-simulator.d.ts +20 -0
  140. package/dist/core/postcall-simulator.d.ts.map +1 -0
  141. package/dist/core/postcall-simulator.js +212 -0
  142. package/dist/core/postcall-simulator.js.map +1 -0
  143. package/dist/core/prompt-assembler.d.ts +25 -0
  144. package/dist/core/prompt-assembler.d.ts.map +1 -0
  145. package/dist/core/prompt-assembler.js +185 -0
  146. package/dist/core/prompt-assembler.js.map +1 -0
  147. package/dist/core/promptfoo-runner.d.ts +13 -0
  148. package/dist/core/promptfoo-runner.d.ts.map +1 -0
  149. package/dist/core/promptfoo-runner.js +49 -0
  150. package/dist/core/promptfoo-runner.js.map +1 -0
  151. package/dist/core/provider-mapper.d.ts +39 -0
  152. package/dist/core/provider-mapper.d.ts.map +1 -0
  153. package/dist/core/provider-mapper.js +120 -0
  154. package/dist/core/provider-mapper.js.map +1 -0
  155. package/dist/core/template-engine.d.ts +10 -0
  156. package/dist/core/template-engine.d.ts.map +1 -0
  157. package/dist/core/template-engine.js +78 -0
  158. package/dist/core/template-engine.js.map +1 -0
  159. package/dist/core/tools-builder.d.ts +14 -0
  160. package/dist/core/tools-builder.d.ts.map +1 -0
  161. package/dist/core/tools-builder.js +208 -0
  162. package/dist/core/tools-builder.js.map +1 -0
  163. package/dist/index.d.ts +18 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +16 -0
  166. package/dist/index.js.map +1 -0
  167. package/dist/types/config.d.ts +100 -0
  168. package/dist/types/config.d.ts.map +1 -0
  169. package/dist/types/config.js +2 -0
  170. package/dist/types/config.js.map +1 -0
  171. package/dist/types/eqho.d.ts +221 -0
  172. package/dist/types/eqho.d.ts.map +1 -0
  173. package/dist/types/eqho.js +2 -0
  174. package/dist/types/eqho.js.map +1 -0
  175. package/dist/types/helpers.d.ts +9 -0
  176. package/dist/types/helpers.d.ts.map +1 -0
  177. package/dist/types/helpers.js +8 -0
  178. package/dist/types/helpers.js.map +1 -0
  179. package/package.json +77 -0
@@ -0,0 +1,57 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import yaml from "js-yaml";
6
+ import { loadDataset, datasetToTests } from "../../core/dataset-loader.js";
7
+ export const scenariosCommand = new Command("scenarios")
8
+ .description("Generate promptfoo test cases from a CSV/JSON dataset")
9
+ .argument("<file>", "Path to CSV, TSV, JSON, or JSONL dataset file")
10
+ .option("-o, --output <file>", "Output file (default: stdout). Writes YAML.")
11
+ .option("--rubric <text>", "Default llm-rubric assertion applied to each test case")
12
+ .option("--merge <config>", "Merge generated tests into an existing promptfooconfig.yaml")
13
+ .action(async (file, opts) => {
14
+ let rows;
15
+ try {
16
+ rows = loadDataset(file);
17
+ }
18
+ catch (err) {
19
+ console.log(chalk.red(String(err)));
20
+ process.exit(1);
21
+ }
22
+ if (!rows.length) {
23
+ console.log(chalk.yellow("Dataset is empty."));
24
+ process.exit(0);
25
+ }
26
+ console.log(chalk.dim(`Loaded ${rows.length} scenarios from ${path.basename(file)}`));
27
+ const baseAssertions = opts.rubric
28
+ ? [{ type: "llm-rubric", value: opts.rubric }]
29
+ : undefined;
30
+ const tests = datasetToTests(rows, baseAssertions);
31
+ if (opts.merge) {
32
+ const configPath = path.resolve(opts.merge);
33
+ if (!fs.existsSync(configPath)) {
34
+ console.log(chalk.red(`Config file not found: ${configPath}`));
35
+ process.exit(1);
36
+ }
37
+ const existing = yaml.load(fs.readFileSync(configPath, "utf-8"));
38
+ const existingTests = existing.tests ?? [];
39
+ existing.tests = [...existingTests, ...tests];
40
+ fs.writeFileSync(configPath, yaml.dump(existing, {
41
+ lineWidth: 120,
42
+ noRefs: true,
43
+ quotingType: '"',
44
+ }));
45
+ console.log(chalk.green(`Merged ${tests.length} test cases into ${configPath} (total: ${existing.tests.length})`));
46
+ return;
47
+ }
48
+ const output = yaml.dump({ tests }, { lineWidth: 120, noRefs: true, quotingType: '"' });
49
+ if (opts.output) {
50
+ fs.writeFileSync(opts.output, output);
51
+ console.log(chalk.green(`Wrote ${tests.length} test cases to ${opts.output}`));
52
+ }
53
+ else {
54
+ console.log(output);
55
+ }
56
+ });
57
+ //# sourceMappingURL=scenarios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../../src/cli/commands/scenarios.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const startCommand: Command;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,eAAO,MAAM,YAAY,SA2QrB,CAAC"}
@@ -0,0 +1,260 @@
1
+ import { Command } from "commander";
2
+ import { input, select, confirm } from "@inquirer/prompts";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { EqhoClient } from "../../core/eqho-client.js";
8
+ import { loadAuth, saveAuth } from "../auth-store.js";
9
+ import { fetchCampaignAgents, resolveSystemPromptSections } from "../../core/agent-fetcher.js";
10
+ import { assemblePrompt } from "../../core/prompt-assembler.js";
11
+ import { generateConfig } from "../../core/config-generator.js";
12
+ import { buildProviderSet, getProxyConfig } from "../../core/provider-mapper.js";
13
+ import { extractGreetings } from "../../core/greeting-builder.js";
14
+ import { isPromptfooInstalled, runPromptfoo } from "../../core/promptfoo-runner.js";
15
+ import { getId } from "../../types/helpers.js";
16
+ import { renderGateway } from "../gateway.js";
17
+ export const startCommand = new Command("start")
18
+ .description("Interactive setup — go from zero to first eval in minutes")
19
+ .option("--yes", "Non-interactive mode (use env vars and defaults)")
20
+ .option("-c, --campaign <id>", "Campaign ID (skip selection)")
21
+ .option("-o, --output <dir>", "Output directory")
22
+ .action(async (opts) => {
23
+ const nonInteractive = opts.yes;
24
+ process.stderr.write(renderGateway("0.5.0") + "\n");
25
+ if (!isPromptfooInstalled()) {
26
+ console.log(chalk.yellow(" ⚠ promptfoo is not installed."));
27
+ console.log(chalk.dim(" It's required to run evals. Install it now:"));
28
+ console.log(chalk.cyan(" npm install promptfoo\n"));
29
+ if (nonInteractive) {
30
+ console.log(chalk.red(" Cannot continue without promptfoo in --yes mode."));
31
+ process.exit(1);
32
+ }
33
+ const shouldContinue = await confirm({
34
+ message: "Continue setup without promptfoo? (you can install it later)",
35
+ default: true,
36
+ });
37
+ if (!shouldContinue)
38
+ process.exit(0);
39
+ console.log();
40
+ }
41
+ // ── Step 1: Authentication ──────────────────────────────────────────
42
+ console.log(chalk.bold(" Step 1/4: Authentication"));
43
+ let auth = loadAuth();
44
+ if (auth) {
45
+ const authLabel = auth.authMode === "bearer"
46
+ ? `SSO (${auth.email ?? "bearer"})`
47
+ : `${(auth.apiKey ?? "").slice(0, 8)}...`;
48
+ console.log(chalk.green(` ✓ Already authenticated (${authLabel})`));
49
+ }
50
+ else {
51
+ const envKey = process.env.EQHO_API_KEY;
52
+ let apiKey;
53
+ if (envKey) {
54
+ apiKey = envKey;
55
+ console.log(chalk.dim(" Using EQHO_API_KEY from environment"));
56
+ }
57
+ else if (nonInteractive) {
58
+ console.log(chalk.red(" ✗ No API key found. Set EQHO_API_KEY or run without --yes"));
59
+ process.exit(1);
60
+ }
61
+ else {
62
+ apiKey = await input({
63
+ message: "Eqho API key:",
64
+ validate: (v) => (v.trim().length > 0 ? true : "Required"),
65
+ });
66
+ }
67
+ const spinner = ora({ text: "Validating connection...", stream: process.stderr }).start();
68
+ const client = new EqhoClient({ apiKey: apiKey.trim(), baseUrl: "https://api.eqho.ai" });
69
+ const valid = await client.validateConnection();
70
+ if (!valid) {
71
+ spinner.fail("Could not connect to Eqho API. Check your API key.");
72
+ process.exit(1);
73
+ }
74
+ spinner.succeed("Connected to Eqho API");
75
+ auth = { authMode: "api_key", apiKey: apiKey.trim(), apiBaseUrl: "https://api.eqho.ai" };
76
+ saveAuth(auth);
77
+ }
78
+ console.log();
79
+ // ── Step 2: Select campaign ─────────────────────────────────────────
80
+ console.log(chalk.bold(" Step 2/4: Select campaign"));
81
+ const client = new EqhoClient(auth);
82
+ let campaignId = opts.campaign;
83
+ if (!campaignId) {
84
+ const spinner = ora({ text: "Fetching campaigns...", stream: process.stderr }).start();
85
+ const { campaigns } = await client.listCampaigns(100);
86
+ spinner.stop();
87
+ if (!campaigns.length) {
88
+ console.log(chalk.red(" No campaigns found in this org."));
89
+ process.exit(1);
90
+ }
91
+ if (nonInteractive) {
92
+ const active = campaigns.filter((c) => c.status === "ACTIVE");
93
+ if (active.length === 0) {
94
+ console.log(chalk.red(" No active campaigns. Specify --campaign <id>"));
95
+ process.exit(1);
96
+ }
97
+ campaignId = getId(active[0]);
98
+ console.log(chalk.dim(` Auto-selected: ${active[0].name}`));
99
+ }
100
+ else {
101
+ campaignId = await select({
102
+ message: "Select a campaign:",
103
+ choices: campaigns.map((c) => ({
104
+ name: `${c.name} ${chalk.dim(`(${c.status})`)}`,
105
+ value: getId(c),
106
+ })),
107
+ });
108
+ }
109
+ }
110
+ const campaign = await client.getCampaign(campaignId);
111
+ console.log(chalk.green(` ✓ Campaign: ${campaign.name}`));
112
+ console.log();
113
+ const proxy = getProxyConfig(loadAuth());
114
+ // ── Step 3: OpenAI key ──────────────────────────────────────────────
115
+ console.log(chalk.bold(" Step 3/4: OpenAI API key"));
116
+ const envOpenAI = process.env.OPENAI_API_KEY;
117
+ let openaiKey;
118
+ if (proxy) {
119
+ console.log(chalk.green(" ✓ Using backend proxy (no local key needed)"));
120
+ openaiKey = proxy.backendToken;
121
+ }
122
+ else if (envOpenAI) {
123
+ console.log(chalk.green(" ✓ Found OPENAI_API_KEY in environment"));
124
+ openaiKey = envOpenAI;
125
+ }
126
+ else if (nonInteractive) {
127
+ console.log(chalk.yellow(" ⚠ No OPENAI_API_KEY found. You'll need to set it in .env"));
128
+ }
129
+ else {
130
+ openaiKey = await input({
131
+ message: "OpenAI API key (or press Enter to skip):",
132
+ });
133
+ if (!openaiKey?.trim()) {
134
+ openaiKey = undefined;
135
+ console.log(chalk.yellow(" ⚠ Skipped. Add OPENAI_API_KEY to .env before running evals."));
136
+ }
137
+ else {
138
+ console.log(chalk.green(" ✓ OpenAI key saved"));
139
+ }
140
+ }
141
+ console.log();
142
+ // ── Step 4: Generate project ────────────────────────────────────────
143
+ console.log(chalk.bold(" Step 4/4: Generating eval project"));
144
+ const spinner = ora({ text: "Fetching agent details...", stream: process.stderr }).start();
145
+ const { agents, errors } = await fetchCampaignAgents(client, campaign, {
146
+ onProgress: (msg) => { spinner.text = msg; },
147
+ });
148
+ if (errors.length) {
149
+ for (const e of errors)
150
+ console.log(chalk.yellow(` Warning: ${e}`));
151
+ }
152
+ if (!agents.length) {
153
+ spinner.fail("No agents found in this campaign.");
154
+ process.exit(1);
155
+ }
156
+ const assembledPrompts = [];
157
+ for (const { agent } of agents) {
158
+ spinner.text = `Assembling prompt for ${agent.name}...`;
159
+ const { sections, seeder } = resolveSystemPromptSections(agent, campaign, "inbound");
160
+ const assembled = assemblePrompt({
161
+ agent,
162
+ campaign,
163
+ roles: agent.roles,
164
+ actions: agent.actions,
165
+ scripts: agent.scripts,
166
+ systemPromptSections: sections,
167
+ conversationSeeder: seeder,
168
+ });
169
+ assembledPrompts.push(assembled);
170
+ }
171
+ spinner.text = "Generating promptfoo config...";
172
+ const firstAgent = agents[0].agent;
173
+ const providers = buildProviderSet(firstAgent, undefined, proxy).map((p) => ({
174
+ id: p.id,
175
+ label: p.label,
176
+ config: p.config,
177
+ }));
178
+ const greetingConfig = extractGreetings(firstAgent);
179
+ const files = generateConfig({
180
+ prompts: assembledPrompts,
181
+ campaignId,
182
+ campaignName: campaign.name,
183
+ providers: providers.length > 0 ? providers : undefined,
184
+ proxy,
185
+ greetingConfig,
186
+ agentName: firstAgent?.name,
187
+ });
188
+ const slug = campaign.name
189
+ .toLowerCase()
190
+ .replace(/[^a-z0-9]+/g, "-")
191
+ .replace(/^-|-$/g, "")
192
+ .slice(0, 40);
193
+ const outDir = path.resolve(opts.output || `${slug}-eval`);
194
+ for (const [filePath, content] of Object.entries(files)) {
195
+ const fullPath = path.join(outDir, filePath);
196
+ const dir = path.dirname(fullPath);
197
+ if (!fs.existsSync(dir))
198
+ fs.mkdirSync(dir, { recursive: true });
199
+ fs.writeFileSync(fullPath, content, "utf-8");
200
+ }
201
+ if (openaiKey) {
202
+ const envPath = path.join(outDir, ".env");
203
+ const envContent = fs.existsSync(envPath) ? fs.readFileSync(envPath, "utf-8") : "";
204
+ if (!envContent.includes("OPENAI_API_KEY=")) {
205
+ fs.writeFileSync(envPath, `${envContent ? envContent + "\n" : ""}OPENAI_API_KEY=${openaiKey}\n`);
206
+ }
207
+ }
208
+ const promptChars = assembledPrompts.reduce((sum, p) => sum + p.systemPrompt.length, 0);
209
+ const toolCount = assembledPrompts.reduce((sum, p) => sum + p.tools.length, 0);
210
+ spinner.succeed("Project generated!");
211
+ console.log();
212
+ console.log(chalk.dim(` Prompt: ${promptChars.toLocaleString()} chars`));
213
+ console.log(chalk.dim(` Tools: ${toolCount} definitions`));
214
+ console.log(chalk.dim(` Agents: ${agents.length}`));
215
+ console.log(chalk.dim(` Directory: ${outDir}`));
216
+ console.log();
217
+ // ── Offer to run first eval ─────────────────────────────────────────
218
+ if (!isPromptfooInstalled()) {
219
+ console.log(chalk.yellow(" promptfoo is not installed."));
220
+ console.log(chalk.dim(" Install it to run evals:"));
221
+ console.log(chalk.cyan(" npm install promptfoo"));
222
+ console.log();
223
+ console.log(chalk.bold(" Then run:"));
224
+ console.log(chalk.cyan(` cd ${path.relative(process.cwd(), outDir) || "."}`));
225
+ console.log(chalk.cyan(" eqho-eval eval"));
226
+ console.log();
227
+ return;
228
+ }
229
+ let shouldRun = false;
230
+ if (nonInteractive) {
231
+ shouldRun = false;
232
+ }
233
+ else {
234
+ shouldRun = await confirm({
235
+ message: "Run your first eval now?",
236
+ default: true,
237
+ });
238
+ }
239
+ if (shouldRun) {
240
+ console.log();
241
+ const { exitCode } = runPromptfoo(["eval"], { cwd: outDir });
242
+ if (exitCode === 0) {
243
+ console.log();
244
+ console.log(chalk.green(" ✓ Eval complete!"));
245
+ console.log(chalk.dim(" View results:"));
246
+ console.log(chalk.cyan(` cd ${path.relative(process.cwd(), outDir) || "."}`));
247
+ console.log(chalk.cyan(" eqho-eval view"));
248
+ }
249
+ }
250
+ else {
251
+ console.log();
252
+ console.log(chalk.bold(" Next steps:"));
253
+ console.log(chalk.cyan(` cd ${path.relative(process.cwd(), outDir) || "."}`));
254
+ console.log(chalk.dim(" 1. Edit tests in promptfooconfig.yaml"));
255
+ console.log(chalk.cyan(" 2. eqho-eval eval"));
256
+ console.log(chalk.cyan(" 3. eqho-eval view"));
257
+ console.log();
258
+ }
259
+ });
260
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const statusCommand: Command;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkGpC,eAAO,MAAM,aAAa,SA6EtB,CAAC"}
@@ -0,0 +1,133 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { loadAuth } from "../auth-store.js";
6
+ function getProjectStatus(cwd) {
7
+ const configPath = path.join(cwd, "eqho.config.json");
8
+ const pfooConfigPath = path.join(cwd, "promptfooconfig.yaml");
9
+ const status = {
10
+ hasProject: false,
11
+ promptFiles: [],
12
+ toolFiles: [],
13
+ testFiles: [],
14
+ hasEnv: false,
15
+ hasOpenAIKey: !!process.env.OPENAI_API_KEY,
16
+ };
17
+ if (fs.existsSync(configPath)) {
18
+ status.hasProject = true;
19
+ status.configPath = configPath;
20
+ try {
21
+ const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
22
+ status.campaignId = config.campaignId;
23
+ status.agentIds = config.agentIds;
24
+ status.lastSynced = config.lastSynced;
25
+ }
26
+ catch { /* ignore */ }
27
+ }
28
+ if (fs.existsSync(pfooConfigPath)) {
29
+ status.hasProject = true;
30
+ status.promptfooConfig = pfooConfigPath;
31
+ }
32
+ const promptsDir = path.join(cwd, "prompts");
33
+ if (fs.existsSync(promptsDir)) {
34
+ try {
35
+ status.promptFiles = fs.readdirSync(promptsDir).filter((f) => f.endsWith(".json"));
36
+ }
37
+ catch { /* ignore */ }
38
+ }
39
+ const toolsDir = path.join(cwd, "tools");
40
+ if (fs.existsSync(toolsDir)) {
41
+ try {
42
+ status.toolFiles = fs.readdirSync(toolsDir).filter((f) => f.endsWith(".json"));
43
+ }
44
+ catch { /* ignore */ }
45
+ }
46
+ const testsDir = path.join(cwd, "tests");
47
+ if (fs.existsSync(testsDir)) {
48
+ try {
49
+ status.testFiles = fs.readdirSync(testsDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml") || f.endsWith(".json"));
50
+ }
51
+ catch { /* ignore */ }
52
+ }
53
+ const envPath = path.join(cwd, ".env");
54
+ if (fs.existsSync(envPath)) {
55
+ status.hasEnv = true;
56
+ if (!status.hasOpenAIKey) {
57
+ try {
58
+ const content = fs.readFileSync(envPath, "utf-8");
59
+ status.hasOpenAIKey = content.includes("OPENAI_API_KEY=");
60
+ }
61
+ catch { /* ignore */ }
62
+ }
63
+ }
64
+ return status;
65
+ }
66
+ function timeAgo(isoString) {
67
+ const diff = Date.now() - new Date(isoString).getTime();
68
+ const mins = Math.floor(diff / 60_000);
69
+ if (mins < 1)
70
+ return "just now";
71
+ if (mins < 60)
72
+ return `${mins}m ago`;
73
+ const hours = Math.floor(mins / 60);
74
+ if (hours < 24)
75
+ return `${hours}h ago`;
76
+ const days = Math.floor(hours / 24);
77
+ return `${days}d ago`;
78
+ }
79
+ export const statusCommand = new Command("status")
80
+ .description("Show current project state")
81
+ .action(async (_opts, cmd) => {
82
+ const jsonMode = cmd.parent?.opts().json;
83
+ const cwd = process.cwd();
84
+ const status = getProjectStatus(cwd);
85
+ if (jsonMode) {
86
+ console.log(JSON.stringify(status, null, 2));
87
+ return;
88
+ }
89
+ console.log();
90
+ if (!status.hasProject) {
91
+ console.log(chalk.yellow(" No eqho-eval project found in this directory."));
92
+ console.log();
93
+ console.log(chalk.dim(" Get started:"));
94
+ console.log(chalk.cyan(" eqho-eval start"));
95
+ console.log(chalk.cyan(" eqho-eval init --campaign <id>"));
96
+ console.log();
97
+ return;
98
+ }
99
+ const auth = loadAuth();
100
+ console.log(chalk.bold(" Project: ") + chalk.dim(cwd));
101
+ if (auth) {
102
+ const authLabel = auth.authMode === "bearer"
103
+ ? `SSO (${auth.email ?? "bearer"})`
104
+ : `API key (${(auth.apiKey ?? "").slice(0, 8)}...)`;
105
+ console.log(chalk.bold(" Auth: ") + chalk.dim(authLabel));
106
+ if (auth.orgId) {
107
+ const orgLabel = auth.orgName ? `${auth.orgName} (${auth.orgId})` : auth.orgId;
108
+ console.log(chalk.bold(" Org: ") + chalk.cyan(orgLabel));
109
+ }
110
+ }
111
+ if (status.campaignId) {
112
+ console.log(chalk.bold(" Campaign: ") + chalk.cyan(status.campaignId));
113
+ }
114
+ if (status.agentIds?.length) {
115
+ console.log(chalk.bold(" Agents: ") + chalk.dim(`${status.agentIds.length} configured`));
116
+ }
117
+ if (status.lastSynced) {
118
+ console.log(chalk.bold(" Last synced: ") + chalk.dim(timeAgo(status.lastSynced)));
119
+ }
120
+ console.log();
121
+ console.log(chalk.bold(" Files:"));
122
+ console.log(chalk.dim(` Prompts: ${status.promptFiles.length || "none"}`));
123
+ console.log(chalk.dim(` Tools: ${status.toolFiles.length || "none"}`));
124
+ console.log(chalk.dim(` Tests: ${status.testFiles.length || "none"}`));
125
+ console.log();
126
+ const envIcon = status.hasOpenAIKey ? chalk.green("✓") : chalk.red("✗");
127
+ console.log(` ${envIcon} OpenAI API key ${status.hasOpenAIKey ? "configured" : "not found"}`);
128
+ if (!status.hasOpenAIKey) {
129
+ console.log(chalk.cyan(" → export OPENAI_API_KEY=sk-... or add to .env"));
130
+ }
131
+ console.log();
132
+ });
133
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const syncCommand: Command;
3
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,WAAW,SAsFpB,CAAC"}
@@ -0,0 +1,80 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import ora from "ora";
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
+ import { EqhoClient, EqhoApiError } from "../../core/eqho-client.js";
7
+ import { fetchCampaignAgents } from "../../core/agent-fetcher.js";
8
+ import { assemblePrompt } from "../../core/prompt-assembler.js";
9
+ import { loadAuth } from "../auth-store.js";
10
+ export const syncCommand = new Command("sync")
11
+ .description("Re-sync prompt and tools from Eqho (preserves your tests)")
12
+ .option("-d, --dir <dir>", "Project directory", ".")
13
+ .action(async (opts) => {
14
+ const auth = loadAuth();
15
+ if (!auth) {
16
+ console.log(chalk.red("Not authenticated. Run: eqho-eval auth"));
17
+ process.exit(1);
18
+ }
19
+ const configPath = path.resolve(opts.dir, "eqho.config.json");
20
+ if (!fs.existsSync(configPath)) {
21
+ console.log(chalk.red("No eqho.config.json found. Run: eqho-eval init"));
22
+ process.exit(1);
23
+ }
24
+ let eqhoConfig;
25
+ try {
26
+ eqhoConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
27
+ }
28
+ catch {
29
+ console.log(chalk.red("Invalid eqho.config.json. Re-run: eqho-eval init"));
30
+ process.exit(1);
31
+ }
32
+ const client = new EqhoClient(auth);
33
+ const spinner = ora({ text: "Syncing from Eqho...", stream: process.stderr }).start();
34
+ let campaign;
35
+ try {
36
+ campaign = await client.getCampaign(eqhoConfig.campaignId);
37
+ }
38
+ catch (err) {
39
+ spinner.fail(`Failed to fetch campaign: ${err instanceof EqhoApiError ? err.message : String(err)}`);
40
+ process.exit(1);
41
+ }
42
+ const { agents, errors } = await fetchCampaignAgents(client, campaign, {
43
+ onProgress: (msg) => { spinner.text = msg; },
44
+ });
45
+ if (errors.length) {
46
+ for (const e of errors)
47
+ console.log(chalk.yellow(` Warning: ${e}`));
48
+ }
49
+ let updated = 0;
50
+ const outDir = path.resolve(opts.dir);
51
+ for (const { agent, systemPromptSections, conversationSeeder } of agents) {
52
+ const assembled = assemblePrompt({
53
+ agent,
54
+ campaign,
55
+ roles: agent.roles,
56
+ actions: agent.actions,
57
+ scripts: agent.scripts,
58
+ systemPromptSections,
59
+ conversationSeeder,
60
+ });
61
+ const promptFile = path.join(outDir, `prompts/${assembled.agentSlug}.json`);
62
+ const toolsFile = path.join(outDir, `tools/${assembled.agentSlug}.json`);
63
+ const chatMessages = [
64
+ { role: "system", content: assembled.systemPrompt },
65
+ ...assembled.conversationSeeder,
66
+ { role: "user", content: "{{message}}" },
67
+ ];
68
+ for (const dir of [path.dirname(promptFile), path.dirname(toolsFile)]) {
69
+ if (!fs.existsSync(dir))
70
+ fs.mkdirSync(dir, { recursive: true });
71
+ }
72
+ fs.writeFileSync(promptFile, JSON.stringify(chatMessages, null, 2));
73
+ fs.writeFileSync(toolsFile, JSON.stringify(assembled.tools, null, 2));
74
+ updated++;
75
+ }
76
+ eqhoConfig.lastSynced = new Date().toISOString();
77
+ fs.writeFileSync(configPath, JSON.stringify(eqhoConfig, null, 2));
78
+ spinner.succeed(`Synced ${updated} agent(s) from ${campaign.name}. Tests preserved.`);
79
+ });
80
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/cli/commands/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const viewCommand: Command;
3
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,WAAW,SAyBpB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import { runPromptfoo, isPromptfooInstalled } from "../../core/promptfoo-runner.js";
4
+ export const viewCommand = new Command("view")
5
+ .description("Open promptfoo web viewer for evaluation results")
6
+ .option("-p, --port <port>", "Port for the viewer")
7
+ .option("--yes", "Skip confirmation prompts")
8
+ .allowUnknownOption(true)
9
+ .action(async (opts, cmd) => {
10
+ if (!isPromptfooInstalled()) {
11
+ console.log(chalk.red("promptfoo is not installed."));
12
+ console.log();
13
+ console.log(chalk.dim(" Install it:"));
14
+ console.log(chalk.cyan(" npm install promptfoo"));
15
+ console.log();
16
+ process.exit(1);
17
+ }
18
+ const args = ["view"];
19
+ if (opts.port)
20
+ args.push("-p", opts.port);
21
+ if (opts.yes)
22
+ args.push("--yes");
23
+ const extraArgs = cmd.args || [];
24
+ args.push(...extraArgs);
25
+ console.log(chalk.dim("Opening promptfoo viewer..."));
26
+ const { exitCode } = runPromptfoo(args);
27
+ process.exit(exitCode);
28
+ });
29
+ //# sourceMappingURL=view.js.map