@pcircle/memesh 4.8.5 → 4.9.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 (226) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/mcp.json +6 -4
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/AGENTS.md +60 -14
  6. package/README.de.md +83 -556
  7. package/README.md +83 -582
  8. package/README.zh-TW.md +84 -573
  9. package/dashboard/dist/index.html +10 -10
  10. package/dist/cli/view-live.d.ts.map +1 -1
  11. package/dist/cli/view-live.js +154 -384
  12. package/dist/cli/view-live.js.map +1 -1
  13. package/dist/core/agent-router.d.ts +11 -10
  14. package/dist/core/agent-router.d.ts.map +1 -1
  15. package/dist/core/agent-router.js +29 -14
  16. package/dist/core/agent-router.js.map +1 -1
  17. package/dist/core/agent-scope-id.d.ts.map +1 -1
  18. package/dist/core/agent-scope-id.js.map +1 -1
  19. package/dist/core/analytics.d.ts.map +1 -1
  20. package/dist/core/analytics.js.map +1 -1
  21. package/dist/core/config.d.ts +4 -40
  22. package/dist/core/config.d.ts.map +1 -1
  23. package/dist/core/config.js +75 -141
  24. package/dist/core/config.js.map +1 -1
  25. package/dist/core/demo.d.ts.map +1 -1
  26. package/dist/core/demo.js +6 -6
  27. package/dist/core/demo.js.map +1 -1
  28. package/dist/core/doctor.d.ts +1 -6
  29. package/dist/core/doctor.d.ts.map +1 -1
  30. package/dist/core/doctor.js +55 -227
  31. package/dist/core/doctor.js.map +1 -1
  32. package/dist/core/dreamer.d.ts +32 -47
  33. package/dist/core/dreamer.d.ts.map +1 -1
  34. package/dist/core/dreamer.js +211 -703
  35. package/dist/core/dreamer.js.map +1 -1
  36. package/dist/core/install-channel.d.ts.map +1 -1
  37. package/dist/core/install-channel.js +4 -47
  38. package/dist/core/install-channel.js.map +1 -1
  39. package/dist/core/install-id.d.ts.map +1 -1
  40. package/dist/core/install-id.js.map +1 -1
  41. package/dist/core/kg-backfill.d.ts.map +1 -1
  42. package/dist/core/kg-backfill.js.map +1 -1
  43. package/dist/core/lesson-engine.d.ts +0 -5
  44. package/dist/core/lesson-engine.d.ts.map +1 -1
  45. package/dist/core/lesson-engine.js +0 -25
  46. package/dist/core/lesson-engine.js.map +1 -1
  47. package/dist/core/lifecycle.d.ts.map +1 -1
  48. package/dist/core/lifecycle.js +54 -48
  49. package/dist/core/lifecycle.js.map +1 -1
  50. package/dist/core/memory-tool.d.ts.map +1 -1
  51. package/dist/core/memory-tool.js +17 -17
  52. package/dist/core/memory-tool.js.map +1 -1
  53. package/dist/core/operations.d.ts +2 -26
  54. package/dist/core/operations.d.ts.map +1 -1
  55. package/dist/core/operations.js +9 -244
  56. package/dist/core/operations.js.map +1 -1
  57. package/dist/core/paths.d.ts +4 -1
  58. package/dist/core/paths.d.ts.map +1 -1
  59. package/dist/core/paths.js +88 -14
  60. package/dist/core/paths.js.map +1 -1
  61. package/dist/core/product-improvements.js +2 -2
  62. package/dist/core/product-improvements.js.map +1 -1
  63. package/dist/core/schema-export.d.ts.map +1 -1
  64. package/dist/core/schema-export.js +10 -0
  65. package/dist/core/schema-export.js.map +1 -1
  66. package/dist/core/semver.d.ts +7 -0
  67. package/dist/core/semver.d.ts.map +1 -0
  68. package/dist/core/semver.js +49 -0
  69. package/dist/core/semver.js.map +1 -0
  70. package/dist/core/serializer.d.ts.map +1 -1
  71. package/dist/core/serializer.js +69 -57
  72. package/dist/core/serializer.js.map +1 -1
  73. package/dist/core/signal-scorer.d.ts.map +1 -1
  74. package/dist/core/signal-scorer.js.map +1 -1
  75. package/dist/core/transcript-extractor.d.ts +1 -85
  76. package/dist/core/transcript-extractor.d.ts.map +1 -1
  77. package/dist/core/transcript-extractor.js +5 -364
  78. package/dist/core/transcript-extractor.js.map +1 -1
  79. package/dist/core/transcript-source.d.ts +22 -6
  80. package/dist/core/transcript-source.d.ts.map +1 -1
  81. package/dist/core/transcript-source.js +108 -69
  82. package/dist/core/transcript-source.js.map +1 -1
  83. package/dist/core/types.d.ts +1 -17
  84. package/dist/core/types.d.ts.map +1 -1
  85. package/dist/core/version-check.d.ts.map +1 -1
  86. package/dist/core/version-check.js +11 -1
  87. package/dist/core/version-check.js.map +1 -1
  88. package/dist/db.d.ts +0 -34
  89. package/dist/db.d.ts.map +1 -1
  90. package/dist/db.js +3 -287
  91. package/dist/db.js.map +1 -1
  92. package/dist/host-runtime/acp.d.ts.map +1 -1
  93. package/dist/host-runtime/acp.js +2 -2
  94. package/dist/host-runtime/acp.js.map +1 -1
  95. package/dist/host-runtime/claude.d.ts.map +1 -1
  96. package/dist/host-runtime/claude.js +9 -7
  97. package/dist/host-runtime/claude.js.map +1 -1
  98. package/dist/host-runtime/codex-session.d.ts +9 -1
  99. package/dist/host-runtime/codex-session.d.ts.map +1 -1
  100. package/dist/host-runtime/codex-session.js +474 -29
  101. package/dist/host-runtime/codex-session.js.map +1 -1
  102. package/dist/host-runtime/codex.d.ts.map +1 -1
  103. package/dist/host-runtime/codex.js +2 -2
  104. package/dist/host-runtime/codex.js.map +1 -1
  105. package/dist/host-runtime/config.d.ts +1 -0
  106. package/dist/host-runtime/config.d.ts.map +1 -1
  107. package/dist/host-runtime/config.js +4 -0
  108. package/dist/host-runtime/config.js.map +1 -1
  109. package/dist/host-runtime/router-client.d.ts.map +1 -1
  110. package/dist/host-runtime/router-client.js +62 -15
  111. package/dist/host-runtime/router-client.js.map +1 -1
  112. package/dist/host-runtime/router.js +2 -2
  113. package/dist/host-runtime/router.js.map +1 -1
  114. package/dist/knowledge-graph.d.ts.map +1 -1
  115. package/dist/knowledge-graph.js +54 -45
  116. package/dist/knowledge-graph.js.map +1 -1
  117. package/dist/mcp/THIRD_PARTY_NOTICES.txt +217 -0
  118. package/dist/mcp/server.js +30685 -38
  119. package/dist/mcp/server.js.map +6 -1
  120. package/dist/skills-manifest.json +22 -22
  121. package/dist/storage/entity-index.d.ts +0 -1
  122. package/dist/storage/entity-index.d.ts.map +1 -1
  123. package/dist/storage/entity-index.js +0 -7
  124. package/dist/storage/entity-index.js.map +1 -1
  125. package/dist/storage/fts-index.d.ts.map +1 -1
  126. package/dist/storage/fts-index.js +6 -7
  127. package/dist/storage/fts-index.js.map +1 -1
  128. package/dist/storage/graph-repairs.d.ts +0 -5
  129. package/dist/storage/graph-repairs.d.ts.map +1 -1
  130. package/dist/storage/graph-repairs.js +4 -91
  131. package/dist/storage/graph-repairs.js.map +1 -1
  132. package/dist/storage/schema.d.ts +1 -1
  133. package/dist/storage/schema.d.ts.map +1 -1
  134. package/dist/storage/schema.js +1 -2
  135. package/dist/storage/schema.js.map +1 -1
  136. package/dist/storage/sqlite.d.ts +0 -1
  137. package/dist/storage/sqlite.d.ts.map +1 -1
  138. package/dist/storage/sqlite.js.map +1 -1
  139. package/dist/transports/agent-messaging.d.ts.map +1 -1
  140. package/dist/transports/agent-messaging.js +5 -7
  141. package/dist/transports/agent-messaging.js.map +1 -1
  142. package/dist/transports/cli/cli.d.ts.map +1 -1
  143. package/dist/transports/cli/cli.js +52 -674
  144. package/dist/transports/cli/cli.js.map +1 -1
  145. package/dist/transports/http/retired-routes.js +1 -1
  146. package/dist/transports/http/retired-routes.js.map +1 -1
  147. package/dist/transports/http/server.d.ts.map +1 -1
  148. package/dist/transports/http/server.js +13 -232
  149. package/dist/transports/http/server.js.map +1 -1
  150. package/dist/transports/mcp/handlers.d.ts +127 -1
  151. package/dist/transports/mcp/handlers.d.ts.map +1 -1
  152. package/dist/transports/mcp/handlers.js +53 -4
  153. package/dist/transports/mcp/handlers.js.map +1 -1
  154. package/dist/transports/schemas.d.ts +52 -0
  155. package/dist/transports/schemas.d.ts.map +1 -1
  156. package/dist/transports/schemas.js +39 -0
  157. package/dist/transports/schemas.js.map +1 -1
  158. package/docs/platforms/README.md +5 -4
  159. package/docs/platforms/agent-messaging.md +124 -60
  160. package/hooks/hooks.json +13 -2
  161. package/llms-install.md +62 -30
  162. package/package.json +4 -5
  163. package/scripts/hooks/_generated/core-paths.js +88 -14
  164. package/scripts/hooks/_generated/fts-index.js +6 -7
  165. package/scripts/hooks/_generated/schema.js +1 -2
  166. package/scripts/hooks/_shared.js +14 -20
  167. package/scripts/hooks/session-start.js +8 -6
  168. package/scripts/hooks/session-summary.js +19 -374
  169. package/skills/memesh/SKILL.md +19 -14
  170. package/skills/memesh-review/SKILL.md +7 -6
  171. package/dist/core/auto-tagger.d.ts +0 -10
  172. package/dist/core/auto-tagger.d.ts.map +0 -1
  173. package/dist/core/auto-tagger.js +0 -63
  174. package/dist/core/auto-tagger.js.map +0 -1
  175. package/dist/core/conflict-candidates.d.ts +0 -20
  176. package/dist/core/conflict-candidates.d.ts.map +0 -1
  177. package/dist/core/conflict-candidates.js +0 -71
  178. package/dist/core/conflict-candidates.js.map +0 -1
  179. package/dist/core/conflict-judge.d.ts +0 -58
  180. package/dist/core/conflict-judge.d.ts.map +0 -1
  181. package/dist/core/conflict-judge.js +0 -189
  182. package/dist/core/conflict-judge.js.map +0 -1
  183. package/dist/core/digest-validator.d.ts +0 -18
  184. package/dist/core/digest-validator.d.ts.map +0 -1
  185. package/dist/core/digest-validator.js +0 -85
  186. package/dist/core/digest-validator.js.map +0 -1
  187. package/dist/core/embedder.d.ts +0 -20
  188. package/dist/core/embedder.d.ts.map +0 -1
  189. package/dist/core/embedder.js +0 -245
  190. package/dist/core/embedder.js.map +0 -1
  191. package/dist/core/failure-analyzer.d.ts +0 -19
  192. package/dist/core/failure-analyzer.d.ts.map +0 -1
  193. package/dist/core/failure-analyzer.js +0 -83
  194. package/dist/core/failure-analyzer.js.map +0 -1
  195. package/dist/core/json-utils.d.ts +0 -3
  196. package/dist/core/json-utils.d.ts.map +0 -1
  197. package/dist/core/json-utils.js +0 -46
  198. package/dist/core/json-utils.js.map +0 -1
  199. package/dist/core/llm-client.d.ts +0 -22
  200. package/dist/core/llm-client.d.ts.map +0 -1
  201. package/dist/core/llm-client.js +0 -203
  202. package/dist/core/llm-client.js.map +0 -1
  203. package/dist/core/llm-telemetry.d.ts +0 -47
  204. package/dist/core/llm-telemetry.d.ts.map +0 -1
  205. package/dist/core/llm-telemetry.js +0 -117
  206. package/dist/core/llm-telemetry.js.map +0 -1
  207. package/dist/core/llm-validator.d.ts +0 -20
  208. package/dist/core/llm-validator.d.ts.map +0 -1
  209. package/dist/core/llm-validator.js +0 -231
  210. package/dist/core/llm-validator.js.map +0 -1
  211. package/dist/core/ollama-host.d.ts +0 -6
  212. package/dist/core/ollama-host.d.ts.map +0 -1
  213. package/dist/core/ollama-host.js +0 -62
  214. package/dist/core/ollama-host.js.map +0 -1
  215. package/dist/core/output-language.d.ts +0 -6
  216. package/dist/core/output-language.d.ts.map +0 -1
  217. package/dist/core/output-language.js +0 -25
  218. package/dist/core/output-language.js.map +0 -1
  219. package/dist/core/prompt-safety.d.ts +0 -4
  220. package/dist/core/prompt-safety.d.ts.map +0 -1
  221. package/dist/core/prompt-safety.js +0 -20
  222. package/dist/core/prompt-safety.js.map +0 -1
  223. package/dist/storage/vector-index.d.ts +0 -3
  224. package/dist/storage/vector-index.d.ts.map +0 -1
  225. package/dist/storage/vector-index.js +0 -13
  226. package/dist/storage/vector-index.js.map +0 -1
