agent-nuvira 3.3.11 → 3.3.13

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 (220) hide show
  1. package/README.md +32 -1
  2. package/dist/agents/agents/reasoner.d.ts.map +1 -1
  3. package/dist/agents/agents/reasoner.js +13 -0
  4. package/dist/agents/agents/reasoner.js.map +1 -1
  5. package/dist/agents/orchestrator.d.ts.map +1 -1
  6. package/dist/agents/orchestrator.js +56 -20
  7. package/dist/agents/orchestrator.js.map +1 -1
  8. package/dist/cli/chat.d.ts +36 -0
  9. package/dist/cli/chat.d.ts.map +1 -1
  10. package/dist/cli/chat.js +456 -43
  11. package/dist/cli/chat.js.map +1 -1
  12. package/dist/cli/cli-program.d.ts.map +1 -1
  13. package/dist/cli/cli-program.js +8 -0
  14. package/dist/cli/cli-program.js.map +1 -1
  15. package/dist/cli/config.d.ts.map +1 -1
  16. package/dist/cli/config.js +35 -4
  17. package/dist/cli/config.js.map +1 -1
  18. package/dist/cli/execute.d.ts.map +1 -1
  19. package/dist/cli/execute.js +14 -0
  20. package/dist/cli/execute.js.map +1 -1
  21. package/dist/cli/knowledge.d.ts +23 -0
  22. package/dist/cli/knowledge.d.ts.map +1 -0
  23. package/dist/cli/knowledge.js +132 -0
  24. package/dist/cli/knowledge.js.map +1 -0
  25. package/dist/cli/loop-executor.d.ts.map +1 -1
  26. package/dist/cli/loop-executor.js +57 -13
  27. package/dist/cli/loop-executor.js.map +1 -1
  28. package/dist/cli/omniroute-control.d.ts +88 -0
  29. package/dist/cli/omniroute-control.d.ts.map +1 -0
  30. package/dist/cli/omniroute-control.js +179 -0
  31. package/dist/cli/omniroute-control.js.map +1 -0
  32. package/dist/cli/omniroute.d.ts +21 -0
  33. package/dist/cli/omniroute.d.ts.map +1 -0
  34. package/dist/cli/omniroute.js +67 -0
  35. package/dist/cli/omniroute.js.map +1 -0
  36. package/dist/cli/tool-install-prompt.d.ts +58 -0
  37. package/dist/cli/tool-install-prompt.d.ts.map +1 -1
  38. package/dist/cli/tool-install-prompt.js +137 -0
  39. package/dist/cli/tool-install-prompt.js.map +1 -1
  40. package/dist/cli/weak-model-prompt.d.ts +16 -7
  41. package/dist/cli/weak-model-prompt.d.ts.map +1 -1
  42. package/dist/cli/weak-model-prompt.js +24 -8
  43. package/dist/cli/weak-model-prompt.js.map +1 -1
  44. package/dist/config/types.d.ts +44 -0
  45. package/dist/config/types.d.ts.map +1 -1
  46. package/dist/context/cache.d.ts +35 -1
  47. package/dist/context/cache.d.ts.map +1 -1
  48. package/dist/context/cache.js +31 -2
  49. package/dist/context/cache.js.map +1 -1
  50. package/dist/context/history.d.ts +21 -0
  51. package/dist/context/history.d.ts.map +1 -1
  52. package/dist/context/history.js +50 -0
  53. package/dist/context/history.js.map +1 -1
  54. package/dist/gateway/hook-contract.d.ts +173 -0
  55. package/dist/gateway/hook-contract.d.ts.map +1 -0
  56. package/dist/gateway/hook-contract.js +352 -0
  57. package/dist/gateway/hook-contract.js.map +1 -0
  58. package/dist/gateway/hooks.d.ts.map +1 -1
  59. package/dist/gateway/hooks.js +14 -0
  60. package/dist/gateway/hooks.js.map +1 -1
  61. package/dist/inference/interface.d.ts +17 -0
  62. package/dist/inference/interface.d.ts.map +1 -1
  63. package/dist/inference/model-catalog.d.ts +17 -0
  64. package/dist/inference/model-catalog.d.ts.map +1 -1
  65. package/dist/inference/model-catalog.js +42 -7
  66. package/dist/inference/model-catalog.js.map +1 -1
  67. package/dist/inference/model-id-validation.d.ts +57 -0
  68. package/dist/inference/model-id-validation.d.ts.map +1 -0
  69. package/dist/inference/model-id-validation.js +127 -0
  70. package/dist/inference/model-id-validation.js.map +1 -0
  71. package/dist/inference/openai-compat-adapter.d.ts.map +1 -1
  72. package/dist/inference/openai-compat-adapter.js +12 -1
  73. package/dist/inference/openai-compat-adapter.js.map +1 -1
  74. package/dist/inference/provider-catalog.d.ts +11 -0
  75. package/dist/inference/provider-catalog.d.ts.map +1 -1
  76. package/dist/inference/provider-catalog.js +80 -0
  77. package/dist/inference/provider-catalog.js.map +1 -1
  78. package/dist/inference/route-resolver.d.ts +2 -8
  79. package/dist/inference/route-resolver.d.ts.map +1 -1
  80. package/dist/inference/route-resolver.js +17 -0
  81. package/dist/inference/route-resolver.js.map +1 -1
  82. package/dist/inference/tool-call-utils.d.ts +4 -3
  83. package/dist/inference/tool-call-utils.d.ts.map +1 -1
  84. package/dist/inference/tool-call-utils.js +26 -12
  85. package/dist/inference/tool-call-utils.js.map +1 -1
  86. package/dist/inference/tools.d.ts +1 -0
  87. package/dist/inference/tools.d.ts.map +1 -1
  88. package/dist/inference/tools.js +20 -3
  89. package/dist/inference/tools.js.map +1 -1
  90. package/dist/learning/agentic-route-gate.d.ts +104 -0
  91. package/dist/learning/agentic-route-gate.d.ts.map +1 -0
  92. package/dist/learning/agentic-route-gate.js +125 -0
  93. package/dist/learning/agentic-route-gate.js.map +1 -0
  94. package/dist/learning/auto-router.d.ts +89 -0
  95. package/dist/learning/auto-router.d.ts.map +1 -1
  96. package/dist/learning/auto-router.js +188 -8
  97. package/dist/learning/auto-router.js.map +1 -1
  98. package/dist/learning/build-prerequisites.d.ts +68 -0
  99. package/dist/learning/build-prerequisites.d.ts.map +1 -0
  100. package/dist/learning/build-prerequisites.js +267 -0
  101. package/dist/learning/build-prerequisites.js.map +1 -0
  102. package/dist/learning/continuation-intent.d.ts +43 -0
  103. package/dist/learning/continuation-intent.d.ts.map +1 -0
  104. package/dist/learning/continuation-intent.js +82 -0
  105. package/dist/learning/continuation-intent.js.map +1 -0
  106. package/dist/learning/error-repair.d.ts +23 -1
  107. package/dist/learning/error-repair.d.ts.map +1 -1
  108. package/dist/learning/error-repair.js +58 -0
  109. package/dist/learning/error-repair.js.map +1 -1
  110. package/dist/learning/knowledge-base.d.ts +124 -0
  111. package/dist/learning/knowledge-base.d.ts.map +1 -0
  112. package/dist/learning/knowledge-base.js +337 -0
  113. package/dist/learning/knowledge-base.js.map +1 -0
  114. package/dist/learning/model-harness.d.ts +19 -0
  115. package/dist/learning/model-harness.d.ts.map +1 -1
  116. package/dist/learning/model-harness.js +27 -0
  117. package/dist/learning/model-harness.js.map +1 -1
  118. package/dist/learning/model-selection.d.ts +2 -1
  119. package/dist/learning/model-selection.d.ts.map +1 -1
  120. package/dist/learning/model-selection.js +35 -2
  121. package/dist/learning/model-selection.js.map +1 -1
  122. package/dist/learning/project-docs.d.ts +83 -0
  123. package/dist/learning/project-docs.d.ts.map +1 -0
  124. package/dist/learning/project-docs.js +132 -0
  125. package/dist/learning/project-docs.js.map +1 -0
  126. package/dist/learning/prompt-budget.d.ts +91 -0
  127. package/dist/learning/prompt-budget.d.ts.map +1 -0
  128. package/dist/learning/prompt-budget.js +99 -0
  129. package/dist/learning/prompt-budget.js.map +1 -0
  130. package/dist/learning/quota-ledger.d.ts +13 -0
  131. package/dist/learning/quota-ledger.d.ts.map +1 -1
  132. package/dist/learning/quota-ledger.js +28 -0
  133. package/dist/learning/quota-ledger.js.map +1 -1
  134. package/dist/learning/reasoning-trace.d.ts +55 -2
  135. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  136. package/dist/learning/reasoning-trace.js +48 -0
  137. package/dist/learning/reasoning-trace.js.map +1 -1
  138. package/dist/learning/resilient-call.d.ts.map +1 -1
  139. package/dist/learning/resilient-call.js +16 -3
  140. package/dist/learning/resilient-call.js.map +1 -1
  141. package/dist/learning/routing-history.d.ts +13 -0
  142. package/dist/learning/routing-history.d.ts.map +1 -1
  143. package/dist/learning/routing-history.js.map +1 -1
  144. package/dist/learning/seeded-benchmark.d.ts +14 -0
  145. package/dist/learning/seeded-benchmark.d.ts.map +1 -1
  146. package/dist/learning/seeded-benchmark.js +43 -4
  147. package/dist/learning/seeded-benchmark.js.map +1 -1
  148. package/dist/learning/turn-report.d.ts +78 -0
  149. package/dist/learning/turn-report.d.ts.map +1 -0
  150. package/dist/learning/turn-report.js +140 -0
  151. package/dist/learning/turn-report.js.map +1 -0
  152. package/dist/security/secret-scan.d.ts +156 -0
  153. package/dist/security/secret-scan.d.ts.map +1 -0
  154. package/dist/security/secret-scan.js +525 -0
  155. package/dist/security/secret-scan.js.map +1 -0
  156. package/dist/tools/edit-verification.d.ts +2 -11
  157. package/dist/tools/edit-verification.d.ts.map +1 -1
  158. package/dist/tools/edit-verification.js +33 -1
  159. package/dist/tools/edit-verification.js.map +1 -1
  160. package/dist/tools/loop-skill-hint.d.ts +51 -0
  161. package/dist/tools/loop-skill-hint.d.ts.map +1 -1
  162. package/dist/tools/loop-skill-hint.js +87 -2
  163. package/dist/tools/loop-skill-hint.js.map +1 -1
  164. package/dist/tools/plan-store.d.ts +126 -3
  165. package/dist/tools/plan-store.d.ts.map +1 -1
  166. package/dist/tools/plan-store.js +290 -6
  167. package/dist/tools/plan-store.js.map +1 -1
  168. package/dist/tools/registry.d.ts +20 -1
  169. package/dist/tools/registry.d.ts.map +1 -1
  170. package/dist/tools/registry.js +165 -4
  171. package/dist/tools/registry.js.map +1 -1
  172. package/dist/tools/remediation-ladder.d.ts +91 -0
  173. package/dist/tools/remediation-ladder.d.ts.map +1 -0
  174. package/dist/tools/remediation-ladder.js +308 -0
  175. package/dist/tools/remediation-ladder.js.map +1 -0
  176. package/dist/tools/run-terminal.d.ts.map +1 -1
  177. package/dist/tools/run-terminal.js +60 -2
  178. package/dist/tools/run-terminal.js.map +1 -1
  179. package/dist/tools/skills-hub.d.ts +7 -0
  180. package/dist/tools/skills-hub.d.ts.map +1 -1
  181. package/dist/tools/skills-hub.js +11 -2
  182. package/dist/tools/skills-hub.js.map +1 -1
  183. package/dist/tools/step-artifact.d.ts +35 -0
  184. package/dist/tools/step-artifact.d.ts.map +1 -0
  185. package/dist/tools/step-artifact.js +154 -0
  186. package/dist/tools/step-artifact.js.map +1 -0
  187. package/dist/tools/tool-loop.d.ts +35 -0
  188. package/dist/tools/tool-loop.d.ts.map +1 -1
  189. package/dist/tools/tool-loop.js +284 -9
  190. package/dist/tools/tool-loop.js.map +1 -1
  191. package/dist/tools/toolsets.js +4 -4
  192. package/dist/tools/toolsets.js.map +1 -1
  193. package/dist/tools/worktree.d.ts +11 -2
  194. package/dist/tools/worktree.d.ts.map +1 -1
  195. package/dist/tools/worktree.js +11 -2
  196. package/dist/tools/worktree.js.map +1 -1
  197. package/dist/utils/effect-verification.js +1 -1
  198. package/dist/utils/effect-verification.js.map +1 -1
  199. package/dist/web-dashboard/chat-console.d.ts +21 -1
  200. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  201. package/dist/web-dashboard/chat-console.js +33 -5
  202. package/dist/web-dashboard/chat-console.js.map +1 -1
  203. package/dist/web-dashboard/server.d.ts +29 -0
  204. package/dist/web-dashboard/server.d.ts.map +1 -1
  205. package/dist/web-dashboard/server.js +410 -5
  206. package/dist/web-dashboard/server.js.map +1 -1
  207. package/dist/web-dashboard/src/types.d.ts +137 -0
  208. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  209. package/dist/web-dashboard/workspace-guard.d.ts +7 -0
  210. package/dist/web-dashboard/workspace-guard.d.ts.map +1 -1
  211. package/dist/web-dashboard/workspace-guard.js +70 -0
  212. package/dist/web-dashboard/workspace-guard.js.map +1 -1
  213. package/package.json +4 -1
  214. package/src/web-dashboard/public/assets/index-DhiuR4S2.js +210 -0
  215. package/src/web-dashboard/public/assets/index-DhiuR4S2.js.map +1 -0
  216. package/src/web-dashboard/public/assets/index-tK8Y2qHB.css +1 -0
  217. package/src/web-dashboard/public/index.html +2 -2
  218. package/src/web-dashboard/public/assets/index-BdKf5Xw2.js +0 -207
  219. package/src/web-dashboard/public/assets/index-BdKf5Xw2.js.map +0 -1
  220. package/src/web-dashboard/public/assets/index-C9eBskc9.css +0 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * KnowledgeBase — tag-scoped, vectorized retrieval over a user's own documents.
