@tangleai/agents 0.21.1 → 0.24.1

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.
@@ -1,22 +1,3 @@
1
- /**
2
- * The program schema.
3
- *
4
- * `queryRef` is the `$id` of an injected query grammar
5
- * (`@jarenjs/json/schemas/jaren-query.schema.json`, or its LLM-profile
6
- * twin — the twin is the better choice for constrained decoding, which
7
- * is what it was derived for). Given one, `select` and `reduce` are
8
- * shape-constrained as well as compile-gated, and the caller must pass
9
- * the same grammar to `createStructuredOutput` as a `ref` so the
10
- * validator can resolve it. Given none, `query` accepts any JSON value
11
- * and the compile gate carries the whole weight.
12
- *
13
- * @param {{ queryRef?: string, maxSteps?: number }} [options]
14
- * @returns {any} a JSON Schema document
15
- */
16
- export function programSchema(options?: {
17
- queryRef?: string;
18
- maxSteps?: number;
19
- }): any;
20
1
  /**
21
2
  * The action language: what a model may say about the environment.
22
3
  *
@@ -35,7 +16,7 @@ export function programSchema(options?: {
35
16
  * below is an operation name, a binding name, a slot reference, a
36
17
  * bounded instruction or a query document. There is no member a
37
18
  * corpus can be poured into, and none can be added later without
38
- * failing `test/ai/program.test.js` — the schema is walked and every
19
+ * failing `test/agents/program.test.ts` — the schema is walked and every
39
20
  * string member must declare a `maxLength`. That is what makes "the
40
21
  * program is constant-size whatever the corpus" a property of the
41
22
  * grammar rather than a promise about how it will be used.
@@ -68,15 +49,34 @@ export function programSchema(options?: {
68
49
  /** Steps one program may have. A plan longer than this is a program
69
50
  * that should have been two runs; it is also past the length a small
70
51
  * model keeps coherent. */
71
- export const MAX_STEPS: 12;
52
+ export declare const MAX_STEPS = 12;
72
53
  /** The whole document's character cap, enforced by the compiler. This
73
54
  * is the constant in "constant-size root request": the program is one
74
55
  * more thing the root carries, and it must not grow with the corpus. */
75
- export const MAX_PROGRAM_CHARS: 4000;
56
+ export declare const MAX_PROGRAM_CHARS = 4000;
76
57
  /** A binding name: short, lowercase, unmistakable in an error message. */
77
- export const NAME_PATTERN: "^[a-z][a-z0-9_]{0,31}$";
58
+ export declare const NAME_PATTERN = "^[a-z][a-z0-9_]{0,31}$";
78
59
  /** The operations a program may name, in the order a plan uses them. */
79
- export const PROGRAM_OPS: string[];
60
+ export declare const PROGRAM_OPS: string[];
61
+ /**
62
+ * The program schema.
63
+ *
64
+ * `queryRef` is the `$id` of an injected query grammar
65
+ * (`@jarenjs/json/schemas/jaren-query.schema.json`, or its LLM-profile
66
+ * twin — the twin is the better choice for constrained decoding, which
67
+ * is what it was derived for). Given one, `select` and `reduce` are
68
+ * shape-constrained as well as compile-gated, and the caller must pass
69
+ * the same grammar to `createStructuredOutput` as a `ref` so the
70
+ * validator can resolve it. Given none, `query` accepts any JSON value
71
+ * and the compile gate carries the whole weight.
72
+ *
73
+ * @param [options]
74
+ * @returns a JSON Schema document
75
+ */
76
+ export declare function programSchema(options?: {
77
+ queryRef?: string;
78
+ maxSteps?: number;
79
+ }): any;
80
80
  /** The program schema with the query seam empty — what a caller with no
81
81
  * grammar injected authors against. */
