@compilr-dev/agents 0.3.11 → 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.
Files changed (37) hide show
  1. package/dist/agent.d.ts +23 -0
  2. package/dist/agent.js +41 -7
  3. package/dist/anchors/manager.js +3 -2
  4. package/dist/context/delegated-result-store.d.ts +67 -0
  5. package/dist/context/delegated-result-store.js +99 -0
  6. package/dist/context/delegation-types.d.ts +82 -0
  7. package/dist/context/delegation-types.js +18 -0
  8. package/dist/context/index.d.ts +6 -0
  9. package/dist/context/index.js +4 -0
  10. package/dist/context/manager.js +12 -32
  11. package/dist/context/tool-result-delegator.d.ts +63 -0
  12. package/dist/context/tool-result-delegator.js +305 -0
  13. package/dist/index.d.ts +5 -5
  14. package/dist/index.js +9 -3
  15. package/dist/memory/loader.js +2 -1
  16. package/dist/memory/types.d.ts +1 -1
  17. package/dist/providers/claude.d.ts +1 -5
  18. package/dist/providers/claude.js +3 -28
  19. package/dist/providers/gemini-native.d.ts +1 -1
  20. package/dist/providers/gemini-native.js +3 -24
  21. package/dist/providers/mock.d.ts +1 -1
  22. package/dist/providers/mock.js +3 -24
  23. package/dist/providers/openai-compatible.d.ts +1 -5
  24. package/dist/providers/openai-compatible.js +3 -28
  25. package/dist/rate-limit/provider-wrapper.d.ts +1 -1
  26. package/dist/rate-limit/provider-wrapper.js +3 -27
  27. package/dist/tools/builtin/index.d.ts +2 -0
  28. package/dist/tools/builtin/index.js +2 -0
  29. package/dist/tools/builtin/recall-result.d.ts +29 -0
  30. package/dist/tools/builtin/recall-result.js +48 -0
  31. package/dist/tools/index.d.ts +2 -2
  32. package/dist/tools/index.js +2 -0
  33. package/dist/utils/index.d.ts +1 -0
  34. package/dist/utils/index.js +2 -0
  35. package/dist/utils/tokenizer.d.ts +18 -0
  36. package/dist/utils/tokenizer.js +56 -0
  37. package/package.json +3 -2
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { createRateLimiter } from './limiter.js';
7
7
  import { withRetry } from './retry.js';
8
+ import { countMessageTokens } from '../utils/tokenizer.js';
8
9
  /**
9
10
  * Wrapper that adds rate limiting and retry to any LLMProvider
10
11
  *
@@ -105,35 +106,10 @@ export class RateLimitedProvider {
105
106
  return withRetry(() => countTokensFn(messages), this.retryConfig);
106
107
  }
107
108
  /**
108
- * Estimate tokens from messages (rough approximation)
109
+ * Estimate tokens from messages using tiktoken
109
110
  */
110
111
  estimateTokens(messages) {
111
- let charCount = 0;
112
- for (const msg of messages) {
113
- if (typeof msg.content === 'string') {
114
- charCount += msg.content.length;
115
- }
116
- else {
117
- for (const block of msg.content) {
118
- switch (block.type) {
119
- case 'text':
120
- charCount += block.text.length;
121
- break;
122
- case 'tool_use':
123
- charCount += JSON.stringify(block.input).length;
124
- break;
125
- case 'tool_result':
126
- charCount += block.content.length;
127
- break;
128
- case 'thinking':
129
- charCount += block.thinking.length;
130
- break;
131
- }
132
- }
133
- }
134
- }
135
- // Rough estimate: 4 characters per token
136
- return Math.ceil(charCount / 4);
112
+ return countMessageTokens(messages);
137
113
  }
138
114
  }