3
+ *
4
+ * WHY THIS EXISTS. The retrieval engine (`src/learning/retrieval.ts`) vectorizes
5
+ * a REPO for token reduction and keys everything by file path; the tagged memory
6
+ * store (`src/tools/memory-tools.ts`) holds FACTS, not whole documents. Neither
7
+ * answers "I brought my documents, gave them a tag, and I want precise answers
8
+ * scoped to that tag." So a user asking about their own data had exactly one
9
+ * path — re-read the file into context on EVERY turn, which costs the document's
10
+ * tokens repeatedly and is slow on large files.
11
+ *
12
+ * This module pays that cost ONCE. A document is extracted, chunked and embedded
13
+ * a single time under a tag; each later question embeds a short query and
14
+ * retrieves its top-k chunks. The tag is a real scope: each tag gets its own
15
+ * vector namespace (`knowledge-<tag>`), so tags never bleed into each other and
16
+ * a tag can be forgotten without touching anything else.
17
+ *
18
+ * The retrieved chunks are USER DATA; the model supplies the generic half of an
19
+ * answer (and `web-research` supplies the net-based half). `formatKnowledgeContext`
20
+ * labels each chunk with its source file so the model can attribute precisely
21
+ * which part of an answer came from the user's data.
22
+ *
23
+ * Storage: vectors in the existing pluggable VectorStore (one JSON/FAISS file
24
+ * per namespace), a small manifest at `<memory>/knowledge-index.json` for
25
+ * listing/removal. Everything lives in the Nuvira data dir (`~/.nuvira/memory`),
26
+ * never in a repository or package.
27
+ */
28
+ import { DEFAULT_CHUNK_TOKENS, DEFAULT_OVERLAP_TOKENS } from './retrieval.js';
29
+ /** A tag is a sandboxed namespace segment: lowercase alphanumerics + hyphens, with at least one alphanumeric. */
30
+ export declare const KNOWLEDGE_TAG_RE: RegExp;
31
+ /** Namespace prefix — keeps knowledge vectors apart from memory/history/repo. */
32
+ export declare const KNOWLEDGE_NAMESPACE_PREFIX = "knowledge-";
33
+ /** Manifest of tags → documents (listing/removal only; vectors live elsewhere). */
34
+ export declare const KNOWLEDGE_MANIFEST_FILE = "knowledge-index.json";
35
+ /** Default chunks returned per query. */
36
+ export declare const DEFAULT_KNOWLEDGE_TOP_K = 6;
37
+ /** One document recorded under a tag. */
38
+ export interface KnowledgeDocument {
39
+ path: string;
40
+ chunks: number;
41
+ addedAt: number;
42
+ }
43
+ /** Manifest entry for a tag. */
44
+ export interface KnowledgeTagEntry {
45
+ tag: string;
46
+ updatedAt: number;
47
+ chunkCount: number;
48
+ documents: KnowledgeDocument[];
49
+ }
50
+ interface KnowledgeManifest {
51
+ version: number;
52
+ tags: Record<string, KnowledgeTagEntry>;
53
+ }
54
+ /** A retrieval hit scoped to a tag. */
55
+ export interface KnowledgeHit {
56
+ tag: string;
57
+ text: string;
58
+ sourcePath: string;
59
+ chunkIndex: number;
60
+ similarity: number;
61
+ }
62
+ /** Result of an ingest call. */
63
+ export interface IngestResult {
64
+ tag: string;
65
+ files: number;
66
+ chunks: number;
67
+ skipped: Array<{
68
+ path: string;
69
+ reason: string;
70
+ }>;
71
+ }
72
+ /** Options shared by ingest/query. */
73
+ export interface KnowledgeOptions {
74
+ chunkTokens?: number;
75
+ overlapTokens?: number;
76
+ topK?: number;
77
+ /**
78
+ * Embedding function override. Defaults to the local embedder. Injectable so
79
+ * callers (and tests) can supply a deterministic/dummy vectorizer without
80
+ * downloading the ~130 MB model.
81
+ */
82
+ embedFn?: (text: string) => Promise<number[]>;
83
+ }
84
+ /**
85
+ * Normalize a user-supplied tag into the sandboxed form. `Dheeraj_Health_report`
86
+ * → `dheeraj-health-report`. This is deliberately forgiving: a human naming a
87
+ * tag should not have to know the namespace rules, and a tag is not a path.
88
+ */
89
+ export declare function normalizeKnowledgeTag(tag: string): string;
90
+ /** True when a (already-normalized) tag is valid and non-empty. */
91
+ export declare function isValidKnowledgeTag(tag: string): boolean;
92
+ /** The VectorStore namespace for a tag. Assumes a normalized tag. */
93
+ export declare function namespaceForTag(tag: string): string;
94
+ /** Read the tag manifest. Never throws — a missing/corrupt file yields empty. */
95
+ export declare function readKnowledgeManifest(): KnowledgeManifest;
96
+ /** Every tag with its recorded documents/chunk counts (sorted by recency). */
97
+ export declare function listKnowledgeTags(): KnowledgeTagEntry[];
98
+ /** One tag's manifest entry, or null. */
99
+ export declare function getKnowledgeTag(tag: string): KnowledgeTagEntry | null;
100
+ /** Recursively collect files under a path (bounded, ignores build/vendor dirs). */
101
+ export declare function collectKnowledgeFiles(root: string, out?: string[], depth?: number): string[];
102
+ /**
103
+ * Ingest raw text under a tag. Idempotent per `<tag>:<sourcePath>#<i>` chunk id,
104
+ * so re-ingesting a changed document overwrites its chunks rather than
105
+ * duplicating them.
106
+ */
107
+ export declare function ingestKnowledgeText(tag: string, sourcePath: string, text: string, opts?: KnowledgeOptions): Promise<number>;
108
+ /**
109
+ * Ingest one or more files/directories under a tag. Extraction, chunking and
110
+ * embedding happen ONCE here; later questions only embed a short query.
111
+ */
112
+ export declare function ingestKnowledge(tag: string, paths: string[], opts?: KnowledgeOptions): Promise<IngestResult>;
113
+ /** Embed the question and return the tag's top-k chunks. Never throws. */
114
+ export declare function queryKnowledge(tag: string, question: string, opts?: KnowledgeOptions): Promise<KnowledgeHit[]>;
115
+ /** Remove a tag's vectors and manifest entry. Returns true when something was removed. */
116
+ export declare function forgetKnowledgeTag(tag: string): Promise<boolean>;
117
+ /**
118
+ * Render retrieved chunks as context that ATTRIBUTES each part to the user's
119
+ * data. The model can then answer the data half from here and the generic half
120
+ * from its own knowledge / `web-research`, and say which is which.
121
+ */
122
+ export declare function formatKnowledgeContext(tag: string, hits: KnowledgeHit[]): string;
123
+ export { DEFAULT_CHUNK_TOKENS, DEFAULT_OVERLAP_TOKENS };
124
+ //# sourceMappingURL=knowledge-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-base.d.ts","sourceRoot":"","sources":["../../src/learning/knowledge-base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,337 @@
1
+ /**
2
+ * KnowledgeBase — tag-scoped, vectorized retrieval over a user's own documents.
3
+ *
4
+ * WHY THIS EXISTS. The retrieval engine (`src/learning/retrieval.ts`) vectorizes
5
+ * a REPO for token reduction and keys everything by file path; the tagged memory
6
+ * store (`src/tools/memory-tools.ts`) holds FACTS, not whole documents. Neither
7
+ * answers "I brought my documents, gave them a tag, and I want precise answers
8
+ * scoped to that tag." So a user asking about their own data had exactly one
9
+ * path — re-read the file into context on EVERY turn, which costs the document's
10
+ * tokens repeatedly and is slow on large files.
11
+ *
12
+ * This module pays that cost ONCE. A document is extracted, chunked and embedded
13
+ * a single time under a tag; each later question embeds a short query and
14
+ * retrieves its top-k chunks. The tag is a real scope: each tag gets its own
15
+ * vector namespace (`knowledge-<tag>`), so tags never bleed into each other and
16
+ * a tag can be forgotten without touching anything else.
17
+ *
18
+ * The retrieved chunks are USER DATA; the model supplies the generic half of an
19
+ * answer (and `web-research` supplies the net-based half). `formatKnowledgeContext`
20
+ * labels each chunk with its source file so the model can attribute precisely
21
+ * which part of an answer came from the user's data.
22
+ *
23
+ * Storage: vectors in the existing pluggable VectorStore (one JSON/FAISS file
24
+ * per namespace), a small manifest at `<memory>/knowledge-index.json` for
25
+ * listing/removal. Everything lives in the Nuvira data dir (`~/.nuvira/memory`),
26
+ * never in a repository or package.
27
+ */
28
+ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
29
+ import { join, extname, basename } from 'node:path';
30
+ import { envBuff, resolveNuviraHome } from '../config/paths.js';
31
+ import { embed, RETRIEVAL_MODEL } from '../memory/embedder.js';
32
+ import { getVectorStore } from '../memory/vector-store.js';
33
+ import { chunkText, DEFAULT_CHUNK_TOKENS, DEFAULT_OVERLAP_TOKENS } from './retrieval.js';
34
+ import { logger } from '../utils/logger.js';
35
+ // ─── Constants ──────────────────────────────────────────────────────────────
36
+ /** A tag is a sandboxed namespace segment: lowercase alphanumerics + hyphens, with at least one alphanumeric. */
37
+ export const KNOWLEDGE_TAG_RE = /^[a-z0-9-]*[a-z0-9][a-z0-9-]*$/;
38
+ /** Namespace prefix — keeps knowledge vectors apart from memory/history/repo. */
39
+ export const KNOWLEDGE_NAMESPACE_PREFIX = 'knowledge-';
40
+ /** Manifest of tags → documents (listing/removal only; vectors live elsewhere). */
41
+ export const KNOWLEDGE_MANIFEST_FILE = 'knowledge-index.json';
42
+ /** Default chunks returned per query. */
43
+ export const DEFAULT_KNOWLEDGE_TOP_K = 6;
44
+ /** Directories never walked when a tag is pointed at a folder. */
45
+ const IGNORE_DIRS = new Set([
46
+ 'node_modules', '.git', 'dist', 'build', '.next', '.cache', '.venv', 'venv',
47
+ '__pycache__', '.turbo', '.nx', 'coverage', '.idea', '.vscode',
48
+ ]);
49
+ /** Cap a directory walk so a stray `.` cannot index an entire disk. */
50
+ const MAX_FILES_PER_INGEST = 500;
51
+ /** Per-chunk text kept in metadata (matches retrieval.ts's budget). */
52
+ const MAX_EXTRACT_CHARS = 2_000_000;
53
+ // ─── Paths (resolved per call so tests that set NUVIRA_MEMORY_DIR are hermetic) ──
54
+ function memoryDir() {
55
+ return envBuff('MEMORY_DIR') || join(resolveNuviraHome(), 'memory');
56
+ }
57
+ function manifestPath() {
58
+ return join(memoryDir(), KNOWLEDGE_MANIFEST_FILE);
59
+ }
60
+ // ─── Tag handling ───────────────────────────────────────────────────────────
61
+ /**
62
+ * Normalize a user-supplied tag into the sandboxed form. `Dheeraj_Health_report`
63
+ * → `dheeraj-health-report`. This is deliberately forgiving: a human naming a
64
+ * tag should not have to know the namespace rules, and a tag is not a path.
65
+ */
66
+ export function normalizeKnowledgeTag(tag) {
67
+ return tag
68
+ .trim()
69
+ .toLowerCase()
70
+ .replace(/[^a-z0-9]+/g, '-')
71
+ .replace(/^-+|-+$/g, '')
72
+ .replace(/-{2,}/g, '-');
73
+ }
74
+ /** True when a (already-normalized) tag is valid and non-empty. */
75
+ export function isValidKnowledgeTag(tag) {
76
+ return KNOWLEDGE_TAG_RE.test(tag);
77
+ }
78
+ /** The VectorStore namespace for a tag. Assumes a normalized tag. */
79
+ export function namespaceForTag(tag) {
80
+ return `${KNOWLEDGE_NAMESPACE_PREFIX}${tag}`;
81
+ }
82
+ // ─── Manifest ───────────────────────────────────────────────────────────────
83
+ function emptyManifest() {
84
+ return { version: 1, tags: {} };
85
+ }
86
+ /** Read the tag manifest. Never throws — a missing/corrupt file yields empty. */
87
+ export function readKnowledgeManifest() {
88
+ try {
89
+ if (!existsSync(manifestPath()))
90
+ return emptyManifest();
91
+ const data = JSON.parse(readFileSync(manifestPath(), 'utf-8'));
92
+ if (!data || typeof data !== 'object' || typeof data.tags !== 'object')
93
+ return emptyManifest();
94
+ return { version: data.version ?? 1, tags: data.tags ?? {} };
95
+ }
96
+ catch {
97
+ return emptyManifest();
98
+ }
99
+ }
100
+ function writeKnowledgeManifest(manifest) {
101
+ try {
102
+ if (!existsSync(memoryDir()))
103
+ mkdirSync(memoryDir(), { recursive: true });
104
+ writeFileSync(manifestPath(), JSON.stringify(manifest, null, 2), 'utf-8');
105
+ }
106
+ catch {
107
+ // Best-effort — the vectors are the source of truth; the manifest is an index.
108
+ }
109
+ }
110
+ /** Every tag with its recorded documents/chunk counts (sorted by recency). */
111
+ export function listKnowledgeTags() {
112
+ return Object.values(readKnowledgeManifest().tags).sort((a, b) => b.updatedAt - a.updatedAt);
113
+ }
114
+ /** One tag's manifest entry, or null. */
115
+ export function getKnowledgeTag(tag) {
116
+ const normalized = normalizeKnowledgeTag(tag);
117
+ return readKnowledgeManifest().tags[normalized] ?? null;
118
+ }
119
+ // ─── File collection ────────────────────────────────────────────────────────
120
+ /** Recursively collect files under a path (bounded, ignores build/vendor dirs). */
121
+ export function collectKnowledgeFiles(root, out = [], depth = 0) {
122
+ if (out.length >= MAX_FILES_PER_INGEST || depth > 8)
123
+ return out;
124
+ let stat;
125
+ try {
126
+ stat = statSync(root);
127
+ }
128
+ catch {
129
+ return out;
130
+ }
131
+ if (stat.isFile()) {
132
+ out.push(root);
133
+ return out;
134
+ }
135
+ if (!stat.isDirectory())
136
+ return out;
137
+ let entries = [];
138
+ try {
139
+ entries = readdirSync(root);
140
+ }
141
+ catch {
142
+ return out;
143
+ }
144
+ for (const entry of entries) {
145
+ if (out.length >= MAX_FILES_PER_INGEST)
146
+ break;
147
+ if (IGNORE_DIRS.has(entry))
148
+ continue;
149
+ collectKnowledgeFiles(join(root, entry), out, depth + 1);
150
+ }
151
+ return out;
152
+ }
153
+ // ─── Text extraction ────────────────────────────────────────────────────────
154
+ /**
155
+ * Extract a file's text, reusing the `read_extract` manager so PDF/DOCX/XLSX/
156
+ * PPTX and text formats all work (and unsupported ones refuse with a reason
157
+ * instead of silently indexing a container's bytes).
158
+ */
159
+ async function extractFileText(filePath) {
160
+ const ext = extname(filePath).toLowerCase();
161
+ // Plain text-ish formats need no heavy reader — read directly.
162
+ if (['.txt', '.md', '.markdown', '.csv', '.tsv', '.json', '.yaml', '.yml', '.log'].includes(ext)) {
163
+ try {
164
+ const text = readFileSync(filePath, 'utf-8');
165
+ return { ok: true, text: text.length > MAX_EXTRACT_CHARS ? text.slice(0, MAX_EXTRACT_CHARS) : text };
166
+ }
167
+ catch (err) {
168
+ return { ok: false, reason: err instanceof Error ? err.message : String(err) };
169
+ }
170
+ }
171
+ try {
172
+ const { getReadExtractManager } = await import('../tools/read-extract.js');
173
+ const result = await getReadExtractManager().extract(filePath);
174
+ if (!result.success || !result.text) {
175
+ return { ok: false, reason: result.error ?? result.code ?? 'extraction failed' };
176
+ }
177
+ return { ok: true, text: result.text };
178
+ }
179
+ catch (err) {
180
+ return { ok: false, reason: err instanceof Error ? err.message : String(err) };
181
+ }
182
+ }
183
+ // ─── Ingest ─────────────────────────────────────────────────────────────────
184
+ /**
185
+ * Ingest raw text under a tag. Idempotent per `<tag>:<sourcePath>#<i>` chunk id,
186
+ * so re-ingesting a changed document overwrites its chunks rather than
187
+ * duplicating them.
188
+ */
189
+ export async function ingestKnowledgeText(tag, sourcePath, text, opts = {}) {
190
+ const normalized = normalizeKnowledgeTag(tag);
191
+ const chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS;
192
+ const overlapTokens = opts.overlapTokens ?? DEFAULT_OVERLAP_TOKENS;
193
+ const embedFn = opts.embedFn ?? ((t) => embed(t, undefined, false, RETRIEVAL_MODEL));
194
+ const label = `${normalized}:${sourcePath}`;
195
+ const chunks = chunkText(text, label, chunkTokens, overlapTokens);
196
+ const store = getVectorStore(namespaceForTag(normalized));
197
+ for (const chunk of chunks) {
198
+ let vector;
199
+ try {
200
+ vector = await embedFn(chunk.text);
201
+ }
202
+ catch {
203
+ // A failed embed leaves a zero vector (never outranks a real match).
204
+ vector = new Array(384).fill(0);
205
+ }
206
+ await store.insert(chunk.id, vector, {
207
+ kind: 'knowledge-chunk',
208
+ tag: normalized,
209
+ sourcePath,
210
+ chunkIndex: chunk.chunkIndex,
211
+ text: chunk.text,
212
+ tokenCount: chunk.tokenCount,
213
+ });
214
+ }
215
+ return chunks.length;
216
+ }
217
+ /**
218
+ * Ingest one or more files/directories under a tag. Extraction, chunking and
219
+ * embedding happen ONCE here; later questions only embed a short query.
220
+ */
221
+ export async function ingestKnowledge(tag, paths, opts = {}) {
222
+ const normalized = normalizeKnowledgeTag(tag);
223
+ if (!isValidKnowledgeTag(normalized)) {
224
+ throw new Error(`Invalid knowledge tag '${tag}' — it must contain at least one letter or digit.`);
225
+ }
226
+ const result = { tag: normalized, files: 0, chunks: 0, skipped: [] };
227
+ const manifest = readKnowledgeManifest();
228
+ const entry = manifest.tags[normalized] ?? {
229
+ tag: normalized,
230
+ updatedAt: Date.now(),
231
+ chunkCount: 0,
232
+ documents: [],
233
+ };
234
+ // Flatten dirs → files, bounded.
235
+ const files = [];
236
+ for (const p of paths) {
237
+ if (existsSync(p)) {
238
+ collectKnowledgeFiles(p, files);
239
+ }
240
+ else {
241
+ result.skipped.push({ path: p, reason: 'not found' });
242
+ }
243
+ }
244
+ for (const file of files) {
245
+ const extracted = await extractFileText(file);
246
+ if (!extracted.ok) {
247
+ result.skipped.push({ path: file, reason: extracted.reason });
248
+ continue;
249
+ }
250
+ try {
251
+ const chunks = await ingestKnowledgeText(normalized, file, extracted.text, opts);
252
+ result.files += 1;
253
+ result.chunks += chunks;
254
+ // Re-ingesting a changed document replaces its chunks; keep the recorded
255
+ // count in step by subtracting the previous contribution first.
256
+ const previous = entry.documents.find((d) => d.path === file);
257
+ if (previous)
258
+ entry.chunkCount -= previous.chunks;
259
+ entry.documents = entry.documents.filter((d) => d.path !== file);
260
+ entry.documents.push({ path: file, chunks, addedAt: Date.now() });
261
+ entry.chunkCount += chunks;
262
+ }
263
+ catch (err) {
264
+ result.skipped.push({ path: file, reason: err instanceof Error ? err.message : String(err) });
265
+ }
266
+ }
267
+ entry.updatedAt = Date.now();
268
+ manifest.tags[normalized] = entry;
269
+ writeKnowledgeManifest(manifest);
270
+ return result;
271
+ }
272
+ // ─── Query ──────────────────────────────────────────────────────────────────
273
+ /** Embed the question and return the tag's top-k chunks. Never throws. */
274
+ export async function queryKnowledge(tag, question, opts = {}) {
275
+ const normalized = normalizeKnowledgeTag(tag);
276
+ const topK = opts.topK ?? DEFAULT_KNOWLEDGE_TOP_K;
277
+ const embedFn = opts.embedFn ?? ((t) => embed(t, undefined, false, RETRIEVAL_MODEL));
278
+ try {
279
+ const queryVector = await embedFn(question);
280
+ const store = getVectorStore(namespaceForTag(normalized));
281
+ const results = await store.search(queryVector, topK, (entry) => {
282
+ return entry.metadata?.kind === 'knowledge-chunk' && entry.metadata?.tag === normalized;
283
+ });
284
+ return results.map(({ entry, similarity }) => ({
285
+ tag: normalized,
286
+ text: String(entry.metadata?.text ?? ''),
287
+ sourcePath: String(entry.metadata?.sourcePath ?? entry.id),
288
+ chunkIndex: Number(entry.metadata?.chunkIndex ?? 0),
289
+ similarity,
290
+ }));
291
+ }
292
+ catch (err) {
293
+ logger.debug(`Knowledge query failed for tag '${normalized}': ${err instanceof Error ? err.message : err}`);
294
+ return [];
295
+ }
296
+ }
297
+ // ─── Forget ─────────────────────────────────────────────────────────────────
298
+ /** Remove a tag's vectors and manifest entry. Returns true when something was removed. */
299
+ export async function forgetKnowledgeTag(tag) {
300
+ const normalized = normalizeKnowledgeTag(tag);
301
+ const manifest = readKnowledgeManifest();
302
+ const existed = Boolean(manifest.tags[normalized]);
303
+ delete manifest.tags[normalized];
304
+ writeKnowledgeManifest(manifest);
305
+ try {
306
+ await getVectorStore(namespaceForTag(normalized)).clear();
307
+ }
308
+ catch {
309
+ // Best-effort — the manifest entry is already gone.
310
+ }
311
+ return existed;
312
+ }
313
+ // ─── Formatting for the model ───────────────────────────────────────────────
314
+ /**
315
+ * Render retrieved chunks as context that ATTRIBUTES each part to the user's
316
+ * data. The model can then answer the data half from here and the generic half
317
+ * from its own knowledge / `web-research`, and say which is which.
318
+ */
319
+ export function formatKnowledgeContext(tag, hits) {
320
+ const normalized = normalizeKnowledgeTag(tag);
321
+ if (hits.length === 0) {
322
+ return `No entries found for knowledge tag '${normalized}'. Ingest documents first with the knowledge tool (action: add).`;
323
+ }
324
+ const parts = hits.map((h) => {
325
+ const name = basename(h.sourcePath);
326
+ return `--- [from your data: ${name} · chunk ${h.chunkIndex + 1} · sim ${h.similarity.toFixed(3)}] ---\n${h.text}`;
327
+ });
328
+ return [
329
+ `Knowledge tag: ${normalized} (${hits.length} relevant chunk${hits.length === 1 ? '' : 's'} from the user's own data)`,
330
+ 'Treat the following as USER DATA — quote it for facts about the user. For general advice, combine it with your own knowledge and, when current guidance is needed, the web-research tool, and say which part is which.',
331
+ '',
332
+ ...parts,
333
+ ].join('\n');
334
+ }
335
+ // Re-export for tests/callers that want the raw embedding defaults.
336
+ export { DEFAULT_CHUNK_TOKENS, DEFAULT_OVERLAP_TOKENS };
337
+ //# sourceMappingURL=knowledge-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-base.js","sourceRoot":"","sources":["../../src/learning/knowledge-base.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,25 @@ export declare function resolveModelHarnessProfile(input: ModelHarnessInput): Mo
59
59
  * Exported because more than one seam needs the same answer.
