@compilr-dev/agents 0.3.11 → 0.3.13

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 (42) hide show
  1. package/dist/agent.d.ts +42 -1
  2. package/dist/agent.js +116 -17
  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/file-tracker.d.ts +59 -1
  9. package/dist/context/file-tracker.js +96 -1
  10. package/dist/context/file-tracking-hook.js +9 -4
  11. package/dist/context/index.d.ts +7 -1
  12. package/dist/context/index.js +4 -0
  13. package/dist/context/manager.js +12 -32
  14. package/dist/context/tool-result-delegator.d.ts +63 -0
  15. package/dist/context/tool-result-delegator.js +314 -0
  16. package/dist/index.d.ts +5 -5
  17. package/dist/index.js +9 -3
  18. package/dist/memory/loader.js +2 -1
  19. package/dist/memory/types.d.ts +1 -1
  20. package/dist/providers/claude.d.ts +1 -5
  21. package/dist/providers/claude.js +6 -29
  22. package/dist/providers/gemini-native.d.ts +1 -1
  23. package/dist/providers/gemini-native.js +10 -24
  24. package/dist/providers/mock.d.ts +1 -1
  25. package/dist/providers/mock.js +3 -24
  26. package/dist/providers/openai-compatible.d.ts +1 -5
  27. package/dist/providers/openai-compatible.js +14 -28
  28. package/dist/providers/types.d.ts +5 -0
  29. package/dist/rate-limit/provider-wrapper.d.ts +1 -1
  30. package/dist/rate-limit/provider-wrapper.js +3 -27
  31. package/dist/tools/builtin/index.d.ts +2 -0
  32. package/dist/tools/builtin/index.js +2 -0
  33. package/dist/tools/builtin/recall-result.d.ts +29 -0
  34. package/dist/tools/builtin/recall-result.js +48 -0
  35. package/dist/tools/builtin/task.js +1 -0
  36. package/dist/tools/index.d.ts +2 -2
  37. package/dist/tools/index.js +2 -0
  38. package/dist/utils/index.d.ts +1 -0
  39. package/dist/utils/index.js +2 -0
  40. package/dist/utils/tokenizer.d.ts +19 -0
  41. package/dist/utils/tokenizer.js +93 -0
  42. package/package.json +3 -2
@@ -0,0 +1,93 @@
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
+ * Maximum text length for tiktoken encoding.
18
+ * Beyond this, fall back to chars/4 heuristic to avoid pathological BPE performance.
19
+ */
20
+ const MAX_TIKTOKEN_LENGTH = 10000;
21
+ /**
22
+ * Minimum length at which we check for low-entropy (repetitive) content.
23
+ * Repetitive single-character strings like 'a'.repeat(5000) cause O(n²+)
24
+ * performance in js-tiktoken's BPE merge loop.
25
+ */
26
+ const ENTROPY_CHECK_THRESHOLD = 2000;
27
+ /**
28
+ * Check if a string is low-entropy (highly repetitive), which causes
29
+ * pathological BPE performance in js-tiktoken.
30
+ *
31
+ * Samples characters from the string and checks unique character ratio.
32
+ * A ratio below 0.01 (e.g., 'aaaa...') triggers the heuristic fallback.
33
+ */
34
+ function isLowEntropy(text) {
35
+ // Sample up to 200 characters evenly across the string
36
+ const sampleSize = Math.min(200, text.length);
37
+ const step = Math.max(1, Math.floor(text.length / sampleSize));
38
+ const seen = new Set();
39
+ for (let i = 0; i < text.length && seen.size < 20; i += step) {
40
+ seen.add(text[i]);
41
+ }
42
+ // If unique chars / length ratio is very low, it's repetitive
43
+ return seen.size / Math.min(sampleSize, text.length) < 0.02;
44
+ }
45
+ /**
46
+ * Count tokens in a text string using tiktoken.
47
+ * Falls back to chars/4 heuristic for very large or pathologically repetitive strings.
48
+ */
49
+ export function countTokens(text) {
50
+ if (!text)
51
+ return 0;
52
+ if (text.length > MAX_TIKTOKEN_LENGTH) {
53
+ return Math.ceil(text.length / 4);
54
+ }
55
+ // Detect low-entropy strings that cause O(n²+) BPE performance
56
+ if (text.length >= ENTROPY_CHECK_THRESHOLD && isLowEntropy(text)) {
57
+ return Math.ceil(text.length / 4);
58
+ }
59
+ return getEncoder().encode(text).length;
60
+ }
61
+ /**
62
+ * Count tokens across an array of messages
63
+ *
64
+ * Extracts all text content from messages (text blocks, tool inputs/results,
65
+ * thinking blocks) and counts tokens using tiktoken.
66
+ */
67
+ export function countMessageTokens(messages) {
68
+ const parts = [];
69
+ for (const msg of messages) {
70
+ if (typeof msg.content === 'string') {
71
+ parts.push(msg.content);
72
+ }
73
+ else {
74
+ for (const block of msg.content) {
75
+ switch (block.type) {
76
+ case 'text':
77
+ parts.push(block.text);
78
+ break;
79
+ case 'tool_use':
80
+ parts.push(JSON.stringify(block.input));
81
+ break;
82
+ case 'tool_result':
83
+ parts.push(typeof block.content === 'string' ? block.content : JSON.stringify(block.content));
84
+ break;
85
+ case 'thinking':
86
+ parts.push(block.thinking);
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ return countTokens(parts.join(' '));
93
+ }
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.13",
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"