139
115
  /**
@@ -33,6 +33,8 @@ export { askUserTool, createAskUserTool } from './ask-user.js';
33
33
  export type { AskUserInput, AskUserResult, AskUserQuestion, AskUserOption, AskUserToolOptions, } from './ask-user.js';
34
34
  export { askUserSimpleTool, createAskUserSimpleTool } from './ask-user-simple.js';
35
35
  export type { AskUserSimpleInput, AskUserSimpleResult, AskUserSimpleToolOptions, } from './ask-user-simple.js';
36
+ export { createRecallResultTool } from './recall-result.js';
37
+ export type { RecallResultInput, RecallResultToolOptions } from './recall-result.js';
36
38
  export { backlogReadTool, backlogWriteTool, createBacklogTools } from './backlog.js';
37
39
  export type { BacklogItem, BacklogStatus, BacklogItemType, BacklogPriority, BacklogReadInput, BacklogReadResult, BacklogWriteInput, BacklogWriteResult, BacklogToolOptions, } from './backlog.js';
38
40
  export declare const builtinTools: {
@@ -32,6 +32,8 @@ export { suggestTool, createSuggestTool } from './suggest.js';
32
32
  // Ask user tools (user interaction)
33
33
  export { askUserTool, createAskUserTool } from './ask-user.js';
34
34
  export { askUserSimpleTool, createAskUserSimpleTool } from './ask-user-simple.js';
35
+ // Recall result tool (tool result delegation)
36
+ export { createRecallResultTool } from './recall-result.js';
35
37
  // Backlog tools (file-based project backlog)
36
38
  export { backlogReadTool, backlogWriteTool, createBacklogTools } from './backlog.js';
37
39
  /**
@@ -0,0 +1,29 @@
1
+ /**
2
+ * recall_full_result tool
3
+ *
4
+ * Retrieves the full output of a previously delegated tool result.
5
+ * Use when a summary is insufficient and you need the complete data.
6
+ */
7
+ import type { Tool } from '../types.js';
8
+ import type { DelegatedResultStore } from '../../context/delegated-result-store.js';
9
+ import type { DelegationEvent } from '../../context/delegation-types.js';
10
+ /**
11
+ * Input for the recall_full_result tool.
12
+ */
13
+ export interface RecallResultInput {
14
+ /** Delegation ID from a previously delegated result (e.g., "dr_1707900000_0") */
15
+ id: string;
16
+ }
17
+ /**
18
+ * Options for creating the recall_full_result tool.
19
+ */
20
+ export interface RecallResultToolOptions {
21
+ /** The delegation store to retrieve results from */
22
+ store: DelegatedResultStore;
23
+ /** Optional event callback for recall events */
24
+ onEvent?: (event: DelegationEvent) => void;
25
+ }
26
+ /**
27
+ * Create a recall_full_result tool that retrieves delegated results from the store.
28
+ */
29
+ export declare function createRecallResultTool(options: RecallResultToolOptions): Tool<RecallResultInput>;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * recall_full_result tool
3
+ *
4
+ * Retrieves the full output of a previously delegated tool result.
5
+ * Use when a summary is insufficient and you need the complete data.
6
+ */
7
+ import { defineTool, createSuccessResult, createErrorResult } from '../define.js';
8
+ /**
9
+ * Create a recall_full_result tool that retrieves delegated results from the store.
10
+ */
11
+ export function createRecallResultTool(options) {
12
+ const { store, onEvent } = options;
13
+ return defineTool({
14
+ name: 'recall_full_result',
15
+ description: 'Retrieve the full output of a previously delegated tool result. ' +
16
+ 'Use when a summary is insufficient and you need the complete data. ' +
17
+ 'Results expire after 10 minutes.',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: {
21
+ id: {
22
+ type: 'string',
23
+ description: 'Delegation ID (e.g., "dr_1707900000_0")',
24
+ },
25
+ },
26
+ required: ['id'],
27
+ },
28
+ execute: (input) => {
29
+ const stored = store.get(input.id);
30
+ onEvent?.({
31
+ type: 'delegation:recall',
32
+ delegationId: input.id,
33
+ found: stored !== undefined,
34
+ });
35
+ if (!stored) {
36
+ return Promise.resolve(createErrorResult('Delegation ID not found or expired. Re-run the original tool to get the result.'));
37
+ }
38
+ return Promise.resolve(createSuccessResult({
39
+ delegationId: stored.id,
40
+ toolName: stored.toolName,
41
+ fullContent: stored.fullContent,
42
+ fullTokens: stored.fullTokens,
43
+ }));
44
+ },
45
+ parallel: true,
46
+ silent: true,
47
+ });
48
+ }
@@ -6,5 +6,5 @@ export { defineTool, createSuccessResult, createErrorResult, wrapToolExecute } f
6
6
  export type { DefineToolOptions } from './define.js';
