@compilr-dev/agents 0.3.10 → 0.3.12
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 +84 -41
- package/dist/agent.d.ts +23 -0
- package/dist/agent.js +41 -7
- package/dist/anchors/manager.js +3 -2
- package/dist/context/delegated-result-store.d.ts +67 -0
- package/dist/context/delegated-result-store.js +99 -0
- package/dist/context/delegation-types.d.ts +82 -0
- package/dist/context/delegation-types.js +18 -0
- package/dist/context/index.d.ts +6 -0
- package/dist/context/index.js +4 -0
- package/dist/context/manager.js +12 -32
- package/dist/context/tool-result-delegator.d.ts +63 -0
- package/dist/context/tool-result-delegator.js +305 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +9 -3
- package/dist/memory/loader.js +2 -1
- package/dist/memory/types.d.ts +1 -1
- package/dist/providers/claude.d.ts +1 -5
- package/dist/providers/claude.js +3 -28
- package/dist/providers/gemini-native.d.ts +1 -1
- package/dist/providers/gemini-native.js +3 -24
- package/dist/providers/mock.d.ts +1 -1
- package/dist/providers/mock.js +3 -24
- package/dist/providers/openai-compatible.d.ts +1 -5
- package/dist/providers/openai-compatible.js +3 -28
- package/dist/rate-limit/provider-wrapper.d.ts +1 -1
- package/dist/rate-limit/provider-wrapper.js +3 -27
- package/dist/tools/builtin/index.d.ts +2 -0
- package/dist/tools/builtin/index.js +2 -0
- package/dist/tools/builtin/recall-result.d.ts +29 -0
- package/dist/tools/builtin/recall-result.js +48 -0
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.js +2 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/tokenizer.d.ts +18 -0
- package/dist/utils/tokenizer.js +56 -0
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
# @compilr-dev/agents
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
```
|
|
4
|
+
\|/
|
|
5
|
+
╭══════════╮ ___ ___ _ __ ___ _ __ (_) |_ __
|
|
6
|
+
║' ▐▌ ▐▌ │ / __|/ _ \| '_ ` _ \| '_ \| | | '__|
|
|
7
|
+
║ │ | (__| (_) | | | | | | |_) | | | |
|
|
8
|
+
╰─═──────═─╯ \___|\___/|_| |_| |_| .__/|_|_|_|
|
|
9
|
+
\________\ | | .dev
|
|
10
|
+
|_| agents
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Lightweight multi-LLM agent library for building CLI AI assistants
|
|
14
|
+
|
|
15
|
+
[](https://www.npmjs.com/package/@compilr-dev/agents)
|
|
16
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
17
|
|
|
5
18
|
## Features
|
|
6
19
|
|
|
7
|
-
- **Multi-LLM Support**:
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
20
|
+
- **Multi-LLM Support**: 9 providers -- Claude, OpenAI, Gemini, Ollama (local), Together AI, Groq, Fireworks, Perplexity, OpenRouter
|
|
21
|
+
- **17 Built-in Tools**: File ops, bash, grep, glob, edit, web fetch, sub-agents, todos, backlog, and more
|
|
22
|
+
- **Sub-agents**: Spawn specialized agents for complex tasks (9 built-in agent types)
|
|
23
|
+
- **11 Skills**: Reusable prompt templates for common workflows
|
|
24
|
+
- **Context Management**: Token budgeting, compaction, summarization
|
|
25
|
+
- **Event Streaming**: Real-time execution monitoring with typed events and abort support
|
|
12
26
|
- **Anchors**: Critical information that survives context compaction
|
|
13
|
-
- **Guardrails**:
|
|
14
|
-
- **Permissions**: Tool-level
|
|
15
|
-
- **Project Memory**:
|
|
16
|
-
- **
|
|
27
|
+
- **Guardrails**: 15 built-in patterns for safety checks (warn/confirm/block)
|
|
28
|
+
- **Permissions**: Tool-level access control (always/session/once/deny) with wildcards
|
|
29
|
+
- **Project Memory**: Auto-loads CLAUDE.md, GEMINI.md, CURSOR.md, and more
|
|
30
|
+
- **Hooks System**: Lifecycle hooks for beforeChat, afterChat, beforeToolCall, afterToolCall
|
|
31
|
+
- **Rate Limiting**: Automatic retry with exponential backoff
|
|
32
|
+
- **TypeScript First**: Full type safety with strict mode
|
|
17
33
|
|
|
18
34
|
## Installation
|
|
19
35
|
|
|
@@ -282,15 +298,43 @@ try {
|
|
|
282
298
|
|
|
283
299
|
## Providers
|
|
284
300
|
|
|
285
|
-
###
|
|
301
|
+
### Built-in Providers
|
|
286
302
|
|
|
287
303
|
```typescript
|
|
288
|
-
import {
|
|
304
|
+
import {
|
|
305
|
+
ClaudeProvider, // Anthropic Claude
|
|
306
|
+
OpenAIProvider, // OpenAI GPT
|
|
307
|
+
GeminiProvider, // Google Gemini
|
|
308
|
+
OllamaProvider, // Local models (no API key)
|
|
309
|
+
TogetherProvider, // Together AI
|
|
310
|
+
GroqProvider, // Groq (fast inference)
|
|
311
|
+
FireworksProvider, // Fireworks AI
|
|
312
|
+
PerplexityProvider, // Perplexity (search-augmented)
|
|
313
|
+
OpenRouterProvider, // OpenRouter (multi-provider)
|
|
314
|
+
} from '@compilr-dev/agents';
|
|
289
315
|
|
|
290
|
-
|
|
316
|
+
// Claude (recommended)
|
|
317
|
+
const claude = new ClaudeProvider({
|
|
291
318
|
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
292
|
-
model: 'claude-sonnet-4-20250514',
|
|
293
|
-
|
|
319
|
+
model: 'claude-sonnet-4-20250514',
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// OpenAI
|
|
323
|
+
const openai = new OpenAIProvider({
|
|
324
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
325
|
+
model: 'gpt-4o',
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Gemini
|
|
329
|
+
const gemini = new GeminiProvider({
|
|
330
|
+
apiKey: process.env.GOOGLE_API_KEY,
|
|
331
|
+
model: 'gemini-2.0-flash',
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// Ollama (local, no API key)
|
|
335
|
+
const ollama = new OllamaProvider({
|
|
336
|
+
model: 'llama3.1:8b',
|
|
337
|
+
baseUrl: 'http://localhost:11434',
|
|
294
338
|
});
|
|
295
339
|
```
|
|
296
340
|
|
|
@@ -1236,42 +1280,41 @@ const tracing = createOtelTracing({
|
|
|
1236
1280
|
const agent = new Agent({ provider, tracing });
|
|
1237
1281
|
```
|
|
1238
1282
|
|
|
1239
|
-
##
|
|
1283
|
+
## Requirements
|
|
1240
1284
|
|
|
1241
|
-
|
|
1285
|
+
- **Node.js** 18 or higher
|
|
1286
|
+
- **API Key** for your chosen provider (except Ollama)
|
|
1242
1287
|
|
|
1243
|
-
|
|
1244
|
-
# Basic agent usage
|
|
1245
|
-
npx tsx examples/basic-agent.ts
|
|
1288
|
+
## Peer Dependencies
|
|
1246
1289
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
# Streaming events
|
|
1251
|
-
npx tsx examples/streaming-events.ts
|
|
1252
|
-
```
|
|
1253
|
-
|
|
1254
|
-
## Testing
|
|
1255
|
-
|
|
1256
|
-
```bash
|
|
1257
|
-
# Run tests
|
|
1258
|
-
npm test
|
|
1259
|
-
|
|
1260
|
-
# Run with coverage
|
|
1261
|
-
npm run test:coverage
|
|
1262
|
-
|
|
1263
|
-
# Watch mode
|
|
1264
|
-
npm run test:watch
|
|
1265
|
-
```
|
|
1290
|
+
- `@anthropic-ai/sdk` (optional, for Claude)
|
|
1291
|
+
- `@modelcontextprotocol/sdk` (optional, for MCP)
|
|
1266
1292
|
|
|
1267
1293
|
## Design Philosophy
|
|
1268
1294
|
|
|
1269
|
-
1. **Minimal dependencies**: Only `@anthropic-ai/sdk` as optional peer
|
|
1295
|
+
1. **Minimal dependencies**: Only `@anthropic-ai/sdk` and `@modelcontextprotocol/sdk` as optional peer deps
|
|
1270
1296
|
2. **Type safety**: Full TypeScript support with strict mode
|
|
1271
1297
|
3. **Extensibility**: Easy to add new providers and tools
|
|
1272
1298
|
4. **Testability**: MockProvider for easy unit testing
|
|
1273
1299
|
5. **Real-time feedback**: Event system for CLI applications
|
|
1274
1300
|
|
|
1301
|
+
## Related Packages
|
|
1302
|
+
|
|
1303
|
+
- [@compilr-dev/cli](https://www.npmjs.com/package/@compilr-dev/cli) - AI-powered CLI assistant
|
|
1304
|
+
- [@compilr-dev/agents-coding](https://www.npmjs.com/package/@compilr-dev/agents-coding) - Coding-specific tools (git, runners, code search)
|
|
1305
|
+
|
|
1306
|
+
## Links
|
|
1307
|
+
|
|
1308
|
+
- [Website](https://compilr.dev)
|
|
1309
|
+
- [npm Package](https://www.npmjs.com/package/@compilr-dev/agents)
|
|
1310
|
+
- [Report Issues](https://github.com/compilr-dev/agents/issues)
|
|
1311
|
+
|
|
1275
1312
|
## License
|
|
1276
1313
|
|
|
1277
|
-
MIT
|
|
1314
|
+
MIT - See [LICENSE](LICENSE) for details.
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
<p align="center">
|
|
1319
|
+
<strong>Built with care by <a href="https://compilr.dev">compilr.dev</a></strong>
|
|
1320
|
+
</p>
|
package/dist/agent.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { ToolPermission, PermissionLevel, PermissionManagerOptions } from '
|
|
|
11
11
|
import type { ProjectMemoryOptions, ProjectMemory } from './memory/types.js';
|
|
12
12
|
import type { UsageTrackerOptions, UsageStats, BudgetStatus, TokenUsage } from './costs/types.js';
|
|
13
13
|
import type { HooksConfig } from './hooks/types.js';
|
|
14
|
+
import type { DelegationConfig } from './context/delegation-types.js';
|
|
14
15
|
import { PermissionManager } from './permissions/manager.js';
|
|
15
16
|
import { ContextManager } from './context/manager.js';
|
|
16
17
|
import { FileAccessTracker } from './context/file-tracker.js';
|
|
@@ -528,6 +529,28 @@ export interface AgentConfig {
|
|
|
528
529
|
* ```
|
|
529
530
|
*/
|
|
530
531
|
hooks?: HooksConfig;
|
|
532
|
+
/**
|
|
533
|
+
* Tool result delegation config. When set and enabled, large tool results
|
|
534
|
+
* are automatically summarized to conserve context tokens. Full results are
|
|
535
|
+
* stored in-memory for optional recall via `recall_full_result`.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* const agent = new Agent({
|
|
540
|
+
* provider,
|
|
541
|
+
* delegation: {
|
|
542
|
+
* enabled: true,
|
|
543
|
+
* delegationThreshold: 8000, // tokens above which to delegate
|
|
544
|
+
* strategy: 'auto', // try LLM, fall back to extractive
|
|
545
|
+
* toolOverrides: {
|
|
546
|
+
* bash: { threshold: 12000 },
|
|
547
|
+
* grep: { threshold: 4000 },
|
|
548
|
+
* },
|
|
549
|
+
* },
|
|
550
|
+
* });
|
|
551
|
+
* ```
|
|
552
|
+
*/
|
|
553
|
+
delegation?: DelegationConfig;
|
|
531
554
|
/**
|
|
532
555
|
* Enable file access tracking for context restoration hints.
|
|
533
556
|
*
|
package/dist/agent.js
CHANGED
|
@@ -9,6 +9,8 @@ import { DefaultToolRegistry } from './tools/registry.js';
|
|
|
9
9
|
import { ContextManager } from './context/manager.js';
|
|
10
10
|
import { FileAccessTracker } from './context/file-tracker.js';
|
|
11
11
|
import { createFileTrackingHook } from './context/file-tracking-hook.js';
|
|
12
|
+
import { ToolResultDelegator, DELEGATION_SYSTEM_PROMPT } from './context/tool-result-delegator.js';
|
|
13
|
+
import { createRecallResultTool } from './tools/builtin/recall-result.js';
|
|
12
14
|
import { AnchorManager } from './anchors/manager.js';
|
|
13
15
|
import { GuardrailManager } from './guardrails/manager.js';
|
|
14
16
|
import { MaxIterationsError, ToolLoopError, ProviderError } from './errors.js';
|
|
@@ -177,19 +179,50 @@ export class Agent {
|
|
|
177
179
|
}
|
|
178
180
|
});
|
|
179
181
|
}
|
|
182
|
+
// Build hooks config (may be extended by file tracking and delegation)
|
|
183
|
+
const hooksConfig = config.hooks ? { ...config.hooks } : {};
|
|
184
|
+
let needsHooksManager = config.hooks !== undefined;
|
|
185
|
+
// Tool result delegation — auto-summarize large results
|
|
186
|
+
if (config.delegation?.enabled) {
|
|
187
|
+
const delegator = new ToolResultDelegator({
|
|
188
|
+
provider: config.provider,
|
|
189
|
+
config: config.delegation,
|
|
190
|
+
onEvent: (event) => {
|
|
191
|
+
this.onEvent?.({
|
|
192
|
+
type: 'custom',
|
|
193
|
+
name: event.type,
|
|
194
|
+
data: event,
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
hooksConfig.afterTool = hooksConfig.afterTool ?? [];
|
|
199
|
+
hooksConfig.afterTool.push(delegator.createHook());
|
|
200
|
+
needsHooksManager = true;
|
|
201
|
+
// Register recall_full_result tool
|
|
202
|
+
this.registerTool(createRecallResultTool({
|
|
203
|
+
store: delegator.getStore(),
|
|
204
|
+
onEvent: (event) => {
|
|
205
|
+
this.onEvent?.({
|
|
206
|
+
type: 'custom',
|
|
207
|
+
name: event.type,
|
|
208
|
+
data: event,
|
|
209
|
+
});
|
|
210
|
+
},
|
|
211
|
+
}));
|
|
212
|
+
// Append delegation instructions to system prompt
|
|
213
|
+
this.systemPrompt += DELEGATION_SYSTEM_PROMPT;
|
|
214
|
+
}
|
|
180
215
|
// File tracking for context restoration hints
|
|
181
216
|
if (config.enableFileTracking && config.contextManager) {
|
|
182
217
|
this.fileTracker = new FileAccessTracker();
|
|
183
218
|
const trackingHook = createFileTrackingHook(this.fileTracker);
|
|
184
|
-
// Merge with existing hooks or create new hooks config
|
|
185
|
-
const hooksConfig = config.hooks ?? {};
|
|
186
219
|
hooksConfig.afterTool = hooksConfig.afterTool ?? [];
|
|
187
220
|
hooksConfig.afterTool.push(trackingHook);
|
|
188
|
-
|
|
221
|
+
needsHooksManager = true;
|
|
189
222
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this.hooksManager = new HooksManager({ hooks:
|
|
223
|
+
// Create hooks manager if any hooks were configured
|
|
224
|
+
if (needsHooksManager) {
|
|
225
|
+
this.hooksManager = new HooksManager({ hooks: hooksConfig });
|
|
193
226
|
}
|
|
194
227
|
// Retry configuration with defaults
|
|
195
228
|
this.retryConfig = {
|
|
@@ -2098,7 +2131,8 @@ export class Agent {
|
|
|
2098
2131
|
throw new MaxIterationsError(maxIterations);
|
|
2099
2132
|
}
|
|
2100
2133
|
}
|
|
2101
|
-
if (!aborted &&
|
|
2134
|
+
if (!aborted &&
|
|
2135
|
+
!(iterations >= maxIterations && this.iterationLimitBehavior === 'summarize')) {
|
|
2102
2136
|
emit({ type: 'done', response: finalResponse });
|
|
2103
2137
|
}
|
|
2104
2138
|
}
|
package/dist/anchors/manager.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import * as fs from 'node:fs';
|
|
5
5
|
import * as path from 'node:path';
|
|
6
6
|
import { generateId } from '../utils/index.js';
|
|
7
|
+
import { countTokens } from '../utils/tokenizer.js';
|
|
7
8
|
import { getDefaultAnchors, isBuiltinAnchor } from './builtin.js';
|
|
8
9
|
/**
|
|
9
10
|
* Default options for AnchorManager
|
|
@@ -14,10 +15,10 @@ const DEFAULT_OPTIONS = {
|
|
|
14
15
|
includeDefaults: true,
|
|
15
16
|
};
|
|
16
17
|
/**
|
|
17
|
-
* Default token estimator
|
|
18
|
+
* Default token estimator using tiktoken (cl100k_base encoding)
|
|
18
19
|
*/
|
|
19
20
|
function defaultEstimateTokens(content) {
|
|
20
|
-
return
|
|
21
|
+
return countTokens(content);
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* AnchorManager - Manages critical information that survives context compaction
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory store for delegated tool results.
|
|
3
|
+
*
|
|
4
|
+
* Stores full tool results that were replaced by summaries, allowing
|
|
5
|
+
* the agent to recall them via `recall_full_result`. Implements TTL
|
|
6
|
+
* expiration and LRU eviction.
|
|
7
|
+
*/
|
|
8
|
+
import type { StoredResult } from './delegation-types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Statistics about the delegation store.
|
|
11
|
+
*/
|
|
12
|
+
export interface DelegatedResultStoreStats {
|
|
13
|
+
/** Number of currently stored results */
|
|
14
|
+
size: number;
|
|
15
|
+
/** Maximum capacity (LRU limit) */
|
|
16
|
+
maxSize: number;
|
|
17
|
+
/** Total results stored since creation */
|
|
18
|
+
totalStored: number;
|
|
19
|
+
/** Total results evicted (TTL or LRU) */
|
|
20
|
+
totalEvicted: number;
|
|
21
|
+
/** Total results successfully recalled */
|
|
22
|
+
totalRecalled: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* In-memory store for delegated results with TTL expiration and LRU eviction.
|
|
26
|
+
*/
|
|
27
|
+
export declare class DelegatedResultStore {
|
|
28
|
+
private readonly results;
|
|
29
|
+
private readonly maxSize;
|
|
30
|
+
private readonly defaultTTL;
|
|
31
|
+
private counter;
|
|
32
|
+
private totalStored;
|
|
33
|
+
private totalEvicted;
|
|
34
|
+
private totalRecalled;
|
|
35
|
+
constructor(options?: {
|
|
36
|
+
maxSize?: number;
|
|
37
|
+
defaultTTL?: number;
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Generate a unique delegation ID.
|
|
41
|
+
*/
|
|
42
|
+
generateId(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Store a delegated result. Evicts oldest entries if at capacity.
|
|
45
|
+
*/
|
|
46
|
+
add(result: StoredResult): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get a stored result by ID. Returns undefined if not found or expired.
|
|
49
|
+
*/
|
|
50
|
+
get(id: string): StoredResult | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Remove all expired entries.
|
|
53
|
+
*/
|
|
54
|
+
cleanup(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear all stored results.
|
|
57
|
+
*/
|
|
58
|
+
clear(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get the default TTL for this store.
|
|
61
|
+
*/
|
|
62
|
+
getDefaultTTL(): number;
|
|
63
|
+
/**
|
|
64
|
+
* Get store statistics.
|
|
65
|
+
*/
|
|
66
|
+
getStats(): DelegatedResultStoreStats;
|
|
67
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory store for delegated tool results.
|
|
3
|
+
*
|
|
4
|
+
* Stores full tool results that were replaced by summaries, allowing
|
|
5
|
+
* the agent to recall them via `recall_full_result`. Implements TTL
|
|
6
|
+
* expiration and LRU eviction.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* In-memory store for delegated results with TTL expiration and LRU eviction.
|
|
10
|
+
*/
|
|
11
|
+
export class DelegatedResultStore {
|
|
12
|
+
results = new Map();
|
|
13
|
+
maxSize;
|
|
14
|
+
defaultTTL;
|
|
15
|
+
counter = 0;
|
|
16
|
+
totalStored = 0;
|
|
17
|
+
totalEvicted = 0;
|
|
18
|
+
totalRecalled = 0;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.maxSize = options?.maxSize ?? 50;
|
|
21
|
+
this.defaultTTL = options?.defaultTTL ?? 600_000;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generate a unique delegation ID.
|
|
25
|
+
*/
|
|
26
|
+
generateId() {
|
|
27
|
+
return `dr_${String(Date.now())}_${String(this.counter++)}`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Store a delegated result. Evicts oldest entries if at capacity.
|
|
31
|
+
*/
|
|
32
|
+
add(result) {
|
|
33
|
+
// Evict expired entries first
|
|
34
|
+
this.cleanup();
|
|
35
|
+
// LRU eviction: remove oldest entries if at capacity
|
|
36
|
+
while (this.results.size >= this.maxSize) {
|
|
37
|
+
const oldestKey = this.results.keys().next().value;
|
|
38
|
+
this.results.delete(oldestKey);
|
|
39
|
+
this.totalEvicted++;
|
|
40
|
+
}
|
|
41
|
+
this.results.set(result.id, result);
|
|
42
|
+
this.totalStored++;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a stored result by ID. Returns undefined if not found or expired.
|
|
46
|
+
*/
|
|
47
|
+
get(id) {
|
|
48
|
+
const result = this.results.get(id);
|
|
49
|
+
if (!result)
|
|
50
|
+
return undefined;
|
|
51
|
+
// Check TTL
|
|
52
|
+
if (Date.now() > result.expiresAt) {
|
|
53
|
+
this.results.delete(id);
|
|
54
|
+
this.totalEvicted++;
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
// Move to end for LRU (delete + re-insert)
|
|
58
|
+
this.results.delete(id);
|
|
59
|
+
this.results.set(id, result);
|
|
60
|
+
this.totalRecalled++;
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Remove all expired entries.
|
|
65
|
+
*/
|
|
66
|
+
cleanup() {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
for (const [id, result] of this.results) {
|
|
69
|
+
if (now > result.expiresAt) {
|
|
70
|
+
this.results.delete(id);
|
|
71
|
+
this.totalEvicted++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Clear all stored results.
|
|
77
|
+
*/
|
|
78
|
+
clear() {
|
|
79
|
+
this.results.clear();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get the default TTL for this store.
|
|
83
|
+
*/
|
|
84
|
+
getDefaultTTL() {
|
|
85
|
+
return this.defaultTTL;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get store statistics.
|
|
89
|
+
*/
|
|
90
|
+
getStats() {
|
|
91
|
+
return {
|
|
92
|
+
size: this.results.size,
|
|
93
|
+
maxSize: this.maxSize,
|
|
94
|
+
totalStored: this.totalStored,
|
|
95
|
+
totalEvicted: this.totalEvicted,
|
|
96
|
+
totalRecalled: this.totalRecalled,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for tool result auto-delegation.
|
|
3
|
+
*
|
|
4
|
+
* When large tool results exceed a token threshold, they are automatically
|
|
5
|
+
* summarized and stored for optional recall. This conserves context tokens
|
|
6
|
+
* while preserving access to the full data.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for tool result delegation.
|
|
10
|
+
* Controls when and how large tool results are summarized.
|
|
11
|
+
*/
|
|
12
|
+
export interface DelegationConfig {
|
|
13
|
+
/** Whether delegation is enabled. Default: false (opt-in) */
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
/** Token count above which results are delegated. Default: 8000 */
|
|
16
|
+
delegationThreshold: number;
|
|
17
|
+
/** Maximum tokens for the summary. Default: 800 */
|
|
18
|
+
summaryMaxTokens: number;
|
|
19
|
+
/** Milliseconds before stored results expire. Default: 600_000 (10 min) */
|
|
20
|
+
resultTTL: number;
|
|
21
|
+
/** Maximum number of stored results (LRU eviction). Default: 50 */
|
|
22
|
+
maxStoredResults: number;
|
|
23
|
+
/** Summarization strategy. Default: 'auto' */
|
|
24
|
+
strategy: 'llm' | 'extractive' | 'auto';
|
|
25
|
+
/** Per-tool threshold/strategy overrides */
|
|
26
|
+
toolOverrides?: Record<string, {
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
threshold?: number;
|
|
29
|
+
strategy?: 'llm' | 'extractive' | 'auto';
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A stored full result that was replaced by a summary.
|
|
34
|
+
*/
|
|
35
|
+
export interface StoredResult {
|
|
36
|
+
/** Unique delegation ID, e.g., 'dr_1707900000_0' */
|
|
37
|
+
id: string;
|
|
38
|
+
/** Name of the tool that produced the result */
|
|
39
|
+
toolName: string;
|
|
40
|
+
/** Input parameters passed to the tool */
|
|
41
|
+
toolInput: Record<string, unknown>;
|
|
42
|
+
/** The full serialized result content */
|
|
43
|
+
fullContent: string;
|
|
44
|
+
/** Token count of the full content */
|
|
45
|
+
fullTokens: number;
|
|
46
|
+
/** The generated summary */
|
|
47
|
+
summary: string;
|
|
48
|
+
/** Token count of the summary */
|
|
49
|
+
summaryTokens: number;
|
|
50
|
+
/** Timestamp when stored */
|
|
51
|
+
storedAt: number;
|
|
52
|
+
/** Timestamp when this result expires */
|
|
53
|
+
expiresAt: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Events emitted during the delegation lifecycle.
|
|
57
|
+
*/
|
|
58
|
+
export type DelegationEvent = {
|
|
59
|
+
type: 'delegation:started';
|
|
60
|
+
toolName: string;
|
|
61
|
+
originalTokens: number;
|
|
62
|
+
delegationId: string;
|
|
63
|
+
} | {
|
|
64
|
+
type: 'delegation:completed';
|
|
65
|
+
toolName: string;
|
|
66
|
+
originalTokens: number;
|
|
67
|
+
summaryTokens: number;
|
|
68
|
+
delegationId: string;
|
|
69
|
+
strategy: 'llm' | 'extractive';
|
|
70
|
+
} | {
|
|
71
|
+
type: 'delegation:failed';
|
|
72
|
+
toolName: string;
|
|
73
|
+
error: string;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'delegation:recall';
|
|
76
|
+
delegationId: string;
|
|
77
|
+
found: boolean;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Default delegation configuration values.
|
|
81
|
+
*/
|
|
82
|
+
export declare const DEFAULT_DELEGATION_CONFIG: DelegationConfig;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for tool result auto-delegation.
|
|
3
|
+
*
|
|
4
|
+
* When large tool results exceed a token threshold, they are automatically
|
|
5
|
+
* summarized and stored for optional recall. This conserves context tokens
|
|
6
|
+
* while preserving access to the full data.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Default delegation configuration values.
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_DELEGATION_CONFIG = {
|
|
12
|
+
enabled: false,
|
|
13
|
+
delegationThreshold: 8000,
|
|
14
|
+
summaryMaxTokens: 800,
|
|
15
|
+
resultTTL: 600_000,
|
|
16
|
+
maxStoredResults: 50,
|
|
17
|
+
strategy: 'auto',
|
|
18
|
+
};
|
package/dist/context/index.d.ts
CHANGED
|
@@ -14,3 +14,9 @@ export { FileAccessTracker } from './file-tracker.js';
|
|
|
14
14
|
export type { FileAccessType, FileAccess, FileAccessTrackerOptions, FormatHintsOptions, FileAccessStats, } from './file-tracker.js';
|
|
15
15
|
export { createFileTrackingHook, TRACKED_TOOLS } from './file-tracking-hook.js';
|
|
16
16
|
export type { ContextCategory, BudgetAllocation, CategoryBudgetInfo, PreflightResult, VerbosityLevel, VerbosityConfig, ContextConfig, FilteringConfig, CompactionConfig, SummarizationConfig, CompactionResult, SummarizationResult, FilteringResult, ContextEvent, ContextEventHandler, ContextStats, CategorizedMessages, SmartCompactOptions, SmartCompactionResult, } from './types.js';
|
|
17
|
+
export { DelegatedResultStore } from './delegated-result-store.js';
|
|
18
|
+
export type { DelegatedResultStoreStats } from './delegated-result-store.js';
|
|
19
|
+
export { ToolResultDelegator, DELEGATION_SYSTEM_PROMPT } from './tool-result-delegator.js';
|
|
20
|
+
export type { ToolResultDelegatorOptions } from './tool-result-delegator.js';
|
|
21
|
+
export { DEFAULT_DELEGATION_CONFIG } from './delegation-types.js';
|
|
22
|
+
export type { DelegationConfig, StoredResult, DelegationEvent } from './delegation-types.js';
|
package/dist/context/index.js
CHANGED
|
@@ -11,3 +11,7 @@
|
|
|
11
11
|
export { ContextManager, DEFAULT_CONTEXT_CONFIG } from './manager.js';
|
|
12
12
|
export { FileAccessTracker } from './file-tracker.js';
|
|
13
13
|
export { createFileTrackingHook, TRACKED_TOOLS } from './file-tracking-hook.js';
|
|
14
|
+
// Tool Result Delegation
|
|
15
|
+
export { DelegatedResultStore } from './delegated-result-store.js';
|
|
16
|
+
export { ToolResultDelegator, DELEGATION_SYSTEM_PROMPT } from './tool-result-delegator.js';
|
|
17
|
+
export { DEFAULT_DELEGATION_CONFIG } from './delegation-types.js';
|