voyageai-cli 1.30.0 → 1.30.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.
Files changed (82) hide show
  1. package/README.md +4 -4
  2. package/package.json +1 -1
  3. package/src/cli.js +8 -0
  4. package/src/commands/about.js +3 -3
  5. package/src/commands/chat.js +32 -11
  6. package/src/commands/code-search.js +751 -0
  7. package/src/commands/doctor.js +1 -1
  8. package/src/commands/export.js +124 -0
  9. package/src/commands/import.js +195 -0
  10. package/src/commands/index-workspace.js +243 -0
  11. package/src/commands/mcp-server.js +113 -3
  12. package/src/commands/playground.js +120 -4
  13. package/src/commands/quickstart.js +4 -4
  14. package/src/commands/workflow.js +132 -65
  15. package/src/lib/catalog.js +4 -2
  16. package/src/lib/code-search.js +315 -0
  17. package/src/lib/codegen.js +1 -1
  18. package/src/lib/explanations.js +3 -3
  19. package/src/lib/export/contexts/benchmark-export.js +27 -0
  20. package/src/lib/export/contexts/chat-export.js +41 -0
  21. package/src/lib/export/contexts/explore-export.js +22 -0
  22. package/src/lib/export/contexts/search-export.js +54 -0
  23. package/src/lib/export/contexts/workflow-export.js +80 -0
  24. package/src/lib/export/formats/clipboard-export.js +29 -0
  25. package/src/lib/export/formats/csv-export.js +45 -0
  26. package/src/lib/export/formats/json-export.js +50 -0
  27. package/src/lib/export/formats/markdown-export.js +189 -0
  28. package/src/lib/export/formats/mermaid-export.js +274 -0
  29. package/src/lib/export/formats/pdf-export.js +117 -0
  30. package/src/lib/export/formats/png-export.js +96 -0
  31. package/src/lib/export/formats/svg-export.js +116 -0
  32. package/src/lib/export/index.js +175 -0
  33. package/src/lib/github.js +226 -0
  34. package/src/lib/template-engine.js +154 -20
  35. package/src/lib/workflow-builder.js +753 -0
  36. package/src/lib/workflow-formatters.js +454 -0
  37. package/src/lib/workflow-input-cache.js +111 -0
  38. package/src/lib/workflow-scaffold.js +1 -1
  39. package/src/lib/workflow.js +297 -28
  40. package/src/mcp/install.js +280 -7
  41. package/src/mcp/schemas/index.js +170 -0
  42. package/src/mcp/server.js +19 -4
  43. package/src/mcp/tools/authoring.js +662 -0
  44. package/src/mcp/tools/code-search.js +620 -0
  45. package/src/mcp/tools/ingest.js +2 -5
  46. package/src/mcp/tools/retrieval.js +2 -15
  47. package/src/mcp/tools/workspace.js +452 -0
  48. package/src/mcp/utils.js +20 -0
  49. package/src/playground/announcements.md +52 -5
  50. package/src/playground/help/workflow-nodes.js +127 -2
  51. package/src/playground/index.html +17109 -12438
  52. package/src/playground/vendor/mermaid.min.js +2811 -0
  53. package/src/workflows/code-review.json +110 -0
  54. package/src/workflows/cost-analysis.json +5 -0
  55. package/src/workflows/rag-chat.json +165 -0
  56. package/src/workflows/tests/code-review.fresh-index.test.json +83 -0
  57. package/src/workflows/tests/code-review.happy-path.test.json +121 -0
  58. package/src/workflows/tests/code-review.no-question.test.json +70 -0
  59. package/src/workflows/tests/consistency-check.happy-path.test.json +28 -0
  60. package/src/workflows/tests/consistency-check.missing-source.test.json +26 -0
  61. package/src/workflows/tests/cost-analysis.happy-path.test.json +28 -0
  62. package/src/workflows/tests/enrich-and-ingest.happy-path.test.json +38 -0
  63. package/src/workflows/tests/enrich-and-ingest.notify-fails.test.json +38 -0
  64. package/src/workflows/tests/intelligent-ingest.all-filtered.test.json +26 -0
  65. package/src/workflows/tests/intelligent-ingest.happy-path.test.json +28 -0
  66. package/src/workflows/tests/kb-health-report.custom-queries.test.json +24 -0
  67. package/src/workflows/tests/kb-health-report.happy-path.test.json +26 -0
  68. package/src/workflows/tests/multi-collection-search.happy-path.test.json +40 -0
  69. package/src/workflows/tests/multi-collection-search.one-empty.test.json +28 -0
  70. package/src/workflows/tests/rag-chat.happy-path.test.json +26 -0
  71. package/src/workflows/tests/rag-chat.no-relevant-results.test.json +25 -0
  72. package/src/workflows/tests/research-and-summarize.happy-path.test.json +33 -0
  73. package/src/workflows/tests/research-and-summarize.no-results.test.json +29 -0
  74. package/src/workflows/tests/search-with-fallback.empty-both.test.json +24 -0
  75. package/src/workflows/tests/search-with-fallback.fallback-branch.test.json +24 -0
  76. package/src/workflows/tests/search-with-fallback.happy-path.test.json +27 -0
  77. package/src/workflows/tests/smart-ingest.duplicate-detected.test.json +34 -0
  78. package/src/workflows/tests/smart-ingest.happy-path.test.json +31 -0
  79. package/src/playground/assets/announcements/appstore.jpg +0 -0
  80. package/src/playground/assets/announcements/circuits.jpg +0 -0
  81. package/src/playground/assets/announcements/csvingest.jpg +0 -0
  82. package/src/playground/assets/announcements/green-wave.jpg +0 -0
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "enrich-and-ingest: happy path",
3
+ "inputs": {
4
+ "document_url": "https://api.example.com/documents/123/metadata",
5
+ "text": "This is the document text to ingest after enrichment with external metadata."
6
+ },
7
+ "mocks": {
8
+ "http": {
9
+ "status": 200,
10
+ "statusText": "OK",
11
+ "headers": { "content-type": "application/json" },
12
+ "body": {
13
+ "title": "Getting Started Guide",
14
+ "author": "Jane Developer",
15
+ "category": "tutorials",
16
+ "timestamp": "2025-01-15T10:00:00Z"
17
+ },
18
+ "durationMs": 150
19
+ },
20
+ "ingest": {
21
+ "chunks": 2,
22
+ "source": "Getting Started Guide",
23
+ "collection": "default"
24
+ }
25
+ },
26
+ "expect": {
27
+ "steps": {
28
+ "fetch_metadata": { "status": "completed" },
29
+ "store": { "status": "completed" },
30
+ "notify": { "status": "completed" }
31
+ },
32
+ "output": {
33
+ "source": { "type": "string", "minLength": 1 },
34
+ "chunks": { "type": "number" }
35
+ },
36
+ "noErrors": true
37
+ }
38
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "enrich-and-ingest: notification failure (continueOnError)",
3
+ "inputs": {
4
+ "document_url": "https://api.example.com/documents/456/metadata",
5
+ "text": "Document text for ingestion even if notification fails."
6
+ },
7
+ "mocks": {
8
+ "http": {
9
+ "status": 200,
10
+ "statusText": "OK",
11
+ "headers": { "content-type": "application/json" },
12
+ "body": {
13
+ "title": "API Reference",
14
+ "author": "John Dev",
15
+ "category": "reference",
16
+ "timestamp": "2025-02-01T14:00:00Z"
17
+ },
18
+ "durationMs": 200
19
+ },
20
+ "ingest": {
21
+ "chunks": 5,
22
+ "source": "API Reference",
23
+ "collection": "default"
24
+ }
25
+ },
26
+ "expect": {
27
+ "steps": {
28
+ "fetch_metadata": { "status": "completed" },
29
+ "store": { "status": "completed" },
30
+ "notify": { "status": "completed" }
31
+ },
32
+ "output": {
33
+ "source": { "type": "string", "minLength": 1 },
34
+ "chunks": { "type": "number" }
35
+ },
36
+ "noErrors": true
37
+ }
38
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "intelligent-ingest: all chunks filtered out (too short)",
3
+ "inputs": {
4
+ "text": "Short. Tiny. Small text.",
5
+ "source": "tiny.md",
6
+ "similarity_threshold": 0.92
7
+ },
8
+ "mocks": {
9
+ "search": {
10
+ "results": [],
11
+ "resultCount": 0
12
+ }
13
+ },
14
+ "expect": {
15
+ "steps": {
16
+ "split": { "status": "completed" },
17
+ "filter_short": { "status": "completed" },
18
+ "check_each": { "status": "completed" },
19
+ "embed_novel": { "status": "completed" }
20
+ },
21
+ "output": {
22
+ "summary": { "type": "string" }
23
+ },
24
+ "noErrors": true
25
+ }
26
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "intelligent-ingest: happy path",
3
+ "inputs": {
4
+ "text": "This is a long document about vector databases and how they work. Vector databases store high-dimensional embeddings and support approximate nearest neighbor search for fast retrieval. They are essential for modern RAG applications. The key advantage is that semantic similarity can be computed efficiently at scale. Various indexing strategies like HNSW and IVF are used to speed up queries.",
5
+ "source": "vector-db-guide.md",
6
+ "similarity_threshold": 0.92
7
+ },
8
+ "mocks": {
9
+ "search": {
10
+ "results": [
11
+ { "text": "Some existing doc about databases", "score": 0.45 }
12
+ ],
13
+ "resultCount": 1
14
+ }
15
+ },
16
+ "expect": {
17
+ "steps": {
18
+ "split": { "status": "completed" },
19
+ "filter_short": { "status": "completed" },
20
+ "check_each": { "status": "completed" },
21
+ "embed_novel": { "status": "completed" }
22
+ },
23
+ "output": {
24
+ "summary": { "type": "string", "minLength": 1 }
25
+ },
26
+ "noErrors": true
27
+ }
28
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "kb-health-report: custom queries",
3
+ "inputs": {
4
+ "test_queries": ["vector search", "embeddings"]
5
+ },
6
+ "mocks": {
7
+ "query": {
8
+ "results": [],
9
+ "resultCount": 0
10
+ },
11
+ "generate": {
12
+ "text": "Knowledge Base Health Report: 2 topics tested. Low coverage detected across test queries.",
13
+ "model": "claude-3-haiku",
14
+ "tokensUsed": 60
15
+ }
16
+ },
17
+ "expect": {
18
+ "steps": {
19
+ "coverage_check": { "status": "completed" },
20
+ "report": { "status": "completed" }
21
+ },
22
+ "noErrors": true
23
+ }
24
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "kb-health-report: happy path",
3
+ "inputs": {
4
+ "test_queries": ["authentication", "deployment", "error handling"]
5
+ },
6
+ "mocks": {
7
+ "query": {
8
+ "results": [
9
+ { "text": "Auth docs available", "score": 0.9 }
10
+ ],
11
+ "resultCount": 1
12
+ },
13
+ "generate": {
14
+ "text": "Knowledge Base Health Report: 3 topics tested. Coverage looks good with results found for all test queries.",
15
+ "model": "claude-3-haiku",
16
+ "tokensUsed": 85
17
+ }
18
+ },
19
+ "expect": {
20
+ "steps": {
21
+ "coverage_check": { "status": "completed" },
22
+ "report": { "status": "completed" }
23
+ },
24
+ "noErrors": true
25
+ }
26
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "multi-collection-search: happy path",
3
+ "inputs": {
4
+ "query": "how to deploy",
5
+ "collection1": "api_docs",
6
+ "collection2": "tutorials",
7
+ "limit": 5
8
+ },
9
+ "mocks": {
10
+ "query": {
11
+ "results": [
12
+ { "text": "Deploy using Docker containers", "score": 0.92, "source": "deploy.md" },
13
+ { "text": "CI/CD pipeline setup guide", "score": 0.85, "source": "ci.md" }
14
+ ],
15
+ "resultCount": 2
16
+ },
17
+ "rerank": {
18
+ "results": [
19
+ { "text": "Deploy using Docker containers", "score": 0.96, "source": "deploy.md" },
20
+ { "text": "CI/CD pipeline setup guide", "score": 0.91, "source": "ci.md" },
21
+ { "text": "Deploy using Docker containers", "score": 0.89, "source": "deploy.md" },
22
+ { "text": "CI/CD pipeline setup guide", "score": 0.82, "source": "ci.md" }
23
+ ],
24
+ "resultCount": 4
25
+ }
26
+ },
27
+ "expect": {
28
+ "steps": {
29
+ "search_1": { "status": "completed" },
30
+ "search_2": { "status": "completed" },
31
+ "merge": { "status": "completed" },
32
+ "rerank_all": { "status": "completed" }
33
+ },
34
+ "output": {
35
+ "results": { "type": "array", "minLength": 1 },
36
+ "resultCount": { "type": "number" }
37
+ },
38
+ "noErrors": true
39
+ }
40
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "multi-collection-search: one collection empty",
3
+ "inputs": {
4
+ "query": "obscure feature",
5
+ "collection1": "api_docs",
6
+ "collection2": "tutorials",
7
+ "limit": 5
8
+ },
9
+ "mocks": {
10
+ "query": {
11
+ "results": [],
12
+ "resultCount": 0
13
+ },
14
+ "rerank": {
15
+ "results": [],
16
+ "resultCount": 0
17
+ }
18
+ },
19
+ "expect": {
20
+ "steps": {
21
+ "search_1": { "status": "completed" },
22
+ "search_2": { "status": "completed" },
23
+ "merge": { "status": "completed" },
24
+ "rerank_all": { "status": "completed" }
25
+ },
26
+ "noErrors": true
27
+ }
28
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "rag-chat: happy path with relevant results",
3
+ "inputs": {
4
+ "question": "How do I create a vector search index?",
5
+ "collection": "docs",
6
+ "collection2": "",
7
+ "limit": 5,
8
+ "min_score": 0.3,
9
+ "system_prompt": "You are a helpful assistant. Cite sources.",
10
+ "chat_history": ""
11
+ },
12
+ "mocks": {
13
+ "query": { "results": [{ "text": "To create a vector search index, use the Atlas UI or CLI...", "source": "atlas-docs.md", "score": 0.92 }, { "text": "Vector indexes support cosine, euclidean, and dotProduct similarity.", "source": "vector-guide.md", "score": 0.85 }], "resultCount": 2 },
14
+ "rerank": { "results": [{ "text": "To create a vector search index, use the Atlas UI or CLI...", "source": "atlas-docs.md", "score": 0.95 }, { "text": "Vector indexes support cosine, euclidean, and dotProduct similarity.", "source": "vector-guide.md", "score": 0.78 }], "resultCount": 2 },
15
+ "generate": { "text": "To create a vector search index, you can use the Atlas UI or the CLI. According to the documentation (atlas-docs.md), the process involves...", "model": "claude-sonnet", "provider": "anthropic" }
16
+ },
17
+ "expect": {
18
+ "steps": {
19
+ "search_primary": { "status": "completed" },
20
+ "rerank": { "status": "completed" },
21
+ "filter_relevant": { "status": "completed" },
22
+ "generate_answer": { "status": "completed" }
23
+ },
24
+ "noErrors": true
25
+ }
26
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "rag-chat: no results above relevance threshold",
3
+ "inputs": {
4
+ "question": "What is the meaning of life?",
5
+ "collection": "technical-docs",
6
+ "collection2": "",
7
+ "limit": 5,
8
+ "min_score": 0.5,
9
+ "system_prompt": "You are a helpful assistant.",
10
+ "chat_history": ""
11
+ },
12
+ "mocks": {
13
+ "query": { "results": [{ "text": "MongoDB Atlas provides cloud database services.", "source": "overview.md", "score": 0.15 }], "resultCount": 1 },
14
+ "rerank": { "results": [{ "text": "MongoDB Atlas provides cloud database services.", "source": "overview.md", "score": 0.12 }], "resultCount": 1 }
15
+ },
16
+ "expect": {
17
+ "steps": {
18
+ "search_primary": { "status": "completed" },
19
+ "rerank": { "status": "completed" },
20
+ "filter_relevant": { "status": "completed" },
21
+ "no_context_response": { "status": "completed" }
22
+ },
23
+ "noErrors": true
24
+ }
25
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "research-and-summarize: happy path",
3
+ "inputs": {
4
+ "question": "How does vector search work?",
5
+ "limit": 5
6
+ },
7
+ "mocks": {
8
+ "query": {
9
+ "results": [
10
+ { "text": "Vector search uses embeddings to find similar documents", "score": 0.95 },
11
+ { "text": "Approximate nearest neighbor algorithms power vector search", "score": 0.88 }
12
+ ],
13
+ "resultCount": 2
14
+ },
15
+ "generate": {
16
+ "text": "Vector search works by converting documents and queries into numerical embeddings and finding the closest matches using ANN algorithms.",
17
+ "model": "claude-3-haiku",
18
+ "tokensUsed": 120
19
+ }
20
+ },
21
+ "expect": {
22
+ "steps": {
23
+ "research": { "status": "completed" },
24
+ "summarize": { "status": "completed" }
25
+ },
26
+ "output": {
27
+ "summary": { "type": "string", "minLength": 1 },
28
+ "sources": { "type": "array", "minLength": 1 },
29
+ "sourceCount": { "type": "number" }
30
+ },
31
+ "noErrors": true
32
+ }
33
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "research-and-summarize: no search results",
3
+ "inputs": {
4
+ "question": "What is the meaning of life?",
5
+ "limit": 5
6
+ },
7
+ "mocks": {
8
+ "query": {
9
+ "results": [],
10
+ "resultCount": 0
11
+ },
12
+ "generate": {
13
+ "text": "No relevant documents were found in the knowledge base to answer this question.",
14
+ "model": "claude-3-haiku",
15
+ "tokensUsed": 45
16
+ }
17
+ },
18
+ "expect": {
19
+ "steps": {
20
+ "research": { "status": "completed" },
21
+ "summarize": { "status": "completed" }
22
+ },
23
+ "output": {
24
+ "summary": { "type": "string", "minLength": 1 },
25
+ "sourceCount": { "type": "number" }
26
+ },
27
+ "noErrors": true
28
+ }
29
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "search-with-fallback: both collections empty",
3
+ "inputs": {
4
+ "query": "nonexistent topic xyz",
5
+ "primary_collection": "api_docs",
6
+ "fallback_collection": "knowledge"
7
+ },
8
+ "mocks": {
9
+ "query": {
10
+ "results": [],
11
+ "resultCount": 0
12
+ }
13
+ },
14
+ "expect": {
15
+ "steps": {
16
+ "primary_search": { "status": "completed" },
17
+ "check_results": { "status": "completed" },
18
+ "format_primary": { "status": "skipped" },
19
+ "fallback_search": { "status": "completed" },
20
+ "format_fallback": { "status": "completed" }
21
+ },
22
+ "noErrors": true
23
+ }
24
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "search-with-fallback: fallback branch (primary empty)",
3
+ "inputs": {
4
+ "query": "obscure topic",
5
+ "primary_collection": "api_docs",
6
+ "fallback_collection": "knowledge"
7
+ },
8
+ "mocks": {
9
+ "query": {
10
+ "results": [],
11
+ "resultCount": 0
12
+ }
13
+ },
14
+ "expect": {
15
+ "steps": {
16
+ "primary_search": { "status": "completed" },
17
+ "check_results": { "status": "completed" },
18
+ "format_primary": { "status": "skipped" },
19
+ "fallback_search": { "status": "completed" },
20
+ "format_fallback": { "status": "completed" }
21
+ },
22
+ "noErrors": true
23
+ }
24
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "search-with-fallback: happy path (primary has results)",
3
+ "inputs": {
4
+ "query": "how to authenticate",
5
+ "primary_collection": "api_docs",
6
+ "fallback_collection": "knowledge"
7
+ },
8
+ "mocks": {
9
+ "query": {
10
+ "results": [
11
+ { "text": "Use Bearer tokens for API authentication", "score": 0.95, "source": "auth.md" },
12
+ { "text": "OAuth2 is supported for third-party apps", "score": 0.88, "source": "oauth.md" }
13
+ ],
14
+ "resultCount": 2
15
+ }
16
+ },
17
+ "expect": {
18
+ "steps": {
19
+ "primary_search": { "status": "completed" },
20
+ "check_results": { "status": "completed" },
21
+ "format_primary": { "status": "completed" },
22
+ "fallback_search": { "status": "skipped" },
23
+ "format_fallback": { "status": "skipped" }
24
+ },
25
+ "noErrors": true
26
+ }
27
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "smart-ingest: duplicate detected (high similarity)",
3
+ "description": "When a near-duplicate is found (similarity above 0.85), the ingest_doc step is correctly skipped to avoid ingesting duplicate content.",
4
+ "inputs": {
5
+ "text": "A document that already exists in the knowledge base",
6
+ "source": "existing-doc.md",
7
+ "threshold": 0.85
8
+ },
9
+ "mocks": {
10
+ "search": {
11
+ "results": [
12
+ { "text": "A document that already exists in the knowledge base", "score": 0.98 }
13
+ ],
14
+ "resultCount": 1
15
+ },
16
+ "similarity": {
17
+ "similarity": 0.97,
18
+ "model": "voyage-4-large"
19
+ },
20
+ "ingest": {
21
+ "chunks": 1,
22
+ "source": "existing-doc.md",
23
+ "collection": "default"
24
+ }
25
+ },
26
+ "expect": {
27
+ "steps": {
28
+ "check_existing": { "status": "completed" },
29
+ "similarity_check": { "status": "completed" },
30
+ "ingest_doc": { "status": "skipped" }
31
+ },
32
+ "noErrors": true
33
+ }
34
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "smart-ingest: novel document (no similar docs found)",
3
+ "inputs": {
4
+ "text": "A completely new document about quantum computing fundamentals",
5
+ "source": "quantum-101.md",
6
+ "threshold": 0.85
7
+ },
8
+ "mocks": {
9
+ "search": {
10
+ "results": [],
11
+ "resultCount": 0
12
+ },
13
+ "similarity": {
14
+ "similarity": 0.12,
15
+ "model": "voyage-4-large"
16
+ },
17
+ "ingest": {
18
+ "chunks": 3,
19
+ "source": "quantum-101.md",
20
+ "collection": "default"
21
+ }
22
+ },
23
+ "expect": {
24
+ "steps": {
25
+ "check_existing": { "status": "completed" },
26
+ "similarity_check": { "status": "skipped" },
27
+ "ingest_doc": { "status": "completed" }
28
+ },
29
+ "noErrors": true
30
+ }
31
+ }