@lloyal-labs/sdk 1.0.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 +162 -0
- package/dist/Branch.d.ts +463 -0
- package/dist/Branch.d.ts.map +1 -0
- package/dist/Branch.js +608 -0
- package/dist/Branch.js.map +1 -0
- package/dist/BranchStore.d.ts +125 -0
- package/dist/BranchStore.d.ts.map +1 -0
- package/dist/BranchStore.js +155 -0
- package/dist/BranchStore.js.map +1 -0
- package/dist/Rerank.d.ts +38 -0
- package/dist/Rerank.d.ts.map +1 -0
- package/dist/Rerank.js +220 -0
- package/dist/Rerank.js.map +1 -0
- package/dist/Session.d.ts +74 -0
- package/dist/Session.d.ts.map +1 -0
- package/dist/Session.js +93 -0
- package/dist/Session.js.map +1 -0
- package/dist/deltas.d.ts +37 -0
- package/dist/deltas.d.ts.map +1 -0
- package/dist/deltas.js +52 -0
- package/dist/deltas.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +1365 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +85 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
package/dist/Branch.js
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Branch = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
/**
|
|
6
|
+
* Forkable inference handle for covalent generation
|
|
7
|
+
*
|
|
8
|
+
* A Branch owns everything needed for independent generation: a KV cache
|
|
9
|
+
* sequence, sampler chain, logits snapshot, and perplexity tracker.
|
|
10
|
+
*
|
|
11
|
+
* Forking is cheap — the KV prefix is shared in memory (metadata-only operation under unified KV —
|
|
12
|
+
* no KV tensor buffers are copied), so sibling branches read from the same physical KV entries.
|
|
13
|
+
* Only tokens decoded after the fork point are exclusive to each branch.
|
|
14
|
+
*
|
|
15
|
+
* Branches form trees, not just flat lists. Fork from root for best-of-N,
|
|
16
|
+
* fork from children for tree search/beam search, fork from a draft for speculative
|
|
17
|
+
* decoding.
|
|
18
|
+
*
|
|
19
|
+
* The produce/commit protocol separates sampling from state advancement:
|
|
20
|
+
* produce() samples without writing to KV, letting you inspect the result
|
|
21
|
+
* before deciding to commit().
|
|
22
|
+
*
|
|
23
|
+
* @example Best-of-N with perplexity selection
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const root = Branch.create(ctx, tokens.length, { temperature: 0.8 });
|
|
26
|
+
* await root.prefill(tokens);
|
|
27
|
+
*
|
|
28
|
+
* const results = [];
|
|
29
|
+
* for (let i = 0; i < 5; i++) {
|
|
30
|
+
* const branch = await root.fork();
|
|
31
|
+
* branch.reseedSampler(1000 + i);
|
|
32
|
+
* const tokens = [];
|
|
33
|
+
* for await (const { token } of branch) tokens.push(token);
|
|
34
|
+
* results.push({ branch, tokens, ppl: branch.perplexity });
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* const best = results.reduce((a, b) => a.ppl < b.ppl ? a : b);
|
|
38
|
+
* for (const r of results) { if (r !== best) await r.branch.prune(); }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @category Branching
|
|
42
|
+
*/
|
|
43
|
+
class Branch {
|
|
44
|
+
_ctx;
|
|
45
|
+
_handle;
|
|
46
|
+
_disposed;
|
|
47
|
+
constructor(ctx, handle) {
|
|
48
|
+
this._ctx = ctx;
|
|
49
|
+
this._handle = handle;
|
|
50
|
+
this._disposed = false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a root branch at the given position
|
|
54
|
+
*
|
|
55
|
+
* The branch takes ownership of the sequence and creates its own sampler
|
|
56
|
+
* chain from the provided params. Call prefill() to decode prompt tokens
|
|
57
|
+
* and capture the logit distribution before forking.
|
|
58
|
+
*
|
|
59
|
+
* @param ctx - SessionContext to create branch on
|
|
60
|
+
* @param position - Starting position (typically prompt token count)
|
|
61
|
+
* @param params - Sampling parameters (temperature, topP, etc.)
|
|
62
|
+
* @param nBatch - Per-branch batch size override (defaults to context nBatch).
|
|
63
|
+
* Controls chunk size for prefill(). Has no effect on
|
|
64
|
+
* single-token commit() which uses a zero-allocation fast path.
|
|
65
|
+
* @param grammar - GBNF grammar string for constrained generation.
|
|
66
|
+
* When provided, sample() returns only grammar-valid tokens. The grammar state
|
|
67
|
+
* is cloned on fork(), so sibling branches can diverge independently.
|
|
68
|
+
* @returns New Branch instance
|
|
69
|
+
*/
|
|
70
|
+
static create(ctx, position, params, nBatch, grammar) {
|
|
71
|
+
const handle = ctx._branchCreate(position, params, nBatch, grammar);
|
|
72
|
+
return new Branch(ctx, handle);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fork this branch to a new sequence (async)
|
|
76
|
+
*
|
|
77
|
+
* Async contract: local branches resolve immediately; cloud branches
|
|
78
|
+
* may perform an HTTP round-trip. Use {@link forkSync} when you know
|
|
79
|
+
* the branch is local and want zero-overhead forking.
|
|
80
|
+
*
|
|
81
|
+
* @returns New forked Branch
|
|
82
|
+
*/
|
|
83
|
+
async fork() {
|
|
84
|
+
return this.forkSync();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Fork this branch to a new sequence (sync)
|
|
88
|
+
*
|
|
89
|
+
* The child shares the parent's KV prefix in memory (metadata-only under unified KV, no KV buffer copy).
|
|
90
|
+
* Logits, sampler state, and perplexity tracker are cloned so the child
|
|
91
|
+
* can diverge independently. Fork from any branch — root or intermediate —
|
|
92
|
+
* to build arbitrarily deep trees.
|
|
93
|
+
*
|
|
94
|
+
* Call reseedSampler() on each child for stochastic diversity.
|
|
95
|
+
*
|
|
96
|
+
* @returns New forked Branch
|
|
97
|
+
*/
|
|
98
|
+
forkSync() {
|
|
99
|
+
this._ensureNotDisposed();
|
|
100
|
+
const newHandle = this._ctx._branchFork(this._handle);
|
|
101
|
+
return new Branch(this._ctx, newHandle);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get a copy of this branch's captured logits snapshot.
|
|
105
|
+
*
|
|
106
|
+
* Returns n_vocab floats — the raw logit distribution from the last
|
|
107
|
+
* prefill() or commit() call.
|
|
108
|
+
*
|
|
109
|
+
* Returns an independent copy of the branch's internal snapshot.
|
|
110
|
+
* The returned Float32Array is safe to hold across async boundaries
|
|
111
|
+
* and is not affected by subsequent decode operations.
|
|
112
|
+
*
|
|
113
|
+
* @returns Independent copy of the logits snapshot (n_vocab elements)
|
|
114
|
+
* @throws If no logits have been captured yet
|
|
115
|
+
*/
|
|
116
|
+
getLogits() {
|
|
117
|
+
this._ensureNotDisposed();
|
|
118
|
+
return this._ctx._branchGetLogits(this._handle);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Bulk-decode tokens into the branch's KV cache and capture logits.
|
|
122
|
+
*
|
|
123
|
+
* `tokens.length` is the total count to process; the branch's `nBatch`
|
|
124
|
+
* (set at `Branch.create`) controls how many are sent per `llama_decode`
|
|
125
|
+
* call. E.g. 500 tokens with `nBatch=64` → 8 calls (7×64 + 1×52).
|
|
126
|
+
*
|
|
127
|
+
* Advances `position` by `tokens.length`. Stores final logits into the
|
|
128
|
+
* branch's internal snapshot — the next `produce()`/`sample()` reads
|
|
129
|
+
* from it.
|
|
130
|
+
*
|
|
131
|
+
* Does NOT accept tokens into the repeat-penalty window — for external
|
|
132
|
+
* tokens (user input between turns), not model-generated tokens.
|
|
133
|
+
* For model output, use `commit()` which does accept + decode.
|
|
134
|
+
*
|
|
135
|
+
* The primary way to feed tokens into a branch's KV cache.
|
|
136
|
+
*
|
|
137
|
+
* @param tokens - Token IDs to decode
|
|
138
|
+
*/
|
|
139
|
+
async prefill(tokens) {
|
|
140
|
+
this._ensureNotDisposed();
|
|
141
|
+
await this._ctx._branchPrefill(this._handle, tokens);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Sample next token from branch's logits snapshot
|
|
145
|
+
*
|
|
146
|
+
* Applies the branch's full sampler chain (top-k, top-p, temperature,
|
|
147
|
+
* repeat/presence penalties) to the captured logits.
|
|
148
|
+
*
|
|
149
|
+
* @returns Sampled token ID
|
|
150
|
+
*/
|
|
151
|
+
sample() {
|
|
152
|
+
this._ensureNotDisposed();
|
|
153
|
+
return this._ctx._branchSample(this._handle);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Record token in the sampler's repeat/presence penalty window
|
|
157
|
+
*
|
|
158
|
+
* @param token - Token to accept
|
|
159
|
+
*/
|
|
160
|
+
accept(token) {
|
|
161
|
+
this._ensureNotDisposed();
|
|
162
|
+
this._ctx._branchAccept(this._handle, token);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Discard this branch (async)
|
|
166
|
+
*
|
|
167
|
+
* Async contract: local branches resolve immediately; cloud branches
|
|
168
|
+
* may perform an HTTP round-trip. Use {@link pruneSync} when you know
|
|
169
|
+
* the branch is local.
|
|
170
|
+
*
|
|
171
|
+
* RESTRICT mode: throws if children exist. Use {@link pruneSubtree} to
|
|
172
|
+
* cascade-delete an entire subtree.
|
|
173
|
+
*/
|
|
174
|
+
async prune() {
|
|
175
|
+
this.pruneSync();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Discard this branch — remove its divergent KV entries and free the handle (sync)
|
|
179
|
+
*
|
|
180
|
+
* Only removes KV entries divergent from the shared prefix; sibling branches
|
|
181
|
+
* are unaffected. The disposed flag is set synchronously — any call to
|
|
182
|
+
* produce(), commit(), etc. after prune() will throw immediately.
|
|
183
|
+
*
|
|
184
|
+
* RESTRICT mode: throws if children exist. Use {@link pruneSubtreeSync} to
|
|
185
|
+
* cascade-delete an entire subtree.
|
|
186
|
+
*/
|
|
187
|
+
pruneSync() {
|
|
188
|
+
if (this._disposed)
|
|
189
|
+
return;
|
|
190
|
+
const kids = this.children;
|
|
191
|
+
if (kids.length > 0) {
|
|
192
|
+
throw new Error(`Branch.prune(): branch ${this._handle} has ${kids.length} active child(ren) ` +
|
|
193
|
+
`[${kids.join(', ')}]. Prune children first or use pruneSubtree().`);
|
|
194
|
+
}
|
|
195
|
+
this._ctx._branchPrune(this._handle);
|
|
196
|
+
this._disposed = true;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Discard this branch and all its descendants (async)
|
|
200
|
+
*
|
|
201
|
+
* Async contract: local branches resolve immediately; cloud branches
|
|
202
|
+
* may perform an HTTP round-trip. Use {@link pruneSubtreeSync} when you know
|
|
203
|
+
* the branch is local.
|
|
204
|
+
*/
|
|
205
|
+
async pruneSubtree() {
|
|
206
|
+
this.pruneSubtreeSync();
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Discard this branch and all its descendants — CASCADE delete (sync)
|
|
210
|
+
*
|
|
211
|
+
* Iterative post-order traversal: prunes children first, then this branch.
|
|
212
|
+
* Use when tearing down an entire subtree (e.g. abandoned search path).
|
|
213
|
+
* Sets disposed synchronously.
|
|
214
|
+
*/
|
|
215
|
+
pruneSubtreeSync() {
|
|
216
|
+
if (this._disposed)
|
|
217
|
+
return;
|
|
218
|
+
this._ctx._branchPruneSubtree(this._handle);
|
|
219
|
+
this._disposed = true;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Reseed the sampler's PRNG for diversity after fork()
|
|
223
|
+
*
|
|
224
|
+
* CRITICAL for parallel generation: Without reseeding, all forked branches
|
|
225
|
+
* produce identical outputs because they share the same PRNG state.
|
|
226
|
+
*
|
|
227
|
+
* Only affects stochastic samplers (temperature > 0). Greedy samplers are unchanged.
|
|
228
|
+
*
|
|
229
|
+
* @param seed - New seed for the PRNG
|
|
230
|
+
*/
|
|
231
|
+
reseedSampler(seed) {
|
|
232
|
+
this._ensureNotDisposed();
|
|
233
|
+
this._ctx._branchSamplerChainReseed(this._handle, seed);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Apply dynamic logit adjustments for this branch only
|
|
237
|
+
*
|
|
238
|
+
* Unlike `logit_bias` in sampling params (which is cloned on fork), steer biases
|
|
239
|
+
* are NOT inherited by child branches. Each branch manages its own steer state
|
|
240
|
+
* independently. This makes steer ideal for path-dependent constraints.
|
|
241
|
+
*
|
|
242
|
+
* **Use cases:**
|
|
243
|
+
* - **tsampler**: Block tokens that would create repeated N-grams based on
|
|
244
|
+
* this branch's specific generation history
|
|
245
|
+
* - **Diverse beam search**: Penalize tokens already chosen by sibling beams
|
|
246
|
+
* to encourage output diversity across the beam
|
|
247
|
+
* - **Dynamic constraints**: Apply token restrictions that change per-step
|
|
248
|
+
*
|
|
249
|
+
* **Sampling order:** Grammar → Logit Bias → Steer → Sampler Chain
|
|
250
|
+
*
|
|
251
|
+
* @param biases - Array of token adjustments. Use `-Infinity` to completely
|
|
252
|
+
* block a token, positive values to boost probability, negative to reduce.
|
|
253
|
+
*
|
|
254
|
+
* @example Block tokens for N-gram deduplication (tsampler pattern)
|
|
255
|
+
* ```ts
|
|
256
|
+
* // Compute which tokens would create repeated 4-grams
|
|
257
|
+
* const blocked = computeNgramBlocks(generatedTokens, n=4);
|
|
258
|
+
*
|
|
259
|
+
* // Block those tokens for this sample only
|
|
260
|
+
* branch.steer(blocked.map(t => ({ token: t, bias: -Infinity })));
|
|
261
|
+
*
|
|
262
|
+
* const { token } = await branch.produce(); // Blocked tokens won't be sampled
|
|
263
|
+
* await branch.commit(token);
|
|
264
|
+
*
|
|
265
|
+
* // Clear for next iteration (recompute based on new history)
|
|
266
|
+
* branch.clearSteer();
|
|
267
|
+
* ```
|
|
268
|
+
*
|
|
269
|
+
* @example Diverse beam search
|
|
270
|
+
* ```ts
|
|
271
|
+
* // Each beam penalizes tokens chosen by siblings this step
|
|
272
|
+
* for (const beam of beams) {
|
|
273
|
+
* // Collect tokens chosen by other beams
|
|
274
|
+
* const siblingTokens = beams
|
|
275
|
+
* .filter(b => b !== beam && b.lastToken !== undefined)
|
|
276
|
+
* .map(b => b.lastToken);
|
|
277
|
+
*
|
|
278
|
+
* // Penalize sibling choices to encourage diversity
|
|
279
|
+
* beam.branch.steer(siblingTokens.map(t => ({ token: t, bias: -2.0 })));
|
|
280
|
+
*
|
|
281
|
+
* const { token } = await beam.branch.produce();
|
|
282
|
+
* await beam.branch.commit(token);
|
|
283
|
+
* beam.lastToken = token;
|
|
284
|
+
* beam.branch.clearSteer();
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*
|
|
288
|
+
* @example Boost specific tokens
|
|
289
|
+
* ```ts
|
|
290
|
+
* // Boost "yes" and "no" tokens for a yes/no question
|
|
291
|
+
* branch.steer([
|
|
292
|
+
* { token: yesTokenId, bias: 5.0 },
|
|
293
|
+
* { token: noTokenId, bias: 5.0 }
|
|
294
|
+
* ]);
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
steer(biases) {
|
|
298
|
+
this._ensureNotDisposed();
|
|
299
|
+
this._ctx._branchSteer(this._handle, biases);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Clear all steer biases from this branch
|
|
303
|
+
*
|
|
304
|
+
* Removes any dynamic logit adjustments set by `steer()`. Call this after
|
|
305
|
+
* each generation step if your steer constraints are computed per-step
|
|
306
|
+
* (e.g., N-gram blocking where the blocked set changes as text grows).
|
|
307
|
+
*
|
|
308
|
+
* @example Per-step steer pattern
|
|
309
|
+
* ```ts
|
|
310
|
+
* for (let i = 0; i < maxTokens; i++) {
|
|
311
|
+
* // Compute constraints based on current state
|
|
312
|
+
* const blocked = computeConstraints(generatedTokens);
|
|
313
|
+
* branch.steer(blocked.map(t => ({ token: t, bias: -Infinity })));
|
|
314
|
+
*
|
|
315
|
+
* const { token, isStop } = await branch.produce();
|
|
316
|
+
* if (isStop) break;
|
|
317
|
+
*
|
|
318
|
+
* await branch.commit(token);
|
|
319
|
+
* branch.clearSteer(); // Reset for next iteration
|
|
320
|
+
* generatedTokens.push(token);
|
|
321
|
+
* }
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
clearSteer() {
|
|
325
|
+
this._ensureNotDisposed();
|
|
326
|
+
this._ctx._branchClearSteer(this._handle);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Replace the sampler chain with new parameters (memoized)
|
|
330
|
+
*
|
|
331
|
+
* If the new params match the current chain's params, this is a no-op.
|
|
332
|
+
* Otherwise the old chain is freed and a new one is created. Use for
|
|
333
|
+
* Entropy-Driven Temperature (EDT) and other adaptive sampling strategies
|
|
334
|
+
* that adjust parameters per-step.
|
|
335
|
+
*
|
|
336
|
+
* @param params - New sampling parameters
|
|
337
|
+
*
|
|
338
|
+
* @example Entropy-Driven Temperature
|
|
339
|
+
* ```typescript
|
|
340
|
+
* const entropy = branch.modelEntropy('nats');
|
|
341
|
+
* branch.setSamplerParams({ temperature: edtTemperature(entropy) });
|
|
342
|
+
* const { token } = await branch.produce();
|
|
343
|
+
* await branch.commit(token);
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
setSamplerParams(params) {
|
|
347
|
+
this._ensureNotDisposed();
|
|
348
|
+
this._ctx._branchSetSamplerParams(this._handle, params);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Replace or remove the grammar constraint
|
|
352
|
+
*
|
|
353
|
+
* Pass a GBNF grammar string to constrain generation. Pass empty string
|
|
354
|
+
* or undefined to remove the constraint. The grammar state is cloned on
|
|
355
|
+
* fork(), so sibling branches can diverge independently after hot-swap.
|
|
356
|
+
*
|
|
357
|
+
* @param grammarStr - GBNF grammar string, or empty/undefined to remove
|
|
358
|
+
*
|
|
359
|
+
* @example Hot-swap grammar mid-generation
|
|
360
|
+
* ```typescript
|
|
361
|
+
* // Start unconstrained, then switch to JSON after detecting tool call
|
|
362
|
+
* branch.setGrammar(jsonGrammar);
|
|
363
|
+
* const { token } = await branch.produce();
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
setGrammar(grammarStr) {
|
|
367
|
+
this._ensureNotDisposed();
|
|
368
|
+
this._ctx._branchSetGrammar(this._handle, grammarStr || '');
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Set lazy grammar — unconstrained until trigger, then grammar-constrained
|
|
372
|
+
*
|
|
373
|
+
* Generation runs freely until a trigger pattern or token fires, at which
|
|
374
|
+
* point the grammar activates and constrains subsequent tokens. Used for
|
|
375
|
+
* tool-call generation: model writes freely until `<tool_call>`, then
|
|
376
|
+
* grammar forces valid XML structure.
|
|
377
|
+
*
|
|
378
|
+
* The grammar state is cloned on fork(), so sibling branches can diverge
|
|
379
|
+
* independently. Call again after a tool result prefill to reset.
|
|
380
|
+
*
|
|
381
|
+
* @param grammar - GBNF grammar string
|
|
382
|
+
* @param triggers - Trigger conditions from formatChat().grammarTriggers
|
|
383
|
+
*/
|
|
384
|
+
setGrammarLazy(grammar, triggers) {
|
|
385
|
+
this._ensureNotDisposed();
|
|
386
|
+
const escapeRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
387
|
+
const patterns = [];
|
|
388
|
+
const tokens = [];
|
|
389
|
+
for (const t of triggers) {
|
|
390
|
+
switch (t.type) {
|
|
391
|
+
case types_1.GrammarTriggerType.WORD:
|
|
392
|
+
patterns.push(escapeRegex(t.value));
|
|
393
|
+
break;
|
|
394
|
+
case types_1.GrammarTriggerType.PATTERN:
|
|
395
|
+
patterns.push(t.value);
|
|
396
|
+
break;
|
|
397
|
+
case types_1.GrammarTriggerType.PATTERN_FULL: {
|
|
398
|
+
const p = t.value;
|
|
399
|
+
patterns.push((p[0] !== '^' ? '^' : '') + p + (p[p.length - 1] !== '$' ? '$' : ''));
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
case types_1.GrammarTriggerType.TOKEN:
|
|
403
|
+
tokens.push(t.token);
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
this._ctx._branchSetGrammarLazy(this._handle, grammar, patterns, tokens);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Sample next token without advancing state (async)
|
|
411
|
+
*
|
|
412
|
+
* Async contract: local branches resolve immediately; cloud branches
|
|
413
|
+
* may perform an HTTP round-trip. Use {@link produceSync} when you know
|
|
414
|
+
* the branch is local and want zero-overhead sampling.
|
|
415
|
+
*/
|
|
416
|
+
async produce() {
|
|
417
|
+
return this.produceSync();
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Sample next token without advancing state (sync)
|
|
421
|
+
*
|
|
422
|
+
* Same as {@link produce} but synchronous. Use when you know the branch
|
|
423
|
+
* is local and want to avoid the microtick overhead of a promise.
|
|
424
|
+
*/
|
|
425
|
+
produceSync() {
|
|
426
|
+
this._ensureNotDisposed();
|
|
427
|
+
const token = this.sample();
|
|
428
|
+
return {
|
|
429
|
+
token,
|
|
430
|
+
text: this._ctx.tokenToText(token),
|
|
431
|
+
isStop: this._ctx.isStopToken(token),
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Accept and decode — update branch state, then write token to KV
|
|
436
|
+
*
|
|
437
|
+
* Accepts the token into the sampler penalty window (for correct PPL
|
|
438
|
+
* measurement), then decodes (writing to KV cache via AsyncWorker on
|
|
439
|
+
* the libuv thread pool) and captures the resulting logits for the next
|
|
440
|
+
* produce() call. Accept-first ordering with rollback: if decode throws,
|
|
441
|
+
* sampler/grammar/metrics are restored from clones.
|
|
442
|
+
*
|
|
443
|
+
* @param token Token to commit (from produce())
|
|
444
|
+
*/
|
|
445
|
+
async commit(token) {
|
|
446
|
+
this._ensureNotDisposed();
|
|
447
|
+
await this._ctx._storeCommit([this._handle], [token]);
|
|
448
|
+
}
|
|
449
|
+
// ===== METRICS =====
|
|
450
|
+
/**
|
|
451
|
+
* Compute entropy of the branch's logits distribution
|
|
452
|
+
*
|
|
453
|
+
* Measures model uncertainty from the branch's captured logits snapshot:
|
|
454
|
+
* - Low entropy: Model is confident (peaked distribution)
|
|
455
|
+
* - High entropy: Model is uncertain (flat distribution)
|
|
456
|
+
*
|
|
457
|
+
* Operates directly on `state->logits_snapshot` — no JS round-trip.
|
|
458
|
+
*
|
|
459
|
+
* @param base - Logarithm base: "nats" (default) or "bits"
|
|
460
|
+
* @returns Entropy value in specified base
|
|
461
|
+
*
|
|
462
|
+
* COST: O(n_vocab) - must sum over all token probabilities
|
|
463
|
+
*/
|
|
464
|
+
modelEntropy(base = 'nats') {
|
|
465
|
+
this._ensureNotDisposed();
|
|
466
|
+
return this._ctx._branchModelEntropy(this._handle, base);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Compute surprisal (negative log-likelihood) for a specific token
|
|
470
|
+
*
|
|
471
|
+
* Measures how "surprising" the model finds the given token from
|
|
472
|
+
* the branch's captured logits snapshot:
|
|
473
|
+
* - Low surprisal: Model expected this token (high probability)
|
|
474
|
+
* - High surprisal: Model didn't expect this token (low probability)
|
|
475
|
+
*
|
|
476
|
+
* Operates directly on `state->logits_snapshot` — no JS round-trip.
|
|
477
|
+
*
|
|
478
|
+
* @param token - Token ID to compute surprisal for
|
|
479
|
+
* @param base - Logarithm base: "nats" (default) or "bits"
|
|
480
|
+
* @returns Surprisal value in specified base
|
|
481
|
+
*
|
|
482
|
+
* COST: O(n_vocab) - softmax normalization required
|
|
483
|
+
*/
|
|
484
|
+
modelSurprisal(token, base = 'nats') {
|
|
485
|
+
this._ensureNotDisposed();
|
|
486
|
+
return this._ctx._branchModelSurprisal(this._handle, token, base);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Sampling-level perplexity (from filtered distribution)
|
|
490
|
+
*
|
|
491
|
+
* Returns perplexity from the distribution actually sampled from
|
|
492
|
+
* (after top-k/p/temp/penalties). Useful for policy priors and
|
|
493
|
+
* monitoring sampler chain impact.
|
|
494
|
+
*
|
|
495
|
+
* Compare with {@link perplexity} which is model-level (raw logits).
|
|
496
|
+
*/
|
|
497
|
+
get samplingPerplexity() {
|
|
498
|
+
this._ensureNotDisposed();
|
|
499
|
+
return this._ctx._branchGetSamplingPerplexity(this._handle);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Set static logit biases on this branch
|
|
503
|
+
*
|
|
504
|
+
* Unlike {@link steer} (which is NOT inherited on fork), logit biases
|
|
505
|
+
* ARE cloned when forking. Use for persistent constraints that should
|
|
506
|
+
* propagate to child branches.
|
|
507
|
+
*
|
|
508
|
+
* Applied during sample() in order: Grammar -> Logit Bias -> Steer -> Sampler Chain
|
|
509
|
+
*
|
|
510
|
+
* @param biases - Array of token adjustments. Use `-Infinity` to block,
|
|
511
|
+
* positive to boost, negative to reduce.
|
|
512
|
+
*/
|
|
513
|
+
setLogitBias(biases) {
|
|
514
|
+
this._ensureNotDisposed();
|
|
515
|
+
this._ctx._branchSetLogitBias(this._handle, biases);
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Clear all static logit biases from this branch
|
|
519
|
+
*/
|
|
520
|
+
clearLogitBias() {
|
|
521
|
+
this._ensureNotDisposed();
|
|
522
|
+
this._ctx._branchClearLogitBias(this._handle);
|
|
523
|
+
}
|
|
524
|
+
// ===== ACCESSORS =====
|
|
525
|
+
/** Branch's current position (number of tokens decoded) */
|
|
526
|
+
get position() {
|
|
527
|
+
this._ensureNotDisposed();
|
|
528
|
+
return this._ctx._branchGetPosition(this._handle);
|
|
529
|
+
}
|
|
530
|
+
/** Branch's perplexity (exp of mean surprisal) */
|
|
531
|
+
get perplexity() {
|
|
532
|
+
this._ensureNotDisposed();
|
|
533
|
+
return this._ctx._branchGetPerplexity(this._handle);
|
|
534
|
+
}
|
|
535
|
+
/** Internal handle (for debugging) */
|
|
536
|
+
get handle() {
|
|
537
|
+
return this._handle;
|
|
538
|
+
}
|
|
539
|
+
/** Whether this branch has been disposed */
|
|
540
|
+
get disposed() {
|
|
541
|
+
return this._disposed;
|
|
542
|
+
}
|
|
543
|
+
/** Parent branch handle, or null if root */
|
|
544
|
+
get parent() {
|
|
545
|
+
this._ensureNotDisposed();
|
|
546
|
+
const h = this._ctx._branchParent(this._handle);
|
|
547
|
+
return h === 0 ? null : h;
|
|
548
|
+
}
|
|
549
|
+
/** Child branch handles */
|
|
550
|
+
get children() {
|
|
551
|
+
this._ensureNotDisposed();
|
|
552
|
+
return this._ctx._branchChildren(this._handle);
|
|
553
|
+
}
|
|
554
|
+
/** True if this branch has no children */
|
|
555
|
+
get isLeaf() {
|
|
556
|
+
this._ensureNotDisposed();
|
|
557
|
+
return this._ctx._branchIsLeaf(this._handle);
|
|
558
|
+
}
|
|
559
|
+
/** True if this branch holds a KV lease */
|
|
560
|
+
get isActive() {
|
|
561
|
+
this._ensureNotDisposed();
|
|
562
|
+
return this._ctx._branchIsActive(this._handle);
|
|
563
|
+
}
|
|
564
|
+
// ===== ASYNC ITERATION =====
|
|
565
|
+
/**
|
|
566
|
+
* Async iterator — generate tokens until EOG
|
|
567
|
+
*
|
|
568
|
+
* Commit-before-yield semantics: every yielded token is already written
|
|
569
|
+
* to KV and accepted into the sampler. Breaking out of the loop is clean —
|
|
570
|
+
* no orphaned uncommitted tokens, perplexity reflects all yielded tokens.
|
|
571
|
+
*
|
|
572
|
+
* For inspect-before-commit (speculative decoding, tree search), use
|
|
573
|
+
* the {@link produce}/{@link commit} protocol directly.
|
|
574
|
+
*
|
|
575
|
+
* @example Generate to completion
|
|
576
|
+
* ```typescript
|
|
577
|
+
* for await (const { token, text } of branch) {
|
|
578
|
+
* process.stdout.write(text);
|
|
579
|
+
* }
|
|
580
|
+
* ```
|
|
581
|
+
*
|
|
582
|
+
* @example Generate with consumer-side bound
|
|
583
|
+
* ```typescript
|
|
584
|
+
* const tokens = [];
|
|
585
|
+
* for await (const { token } of branch) {
|
|
586
|
+
* tokens.push(token);
|
|
587
|
+
* if (tokens.length >= limit) break;
|
|
588
|
+
* }
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
async *[Symbol.asyncIterator]() {
|
|
592
|
+
while (!this._disposed) {
|
|
593
|
+
const { token, text, isStop } = await this.produce();
|
|
594
|
+
if (isStop)
|
|
595
|
+
return;
|
|
596
|
+
await this.commit(token);
|
|
597
|
+
yield { token, text };
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
// ===== INTERNAL =====
|
|
601
|
+
_ensureNotDisposed() {
|
|
602
|
+
if (this._disposed) {
|
|
603
|
+
throw new Error('Branch has been disposed');
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
exports.Branch = Branch;
|
|
608
|
+
//# sourceMappingURL=Branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Branch.js","sourceRoot":"","sources":["../src/Branch.ts"],"names":[],"mappings":"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"}
|