82
- export const PROGRAM_SCHEMA: any;
82
+ export declare const PROGRAM_SCHEMA: any;
@@ -1,4 +1,3 @@
1
- //@ts-check
2
1
  /**
3
2
  * The action language: what a model may say about the environment.
4
3
  *
@@ -17,7 +16,7 @@
17
16
  * below is an operation name, a binding name, a slot reference, a
18
17
  * bounded instruction or a query document. There is no member a
19
18
  * corpus can be poured into, and none can be added later without
20
- * failing `test/ai/program.test.js` — the schema is walked and every
19
+ * failing `test/agents/program.test.ts` — the schema is walked and every
21
20
  * string member must declare a `maxLength`. That is what makes "the
22
21
  * program is constant-size whatever the corpus" a property of the
23
22
  * grammar rather than a promise about how it will be used.
@@ -47,77 +46,64 @@
47
46
  * that hard-`$ref`'d a grammar this package may not import would make
48
47
  * the whole language unusable with the seam empty.
49
48
  */
50
-
51
49
  /** Steps one program may have. A plan longer than this is a program
52
50
  * that should have been two runs; it is also past the length a small
53
51
  * model keeps coherent. */
54
52
  export const MAX_STEPS = 12;
55
-
56
53
  /** The whole document's character cap, enforced by the compiler. This
57
54
  * is the constant in "constant-size root request": the program is one
58
55
  * more thing the root carries, and it must not grow with the corpus. */
59
56
  export const MAX_PROGRAM_CHARS = 4000;
60
-
61
57
  /** A binding name: short, lowercase, unmistakable in an error message. */
62
58
  export const NAME_PATTERN = '^[a-z][a-z0-9_]{0,31}$';
63
-
64
59
  /** How long a slot reference may be — an address, never a payload. */
65
60
  const SLOT_REF_MAX = 200;
66
-
67
61
  /** How long a sub-call instruction may be. An instruction, not content:
68
62
  * the content is the slot the sub-call is run over. */
69
63
  const PROMPT_MAX = 1000;
70
-
71
64
  /** How long a grep pattern may be. */
72
65
  const PATTERN_MAX = 200;
73
-
74
66
  /** The operations a program may name, in the order a plan uses them. */
75
67
  export const PROGRAM_OPS = ['chunk', 'grep', 'select', 'stat', 'peek', 'map', 'reduce', 'answer'];
76
-
77
68
  /** The one input member. See the file header for why it is not per-op. */
78
69
  const FROM = {
79
- type: 'string',
80
- minLength: 1,
81
- maxLength: SLOT_REF_MAX,
82
- description: 'What this step reads: a name from an earlier step\'s "as", or a slot from the digest.',
70
+ type: 'string',
71
+ minLength: 1,
72
+ maxLength: SLOT_REF_MAX,
73
+ description: 'What this step reads: a name from an earlier step\'s "as", or a slot from the digest.',
83
74
  };
84
-
85
75
  /** The one output member: the name later steps use to read this one.
86
76
  * `maxLength` as well as the pattern, which already bounds it: the D2
87
- * walk in `test/ai/program.test.js` checks that every string member
77
+ * walk in `test/agents/program.test.ts` checks that every string member
88
78
  * declares a cap, and a check that has to interpret a regex to decide
89
79
  * whether one is bounded is a weaker check than one that reads a
90
80
  * number. */
91
81
  const AS = {
92
- type: 'string',
93
- pattern: NAME_PATTERN,
94
- maxLength: 32,
95
- description: 'A short name for this step\'s result, used as "from" by a later step.',
82
+ type: 'string',
83
+ pattern: NAME_PATTERN,
84
+ maxLength: 32,
85
+ description: 'A short name for this step\'s result, used as "from" by a later step.',
96
86
  };
97
-
98
87
  /**
99
88
  * One step's schema.
100
- * @param {string} op
101
- * @param {string} description
102
- * @param {Record<string, any>} extra - members beyond `from`/`as`
103
- * @param {string[]} [required] - beyond `from`, `as`
89
+ * @param extra - members beyond `from`/`as`
90
+ * @param [required] - beyond `from`, `as`
104
91
  */
