@tangleai/agents 0.21.1 → 0.25.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/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # @tangleai/agents
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Patch Changes
6
+
7
+ - @tangleai/context@0.25.0
8
+ - @tangleai/models@0.25.0
9
+
10
+ ## 0.24.1
11
+
12
+ ### Patch Changes
13
+
14
+ - @tangleai/context@0.24.1
15
+ - @tangleai/models@0.24.1
16
+
17
+ ## 0.24.0
18
+
19
+ ### Patch Changes
20
+
21
+ - @tangleai/context@0.24.0
22
+ - @tangleai/models@0.24.0
23
+
24
+ ## 0.23.0
25
+
26
+ ### Patch Changes
27
+
28
+ - @tangleai/context@0.23.0
29
+ - @tangleai/models@0.23.0
30
+
31
+ ## 0.22.0
32
+
33
+ ### Patch Changes
34
+
35
+ - Convert the migrated source, tests, benchmarks and hosts to strict TypeScript,
36
+ with JavaScript and declarations emitted through one release build. Move the
37
+ program pen from `@tangleai/jaren/program` and the Jaren integration barrel to
38
+ `@tangleai/linq/program`, preserving its JSON format and phantom binding types.
39
+ The new `@tangleai/linq` root exposes the program namespace and shared build error.
40
+
41
+ Match the embedder declarations to unknown widths before the first response,
42
+ retain precise ledger result variants, and enforce the refinement-pressure
43
+ instrument's stated 60-second deadline through the chat client's abort signal.
44
+ - Updated dependencies
45
+ - @tangleai/models@0.22.0
46
+ - @tangleai/context@0.22.0
47
+
3
48
  ## 0.21.1
4
49
 
5
50
  ### Patch Changes
package/README.md CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  Validated tools, bounded agents, action programs, recursive execution and guarded refinement.
4
4
 
5
- This package keeps its JS/JSDoc implementation and deterministic tests. Inject
5
+ The implementation and deterministic tests use strict TypeScript. Published
6
+ packages contain ESM JavaScript and declarations emitted from that source. Inject
6
7
  fetch, storage and compiler services at the existing seams. The public source
7
8
  exports and emitted npm JavaScript share one implementation.
8
9
 
@@ -164,7 +165,7 @@ Back it with `@jarenjs/db` over OPFS, with one `localStorage` slot, with a file,
164
165
  server — or with nothing. The package gains no dependency either way, which is the whole
165
166
  posture: storage stays injected and it degrades to in-memory and
166
167
  schema-only. This site's assistant backs it with a single JSON slot
