@rce-mcp/data-plane 0.1.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/dist/.tsbuildinfo +1 -0
- package/dist/index.d.ts +633 -0
- package/dist/index.js +2207 -0
- package/dist/sqlite-runtime.d.ts +18 -0
- package/dist/sqlite-runtime.js +71 -0
- package/package.json +22 -0
- package/src/index.ts +3393 -0
- package/src/sqlite-runtime.ts +137 -0
- package/test/ioredis-mock.d.ts +1 -0
- package/test/queue.integration.test.ts +129 -0
- package/test/runtime-mode.test.ts +56 -0
- package/test/sqlite-queue.integration.test.ts +54 -0
- package/test/usage-metering.integration.test.ts +71 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +4 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
import { Pool } from "pg";
|
|
2
|
+
import { type Redis as RedisClient } from "ioredis";
|
|
3
|
+
import type { SearchContextOutput } from "@rce-mcp/contracts";
|
|
4
|
+
import { sqliteRuntimeDriverName } from "./sqlite-runtime.js";
|
|
5
|
+
export { sqliteRuntimeDriverName } from "./sqlite-runtime.js";
|
|
6
|
+
export type RuntimeMode = "cloud" | "local" | "hybrid";
|
|
7
|
+
export type LocalSqliteRuntime = ReturnType<typeof sqliteRuntimeDriverName>;
|
|
8
|
+
export declare const CLOUD_REQUIRED_ENV_VARS: readonly ["DATABASE_URL", "REDIS_URL", "S3_BUCKET", "S3_REGION", "S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"];
|
|
9
|
+
export interface RuntimeModeResolution {
|
|
10
|
+
requested_mode: RuntimeMode;
|
|
11
|
+
effective_mode: "cloud" | "local";
|
|
12
|
+
cloud_configured: boolean;
|
|
13
|
+
missing_cloud_vars: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function parseRuntimeMode(value: string | undefined): RuntimeMode;
|
|
16
|
+
export declare function missingCloudRuntimeEnvVars(env: NodeJS.ProcessEnv): string[];
|
|
17
|
+
export declare function isCloudRuntimeConfigured(env: NodeJS.ProcessEnv): boolean;
|
|
18
|
+
export declare function resolveRuntimeMode(env: NodeJS.ProcessEnv): RuntimeModeResolution;
|
|
19
|
+
export interface CandidateScoreWeights {
|
|
20
|
+
lexical_weight: number;
|
|
21
|
+
vector_weight: number;
|
|
22
|
+
path_match_boost: number;
|
|
23
|
+
recency_boost: number;
|
|
24
|
+
generated_penalty: number;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkspaceRecord {
|
|
27
|
+
workspace_id: string;
|
|
28
|
+
tenant_id: string;
|
|
29
|
+
project_root_path: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ReadyIndexRecord {
|
|
33
|
+
index_id: string;
|
|
34
|
+
workspace_id: string;
|
|
35
|
+
tenant_id: string;
|
|
36
|
+
index_version: string;
|
|
37
|
+
status: "indexing" | "ready" | "failed";
|
|
38
|
+
created_at: string;
|
|
39
|
+
updated_at: string;
|
|
40
|
+
}
|
|
41
|
+
export interface IndexMetadataRecord {
|
|
42
|
+
embedding_provider: string;
|
|
43
|
+
embedding_model?: string;
|
|
44
|
+
embedding_dimensions: number;
|
|
45
|
+
embedding_version?: string;
|
|
46
|
+
chunking_strategy: "language_aware" | "sliding";
|
|
47
|
+
chunking_fallback_strategy: "sliding";
|
|
48
|
+
created_at: string;
|
|
49
|
+
}
|
|
50
|
+
export interface RankChunksInput {
|
|
51
|
+
tenant_id: string;
|
|
52
|
+
index_id: string;
|
|
53
|
+
query: string;
|
|
54
|
+
query_embedding: number[];
|
|
55
|
+
query_tokens: string[];
|
|
56
|
+
top_k: number;
|
|
57
|
+
candidate_weights?: CandidateScoreWeights;
|
|
58
|
+
filters?: {
|
|
59
|
+
language?: string;
|
|
60
|
+
path_prefix?: string;
|
|
61
|
+
glob?: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export interface RankedChunkCandidate {
|
|
65
|
+
chunk_id: string;
|
|
66
|
+
file_id: string;
|
|
67
|
+
path: string;
|
|
68
|
+
start_line: number;
|
|
69
|
+
end_line: number;
|
|
70
|
+
snippet: string;
|
|
71
|
+
language?: string;
|
|
72
|
+
generated?: boolean;
|
|
73
|
+
updated_at: string;
|
|
74
|
+
score: number;
|
|
75
|
+
lexical_score: number;
|
|
76
|
+
vector_score: number;
|
|
77
|
+
path_match: boolean;
|
|
78
|
+
recency_boosted: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface PersistedChunk {
|
|
81
|
+
chunk_id: string;
|
|
82
|
+
file_id: string;
|
|
83
|
+
path: string;
|
|
84
|
+
start_line: number;
|
|
85
|
+
end_line: number;
|
|
86
|
+
snippet: string;
|
|
87
|
+
language?: string;
|
|
88
|
+
generated?: boolean;
|
|
89
|
+
updated_at: string;
|
|
90
|
+
embedding: number[];
|
|
91
|
+
}
|
|
92
|
+
export interface PersistedFileRecord {
|
|
93
|
+
file_id: string;
|
|
94
|
+
repo_path: string;
|
|
95
|
+
content_hash: string;
|
|
96
|
+
language?: string;
|
|
97
|
+
}
|
|
98
|
+
export interface UpsertFileInput {
|
|
99
|
+
tenant_id: string;
|
|
100
|
+
index_id: string;
|
|
101
|
+
repo_path: string;
|
|
102
|
+
content_hash: string;
|
|
103
|
+
size_bytes: number;
|
|
104
|
+
language?: string;
|
|
105
|
+
warning_metadata?: Record<string, unknown>;
|
|
106
|
+
updated_at?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface UpsertChunkInput {
|
|
109
|
+
start_line: number;
|
|
110
|
+
end_line: number;
|
|
111
|
+
snippet: string;
|
|
112
|
+
embedding: number[];
|
|
113
|
+
generated?: boolean;
|
|
114
|
+
updated_at?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface IndexRepository {
|
|
117
|
+
migrate(): Promise<void>;
|
|
118
|
+
upsertWorkspace(input: WorkspaceRecord): Promise<void>;
|
|
119
|
+
resolveWorkspaceByProjectRoot(tenant_id: string, project_root_path: string): Promise<WorkspaceRecord | undefined>;
|
|
120
|
+
resolveWorkspaceByWorkspaceId(tenant_id: string, workspace_id: string): Promise<WorkspaceRecord | undefined>;
|
|
121
|
+
createIndexVersion(input: {
|
|
122
|
+
tenant_id: string;
|
|
123
|
+
workspace_id: string;
|
|
124
|
+
index_version: string;
|
|
125
|
+
status?: "indexing" | "ready" | "failed";
|
|
126
|
+
}): Promise<ReadyIndexRecord>;
|
|
127
|
+
markIndexStatus(input: {
|
|
128
|
+
tenant_id: string;
|
|
129
|
+
workspace_id: string;
|
|
130
|
+
index_id: string;
|
|
131
|
+
status: "indexing" | "ready" | "failed";
|
|
132
|
+
}): Promise<void>;
|
|
133
|
+
getIndexByVersion(input: {
|
|
134
|
+
tenant_id: string;
|
|
135
|
+
workspace_id: string;
|
|
136
|
+
index_version: string;
|
|
137
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
138
|
+
resetIndexContent(input: {
|
|
139
|
+
tenant_id: string;
|
|
140
|
+
index_id: string;
|
|
141
|
+
}): Promise<void>;
|
|
142
|
+
getLatestReadyIndex(input: {
|
|
143
|
+
tenant_id: string;
|
|
144
|
+
workspace_id: string;
|
|
145
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
146
|
+
getFilesByIndex(input: {
|
|
147
|
+
tenant_id: string;
|
|
148
|
+
index_id: string;
|
|
149
|
+
}): Promise<PersistedFileRecord[]>;
|
|
150
|
+
copyFileFromIndex(input: {
|
|
151
|
+
tenant_id: string;
|
|
152
|
+
source_index_id: string;
|
|
153
|
+
target_index_id: string;
|
|
154
|
+
repo_path: string;
|
|
155
|
+
}): Promise<void>;
|
|
156
|
+
upsertFile(input: UpsertFileInput): Promise<{
|
|
157
|
+
file_id: string;
|
|
158
|
+
}>;
|
|
159
|
+
replaceFileChunks(input: {
|
|
160
|
+
tenant_id: string;
|
|
161
|
+
file_id: string;
|
|
162
|
+
repo_path: string;
|
|
163
|
+
chunks: UpsertChunkInput[];
|
|
164
|
+
}): Promise<void>;
|
|
165
|
+
saveManifest(input: {
|
|
166
|
+
index_id: string;
|
|
167
|
+
object_key: string;
|
|
168
|
+
checksum: string;
|
|
169
|
+
}): Promise<void>;
|
|
170
|
+
saveIndexMetadata?(input: {
|
|
171
|
+
tenant_id: string;
|
|
172
|
+
index_id: string;
|
|
173
|
+
embedding_provider: string;
|
|
174
|
+
embedding_model?: string;
|
|
175
|
+
embedding_dimensions: number;
|
|
176
|
+
embedding_version?: string;
|
|
177
|
+
chunking_strategy: "language_aware" | "sliding";
|
|
178
|
+
chunking_fallback_strategy: "sliding";
|
|
179
|
+
}): Promise<void>;
|
|
180
|
+
getIndexMetadata?(input: {
|
|
181
|
+
tenant_id: string;
|
|
182
|
+
index_id: string;
|
|
183
|
+
}): Promise<IndexMetadataRecord | undefined>;
|
|
184
|
+
listChunksByIndex(input: {
|
|
185
|
+
tenant_id: string;
|
|
186
|
+
index_id: string;
|
|
187
|
+
filters?: {
|
|
188
|
+
language?: string;
|
|
189
|
+
path_prefix?: string;
|
|
190
|
+
glob?: string;
|
|
191
|
+
};
|
|
192
|
+
}): Promise<PersistedChunk[]>;
|
|
193
|
+
rankChunksByIndex?(input: RankChunksInput): Promise<RankedChunkCandidate[]>;
|
|
194
|
+
}
|
|
195
|
+
export declare class SqliteIndexRepository implements IndexRepository {
|
|
196
|
+
private readonly dbPath;
|
|
197
|
+
private readonly db;
|
|
198
|
+
constructor(dbPath: string);
|
|
199
|
+
close(): void;
|
|
200
|
+
migrate(): Promise<void>;
|
|
201
|
+
upsertWorkspace(input: WorkspaceRecord): Promise<void>;
|
|
202
|
+
resolveWorkspaceByProjectRoot(tenant_id: string, project_root_path: string): Promise<WorkspaceRecord | undefined>;
|
|
203
|
+
resolveWorkspaceByWorkspaceId(tenant_id: string, workspace_id: string): Promise<WorkspaceRecord | undefined>;
|
|
204
|
+
createIndexVersion(input: {
|
|
205
|
+
tenant_id: string;
|
|
206
|
+
workspace_id: string;
|
|
207
|
+
index_version: string;
|
|
208
|
+
status?: "indexing" | "ready" | "failed";
|
|
209
|
+
}): Promise<ReadyIndexRecord>;
|
|
210
|
+
markIndexStatus(input: {
|
|
211
|
+
tenant_id: string;
|
|
212
|
+
workspace_id: string;
|
|
213
|
+
index_id: string;
|
|
214
|
+
status: "indexing" | "ready" | "failed";
|
|
215
|
+
}): Promise<void>;
|
|
216
|
+
getIndexByVersion(input: {
|
|
217
|
+
tenant_id: string;
|
|
218
|
+
workspace_id: string;
|
|
219
|
+
index_version: string;
|
|
220
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
221
|
+
resetIndexContent(input: {
|
|
222
|
+
tenant_id: string;
|
|
223
|
+
index_id: string;
|
|
224
|
+
}): Promise<void>;
|
|
225
|
+
getLatestReadyIndex(input: {
|
|
226
|
+
tenant_id: string;
|
|
227
|
+
workspace_id: string;
|
|
228
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
229
|
+
getFilesByIndex(input: {
|
|
230
|
+
tenant_id: string;
|
|
231
|
+
index_id: string;
|
|
232
|
+
}): Promise<PersistedFileRecord[]>;
|
|
233
|
+
copyFileFromIndex(input: {
|
|
234
|
+
tenant_id: string;
|
|
235
|
+
source_index_id: string;
|
|
236
|
+
target_index_id: string;
|
|
237
|
+
repo_path: string;
|
|
238
|
+
}): Promise<void>;
|
|
239
|
+
upsertFile(input: UpsertFileInput): Promise<{
|
|
240
|
+
file_id: string;
|
|
241
|
+
}>;
|
|
242
|
+
replaceFileChunks(input: {
|
|
243
|
+
tenant_id: string;
|
|
244
|
+
file_id: string;
|
|
245
|
+
repo_path: string;
|
|
246
|
+
chunks: UpsertChunkInput[];
|
|
247
|
+
}): Promise<void>;
|
|
248
|
+
saveManifest(input: {
|
|
249
|
+
index_id: string;
|
|
250
|
+
object_key: string;
|
|
251
|
+
checksum: string;
|
|
252
|
+
}): Promise<void>;
|
|
253
|
+
saveIndexMetadata(input: {
|
|
254
|
+
tenant_id: string;
|
|
255
|
+
index_id: string;
|
|
256
|
+
embedding_provider: string;
|
|
257
|
+
embedding_model?: string;
|
|
258
|
+
embedding_dimensions: number;
|
|
259
|
+
embedding_version?: string;
|
|
260
|
+
chunking_strategy: "language_aware" | "sliding";
|
|
261
|
+
chunking_fallback_strategy: "sliding";
|
|
262
|
+
}): Promise<void>;
|
|
263
|
+
getIndexMetadata(input: {
|
|
264
|
+
tenant_id: string;
|
|
265
|
+
index_id: string;
|
|
266
|
+
}): Promise<IndexMetadataRecord | undefined>;
|
|
267
|
+
listChunksByIndex(input: {
|
|
268
|
+
tenant_id: string;
|
|
269
|
+
index_id: string;
|
|
270
|
+
filters?: {
|
|
271
|
+
language?: string;
|
|
272
|
+
path_prefix?: string;
|
|
273
|
+
glob?: string;
|
|
274
|
+
};
|
|
275
|
+
}): Promise<PersistedChunk[]>;
|
|
276
|
+
rankChunksByIndex(input: RankChunksInput): Promise<RankedChunkCandidate[]>;
|
|
277
|
+
}
|
|
278
|
+
export declare class PostgresIndexRepository implements IndexRepository {
|
|
279
|
+
private readonly pool;
|
|
280
|
+
private readonly options;
|
|
281
|
+
private embeddingStorage;
|
|
282
|
+
constructor(pool: Pool, options?: {
|
|
283
|
+
chunkEmbeddingDimensions?: number;
|
|
284
|
+
preferPgVector?: boolean;
|
|
285
|
+
});
|
|
286
|
+
migrate(): Promise<void>;
|
|
287
|
+
upsertWorkspace(input: WorkspaceRecord): Promise<void>;
|
|
288
|
+
resolveWorkspaceByProjectRoot(tenant_id: string, project_root_path: string): Promise<WorkspaceRecord | undefined>;
|
|
289
|
+
resolveWorkspaceByWorkspaceId(tenant_id: string, workspace_id: string): Promise<WorkspaceRecord | undefined>;
|
|
290
|
+
createIndexVersion(input: {
|
|
291
|
+
tenant_id: string;
|
|
292
|
+
workspace_id: string;
|
|
293
|
+
index_version: string;
|
|
294
|
+
status?: "indexing" | "ready" | "failed";
|
|
295
|
+
}): Promise<ReadyIndexRecord>;
|
|
296
|
+
markIndexStatus(input: {
|
|
297
|
+
tenant_id: string;
|
|
298
|
+
workspace_id: string;
|
|
299
|
+
index_id: string;
|
|
300
|
+
status: "indexing" | "ready" | "failed";
|
|
301
|
+
}): Promise<void>;
|
|
302
|
+
getIndexByVersion(input: {
|
|
303
|
+
tenant_id: string;
|
|
304
|
+
workspace_id: string;
|
|
305
|
+
index_version: string;
|
|
306
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
307
|
+
resetIndexContent(input: {
|
|
308
|
+
tenant_id: string;
|
|
309
|
+
index_id: string;
|
|
310
|
+
}): Promise<void>;
|
|
311
|
+
getLatestReadyIndex(input: {
|
|
312
|
+
tenant_id: string;
|
|
313
|
+
workspace_id: string;
|
|
314
|
+
}): Promise<ReadyIndexRecord | undefined>;
|
|
315
|
+
getFilesByIndex(input: {
|
|
316
|
+
tenant_id: string;
|
|
317
|
+
index_id: string;
|
|
318
|
+
}): Promise<PersistedFileRecord[]>;
|
|
319
|
+
copyFileFromIndex(input: {
|
|
320
|
+
tenant_id: string;
|
|
321
|
+
source_index_id: string;
|
|
322
|
+
target_index_id: string;
|
|
323
|
+
repo_path: string;
|
|
324
|
+
}): Promise<void>;
|
|
325
|
+
upsertFile(input: UpsertFileInput): Promise<{
|
|
326
|
+
file_id: string;
|
|
327
|
+
}>;
|
|
328
|
+
replaceFileChunks(input: {
|
|
329
|
+
tenant_id: string;
|
|
330
|
+
file_id: string;
|
|
331
|
+
repo_path: string;
|
|
332
|
+
chunks: UpsertChunkInput[];
|
|
333
|
+
}): Promise<void>;
|
|
334
|
+
saveManifest(input: {
|
|
335
|
+
index_id: string;
|
|
336
|
+
object_key: string;
|
|
337
|
+
checksum: string;
|
|
338
|
+
}): Promise<void>;
|
|
339
|
+
saveIndexMetadata(input: {
|
|
340
|
+
tenant_id: string;
|
|
341
|
+
index_id: string;
|
|
342
|
+
embedding_provider: string;
|
|
343
|
+
embedding_model?: string;
|
|
344
|
+
embedding_dimensions: number;
|
|
345
|
+
embedding_version?: string;
|
|
346
|
+
chunking_strategy: "language_aware" | "sliding";
|
|
347
|
+
chunking_fallback_strategy: "sliding";
|
|
348
|
+
}): Promise<void>;
|
|
349
|
+
getIndexMetadata(input: {
|
|
350
|
+
tenant_id: string;
|
|
351
|
+
index_id: string;
|
|
352
|
+
}): Promise<IndexMetadataRecord | undefined>;
|
|
353
|
+
listChunksByIndex(input: {
|
|
354
|
+
tenant_id: string;
|
|
355
|
+
index_id: string;
|
|
356
|
+
filters?: {
|
|
357
|
+
language?: string;
|
|
358
|
+
path_prefix?: string;
|
|
359
|
+
glob?: string;
|
|
360
|
+
};
|
|
361
|
+
}): Promise<PersistedChunk[]>;
|
|
362
|
+
rankChunksByIndex(input: RankChunksInput): Promise<RankedChunkCandidate[]>;
|
|
363
|
+
private insertChunk;
|
|
364
|
+
private globToPostgresRegex;
|
|
365
|
+
}
|
|
366
|
+
export declare function createPostgresPool(databaseUrl: string): Pool;
|
|
367
|
+
export interface QueryCache {
|
|
368
|
+
get(cacheKey: string): Promise<SearchContextOutput | undefined>;
|
|
369
|
+
set(cacheKey: string, value: SearchContextOutput, ttlSeconds?: number): Promise<void>;
|
|
370
|
+
invalidateWorkspace(workspace_id: string): Promise<void>;
|
|
371
|
+
}
|
|
372
|
+
export interface RedisLike {
|
|
373
|
+
get(key: string): Promise<string | null>;
|
|
374
|
+
set(key: string, value: string, mode: "EX", ttlSeconds: number): Promise<unknown>;
|
|
375
|
+
keys(pattern: string): Promise<string[]>;
|
|
376
|
+
del(...keys: string[]): Promise<number>;
|
|
377
|
+
rpush(key: string, ...values: string[]): Promise<number>;
|
|
378
|
+
lrem(key: string, count: number, value: string): Promise<number>;
|
|
379
|
+
brpoplpush(source: string, destination: string, timeout: number): Promise<string | null>;
|
|
380
|
+
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
381
|
+
llen(key: string): Promise<number>;
|
|
382
|
+
connect?(): Promise<unknown>;
|
|
383
|
+
status?: string;
|
|
384
|
+
}
|
|
385
|
+
export declare class RedisQueryCache implements QueryCache {
|
|
386
|
+
private readonly redis;
|
|
387
|
+
private readonly keyPrefix;
|
|
388
|
+
constructor(redis: RedisLike, options?: {
|
|
389
|
+
keyPrefix?: string;
|
|
390
|
+
});
|
|
391
|
+
get(cacheKey: string): Promise<SearchContextOutput | undefined>;
|
|
392
|
+
set(cacheKey: string, value: SearchContextOutput, ttlSeconds?: number): Promise<void>;
|
|
393
|
+
invalidateWorkspace(workspace_id: string): Promise<void>;
|
|
394
|
+
private wrapKey;
|
|
395
|
+
}
|
|
396
|
+
export declare class InMemoryQueryCache implements QueryCache {
|
|
397
|
+
private readonly cache;
|
|
398
|
+
get(cacheKey: string): Promise<SearchContextOutput | undefined>;
|
|
399
|
+
set(cacheKey: string, value: SearchContextOutput, ttlSeconds?: number): Promise<void>;
|
|
400
|
+
invalidateWorkspace(workspace_id: string): Promise<void>;
|
|
401
|
+
}
|
|
402
|
+
export declare class SqliteQueryCache implements QueryCache {
|
|
403
|
+
private readonly dbPath;
|
|
404
|
+
private readonly db;
|
|
405
|
+
constructor(dbPath: string);
|
|
406
|
+
close(): void;
|
|
407
|
+
get(cacheKey: string): Promise<SearchContextOutput | undefined>;
|
|
408
|
+
set(cacheKey: string, value: SearchContextOutput, ttlSeconds?: number): Promise<void>;
|
|
409
|
+
invalidateWorkspace(workspace_id: string): Promise<void>;
|
|
410
|
+
}
|
|
411
|
+
export interface IndexJobPayload {
|
|
412
|
+
job_id: string;
|
|
413
|
+
tenant_id: string;
|
|
414
|
+
workspace_id: string;
|
|
415
|
+
index_version: string;
|
|
416
|
+
manifest_key: string;
|
|
417
|
+
attempts: number;
|
|
418
|
+
enqueued_at: string;
|
|
419
|
+
claimed_at?: string;
|
|
420
|
+
}
|
|
421
|
+
interface FailedIndexJobPayload extends IndexJobPayload {
|
|
422
|
+
failed_at: string;
|
|
423
|
+
last_error: string;
|
|
424
|
+
}
|
|
425
|
+
export interface UsageMeteringRecordInput {
|
|
426
|
+
tenant_id: string;
|
|
427
|
+
workspace_id?: string;
|
|
428
|
+
tool_name: string;
|
|
429
|
+
trace_id: string;
|
|
430
|
+
status: "success" | "error";
|
|
431
|
+
latency_ms: number;
|
|
432
|
+
result_count: number;
|
|
433
|
+
units: number;
|
|
434
|
+
created_at?: string;
|
|
435
|
+
}
|
|
436
|
+
export interface AuditEventInput {
|
|
437
|
+
tenant_id: string;
|
|
438
|
+
subject: string;
|
|
439
|
+
action: string;
|
|
440
|
+
resource: string;
|
|
441
|
+
status: "success" | "error" | "denied";
|
|
442
|
+
trace_id: string;
|
|
443
|
+
details?: Record<string, unknown>;
|
|
444
|
+
created_at?: string;
|
|
445
|
+
}
|
|
446
|
+
export interface UsageSummary {
|
|
447
|
+
tenant_id: string;
|
|
448
|
+
tool_name: string;
|
|
449
|
+
request_count: number;
|
|
450
|
+
error_count: number;
|
|
451
|
+
total_units: number;
|
|
452
|
+
p95_latency_ms: number;
|
|
453
|
+
last_seen_at?: string;
|
|
454
|
+
}
|
|
455
|
+
export interface AuditEventRecord {
|
|
456
|
+
event_id: string;
|
|
457
|
+
tenant_id: string;
|
|
458
|
+
subject: string;
|
|
459
|
+
action: string;
|
|
460
|
+
resource: string;
|
|
461
|
+
status: "success" | "error" | "denied";
|
|
462
|
+
trace_id: string;
|
|
463
|
+
details?: Record<string, unknown>;
|
|
464
|
+
created_at: string;
|
|
465
|
+
}
|
|
466
|
+
export interface UsageMeterStore {
|
|
467
|
+
migrate(): Promise<void>;
|
|
468
|
+
recordUsage(input: UsageMeteringRecordInput): Promise<void>;
|
|
469
|
+
recordAuditEvent(input: AuditEventInput): Promise<void>;
|
|
470
|
+
listUsageSummary(input?: {
|
|
471
|
+
tenant_id?: string;
|
|
472
|
+
from?: string;
|
|
473
|
+
to?: string;
|
|
474
|
+
}): Promise<UsageSummary[]>;
|
|
475
|
+
listAuditEvents(input?: {
|
|
476
|
+
tenant_id?: string;
|
|
477
|
+
limit?: number;
|
|
478
|
+
}): Promise<AuditEventRecord[]>;
|
|
479
|
+
}
|
|
480
|
+
export interface ClaimedIndexJob {
|
|
481
|
+
raw: string;
|
|
482
|
+
payload: IndexJobPayload;
|
|
483
|
+
}
|
|
484
|
+
export interface IndexJobQueue {
|
|
485
|
+
enqueue(job: Omit<IndexJobPayload, "job_id" | "attempts" | "enqueued_at"> & {
|
|
486
|
+
job_id?: string;
|
|
487
|
+
}): Promise<IndexJobPayload>;
|
|
488
|
+
claimNext(timeoutSeconds?: number): Promise<ClaimedIndexJob | undefined>;
|
|
489
|
+
ack(claimed: ClaimedIndexJob): Promise<void>;
|
|
490
|
+
retryOrDeadLetter(claimed: ClaimedIndexJob, errorMessage: string): Promise<void>;
|
|
491
|
+
reclaimOrphaned(maxClaimAgeSeconds?: number): Promise<number>;
|
|
492
|
+
deadLetterCount(): Promise<number>;
|
|
493
|
+
pendingCount(): Promise<number>;
|
|
494
|
+
processingCount(): Promise<number>;
|
|
495
|
+
listDeadLetters(): Promise<FailedIndexJobPayload[]>;
|
|
496
|
+
}
|
|
497
|
+
export declare class RedisIndexJobQueue implements IndexJobQueue {
|
|
498
|
+
private readonly redis;
|
|
499
|
+
private readonly pendingKey;
|
|
500
|
+
private readonly processingKey;
|
|
501
|
+
private readonly deadLetterKey;
|
|
502
|
+
private readonly maxAttempts;
|
|
503
|
+
private readonly leasePrefix;
|
|
504
|
+
private readonly claimLeaseSeconds;
|
|
505
|
+
private readonly reconnectRetries;
|
|
506
|
+
private readonly reconnectDelayMs;
|
|
507
|
+
constructor(redis: RedisLike, options?: {
|
|
508
|
+
keyPrefix?: string;
|
|
509
|
+
maxAttempts?: number;
|
|
510
|
+
claimLeaseSeconds?: number;
|
|
511
|
+
reconnectRetries?: number;
|
|
512
|
+
reconnectDelayMs?: number;
|
|
513
|
+
});
|
|
514
|
+
enqueue(job: Omit<IndexJobPayload, "job_id" | "attempts" | "enqueued_at"> & {
|
|
515
|
+
job_id?: string;
|
|
516
|
+
}): Promise<IndexJobPayload>;
|
|
517
|
+
claimNext(timeoutSeconds?: number): Promise<ClaimedIndexJob | undefined>;
|
|
518
|
+
ack(claimed: ClaimedIndexJob): Promise<void>;
|
|
519
|
+
retryOrDeadLetter(claimed: ClaimedIndexJob, errorMessage: string): Promise<void>;
|
|
520
|
+
reclaimOrphaned(maxClaimAgeSeconds?: number): Promise<number>;
|
|
521
|
+
deadLetterCount(): Promise<number>;
|
|
522
|
+
pendingCount(): Promise<number>;
|
|
523
|
+
processingCount(): Promise<number>;
|
|
524
|
+
listDeadLetters(): Promise<FailedIndexJobPayload[]>;
|
|
525
|
+
private runRedisOperation;
|
|
526
|
+
private isRecoverableRedisError;
|
|
527
|
+
private leaseKey;
|
|
528
|
+
}
|
|
529
|
+
export declare class InMemoryIndexJobQueue implements IndexJobQueue {
|
|
530
|
+
private readonly pending;
|
|
531
|
+
private readonly dead;
|
|
532
|
+
private readonly processing;
|
|
533
|
+
private readonly maxAttempts;
|
|
534
|
+
constructor(options?: {
|
|
535
|
+
maxAttempts?: number;
|
|
536
|
+
});
|
|
537
|
+
enqueue(job: Omit<IndexJobPayload, "job_id" | "attempts" | "enqueued_at"> & {
|
|
538
|
+
job_id?: string;
|
|
539
|
+
}): Promise<IndexJobPayload>;
|
|
540
|
+
claimNext(): Promise<ClaimedIndexJob | undefined>;
|
|
541
|
+
ack(claimed: ClaimedIndexJob): Promise<void>;
|
|
542
|
+
retryOrDeadLetter(claimed: ClaimedIndexJob, errorMessage: string): Promise<void>;
|
|
543
|
+
reclaimOrphaned(maxClaimAgeSeconds?: number): Promise<number>;
|
|
544
|
+
deadLetterCount(): Promise<number>;
|
|
545
|
+
pendingCount(): Promise<number>;
|
|
546
|
+
processingCount(): Promise<number>;
|
|
547
|
+
listDeadLetters(): Promise<FailedIndexJobPayload[]>;
|
|
548
|
+
}
|
|
549
|
+
export declare class SqliteIndexJobQueue implements IndexJobQueue {
|
|
550
|
+
private readonly dbPath;
|
|
551
|
+
private readonly db;
|
|
552
|
+
private readonly maxAttempts;
|
|
553
|
+
private readonly claimTtlSeconds;
|
|
554
|
+
constructor(dbPath: string, options?: {
|
|
555
|
+
maxAttempts?: number;
|
|
556
|
+
claimTtlSeconds?: number;
|
|
557
|
+
});
|
|
558
|
+
close(): void;
|
|
559
|
+
enqueue(job: Omit<IndexJobPayload, "job_id" | "attempts" | "enqueued_at"> & {
|
|
560
|
+
job_id?: string;
|
|
561
|
+
}): Promise<IndexJobPayload>;
|
|
562
|
+
claimNext(timeoutSeconds?: number): Promise<ClaimedIndexJob | undefined>;
|
|
563
|
+
ack(claimed: ClaimedIndexJob): Promise<void>;
|
|
564
|
+
retryOrDeadLetter(claimed: ClaimedIndexJob, errorMessage: string): Promise<void>;
|
|
565
|
+
reclaimOrphaned(maxClaimAgeSeconds?: number): Promise<number>;
|
|
566
|
+
deadLetterCount(): Promise<number>;
|
|
567
|
+
pendingCount(): Promise<number>;
|
|
568
|
+
processingCount(): Promise<number>;
|
|
569
|
+
listDeadLetters(): Promise<FailedIndexJobPayload[]>;
|
|
570
|
+
private claimNextImmediate;
|
|
571
|
+
}
|
|
572
|
+
export declare class InMemoryUsageMeterStore implements UsageMeterStore {
|
|
573
|
+
private readonly usage;
|
|
574
|
+
private readonly audit;
|
|
575
|
+
migrate(): Promise<void>;
|
|
576
|
+
recordUsage(input: UsageMeteringRecordInput): Promise<void>;
|
|
577
|
+
recordAuditEvent(input: AuditEventInput): Promise<void>;
|
|
578
|
+
listUsageSummary(input?: {
|
|
579
|
+
tenant_id?: string;
|
|
580
|
+
from?: string;
|
|
581
|
+
to?: string;
|
|
582
|
+
}): Promise<UsageSummary[]>;
|
|
583
|
+
listAuditEvents(input?: {
|
|
584
|
+
tenant_id?: string;
|
|
585
|
+
limit?: number;
|
|
586
|
+
}): Promise<AuditEventRecord[]>;
|
|
587
|
+
}
|
|
588
|
+
export declare class SqliteUsageMeterStore implements UsageMeterStore {
|
|
589
|
+
private readonly dbPath;
|
|
590
|
+
private readonly db;
|
|
591
|
+
constructor(dbPath: string);
|
|
592
|
+
close(): void;
|
|
593
|
+
migrate(): Promise<void>;
|
|
594
|
+
recordUsage(input: UsageMeteringRecordInput): Promise<void>;
|
|
595
|
+
recordAuditEvent(input: AuditEventInput): Promise<void>;
|
|
596
|
+
listUsageSummary(input?: {
|
|
597
|
+
tenant_id?: string;
|
|
598
|
+
from?: string;
|
|
599
|
+
to?: string;
|
|
600
|
+
}): Promise<UsageSummary[]>;
|
|
601
|
+
listAuditEvents(input?: {
|
|
602
|
+
tenant_id?: string;
|
|
603
|
+
limit?: number;
|
|
604
|
+
}): Promise<AuditEventRecord[]>;
|
|
605
|
+
}
|
|
606
|
+
export declare class PostgresUsageMeterStore implements UsageMeterStore {
|
|
607
|
+
private readonly pool;
|
|
608
|
+
constructor(pool: Pool);
|
|
609
|
+
migrate(): Promise<void>;
|
|
610
|
+
recordUsage(input: UsageMeteringRecordInput): Promise<void>;
|
|
611
|
+
recordAuditEvent(input: AuditEventInput): Promise<void>;
|
|
612
|
+
listUsageSummary(input?: {
|
|
613
|
+
tenant_id?: string;
|
|
614
|
+
from?: string;
|
|
615
|
+
to?: string;
|
|
616
|
+
}): Promise<UsageSummary[]>;
|
|
617
|
+
listAuditEvents(input?: {
|
|
618
|
+
tenant_id?: string;
|
|
619
|
+
limit?: number;
|
|
620
|
+
}): Promise<AuditEventRecord[]>;
|
|
621
|
+
}
|
|
622
|
+
export declare function createRedisClient(url: string): RedisClient;
|
|
623
|
+
export declare function buildQueryCacheKey(input: {
|
|
624
|
+
workspace_id: string;
|
|
625
|
+
index_version: string;
|
|
626
|
+
query: string;
|
|
627
|
+
top_k: number;
|
|
628
|
+
filters?: {
|
|
629
|
+
language?: string;
|
|
630
|
+
path_prefix?: string;
|
|
631
|
+
glob?: string;
|
|
632
|
+
};
|
|
633
|
+
}): string;
|