60
60
  */
61
61
  export declare function isTinyModel(model: string | undefined): boolean;
62
+ /**
63
+ * May this served model hold an AGENTIC software task?
64
+ *
65
+ * The single predicate behind every agentic capability gate, so the router's
66
+ * ranking floor and its LATER model-first override can never disagree. That
67
+ * divergence was a live bug (2026-10-04): the floor correctly removed a
68
+ * ≤4B local model from the ranking, but the model-first override — which runs
69
+ * afterwards — re-introduced `local/gemma4:e4b` for a Tauri build ask, and chat
70
+ * then fabricated tool output.
71
+ *
72
+ * Deliberately conservative, exactly like the floor it serves:
73
+ * - an UNKNOWN model (`undefined`) is KEPT — never eliminate on ignorance;
74
+ * - a ≤4B tiny tag is always out;
75
+ * - a LOCAL provider whose served id is a placeholder (`default`, `unknown`)
76
+ * is out — we cannot judge local compute with no real tag, and it is the
77
+ * case that carried the failed build. A local 70B (`llama3:70b`) keeps
78
+ * working.
79
+ */
80
+ export declare function isAgenticCapableModel(model: string | undefined, provider: string): boolean;
62
81
  /**
63
82
  * Should this model skip a native tool-calling attempt entirely?
64
83
  *
@@ -1 +1 @@
1
- {"version":3,"file":"model-harness.d.ts","sourceRoot":"","sources":["../../src/learning/model-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,sCAAsC;AACtC,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC3B,wEAAwE;IACxE,SAAS,EAAE,gBAAgB,CAAC;IAC5B,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAClC,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmCD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,GAAG,mBAAmB,CAoCxF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAG9D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAEvE"}
1
+ {"version":3,"file":"model-harness.d.ts","sourceRoot":"","sources":["../../src/learning/model-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,sCAAsC;AACtC,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC3B,wEAAwE;IACxE,SAAS,EAAE,gBAAgB,CAAC;IAC5B,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,cAAc,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAClC,+EAA+E;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmCD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,GAAG,mBAAmB,CAoCxF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAG9D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAK1F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAEvE"}
@@ -100,6 +100,33 @@ export function isTinyModel(model) {
100
100
  const tag = (model ?? '').trim();
101
101
  return TINY_MODEL.test(tag) || TINY_FAMILY.test(tag);
102
102
  }
103
+ /**
104
+ * May this served model hold an AGENTIC software task?
105
+ *
106
+ * The single predicate behind every agentic capability gate, so the router's
107
+ * ranking floor and its LATER model-first override can never disagree. That
108
+ * divergence was a live bug (2026-10-04): the floor correctly removed a
109
+ * ≤4B local model from the ranking, but the model-first override — which runs
110
+ * afterwards — re-introduced `local/gemma4:e4b` for a Tauri build ask, and chat
111
+ * then fabricated tool output.
112
+ *
113
+ * Deliberately conservative, exactly like the floor it serves:
114
+ * - an UNKNOWN model (`undefined`) is KEPT — never eliminate on ignorance;
115
+ * - a ≤4B tiny tag is always out;
116
+ * - a LOCAL provider whose served id is a placeholder (`default`, `unknown`)
117
+ * is out — we cannot judge local compute with no real tag, and it is the
118
+ * case that carried the failed build. A local 70B (`llama3:70b`) keeps
119
+ * working.
120
+ */
121
+ export function isAgenticCapableModel(model, provider) {
122
+ if (model === undefined)
123
+ return true;
124
+ if (isTinyModel(model))
125
+ return false;
126
+ if (provider === 'local' && /^(?:default|unknown)$/i.test(String(model).trim()))
127
+ return false;
128
+ return true;
129
+ }
103
130
  /**
104
131
  * Should this model skip a native tool-calling attempt entirely?
105
132
  *
@@ -1 +1 @@
1
- {"version":3,"file":"model-harness.js","sourceRoot":"","sources":["../../src/learning/model-harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA6BH;;;;;GAKG;AACH,MAAM,UAAU,GAAG,uCAAuC,CAAC;AAE3D,sEAAsE;AACtE,gFAAgF;AAChF,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,WAAW,GAAG,6CAA6C,CAAC;AAElE;;;;GAIG;AACH,MAAM,oBAAoB,GACxB,8MAA8M,CAAC;AAEjN;;;;GAIG;AACH,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAExC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAChC,qFAAqF;AACrF,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAwB;IACjE,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,IAAI,QAAQ,CAAC;IACxD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,cAAc,IAAI,CAAC,MAAM,CAAC;IAEzC,wEAAwE;IACxE,4EAA4E;IAC5E,MAAM,SAAS,GAAqB,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;IAE/D,IAAI,QAAQ,GAAqB,QAAQ,CAAC;IAC1C,IAAI,MAAc,CAAC;IAEnB,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,GAAG,QAAQ,CAAC;QACpB,MAAM,GAAG,eAAe,KAAK,IAAI,SAAS,wBAAwB,SAAS,YAAY,CAAC;IAC1F,CAAC;SAAM,IAAI,cAAc,KAAK,KAAK,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,wBAAwB,EAAE,CAAC;YAC/D,QAAQ,GAAG,KAAK,CAAC;YACjB,MAAM,GAAG,uCAAuC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,UAAU,MAAM,OAAO,wBAAwB,EAAE,EAAE,CAAC;QACnJ,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,QAAQ,CAAC;YACpB,MAAM,GAAG,8CAA8C,MAAM,MAAM,wBAAwB,yCAAyC,CAAC;QACvI,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,oBAAoB,cAAc,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,SAAS,iDAAiD,EAAE,CAAC;IAClI,CAAC;IAED,OAAO;QACL,QAAQ;QACR,SAAS;QACT,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,qBAAqB;QACtE,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjC,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAwB;IAC5D,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"model-harness.js","sourceRoot":"","sources":["../../src/learning/model-harness.ts"],"names":[],"mappings":"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"}
@@ -54,7 +54,8 @@ export declare function hasCredentials(configManager: ConfigManager, provider: s
54
54
  export declare const MODEL_HEALTH_CEILING = 0.6;
55
55
  /**
56
56
  * Verified working models for a provider, ranked by learned health:
57
- * lowest error rate first, then lowest latency, then most recently verified.
57
+ * strongest verification source first, then lowest error rate, then lowest
58
+ * latency, then most recently verified.
58
59
  * Empty when nothing has been verified yet (cold start / no keys).
59
60
  *
60
61
  * MODELS AT/ABOVE `MODEL_HEALTH_CEILING` SORT AFTER THE HEALTHY ONES but are
@@ -1 +1 @@
1
- {"version":3,"file":"model-selection.d.ts","sourceRoot":"","sources":["../../src/learning/model-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAU1D,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,qEAAsE,CAAC;AAErG;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,CAAC;AAMnE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAA6B,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOtF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAuC7D;AAcD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,aAAa,GAAG,cAAc,EAAE,CAiErF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAE3E;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,aAAa,GAC5B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0BjD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxG;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAS1F;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAa5E"}
1
+ {"version":3,"file":"model-selection.d.ts","sourceRoot":"","sources":["../../src/learning/model-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAU1D,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,qEAAsE,CAAC;AAErG;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,CAAC;AAMnE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAA6B,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOtF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAqBxC;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA6C7D;AAcD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,aAAa,GAAG,cAAc,EAAE,CAuErF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAE3E;AAED,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,aAAa,GAC5B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA0BjD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxG;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAS1F;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,CAa5E"}