voyageai-cli 1.28.0 → 1.30.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 (58) hide show
  1. package/README.md +82 -8
  2. package/package.json +2 -1
  3. package/src/commands/app.js +15 -0
  4. package/src/commands/benchmark.js +22 -8
  5. package/src/commands/chat.js +18 -0
  6. package/src/commands/chunk.js +10 -0
  7. package/src/commands/demo.js +4 -0
  8. package/src/commands/embed.js +13 -0
  9. package/src/commands/estimate.js +3 -0
  10. package/src/commands/eval.js +6 -0
  11. package/src/commands/explain.js +2 -0
  12. package/src/commands/generate.js +2 -0
  13. package/src/commands/ingest.js +4 -0
  14. package/src/commands/init.js +2 -0
  15. package/src/commands/mcp-server.js +2 -0
  16. package/src/commands/models.js +2 -0
  17. package/src/commands/ping.js +7 -0
  18. package/src/commands/pipeline.js +15 -0
  19. package/src/commands/playground.js +685 -8
  20. package/src/commands/query.js +16 -0
  21. package/src/commands/rerank.js +12 -0
  22. package/src/commands/scaffold.js +2 -0
  23. package/src/commands/search.js +11 -0
  24. package/src/commands/similarity.js +9 -0
  25. package/src/commands/store.js +4 -0
  26. package/src/commands/workflow.js +702 -13
  27. package/src/lib/capability-report.js +134 -0
  28. package/src/lib/chat.js +32 -1
  29. package/src/lib/config.js +2 -0
  30. package/src/lib/cost-display.js +107 -0
  31. package/src/lib/explanations.js +94 -0
  32. package/src/lib/llm.js +125 -18
  33. package/src/lib/npm-utils.js +265 -0
  34. package/src/lib/quality-audit.js +71 -0
  35. package/src/lib/security/blocked-domains.json +17 -0
  36. package/src/lib/security-audit.js +198 -0
  37. package/src/lib/telemetry.js +23 -1
  38. package/src/lib/workflow-registry.js +416 -0
  39. package/src/lib/workflow-scaffold.js +380 -0
  40. package/src/lib/workflow-test-runner.js +208 -0
  41. package/src/lib/workflow.js +559 -7
  42. package/src/playground/announcements.md +80 -0
  43. package/src/playground/assets/announcements/appstore.jpg +0 -0
  44. package/src/playground/assets/announcements/circuits.jpg +0 -0
  45. package/src/playground/assets/announcements/csvingest.jpg +0 -0
  46. package/src/playground/assets/announcements/green-wave.jpg +0 -0
  47. package/src/playground/help/workflow-nodes.js +472 -0
  48. package/src/playground/icons/V.png +0 -0
  49. package/src/playground/index.html +3634 -226
  50. package/src/workflows/consistency-check.json +4 -0
  51. package/src/workflows/cost-analysis.json +4 -0
  52. package/src/workflows/enrich-and-ingest.json +56 -0
  53. package/src/workflows/intelligent-ingest.json +66 -0
  54. package/src/workflows/kb-health-report.json +45 -0
  55. package/src/workflows/multi-collection-search.json +4 -0
  56. package/src/workflows/research-and-summarize.json +4 -0
  57. package/src/workflows/search-with-fallback.json +66 -0
  58. package/src/workflows/smart-ingest.json +4 -0
@@ -5,6 +5,7 @@ const { generateEmbeddings, apiRequest } = require('../lib/api');
5
5
  const { getMongoCollection } = require('../lib/mongo');
6
6
  const { loadProject } = require('../lib/project');
7
7
  const ui = require('../lib/ui');
8
+ const { showCombinedCostSummary } = require('../lib/cost-display');
8
9
 
