@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 +45 -0
- package/README.md +7 -6
- package/package.json +6 -6
- package/src/agent.d.ts +31 -33
- package/src/agent.js +522 -669
- package/src/index.d.ts +12 -11
- package/src/index.js +7 -12
- package/src/program-result.d.ts +7 -29
- package/src/program-result.js +16 -40
- package/src/program-session.d.ts +7 -13
- package/src/program-session.js +130 -108
- package/src/program-shape.d.ts +17 -17
- package/src/program-shape.js +47 -40
- package/src/program.d.ts +140 -108
- package/src/program.js +637 -712
- package/src/recursive.d.ts +65 -37
- package/src/recursive.js +223 -263
- package/src/refine.d.ts +49 -15
- package/src/refine.js +396 -445
- package/src/schemas/program.d.ts +25 -25
- package/src/schemas/program.js +88 -104
- package/src/toolbox.d.ts +27 -26
- package/src/toolbox.js +90 -124
package/src/schemas/program.d.ts
CHANGED
|
@@ -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/
|
|
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
|
|
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
|
|
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
|
|
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;
|
package/src/schemas/program.js
CHANGED
|
@@ -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/
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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/
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
101
|
-
* @param
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
|
134
|
-
* @returns
|
|
119
|
+
* @param [options]
|
|
120
|
+
* @returns a JSON Schema document
|
|
135
121
|
*/
|
|
136
122
|
export function programSchema(options = {}) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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
|
|
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
|
|
35
|
-
* @param
|
|
36
|
-
* @param
|
|
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(
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
};
|