@kb-labs/core-platform 1.0.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.
- package/README.md +108 -0
- package/dist/adapters/index.cjs +26 -0
- package/dist/adapters/index.cjs.map +1 -0
- package/dist/adapters/index.d.cts +125 -0
- package/dist/adapters/index.d.ts +125 -0
- package/dist/adapters/index.js +21 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/artifacts-BUghvkUU.d.cts +273 -0
- package/dist/artifacts-Bd-1UVTw.d.ts +273 -0
- package/dist/artifacts-DrVnkLzu.d.cts +1374 -0
- package/dist/artifacts-DrVnkLzu.d.ts +1374 -0
- package/dist/core/index.cjs +4 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +2 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/database-DGV6a1nj.d.cts +427 -0
- package/dist/database-DGV6a1nj.d.ts +427 -0
- package/dist/index.cjs +1405 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +579 -0
- package/dist/index.d.ts +579 -0
- package/dist/index.js +1381 -0
- package/dist/index.js.map +1 -0
- package/dist/log-reader-BVohbSMB.d.cts +314 -0
- package/dist/log-reader-uOHBLBax.d.ts +314 -0
- package/dist/noop/adapters/index.cjs +656 -0
- package/dist/noop/adapters/index.cjs.map +1 -0
- package/dist/noop/adapters/index.d.cts +71 -0
- package/dist/noop/adapters/index.d.ts +71 -0
- package/dist/noop/adapters/index.js +637 -0
- package/dist/noop/adapters/index.js.map +1 -0
- package/dist/noop/core/index.cjs +217 -0
- package/dist/noop/core/index.cjs.map +1 -0
- package/dist/noop/core/index.d.cts +94 -0
- package/dist/noop/core/index.d.ts +94 -0
- package/dist/noop/core/index.js +212 -0
- package/dist/noop/core/index.js.map +1 -0
- package/dist/noop/index.cjs +806 -0
- package/dist/noop/index.cjs.map +1 -0
- package/dist/noop/index.d.cts +36 -0
- package/dist/noop/index.d.ts +36 -0
- package/dist/noop/index.js +787 -0
- package/dist/noop/index.js.map +1 -0
- package/dist/resources-DaufJFad.d.cts +419 -0
- package/dist/resources-DaufJFad.d.ts +419 -0
- package/dist/serializable/index.cjs +162 -0
- package/dist/serializable/index.cjs.map +1 -0
- package/dist/serializable/index.d.cts +352 -0
- package/dist/serializable/index.d.ts +352 -0
- package/dist/serializable/index.js +152 -0
- package/dist/serializable/index.js.map +1 -0
- package/dist/snapshot-provider--COac4P-.d.ts +923 -0
- package/dist/snapshot-provider-nE9wuc1C.d.cts +923 -0
- package/package.json +92 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1405 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
9
|
+
|
|
10
|
+
// src/adapters/llm-types.ts
|
|
11
|
+
var TIER_ORDER = [
|
|
12
|
+
"small",
|
|
13
|
+
"medium",
|
|
14
|
+
"large"
|
|
15
|
+
];
|
|
16
|
+
function isTierHigher(a, b) {
|
|
17
|
+
return TIER_ORDER.indexOf(a) > TIER_ORDER.indexOf(b);
|
|
18
|
+
}
|
|
19
|
+
function isTierLower(a, b) {
|
|
20
|
+
return TIER_ORDER.indexOf(a) < TIER_ORDER.indexOf(b);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/wrappers/analytics-llm.ts
|
|
24
|
+
var AnalyticsLLM = class {
|
|
25
|
+
constructor(realLLM, analytics) {
|
|
26
|
+
this.realLLM = realLLM;
|
|
27
|
+
this.analytics = analytics;
|
|
28
|
+
}
|
|
29
|
+
async getProtocolCapabilities() {
|
|
30
|
+
if (!this.realLLM.getProtocolCapabilities) {
|
|
31
|
+
return {
|
|
32
|
+
cache: { supported: false },
|
|
33
|
+
stream: { supported: true }
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return this.realLLM.getProtocolCapabilities();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate a completion with analytics tracking.
|
|
40
|
+
*/
|
|
41
|
+
async complete(prompt, options) {
|
|
42
|
+
const startTime = Date.now();
|
|
43
|
+
const requestId = generateRequestId();
|
|
44
|
+
const metadata = options?.metadata;
|
|
45
|
+
await this.analytics.track("llm.completion.started", {
|
|
46
|
+
requestId,
|
|
47
|
+
tier: metadata?.tier,
|
|
48
|
+
provider: metadata?.provider,
|
|
49
|
+
model: options?.model,
|
|
50
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
51
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
52
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
53
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
54
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
55
|
+
promptLength: prompt.length,
|
|
56
|
+
maxTokens: options?.maxTokens,
|
|
57
|
+
temperature: options?.temperature
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const response = await this.realLLM.complete(prompt, options);
|
|
61
|
+
await this.trackCacheOutcome(requestId, metadata, response);
|
|
62
|
+
const durationMs = Date.now() - startTime;
|
|
63
|
+
const usageMetrics = buildUsageAnalytics(response);
|
|
64
|
+
await this.analytics.track("llm.completion.completed", {
|
|
65
|
+
requestId,
|
|
66
|
+
tier: metadata?.tier,
|
|
67
|
+
provider: metadata?.provider,
|
|
68
|
+
model: response.model,
|
|
69
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
70
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
71
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
72
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
73
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
74
|
+
...usageMetrics,
|
|
75
|
+
durationMs
|
|
76
|
+
});
|
|
77
|
+
return response;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
await this.analytics.track("llm.completion.error", {
|
|
80
|
+
requestId,
|
|
81
|
+
tier: metadata?.tier,
|
|
82
|
+
provider: metadata?.provider,
|
|
83
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
84
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
85
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
86
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
87
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
88
|
+
error: error instanceof Error ? error.message : String(error),
|
|
89
|
+
durationMs: Date.now() - startTime
|
|
90
|
+
});
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Stream a completion.
|
|
96
|
+
* Note: Streaming is harder to track token-by-token, so we track start/end only.
|
|
97
|
+
*/
|
|
98
|
+
async *stream(prompt, options) {
|
|
99
|
+
const startTime = Date.now();
|
|
100
|
+
const requestId = generateRequestId();
|
|
101
|
+
const metadata = options?.metadata;
|
|
102
|
+
await this.analytics.track("llm.stream.started", {
|
|
103
|
+
requestId,
|
|
104
|
+
tier: metadata?.tier,
|
|
105
|
+
provider: metadata?.provider,
|
|
106
|
+
model: options?.model,
|
|
107
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
108
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
109
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
110
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
111
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
112
|
+
promptLength: prompt.length
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
let totalChunks = 0;
|
|
116
|
+
let totalLength = 0;
|
|
117
|
+
for await (const chunk of this.realLLM.stream(prompt, options)) {
|
|
118
|
+
totalChunks++;
|
|
119
|
+
totalLength += chunk.length;
|
|
120
|
+
yield chunk;
|
|
121
|
+
}
|
|
122
|
+
await this.analytics.track("llm.stream.completed", {
|
|
123
|
+
requestId,
|
|
124
|
+
tier: metadata?.tier,
|
|
125
|
+
provider: metadata?.provider,
|
|
126
|
+
model: options?.model,
|
|
127
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
128
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
129
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
130
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
131
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
132
|
+
durationMs: Date.now() - startTime,
|
|
133
|
+
totalChunks,
|
|
134
|
+
totalLength
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
await this.analytics.track("llm.stream.error", {
|
|
138
|
+
requestId,
|
|
139
|
+
tier: metadata?.tier,
|
|
140
|
+
provider: metadata?.provider,
|
|
141
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
142
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
143
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
144
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
145
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
146
|
+
error: error instanceof Error ? error.message : String(error),
|
|
147
|
+
durationMs: Date.now() - startTime
|
|
148
|
+
});
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Chat with native tool calling support (optional).
|
|
154
|
+
* Proxies to underlying LLM if it supports chatWithTools.
|
|
155
|
+
*/
|
|
156
|
+
async chatWithTools(messages, options) {
|
|
157
|
+
if (!this.realLLM.chatWithTools) {
|
|
158
|
+
throw new Error("Underlying LLM does not support chatWithTools");
|
|
159
|
+
}
|
|
160
|
+
const startTime = Date.now();
|
|
161
|
+
const requestId = generateRequestId();
|
|
162
|
+
const metadata = options?.metadata;
|
|
163
|
+
await this.analytics.track("llm.chatWithTools.started", {
|
|
164
|
+
requestId,
|
|
165
|
+
tier: metadata?.tier,
|
|
166
|
+
provider: metadata?.provider,
|
|
167
|
+
model: options?.model,
|
|
168
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
169
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
170
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
171
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
172
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
173
|
+
messageCount: messages.length,
|
|
174
|
+
toolCount: options.tools.length,
|
|
175
|
+
toolChoice: options.toolChoice,
|
|
176
|
+
maxTokens: options?.maxTokens,
|
|
177
|
+
temperature: options?.temperature
|
|
178
|
+
});
|
|
179
|
+
try {
|
|
180
|
+
const response = await this.realLLM.chatWithTools(messages, options);
|
|
181
|
+
await this.trackCacheOutcome(requestId, metadata, response);
|
|
182
|
+
const durationMs = Date.now() - startTime;
|
|
183
|
+
const usageMetrics = buildUsageAnalytics(response);
|
|
184
|
+
await this.analytics.track("llm.chatWithTools.completed", {
|
|
185
|
+
requestId,
|
|
186
|
+
tier: metadata?.tier,
|
|
187
|
+
provider: metadata?.provider,
|
|
188
|
+
model: response.model,
|
|
189
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
190
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
191
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
192
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
193
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
194
|
+
...usageMetrics,
|
|
195
|
+
toolCallCount: response.toolCalls?.length ?? 0,
|
|
196
|
+
toolNames: response.toolCalls?.map((tc) => tc.name) ?? [],
|
|
197
|
+
durationMs
|
|
198
|
+
});
|
|
199
|
+
return response;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
await this.analytics.track("llm.chatWithTools.error", {
|
|
202
|
+
requestId,
|
|
203
|
+
tier: metadata?.tier,
|
|
204
|
+
provider: metadata?.provider,
|
|
205
|
+
cacheRequestedMode: metadata?.cacheDecisionTrace?.cacheRequestedMode,
|
|
206
|
+
cacheAppliedMode: metadata?.cacheDecisionTrace?.cacheAppliedMode,
|
|
207
|
+
streamRequestedMode: metadata?.cacheDecisionTrace?.streamRequestedMode,
|
|
208
|
+
streamAppliedMode: metadata?.cacheDecisionTrace?.streamAppliedMode,
|
|
209
|
+
streamFallback: metadata?.cacheDecisionTrace?.streamFallback,
|
|
210
|
+
error: error instanceof Error ? error.message : String(error),
|
|
211
|
+
durationMs: Date.now() - startTime
|
|
212
|
+
});
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async trackCacheOutcome(requestId, metadata, response) {
|
|
217
|
+
const trace = metadata?.cacheDecisionTrace;
|
|
218
|
+
if (!trace) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const cacheReadTokens = response.usage.cacheReadTokens ?? 0;
|
|
222
|
+
const cacheWriteTokens = response.usage.cacheWriteTokens ?? 0;
|
|
223
|
+
const basePayload = {
|
|
224
|
+
requestId,
|
|
225
|
+
tier: metadata?.tier,
|
|
226
|
+
provider: metadata?.provider,
|
|
227
|
+
cacheRequestedMode: trace.cacheRequestedMode,
|
|
228
|
+
cacheAppliedMode: trace.cacheAppliedMode,
|
|
229
|
+
cacheSupported: trace.cacheSupported,
|
|
230
|
+
cacheReadTokens,
|
|
231
|
+
cacheWriteTokens,
|
|
232
|
+
promptTokens: response.usage.promptTokens,
|
|
233
|
+
completionTokens: response.usage.completionTokens,
|
|
234
|
+
model: response.model
|
|
235
|
+
};
|
|
236
|
+
if (trace.cacheAppliedMode === "bypass" || trace.cacheRequestedMode === "bypass") {
|
|
237
|
+
await this.analytics.track("llm.cache.bypass", {
|
|
238
|
+
...basePayload,
|
|
239
|
+
reason: trace.reason ?? "CACHE_BYPASSED"
|
|
240
|
+
});
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (cacheReadTokens > 0) {
|
|
244
|
+
await this.analytics.track("llm.cache.hit", basePayload);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
await this.analytics.track("llm.cache.miss", {
|
|
248
|
+
...basePayload,
|
|
249
|
+
reason: trace.reason ?? "NO_CACHE_READ_TOKENS"
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
function generateRequestId() {
|
|
254
|
+
return `llm-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
255
|
+
}
|
|
256
|
+
function buildUsageAnalytics(response) {
|
|
257
|
+
const model = response.model.toLowerCase();
|
|
258
|
+
const promptTokens = response.usage.promptTokens;
|
|
259
|
+
const completionTokens = response.usage.completionTokens;
|
|
260
|
+
const cacheReadTokens = response.usage.cacheReadTokens ?? 0;
|
|
261
|
+
const cacheWriteTokens = response.usage.cacheWriteTokens ?? 0;
|
|
262
|
+
const billablePromptTokens = response.usage.billablePromptTokens ?? Math.max(promptTokens - cacheReadTokens, 0);
|
|
263
|
+
const totalTokens = promptTokens + completionTokens;
|
|
264
|
+
const billableTotalTokens = billablePromptTokens + completionTokens;
|
|
265
|
+
const pricing = getPricing(model);
|
|
266
|
+
const normalInputTokens = Math.max(promptTokens - cacheReadTokens, 0);
|
|
267
|
+
const cachedInputTokens = cacheReadTokens;
|
|
268
|
+
const cachedInputRate = pricing.cachedInput ?? pricing.input;
|
|
269
|
+
const inputCost = normalInputTokens / 1e6 * pricing.input + cachedInputTokens / 1e6 * cachedInputRate;
|
|
270
|
+
const outputCost = completionTokens / 1e6 * pricing.output;
|
|
271
|
+
const estimatedCost = inputCost + outputCost;
|
|
272
|
+
const uncachedInputCost = promptTokens / 1e6 * pricing.input;
|
|
273
|
+
const uncachedOutputCost = outputCost;
|
|
274
|
+
const estimatedUncachedCost = uncachedInputCost + uncachedOutputCost;
|
|
275
|
+
const estimatedCacheSavingsUsd = Math.max(estimatedUncachedCost - estimatedCost, 0);
|
|
276
|
+
const estimatedSavedPromptTokens = Math.max(promptTokens - billablePromptTokens, 0);
|
|
277
|
+
return {
|
|
278
|
+
promptTokens,
|
|
279
|
+
completionTokens,
|
|
280
|
+
totalTokens,
|
|
281
|
+
cacheReadTokens,
|
|
282
|
+
cacheWriteTokens,
|
|
283
|
+
billablePromptTokens,
|
|
284
|
+
billableTotalTokens,
|
|
285
|
+
estimatedSavedPromptTokens,
|
|
286
|
+
estimatedCost,
|
|
287
|
+
estimatedUncachedCost,
|
|
288
|
+
estimatedCacheSavingsUsd
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function getPricing(model) {
|
|
292
|
+
const pricing = {
|
|
293
|
+
// OpenAI models (2025-01 pricing)
|
|
294
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6, cachedInput: 0.075 },
|
|
295
|
+
"gpt-4o": { input: 2.5, output: 10, cachedInput: 1.25 },
|
|
296
|
+
"gpt-4-turbo": { input: 10, output: 30 },
|
|
297
|
+
"gpt-4": { input: 30, output: 60 },
|
|
298
|
+
"gpt-3.5-turbo": { input: 0.5, output: 1.5 },
|
|
299
|
+
// Claude models (2025-01 pricing)
|
|
300
|
+
// Cached input discounts vary by policy (5m/1h), conservative defaults:
|
|
301
|
+
// if unknown, keep cachedInput equal to input.
|
|
302
|
+
"claude-3-opus": { input: 15, output: 75 },
|
|
303
|
+
"claude-3-sonnet": { input: 3, output: 15 },
|
|
304
|
+
"claude-3-haiku": { input: 0.25, output: 1.25 }
|
|
305
|
+
};
|
|
306
|
+
const sortedKeys = Object.keys(pricing).sort((a, b) => b.length - a.length);
|
|
307
|
+
let modelPricing = pricing["gpt-4o-mini"];
|
|
308
|
+
for (const key of sortedKeys) {
|
|
309
|
+
if (model.includes(key)) {
|
|
310
|
+
modelPricing = pricing[key];
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return modelPricing;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// src/wrappers/analytics-embeddings.ts
|
|
318
|
+
function generateRequestId2() {
|
|
319
|
+
return `emb_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
320
|
+
}
|
|
321
|
+
function estimateCost(textLength, provider = "openai") {
|
|
322
|
+
const pricing = {
|
|
323
|
+
openai: 2e-5,
|
|
324
|
+
// per 1K tokens
|
|
325
|
+
cohere: 1e-4
|
|
326
|
+
// per 1K tokens
|
|
327
|
+
};
|
|
328
|
+
const pricePerK = pricing[provider] || pricing.openai;
|
|
329
|
+
const estimatedTokens = Math.ceil(textLength / 750);
|
|
330
|
+
return estimatedTokens / 1e3 * pricePerK;
|
|
331
|
+
}
|
|
332
|
+
var AnalyticsEmbeddings = class {
|
|
333
|
+
constructor(realEmbeddings, analytics) {
|
|
334
|
+
this.realEmbeddings = realEmbeddings;
|
|
335
|
+
this.analytics = analytics;
|
|
336
|
+
}
|
|
337
|
+
get dimensions() {
|
|
338
|
+
return this.realEmbeddings.dimensions;
|
|
339
|
+
}
|
|
340
|
+
async getDimensions() {
|
|
341
|
+
return this.realEmbeddings.getDimensions();
|
|
342
|
+
}
|
|
343
|
+
async embed(text) {
|
|
344
|
+
const startTime = Date.now();
|
|
345
|
+
const requestId = generateRequestId2();
|
|
346
|
+
await this.analytics.track("embeddings.embed.started", {
|
|
347
|
+
requestId,
|
|
348
|
+
textLength: text.length,
|
|
349
|
+
batchSize: 1
|
|
350
|
+
});
|
|
351
|
+
try {
|
|
352
|
+
const result = await this.realEmbeddings.embed(text);
|
|
353
|
+
const durationMs = Date.now() - startTime;
|
|
354
|
+
await this.analytics.track("embeddings.embed.completed", {
|
|
355
|
+
requestId,
|
|
356
|
+
textLength: text.length,
|
|
357
|
+
dimensions: result.length,
|
|
358
|
+
durationMs,
|
|
359
|
+
estimatedCost: estimateCost(text.length),
|
|
360
|
+
batchSize: 1
|
|
361
|
+
});
|
|
362
|
+
return result;
|
|
363
|
+
} catch (error) {
|
|
364
|
+
await this.analytics.track("embeddings.embed.error", {
|
|
365
|
+
requestId,
|
|
366
|
+
error: error instanceof Error ? error.message : String(error),
|
|
367
|
+
durationMs: Date.now() - startTime
|
|
368
|
+
});
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
async embedBatch(texts) {
|
|
373
|
+
const startTime = Date.now();
|
|
374
|
+
const requestId = generateRequestId2();
|
|
375
|
+
const totalTextLength = texts.reduce((sum, text) => sum + text.length, 0);
|
|
376
|
+
await this.analytics.track("embeddings.embedBatch.started", {
|
|
377
|
+
requestId,
|
|
378
|
+
totalTextLength,
|
|
379
|
+
batchSize: texts.length
|
|
380
|
+
});
|
|
381
|
+
try {
|
|
382
|
+
const results = await this.realEmbeddings.embedBatch(texts);
|
|
383
|
+
const durationMs = Date.now() - startTime;
|
|
384
|
+
await this.analytics.track("embeddings.embedBatch.completed", {
|
|
385
|
+
requestId,
|
|
386
|
+
totalTextLength,
|
|
387
|
+
batchSize: texts.length,
|
|
388
|
+
dimensions: results[0]?.length ?? 0,
|
|
389
|
+
durationMs,
|
|
390
|
+
estimatedCost: estimateCost(totalTextLength),
|
|
391
|
+
avgTextLength: Math.round(totalTextLength / texts.length)
|
|
392
|
+
});
|
|
393
|
+
return results;
|
|
394
|
+
} catch (error) {
|
|
395
|
+
await this.analytics.track("embeddings.embedBatch.error", {
|
|
396
|
+
requestId,
|
|
397
|
+
error: error instanceof Error ? error.message : String(error),
|
|
398
|
+
durationMs: Date.now() - startTime,
|
|
399
|
+
batchSize: texts.length
|
|
400
|
+
});
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// src/wrappers/analytics-vector-store.ts
|
|
407
|
+
function generateRequestId3() {
|
|
408
|
+
return `vec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
409
|
+
}
|
|
410
|
+
var AnalyticsVectorStore = class {
|
|
411
|
+
constructor(realVectorStore, analytics) {
|
|
412
|
+
this.realVectorStore = realVectorStore;
|
|
413
|
+
this.analytics = analytics;
|
|
414
|
+
}
|
|
415
|
+
async search(query, limit, filter) {
|
|
416
|
+
const startTime = Date.now();
|
|
417
|
+
const requestId = generateRequestId3();
|
|
418
|
+
await this.analytics.track("vectorstore.search.started", {
|
|
419
|
+
requestId,
|
|
420
|
+
dimensions: query.length,
|
|
421
|
+
limit,
|
|
422
|
+
hasFilter: !!filter
|
|
423
|
+
});
|
|
424
|
+
try {
|
|
425
|
+
const results = await this.realVectorStore.search(query, limit, filter);
|
|
426
|
+
const durationMs = Date.now() - startTime;
|
|
427
|
+
const avgScore = results.length > 0 ? results.reduce((sum, r) => sum + r.score, 0) / results.length : 0;
|
|
428
|
+
await this.analytics.track("vectorstore.search.completed", {
|
|
429
|
+
requestId,
|
|
430
|
+
dimensions: query.length,
|
|
431
|
+
limit,
|
|
432
|
+
resultsCount: results.length,
|
|
433
|
+
avgScore,
|
|
434
|
+
durationMs,
|
|
435
|
+
hasFilter: !!filter
|
|
436
|
+
});
|
|
437
|
+
return results;
|
|
438
|
+
} catch (error) {
|
|
439
|
+
await this.analytics.track("vectorstore.search.error", {
|
|
440
|
+
requestId,
|
|
441
|
+
error: error instanceof Error ? error.message : String(error),
|
|
442
|
+
durationMs: Date.now() - startTime
|
|
443
|
+
});
|
|
444
|
+
throw error;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
async upsert(vectors) {
|
|
448
|
+
const startTime = Date.now();
|
|
449
|
+
const requestId = generateRequestId3();
|
|
450
|
+
await this.analytics.track("vectorstore.upsert.started", {
|
|
451
|
+
requestId,
|
|
452
|
+
vectorCount: vectors.length
|
|
453
|
+
});
|
|
454
|
+
try {
|
|
455
|
+
await this.realVectorStore.upsert(vectors);
|
|
456
|
+
const durationMs = Date.now() - startTime;
|
|
457
|
+
await this.analytics.track("vectorstore.upsert.completed", {
|
|
458
|
+
requestId,
|
|
459
|
+
vectorCount: vectors.length,
|
|
460
|
+
durationMs
|
|
461
|
+
});
|
|
462
|
+
} catch (error) {
|
|
463
|
+
await this.analytics.track("vectorstore.upsert.error", {
|
|
464
|
+
requestId,
|
|
465
|
+
error: error instanceof Error ? error.message : String(error),
|
|
466
|
+
durationMs: Date.now() - startTime,
|
|
467
|
+
vectorCount: vectors.length
|
|
468
|
+
});
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
async delete(ids) {
|
|
473
|
+
const startTime = Date.now();
|
|
474
|
+
const requestId = generateRequestId3();
|
|
475
|
+
await this.analytics.track("vectorstore.delete.started", {
|
|
476
|
+
requestId,
|
|
477
|
+
idsCount: ids.length
|
|
478
|
+
});
|
|
479
|
+
try {
|
|
480
|
+
await this.realVectorStore.delete(ids);
|
|
481
|
+
const durationMs = Date.now() - startTime;
|
|
482
|
+
await this.analytics.track("vectorstore.delete.completed", {
|
|
483
|
+
requestId,
|
|
484
|
+
idsCount: ids.length,
|
|
485
|
+
durationMs
|
|
486
|
+
});
|
|
487
|
+
} catch (error) {
|
|
488
|
+
await this.analytics.track("vectorstore.delete.error", {
|
|
489
|
+
requestId,
|
|
490
|
+
error: error instanceof Error ? error.message : String(error),
|
|
491
|
+
durationMs: Date.now() - startTime
|
|
492
|
+
});
|
|
493
|
+
throw error;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
async count() {
|
|
497
|
+
const startTime = Date.now();
|
|
498
|
+
const requestId = generateRequestId3();
|
|
499
|
+
try {
|
|
500
|
+
const count = await this.realVectorStore.count();
|
|
501
|
+
const durationMs = Date.now() - startTime;
|
|
502
|
+
await this.analytics.track("vectorstore.count.completed", {
|
|
503
|
+
requestId,
|
|
504
|
+
count,
|
|
505
|
+
durationMs
|
|
506
|
+
});
|
|
507
|
+
return count;
|
|
508
|
+
} catch (error) {
|
|
509
|
+
await this.analytics.track("vectorstore.count.error", {
|
|
510
|
+
requestId,
|
|
511
|
+
error: error instanceof Error ? error.message : String(error),
|
|
512
|
+
durationMs: Date.now() - startTime
|
|
513
|
+
});
|
|
514
|
+
throw error;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
async get(ids) {
|
|
518
|
+
if (!this.realVectorStore.get) {
|
|
519
|
+
throw new Error("get() not implemented by underlying vector store");
|
|
520
|
+
}
|
|
521
|
+
const startTime = Date.now();
|
|
522
|
+
const requestId = generateRequestId3();
|
|
523
|
+
try {
|
|
524
|
+
const results = await this.realVectorStore.get(ids);
|
|
525
|
+
const durationMs = Date.now() - startTime;
|
|
526
|
+
await this.analytics.track("vectorstore.get.completed", {
|
|
527
|
+
requestId,
|
|
528
|
+
idsCount: ids.length,
|
|
529
|
+
resultsCount: results.length,
|
|
530
|
+
durationMs
|
|
531
|
+
});
|
|
532
|
+
return results;
|
|
533
|
+
} catch (error) {
|
|
534
|
+
await this.analytics.track("vectorstore.get.error", {
|
|
535
|
+
requestId,
|
|
536
|
+
error: error instanceof Error ? error.message : String(error),
|
|
537
|
+
durationMs: Date.now() - startTime
|
|
538
|
+
});
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
async query(filter) {
|
|
543
|
+
if (!this.realVectorStore.query) {
|
|
544
|
+
throw new Error("query() not implemented by underlying vector store");
|
|
545
|
+
}
|
|
546
|
+
const startTime = Date.now();
|
|
547
|
+
const requestId = generateRequestId3();
|
|
548
|
+
try {
|
|
549
|
+
const results = await this.realVectorStore.query(filter);
|
|
550
|
+
const durationMs = Date.now() - startTime;
|
|
551
|
+
await this.analytics.track("vectorstore.query.completed", {
|
|
552
|
+
requestId,
|
|
553
|
+
resultsCount: results.length,
|
|
554
|
+
durationMs
|
|
555
|
+
});
|
|
556
|
+
return results;
|
|
557
|
+
} catch (error) {
|
|
558
|
+
await this.analytics.track("vectorstore.query.error", {
|
|
559
|
+
requestId,
|
|
560
|
+
error: error instanceof Error ? error.message : String(error),
|
|
561
|
+
durationMs: Date.now() - startTime
|
|
562
|
+
});
|
|
563
|
+
throw error;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
// src/wrappers/analytics-cache.ts
|
|
569
|
+
function generateRequestId4() {
|
|
570
|
+
return `cache_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
571
|
+
}
|
|
572
|
+
var cacheCounter = 0;
|
|
573
|
+
function shouldSampleCacheEvent(eventType) {
|
|
574
|
+
cacheCounter = (cacheCounter + 1) % 100;
|
|
575
|
+
if (eventType === "cache.get.hit" || eventType === "cache.set.completed") {
|
|
576
|
+
return cacheCounter === 0;
|
|
577
|
+
}
|
|
578
|
+
if (eventType === "cache.get.miss") {
|
|
579
|
+
return cacheCounter % 10 === 0;
|
|
580
|
+
}
|
|
581
|
+
return true;
|
|
582
|
+
}
|
|
583
|
+
var AnalyticsCache = class {
|
|
584
|
+
constructor(realCache, analytics) {
|
|
585
|
+
this.realCache = realCache;
|
|
586
|
+
this.analytics = analytics;
|
|
587
|
+
}
|
|
588
|
+
async get(key) {
|
|
589
|
+
const startTime = Date.now();
|
|
590
|
+
const requestId = generateRequestId4();
|
|
591
|
+
try {
|
|
592
|
+
const result = await this.realCache.get(key);
|
|
593
|
+
const durationMs = Date.now() - startTime;
|
|
594
|
+
const hit = result !== null;
|
|
595
|
+
const eventType = hit ? "cache.get.hit" : "cache.get.miss";
|
|
596
|
+
if (shouldSampleCacheEvent(eventType)) {
|
|
597
|
+
await this.analytics.track(eventType, {
|
|
598
|
+
requestId,
|
|
599
|
+
key,
|
|
600
|
+
durationMs
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
return result;
|
|
604
|
+
} catch (error) {
|
|
605
|
+
await this.analytics.track("cache.get.error", {
|
|
606
|
+
requestId,
|
|
607
|
+
key,
|
|
608
|
+
error: error instanceof Error ? error.message : String(error),
|
|
609
|
+
durationMs: Date.now() - startTime
|
|
610
|
+
});
|
|
611
|
+
throw error;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
async set(key, value, ttl) {
|
|
615
|
+
const startTime = Date.now();
|
|
616
|
+
const requestId = generateRequestId4();
|
|
617
|
+
try {
|
|
618
|
+
await this.realCache.set(key, value, ttl);
|
|
619
|
+
const durationMs = Date.now() - startTime;
|
|
620
|
+
if (shouldSampleCacheEvent("cache.set.completed")) {
|
|
621
|
+
await this.analytics.track("cache.set.completed", {
|
|
622
|
+
requestId,
|
|
623
|
+
key,
|
|
624
|
+
ttl: ttl ?? null,
|
|
625
|
+
durationMs
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
} catch (error) {
|
|
629
|
+
await this.analytics.track("cache.set.error", {
|
|
630
|
+
requestId,
|
|
631
|
+
key,
|
|
632
|
+
error: error instanceof Error ? error.message : String(error),
|
|
633
|
+
durationMs: Date.now() - startTime
|
|
634
|
+
});
|
|
635
|
+
throw error;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
async delete(key) {
|
|
639
|
+
const startTime = Date.now();
|
|
640
|
+
const requestId = generateRequestId4();
|
|
641
|
+
try {
|
|
642
|
+
await this.realCache.delete(key);
|
|
643
|
+
const durationMs = Date.now() - startTime;
|
|
644
|
+
await this.analytics.track("cache.delete.completed", {
|
|
645
|
+
requestId,
|
|
646
|
+
key,
|
|
647
|
+
durationMs
|
|
648
|
+
});
|
|
649
|
+
} catch (error) {
|
|
650
|
+
await this.analytics.track("cache.delete.error", {
|
|
651
|
+
requestId,
|
|
652
|
+
key,
|
|
653
|
+
error: error instanceof Error ? error.message : String(error),
|
|
654
|
+
durationMs: Date.now() - startTime
|
|
655
|
+
});
|
|
656
|
+
throw error;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
async clear(pattern) {
|
|
660
|
+
const startTime = Date.now();
|
|
661
|
+
const requestId = generateRequestId4();
|
|
662
|
+
try {
|
|
663
|
+
await this.realCache.clear(pattern);
|
|
664
|
+
const durationMs = Date.now() - startTime;
|
|
665
|
+
await this.analytics.track("cache.clear.completed", {
|
|
666
|
+
requestId,
|
|
667
|
+
pattern: pattern ?? null,
|
|
668
|
+
durationMs
|
|
669
|
+
});
|
|
670
|
+
} catch (error) {
|
|
671
|
+
await this.analytics.track("cache.clear.error", {
|
|
672
|
+
requestId,
|
|
673
|
+
pattern: pattern ?? null,
|
|
674
|
+
error: error instanceof Error ? error.message : String(error),
|
|
675
|
+
durationMs: Date.now() - startTime
|
|
676
|
+
});
|
|
677
|
+
throw error;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
async zadd(key, score, member) {
|
|
681
|
+
const startTime = Date.now();
|
|
682
|
+
const requestId = generateRequestId4();
|
|
683
|
+
try {
|
|
684
|
+
await this.realCache.zadd(key, score, member);
|
|
685
|
+
const durationMs = Date.now() - startTime;
|
|
686
|
+
await this.analytics.track("cache.zadd.completed", {
|
|
687
|
+
requestId,
|
|
688
|
+
key,
|
|
689
|
+
durationMs
|
|
690
|
+
});
|
|
691
|
+
} catch (error) {
|
|
692
|
+
await this.analytics.track("cache.zadd.error", {
|
|
693
|
+
requestId,
|
|
694
|
+
key,
|
|
695
|
+
error: error instanceof Error ? error.message : String(error),
|
|
696
|
+
durationMs: Date.now() - startTime
|
|
697
|
+
});
|
|
698
|
+
throw error;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
async zrangebyscore(key, min, max) {
|
|
702
|
+
const startTime = Date.now();
|
|
703
|
+
const requestId = generateRequestId4();
|
|
704
|
+
try {
|
|
705
|
+
const results = await this.realCache.zrangebyscore(key, min, max);
|
|
706
|
+
const durationMs = Date.now() - startTime;
|
|
707
|
+
return results;
|
|
708
|
+
} catch (error) {
|
|
709
|
+
await this.analytics.track("cache.zrangebyscore.error", {
|
|
710
|
+
requestId,
|
|
711
|
+
key,
|
|
712
|
+
error: error instanceof Error ? error.message : String(error),
|
|
713
|
+
durationMs: Date.now() - startTime
|
|
714
|
+
});
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
async zrem(key, member) {
|
|
719
|
+
const startTime = Date.now();
|
|
720
|
+
const requestId = generateRequestId4();
|
|
721
|
+
try {
|
|
722
|
+
await this.realCache.zrem(key, member);
|
|
723
|
+
const durationMs = Date.now() - startTime;
|
|
724
|
+
await this.analytics.track("cache.zrem.completed", {
|
|
725
|
+
requestId,
|
|
726
|
+
key,
|
|
727
|
+
durationMs
|
|
728
|
+
});
|
|
729
|
+
} catch (error) {
|
|
730
|
+
await this.analytics.track("cache.zrem.error", {
|
|
731
|
+
requestId,
|
|
732
|
+
key,
|
|
733
|
+
error: error instanceof Error ? error.message : String(error),
|
|
734
|
+
durationMs: Date.now() - startTime
|
|
735
|
+
});
|
|
736
|
+
throw error;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async setIfNotExists(key, value, ttl) {
|
|
740
|
+
const startTime = Date.now();
|
|
741
|
+
const requestId = generateRequestId4();
|
|
742
|
+
try {
|
|
743
|
+
const result = await this.realCache.setIfNotExists(key, value, ttl);
|
|
744
|
+
const durationMs = Date.now() - startTime;
|
|
745
|
+
await this.analytics.track("cache.setIfNotExists.completed", {
|
|
746
|
+
requestId,
|
|
747
|
+
key,
|
|
748
|
+
success: result,
|
|
749
|
+
ttl: ttl ?? null,
|
|
750
|
+
durationMs
|
|
751
|
+
});
|
|
752
|
+
return result;
|
|
753
|
+
} catch (error) {
|
|
754
|
+
await this.analytics.track("cache.setIfNotExists.error", {
|
|
755
|
+
requestId,
|
|
756
|
+
key,
|
|
757
|
+
error: error instanceof Error ? error.message : String(error),
|
|
758
|
+
durationMs: Date.now() - startTime
|
|
759
|
+
});
|
|
760
|
+
throw error;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
|
|
765
|
+
// src/wrappers/analytics-storage.ts
|
|
766
|
+
function generateRequestId5() {
|
|
767
|
+
return `storage_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
768
|
+
}
|
|
769
|
+
var AnalyticsStorage = class {
|
|
770
|
+
constructor(realStorage, analytics) {
|
|
771
|
+
this.realStorage = realStorage;
|
|
772
|
+
this.analytics = analytics;
|
|
773
|
+
}
|
|
774
|
+
async read(path3) {
|
|
775
|
+
const startTime = Date.now();
|
|
776
|
+
const requestId = generateRequestId5();
|
|
777
|
+
try {
|
|
778
|
+
const result = await this.realStorage.read(path3);
|
|
779
|
+
const durationMs = Date.now() - startTime;
|
|
780
|
+
const bytesRead = result?.length ?? 0;
|
|
781
|
+
await this.analytics.track("storage.read.completed", {
|
|
782
|
+
requestId,
|
|
783
|
+
path: path3,
|
|
784
|
+
bytesRead,
|
|
785
|
+
durationMs,
|
|
786
|
+
found: result !== null
|
|
787
|
+
});
|
|
788
|
+
return result;
|
|
789
|
+
} catch (error) {
|
|
790
|
+
await this.analytics.track("storage.read.error", {
|
|
791
|
+
requestId,
|
|
792
|
+
path: path3,
|
|
793
|
+
error: error instanceof Error ? error.message : String(error),
|
|
794
|
+
durationMs: Date.now() - startTime
|
|
795
|
+
});
|
|
796
|
+
throw error;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
async write(path3, data) {
|
|
800
|
+
const startTime = Date.now();
|
|
801
|
+
const requestId = generateRequestId5();
|
|
802
|
+
try {
|
|
803
|
+
await this.realStorage.write(path3, data);
|
|
804
|
+
const durationMs = Date.now() - startTime;
|
|
805
|
+
await this.analytics.track("storage.write.completed", {
|
|
806
|
+
requestId,
|
|
807
|
+
path: path3,
|
|
808
|
+
bytesWritten: data.length,
|
|
809
|
+
durationMs
|
|
810
|
+
});
|
|
811
|
+
} catch (error) {
|
|
812
|
+
await this.analytics.track("storage.write.error", {
|
|
813
|
+
requestId,
|
|
814
|
+
path: path3,
|
|
815
|
+
error: error instanceof Error ? error.message : String(error),
|
|
816
|
+
durationMs: Date.now() - startTime
|
|
817
|
+
});
|
|
818
|
+
throw error;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
async delete(path3) {
|
|
822
|
+
const startTime = Date.now();
|
|
823
|
+
const requestId = generateRequestId5();
|
|
824
|
+
try {
|
|
825
|
+
await this.realStorage.delete(path3);
|
|
826
|
+
const durationMs = Date.now() - startTime;
|
|
827
|
+
await this.analytics.track("storage.delete.completed", {
|
|
828
|
+
requestId,
|
|
829
|
+
path: path3,
|
|
830
|
+
durationMs
|
|
831
|
+
});
|
|
832
|
+
} catch (error) {
|
|
833
|
+
await this.analytics.track("storage.delete.error", {
|
|
834
|
+
requestId,
|
|
835
|
+
path: path3,
|
|
836
|
+
error: error instanceof Error ? error.message : String(error),
|
|
837
|
+
durationMs: Date.now() - startTime
|
|
838
|
+
});
|
|
839
|
+
throw error;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
async list(prefix) {
|
|
843
|
+
const startTime = Date.now();
|
|
844
|
+
const requestId = generateRequestId5();
|
|
845
|
+
try {
|
|
846
|
+
const results = await this.realStorage.list(prefix);
|
|
847
|
+
const durationMs = Date.now() - startTime;
|
|
848
|
+
await this.analytics.track("storage.list.completed", {
|
|
849
|
+
requestId,
|
|
850
|
+
prefix,
|
|
851
|
+
filesCount: results.length,
|
|
852
|
+
durationMs
|
|
853
|
+
});
|
|
854
|
+
return results;
|
|
855
|
+
} catch (error) {
|
|
856
|
+
await this.analytics.track("storage.list.error", {
|
|
857
|
+
requestId,
|
|
858
|
+
prefix,
|
|
859
|
+
error: error instanceof Error ? error.message : String(error),
|
|
860
|
+
durationMs: Date.now() - startTime
|
|
861
|
+
});
|
|
862
|
+
throw error;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
async exists(path3) {
|
|
866
|
+
const startTime = Date.now();
|
|
867
|
+
const requestId = generateRequestId5();
|
|
868
|
+
try {
|
|
869
|
+
const result = await this.realStorage.exists(path3);
|
|
870
|
+
const durationMs = Date.now() - startTime;
|
|
871
|
+
await this.analytics.track("storage.exists.completed", {
|
|
872
|
+
requestId,
|
|
873
|
+
path: path3,
|
|
874
|
+
exists: result,
|
|
875
|
+
durationMs
|
|
876
|
+
});
|
|
877
|
+
return result;
|
|
878
|
+
} catch (error) {
|
|
879
|
+
await this.analytics.track("storage.exists.error", {
|
|
880
|
+
requestId,
|
|
881
|
+
path: path3,
|
|
882
|
+
error: error instanceof Error ? error.message : String(error),
|
|
883
|
+
durationMs: Date.now() - startTime
|
|
884
|
+
});
|
|
885
|
+
throw error;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
// src/wrappers/scoped-analytics.ts
|
|
891
|
+
var ScopedAnalytics = class {
|
|
892
|
+
constructor(realAnalytics, scopedSource) {
|
|
893
|
+
this.realAnalytics = realAnalytics;
|
|
894
|
+
this.scopedSource = scopedSource;
|
|
895
|
+
if (realAnalytics.setSource) {
|
|
896
|
+
realAnalytics.setSource(scopedSource);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
async track(event, properties) {
|
|
900
|
+
await this.realAnalytics.track(event, properties);
|
|
901
|
+
}
|
|
902
|
+
async identify(userId, traits) {
|
|
903
|
+
await this.realAnalytics.identify(userId, traits);
|
|
904
|
+
}
|
|
905
|
+
async flush() {
|
|
906
|
+
await this.realAnalytics.flush();
|
|
907
|
+
}
|
|
908
|
+
// Optional methods - delegate if available
|
|
909
|
+
async getEvents(query) {
|
|
910
|
+
if (!this.realAnalytics.getEvents) {
|
|
911
|
+
throw new Error("getEvents not supported by underlying analytics adapter");
|
|
912
|
+
}
|
|
913
|
+
return this.realAnalytics.getEvents(query);
|
|
914
|
+
}
|
|
915
|
+
async getStats() {
|
|
916
|
+
if (!this.realAnalytics.getStats) {
|
|
917
|
+
throw new Error("getStats not supported by underlying analytics adapter");
|
|
918
|
+
}
|
|
919
|
+
return this.realAnalytics.getStats();
|
|
920
|
+
}
|
|
921
|
+
async getBufferStatus() {
|
|
922
|
+
if (!this.realAnalytics.getBufferStatus) {
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
return this.realAnalytics.getBufferStatus();
|
|
926
|
+
}
|
|
927
|
+
async getDlqStatus() {
|
|
928
|
+
if (!this.realAnalytics.getDlqStatus) {
|
|
929
|
+
return null;
|
|
930
|
+
}
|
|
931
|
+
return this.realAnalytics.getDlqStatus();
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* Get current source from underlying adapter
|
|
935
|
+
*/
|
|
936
|
+
getSource() {
|
|
937
|
+
if (this.realAnalytics.getSource) {
|
|
938
|
+
return this.realAnalytics.getSource();
|
|
939
|
+
}
|
|
940
|
+
return this.scopedSource;
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Delegate setSource to underlying adapter
|
|
944
|
+
*/
|
|
945
|
+
setSource(source) {
|
|
946
|
+
if (this.realAnalytics.setSource) {
|
|
947
|
+
this.realAnalytics.setSource(source);
|
|
948
|
+
}
|
|
949
|
+
this.scopedSource = source;
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Get the scoped source (for testing/debugging)
|
|
953
|
+
*/
|
|
954
|
+
getScopedSource() {
|
|
955
|
+
return this.scopedSource;
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Get the underlying analytics adapter (for introspection)
|
|
959
|
+
*/
|
|
960
|
+
getUnderlyingAdapter() {
|
|
961
|
+
return this.realAnalytics;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
function createScopedAnalytics(analytics, scopedSource) {
|
|
965
|
+
return new ScopedAnalytics(analytics, scopedSource);
|
|
966
|
+
}
|
|
967
|
+
function isScopedAnalytics(analytics) {
|
|
968
|
+
return analytics instanceof ScopedAnalytics;
|
|
969
|
+
}
|
|
970
|
+
function unwrapScopedAnalytics(analytics) {
|
|
971
|
+
if (isScopedAnalytics(analytics)) {
|
|
972
|
+
return analytics.getUnderlyingAdapter();
|
|
973
|
+
}
|
|
974
|
+
return analytics;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// src/logging/prefixed-logger.ts
|
|
978
|
+
var SYSTEM_LOG_FIELDS = /* @__PURE__ */ new Set([
|
|
979
|
+
// Core observability
|
|
980
|
+
"reqId",
|
|
981
|
+
"requestId",
|
|
982
|
+
"traceId",
|
|
983
|
+
"spanId",
|
|
984
|
+
"parentSpanId",
|
|
985
|
+
"invocationId",
|
|
986
|
+
"executionId",
|
|
987
|
+
"tenantId",
|
|
988
|
+
"layer",
|
|
989
|
+
// REST context
|
|
990
|
+
"method",
|
|
991
|
+
"url",
|
|
992
|
+
// Workflow context
|
|
993
|
+
"workflowId",
|
|
994
|
+
"runId",
|
|
995
|
+
"stepId",
|
|
996
|
+
"jobId",
|
|
997
|
+
"attempt",
|
|
998
|
+
// Webhook context
|
|
999
|
+
"event",
|
|
1000
|
+
"source",
|
|
1001
|
+
// Cron context
|
|
1002
|
+
"cronId",
|
|
1003
|
+
"schedule",
|
|
1004
|
+
"scheduledAt",
|
|
1005
|
+
"lastRunAt"
|
|
1006
|
+
]);
|
|
1007
|
+
function createPrefixedLogger(baseLogger, options = {}) {
|
|
1008
|
+
const {
|
|
1009
|
+
prefix = "plugin_",
|
|
1010
|
+
warnOnRename = true,
|
|
1011
|
+
protectedFields = SYSTEM_LOG_FIELDS
|
|
1012
|
+
} = options;
|
|
1013
|
+
return {
|
|
1014
|
+
// Proxy all log methods (defensive check for bind)
|
|
1015
|
+
trace: baseLogger.trace?.bind ? baseLogger.trace.bind(baseLogger) : baseLogger.trace,
|
|
1016
|
+
debug: baseLogger.debug?.bind ? baseLogger.debug.bind(baseLogger) : baseLogger.debug,
|
|
1017
|
+
info: baseLogger.info?.bind ? baseLogger.info.bind(baseLogger) : baseLogger.info,
|
|
1018
|
+
warn: baseLogger.warn?.bind ? baseLogger.warn.bind(baseLogger) : baseLogger.warn,
|
|
1019
|
+
error: baseLogger.error?.bind ? baseLogger.error.bind(baseLogger) : baseLogger.error,
|
|
1020
|
+
fatal: baseLogger.fatal?.bind ? baseLogger.fatal.bind(baseLogger) : baseLogger.fatal,
|
|
1021
|
+
// Proxy optional log buffer
|
|
1022
|
+
getLogBuffer: baseLogger.getLogBuffer?.bind ? baseLogger.getLogBuffer.bind(baseLogger) : baseLogger.getLogBuffer,
|
|
1023
|
+
// Wrap child() to add prefixing
|
|
1024
|
+
child(fields) {
|
|
1025
|
+
const prefixed = {};
|
|
1026
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
1027
|
+
if (protectedFields.has(key)) {
|
|
1028
|
+
const newKey = `${prefix}${key}`;
|
|
1029
|
+
prefixed[newKey] = value;
|
|
1030
|
+
if (warnOnRename && process.env.NODE_ENV !== "production") {
|
|
1031
|
+
console.warn(
|
|
1032
|
+
`[Logger] Field "${key}" is reserved for system observability. Renamed to "${newKey}".`
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
} else {
|
|
1036
|
+
prefixed[key] = value;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
return createPrefixedLogger(baseLogger.child(prefixed), options);
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
var MemoryHistoryStore = class {
|
|
1044
|
+
entries = [];
|
|
1045
|
+
maxEntries;
|
|
1046
|
+
constructor(maxEntries = 1e4) {
|
|
1047
|
+
this.maxEntries = maxEntries;
|
|
1048
|
+
}
|
|
1049
|
+
async save(record) {
|
|
1050
|
+
this.entries.push(record);
|
|
1051
|
+
if (this.entries.length > this.maxEntries) {
|
|
1052
|
+
this.entries.shift();
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
async find(options) {
|
|
1056
|
+
const { scopeId, queryHash, queryVector, limit = 10 } = options;
|
|
1057
|
+
let results = this.entries.filter((entry) => entry.scopeId === scopeId);
|
|
1058
|
+
if (queryHash) {
|
|
1059
|
+
results = results.filter((entry) => entry.queryHash === queryHash);
|
|
1060
|
+
}
|
|
1061
|
+
if (queryVector && queryVector.length > 0) {
|
|
1062
|
+
results = results.map((entry) => {
|
|
1063
|
+
const similarity = entry.queryVector ? this.cosineSimilarity(queryVector, entry.queryVector) : 0;
|
|
1064
|
+
return { entry, similarity };
|
|
1065
|
+
}).filter((item) => item.similarity > 0.7).sort((a, b) => b.similarity - a.similarity).slice(0, limit).map((item) => item.entry);
|
|
1066
|
+
} else {
|
|
1067
|
+
results = results.slice(0, limit);
|
|
1068
|
+
}
|
|
1069
|
+
return results;
|
|
1070
|
+
}
|
|
1071
|
+
async popular(scopeId, limit = 20) {
|
|
1072
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1073
|
+
for (const entry of this.entries) {
|
|
1074
|
+
if (entry.scopeId !== scopeId) {
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
const count = counts.get(entry.query) ?? 0;
|
|
1078
|
+
counts.set(entry.query, count + 1);
|
|
1079
|
+
}
|
|
1080
|
+
return Array.from(counts.entries()).map(([query, count]) => ({ query, count })).sort((a, b) => b.count - a.count).slice(0, limit);
|
|
1081
|
+
}
|
|
1082
|
+
async saveReasoningPlan(record) {
|
|
1083
|
+
const targetHash = record.queryHash ?? crypto.createHash("sha256").update(record.query.toLowerCase().trim()).digest("hex");
|
|
1084
|
+
const matches = this.entries.filter((entry) => entry.scopeId === record.scopeId && entry.queryHash === targetHash);
|
|
1085
|
+
if (matches.length === 0) {
|
|
1086
|
+
await this.save({ ...record, queryHash: targetHash });
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
for (const entry of matches) {
|
|
1090
|
+
entry.reasoningPlan = record.reasoningPlan;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
cosineSimilarity(vec1, vec2) {
|
|
1094
|
+
if (vec1.length !== vec2.length) {
|
|
1095
|
+
return 0;
|
|
1096
|
+
}
|
|
1097
|
+
let dot = 0;
|
|
1098
|
+
let norm1 = 0;
|
|
1099
|
+
let norm2 = 0;
|
|
1100
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
1101
|
+
dot += vec1[i] * vec2[i];
|
|
1102
|
+
norm1 += vec1[i] * vec1[i];
|
|
1103
|
+
norm2 += vec2[i] * vec2[i];
|
|
1104
|
+
}
|
|
1105
|
+
const denom = Math.sqrt(norm1) * Math.sqrt(norm2);
|
|
1106
|
+
return denom === 0 ? 0 : dot / denom;
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
// src/learning/memory-feedback-store.ts
|
|
1111
|
+
var MemoryFeedbackStore = class {
|
|
1112
|
+
entries = [];
|
|
1113
|
+
maxEntries;
|
|
1114
|
+
constructor(maxEntries = 1e4) {
|
|
1115
|
+
this.maxEntries = maxEntries;
|
|
1116
|
+
}
|
|
1117
|
+
async save(record) {
|
|
1118
|
+
this.entries.push(record);
|
|
1119
|
+
if (this.entries.length > this.maxEntries) {
|
|
1120
|
+
this.entries.shift();
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
async list(scopeId, limit = 100) {
|
|
1124
|
+
const scoped = this.entries.filter((entry) => entry.scopeId === scopeId);
|
|
1125
|
+
return scoped.slice(-limit);
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
var FileHistoryStore = class {
|
|
1129
|
+
constructor(storage, options = {}) {
|
|
1130
|
+
this.storage = storage;
|
|
1131
|
+
this.basePath = options.basePath ? this.ensureTrailingSlash(options.basePath) : ".kb/mind/learning/history/";
|
|
1132
|
+
this.filePrefix = options.filePrefix ?? "history-";
|
|
1133
|
+
this.maxRecordsPerFile = options.maxRecordsPerFile ?? 1e3;
|
|
1134
|
+
this.maxFiles = options.maxFiles ?? 30;
|
|
1135
|
+
}
|
|
1136
|
+
basePath;
|
|
1137
|
+
filePrefix;
|
|
1138
|
+
maxRecordsPerFile;
|
|
1139
|
+
maxFiles;
|
|
1140
|
+
async save(record) {
|
|
1141
|
+
const target = await this.getWritableFile();
|
|
1142
|
+
const line = JSON.stringify({ v: 1, record }) + "\n";
|
|
1143
|
+
try {
|
|
1144
|
+
const existing = await this.storage.read(target);
|
|
1145
|
+
const buffer = existing ? Buffer.concat([existing, Buffer.from(line, "utf8")]) : Buffer.from(line, "utf8");
|
|
1146
|
+
await this.storage.write(target, buffer);
|
|
1147
|
+
await this.enforceRotation();
|
|
1148
|
+
} catch (error) {
|
|
1149
|
+
console.error("[FileHistoryStore] Failed to write history", {
|
|
1150
|
+
target,
|
|
1151
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
async find(options) {
|
|
1156
|
+
const files = await this.getFilesSorted();
|
|
1157
|
+
const results = [];
|
|
1158
|
+
for (const file of files) {
|
|
1159
|
+
if (options.limit && results.length >= options.limit) {
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
const buf = await this.storage.read(file);
|
|
1163
|
+
if (!buf) {
|
|
1164
|
+
continue;
|
|
1165
|
+
}
|
|
1166
|
+
const lines = buf.toString("utf8").split("\n").filter(Boolean);
|
|
1167
|
+
for (const line of lines) {
|
|
1168
|
+
if (options.limit && results.length >= options.limit) {
|
|
1169
|
+
break;
|
|
1170
|
+
}
|
|
1171
|
+
try {
|
|
1172
|
+
const parsed = JSON.parse(line);
|
|
1173
|
+
const rec = parsed.record;
|
|
1174
|
+
if (rec.scopeId !== options.scopeId) {
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
if (options.queryHash && rec.queryHash !== options.queryHash) {
|
|
1178
|
+
continue;
|
|
1179
|
+
}
|
|
1180
|
+
if (options.queryVector && options.queryVector.length > 0 && rec.queryVector) {
|
|
1181
|
+
const similarity = this.cosineSimilarity(options.queryVector, rec.queryVector);
|
|
1182
|
+
if (similarity <= 0.7) {
|
|
1183
|
+
continue;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
results.push(rec);
|
|
1187
|
+
} catch {
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return options.limit ? results.slice(0, options.limit) : results;
|
|
1193
|
+
}
|
|
1194
|
+
async popular(scopeId, limit = 20) {
|
|
1195
|
+
const files = await this.getFilesSorted();
|
|
1196
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1197
|
+
for (const file of files) {
|
|
1198
|
+
const buf = await this.storage.read(file);
|
|
1199
|
+
if (!buf) {
|
|
1200
|
+
continue;
|
|
1201
|
+
}
|
|
1202
|
+
const lines = buf.toString("utf8").split("\n").filter(Boolean);
|
|
1203
|
+
for (const line of lines) {
|
|
1204
|
+
try {
|
|
1205
|
+
const parsed = JSON.parse(line);
|
|
1206
|
+
const rec = parsed.record;
|
|
1207
|
+
if (rec.scopeId !== scopeId) {
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
counts.set(rec.query, (counts.get(rec.query) ?? 0) + 1);
|
|
1211
|
+
} catch {
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
return Array.from(counts.entries()).map(([query, count]) => ({ query, count })).sort((a, b) => b.count - a.count).slice(0, limit);
|
|
1217
|
+
}
|
|
1218
|
+
async saveReasoningPlan(record) {
|
|
1219
|
+
const hash = record.queryHash ?? crypto.createHash("sha256").update(record.query.toLowerCase().trim()).digest("hex");
|
|
1220
|
+
await this.save({ ...record, queryHash: hash });
|
|
1221
|
+
}
|
|
1222
|
+
async getWritableFile() {
|
|
1223
|
+
const files = await this.getFilesSorted();
|
|
1224
|
+
if (files.length === 0) {
|
|
1225
|
+
return this.segmentPath(Date.now());
|
|
1226
|
+
}
|
|
1227
|
+
const latest = files[files.length - 1];
|
|
1228
|
+
const buf = await this.storage.read(latest);
|
|
1229
|
+
if (!buf) {
|
|
1230
|
+
return latest;
|
|
1231
|
+
}
|
|
1232
|
+
const count = buf.toString("utf8").split("\n").filter(Boolean).length;
|
|
1233
|
+
if (count >= this.maxRecordsPerFile) {
|
|
1234
|
+
return this.segmentPath(Date.now());
|
|
1235
|
+
}
|
|
1236
|
+
return latest;
|
|
1237
|
+
}
|
|
1238
|
+
async getFilesSorted() {
|
|
1239
|
+
const files = await this.storage.list(this.basePath);
|
|
1240
|
+
return files.filter((f) => f.startsWith(this.basePath + this.filePrefix) && f.endsWith(".jsonl")).sort();
|
|
1241
|
+
}
|
|
1242
|
+
segmentPath(ts) {
|
|
1243
|
+
const date = new Date(ts);
|
|
1244
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1245
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1246
|
+
const year = date.getFullYear();
|
|
1247
|
+
const filename = `${this.filePrefix}${year}${month}${day}-${ts}.jsonl`;
|
|
1248
|
+
return path__default.default.posix.join(this.basePath, filename);
|
|
1249
|
+
}
|
|
1250
|
+
async enforceRotation() {
|
|
1251
|
+
const files = await this.getFilesSorted();
|
|
1252
|
+
if (files.length <= this.maxFiles) {
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
const excess = files.length - this.maxFiles;
|
|
1256
|
+
const toDelete = files.slice(0, excess);
|
|
1257
|
+
await Promise.all(toDelete.map((f) => this.storage.delete(f)));
|
|
1258
|
+
}
|
|
1259
|
+
ensureTrailingSlash(p) {
|
|
1260
|
+
return p.endsWith("/") ? p : `${p}/`;
|
|
1261
|
+
}
|
|
1262
|
+
cosineSimilarity(vec1, vec2) {
|
|
1263
|
+
if (vec1.length !== vec2.length) {
|
|
1264
|
+
return 0;
|
|
1265
|
+
}
|
|
1266
|
+
let dot = 0;
|
|
1267
|
+
let norm1 = 0;
|
|
1268
|
+
let norm2 = 0;
|
|
1269
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
1270
|
+
dot += vec1[i] * vec2[i];
|
|
1271
|
+
norm1 += vec1[i] * vec1[i];
|
|
1272
|
+
norm2 += vec2[i] * vec2[i];
|
|
1273
|
+
}
|
|
1274
|
+
const denom = Math.sqrt(norm1) * Math.sqrt(norm2);
|
|
1275
|
+
return denom === 0 ? 0 : dot / denom;
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
var FileFeedbackStore = class {
|
|
1279
|
+
constructor(storage, options = {}) {
|
|
1280
|
+
this.storage = storage;
|
|
1281
|
+
this.basePath = options.basePath ? this.ensureTrailingSlash(options.basePath) : ".kb/mind/learning/feedback/";
|
|
1282
|
+
this.filePrefix = options.filePrefix ?? "feedback-";
|
|
1283
|
+
this.maxRecordsPerFile = options.maxRecordsPerFile ?? 1e3;
|
|
1284
|
+
this.maxFiles = options.maxFiles ?? 30;
|
|
1285
|
+
}
|
|
1286
|
+
basePath;
|
|
1287
|
+
filePrefix;
|
|
1288
|
+
maxRecordsPerFile;
|
|
1289
|
+
maxFiles;
|
|
1290
|
+
async save(record) {
|
|
1291
|
+
const target = await this.getWritableFile();
|
|
1292
|
+
const line = JSON.stringify({ v: 1, record }) + "\n";
|
|
1293
|
+
try {
|
|
1294
|
+
const existing = await this.storage.read(target);
|
|
1295
|
+
const buffer = existing ? Buffer.concat([existing, Buffer.from(line, "utf8")]) : Buffer.from(line, "utf8");
|
|
1296
|
+
await this.storage.write(target, buffer);
|
|
1297
|
+
await this.enforceRotation();
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
console.error("[FileFeedbackStore] Failed to write feedback", {
|
|
1300
|
+
target,
|
|
1301
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
async list(scopeId, limit = 100) {
|
|
1306
|
+
const files = await this.getFilesSorted();
|
|
1307
|
+
const results = [];
|
|
1308
|
+
for (const file of files) {
|
|
1309
|
+
if (results.length >= limit) {
|
|
1310
|
+
break;
|
|
1311
|
+
}
|
|
1312
|
+
const buf = await this.storage.read(file);
|
|
1313
|
+
if (!buf) {
|
|
1314
|
+
continue;
|
|
1315
|
+
}
|
|
1316
|
+
const lines = buf.toString("utf8").split("\n").filter(Boolean);
|
|
1317
|
+
for (const line of lines) {
|
|
1318
|
+
if (results.length >= limit) {
|
|
1319
|
+
break;
|
|
1320
|
+
}
|
|
1321
|
+
try {
|
|
1322
|
+
const parsed = JSON.parse(line);
|
|
1323
|
+
const rec = parsed.record;
|
|
1324
|
+
if (rec.scopeId !== scopeId) {
|
|
1325
|
+
continue;
|
|
1326
|
+
}
|
|
1327
|
+
results.push(rec);
|
|
1328
|
+
} catch {
|
|
1329
|
+
continue;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
return results.slice(-limit);
|
|
1334
|
+
}
|
|
1335
|
+
async getWritableFile() {
|
|
1336
|
+
const files = await this.getFilesSorted();
|
|
1337
|
+
if (files.length === 0) {
|
|
1338
|
+
return this.segmentPath(Date.now());
|
|
1339
|
+
}
|
|
1340
|
+
const latest = files[files.length - 1];
|
|
1341
|
+
const buf = await this.storage.read(latest);
|
|
1342
|
+
if (!buf) {
|
|
1343
|
+
return latest;
|
|
1344
|
+
}
|
|
1345
|
+
const count = buf.toString("utf8").split("\n").filter(Boolean).length;
|
|
1346
|
+
if (count >= this.maxRecordsPerFile) {
|
|
1347
|
+
return this.segmentPath(Date.now());
|
|
1348
|
+
}
|
|
1349
|
+
return latest;
|
|
1350
|
+
}
|
|
1351
|
+
async getFilesSorted() {
|
|
1352
|
+
const files = await this.storage.list(this.basePath);
|
|
1353
|
+
return files.filter((f) => f.startsWith(this.basePath + this.filePrefix) && f.endsWith(".jsonl")).sort();
|
|
1354
|
+
}
|
|
1355
|
+
segmentPath(ts) {
|
|
1356
|
+
const date = new Date(ts);
|
|
1357
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1358
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1359
|
+
const year = date.getFullYear();
|
|
1360
|
+
const filename = `${this.filePrefix}${year}${month}${day}-${ts}.jsonl`;
|
|
1361
|
+
return path__default.default.posix.join(this.basePath, filename);
|
|
1362
|
+
}
|
|
1363
|
+
async enforceRotation() {
|
|
1364
|
+
const files = await this.getFilesSorted();
|
|
1365
|
+
if (files.length <= this.maxFiles) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
const excess = files.length - this.maxFiles;
|
|
1369
|
+
const toDelete = files.slice(0, excess);
|
|
1370
|
+
await Promise.all(toDelete.map((f) => this.storage.delete(f)));
|
|
1371
|
+
}
|
|
1372
|
+
ensureTrailingSlash(p) {
|
|
1373
|
+
return p.endsWith("/") ? p : `${p}/`;
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// src/runs/run-types.ts
|
|
1378
|
+
var TERMINAL_RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
1379
|
+
"completed",
|
|
1380
|
+
"failed",
|
|
1381
|
+
"failed_by_review",
|
|
1382
|
+
"cancelled"
|
|
1383
|
+
]);
|
|
1384
|
+
|
|
1385
|
+
exports.AnalyticsCache = AnalyticsCache;
|
|
1386
|
+
exports.AnalyticsEmbeddings = AnalyticsEmbeddings;
|
|
1387
|
+
exports.AnalyticsLLM = AnalyticsLLM;
|
|
1388
|
+
exports.AnalyticsStorage = AnalyticsStorage;
|
|
1389
|
+
exports.AnalyticsVectorStore = AnalyticsVectorStore;
|
|
1390
|
+
exports.FileFeedbackStore = FileFeedbackStore;
|
|
1391
|
+
exports.FileHistoryStore = FileHistoryStore;
|
|
1392
|
+
exports.MemoryFeedbackStore = MemoryFeedbackStore;
|
|
1393
|
+
exports.MemoryHistoryStore = MemoryHistoryStore;
|
|
1394
|
+
exports.SYSTEM_LOG_FIELDS = SYSTEM_LOG_FIELDS;
|
|
1395
|
+
exports.ScopedAnalytics = ScopedAnalytics;
|
|
1396
|
+
exports.TERMINAL_RUN_STATUSES = TERMINAL_RUN_STATUSES;
|
|
1397
|
+
exports.TIER_ORDER = TIER_ORDER;
|
|
1398
|
+
exports.createPrefixedLogger = createPrefixedLogger;
|
|
1399
|
+
exports.createScopedAnalytics = createScopedAnalytics;
|
|
1400
|
+
exports.isScopedAnalytics = isScopedAnalytics;
|
|
1401
|
+
exports.isTierHigher = isTierHigher;
|
|
1402
|
+
exports.isTierLower = isTierLower;
|
|
1403
|
+
exports.unwrapScopedAnalytics = unwrapScopedAnalytics;
|
|
1404
|
+
//# sourceMappingURL=index.cjs.map
|
|
1405
|
+
//# sourceMappingURL=index.cjs.map
|