105
92
  function step(op, description, extra = {}, required = []) {
106
- return {
107
- title: op,
108
- description,
109
- type: 'object',
110
- properties: {
111
- op: { const: op },
112
- from: FROM,
113
- as: AS,
114
- ...extra,
115
- },
116
- required: ['op', 'from', 'as', ...required],
117
- additionalProperties: false,
118
- };
93
+ return {
94
+ title: op,
95
+ description,
96
+ type: 'object',
97
+ properties: {
98
+ op: { const: op },
99
+ from: FROM,
100
+ as: AS,
101
+ ...extra,
102
+ },
103
+ required: ['op', 'from', 'as', ...required],
104
+ additionalProperties: false,
105
+ };
119
106
  }
120
-
121
107
  /**
122
108
  * The program schema.
123
109
  *
@@ -130,76 +116,74 @@ function step(op, description, extra = {}, required = []) {
130
116
  * validator can resolve it. Given none, `query` accepts any JSON value
131
117
  * and the compile gate carries the whole weight.
132
118
  *
133
- * @param {{ queryRef?: string, maxSteps?: number }} [options]
134
- * @returns {any} a JSON Schema document
119
+ * @param [options]
120
+ * @returns a JSON Schema document
135
121
  */
136
122
  export function programSchema(options = {}) {
137
- const query = options.queryRef === undefined
138
- ? { description: 'A jaren-query document.' }
139
- : { $ref: options.queryRef, description: 'A jaren-query document.' };
140
- const maxSteps = options.maxSteps ?? MAX_STEPS;
141
-
142
- return {
143
- $id: 'https://jarenjs.github.io/schemas/ai/program.json',
144
- title: 'Environment program',
145
- description: 'A plan over slots in the agent\'s environment. Steps name slots and never'
146
- + ' carry their content; the last step is always "answer".',
147
- type: 'object',
148
- properties: {
149
- steps: {
150
- type: 'array',
151
- minItems: 1,
152
- maxItems: maxSteps,
153
- items: {
154
- // anyOf, not oneOf: the branches are disjoint by their `op`
155
- // const, and oneOf is the keyword provider implementations
156
- // most often refuse (the same reason schemas/patch.js gives).
157
- anyOf: [
158
- step('chunk', 'Split a slot into addressable pieces.', {
159
- strategy: { enum: ['size', 'line', 'separator'], description: 'How to cut. Default size.' },
160
- size: { type: 'integer', minimum: 200, maximum: 100000, description: 'Piece size in characters.' },
161
- }),
162
- step('grep', 'Scan for a pattern and record which slots matched.', {
163
- pattern: { type: 'string', minLength: 1, maxLength: PATTERN_MAX, description: 'A regular expression.' },
164
- flags: { enum: ['i', 'm', 'im', ''], description: 'Regex flags. Default i.' },
165
- limit: { type: 'integer', minimum: 1, maximum: 200, description: 'Maximum matches recorded.' },
166
- }, ['pattern']),
167
- step('select', 'Run a query over a JSON slot and store the result.', { query }, ['query']),
168
- step('stat', 'Counts, sizes and shape of a slot or a family.'),
169
- step('peek', 'Metadata and a head excerpt of one slot.'),
170
- step('map', 'Ask the model once per piece. The ONLY step that calls a model.', {
171
- prompt: {
172
- type: 'string',
173
- minLength: 1,
174
- maxLength: PROMPT_MAX,
175
- description: 'What to ask about each piece. Ask for a JSON value; the piece is'
176
- + ' supplied automatically, so do not paste any content here.',
177
- },
178
- }, ['prompt']),
179
- step('reduce', 'Combine a map\'s results with a query, into one slot.', {
180
- query, outputSchema: { type: 'object', description: 'Declared JSON Schema for an inference-unknown result; validated before storage.' },
181
- }, ['query']),
182
- {
183
- title: 'answer',
184
- description: 'The last step: the slot the answer is read from.',
185
- type: 'object',
186
- properties: {
187
- op: { const: 'answer' },
188
- from: FROM,
189
- chars: { type: 'integer', minimum: 1, maximum: 8000, description: 'How much of it to read.' },
190
- },
191
- required: ['op', 'from'],
192
- additionalProperties: false,
123
+ const query = options.queryRef === undefined
124
+ ? { description: 'A jaren-query document.' }
125
+ : { $ref: options.queryRef, description: 'A jaren-query document.' };
126
+ const maxSteps = options.maxSteps ?? MAX_STEPS;
127
+ return {
128
+ $id: 'https://jarenjs.github.io/schemas/ai/program.json',
129
+ title: 'Environment program',
130
+ description: 'A plan over slots in the agent\'s environment. Steps name slots and never'
131
+ + ' carry their content; the last step is always "answer".',
132
+ type: 'object',
133
+ properties: {
134
+ steps: {
135
+ type: 'array',
136
+ minItems: 1,
137
+ maxItems: maxSteps,
138
+ items: {
139
+ // anyOf, not oneOf: the branches are disjoint by their `op`
140
+ // const, and oneOf is the keyword provider implementations
141
+ // most often refuse (the same reason schemas/patch.ts gives).
142
+ anyOf: [
143
+ step('chunk', 'Split a slot into addressable pieces.', {
144
+ strategy: { enum: ['size', 'line', 'separator'], description: 'How to cut. Default size.' },
145
+ size: { type: 'integer', minimum: 200, maximum: 100000, description: 'Piece size in characters.' },
146
+ }),
147
+ step('grep', 'Scan for a pattern and record which slots matched.', {
148
+ pattern: { type: 'string', minLength: 1, maxLength: PATTERN_MAX, description: 'A regular expression.' },
149
+ flags: { enum: ['i', 'm', 'im', ''], description: 'Regex flags. Default i.' },
150
+ limit: { type: 'integer', minimum: 1, maximum: 200, description: 'Maximum matches recorded.' },
151
+ }, ['pattern']),
152
+ step('select', 'Run a query over a JSON slot and store the result.', { query }, ['query']),
153
+ step('stat', 'Counts, sizes and shape of a slot or a family.'),
154
+ step('peek', 'Metadata and a head excerpt of one slot.'),
155
+ step('map', 'Ask the model once per piece. The ONLY step that calls a model.', {
156
+ prompt: {
157
+ type: 'string',
158
+ minLength: 1,
159
+ maxLength: PROMPT_MAX,
160
+ description: 'What to ask about each piece. Ask for a JSON value; the piece is'
161
+ + ' supplied automatically, so do not paste any content here.',
162
+ },
163
+ }, ['prompt']),
164
+ step('reduce', 'Combine a map\'s results with a query, into one slot.', {
165
+ query, outputSchema: { type: 'object', description: 'Declared JSON Schema for an inference-unknown result; validated before storage.' },
166
+ }, ['query']),
167
+ {
168
+ title: 'answer',
169
+ description: 'The last step: the slot the answer is read from.',
170
+ type: 'object',
171
+ properties: {
172
+ op: { const: 'answer' },
173
+ from: FROM,
174
+ chars: { type: 'integer', minimum: 1, maximum: 8000, description: 'How much of it to read.' },
175
+ },
176
+ required: ['op', 'from'],
177
+ additionalProperties: false,
178
+ },
179
+ ],
180
+ },
193
181
  },
194
- ],
195
182
  },
196
- },
197
- },
198
- required: ['steps'],
199
- additionalProperties: false,
200
- };
183
+ required: ['steps'],
184
+ additionalProperties: false,
185
+ };
201
186
  }
202
-
203
187
  /** The program schema with the query seam empty — what a caller with no
204
188
  * grammar injected authors against. */
205
189
  export const PROGRAM_SCHEMA = programSchema();
package/src/toolbox.d.ts CHANGED
@@ -1,21 +1,25 @@
1
1
  /**
2
- * @typedef {Object} ToolDef
3
- * @property {string} name
4
- * @property {string} description
5
- * @property {any} inputSchema - JSON Schema for the arguments object
6
- * @property {(input: any) => any} execute - may return a value or a promise
2
+ * The toolbox: a registry of tools an AI may call, each declared with
3
+ * a JSON Schema `inputSchema` that Jaren itself compiles and enforces
4
+ * before the tool runs — the suite guarding its own tools. One
5
+ * registry serves every surface that wants to drive the host app:
6
+ *
7
+ * - an embedded agent loop (`toFunctionTools()` produces the OpenAI
8
+ * function-calling definitions, `execute()` dispatches a call);
9
+ * - a browser-hosted agent over WebMCP (`registerModelContext()`
10
+ * publishes the same tools on either browser model-context root).
11
+ *
12
+ * `execute` never throws for content-level problems: an unknown tool
13
+ * or a throwing tool comes back as `{ error }`, invalid input as
14
+ * `{ error, errors, inputSchema }` plus a `hint` where the model sent
15
+ * JSON-encoded text for a structured property — results the calling
16
+ * model can read and recover from.
7
17
  */
8
18
  /**
9
- * @param {{ validator?: any }} [options] - a shared JarenValidator, if
19
+ * @param [options] - a shared JarenValidator, if
10
20
  * the host already has one
11
- * @returns {{
12
- * add: (def: ToolDef) => void,
13
- * list: () => { name: string, description: string, inputSchema: any }[],
14
- * toFunctionTools: () => any[],
15
- * execute: (name: string, args: any) => any,
16
- * }}
17
21
  */
18
- export function createToolbox(options?: {
22
+ export declare function createToolbox(options?: {
19
23
  validator?: any;
20
24
  }): {
21
25
  add: (def: ToolDef) => void;
@@ -31,25 +35,22 @@ export function createToolbox(options?: {
31
35
  * Publish validated tools through the shared browser adapter. Await `ready`
32
36
  * for completion and call `dispose` when the host leaves. The optional context
33
37
  * remains the second argument; undefined requests automatic discovery.
34
- * @param {ReturnType<typeof createToolbox>} toolbox
35
- * @param {unknown} [modelContext]
36
- * @param {(error: unknown) => void} [onError]
37
- * @param {Omit<import('@jarenjs/contract/webmcp').WebMcpOptions, 'context'|'onError'>} [options]
38
+ * @param [modelContext]
39
+ * @param [onError]
40
+ * @param [options]
38
41
  */
39
- export function registerModelContext(toolbox: ReturnType<typeof createToolbox>, modelContext?: unknown, onError?: (error: unknown) => void, options?: Omit<import("@jarenjs/contract/webmcp").WebMcpOptions, "context" | "onError">): {
42
+ export declare function registerModelContext(toolbox: ReturnType<typeof createToolbox>, modelContext?: unknown, onError?: (error: unknown) => void, options?: Omit<import('@jarenjs/contract/webmcp').WebMcpOptions, 'context' | 'onError'>): {
40
43
  ready: Promise<import("@jarenjs/contract/webmcp").WebMcpResult>;
41
44
  dispose: () => Promise<import("@jarenjs/contract/webmcp").WebMcpResult>;
42
45
  readonly status: "disposed" | "failed" | "pending" | "registered" | "unavailable";
43
46
  };
44
47
  export type ToolDef = {
45
48
  name: string;
46
- description: string;
47
- /**
48
- * - JSON Schema for the arguments object
49
- */
50
- inputSchema: any;
51
- /**
52
- * - may return a value or a promise
53
- */
49
+ description: string; /**
50
+ * - JSON Schema for the arguments object
51
+ */
52
+ inputSchema: any; /**
53
+ * - may return a value or a promise
54
+ */
54
55
  execute: (input: any) => any;
55
56
  };