@@ -1,203 +0,0 @@
1
- import { redactSecrets } from './paths.js';
2
- import { resolveOllamaHost, UnsafeOllamaHostError } from './ollama-host.js';
3
- export class LLMResponseParseError extends Error {
4
- constructor(provider, detail) {
5
- super(`${provider}: response parse failed — ${detail}`);
6
- this.name = 'LLMResponseParseError';
7
- }
8
- }
9
- export async function callLLM(prompt, config, opts = {}) {
10
- const chain = [config, ...(opts.fallbacks ?? [])];
11
- const attempts = [];
12
- const reportAttempts = () => {
13
- if (!opts.onAttempt)
14
- return;
15
- try {
16
- opts.onAttempt(attempts);
17
- }
18
- catch { }
19
- };
20
- let lastErr = null;
21
- for (let i = 0; i < chain.length; i++) {
22
- const cfg = chain[i];
23
- const t0 = Date.now();
24
- try {
25
- const text = await callSingle(prompt, cfg, opts.maxTokens ?? 200);
26
- attempts.push({
27
- provider: cfg.provider, model: cfg.model,
28
- status: 'ok', latencyMs: Date.now() - t0, index: i,
29
- });
30
- reportAttempts();
31
- return text;
32
- }
33
- catch (err) {
34
- const e = err instanceof Error ? err : new Error(String(err));
35
- const klass = classifyError(e);
36
- attempts.push({
37
- provider: cfg.provider, model: cfg.model,
38
- status: 'fail', latencyMs: Date.now() - t0,
39
- errorClass: klass, errorMessage: redactSecrets(e.message), index: i,
40
- });
41
- lastErr = e;
42
- if (klass === 'bad_request')
43
- break;
44
- }
45
- }
46
- reportAttempts();
47
- throw lastErr ?? new Error('callLLM: no providers configured');
48
- }
49
- const REQUEST_TIMEOUT_MS = 30_000;
50
- function fetchWithTimeout(url, init) {
51
- return fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
52
- }
53
- async function callSingle(prompt, config, maxTokens) {
54
- if (config.provider === 'anthropic') {
55
- const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
56
- if (!apiKey)
57
- throw new Error('Anthropic: no API key configured');
58
- const res = await fetchWithTimeout('https://api.anthropic.com/v1/messages', {
59
- method: 'POST',
60
- headers: {
61
- 'x-api-key': apiKey,
62
- 'anthropic-version': '2023-06-01',
63
- 'content-type': 'application/json',
64
- },
65
- body: JSON.stringify({
66
- model: config.model || 'claude-haiku-4-5',
67
- max_tokens: maxTokens,
68
- messages: [{ role: 'user', content: prompt }],
69
- }),
70
- });
71
- if (!res.ok)
72
- throw new Error(`Anthropic API error: ${res.status}`);
73
- const data = await readJsonOrThrow(res, 'anthropic');
74
- const text = extractAnthropicText(data);
75
- if (text == null) {
76
- throw new LLMResponseParseError('anthropic', `missing content[0].text in ${describeShape(data)}`);
77
- }
78
- return text;
79
- }
80
- if (config.provider === 'openai') {
81
- const apiKey = config.apiKey || process.env.OPENAI_API_KEY;
82
- if (!apiKey)
83
- throw new Error('OpenAI: no API key configured');
84
- const res = await fetchWithTimeout('https://api.openai.com/v1/chat/completions', {
85
- method: 'POST',
86
- headers: {
87
- 'Authorization': `Bearer ${apiKey}`,
88
- 'Content-Type': 'application/json',
89
- },
90
- body: JSON.stringify({
91
- model: config.model || 'gpt-4o-mini',
92
- max_tokens: maxTokens,
93
- messages: [{ role: 'user', content: prompt }],
94
- }),
95
- });
96
- if (!res.ok)
97
- throw new Error(`OpenAI API error: ${res.status}`);
98
- const data = await readJsonOrThrow(res, 'openai');
99
- const text = extractOpenAIText(data);
100
- if (text == null) {
101
- throw new LLMResponseParseError('openai', `missing choices[0].message.content in ${describeShape(data)}`);
102
- }
103
- return text;
104
- }
105
- if (config.provider === 'ollama') {
106
- const host = resolveOllamaHost(config.host);
107
- const res = await fetchWithTimeout(`${host}/api/generate`, {
108
- method: 'POST',
109
- headers: { 'Content-Type': 'application/json' },
110
- body: JSON.stringify({
111
- model: config.model || 'llama3.2',
112
- prompt,
113
- stream: false,
114
- }),
115
- });
116
- if (!res.ok)
117
- throw new Error(`Ollama error: ${res.status}`);
118
- const data = await readJsonOrThrow(res, 'ollama');
119
- const text = extractOllamaText(data);
120
- if (text == null) {
121
- throw new LLMResponseParseError('ollama', `missing response field in ${describeShape(data)}`);
122
- }
123
- return text;
124
- }
125
- throw new Error(`No LLM provider configured (llm.provider is ${config.provider === undefined ? 'unset' : `"${String(config.provider)}"`}). ` +
126
- 'Set one with `memesh config set llm.provider <anthropic|openai|ollama>`.');
127
- }
128
- async function readJsonOrThrow(res, provider) {
129
- try {
130
- return await res.json();
131
- }
132
- catch (err) {
133
- const msg = err instanceof Error ? err.message : String(err);
134
- throw new LLMResponseParseError(provider, `body is not valid JSON (${msg})`);
135
- }
136
- }
137
- function extractAnthropicText(data) {
138
- if (!isObject(data))
139
- return null;
140
- const content = data.content;
141
- if (!Array.isArray(content) || content.length === 0)
142
- return null;
143
- const first = content[0];
144
- if (!isObject(first))
145
- return null;
146
- const text = first.text;
147
- return typeof text === 'string' ? text : null;
148
- }
149
- function extractOpenAIText(data) {
150
- if (!isObject(data))
151
- return null;
152
- const choices = data.choices;
153
- if (!Array.isArray(choices) || choices.length === 0)
154
- return null;
155
- const first = choices[0];
156
- if (!isObject(first))
157
- return null;
158
- const message = first.message;
159
- if (!isObject(message))
160
- return null;
161
- const content = message.content;
162
- return typeof content === 'string' ? content : null;
163
- }
164
- function extractOllamaText(data) {
165
- if (!isObject(data))
166
- return null;
167
- const response = data.response;
168
- return typeof response === 'string' ? response : null;
169
- }
170
- function isObject(v) {
171
- return typeof v === 'object' && v !== null;
172
- }
173
- function describeShape(v) {
174
- if (v == null)
175
- return String(v);
176
- if (Array.isArray(v))
177
- return `array(len=${v.length})`;
178
- if (typeof v !== 'object')
179
- return typeof v;
180
- const keyCount = Object.keys(v).length;
181
- return `object(${keyCount}-keys)`;
182
- }
183
- export function classifyError(e) {
184
- if (e instanceof UnsafeOllamaHostError)
185
- return 'bad_request';
186
- if (e instanceof LLMResponseParseError)
187
- return 'parse';
188
- const msg = e.message;
189
- if (/\b(401|403|invalid_api_key|authentication|x-api-key|unauthorized)\b/i.test(msg))
190
- return 'auth';
191
- if (/no API key/i.test(msg))
192
- return 'auth';
193
- if (/\b(429|rate.?limit|quota)\b/i.test(msg))
194
- return 'rate_limit';
195
- if (/\b(50[023]|service unavailable|bad gateway)\b/i.test(msg))
196
- return 'upstream';
197
- if (/\b400\b/.test(msg))
198
- return 'bad_request';
199
- if (/(ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|fetch failed|aborted)/i.test(msg))
200
- return 'network';
201
- return 'unknown';
202
- }
203
- //# sourceMappingURL=llm-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-client.js","sourceRoot":"","sources":["../../src/core/llm-client.ts"],"names":[],"mappings":"AA2CA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAkB5E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,QAA+B,EAAE,MAAc;QACzD,KAAK,CAAC,GAAG,QAAQ,6BAA6B,MAAM,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAqDD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAc,EACd,MAAiB,EACjB,OAAuB,EAAE;IAEzB,MAAM,KAAK,GAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC;YAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAyC,CAAC;IACrF,CAAC,CAAC;IAEF,IAAI,OAAO,GAAiB,IAAI,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC;YAClE,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK;gBACxC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC;aACnD,CAAC,CAAC;YACH,cAAc,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK;gBACxC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE;gBAC1C,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;aACpE,CAAC,CAAC;YACH,OAAO,GAAG,CAAC,CAAC;YAGZ,IAAI,KAAK,KAAK,aAAa;gBAAE,MAAM;QACrC,CAAC;IACH,CAAC;IAED,cAAc,EAAE,CAAC;IACjB,MAAM,OAAO,IAAI,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACjE,CAAC;AAmBD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAUlC,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAiB;IACtD,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAGD,KAAK,UAAU,UAAU,CACvB,MAAc,EACd,MAAiB,EACjB,SAAiB;IAEjB,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC9D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,uCAAuC,EAAE;YAC1E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,WAAW,EAAE,MAAM;gBACnB,mBAAmB,EAAE,YAAY;gBACjC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,kBAAkB;gBACzC,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,qBAAqB,CAAC,WAAW,EAAE,8BAA8B,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,4CAA4C,EAAE;YAC/E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,MAAM,EAAE;gBACnC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,aAAa;gBACpC,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,yCAAyC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,GAAG,IAAI,eAAe,EAAE;YACzD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,UAAU;gBACjC,MAAM;gBACN,MAAM,EAAE,KAAK;aAKd,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,6BAA6B,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAUD,MAAM,IAAI,KAAK,CACb,+CAA+C,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,KAAK;QAC5H,0EAA0E,CAC3E,CAAC;AACJ,CAAC;AAoBD,KAAK,UAAU,eAAe,CAAC,GAAa,EAAE,QAA+B;IAC3E,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,GAAG,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAa;IACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,OAAO,GAAI,IAA0B,CAAC,OAAO,CAAC;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,IAAI,GAAI,KAA4B,CAAC,IAAI,CAAC;IAChD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAa;IACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,OAAO,GAAI,IAAuB,CAAC,OAAO,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,OAAO,GAAI,KAA+B,CAAC,OAAO,CAAC;IACzD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,OAAO,GAAI,OAAiC,CAAC,OAAO,CAAC;IAC3D,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAa;IACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,QAAQ,GAAI,IAAuB,CAAC,QAAQ,CAAC;IACnD,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC;AAC7C,CAAC;AAUD,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC;IACtD,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAA4B,CAAC,CAAC,MAAM,CAAC;IAClE,OAAO,UAAU,QAAQ,QAAQ,CAAC;AACpC,CAAC;AASD,MAAM,UAAU,aAAa,CAAC,CAAQ;IAIpC,IAAI,CAAC,YAAY,qBAAqB;QAAE,OAAO,aAAa,CAAC;IAG7D,IAAI,CAAC,YAAY,qBAAqB;QAAE,OAAO,OAAO,CAAC;IACvD,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC;IAEtB,IAAI,sEAAsE,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAEpG,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAE3C,IAAI,8BAA8B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IAElE,IAAI,gDAAgD,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAGlF,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,aAAa,CAAC;IAE9C,IAAI,qEAAqE,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACtG,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1,47 +0,0 @@
1
- import type { MemeshDatabase } from '../storage/sqlite.js';
2
- import type { LLMAttempt } from './llm-client.js';
3
- export interface RecordTelemetryOpts {
4
- flow: string;
5
- project?: string;
6
- db?: MemeshDatabase;
7
- }
8
- export declare function recordTelemetry(attempts: LLMAttempt[], opts: RecordTelemetryOpts): void;
9
- export interface TelemetrySummary {
10
- flow: string;
11
- total_calls: number;
12
- total_attempts: number;
13
- successes: number;
14
- failures: number;
15
- fallback_used: number;
16
- median_latency_ms: number | null;
17
- by_provider: Record<string, {
18
- ok: number;
19
- fail: number;
20
- }>;
21
- by_model: Record<string, {
22
- ok: number;
23
- fail: number;
24
- }>;
25
- by_project: Record<string, {
26
- ok: number;
27
- fail: number;
28
- }>;
29
- by_error_class: Record<string, number>;
30
- sample_errors: Array<{
31
- error_class: string | null;
32
- message: string;
33
- }>;
34
- window_days: number;
35
- }
36
- export declare function summariseTelemetry(windowDays?: number, db?: MemeshDatabase): TelemetrySummary[];
37
- export interface PruneOptions {
38
- olderThanDays?: number;
39
- db?: MemeshDatabase;
40
- }
41
- export interface PruneResult {
42
- deletedRows: number;
43
- cutoffIso: string;
44
- totalRowsAfter: number;
45
- }
46
- export declare function pruneTelemetry(opts?: PruneOptions): PruneResult;
47
- //# sourceMappingURL=llm-telemetry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-telemetry.d.ts","sourceRoot":"","sources":["../../src/core/llm-telemetry.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,WAAW,mBAAmB;IAElC,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,EAAE,CAAC,EAAE,cAAc,CAAC;CACrB;AAcD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,mBAAmB,GAAG,IAAI,CA2CvF;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAK1D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAKvD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAMvC,aAAa,EAAE,KAAK,CAAC;QAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,WAAW,EAAE,MAAM,CAAC;CACrB;AAWD,wBAAgB,kBAAkB,CAAC,UAAU,SAAK,EAAE,EAAE,CAAC,EAAE,cAAc,GAAG,gBAAgB,EAAE,CA2F3F;AAED,MAAM,WAAW,YAAY;IAE3B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,EAAE,CAAC,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAaD,wBAAgB,cAAc,CAAC,IAAI,GAAE,YAAiB,GAAG,WAAW,CAsBnE"}
@@ -1,117 +0,0 @@
1
- import { getDatabase } from '../db.js';
2
- export function recordTelemetry(attempts, opts) {
3
- if (!attempts || attempts.length === 0)
4
- return;
5
- let db;
6
- try {
7
- db = opts.db ?? getDatabase();
8
- }
9
- catch {
10
- return;
11
- }
12
- const stmt = db.prepare(`
13
- INSERT INTO llm_telemetry (
14
- flow, provider, model, project, attempt_index, status,
15
- latency_ms, error_class, error_message, fallback_used
16
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
17
- `);
18
- const tx = db.transaction((rows) => {
19
- for (const a of rows) {
20
- try {
21
- stmt.run(opts.flow, a.provider, a.model ?? null, opts.project ?? null, a.index, a.status, a.latencyMs, a.errorClass ?? null, a.errorMessage ?? null, a.index > 0 ? 1 : 0);
22
- }
23
- catch {
24
- }
25
- }
26
- });
27
- try {
28
- tx(attempts);
29
- }
30
- catch { }
31
- }
32
- const MAX_SAMPLE_ERRORS = 5;
33
- export function summariseTelemetry(windowDays = 30, db) {
34
- const conn = db ?? getDatabase();
35
- const since = new Date(Date.now() - windowDays * 86400000).toISOString();
36
- const rows = conn.prepare(`
37
- SELECT flow, provider, model, project, status, latency_ms, error_class, error_message, attempt_index, fallback_used
38
- FROM llm_telemetry
39
- -- The mirror image of the prune's bug: with a raw ISO parameter, every
40
- -- row from the window's first day compared as BELOW the cutoff and was
41
- -- dropped from the scorecard. Same normalisation, same reason.
42
- WHERE ts >= datetime(?)
43
- ORDER BY ts ASC
44
- `).all(since);
45
- const byFlow = new Map();
46
- for (const r of rows) {
47
- let bucket = byFlow.get(r.flow);
48
- if (!bucket) {
49
- bucket = { attempts: [], primaryAttempts: 0 };
50
- byFlow.set(r.flow, bucket);
51
- }
52
- bucket.attempts.push(r);
53
- if (r.attempt_index === 0)
54
- bucket.primaryAttempts++;
55
- }
56
- const out = [];
57
- for (const [flow, bucket] of byFlow) {
58
- const successes = bucket.attempts.filter(a => a.status === 'ok').length;
59
- const failures = bucket.attempts.filter(a => a.status === 'fail').length;
60
- const fallbackUsed = bucket.attempts.filter(a => a.fallback_used === 1).length;
61
- const okLatencies = bucket.attempts.filter(a => a.status === 'ok' && a.latency_ms != null).map(a => a.latency_ms).sort((a, b) => a - b);
62
- const median = okLatencies.length === 0 ? null : okLatencies[Math.floor(okLatencies.length / 2)];
63
- const byProvider = {};
64
- const byModel = {};
65
- const byProject = {};
66
- const bump = (rec, key, slot) => {
67
- (rec[key] ??= { ok: 0, fail: 0 })[slot]++;
68
- };
69
- for (const a of bucket.attempts) {
70
- const slot = a.status === 'ok' ? 'ok' : 'fail';
71
- bump(byProvider, a.provider, slot);
72
- bump(byModel, a.model ?? 'unknown', slot);
73
- bump(byProject, a.project ?? '_unscoped', slot);
74
- }
75
- const byErrorClass = {};
76
- for (const a of bucket.attempts) {
77
- if (a.error_class)
78
- byErrorClass[a.error_class] = (byErrorClass[a.error_class] ?? 0) + 1;
79
- }
80
- const sampleErrors = [];
81
- for (let i = bucket.attempts.length - 1; i >= 0 && sampleErrors.length < MAX_SAMPLE_ERRORS; i--) {
82
- const a = bucket.attempts[i];
83
- if (a.status === 'fail' && a.error_message) {
84
- sampleErrors.push({ error_class: a.error_class, message: a.error_message });
85
- }
86
- }
87
- out.push({
88
- flow,
89
- total_calls: bucket.primaryAttempts,
90
- total_attempts: bucket.attempts.length,
91
- successes,
92
- failures,
93
- fallback_used: fallbackUsed,
94
- median_latency_ms: median,
95
- by_provider: byProvider,
96
- by_model: byModel,
97
- by_project: byProject,
98
- by_error_class: byErrorClass,
99
- sample_errors: sampleErrors,
100
- window_days: windowDays,
101
- });
102
- }
103
- return out.sort((a, b) => b.total_attempts - a.total_attempts);
104
- }
105
- export function pruneTelemetry(opts = {}) {
106
- const olderThanDays = opts.olderThanDays ?? 180;
107
- const db = opts.db ?? getDatabase();
108
- const cutoffIso = new Date(Date.now() - olderThanDays * 86400000).toISOString();
109
- const result = db.prepare('DELETE FROM llm_telemetry WHERE ts < datetime(?)').run(cutoffIso);
110
- const totalRowsAfter = db.prepare('SELECT COUNT(*) AS c FROM llm_telemetry').get().c;
111
- return {
112
- deletedRows: Number(result.changes),
113
- cutoffIso,
114
- totalRowsAfter,
115
- };
116
- }
117
- //# sourceMappingURL=llm-telemetry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-telemetry.js","sourceRoot":"","sources":["../../src/core/llm-telemetry.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- export interface ModelInfo {
2
- id: string;
3
- created?: string;
4
- }
5
- export interface ValidationResult {
6
- valid: boolean;
7
- error?: string;
8
- errorCode?: string;
9
- models?: ModelInfo[];
10
- suggested?: string;
11
- catalogVerified?: boolean;
12
- inferenceVerified?: boolean;
13
- testedModel?: string;
14
- }
15
- export declare function pickSuggestedModel(models: ModelInfo[]): string | undefined;
16
- export declare function probeAnthropic(apiKey: string): Promise<ValidationResult>;
17
- export declare function probeOpenAI(apiKey: string): Promise<ValidationResult>;
18
- export declare function probeOllama(host?: string): Promise<ValidationResult>;
19
- export declare function probeProvider(provider: 'anthropic' | 'openai' | 'ollama', apiKey?: string, host?: string, model?: string): Promise<ValidationResult>;
20
- //# sourceMappingURL=llm-validator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"llm-validator.d.ts","sourceRoot":"","sources":["../../src/core/llm-validator.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IAEX,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IAaf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA+ID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,GAAG,SAAS,CAc1E;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8B9E;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6B3E;AAED,wBAAsB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqC1E;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,EAC3C,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC,CAyC3B"}
@@ -1,231 +0,0 @@
1
- import { callLLM } from './llm-client.js';
2
- import { resolveOllamaHost, UNSAFE_OLLAMA_HOST_ERROR } from './ollama-host.js';
3
- import { redactSecrets } from './paths.js';
4
- import { sanitizeForPrompt } from './prompt-safety.js';
5
- class ProbeError extends Error {
6
- errorCode;
7
- constructor(message, errorCode) {
8
- super(message);
9
- this.errorCode = errorCode;
10
- this.name = 'ProbeError';
11
- }
12
- }
13
- function codeForStatus(status) {
14
- if (status === 401 || status === 403)
15
- return 'auth';
16
- return `http_${status}`;
17
- }
18
- function probeErrorCode(err) {
19
- if (err instanceof ProbeError)
20
- return err.errorCode;
21
- const msg = err instanceof Error ? err.message : String(err);
22
- if (/(ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|fetch failed|abort)/i.test(msg))
23
- return 'network';
24
- return 'unknown';
25
- }
26
- const FETCH_TIMEOUT_MS = 8000;
27
- const MAX_BODY_BYTES = 8192;
28
- const MAX_ERROR_CHARS = 300;
29
- function safeErrorString(s) {
30
- return redactSecrets(s)
31
- .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '')
32
- .slice(0, MAX_ERROR_CHARS);
33
- }
34
- function fail(errorCode, message, extra) {
35
- return { ...extra, valid: false, error: safeErrorString(message), errorCode };
36
- }
37
- function extractProviderError(status, body) {
38
- try {
39
- const j = JSON.parse(body);
40
- const msg = j?.error?.message;
41
- const type = j?.error?.type;
42
- if (msg)
43
- return safeErrorString(type ? `${msg} (${type})` : msg);
44
- }
45
- catch {
46
- }
47
- if (status === 401)
48
- return 'Authentication failed — the API key was rejected.';
49
- if (status === 403)
50
- return 'Forbidden — the key may lack permission for this endpoint.';
51
- if (status === 429)
52
- return 'Rate limited or quota exhausted.';
53
- if (status >= 500)
54
- return `Provider returned ${status} (server-side error).`;
55
- return `HTTP ${status}`;
56
- }
57
- async function readBodyCapped(res) {
58
- const reader = res.body?.getReader();
59
- if (!reader)
60
- return await res.text().catch(() => '');
61
- const chunks = [];
62
- let total = 0;
63
- try {
64
- while (total < MAX_BODY_BYTES) {
65
- const { done, value } = await reader.read();
66
- if (done)
67
- break;
68
- chunks.push(value);
69
- total += value.byteLength;
70
- }
71
- if (total >= MAX_BODY_BYTES)
72
- await reader.cancel().catch(() => { });
73
- }
74
- catch {
75
- }
76
- const merged = new Uint8Array(Math.min(total, MAX_BODY_BYTES));
77
- let off = 0;
78
- for (const c of chunks) {
79
- const room = merged.byteLength - off;
80
- if (room <= 0)
81
- break;
82
- merged.set(c.subarray(0, Math.min(c.byteLength, room)), off);
83
- off += Math.min(c.byteLength, room);
84
- }
85
- return new TextDecoder().decode(merged);
86
- }
87
- async function fetchJson(url, init) {
88
- const ctrl = new AbortController();
89
- const t = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
90
- try {
91
- const res = await fetch(url, { ...init, signal: ctrl.signal });
92
- if (!res.ok) {
93
- const body = await readBodyCapped(res).catch(() => '');
94
- throw new ProbeError(extractProviderError(res.status, body), codeForStatus(res.status));
95
- }
96
- return (await res.json());
97
- }
98
- finally {
99
- clearTimeout(t);
100
- }
101
- }
102
- export function pickSuggestedModel(models) {
103
- if (models.length === 0)
104
- return undefined;
105
- const SMALL_HINTS = ['mini', 'nano', 'haiku', 'flash', 'lite', 'small', '8b', '7b', '3b'];
106
- const candidates = models.filter((m) => SMALL_HINTS.some((h) => m.id.toLowerCase().includes(h)));
107
- const pool = candidates.length > 0 ? candidates : models;
108
- const sorted = [...pool].sort((a, b) => {
109
- if (a.created && b.created)
110
- return b.created.localeCompare(a.created);
111
- return 0;
112
- });
113
- return sorted[0].id;
114
- }
115
- export async function probeAnthropic(apiKey) {
116
- if (!apiKey)
117
- return fail('auth', 'API key is empty');
118
- try {
119
- const data = await fetchJson('https://api.anthropic.com/v1/models?limit=200', {
120
- method: 'GET',
121
- headers: {
122
- 'x-api-key': apiKey,
123
- 'anthropic-version': '2023-06-01',
124
- },
125
- });
126
- const models = (data.data ?? []).map((m) => ({
127
- id: m.id,
128
- created: m.created_at,
129
- }));
130
- if (models.length === 0) {
131
- return fail('no_models', 'Anthropic answered, but returned no models — a proxy or gateway may be intercepting the request. Check the endpoint and API key.');
132
- }
133
- return { valid: true, models, suggested: pickSuggestedModel(models) };
134
- }
135
- catch (err) {
136
- return fail(probeErrorCode(err), err instanceof Error ? err.message : String(err));
137
- }
138
- }
139
- export async function probeOpenAI(apiKey) {
140
- if (!apiKey)
141
- return fail('auth', 'API key is empty');
142
- try {
143
- const data = await fetchJson('https://api.openai.com/v1/models', {
144
- method: 'GET',
145
- headers: { Authorization: `Bearer ${apiKey}` },
146
- });
147
- const NON_CHAT_PREFIXES = ['whisper', 'tts-', 'dall-e', 'davinci-codex', 'text-embedding', 'text-similarity', 'omni-moderation'];
148
- const models = (data.data ?? [])
149
- .filter((m) => !NON_CHAT_PREFIXES.some((p) => m.id.startsWith(p)))
150
- .map((m) => ({
151
- id: m.id,
152
- created: m.created ? new Date(m.created * 1000).toISOString() : undefined,
153
- }));
154
- if (models.length === 0) {
155
- return fail('no_models', 'OpenAI answered, but returned no chat-capable models — a proxy or gateway may be intercepting the request. Check the endpoint and API key.');
156
- }
157
- return { valid: true, models, suggested: pickSuggestedModel(models) };
158
- }
159
- catch (err) {
160
- return fail(probeErrorCode(err), err instanceof Error ? err.message : String(err));
161
- }
162
- }
163
- export async function probeOllama(host) {
164
- let base;
165
- try {
166
- base = resolveOllamaHost(host);
167
- }
168
- catch {
169
- return fail('bad_host', UNSAFE_OLLAMA_HOST_ERROR);
170
- }
171
- try {
172
- const data = await fetchJson(`${base}/api/tags`, { method: 'GET' });
173
- const models = (data.models ?? []).map((m) => ({
174
- id: m.name,
175
- created: m.modified_at,
176
- }));
177
- if (models.length === 0) {
178
- return fail('no_models', `Ollama is reachable at ${base} but has no models installed. Run \`ollama pull <model>\` first.`);
179
- }
180
- return { valid: true, models, suggested: pickSuggestedModel(models) };
181
- }
182
- catch (err) {
183
- const msg = err instanceof Error ? err.message : String(err);
184
- if (msg.includes('ECONNREFUSED') || msg.includes('fetch failed')) {
185
- return fail('network', `Ollama not reachable at ${base}. Is it installed and running?`);
186
- }
187
- return fail(probeErrorCode(err), msg);
188
- }
189
- }
190
- export async function probeProvider(provider, apiKey, host, model) {
191
- const catalog = provider === 'anthropic'
192
- ? await probeAnthropic(apiKey ?? '')
193
- : provider === 'openai'
194
- ? await probeOpenAI(apiKey ?? '')
195
- : provider === 'ollama'
196
- ? await probeOllama(host)
197
- : fail('unknown', `Unknown provider: ${provider}`);
198
- if (!catalog.valid) {
199
- return { ...catalog, catalogVerified: false, inferenceVerified: false };
200
- }
201
- const testedModel = model || catalog.suggested || catalog.models?.[0]?.id;
202
- if (!testedModel) {
203
- return fail('no_models', 'The provider catalog returned no model that could be tested.', {
204
- ...catalog, catalogVerified: true, inferenceVerified: false,
205
- });
206
- }
207
- try {
208
- const response = await callLLM(sanitizeForPrompt('Reply with exactly: OK'), {
209
- provider,
210
- model: testedModel,
211
- ...(apiKey ? { apiKey } : {}),
212
- ...(provider === 'ollama' && host ? { host } : {}),
213
- }, { maxTokens: 8 });
214
- if (!response.trim())
215
- throw new Error('provider returned an empty response');
216
- return {
217
- ...catalog,
218
- valid: true,
219
- catalogVerified: true,
220
- inferenceVerified: true,
221
- testedModel,
222
- };
223
- }
224
- catch (err) {
225
- const detail = err instanceof Error ? err.message : String(err);
226
- return fail('inference_failed', `Model ${testedModel} failed the inference probe: ${detail}`, {
227
- ...catalog, catalogVerified: true, inferenceVerified: false, testedModel,
228
- });
229
- }
230
- }
231
- //# sourceMappingURL=llm-validator.js.map