7
7
  export { DefaultToolRegistry, createToolRegistry } from './registry.js';
8
8
  export type { ToolRegistryOptions } from './registry.js';
9
- export { readFileTool, createReadFileTool, writeFileTool, createWriteFileTool, bashTool, createBashTool, execStream, detectFifoUsage, bashOutputTool, createBashOutputTool, killShellTool, createKillShellTool, ShellManager, getDefaultShellManager, setDefaultShellManager, grepTool, createGrepTool, globTool, createGlobTool, editTool, createEditTool, todoWriteTool, todoReadTool, createTodoTools, TodoStore, resetDefaultTodoStore, getDefaultTodoStore, createIsolatedTodoStore, cleanupTodoContextMessages, getTodoContextStats, webFetchTool, createWebFetchTool, createTaskTool, defaultAgentTypes, suggestTool, createSuggestTool, builtinTools, allBuiltinTools, TOOL_NAMES, TOOL_SETS, } from './builtin/index.js';
10
- export type { ReadFileInput, WriteFileInput, BashInput, BashResult, FifoDetectionResult, BashOutputInput, BashOutputResult, KillShellInput, KillShellResult, ShellStatus, BackgroundShell, ShellOutput, ShellManagerOptions, GrepInput, GlobInput, EditInput, TodoWriteInput, TodoReadInput, TodoItem, TodoStatus, TodoContextCleanupOptions, WebFetchInput, WebFetchResult, WebFetchOptions, TaskInput, TaskResult, AgentTypeConfig, TaskToolOptions, ContextMode, ThoroughnessLevel, SubAgentEventInfo, SuggestInput, SuggestToolOptions, } from './builtin/index.js';
9
+ export { readFileTool, createReadFileTool, writeFileTool, createWriteFileTool, bashTool, createBashTool, execStream, detectFifoUsage, bashOutputTool, createBashOutputTool, killShellTool, createKillShellTool, ShellManager, getDefaultShellManager, setDefaultShellManager, grepTool, createGrepTool, globTool, createGlobTool, editTool, createEditTool, todoWriteTool, todoReadTool, createTodoTools, TodoStore, resetDefaultTodoStore, getDefaultTodoStore, createIsolatedTodoStore, cleanupTodoContextMessages, getTodoContextStats, webFetchTool, createWebFetchTool, createTaskTool, defaultAgentTypes, suggestTool, createSuggestTool, createRecallResultTool, builtinTools, allBuiltinTools, TOOL_NAMES, TOOL_SETS, } from './builtin/index.js';
10
+ export type { ReadFileInput, WriteFileInput, BashInput, BashResult, FifoDetectionResult, BashOutputInput, BashOutputResult, KillShellInput, KillShellResult, ShellStatus, BackgroundShell, ShellOutput, ShellManagerOptions, GrepInput, GlobInput, EditInput, TodoWriteInput, TodoReadInput, TodoItem, TodoStatus, TodoContextCleanupOptions, WebFetchInput, WebFetchResult, WebFetchOptions, TaskInput, TaskResult, AgentTypeConfig, TaskToolOptions, ContextMode, ThoroughnessLevel, SubAgentEventInfo, SuggestInput, SuggestToolOptions, RecallResultInput, RecallResultToolOptions, } from './builtin/index.js';
@@ -35,6 +35,8 @@ webFetchTool, createWebFetchTool,
35
35
  createTaskTool, defaultAgentTypes,