9
10
  /**
10
11
  * Register the query command on a Commander program.
@@ -33,6 +34,7 @@ function registerQuery(program) {
33
34
  .option('-q, --quiet', 'Suppress non-essential output')
34
35
  .action(async (text, opts) => {
35
36
  let client;
37
+ const telemetry = require('../lib/telemetry');
36
38
  try {
37
39
  // Merge project config
38
40
  const { config: proj } = loadProject();
@@ -51,6 +53,14 @@ function registerQuery(program) {
51
53
  process.exit(1);
52
54
  }
53
55
 
56
+ const done = telemetry.timer('cli_query', {
57
+ model,
58
+ rerankModel: doRerank ? rerankModel : undefined,
59
+ rerank: doRerank,
60
+ limit: opts.limit,
61
+ topK: opts.topK,
62
+ });
63
+
54
64
  const useColor = !opts.json;
55
65
  const useSpinner = useColor && !opts.quiet;
56
66
 
@@ -242,8 +252,14 @@ function registerQuery(program) {
242
252
  if (!opts.quiet) {
243
253
  const totalTokens = embedTokens + rerankTokens;
244
254
  console.log(ui.dim(` Tokens: ${totalTokens} (embed: ${embedTokens}${rerankTokens ? `, rerank: ${rerankTokens}` : ''})`));
255
+ const costOps = [{ model, tokens: embedTokens, label: `embed (${model})` }];
256
+ if (rerankTokens) costOps.push({ model: rerankModel, tokens: rerankTokens, label: `rerank (${rerankModel})` });
257
+ showCombinedCostSummary(costOps, opts);
245
258
  }
259
+
260
+ done({ resultCount: finalResults.length });
246
261
  } catch (err) {
262
+ telemetry.send('cli_error', { command: 'query', errorType: err.constructor.name });
247
263
  console.error(ui.error(err.message));
248
264
  process.exit(1);
249
265
  } finally {
@@ -4,6 +4,7 @@ const fs = require('fs');
4
4
  const { DEFAULT_RERANK_MODEL } = require('../lib/catalog');
5
5
  const { apiRequest } = require('../lib/api');
6
6
  const ui = require('../lib/ui');
7
+ const { showCostSummary } = require('../lib/cost-display');
7
8
 
8
9
  /**
9
10
  * Register the rerank command on a Commander program.
@@ -25,6 +26,7 @@ function registerRerank(program) {
25
26
  .option('--json', 'Machine-readable JSON output')
26
27
  .option('-q, --quiet', 'Suppress non-essential output')
27
28
  .action(async (opts) => {
29
+ const telemetry = require('../lib/telemetry');
28
30
  try {
29
31
  let documents = opts.documents;
30
32
 
@@ -81,6 +83,12 @@ function registerRerank(program) {
81
83
  opts.model = chosenModel;
82
84
  }
83
85
 
86
+ const done = telemetry.timer('cli_rerank', {
87
+ model: opts.model,
88
+ docCount: documents.length,
89
+ topK: opts.topK,
90
+ });
91
+
84
92
  const body = {
85
93
  query: opts.query,
86
94
  documents,
@@ -120,6 +128,7 @@ function registerRerank(program) {
120
128
  if (result.usage) {
121
129
  console.log(ui.label('Tokens', ui.dim(String(result.usage.total_tokens))));
122
130
  }
131
+ showCostSummary(result.model || opts.model, result.usage?.total_tokens || 0, opts);
123
132
  console.log('');
124
133
  }
125
134
 
@@ -134,7 +143,10 @@ function registerRerank(program) {
134
143
 
135
144
  console.log('');
136
145
  console.log(ui.success('Reranking complete'));
146
+
147
+ done();
137
148
  } catch (err) {
149
+ telemetry.send('cli_error', { command: 'rerank', errorType: err.constructor.name });
138
150
  console.error(ui.error(err.message));
139
151
  process.exit(1);
140
152
  }
@@ -55,7 +55,9 @@ function registerScaffold(program) {
55
55
  .option('--dry-run', 'Show what would be created without writing')
56
56
  .option('-q, --quiet', 'Suppress non-essential output')
57
57
  .action(async (name, opts) => {
58
+ const telemetry = require('../lib/telemetry');
58
59
  try {
60
+ telemetry.send('cli_scaffold', { template: opts.target });
59
61
  const target = opts.target;
60
62
  const projectDir = path.resolve(process.cwd(), name);
61
63
 
@@ -4,6 +4,7 @@ const { getDefaultModel } = require('../lib/catalog');
4
4
  const { generateEmbeddings } = require('../lib/api');
5
5
  const { getMongoCollection } = require('../lib/mongo');
6
6
  const ui = require('../lib/ui');
7
+ const { showCostSummary } = require('../lib/cost-display');
7
8
 
8
9
  /**
9
10
  * Register the search command on a Commander program.
@@ -29,7 +30,13 @@ function registerSearch(program) {
29
30
  .option('-q, --quiet', 'Suppress non-essential output')
30
31
  .action(async (opts) => {
31
32
  let client;
33
+ const telemetry = require('../lib/telemetry');
32
34
  try {
35
+ const done = telemetry.timer('cli_search', {
36
+ model: opts.model,
37
+ limit: opts.limit,
38
+ });
39
+
33
40
  const useColor = !opts.json;
34
41
  const useSpinner = useColor && !opts.quiet;
35
42
  let spin;
@@ -93,9 +100,12 @@ function registerSearch(program) {
93
100
  if (!opts.quiet) {
94
101
  console.log(ui.label('Query', ui.cyan(`"${opts.query}"`)));
95
102
  console.log(ui.label('Results', String(cleanResults.length)));
103
+ showCostSummary(opts.model, embedResult.usage?.total_tokens || 0, opts);
96
104
  console.log('');
97
105
  }
98
106
 
107
+ done({ resultCount: cleanResults.length });
108
+
99
109
  if (cleanResults.length === 0) {
100
110
  console.log(ui.yellow('No results found.'));
101
111
  return;
@@ -113,6 +123,7 @@ function registerSearch(program) {
113
123
  console.log('');
114
124
  }
115
125
  } catch (err) {
126
+ telemetry.send('cli_error', { command: 'search', errorType: err.constructor.name });
116
127
  console.error(ui.error(err.message));
117
128
  process.exit(1);
118
129
  } finally {
@@ -5,6 +5,7 @@ const { generateEmbeddings } = require('../lib/api');
5
5
  const { cosineSimilarity } = require('../lib/math');
6
6
  const { getDefaultModel } = require('../lib/catalog');
7
7
  const ui = require('../lib/ui');
8
+ const { showCostSummary } = require('../lib/cost-display');
8
9
 
9
10
  /**
10
11
  * Register the similarity command on a Commander program.
@@ -23,6 +24,7 @@ function registerSimilarity(program) {
23
24
  .option('--json', 'Machine-readable JSON output')
24
25
  .option('-q, --quiet', 'Suppress non-essential output')
25
26
  .action(async (texts, opts) => {
27
+ const telemetry = require('../lib/telemetry');
26
28
  try {
27
29
  let textA = null;
28
30
  let compareTexts = [];
@@ -57,6 +59,8 @@ function registerSimilarity(program) {
57
59
  process.exit(1);
58
60
  }
59
61
 
62
+ const done = telemetry.timer('cli_similarity', { model: opts.model });
63
+
60
64
  // Batch all texts into one API call
61
65
  const allTexts = [textA, ...compareTexts];
62
66
 
@@ -113,6 +117,7 @@ function registerSimilarity(program) {
113
117
  console.log(ui.label('Text B', `"${truncate(compareTexts[0], 70)}"`));
114
118
  console.log(ui.label('Model', ui.cyan(model)));
115
119
  console.log(ui.label('Tokens', ui.dim(String(tokens))));
120
+ showCostSummary(model, tokens, opts);
116
121
  console.log('');
117
122
  } else {
118
123
  // One-vs-many comparison
@@ -152,9 +157,13 @@ function registerSimilarity(program) {
152
157
 
153
158
  console.log('');
154
159
  console.log(` ${ui.dim(`${results.length} comparisons, ${tokens} tokens`)}`);
160
+ showCostSummary(model, tokens, opts);
155
161
  console.log('');
156
162
  }
163
+
164
+ done();
157
165
  } catch (err) {
166
+ telemetry.send('cli_error', { command: 'similarity', errorType: err.constructor.name });
158
167
  console.error(ui.error(err.message));
159
168
  process.exit(1);
160
169
  }
@@ -29,6 +29,8 @@ function registerStore(program) {
29
29
  .option('-q, --quiet', 'Suppress non-essential output')
30
30
  .action(async (opts) => {
31
31
  let client;
32
+ const telemetry = require('../lib/telemetry');
33
+ const done = telemetry.timer('cli_store', { model: opts.model });
32
34
  try {
33
35
  // Batch mode: .jsonl file
34
36
  if (opts.file && opts.file.endsWith('.jsonl')) {
@@ -102,7 +104,9 @@ function registerStore(program) {
102
104
  console.log(ui.label('Tokens', String(embedResult.usage.total_tokens)));
103
105
  }
104
106
  }
107
+ done();
105
108
  } catch (err) {
109
+ telemetry.send('cli_error', { command: 'store', errorType: err.constructor.name });
106
110
  console.error(ui.error(err.message));
107
111
  process.exit(1);
108
112
  } finally {