byterover-cli 2.0.0 → 2.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/README.md +6 -81
- package/dist/agent/core/domain/llm/index.d.ts +1 -1
- package/dist/agent/core/domain/llm/index.js +1 -1
- package/dist/agent/core/domain/llm/registry.d.ts +8 -0
- package/dist/agent/core/domain/llm/registry.js +34 -0
- package/dist/agent/core/domain/sandbox/types.d.ts +2 -0
- package/dist/agent/core/domain/tools/constants.d.ts +3 -0
- package/dist/agent/core/domain/tools/constants.js +3 -0
- package/dist/agent/core/interfaces/cipher-services.d.ts +2 -4
- package/dist/agent/core/interfaces/i-cipher-agent.d.ts +9 -1
- package/dist/agent/core/interfaces/i-sandbox-service.d.ts +8 -0
- package/dist/agent/core/interfaces/i-tool-provider.d.ts +10 -0
- package/dist/agent/core/interfaces/i-tool-scheduler.d.ts +9 -0
- package/dist/agent/infra/agent/agent-schemas.d.ts +0 -9
- package/dist/agent/infra/agent/agent-schemas.js +0 -3
- package/dist/agent/infra/agent/cipher-agent.d.ts +25 -1
- package/dist/agent/infra/agent/cipher-agent.js +138 -11
- package/dist/agent/infra/agent/provider-update-config.d.ts +0 -2
- package/dist/agent/infra/agent/service-initializer.d.ts +2 -6
- package/dist/agent/infra/agent/service-initializer.js +45 -38
- package/dist/agent/infra/blob/blob-storage-factory.d.ts +2 -2
- package/dist/agent/infra/blob/blob-storage-factory.js +4 -4
- package/dist/agent/infra/blob/file-blob-storage.d.ts +96 -0
- package/dist/agent/infra/blob/file-blob-storage.js +454 -0
- package/dist/agent/infra/blob/index.d.ts +2 -3
- package/dist/agent/infra/blob/index.js +4 -6
- package/dist/agent/infra/llm/agent-llm-service.d.ts +3 -0
- package/dist/agent/infra/llm/agent-llm-service.js +34 -52
- package/dist/agent/infra/llm/context/compression/compression-helpers.d.ts +35 -0
- package/dist/agent/infra/llm/context/compression/compression-helpers.js +124 -0
- package/dist/agent/infra/llm/context/compression/escalated-compression.d.ts +62 -0
- package/dist/agent/infra/llm/context/compression/escalated-compression.js +144 -0
- package/dist/agent/infra/llm/context/compression/index.d.ts +3 -0
- package/dist/agent/infra/llm/context/compression/index.js +3 -0
- package/dist/agent/infra/llm/context/compression/reactive-overflow.d.ts +0 -27
- package/dist/agent/infra/llm/context/compression/reactive-overflow.js +5 -122
- package/dist/agent/infra/llm/context/context-manager.d.ts +20 -1
- package/dist/agent/infra/llm/context/context-manager.js +37 -7
- package/dist/agent/infra/llm/providers/index.js +0 -2
- package/dist/agent/infra/llm/providers/types.d.ts +1 -5
- package/dist/agent/infra/map/agentic-map-service.d.ts +97 -0
- package/dist/agent/infra/map/agentic-map-service.js +309 -0
- package/dist/agent/infra/map/context-tree-store.d.ts +94 -0
- package/dist/agent/infra/map/context-tree-store.js +278 -0
- package/dist/agent/infra/map/index.d.ts +4 -0
- package/dist/agent/infra/map/index.js +4 -0
- package/dist/agent/infra/map/llm-map-memory.d.ts +59 -0
- package/dist/agent/infra/map/llm-map-memory.js +187 -0
- package/dist/agent/infra/map/llm-map-service.d.ts +36 -0
- package/dist/agent/infra/map/llm-map-service.js +118 -0
- package/dist/agent/infra/map/map-shared.d.ts +140 -0
- package/dist/agent/infra/map/map-shared.js +325 -0
- package/dist/agent/infra/map/worker-pool.d.ts +45 -0
- package/dist/agent/infra/map/worker-pool.js +73 -0
- package/dist/agent/infra/sandbox/curation-helpers.d.ts +62 -0
- package/dist/agent/infra/sandbox/curation-helpers.js +219 -0
- package/dist/agent/infra/sandbox/sandbox-service.d.ts +12 -0
- package/dist/agent/infra/sandbox/sandbox-service.js +39 -7
- package/dist/agent/infra/sandbox/tools-sdk.d.ts +48 -1
- package/dist/agent/infra/sandbox/tools-sdk.js +52 -1
- package/dist/agent/infra/session/session-manager.d.ts +8 -1
- package/dist/agent/infra/session/session-manager.js +24 -4
- package/dist/agent/infra/storage/file-key-storage.d.ts +142 -0
- package/dist/agent/infra/storage/file-key-storage.js +572 -0
- package/dist/agent/infra/storage/granular-history-storage.d.ts +1 -1
- package/dist/agent/infra/storage/granular-history-storage.js +1 -1
- package/dist/agent/infra/system-prompt/contributors/context-tree-structure-contributor.d.ts +4 -0
- package/dist/agent/infra/system-prompt/contributors/context-tree-structure-contributor.js +42 -14
- package/dist/agent/infra/system-prompt/contributors/map-selection-contributor.d.ts +16 -0
- package/dist/agent/infra/system-prompt/contributors/map-selection-contributor.js +47 -0
- package/dist/agent/infra/tools/core-tool-scheduler.js +3 -1
- package/dist/agent/infra/tools/implementations/agentic-map-tool.d.ts +35 -0
- package/dist/agent/infra/tools/implementations/agentic-map-tool.js +156 -0
- package/dist/agent/infra/tools/implementations/code-exec-tool.js +1 -0
- package/dist/agent/infra/tools/implementations/curate-tool.d.ts +9 -9
- package/dist/agent/infra/tools/implementations/expand-knowledge-tool.d.ts +18 -0
- package/dist/agent/infra/tools/implementations/expand-knowledge-tool.js +43 -0
- package/dist/agent/infra/tools/implementations/llm-map-tool.d.ts +24 -0
- package/dist/agent/infra/tools/implementations/llm-map-tool.js +87 -0
- package/dist/agent/infra/tools/implementations/memory-symbol-tree.d.ts +28 -1
- package/dist/agent/infra/tools/implementations/memory-symbol-tree.js +27 -3
- package/dist/agent/infra/tools/implementations/search-knowledge-service.d.ts +1 -0
- package/dist/agent/infra/tools/implementations/search-knowledge-service.js +83 -12
- package/dist/agent/infra/tools/implementations/search-knowledge-tool.js +2 -2
- package/dist/agent/infra/tools/tool-manager.js +6 -0
- package/dist/agent/infra/tools/tool-provider.d.ts +12 -0
- package/dist/agent/infra/tools/tool-provider.js +78 -0
- package/dist/agent/infra/tools/tool-registry.d.ts +14 -0
- package/dist/agent/infra/tools/tool-registry.js +32 -0
- package/dist/agent/resources/prompts/system-prompt.yml +48 -74
- package/dist/agent/resources/tools/expand_knowledge.txt +20 -0
- package/dist/oclif/commands/curate/index.js +1 -2
- package/dist/oclif/commands/main.js +1 -0
- package/dist/oclif/commands/providers/connect.d.ts +1 -3
- package/dist/oclif/commands/providers/connect.js +7 -29
- package/dist/oclif/commands/query.js +1 -2
- package/dist/server/constants.d.ts +7 -0
- package/dist/server/constants.js +8 -0
- package/dist/server/core/domain/entities/provider-registry.js +1 -15
- package/dist/server/core/domain/knowledge/memory-scoring.js +1 -1
- package/dist/server/core/domain/knowledge/summary-types.d.ts +126 -0
- package/dist/server/core/domain/knowledge/summary-types.js +7 -0
- package/dist/server/core/domain/transport/schemas.d.ts +0 -4
- package/dist/server/core/interfaces/context-tree/i-context-tree-archive-service.d.ts +30 -0
- package/dist/server/core/interfaces/context-tree/i-context-tree-archive-service.js +1 -0
- package/dist/server/core/interfaces/context-tree/i-context-tree-manifest-service.d.ts +30 -0
- package/dist/server/core/interfaces/context-tree/i-context-tree-manifest-service.js +1 -0
- package/dist/server/core/interfaces/context-tree/i-context-tree-summary-service.d.ts +29 -0
- package/dist/server/core/interfaces/context-tree/i-context-tree-summary-service.js +1 -0
- package/dist/server/infra/cogit/context-tree-to-push-context-mapper.js +10 -3
- package/dist/server/infra/connectors/skill/skill-connector.d.ts +4 -0
- package/dist/server/infra/connectors/skill/skill-connector.js +4 -0
- package/dist/server/infra/context-tree/children-hash.d.ts +20 -0
- package/dist/server/infra/context-tree/children-hash.js +22 -0
- package/dist/server/infra/context-tree/derived-artifact.d.ts +28 -0
- package/dist/server/infra/context-tree/derived-artifact.js +48 -0
- package/dist/server/infra/context-tree/file-context-tree-archive-service.d.ts +37 -0
- package/dist/server/infra/context-tree/file-context-tree-archive-service.js +219 -0
- package/dist/server/infra/context-tree/file-context-tree-manifest-service.d.ts +50 -0
- package/dist/server/infra/context-tree/file-context-tree-manifest-service.js +278 -0
- package/dist/server/infra/context-tree/file-context-tree-merger.js +4 -0
- package/dist/server/infra/context-tree/file-context-tree-snapshot-service.js +12 -4
- package/dist/server/infra/context-tree/file-context-tree-summary-service.d.ts +44 -0
- package/dist/server/infra/context-tree/file-context-tree-summary-service.js +313 -0
- package/dist/server/infra/context-tree/file-context-tree-writer-service.js +5 -0
- package/dist/server/infra/context-tree/prompts/summary-generation.d.ts +22 -0
- package/dist/server/infra/context-tree/prompts/summary-generation.js +45 -0
- package/dist/server/infra/context-tree/snapshot-diff.d.ts +19 -0
- package/dist/server/infra/context-tree/snapshot-diff.js +39 -0
- package/dist/server/infra/context-tree/summary-frontmatter.d.ts +24 -0
- package/dist/server/infra/context-tree/summary-frontmatter.js +111 -0
- package/dist/server/infra/daemon/agent-process.js +2 -14
- package/dist/server/infra/executor/curate-executor.d.ts +1 -0
- package/dist/server/infra/executor/curate-executor.js +82 -34
- package/dist/server/infra/executor/folder-pack-executor.js +1 -1
- package/dist/server/infra/executor/pre-compaction/compaction-escalation.d.ts +6 -0
- package/dist/server/infra/executor/pre-compaction/compaction-escalation.js +6 -0
- package/dist/server/infra/executor/pre-compaction/index.d.ts +3 -0
- package/dist/server/infra/executor/pre-compaction/index.js +1 -0
- package/dist/server/infra/executor/pre-compaction/pre-compaction-service.d.ts +59 -0
- package/dist/server/infra/executor/pre-compaction/pre-compaction-service.js +124 -0
- package/dist/server/infra/executor/pre-compaction/prompts.d.ts +24 -0
- package/dist/server/infra/executor/pre-compaction/prompts.js +47 -0
- package/dist/server/infra/executor/query-executor.d.ts +3 -0
- package/dist/server/infra/executor/query-executor.js +39 -4
- package/dist/server/infra/http/authenticated-http-client.js +4 -0
- package/dist/server/infra/http/provider-model-fetcher-registry.js +1 -5
- package/dist/server/infra/http/provider-model-fetchers.d.ts +0 -14
- package/dist/server/infra/http/provider-model-fetchers.js +0 -132
- package/dist/server/infra/provider/provider-config-resolver.js +0 -55
- package/dist/server/utils/curate-result-parser.d.ts +4 -4
- package/dist/shared/constants/curation.d.ts +6 -0
- package/dist/shared/constants/curation.js +6 -0
- package/dist/shared/utils/escalation-utils.d.ts +59 -0
- package/dist/shared/utils/escalation-utils.js +141 -0
- package/dist/tui/components/command-input.js +1 -1
- package/dist/tui/components/inline-prompts/inline-confirm.js +6 -1
- package/dist/tui/features/commands/definitions/exit.d.ts +2 -0
- package/dist/tui/features/commands/definitions/exit.js +9 -0
- package/dist/tui/features/commands/definitions/index.js +3 -0
- package/dist/tui/features/exit/components/exit-flow.d.ts +10 -0
- package/dist/tui/features/exit/components/exit-flow.js +19 -0
- package/dist/tui/features/provider/components/provider-flow.js +1 -21
- package/oclif.manifest.json +100 -109
- package/package.json +11 -4
- package/dist/agent/infra/blob/migrations.d.ts +0 -63
- package/dist/agent/infra/blob/migrations.js +0 -148
- package/dist/agent/infra/blob/sqlite-blob-storage.d.ts +0 -82
- package/dist/agent/infra/blob/sqlite-blob-storage.js +0 -307
- package/dist/agent/infra/llm/providers/google-vertex.d.ts +0 -15
- package/dist/agent/infra/llm/providers/google-vertex.js +0 -36
- package/dist/agent/infra/storage/blob-history-storage.d.ts +0 -81
- package/dist/agent/infra/storage/blob-history-storage.js +0 -193
- package/dist/agent/infra/storage/dual-format-history-storage.d.ts +0 -83
- package/dist/agent/infra/storage/dual-format-history-storage.js +0 -165
- package/dist/agent/infra/storage/sqlite-key-storage.d.ts +0 -113
- package/dist/agent/infra/storage/sqlite-key-storage.js +0 -438
- package/dist/server/infra/provider/vertex-ai-utils.d.ts +0 -10
- package/dist/server/infra/provider/vertex-ai-utils.js +0 -28
- package/dist/tui/features/provider/components/credential-path-dialog.d.ts +0 -30
- package/dist/tui/features/provider/components/credential-path-dialog.js +0 -85
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { setMaxListeners } from 'node:events';
|
|
3
|
+
import { getEffectiveMaxInputTokens, resolveRegistryProvider } from '../../core/domain/llm/index.js';
|
|
2
4
|
import { STREAMING_EVENT_NAMES } from '../../core/domain/streaming/types.js';
|
|
5
|
+
import { ToolName } from '../../core/domain/tools/constants.js';
|
|
3
6
|
import { AgentEventBus } from '../events/event-emitter.js';
|
|
7
|
+
import { createGeneratorForProvider } from '../llm/providers/index.js';
|
|
8
|
+
import { EventBasedLogger } from '../logger/event-based-logger.js';
|
|
9
|
+
import { deregisterRootEligibleSession, registerRootEligibleSession } from '../map/agentic-map-service.js';
|
|
4
10
|
import { SessionManager } from '../session/session-manager.js';
|
|
5
11
|
import { TransportEventBridge } from '../transport/transport-event-bridge.js';
|
|
6
12
|
import { AgentError } from './agent-error.js';
|
|
@@ -30,6 +36,8 @@ export class CipherAgent extends BaseAgent {
|
|
|
30
36
|
// Private state (must come before methods)
|
|
31
37
|
_agentEventBus;
|
|
32
38
|
_brvConfig;
|
|
39
|
+
/** Unique ID for this agent instance — scopes nesting registry ownership. */
|
|
40
|
+
_instanceId = randomUUID();
|
|
33
41
|
_projectIdProvider;
|
|
34
42
|
/**
|
|
35
43
|
* Session ID - created once during start().
|
|
@@ -42,6 +50,11 @@ export class CipherAgent extends BaseAgent {
|
|
|
42
50
|
_transportClient;
|
|
43
51
|
activeStreamControllers = new Map();
|
|
44
52
|
eventBridge;
|
|
53
|
+
/**
|
|
54
|
+
* Tracks session IDs this agent instance registered as root-eligible.
|
|
55
|
+
* Used for bulk deregistration on agent teardown (cleanupServices).
|
|
56
|
+
*/
|
|
57
|
+
rootEligibleSessions = new Set();
|
|
45
58
|
sessionManager;
|
|
46
59
|
/**
|
|
47
60
|
* Creates a new CipherAgent instance.
|
|
@@ -143,6 +156,13 @@ export class CipherAgent extends BaseAgent {
|
|
|
143
156
|
this.eventBridge.dispose();
|
|
144
157
|
this.eventBridge = undefined;
|
|
145
158
|
}
|
|
159
|
+
// Deregister all root-eligible sessions before session manager disposal.
|
|
160
|
+
// stop()/restart() disposes without calling deleteSession() per session,
|
|
161
|
+
// so this bulk cleanup prevents registry accumulation across restarts.
|
|
162
|
+
for (const sessionId of this.rootEligibleSessions) {
|
|
163
|
+
deregisterRootEligibleSession(sessionId, this._instanceId);
|
|
164
|
+
}
|
|
165
|
+
this.rootEligibleSessions.clear();
|
|
146
166
|
// Dispose session manager
|
|
147
167
|
if (this.sessionManager) {
|
|
148
168
|
this.sessionManager.dispose();
|
|
@@ -166,17 +186,27 @@ export class CipherAgent extends BaseAgent {
|
|
|
166
186
|
*/
|
|
167
187
|
async createSession(sessionId) {
|
|
168
188
|
this.ensureStarted();
|
|
169
|
-
|
|
189
|
+
const session = await this.getSessionManagerInternal().createSession(sessionId);
|
|
190
|
+
this.registerSessionInternal(session.id);
|
|
191
|
+
return session;
|
|
170
192
|
}
|
|
171
193
|
/**
|
|
172
194
|
* Create a task-scoped child session for parallel execution.
|
|
173
195
|
* The session gets its own sandbox, context manager, and LLM service.
|
|
174
196
|
*/
|
|
175
|
-
async createTaskSession(taskId, commandType) {
|
|
197
|
+
async createTaskSession(taskId, commandType, options) {
|
|
176
198
|
this.ensureStarted();
|
|
177
199
|
const sessionMgr = this.getSessionManagerInternal();
|
|
178
200
|
const parentSessionId = this.getSessionIdInternal();
|
|
179
201
|
const childSession = await sessionMgr.createChildSession(parentSessionId, commandType, `task-${commandType}-${taskId}`);
|
|
202
|
+
// Only register as root-eligible when explicitly opted in.
|
|
203
|
+
// Top-level executors that may call agentic_map (curate-executor,
|
|
204
|
+
// folder-pack-executor) pass mapRootEligible: true.
|
|
205
|
+
// For agentic_map sub-sessions (created by processItem), registration
|
|
206
|
+
// is skipped here — processItem sets its own isRootCaller: false record.
|
|
207
|
+
if (options?.mapRootEligible) {
|
|
208
|
+
this.registerSessionInternal(childSession.id);
|
|
209
|
+
}
|
|
180
210
|
return childSession.id;
|
|
181
211
|
}
|
|
182
212
|
/**
|
|
@@ -203,7 +233,15 @@ export class CipherAgent extends BaseAgent {
|
|
|
203
233
|
if (this.stateManager) {
|
|
204
234
|
this.stateManager.clearSessionOverride(sessionId);
|
|
205
235
|
}
|
|
206
|
-
|
|
236
|
+
const deleted = await this.getSessionManagerInternal().deleteSession(sessionId);
|
|
237
|
+
if (deleted && this.rootEligibleSessions.has(sessionId)) {
|
|
238
|
+
// Deregister only if this agent instance owns the session.
|
|
239
|
+
// Scoping prevents one agent's teardown from removing another
|
|
240
|
+
// agent's live record when they share a session ID.
|
|
241
|
+
deregisterRootEligibleSession(sessionId, this._instanceId);
|
|
242
|
+
this.rootEligibleSessions.delete(sessionId);
|
|
243
|
+
}
|
|
244
|
+
return deleted;
|
|
207
245
|
}
|
|
208
246
|
/**
|
|
209
247
|
* Delete a task session and all its resources (sandbox + history).
|
|
@@ -212,6 +250,13 @@ export class CipherAgent extends BaseAgent {
|
|
|
212
250
|
this.ensureStarted();
|
|
213
251
|
await this.services.sandboxService.clearSession(sessionId);
|
|
214
252
|
await this.getSessionManagerInternal().deleteSession(sessionId);
|
|
253
|
+
// Deregister root-eligible record if this agent owns it.
|
|
254
|
+
// For agentic_map sub-sessions, the record was overwritten to isRootCaller: false
|
|
255
|
+
// by processItem, so deregisterRootEligibleSession is a no-op (correct).
|
|
256
|
+
if (this.rootEligibleSessions.has(sessionId)) {
|
|
257
|
+
deregisterRootEligibleSession(sessionId, this._instanceId);
|
|
258
|
+
this.rootEligibleSessions.delete(sessionId);
|
|
259
|
+
}
|
|
215
260
|
}
|
|
216
261
|
/**
|
|
217
262
|
* Execute the agent with user input.
|
|
@@ -299,7 +344,11 @@ export class CipherAgent extends BaseAgent {
|
|
|
299
344
|
this.ensureStarted();
|
|
300
345
|
const sessionMgr = this.getSessionManagerInternal();
|
|
301
346
|
const existingSession = sessionMgr.getSession(sessionId);
|
|
302
|
-
|
|
347
|
+
if (existingSession)
|
|
348
|
+
return existingSession;
|
|
349
|
+
const newSession = await sessionMgr.createSession(sessionId);
|
|
350
|
+
this.registerSessionInternal(newSession.id); // only on actual creation
|
|
351
|
+
return newSession;
|
|
303
352
|
}
|
|
304
353
|
/**
|
|
305
354
|
* Get a session by ID.
|
|
@@ -382,8 +431,6 @@ export class CipherAgent extends BaseAgent {
|
|
|
382
431
|
providerApiKey: providerUpdate.providerApiKey,
|
|
383
432
|
providerBaseUrl: providerUpdate.providerBaseUrl,
|
|
384
433
|
providerHeaders: providerUpdate.providerHeaders,
|
|
385
|
-
providerLocation: providerUpdate.providerLocation,
|
|
386
|
-
providerProject: providerUpdate.providerProject,
|
|
387
434
|
siteName: this.config.siteName,
|
|
388
435
|
temperature: this.config.llm.temperature,
|
|
389
436
|
verbose: this.config.llm.verbose,
|
|
@@ -394,16 +441,27 @@ export class CipherAgent extends BaseAgent {
|
|
|
394
441
|
maxSessions: this.config.sessions.maxSessions,
|
|
395
442
|
sessionTTL: this.config.sessions.sessionTTL,
|
|
396
443
|
},
|
|
444
|
+
onSessionRemoved: (sessionId) => {
|
|
445
|
+
this.handleSessionRemoved(sessionId);
|
|
446
|
+
},
|
|
397
447
|
});
|
|
398
|
-
// Success — dispose old and swap
|
|
448
|
+
// Success — dispose old and swap.
|
|
449
|
+
// Deregister all root-eligible sessions from the old SM first —
|
|
450
|
+
// they no longer exist after dispose(). The next stream()/execute()
|
|
451
|
+
// will recreate sessions via getOrCreateSession and re-register them.
|
|
399
452
|
if (this.sessionManager) {
|
|
453
|
+
for (const sid of this.rootEligibleSessions) {
|
|
454
|
+
deregisterRootEligibleSession(sid, this._instanceId);
|
|
455
|
+
}
|
|
456
|
+
this.rootEligibleSessions.clear();
|
|
400
457
|
this.sessionManager.dispose();
|
|
401
458
|
}
|
|
402
459
|
this.sessionManager = newSessionManager;
|
|
403
460
|
// Re-wire SessionManager into sandbox for tools.agentQuery()
|
|
404
461
|
this.services.sandboxService.setSessionManager?.(this.sessionManager);
|
|
462
|
+
// Rebind map tools with fresh generator/tokenizer/maxContextTokens
|
|
463
|
+
this.rebindMapTools(services, httpConfig, sessionLLMConfig);
|
|
405
464
|
}
|
|
406
|
-
// === Protected Methods (implement abstract from BaseAgent) ===
|
|
407
465
|
/**
|
|
408
466
|
* Reset the agent to initial state.
|
|
409
467
|
* Resets execution state only. To reset sessions, use resetSession(sessionId).
|
|
@@ -414,6 +472,7 @@ export class CipherAgent extends BaseAgent {
|
|
|
414
472
|
this.stateManager.reset();
|
|
415
473
|
}
|
|
416
474
|
}
|
|
475
|
+
// === Protected Methods (implement abstract from BaseAgent) ===
|
|
417
476
|
/**
|
|
418
477
|
* Reset a specific session's conversation history.
|
|
419
478
|
* @param sessionId - The session ID to reset
|
|
@@ -478,8 +537,6 @@ export class CipherAgent extends BaseAgent {
|
|
|
478
537
|
providerApiKey: this.config.providerApiKey,
|
|
479
538
|
providerBaseUrl: this.config.providerBaseUrl,
|
|
480
539
|
providerHeaders: this.config.providerHeaders,
|
|
481
|
-
providerLocation: this.config.providerLocation,
|
|
482
|
-
providerProject: this.config.providerProject,
|
|
483
540
|
siteName: this.config.siteName,
|
|
484
541
|
temperature: this.config.llm.temperature,
|
|
485
542
|
verbose: this.config.llm.verbose,
|
|
@@ -490,6 +547,9 @@ export class CipherAgent extends BaseAgent {
|
|
|
490
547
|
maxSessions: this.config.sessions.maxSessions,
|
|
491
548
|
sessionTTL: this.config.sessions.sessionTTL,
|
|
492
549
|
},
|
|
550
|
+
onSessionRemoved: (sessionId) => {
|
|
551
|
+
this.handleSessionRemoved(sessionId);
|
|
552
|
+
},
|
|
493
553
|
});
|
|
494
554
|
// Wire SessionManager into sandbox for tools.agentQuery() sub-agent delegation
|
|
495
555
|
this.services.sandboxService.setSessionManager?.(this.sessionManager);
|
|
@@ -497,6 +557,11 @@ export class CipherAgent extends BaseAgent {
|
|
|
497
557
|
// Each agent has exactly 1 session created at start time
|
|
498
558
|
const defaultSession = await this.sessionManager.createSession();
|
|
499
559
|
this._sessionId = defaultSession.id;
|
|
560
|
+
this.registerSessionInternal(defaultSession.id);
|
|
561
|
+
// Inject agent instance and content generator into ToolProvider for map tools.
|
|
562
|
+
// Uses rebindMapTools() which atomically replaces map tools with fresh deps
|
|
563
|
+
// (generator, tokenizer, maxContextTokens, logger).
|
|
564
|
+
this.rebindMapTools(services, httpConfig, sessionLLMConfig);
|
|
500
565
|
// Create event bridge if transport client is injected (child process mode).
|
|
501
566
|
// The bridge forwards AgentEventBus llmservice:* events to the transport server.
|
|
502
567
|
if (this._transportClient) {
|
|
@@ -581,6 +646,9 @@ export class CipherAgent extends BaseAgent {
|
|
|
581
646
|
const sessionMgr = this.getSessionManagerInternal();
|
|
582
647
|
const existingSession = sessionMgr.getSession(sessionId);
|
|
583
648
|
const session = existingSession ?? (await sessionMgr.createSession(sessionId));
|
|
649
|
+
if (!existingSession) {
|
|
650
|
+
this.registerSessionInternal(session.id); // only on actual creation
|
|
651
|
+
}
|
|
584
652
|
// Increment iteration counter
|
|
585
653
|
this.getStateManager().incrementIteration();
|
|
586
654
|
// Call session.streamRun() which emits events and run:complete
|
|
@@ -695,7 +763,6 @@ export class CipherAgent extends BaseAgent {
|
|
|
695
763
|
}
|
|
696
764
|
this._sessionId = sessionId;
|
|
697
765
|
}
|
|
698
|
-
// === Private Helpers (alphabetical order) ===
|
|
699
766
|
/**
|
|
700
767
|
* Build HTTP config for ByteRover API calls.
|
|
701
768
|
* Uses lazy providers when injected (child process mode), otherwise static config.
|
|
@@ -710,6 +777,7 @@ export class CipherAgent extends BaseAgent {
|
|
|
710
777
|
teamId: this._teamIdProvider ?? this.config.teamId ?? this._brvConfig?.teamId ?? '',
|
|
711
778
|
};
|
|
712
779
|
}
|
|
780
|
+
// === Private Helpers (alphabetical order) ===
|
|
713
781
|
getHistoryStorageInternal() {
|
|
714
782
|
const storage = this.services?.historyStorage;
|
|
715
783
|
if (!storage) {
|
|
@@ -736,4 +804,63 @@ export class CipherAgent extends BaseAgent {
|
|
|
736
804
|
}
|
|
737
805
|
return manager;
|
|
738
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* Handle SessionManager lifecycle removals (delete/end/TTL-expire) and keep
|
|
809
|
+
* root-eligible tracking synchronized with the global nesting registry.
|
|
810
|
+
*/
|
|
811
|
+
handleSessionRemoved(sessionId) {
|
|
812
|
+
if (!this.rootEligibleSessions.has(sessionId))
|
|
813
|
+
return;
|
|
814
|
+
deregisterRootEligibleSession(sessionId, this._instanceId);
|
|
815
|
+
this.rootEligibleSessions.delete(sessionId);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Rebuild map tool dependencies and update ToolProvider + SandboxService.
|
|
819
|
+
* Called from both start() (initial setup) and refreshProviderConfig() (hot-swap).
|
|
820
|
+
*/
|
|
821
|
+
rebindMapTools(services, httpConfig, sessionLLMConfig) {
|
|
822
|
+
const mapProvider = sessionLLMConfig.provider
|
|
823
|
+
?? (sessionLLMConfig.openRouterApiKey ? 'openrouter' : 'byterover');
|
|
824
|
+
const mapGenerator = createGeneratorForProvider(mapProvider, {
|
|
825
|
+
apiKey: mapProvider === 'openrouter'
|
|
826
|
+
? (sessionLLMConfig.openRouterApiKey ?? sessionLLMConfig.providerApiKey)
|
|
827
|
+
: sessionLLMConfig.providerApiKey,
|
|
828
|
+
baseUrl: sessionLLMConfig.providerBaseUrl,
|
|
829
|
+
headers: sessionLLMConfig.providerHeaders,
|
|
830
|
+
httpConfig: httpConfig,
|
|
831
|
+
httpReferer: sessionLLMConfig.httpReferer,
|
|
832
|
+
maxTokens: 4096,
|
|
833
|
+
model: sessionLLMConfig.model,
|
|
834
|
+
siteName: sessionLLMConfig.siteName,
|
|
835
|
+
temperature: 0,
|
|
836
|
+
});
|
|
837
|
+
// Adapter pattern: wrap mapGenerator.estimateTokensSync() as ITokenizer
|
|
838
|
+
const mapTokenizer = {
|
|
839
|
+
countTokens: (text) => mapGenerator.estimateTokensSync(text),
|
|
840
|
+
};
|
|
841
|
+
// Compute registry-clamped maxContextTokens
|
|
842
|
+
const mapModel = sessionLLMConfig.model ?? 'gemini-3-flash-preview';
|
|
843
|
+
const mapRegistryProvider = resolveRegistryProvider(mapModel, mapProvider);
|
|
844
|
+
const effectiveMaxContextTokens = getEffectiveMaxInputTokens(mapRegistryProvider, mapModel, sessionLLMConfig.maxInputTokens);
|
|
845
|
+
const mapLogger = new EventBasedLogger(this._agentEventBus, 'MapTools');
|
|
846
|
+
// Atomically replace map tools with fresh generator/tokenizer/maxContextTokens.
|
|
847
|
+
// replaceTools() is build-then-swap — if build fails, old tools remain intact.
|
|
848
|
+
services.toolProvider.replaceTools([ToolName.LLM_MAP, ToolName.AGENTIC_MAP], {
|
|
849
|
+
agentInstance: this,
|
|
850
|
+
contentGenerator: mapGenerator,
|
|
851
|
+
logger: mapLogger,
|
|
852
|
+
maxContextTokens: effectiveMaxContextTokens,
|
|
853
|
+
tokenizer: mapTokenizer,
|
|
854
|
+
});
|
|
855
|
+
// Update sandbox for tools.curation.mapExtract()
|
|
856
|
+
services.sandboxService.setContentGenerator?.(mapGenerator);
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Register a session as root-eligible and track it for lifecycle cleanup.
|
|
860
|
+
* Routes all root-eligible registrations through a single point.
|
|
861
|
+
*/
|
|
862
|
+
registerSessionInternal(sessionId) {
|
|
863
|
+
registerRootEligibleSession(sessionId, this._instanceId); // throws if id is a live sub-session record
|
|
864
|
+
this.rootEligibleSessions.add(sessionId);
|
|
865
|
+
}
|
|
739
866
|
}
|
|
@@ -44,7 +44,7 @@ export interface SessionLLMConfig {
|
|
|
44
44
|
maxTokens?: number;
|
|
45
45
|
model: string;
|
|
46
46
|
openRouterApiKey?: string;
|
|
47
|
-
/** Provider ID (anthropic, openai, google,
|
|
47
|
+
/** Provider ID (anthropic, openai, google, xai, groq, mistral, openrouter, byterover) */
|
|
48
48
|
provider?: string;
|
|
49
49
|
/** API key for the direct provider */
|
|
50
50
|
providerApiKey?: string;
|
|
@@ -52,10 +52,6 @@ export interface SessionLLMConfig {
|
|
|
52
52
|
providerBaseUrl?: string;
|
|
53
53
|
/** Custom headers for the provider */
|
|
54
54
|
providerHeaders?: Record<string, string>;
|
|
55
|
-
/** GCP location for Vertex AI (default: us-central1) */
|
|
56
|
-
providerLocation?: string;
|
|
57
|
-
/** GCP project ID for Vertex AI */
|
|
58
|
-
providerProject?: string;
|
|
59
55
|
siteName?: string;
|
|
60
56
|
temperature?: number;
|
|
61
57
|
verbose?: boolean;
|
|
@@ -76,7 +72,7 @@ export type { CipherAgentServices, SessionManagerConfig, SessionServices } from
|
|
|
76
72
|
* 8. Policy engine (no dependencies)
|
|
77
73
|
* 9. Tool scheduler (depends on ToolProvider, PolicyEngine)
|
|
78
74
|
* 10. Tool manager (depends on ToolProvider, ToolScheduler)
|
|
79
|
-
* 11. History storage (
|
|
75
|
+
* 11. History storage (file-based granular storage)
|
|
80
76
|
* 12. Return all services
|
|
81
77
|
*
|
|
82
78
|
* @param config - Validated agent configuration (Zod-validated)
|
|
@@ -18,6 +18,9 @@ import { SessionEventBus } from '../events/event-emitter.js';
|
|
|
18
18
|
import { FileSystemService } from '../file-system/file-system-service.js';
|
|
19
19
|
import { AgentLLMService } from '../llm/agent-llm-service.js';
|
|
20
20
|
import { CompactionService } from '../llm/context/compaction/compaction-service.js';
|
|
21
|
+
import { EscalatedCompressionStrategy } from '../llm/context/compression/escalated-compression.js';
|
|
22
|
+
import { MiddleRemovalStrategy } from '../llm/context/compression/middle-removal.js';
|
|
23
|
+
import { OldestRemovalStrategy } from '../llm/context/compression/oldest-removal.js';
|
|
21
24
|
import { LoggingContentGenerator, RetryableContentGenerator, } from '../llm/generators/index.js';
|
|
22
25
|
import { createGeneratorForProvider } from '../llm/providers/index.js';
|
|
23
26
|
import { DEFAULT_RETRY_POLICY } from '../llm/retry/retry-policy.js';
|
|
@@ -26,12 +29,11 @@ import { EventBasedLogger } from '../logger/event-based-logger.js';
|
|
|
26
29
|
import { MemoryManager } from '../memory/memory-manager.js';
|
|
27
30
|
import { ProcessService } from '../process/process-service.js';
|
|
28
31
|
import { SandboxService } from '../sandbox/sandbox-service.js';
|
|
29
|
-
import {
|
|
30
|
-
import { DualFormatHistoryStorage } from '../storage/dual-format-history-storage.js';
|
|
32
|
+
import { FileKeyStorage } from '../storage/file-key-storage.js';
|
|
31
33
|
import { GranularHistoryStorage } from '../storage/granular-history-storage.js';
|
|
32
34
|
import { MessageStorageService } from '../storage/message-storage-service.js';
|
|
33
|
-
import { SqliteKeyStorage } from '../storage/sqlite-key-storage.js';
|
|
34
35
|
import { ContextTreeStructureContributor } from '../system-prompt/contributors/context-tree-structure-contributor.js';
|
|
36
|
+
import { MapSelectionContributor } from '../system-prompt/contributors/map-selection-contributor.js';
|
|
35
37
|
import { SystemPromptManager } from '../system-prompt/system-prompt-manager.js';
|
|
36
38
|
import { CoreToolScheduler } from '../tools/core-tool-scheduler.js';
|
|
37
39
|
import { DEFAULT_POLICY_RULES } from '../tools/default-policy-rules.js';
|
|
@@ -54,7 +56,7 @@ import { ToolProvider } from '../tools/tool-provider.js';
|
|
|
54
56
|
* 8. Policy engine (no dependencies)
|
|
55
57
|
* 9. Tool scheduler (depends on ToolProvider, PolicyEngine)
|
|
56
58
|
* 10. Tool manager (depends on ToolProvider, ToolScheduler)
|
|
57
|
-
* 11. History storage (
|
|
59
|
+
* 11. History storage (file-based granular storage)
|
|
58
60
|
* 12. Return all services
|
|
59
61
|
*
|
|
60
62
|
* @param config - Validated agent configuration (Zod-validated)
|
|
@@ -126,6 +128,10 @@ export async function createCipherAgentServices(config, agentEventBus) {
|
|
|
126
128
|
workingDirectory,
|
|
127
129
|
});
|
|
128
130
|
systemPromptManager.registerContributor(contextTreeContributor);
|
|
131
|
+
// Register map selection contributor for curate commands
|
|
132
|
+
// Priority 16 — right after context tree structure, before memories
|
|
133
|
+
const mapSelectionContributor = new MapSelectionContributor('mapSelection', 16);
|
|
134
|
+
systemPromptManager.registerContributor(mapSelectionContributor);
|
|
129
135
|
// 7. Tool provider (depends on FileSystemService, ProcessService, MemoryManager, SystemPromptManager)
|
|
130
136
|
const verbose = config.llm.verbose ?? false;
|
|
131
137
|
const descriptionLoader = new ToolDescriptionLoader();
|
|
@@ -148,38 +154,22 @@ export async function createCipherAgentServices(config, agentEventBus) {
|
|
|
148
154
|
// 10. Tool manager (with scheduler for policy-based execution)
|
|
149
155
|
const toolManager = new ToolManager(toolProvider, toolScheduler);
|
|
150
156
|
await toolManager.initialize();
|
|
151
|
-
// 11. History storage
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
//
|
|
166
|
-
|
|
167
|
-
// - Existing sessions → BlobHistoryStorage (no migration)
|
|
168
|
-
historyStorage = new DualFormatHistoryStorage(blobHistoryStorage, granularStorage);
|
|
169
|
-
// Create CompactionService for context overflow management
|
|
170
|
-
const tokenizer = new GeminiTokenizer(config.model ?? 'gemini-3-flash-preview');
|
|
171
|
-
compactionService = new CompactionService(messageStorage, tokenizer, {
|
|
172
|
-
overflowThreshold: 0.85, // 85% triggers compaction check
|
|
173
|
-
protectedTurns: 2, // Protect last 2 user turns from pruning
|
|
174
|
-
pruneKeepPercent: 0.2, // Keep 20% of context window in tool outputs
|
|
175
|
-
pruneMinimumPercent: 0.1, // Only prune if 10%+ of context window can be saved
|
|
176
|
-
});
|
|
177
|
-
logger.info('Granular history storage enabled for new sessions');
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
// Default: use blob storage for all sessions
|
|
181
|
-
historyStorage = new BlobHistoryStorage(blobStorage);
|
|
182
|
-
}
|
|
157
|
+
// 11. History storage - granular file-based storage
|
|
158
|
+
const keyStorage = new FileKeyStorage({
|
|
159
|
+
storageDir: storageBasePath,
|
|
160
|
+
});
|
|
161
|
+
await keyStorage.initialize();
|
|
162
|
+
const messageStorage = new MessageStorageService(keyStorage);
|
|
163
|
+
const messageStorageService = messageStorage;
|
|
164
|
+
const historyStorage = new GranularHistoryStorage(messageStorage);
|
|
165
|
+
// CompactionService for context overflow management
|
|
166
|
+
const tokenizer = new GeminiTokenizer(config.model ?? 'gemini-3-flash-preview');
|
|
167
|
+
const compactionService = new CompactionService(messageStorage, tokenizer, {
|
|
168
|
+
overflowThreshold: 0.85, // 85% triggers compaction check
|
|
169
|
+
protectedTurns: 2, // Protect last 2 user turns from pruning
|
|
170
|
+
pruneKeepPercent: 0.2, // Keep 20% of context window in tool outputs
|
|
171
|
+
pruneMinimumPercent: 0.1, // Only prune if 10%+ of context window can be saved
|
|
172
|
+
});
|
|
183
173
|
// 12. Log successful initialization
|
|
184
174
|
logger.info('CipherAgent services initialized successfully', {
|
|
185
175
|
model: config.model,
|
|
@@ -239,6 +229,20 @@ export function createSessionServices(sessionId, sharedServices, httpConfig, llm
|
|
|
239
229
|
logResponses: llmConfig.verbose,
|
|
240
230
|
verbose: llmConfig.verbose,
|
|
241
231
|
});
|
|
232
|
+
// Create escalated compression strategy with retry-only generator (no UI noise).
|
|
233
|
+
// Skip LoggingContentGenerator: avoids llmservice:thinking spinner events.
|
|
234
|
+
// Use a silenced SessionEventBus: RetryableContentGenerator emits
|
|
235
|
+
// llmservice:warning/error via eventBus on retries. Using a detached
|
|
236
|
+
// event bus with no listeners ensures these fire into void.
|
|
237
|
+
const compactionEventBus = new SessionEventBus();
|
|
238
|
+
const compactionGenerator = new RetryableContentGenerator(baseGenerator, {
|
|
239
|
+
eventBus: compactionEventBus,
|
|
240
|
+
policy: DEFAULT_RETRY_POLICY,
|
|
241
|
+
});
|
|
242
|
+
const escalatedStrategy = new EscalatedCompressionStrategy({
|
|
243
|
+
generator: compactionGenerator,
|
|
244
|
+
model: llmConfig.model ?? 'gemini-3-flash-preview',
|
|
245
|
+
});
|
|
242
246
|
return new AgentLLMService(sessionId, generator, {
|
|
243
247
|
maxInputTokens: llmConfig.maxInputTokens,
|
|
244
248
|
maxIterations: llmConfig.maxIterations ?? 50,
|
|
@@ -249,6 +253,11 @@ export function createSessionServices(sessionId, sharedServices, httpConfig, llm
|
|
|
249
253
|
verbose: llmConfig.verbose ?? false,
|
|
250
254
|
}, {
|
|
251
255
|
compactionService: sharedServices.compactionService,
|
|
256
|
+
compressionStrategies: [
|
|
257
|
+
escalatedStrategy,
|
|
258
|
+
new MiddleRemovalStrategy({ preserveEnd: 5, preserveStart: 4 }),
|
|
259
|
+
new OldestRemovalStrategy({ minMessagesToKeep: 4 }),
|
|
260
|
+
],
|
|
252
261
|
historyStorage: sharedServices.historyStorage,
|
|
253
262
|
logger: sessionLogger,
|
|
254
263
|
memoryManager: sharedServices.memoryManager,
|
|
@@ -267,10 +276,8 @@ export function createSessionServices(sessionId, sharedServices, httpConfig, llm
|
|
|
267
276
|
headers: llmConfig.providerHeaders,
|
|
268
277
|
httpConfig: httpConfig,
|
|
269
278
|
httpReferer: llmConfig.httpReferer,
|
|
270
|
-
location: llmConfig.providerLocation,
|
|
271
279
|
maxTokens: llmConfig.maxTokens ?? 8192,
|
|
272
280
|
model: llmConfig.model,
|
|
273
|
-
project: llmConfig.providerProject,
|
|
274
281
|
siteName: llmConfig.siteName,
|
|
275
282
|
temperature: llmConfig.temperature ?? 0.7,
|
|
276
283
|
});
|
|
@@ -2,10 +2,10 @@ import type { BlobStorageConfig } from '../../core/domain/blob/types.js';
|
|
|
2
2
|
import type { IBlobStorage } from '../../core/interfaces/i-blob-storage.js';
|
|
3
3
|
/**
|
|
4
4
|
* Factory function to create blob storage backend.
|
|
5
|
-
*
|
|
5
|
+
* Uses file-based storage with one directory per blob.
|
|
6
6
|
*
|
|
7
7
|
* @param config - Blob storage configuration
|
|
8
|
-
* @returns
|
|
8
|
+
* @returns File-based blob storage implementation
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* const storage = createBlobStorage({ storageDir: '/path/to/xdg/storage' });
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FileBlobStorage } from './file-blob-storage.js';
|
|
2
2
|
/**
|
|
3
3
|
* Factory function to create blob storage backend.
|
|
4
|
-
*
|
|
4
|
+
* Uses file-based storage with one directory per blob.
|
|
5
5
|
*
|
|
6
6
|
* @param config - Blob storage configuration
|
|
7
|
-
* @returns
|
|
7
|
+
* @returns File-based blob storage implementation
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* const storage = createBlobStorage({ storageDir: '/path/to/xdg/storage' });
|
|
11
11
|
*/
|
|
12
12
|
export function createBlobStorage(config) {
|
|
13
|
-
return new
|
|
13
|
+
return new FileBlobStorage(config);
|
|
14
14
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { BlobMetadata, BlobStats, BlobStorageConfig, StoredBlob } from '../../core/domain/blob/types.js';
|
|
2
|
+
import type { IBlobStorage } from '../../core/interfaces/i-blob-storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* File-based blob storage implementation.
|
|
5
|
+
*
|
|
6
|
+
* Stores blobs as individual files on the filesystem:
|
|
7
|
+
* {storageDir}/blobs/{key}/content.bin — binary content
|
|
8
|
+
* {storageDir}/blobs/{key}/metadata.json — JSON metadata
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - One directory per blob (O(1) read/write/delete)
|
|
12
|
+
* - Atomic writes via write-to-temp + rename
|
|
13
|
+
* - Size limit enforcement (per-blob and total)
|
|
14
|
+
* - In-memory mode for fast unit tests
|
|
15
|
+
* - Prefix-based listing via readdir
|
|
16
|
+
*/
|
|
17
|
+
export declare class FileBlobStorage implements IBlobStorage {
|
|
18
|
+
private readonly baseDir;
|
|
19
|
+
private initialized;
|
|
20
|
+
private readonly inMemory;
|
|
21
|
+
private readonly maxBlobSize;
|
|
22
|
+
private readonly maxTotalSize;
|
|
23
|
+
private memoryStore;
|
|
24
|
+
private readonly storageDir;
|
|
25
|
+
constructor(config?: Partial<BlobStorageConfig>);
|
|
26
|
+
/**
|
|
27
|
+
* Clear all blobs from storage.
|
|
28
|
+
*/
|
|
29
|
+
clear(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Close the storage. Releases in-memory data.
|
|
32
|
+
*/
|
|
33
|
+
close(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Delete a blob by its key.
|
|
36
|
+
*/
|
|
37
|
+
delete(key: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Check if a blob exists.
|
|
40
|
+
*/
|
|
41
|
+
exists(key: string): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Get metadata for a blob without retrieving its content.
|
|
44
|
+
*/
|
|
45
|
+
getMetadata(key: string): Promise<BlobMetadata | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Get storage statistics.
|
|
48
|
+
*/
|
|
49
|
+
getStats(): Promise<BlobStats>;
|
|
50
|
+
/**
|
|
51
|
+
* Initialize the storage backend.
|
|
52
|
+
*/
|
|
53
|
+
initialize(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* List all blob keys, optionally filtered by prefix.
|
|
56
|
+
*/
|
|
57
|
+
list(prefix?: string): Promise<string[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieve a blob by its key.
|
|
60
|
+
*/
|
|
61
|
+
retrieve(key: string): Promise<StoredBlob | undefined>;
|
|
62
|
+
/**
|
|
63
|
+
* Store a blob with optional metadata.
|
|
64
|
+
*/
|
|
65
|
+
store(key: string, content: Buffer | string, metadata?: Partial<BlobMetadata>): Promise<StoredBlob>;
|
|
66
|
+
private ensureInitialized;
|
|
67
|
+
/**
|
|
68
|
+
* Get stats by scanning the blobs directory.
|
|
69
|
+
*/
|
|
70
|
+
private getStatsFromDisk;
|
|
71
|
+
/**
|
|
72
|
+
* List keys from disk, optionally filtered by prefix.
|
|
73
|
+
*/
|
|
74
|
+
private listFromDisk;
|
|
75
|
+
/**
|
|
76
|
+
* Read metadata from disk for a given key.
|
|
77
|
+
*/
|
|
78
|
+
private readMetadataFromDisk;
|
|
79
|
+
/**
|
|
80
|
+
* Retrieve a blob from disk.
|
|
81
|
+
*/
|
|
82
|
+
private retrieveFromDisk;
|
|
83
|
+
/**
|
|
84
|
+
* Convert StoredMetadata to public BlobMetadata.
|
|
85
|
+
*/
|
|
86
|
+
private toPublicMetadata;
|
|
87
|
+
/**
|
|
88
|
+
* Validate blob key.
|
|
89
|
+
* Keys must be alphanumeric with hyphens and underscores only.
|
|
90
|
+
*/
|
|
91
|
+
private validateKey;
|
|
92
|
+
/**
|
|
93
|
+
* Write blob content and metadata to disk atomically.
|
|
94
|
+
*/
|
|
95
|
+
private writeToDisk;
|
|
96
|
+
}
|