36
36
  // Suggest (next action suggestions)
37
37
  suggestTool, createSuggestTool,
38
+ // Recall result (delegation)
39
+ createRecallResultTool,
38
40
  // Collections
39
41
  builtinTools, allBuiltinTools,
40
42
  // Tool names - single source of truth
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Utility functions for @compilr-dev/agents
3
3
  */
4
+ export { countTokens, countMessageTokens } from './tokenizer.js';
4
5
  /**
5
6
  * Generate a unique ID for tool uses
6
7
  */
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Utility functions for @compilr-dev/agents
3
3
  */
4
+ // Token counting
5
+ export { countTokens, countMessageTokens } from './tokenizer.js';
4
6
  /**
5
7
  * Generate a unique ID for tool uses
6
8
  */
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Token counting utility using tiktoken (cl100k_base encoding)
3
+ *
4
+ * Replaces the rough `Math.ceil(charCount / 4)` heuristic with actual
5
+ * BPE tokenization for accurate context window management.
6
+ */
7
+ import type { Message } from '../providers/types.js';
8
+ /**
9
+ * Count tokens in a text string using tiktoken
10
+ */
11
+ export declare function countTokens(text: string): number;
12
+ /**
13
+ * Count tokens across an array of messages
14
+ *
15
+ * Extracts all text content from messages (text blocks, tool inputs/results,
16
+ * thinking blocks) and counts tokens using tiktoken.
17
+ */
18
+ export declare function countMessageTokens(messages: Message[]): number;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Token counting utility using tiktoken (cl100k_base encoding)
3
+ *
4
+ * Replaces the rough `Math.ceil(charCount / 4)` heuristic with actual
5
+ * BPE tokenization for accurate context window management.
6
+ */
7
+ import { getEncoding } from 'js-tiktoken';
8
+ // Lazy-initialized encoder (loaded on first use)
9
+ let encoder = null;
10
+ function getEncoder() {
11
+ if (!encoder) {
12
+ encoder = getEncoding('cl100k_base');
13
+ }
14
+ return encoder;
15
+ }
16
+ /**
17
+ * Count tokens in a text string using tiktoken
18
+ */
19
+ export function countTokens(text) {
20
+ if (!text)
21
+ return 0;
22
+ return getEncoder().encode(text).length;
23
+ }
24
+ /**
25
+ * Count tokens across an array of messages
26
+ *
27
+ * Extracts all text content from messages (text blocks, tool inputs/results,
28
+ * thinking blocks) and counts tokens using tiktoken.
29
+ */
30
+ export function countMessageTokens(messages) {
31
+ const parts = [];
32
+ for (const msg of messages) {
33
+ if (typeof msg.content === 'string') {
34
+ parts.push(msg.content);
35
+ }
36
+ else {
37
+ for (const block of msg.content) {
38
+ switch (block.type) {
39
+ case 'text':
40
+ parts.push(block.text);
41
+ break;
42
+ case 'tool_use':
43
+ parts.push(JSON.stringify(block.input));
44
+ break;
45
+ case 'tool_result':
46
+ parts.push(typeof block.content === 'string' ? block.content : JSON.stringify(block.content));
47
+ break;
48
+ case 'thinking':
49
+ parts.push(block.thinking);
50
+ break;
51
+ }
52
+ }
53
+ }
54
+ }
55
+ return countTokens(parts.join(' '));
56
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compilr-dev/agents",
3
- "version": "0.3.11",
3
+ "version": "0.3.12",
4
4
  "description": "Lightweight multi-LLM agent library for building CLI AI assistants",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -77,7 +77,8 @@
77
77
  "vitest": "^4.0.18"
78
78
  },
79
79
  "dependencies": {
80
- "@google/genai": "^1.38.0"
80
+ "@google/genai": "^1.38.0",
81
+ "js-tiktoken": "^1.0.21"
81
82
  },
82
83
  "overrides": {
83
84
  "hono": "^4.11.7"