167
- ([`ledgerStore.js`](https://github.com/jklarenbeek/jarenjs/blob/main/packages/website/src/lib/ledgerStore.js)), which is all a browser session
168
+ ([`storage/slot.ts`](../context/src/storage/slot.ts)), which is all a browser session
168
169
  needs. The ledger serializes its own writes. An adapter with `mutate` also
169
170
  serializes other writers at storage; `ledger.concurrency` reports `atomic` or
170
171
  `single-writer`. Four-method adapters require host coordination between writers.
@@ -247,7 +248,7 @@ const { memories, scores, skipped } = await ledger.recall({
247
248
  collection is the query language's own k-nearest composition (QUERY-FORMAT §8.15) — and
248
249
  over a `derive: 'vector'` column the store plans it as a cut the engine finishes, with
249
250
  `explain()` naming the mode (its ARCHITECTURE, "The k-nearest plan").
250
- - **Measured, whichever way it fell.** `benchmark/retrieval.js` scores the ranked path beside the
251
+ - **Measured, whichever way it fell.** `benchmark/retrieval.ts` scores the ranked path beside the
251
252
  default over the same seeded corpus, through the deterministic reference embedder
252
253
  (§Embeddings — lexical, so a mechanism score, not a model-quality claim): <!--fact:retrieval.ranked-->5.0% of questions at 10,000 memories through the hash-trigram-64 reference embedder (33.8% at 1,000), ahead of tag match and recency's 1.3%<!--/fact-->.
253
254
  A real model's number is the host's to measure through the same instrument's `--live` tier.
@@ -487,7 +488,7 @@ the model fetches a round back when it needs one — a normal tool call that sho
487
488
  a round while claiming an address for it, which is the failure this exists to remove.
488
489
 
489
490
  The contract, asserted over every budget the benchmark sweeps in both payload shapes
490
- (`test/agents/compaction-recovery.test.js`): **every fact the full transcript held is either
491
+ (`test/agents/compaction-recovery.test.ts`): **every fact the full transcript held is either
491
492
  still in the request verbatim or reachable through an address the request names** — <!--fact:horizon.ledgerRecovered-->40 of 40<!--/fact--> record values at the same budget, where the same runs without a ledger keep <!--fact:horizon.synopsisBand-->1 to 28<!--/fact--> of them. What that
492
493
  costs is a few characters of verbatim retention at the tightest budgets, published beside
493
494
  the win.
@@ -529,7 +530,7 @@ Without a `ledger`, all of this is inert and compaction behaves exactly as it al
529
530
 
530
531
  ## The action language — a program the model writes and the compiler checks
531
532
 
532
- For typed fixture and host authoring, the [AI program pen](../jaren/docs/PROGRAM-PEN.md)
533
+ For typed fixture and host authoring, the [AI program pen](../linq/docs/PROGRAM-PEN.md)
533
534
  emits this same document and imports no AI runtime.
534
535
 
535
536
  The environment lets a model *address* a corpus. A program lets it *work* one: a small
@@ -574,7 +575,7 @@ Three properties, each asserted rather than intended:
574
575
  compile keeps the **query engine's own** code (`JQ0003`, …) with its pointer rebased onto
575
576
  the step it came from.
576
577
  - **No step can carry content.** Every member of every step is an operation name, a binding,
577
- a slot reference, a bounded instruction or a query document — `test/agents/program.test.js`
578
+ a slot reference, a bounded instruction or a query document — `test/agents/program.test.ts`
578
579
  walks the grammar and fails if a string member is ever declared without a cap. So the
579
580
  program is the same size for a 10 kB corpus and a 10 MB one, which is what keeps the root
580
581
  request flat while a program runs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangleai/agents",
3
- "version": "0.21.1",
3
+ "version": "0.25.0",
4
4
  "description": "Validated tools, bounded agents, action programs, recursive execution and guarded refinement.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -59,11 +59,11 @@
59
59
  },
60
60
  "sideEffects": false,
61
61
  "dependencies": {
62
- "@jarenjs/core": "0.84.3",
63
- "@jarenjs/validate": "0.84.3",
64
- "@tangleai/models": "^0.21.1",
65
- "@tangleai/context": "^0.21.1",
66
- "@jarenjs/contract": "0.84.3"
62
+ "@jarenjs/core": "0.86.0",
63
+ "@jarenjs/validate": "0.86.0",
64
+ "@tangleai/models": "^0.25.0",
65
+ "@tangleai/context": "^0.25.0",
66
+ "@jarenjs/contract": "0.86.0"
67
67
  },
68
68
  "private": false,
69
69
  "files": [
package/src/agent.d.ts CHANGED
@@ -1,23 +1,32 @@
1
1
  /**
2
- * @typedef {Object} AgentHooks
3
- * @property {(text: string) => void} [onDelta] - streamed reply text
4
- * @property {(text: string) => void} [onReasoning] - streamed thinking
5
- * @property {(call: { name: string, arguments: string }) => void} [onToolCall]
6
- * @property {(step: { name: string, result: any }) => void} [onToolResult]
7
- * @property {AbortSignal} [signal]
2
+ * The agent loop: a bounded, deterministic tool-call round-trip over a
3
+ * chat client and a toolbox. The model proposes tool calls; the loop
4
+ * executes them through the schema-guarded toolbox, appends the
5
+ * results, and asks again up to `maxToolRounds` times, then it stops
6
+ * and says so instead of spinning. Weak local models are first-class
7
+ * citizens here: malformed tool arguments and failing tools become
8
+ * readable `{ error }` results the model can correct, never crashes.
9
+ *
10
+ * `send` never mutates the history it is given; it returns the full
11
+ * new transcript (wire-shape messages) so the host can persist it and
12
+ * send it back next turn.
13
+ *
14
+ * Given a `ledger`, compaction stops destroying: every round that
15
+ * leaves the request is written to an addressable slot first, the
16
+ * synopsis carries the addresses, and a `recall` tool fetches one back.
17
+ * Without a ledger the old path runs unchanged, synchronously, byte for
18
+ * byte — the new behaviour is opt-in and named.
19
+ *
20
+ * A ledger also gives the loop an OBJECTIVE and a BUDGET. The active
21
+ * goal and its progress are composed into the system prompt of every
22
+ * request — unconditionally, because it is the thing being worked on —
23
+ * while memories and skills are retrieved only when asked for. The
24
+ * composition happens in the REQUEST and never in the transcript: the
25
+ * history the host persists stays the immutable base prompt plus the
26
+ * conversation, so a resumed session composes today's goal rather than
27
+ * accumulating yesterday's.
8
28
  */
9
29
  /**
10
- * @param {{ client: { complete: (request: any) => Promise<any> },
11
- * toolbox?: { toFunctionTools: () => any[], execute: (name: string, args: any) => any } | null,
12
- * system?: string, maxToolRounds?: number, maxToolResultChars?: number,
13
- * historyBudget?: number, ledger?: any,
14
- * budget?: { turns?: number, tokens?: number, ms?: number,
15
- * spent?: { turns?: number, tokens?: number, ms?: number } },
16
- * retrieval?: { memories?: { tags?: string[], where?: any, limit?: number },
17
- * skills?: { tags?: string[], where?: any, limit?: number } },
18
- * now?: () => number,
19
- * environment?: any, transcript?: { slot?: string, window?: number },
20
- * compaction?: (droppedRounds: any[][], addresses?: any[]) => string }} options
21
30
  * - `historyBudget` caps the request history in CHARACTERS (tokens
22
31
  * are provider-private; characters are deterministic). When a
23
32
  * request would exceed it, the middle of the conversation is
@@ -63,13 +72,8 @@
63
72
  * no budget to exceed when the history is addressed instead of resent.
64
73
  * Both together is legal and redundant; neither changes the other's
65
74
  * behaviour.
66
- * @returns {{ send: (history: any[], hooks?: AgentHooks) => Promise<{
67
- * message: any, messages: any[], steps: any[], stopReason: string }>,
68
- * resume: (history?: any[], hooks?: AgentHooks) => Promise<{
69
- * message: any, messages: any[], steps: any[], stopReason: string }>,
70
- * spend: () => { turns: number, tokens: number, ms: number } }}
71
75
  */
72
- export function createAgent(options: {
76
+ export declare function createAgent(options: {
73
77
  client: {
74
78
  complete: (request: any) => Promise<any>;
75
79
  };
@@ -135,18 +139,12 @@ export function createAgent(options: {
135
139
  * message, then its content. Line-oriented on purpose — `grep` reports
136
140
  * the line that matched, so a tool result written as one JSON line comes
137
141
  * back as one legible hit with its address beside it.
138
- * @param {any[]} messages
139
- * @returns {string}
140
142
  */
141
- export function transcriptText(messages: any[]): string;
143
+ export declare function transcriptText(messages: any[]): string;
142
144
  export type AgentHooks = {
143
- /**
144
- * - streamed reply text
145
- */
146
- onDelta?: (text: string) => void;
147
- /**
148
- * - streamed thinking
149
- */
145
+ onDelta?: (text: string) => void; /**
146
+ * - streamed thinking
147
+ */
150
148
  onReasoning?: (text: string) => void;
151
149
  onToolCall?: (call: {
152
150
  name: string;