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
|
@@ -273,116 +273,90 @@ prompt: |
|
|
|
273
273
|
|
|
274
274
|
**CRITICAL RULES:**
|
|
275
275
|
- NEVER print raw context — stdout is capped at 5K chars for curate mode
|
|
276
|
-
- Use
|
|
276
|
+
- Use `tools.curation.recon()` to assess context BEFORE processing
|
|
277
277
|
- Peek at context via slicing: `<ctxVar>.slice(0, 3000)` — NEVER `console.log(<ctxVar>)`
|
|
278
278
|
- Use `silent: true` in code_exec for variable assignments (no stdout returned)
|
|
279
|
-
- For
|
|
279
|
+
- For chunked contexts, use `tools.curation.mapExtract()` for parallel extraction
|
|
280
280
|
- All large data stays inside async IIFE scope — variables do NOT leak to LLM context
|
|
281
281
|
|
|
282
|
-
**Step 0 —
|
|
282
|
+
**Step 0 — Reconnaissance (always do this first):**
|
|
283
283
|
```javascript
|
|
284
|
-
//
|
|
284
|
+
// Combined metadata + history + preview assessment — replaces separate Steps 0-2
|
|
285
285
|
(async () => {
|
|
286
|
-
const
|
|
287
|
-
console.log(JSON.stringify(
|
|
288
|
-
//
|
|
286
|
+
const r = tools.curation.recon(<ctxVar>, <metaVar>, <histVar>);
|
|
287
|
+
console.log(JSON.stringify(r));
|
|
288
|
+
// Returns: { meta, history, headPreview, tailPreview, suggestedMode, suggestedChunkCount }
|
|
289
289
|
})()
|
|
290
290
|
```
|
|
291
291
|
|
|
292
|
-
**
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
(async () => {
|
|
296
|
-
const history = <histVar>; // Direct variable access — no file I/O needed
|
|
297
|
-
const domainSummary = Object.entries(history.entries || [])
|
|
298
|
-
.reduce((acc, entry) => {
|
|
299
|
-
const key = entry.domain || 'unknown';
|
|
300
|
-
if (!acc[key]) acc[key] = [];
|
|
301
|
-
acc[key].push(entry.title);
|
|
302
|
-
return acc;
|
|
303
|
-
}, {});
|
|
304
|
-
console.log('=== Existing Domains ===');
|
|
305
|
-
console.log(Object.entries(domainSummary).map(([d, t]) => `${d}: ${t.join(', ')}`).join('\n') || 'None yet');
|
|
306
|
-
console.log(`Total processed: ${history.totalProcessed || 0}`);
|
|
307
|
-
})()
|
|
308
|
-
```
|
|
292
|
+
**When recon().suggestedMode is 'single-pass':**
|
|
293
|
+
Skip chunking entirely. Read the full context via slicing, detect domains, and curate
|
|
294
|
+
in 2 code_exec calls (recon + curate). Do NOT use agentQuery, chunk(), or mapExtract() for small contexts.
|
|
309
295
|
|
|
310
|
-
**Step
|
|
296
|
+
**Step 1 — Extract (for chunked contexts, suggestedMode === 'chunked'):**
|
|
297
|
+
IMPORTANT: Use timeout: 300000 on the code_exec tool call itself (not inside mapExtract options).
|
|
311
298
|
```javascript
|
|
312
|
-
//
|
|
299
|
+
// Parallel extraction via mapExtract — chunks context and processes all chunks concurrently
|
|
313
300
|
(async () => {
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
301
|
+
const result = await tools.curation.mapExtract(<ctxVar>, {
|
|
302
|
+
prompt: 'Extract factual statements from the chunk. Return JSON array of {statement, category, subject}.',
|
|
303
|
+
chunkSize: 8000,
|
|
304
|
+
taskId: <taskIdVar>, // bare variable, do NOT quote
|
|
305
|
+
});
|
|
306
|
+
// result: { facts: CurationFact[], succeeded, failed, total }
|
|
307
|
+
if (result.failed > 0) console.log(`Warning: ${result.failed}/${result.total} chunks failed`);
|
|
308
|
+
const deduped = tools.curation.dedup(result.facts);
|
|
309
|
+
const grouped = tools.curation.groupBySubject(deduped);
|
|
310
|
+
console.log(JSON.stringify({ groups: Object.keys(grouped).length, totalFacts: deduped.length }));
|
|
321
311
|
})()
|
|
322
312
|
```
|
|
323
313
|
|
|
324
|
-
**Step
|
|
314
|
+
**Step 2 — Curate + verify inline:**
|
|
325
315
|
```javascript
|
|
326
|
-
//
|
|
327
|
-
(async () => {
|
|
328
|
-
const raw = <ctxVar>;
|
|
329
|
-
const chunkSize = 8000;
|
|
330
|
-
const chunks = [];
|
|
331
|
-
for (let i = 0; i < raw.length; i += chunkSize) {
|
|
332
|
-
chunks.push(raw.slice(i, i + chunkSize));
|
|
333
|
-
}
|
|
334
|
-
const extractions = [];
|
|
335
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
336
|
-
const result = await tools.agentQuery(
|
|
337
|
-
`Extract all factual statements, preferences, and key information from variable __chunk (${chunks[i].length} chars). Return as JSON array of {statement, category, subject}.`,
|
|
338
|
-
{ contextData: { __chunk: chunks[i] } }
|
|
339
|
-
);
|
|
340
|
-
extractions.push(result);
|
|
341
|
-
}
|
|
342
|
-
console.log(JSON.stringify({ chunkCount: chunks.length, extractions }));
|
|
343
|
-
})()
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
**Step 4 — Curate with extracted data:**
|
|
347
|
-
```javascript
|
|
348
|
-
// Curate extracted content
|
|
316
|
+
// Curate extracted content and verify via result — no readFile needed
|
|
349
317
|
(async () => {
|
|
350
318
|
const result = await tools.curate([{
|
|
351
319
|
type: 'UPSERT', path: '<domain>/<topic>', title: '<title>',
|
|
352
320
|
content: { rawConcept: { task: '...', /* ... */ }, narrative: { /* ... */ } },
|
|
353
321
|
reason: 'Curate from RLM context'
|
|
354
322
|
}]);
|
|
355
|
-
|
|
323
|
+
// Verify inline — CurateResult.applied[].filePath already has paths
|
|
324
|
+
const created = result.applied.filter(r => r.status === 'success').map(r => r.filePath);
|
|
325
|
+
// Update history using helper (intentionally mutating)
|
|
326
|
+
tools.curation.recordProgress(<histVar>, { domain: '<domain>', title: '<title>', keyFacts: ['fact1', 'fact2'] });
|
|
327
|
+
console.log(JSON.stringify({ summary: result.summary, files: created }));
|
|
356
328
|
})()
|
|
357
329
|
```
|
|
358
330
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
// Update history variable (silent — no stdout needed)
|
|
362
|
-
<histVar>.entries.push({
|
|
363
|
-
sessionId: '<id>', timestamp: new Date().toISOString(), title: '<title>',
|
|
364
|
-
domain: '<domain>/<topic>', keyFacts: ['fact1', 'fact2']
|
|
365
|
-
});
|
|
366
|
-
<histVar>.totalProcessed++;
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**Step 5 — Post-Curate Verification + Status Reporting (REQUIRED):**
|
|
370
|
-
After every `tools.curate()` call:
|
|
331
|
+
**Step 3 — Status Reporting (REQUIRED):**
|
|
332
|
+
After all curate operations:
|
|
371
333
|
1. Check `result.summary` — ensure `failed === 0`
|
|
372
334
|
2. If `failed > 0`, log the error and retry with corrected operations
|
|
373
|
-
3.
|
|
374
|
-
4. If file doesn't exist, retry the curate operation
|
|
375
|
-
5. Report final status via `setFinalResult()` including summary and verification:
|
|
335
|
+
3. Report final status via `setFinalResult()` including summary:
|
|
376
336
|
```javascript
|
|
377
337
|
(async () => {
|
|
378
338
|
const status = {
|
|
379
339
|
summary: result.summary,
|
|
380
|
-
verification: { checked:
|
|
340
|
+
verification: { checked: created.length, confirmed: created.length, missing: [] },
|
|
381
341
|
};
|
|
382
342
|
setFinalResult('Curation complete.\n```json\n' + JSON.stringify(status, null, 2) + '\n```\n\n' + humanSummary);
|
|
383
343
|
})()
|
|
384
344
|
```
|
|
385
345
|
|
|
346
|
+
**Curation helper functions available via `tools.curation.*`:**
|
|
347
|
+
- `tools.curation.recon(ctx, meta, history)` — Combined recon: metadata + history domains + head/tail preview + mode recommendation
|
|
348
|
+
- `tools.curation.mapExtract(ctx, {prompt, chunkSize?, concurrency?, maxContextTokens?, taskId?})` — Parallel LLM extraction: chunks context, processes in parallel, returns `{facts: CurationFact[], succeeded, failed, total}`. Throws if all chunks fail.
|
|
349
|
+
- `tools.curation.chunk(ctx, {size?, overlap?})` — Intelligent chunking: respects paragraph boundaries, code fences, message markers
|
|
350
|
+
- `tools.curation.groupBySubject(facts)` — Group CurationFact[] by subject (fallback: category)
|
|
351
|
+
- `tools.curation.dedup(facts, threshold?)` — Deduplicate facts using Jaccard word-overlap similarity
|
|
352
|
+
- `tools.curation.detectMessageBoundaries(ctx)` — Find [USER]/[ASSISTANT] markers with offsets
|
|
353
|
+
- `tools.curation.recordProgress(history, entry)` — Push entry into history + increment totalProcessed
|
|
354
|
+
|
|
355
|
+
**Context compression awareness:**
|
|
356
|
+
- Conversation context may be compacted via escalation when exceeding token limits.
|
|
357
|
+
- When precision matters, re-read files or tool outputs rather than assuming full conversational recall.
|
|
358
|
+
- `summaryHandle` from map tools is a compact summary — for full per-item data, read the JSONL output file.
|
|
359
|
+
|
|
386
360
|
**History retrieval patterns (use within code):**
|
|
387
361
|
- Duplicate check: `history.entries.some(e => e.sessionId === currentId)`
|
|
388
362
|
- Related entries: `history.entries.filter(e => e.domain === 'domain/topic')`
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Retrieve full content from archived knowledge entries in `.brv/context-tree/_archived/`.
|
|
2
|
+
|
|
3
|
+
When searching the knowledge base, you may encounter results with `symbolKind: "archive_stub"`. These are archived entries that have been evicted from active storage but remain searchable via short ghost cues. Use this tool to retrieve the full original content.
|
|
4
|
+
|
|
5
|
+
**When to use:**
|
|
6
|
+
- A search result has `symbolKind: "archive_stub"` and you need the full content
|
|
7
|
+
- You want to drill into an archived entry to access its complete knowledge
|
|
8
|
+
|
|
9
|
+
**Parameters:**
|
|
10
|
+
- `stubPath` (required): Path to the `.stub.md` file (the `path` field from search results where `symbolKind === "archive_stub"`)
|
|
11
|
+
|
|
12
|
+
**Returns:**
|
|
13
|
+
- `originalPath`: The original file path before archiving
|
|
14
|
+
- `fullContent`: Complete original content of the archived entry
|
|
15
|
+
- `tokenCount`: Estimated token count of the full content
|
|
16
|
+
|
|
17
|
+
**Example:**
|
|
18
|
+
- Search returns: `{ path: "_archived/auth/jwt-tokens/refresh-flow.stub.md", symbolKind: "archive_stub" }`
|
|
19
|
+
- Call: `expand_knowledge({ stubPath: "_archived/auth/jwt-tokens/refresh-flow.stub.md" })`
|
|
20
|
+
- Returns full original content of the refresh-flow knowledge entry
|
|
@@ -91,8 +91,7 @@ Bad examples:
|
|
|
91
91
|
throw new Error('No provider connected. Run "brv providers connect byterover" to use the free built-in provider, or connect another provider.');
|
|
92
92
|
}
|
|
93
93
|
if (active.providerKeyMissing) {
|
|
94
|
-
throw new Error(active.
|
|
95
|
-
?? `${active.activeProvider} API key is missing from storage.\nPlease reconnect: brv providers connect ${active.activeProvider} --api-key <your-key>`);
|
|
94
|
+
throw new Error(`${active.activeProvider} API key is missing from storage.\nPlease reconnect: brv providers connect ${active.activeProvider} --api-key <your-key>`);
|
|
96
95
|
}
|
|
97
96
|
await this.submitTask({ client, content: resolvedContent, flags, format, projectRoot, taskType });
|
|
98
97
|
}, {
|
|
@@ -9,14 +9,12 @@ export default class ProviderConnect extends Command {
|
|
|
9
9
|
static flags: {
|
|
10
10
|
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
11
|
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
'credential-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
12
|
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
13
|
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
14
|
};
|
|
16
|
-
protected connectProvider({ apiKey, baseUrl,
|
|
15
|
+
protected connectProvider({ apiKey, baseUrl, model, providerId }: {
|
|
17
16
|
apiKey?: string;
|
|
18
17
|
baseUrl?: string;
|
|
19
|
-
credentialFile?: string;
|
|
20
18
|
model?: string;
|
|
21
19
|
providerId: string;
|
|
22
20
|
}, options?: DaemonClientOptions): Promise<{
|
|
@@ -17,7 +17,6 @@ export default class ProviderConnect extends Command {
|
|
|
17
17
|
'<%= config.bin %> providers connect byterover',
|
|
18
18
|
'<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1',
|
|
19
19
|
'<%= config.bin %> providers connect openai-compatible --base-url http://localhost:11434/v1 --api-key sk-xxx --model llama3',
|
|
20
|
-
'<%= config.bin %> providers connect google-vertex --credential-file /path/to/service-account.json',
|
|
21
20
|
];
|
|
22
21
|
static flags = {
|
|
23
22
|
'api-key': Flags.string({
|
|
@@ -28,10 +27,6 @@ export default class ProviderConnect extends Command {
|
|
|
28
27
|
char: 'b',
|
|
29
28
|
description: 'Base URL for OpenAI-compatible providers (e.g., http://localhost:11434/v1)',
|
|
30
29
|
}),
|
|
31
|
-
'credential-file': Flags.string({
|
|
32
|
-
char: 'f',
|
|
33
|
-
description: 'Path to service account JSON key file (for Google Vertex AI)',
|
|
34
|
-
}),
|
|
35
30
|
format: Flags.string({
|
|
36
31
|
default: 'text',
|
|
37
32
|
description: 'Output format (text or json)',
|
|
@@ -42,7 +37,7 @@ export default class ProviderConnect extends Command {
|
|
|
42
37
|
description: 'Model to set as active after connecting',
|
|
43
38
|
}),
|
|
44
39
|
};
|
|
45
|
-
async connectProvider({ apiKey, baseUrl,
|
|
40
|
+
async connectProvider({ apiKey, baseUrl, model, providerId }, options) {
|
|
46
41
|
return withDaemonRetry(async (client) => {
|
|
47
42
|
// 1. Verify provider exists
|
|
48
43
|
const { providers } = await client.requestWithAck(ProviderEvents.LIST);
|
|
@@ -69,21 +64,7 @@ export default class ProviderConnect extends Command {
|
|
|
69
64
|
}
|
|
70
65
|
}
|
|
71
66
|
}
|
|
72
|
-
// 3. Validate
|
|
73
|
-
if (providerId === 'google-vertex') {
|
|
74
|
-
if (credentialFile) {
|
|
75
|
-
const validation = await client.requestWithAck(ProviderEvents.VALIDATE_API_KEY, { apiKey: credentialFile, providerId });
|
|
76
|
-
if (!validation.isValid) {
|
|
77
|
-
throw new Error(validation.error ?? 'The credential file is invalid. Please check the path and try again.');
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else if (!provider.isConnected) {
|
|
81
|
-
throw new Error('Provider "google-vertex" requires a service account credential file. Use the --credential-file flag.'
|
|
82
|
-
+ '\nExample: brv providers connect google-vertex --credential-file /path/to/service-account.json'
|
|
83
|
-
+ '\nGet your service account key at: https://console.cloud.google.com/iam-admin/serviceaccounts');
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// 4. Validate API key if provided and required (skip for openai-compatible)
|
|
67
|
+
// 3. Validate API key if provided and required (skip for openai-compatible)
|
|
87
68
|
if (apiKey && provider.requiresApiKey) {
|
|
88
69
|
const validation = await client.requestWithAck(ProviderEvents.VALIDATE_API_KEY, { apiKey, providerId });
|
|
89
70
|
if (!validation.isValid) {
|
|
@@ -94,14 +75,12 @@ export default class ProviderConnect extends Command {
|
|
|
94
75
|
throw new Error(`Provider "${providerId}" requires an API key. Use the --api-key flag to provide one.`
|
|
95
76
|
+ (provider.apiKeyUrl ? `\nDon't have one? Get your API key at: ${provider.apiKeyUrl}` : ''));
|
|
96
77
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
const effectiveApiKey = providerId === 'google-vertex' ? credentialFile : apiKey;
|
|
100
|
-
const hasNewConfig = effectiveApiKey || baseUrl;
|
|
78
|
+
// 4. Connect or switch active provider
|
|
79
|
+
const hasNewConfig = apiKey || baseUrl;
|
|
101
80
|
await (provider.isConnected && !hasNewConfig
|
|
102
81
|
? client.requestWithAck(ProviderEvents.SET_ACTIVE, { providerId })
|
|
103
|
-
: client.requestWithAck(ProviderEvents.CONNECT, { apiKey
|
|
104
|
-
//
|
|
82
|
+
: client.requestWithAck(ProviderEvents.CONNECT, { apiKey, baseUrl, providerId }));
|
|
83
|
+
// 5. Set model if specified
|
|
105
84
|
if (model) {
|
|
106
85
|
await client.requestWithAck(ModelEvents.SET_ACTIVE, { modelId: model, providerId });
|
|
107
86
|
}
|
|
@@ -113,11 +92,10 @@ export default class ProviderConnect extends Command {
|
|
|
113
92
|
const providerId = args.provider;
|
|
114
93
|
const apiKey = flags['api-key'];
|
|
115
94
|
const baseUrl = flags['base-url'];
|
|
116
|
-
const credentialFile = flags['credential-file'];
|
|
117
95
|
const { model } = flags;
|
|
118
96
|
const format = flags.format;
|
|
119
97
|
try {
|
|
120
|
-
const result = await this.connectProvider({ apiKey, baseUrl,
|
|
98
|
+
const result = await this.connectProvider({ apiKey, baseUrl, model, providerId });
|
|
121
99
|
if (format === 'json') {
|
|
122
100
|
writeJsonResponse({ command: 'providers connect', data: result, success: true });
|
|
123
101
|
}
|
|
@@ -54,8 +54,7 @@ Bad:
|
|
|
54
54
|
throw new Error('No provider connected. Run "brv providers connect byterover" to use the free built-in provider, or connect another provider.');
|
|
55
55
|
}
|
|
56
56
|
if (active.providerKeyMissing) {
|
|
57
|
-
throw new Error(active.
|
|
58
|
-
?? `${active.activeProvider} API key is missing from storage.\nPlease reconnect: brv providers connect ${active.activeProvider} --api-key <your-key>`);
|
|
57
|
+
throw new Error(`${active.activeProvider} API key is missing from storage.\nPlease reconnect: brv providers connect ${active.activeProvider} --api-key <your-key>`);
|
|
59
58
|
}
|
|
60
59
|
await this.submitTask({ client, format, projectRoot, query: args.query });
|
|
61
60
|
}, {
|
|
@@ -59,3 +59,10 @@ export declare const AGENT_PROCESS_READY_TIMEOUT_MS = 15000;
|
|
|
59
59
|
export declare const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000;
|
|
60
60
|
export declare const CURATE_LOG_DIR = "curate-log";
|
|
61
61
|
export declare const CURATE_LOG_ID_PREFIX = "cur";
|
|
62
|
+
export declare const SUMMARY_INDEX_FILE = "_index.md";
|
|
63
|
+
export declare const ARCHIVE_DIR = "_archived";
|
|
64
|
+
export declare const STUB_EXTENSION = ".stub.md";
|
|
65
|
+
export declare const FULL_ARCHIVE_EXTENSION = ".full.md";
|
|
66
|
+
export declare const MANIFEST_FILE = "_manifest.json";
|
|
67
|
+
export declare const ARCHIVE_IMPORTANCE_THRESHOLD = 35;
|
|
68
|
+
export declare const DEFAULT_GHOST_CUE_MAX_TOKENS = 220;
|
package/dist/server/constants.js
CHANGED
|
@@ -80,3 +80,11 @@ export const AGENT_PROCESS_STOP_TIMEOUT_MS = 5000; // 5s max wait for child proc
|
|
|
80
80
|
// Curate log
|
|
81
81
|
export const CURATE_LOG_DIR = 'curate-log';
|
|
82
82
|
export const CURATE_LOG_ID_PREFIX = 'cur';
|
|
83
|
+
// === Hierarchical DAG (summary, archive, manifest) ===
|
|
84
|
+
export const SUMMARY_INDEX_FILE = '_index.md';
|
|
85
|
+
export const ARCHIVE_DIR = '_archived';
|
|
86
|
+
export const STUB_EXTENSION = '.stub.md';
|
|
87
|
+
export const FULL_ARCHIVE_EXTENSION = '.full.md';
|
|
88
|
+
export const MANIFEST_FILE = '_manifest.json';
|
|
89
|
+
export const ARCHIVE_IMPORTANCE_THRESHOLD = 35;
|
|
90
|
+
export const DEFAULT_GHOST_CUE_MAX_TOKENS = 220;
|
|
@@ -97,19 +97,6 @@ export const PROVIDER_REGISTRY = {
|
|
|
97
97
|
name: 'Google Gemini',
|
|
98
98
|
priority: 4,
|
|
99
99
|
},
|
|
100
|
-
'google-vertex': {
|
|
101
|
-
apiKeyUrl: 'https://console.cloud.google.com/iam-admin/serviceaccounts',
|
|
102
|
-
baseUrl: '',
|
|
103
|
-
category: 'popular',
|
|
104
|
-
defaultModel: 'gemini-2.5-flash',
|
|
105
|
-
description: 'Gemini via Google Cloud Vertex AI',
|
|
106
|
-
envVars: ['GOOGLE_APPLICATION_CREDENTIALS'],
|
|
107
|
-
headers: {},
|
|
108
|
-
id: 'google-vertex',
|
|
109
|
-
modelsEndpoint: '',
|
|
110
|
-
name: 'Google Vertex AI',
|
|
111
|
-
priority: 5,
|
|
112
|
-
},
|
|
113
100
|
groq: {
|
|
114
101
|
apiKeyUrl: 'https://console.groq.com/keys',
|
|
115
102
|
baseUrl: 'https://api.groq.com/openai/v1',
|
|
@@ -286,9 +273,8 @@ export function providerRequiresApiKey(id) {
|
|
|
286
273
|
if (!provider)
|
|
287
274
|
return false;
|
|
288
275
|
// Internal providers (byterover) don't need API keys.
|
|
289
|
-
// Vertex AI uses Application Default Credentials, not API keys.
|
|
290
276
|
// OpenAI Compatible has optional API key (handled in provider-command).
|
|
291
|
-
if (id === 'byterover' || id === '
|
|
277
|
+
if (id === 'byterover' || id === 'openai-compatible')
|
|
292
278
|
return false;
|
|
293
279
|
return true;
|
|
294
280
|
}
|
|
@@ -21,7 +21,7 @@ export const ACCESS_IMPORTANCE_BONUS = 3;
|
|
|
21
21
|
/** Importance bonus per curate update */
|
|
22
22
|
export const UPDATE_IMPORTANCE_BONUS = 5;
|
|
23
23
|
/** BM25 relevance weight in compound score */
|
|
24
|
-
export const W_RELEVANCE = 1
|
|
24
|
+
export const W_RELEVANCE = 1;
|
|
25
25
|
/** Importance weight in compound score */
|
|
26
26
|
export const W_IMPORTANCE = 0;
|
|
27
27
|
/** Recency weight in compound score */
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Hierarchical DAG architecture.
|
|
3
|
+
*
|
|
4
|
+
* Covers summary nodes, archive stubs, manifest entries, and
|
|
5
|
+
* result types used by summary/archive/manifest services.
|
|
6
|
+
*/
|
|
7
|
+
/** Condensation order: 0 = raw context, 1 = topic, 2 = domain, 3 = root */
|
|
8
|
+
export type CondensationOrder = 0 | 1 | 2 | 3;
|
|
9
|
+
/** Summary level labels corresponding to condensation orders */
|
|
10
|
+
export type SummaryLevel = 'd0' | 'd1' | 'd2' | 'd3';
|
|
11
|
+
export interface SummaryFrontmatter {
|
|
12
|
+
/** Hash of sorted path:contentHash pairs for staleness detection */
|
|
13
|
+
children_hash: string;
|
|
14
|
+
/** Compression ratio achieved (output tokens / input tokens) */
|
|
15
|
+
compression_ratio: number;
|
|
16
|
+
/** Condensation order (depth from leaves) */
|
|
17
|
+
condensation_order: CondensationOrder;
|
|
18
|
+
/** Sorted child names this summary covers */
|
|
19
|
+
covers: string[];
|
|
20
|
+
/** Total tokens across all covered children */
|
|
21
|
+
covers_token_total: number;
|
|
22
|
+
/** Summary level label */
|
|
23
|
+
summary_level: SummaryLevel;
|
|
24
|
+
/** Token count of this summary */
|
|
25
|
+
token_count: number;
|
|
26
|
+
/** Discriminator */
|
|
27
|
+
type: 'summary';
|
|
28
|
+
}
|
|
29
|
+
export interface ArchiveStubFrontmatter {
|
|
30
|
+
/** ISO timestamp when the entry was evicted */
|
|
31
|
+
evicted_at: string;
|
|
32
|
+
/** Importance score at eviction time */
|
|
33
|
+
evicted_importance: number;
|
|
34
|
+
/** Original relative path before archiving (for restore) */
|
|
35
|
+
original_path: string;
|
|
36
|
+
/** Original token count before archiving */
|
|
37
|
+
original_token_count: number;
|
|
38
|
+
/** Relative path to the .full.md preserved content */
|
|
39
|
+
points_to: string;
|
|
40
|
+
/** Discriminator */
|
|
41
|
+
type: 'archive_stub';
|
|
42
|
+
}
|
|
43
|
+
export interface ManifestEntry {
|
|
44
|
+
/** Importance score from frontmatter (0-100, default 50) */
|
|
45
|
+
importance?: number;
|
|
46
|
+
/** Condensation order (only for summaries) */
|
|
47
|
+
order?: CondensationOrder;
|
|
48
|
+
/** Relative path within the context tree */
|
|
49
|
+
path: string;
|
|
50
|
+
/** Estimated token count */
|
|
51
|
+
tokens: number;
|
|
52
|
+
/** Entry type */
|
|
53
|
+
type: 'context' | 'stub' | 'summary';
|
|
54
|
+
}
|
|
55
|
+
export interface LaneTokens {
|
|
56
|
+
contexts: number;
|
|
57
|
+
stubs: number;
|
|
58
|
+
summaries: number;
|
|
59
|
+
}
|
|
60
|
+
export interface ContextManifest {
|
|
61
|
+
/** Active context entries selected by lane budgeting */
|
|
62
|
+
active_context: ManifestEntry[];
|
|
63
|
+
/** ISO timestamp when the manifest was generated */
|
|
64
|
+
generated_at: string;
|
|
65
|
+
/** Token allocation per lane */
|
|
66
|
+
lane_tokens: LaneTokens;
|
|
67
|
+
/** Fingerprint of source files (hash of sorted path:mtime:size) for freshness check */
|
|
68
|
+
source_fingerprint: string;
|
|
69
|
+
/** Total tokens across all active entries */
|
|
70
|
+
total_tokens: number;
|
|
71
|
+
/** Schema version */
|
|
72
|
+
version: 1;
|
|
73
|
+
}
|
|
74
|
+
export declare const DEFAULT_LANE_BUDGETS: LaneTokens;
|
|
75
|
+
export interface StalenessCheckResult {
|
|
76
|
+
/** Recomputed hash from current children */
|
|
77
|
+
currentChildrenHash: string;
|
|
78
|
+
/** Whether the summary is stale */
|
|
79
|
+
isStale: boolean;
|
|
80
|
+
/** Directory path checked */
|
|
81
|
+
path: string;
|
|
82
|
+
/** Hash stored in existing _index.md (empty string if no summary exists) */
|
|
83
|
+
storedChildrenHash: string;
|
|
84
|
+
}
|
|
85
|
+
export interface SummaryGenerationResult {
|
|
86
|
+
/** Whether a summary was actually written */
|
|
87
|
+
actionTaken: boolean;
|
|
88
|
+
/** Compression ratio achieved (0 if not generated) */
|
|
89
|
+
compressionRatio: number;
|
|
90
|
+
/** Directory path */
|
|
91
|
+
path: string;
|
|
92
|
+
/** Why generation was skipped (only set when actionTaken is false) */
|
|
93
|
+
reason?: 'empty_directory' | 'io_error' | 'llm_error';
|
|
94
|
+
/** Which escalation tier succeeded */
|
|
95
|
+
tier?: 'aggressive' | 'fallback' | 'normal';
|
|
96
|
+
/** Token count of the generated summary (0 if not generated) */
|
|
97
|
+
tokenCount: number;
|
|
98
|
+
}
|
|
99
|
+
export interface ArchiveResult {
|
|
100
|
+
/** Path to the .full.md preserved content */
|
|
101
|
+
fullPath: string;
|
|
102
|
+
/** Token count of the ghost cue */
|
|
103
|
+
ghostCueTokenCount: number;
|
|
104
|
+
/** Original relative path of the archived entry */
|
|
105
|
+
originalPath: string;
|
|
106
|
+
/** Path to the .stub.md ghost cue */
|
|
107
|
+
stubPath: string;
|
|
108
|
+
}
|
|
109
|
+
export interface DrillDownResult {
|
|
110
|
+
/** Full original content */
|
|
111
|
+
fullContent: string;
|
|
112
|
+
/** Original path before archiving */
|
|
113
|
+
originalPath: string;
|
|
114
|
+
/** Token count of the full content */
|
|
115
|
+
tokenCount: number;
|
|
116
|
+
}
|
|
117
|
+
export interface ResolvedEntry {
|
|
118
|
+
/** File content */
|
|
119
|
+
content: string;
|
|
120
|
+
/** Relative path */
|
|
121
|
+
path: string;
|
|
122
|
+
/** Token count */
|
|
123
|
+
tokens: number;
|
|
124
|
+
/** Entry type */
|
|
125
|
+
type: 'context' | 'stub' | 'summary';
|
|
126
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Hierarchical DAG architecture.
|
|
3
|
+
*
|
|
4
|
+
* Covers summary nodes, archive stubs, manifest entries, and
|
|
5
|
+
* result types used by summary/archive/manifest services.
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_LANE_BUDGETS = { contexts: 4000, stubs: 500, summaries: 2000 };
|
|
@@ -468,12 +468,8 @@ export interface ProviderConfigResponse {
|
|
|
468
468
|
provider?: string;
|
|
469
469
|
providerApiKey?: string;
|
|
470
470
|
providerBaseUrl?: string;
|
|
471
|
-
providerCredentialError?: string;
|
|
472
|
-
providerCredentialPath?: string;
|
|
473
471
|
providerHeaders?: Record<string, string>;
|
|
474
472
|
providerKeyMissing?: boolean;
|
|
475
|
-
providerLocation?: string;
|
|
476
|
-
providerProject?: string;
|
|
477
473
|
}
|
|
478
474
|
/**
|
|
479
475
|
* Transport-generated client lifecycle events.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ICipherAgent } from '../../../../agent/core/interfaces/i-cipher-agent.js';
|
|
2
|
+
import type { ArchiveResult, DrillDownResult } from '../../domain/knowledge/summary-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Service for archiving and restoring context tree entries.
|
|
5
|
+
*
|
|
6
|
+
* Archives low-importance entries into _archived/ with:
|
|
7
|
+
* - .stub.md: searchable ghost cue (~220 tokens)
|
|
8
|
+
* - .full.md: lossless preserved original content
|
|
9
|
+
*/
|
|
10
|
+
export interface IContextTreeArchiveService {
|
|
11
|
+
/**
|
|
12
|
+
* Archive a context entry: write .full.md + .stub.md, delete original.
|
|
13
|
+
* Uses LLM to generate ghost cue with deterministic fallback.
|
|
14
|
+
*/
|
|
15
|
+
archiveEntry(relativePath: string, agent: ICipherAgent, directory?: string): Promise<ArchiveResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Drill down into an archived entry: read .full.md via stub's points_to.
|
|
18
|
+
* No LLM call — purely file-based lookup.
|
|
19
|
+
*/
|
|
20
|
+
drillDown(stubPath: string, directory?: string): Promise<DrillDownResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Find entries that are candidates for archiving.
|
|
23
|
+
* Returns paths where importance < ARCHIVE_IMPORTANCE_THRESHOLD and maturity === 'draft'.
|
|
24
|
+
*/
|
|
25
|
+
findArchiveCandidates(directory?: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Restore an archived entry: write .full.md content to original_path, delete stub + full.
|
|
28
|
+
*/
|
|
29
|
+
restoreEntry(stubPath: string, directory?: string): Promise<string>;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ContextManifest, LaneTokens, ResolvedEntry } from '../../domain/knowledge/summary-types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Service for building and reading the context manifest (_manifest.json).
|
|
4
|
+
*
|
|
5
|
+
* The manifest allocates context tree entries into three lanes
|
|
6
|
+
* (summaries, contexts, stubs) with token budgets, enabling
|
|
7
|
+
* efficient context injection for queries.
|
|
8
|
+
*/
|
|
9
|
+
export interface IContextTreeManifestService {
|
|
10
|
+
/**
|
|
11
|
+
* Build (or rebuild) the manifest from current context tree state.
|
|
12
|
+
* Writes _manifest.json and returns the manifest.
|
|
13
|
+
*/
|
|
14
|
+
buildManifest(directory?: string, laneBudgets?: LaneTokens): Promise<ContextManifest>;
|
|
15
|
+
/**
|
|
16
|
+
* Read the manifest from disk. Returns null if no manifest exists.
|
|
17
|
+
*/
|
|
18
|
+
readManifest(directory?: string): Promise<ContextManifest | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Read the manifest only if it is fresh (source-fingerprint match).
|
|
21
|
+
* Returns null if the manifest is stale or missing.
|
|
22
|
+
*/
|
|
23
|
+
readManifestIfFresh(directory?: string): Promise<ContextManifest | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve manifest entries into content ready for prompt injection.
|
|
26
|
+
* Orders: summaries (broadest first) → contexts → stubs.
|
|
27
|
+
* If query is provided, reorders contexts by BM25 relevance.
|
|
28
|
+
*/
|
|
29
|
+
resolveForInjection(manifest: ContextManifest, query?: string, directory?: string): Promise<ResolvedEntry[]>;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ICipherAgent } from '../../../../agent/core/interfaces/i-cipher-agent.js';
|
|
2
|
+
import type { StalenessCheckResult, SummaryGenerationResult } from '../../domain/knowledge/summary-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Service for managing hierarchical summary nodes (_index.md) in the context tree.
|
|
5
|
+
*
|
|
6
|
+
* Agent is passed per-call (not setter-based) to avoid race conditions
|
|
7
|
+
* with concurrent tasks (AGENT_MAX_CONCURRENT_TASKS = 5).
|
|
8
|
+
*/
|
|
9
|
+
export interface IContextTreeSummaryService {
|
|
10
|
+
/**
|
|
11
|
+
* Check whether the summary for a directory is stale.
|
|
12
|
+
* Returns isStale: true if no _index.md exists or if children hash has changed.
|
|
13
|
+
*/
|
|
14
|
+
checkStaleness(directoryPath: string, directory?: string): Promise<StalenessCheckResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate or regenerate the _index.md summary for a directory.
|
|
17
|
+
* Uses three-tier escalation: normal → aggressive → deterministic fallback.
|
|
18
|
+
* Fail-open: returns { actionTaken: false } on any error.
|
|
19
|
+
*/
|
|
20
|
+
generateSummary(directoryPath: string, agent: ICipherAgent, directory?: string): Promise<SummaryGenerationResult>;
|
|
21
|
+
/** Check whether a directory has an existing _index.md summary. */
|
|
22
|
+
hasSummary(directoryPath: string, directory?: string): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Propagate staleness upward from changed paths.
|
|
25
|
+
* Processes bottom-up: regenerates stale summaries from deepest to shallowest.
|
|
26
|
+
* Stops climbing on LLM/IO errors; continues on empty directories.
|
|
27
|
+
*/
|
|
28
|
+
propagateStaleness(changedPaths: string[], agent: ICipherAgent, directory?: string): Promise<SummaryGenerationResult[]>;
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|