toolgz 0.2.6 → 0.2.8
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 +42 -8
- package/dist/index.js +13 -0
- package/dist/recommend.js +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,6 +346,31 @@ style in 0.2.0.
|
|
|
346
346
|
|
|
347
347
|
---
|
|
348
348
|
|
|
349
|
+
## Runnable examples
|
|
350
|
+
|
|
351
|
+
Five files in [`examples/`](examples), all offline — no API key, no cost. Every one is
|
|
352
|
+
**executed by the test suite**, so an example that stops working is a failing test rather
|
|
353
|
+
than a bug report from you.
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
npx tsx examples/01-minimal.ts
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
| File | Shows |
|
|
360
|
+
|---|---|
|
|
361
|
+
| [`01-minimal.ts`](examples/01-minimal.ts) | the smallest useful thing: `recommendLevel` → `compress` → `resolve` |
|
|
362
|
+
| [`02-agent-loop.ts`](examples/02-agent-loop.ts) | the full loop against a scripted model, covering all three `resolve()` outcomes including a recovery |
|
|
363
|
+
| [`03-mcp-servers.ts`](examples/03-mcp-servers.ts) | 149 real tools from 14 MCP servers, all four levels, and the name-collision hazard |
|
|
364
|
+
| [`04-providers.ts`](examples/04-providers.ts) | the four provider envelopes side by side, plus the Gemini schema repairs |
|
|
365
|
+
| [`05-per-model.ts`](examples/05-per-model.ts) | `model`/`objective` selection and reading `stats` to see what was actually used |
|
|
366
|
+
|
|
367
|
+
Two things `04-providers.ts` demonstrates rather than describes, because both have bitten
|
|
368
|
+
people: `/v1/responses` needs the **flat** tool shape when you set reasoning effort, and
|
|
369
|
+
Gemini returns **one** wrapper object containing all declarations, so you count
|
|
370
|
+
`tools[0].functionDeclarations.length`.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
349
374
|
## Using it: the full guide
|
|
350
375
|
|
|
351
376
|
Everything below was a separate `docs/GUIDE.md`. It is inline now, deliberately: the
|
|
@@ -767,8 +792,7 @@ console.log(c.stats);
|
|
|
767
792
|
// originalChars: 61461, compressedChars: 2211, savedPct: 96.4 }
|
|
768
793
|
```
|
|
769
794
|
|
|
770
|
-
`savedPct` is a character
|
|
771
|
-
sanity check, not for billing.
|
|
795
|
+
`savedPct` is a character saving, a few points optimistic against tokens. `originalChars` and `compressedChars` give the raw character counts.
|
|
772
796
|
|
|
773
797
|
**I need the real token numbers.**
|
|
774
798
|
Count them with the provider's own endpoint. Never use `tiktoken` for Claude —
|
|
@@ -842,11 +866,21 @@ Returns:
|
|
|
842
866
|
| `codeFor(name)` | `→ string` | real name → level-3 code; throws below level 3 |
|
|
843
867
|
| `stats` | `CompressStats` | `level`, `mapStyle`, `requestedMapStyle`, `fallbackReason`, `toolCount`, `wireToolCount`, `originalChars`, `compressedChars`, `savedPct` |
|
|
844
868
|
|
|
845
|
-
> **`savedPct`
|
|
846
|
-
>
|
|
847
|
-
>
|
|
848
|
-
>
|
|
849
|
-
>
|
|
869
|
+
> **`savedPct` is a character saving, and runs a few points optimistic against tokens.**
|
|
870
|
+
> On the real 149-tool corpus it reports 46.8% at level 1 where `count_tokens` measures
|
|
871
|
+
> 39.2%, and 96.6% at level 3 against 95.6%.
|
|
872
|
+
>
|
|
873
|
+
> We tried making it a token estimate in 0.2.7 and reverted it in 0.2.8. Providers charge a
|
|
874
|
+
> fixed framing cost per tool definition that character counting cannot see: at 149 tools
|
|
875
|
+
> it amortises away, at 2 tools it dominates, and the calibrated estimate was off by 44% on
|
|
876
|
+
> a small level-1 block while being within 1% at scale. The plain character ratio is the
|
|
877
|
+
> smaller and more predictable error.
|
|
878
|
+
>
|
|
879
|
+
> Use it as a local signal. For anything you publish, measure with your provider's token
|
|
880
|
+
> counter. `originalChars` and `compressedChars` are on `stats` for the raw counts.
|
|
881
|
+
>
|
|
882
|
+
> A negative value is possible and correct: on a very small tool set, level 1's signature
|
|
883
|
+
> line can exceed the per-property descriptions it strips.
|
|
850
884
|
| `encodeCallForTest(name, args)` | `→ {name, args}` | build the raw call a model would emit; test aid |
|
|
851
885
|
|
|
852
886
|
### `recommendLevel(tools, namespaceOf?) → Recommendation`
|
|
@@ -955,7 +989,7 @@ and it does not get deleted.
|
|
|
955
989
|
## Development
|
|
956
990
|
|
|
957
991
|
```bash
|
|
958
|
-
npm test #
|
|
992
|
+
npm test # 283 tests, offline, no cost
|
|
959
993
|
npm run build # tsc → dist/ with .d.ts
|
|
960
994
|
|
|
961
995
|
npx tsx bench/harness/run-multi.ts --provider=all --reps=3 --variants # costs money
|
package/dist/index.js
CHANGED
|
@@ -160,6 +160,19 @@ export function compress(input, options = {}) {
|
|
|
160
160
|
};
|
|
161
161
|
const finish = (wire, systemPreamble, cachePreamble, resolve, encode) => {
|
|
162
162
|
const compressedChars = countSchemaTokensApprox(wire) + systemPreamble.length;
|
|
163
|
+
// `savedPct` is a CHARACTER saving, deliberately.
|
|
164
|
+
//
|
|
165
|
+
// 0.2.7 tried to make it a token estimate by dividing each side by a chars-per-token
|
|
166
|
+
// ratio calibrated against count_tokens. That was a mistake, and measurement caught
|
|
167
|
+
// it: providers charge a fixed framing cost per tool definition that character
|
|
168
|
+
// counting cannot see. At 149 tools it amortises away, at 2 tools it dominates — the
|
|
169
|
+
// ratio approach was off by 44% on a 2-tool level-1 block while being within 1% at
|
|
170
|
+
// 149. No local character-based calculation can span that range.
|
|
171
|
+
//
|
|
172
|
+
// The plain character ratio is the smaller and more predictable error: it runs a few
|
|
173
|
+
// points optimistic (−7.7% chars against −4.9% real tokens on a 2-tool set; 46.8%
|
|
174
|
+
// against 39.2% on 149 real tools). So it is reported as what it is, and the docs say
|
|
175
|
+
// to measure with your provider's counter for anything you publish.
|
|
163
176
|
return {
|
|
164
177
|
tools: wire,
|
|
165
178
|
systemPreamble,
|
package/dist/recommend.js
CHANGED
|
@@ -57,7 +57,11 @@ export function recommendLevel(tools, namespaceOf = defaultNamespaceOf) {
|
|
|
57
57
|
// provider's own schema enforcement, which levels 2-3 give up. That is worth more
|
|
58
58
|
// than a saving you would not notice — hence an absolute threshold on the block,
|
|
59
59
|
// not a shape test.
|
|
60
|
-
|
|
60
|
+
// 10,000 tokens is ~5% of a 200k window. Below that, reclaiming the block does not
|
|
61
|
+
// change what fits, and level 1 keeps the provider's own argument validation — worth
|
|
62
|
+
// more than a saving you would not notice. An external reviewer flagged the earlier
|
|
63
|
+
// 4,000 threshold for pushing 14-tool sets into dispatcher mode; they were right.
|
|
64
|
+
const THRESHOLD_TOKENS = 10000;
|
|
61
65
|
if (l1Tokens < THRESHOLD_TOKENS) {
|
|
62
66
|
return {
|
|
63
67
|
...base,
|
|
@@ -68,6 +72,6 @@ export function recommendLevel(tools, namespaceOf = defaultNamespaceOf) {
|
|
|
68
72
|
return {
|
|
69
73
|
...base,
|
|
70
74
|
level: 3,
|
|
71
|
-
reason: `${toolCount} tools take ~${l1Tokens.toLocaleString()} tokens at level 1; level 3 replaces them with two dispatcher tools plus a cached map. Measured on 149 real MCP tools: 41,648 tokens at level 1 against 2,980 at level 3, and 60/60 tasks completed across four frontier providers with zero hallucinated names. The cost is roughly 0.3-1.7 lookup calls per task — so about half an extra turn — plus the loss of provider-side argument checking
|
|
75
|
+
reason: `${toolCount} tools take ~${l1Tokens.toLocaleString()} tokens at level 1; level 3 replaces them with two dispatcher tools plus a cached map. Measured on 149 real MCP tools: 41,648 tokens at level 1 against 2,980 at level 3, and 60/60 tasks completed across four frontier providers with zero hallucinated names. The cost is roughly 0.3-1.7 lookup calls per task — so about half an extra turn — plus the loss of provider-side argument checking. Keep \`validate\` on; it is what catches malformed arguments instead. If latency matters more than context, stay at level 1.`,
|
|
72
76
|
};
|
|
73
77
|
}
|