@procedures/llm 0.7.0 → 0.8.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 +29 -0
- package/README.md +52 -8
- package/dist/.tsbuildinfo +1 -1
- package/dist/events.d.ts +8 -3
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +100 -39
- package/dist/events.js.map +1 -1
- package/dist/loop.d.ts +72 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +107 -0
- package/dist/loop.js.map +1 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +31 -16
- package/dist/module.js.map +1 -1
- package/dist/procedures/llm/complete.d.ts +2 -1
- package/dist/procedures/llm/complete.d.ts.map +1 -1
- package/dist/procedures/llm/complete.js +28 -46
- package/dist/procedures/llm/complete.js.map +1 -1
- package/dist/procedures/llm/stream.d.ts +8 -2
- package/dist/procedures/llm/stream.d.ts.map +1 -1
- package/dist/procedures/llm/stream.js +22 -4
- package/dist/procedures/llm/stream.js.map +1 -1
- package/dist/tools.d.ts +11 -9
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +34 -10
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +50 -15
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/events.ts +114 -43
- package/src/loop.ts +159 -0
- package/src/module.ts +33 -16
- package/src/procedures/llm/complete.ts +30 -48
- package/src/procedures/llm/stream.ts +26 -7
- package/src/tools.ts +35 -10
- package/src/types.ts +53 -17
package/src/tools.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Procedures as tools of the model (`llm.complete` with `procedures`).
|
|
2
|
+
* Procedures as tools of the model (`llm.complete` and `llm.stream` with `procedures`).
|
|
3
3
|
*
|
|
4
|
-
* The caller names the procedures.
|
|
4
|
+
* The caller names the procedures. The procedure gives the model a tool for each one. The name
|
|
5
5
|
* is the key with `_` in place of each `.`. The description and the input schema come from the
|
|
6
|
-
* procedure. When the model asks for a tool,
|
|
7
|
-
*
|
|
6
|
+
* procedure. When the model asks for a tool, the procedure starts it through `ctx.client` with
|
|
7
|
+
* the input of the model. The output goes back as a `tool_result`.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* `loop.ts` has the loop of the two procedures.
|
|
10
|
+
*
|
|
11
|
+
* The procedures `llm.complete` and `llm.stream` are data-driven (`markDataDriven`): the input
|
|
12
|
+
* chooses the callees. Thus the admission of the host examines each nested call: its capability
|
|
13
|
+
* and its expose rule. Before the first request, the same rules examine each named procedure,
|
|
14
|
+
* so a refused tool costs no request.
|
|
13
15
|
*/
|
|
14
16
|
|
|
15
17
|
import {
|
|
@@ -38,7 +40,7 @@ export interface ProcedureTool {
|
|
|
38
40
|
readonly param: ToolParam;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
/** The default of `maxRounds`: the most requests to the model in one call of `llm.complete`. */
|
|
43
|
+
/** The default of `maxRounds`: the most requests to the model in one call of `llm.complete` or `llm.stream`. */
|
|
42
44
|
export const DEFAULT_MAX_ROUNDS = 8;
|
|
43
45
|
/** The most characters of the output of a tool that the model gets. */
|
|
44
46
|
export const MAX_TOOL_RESULT_CHARS = 200_000;
|
|
@@ -152,6 +154,29 @@ function resultText(output: unknown): string {
|
|
|
152
154
|
return `${text.slice(0, MAX_TOOL_RESULT_CHARS)}\n[llm: the output has ${text.length} characters, and this result has the first ${MAX_TOOL_RESULT_CHARS}]`;
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
/**
|
|
158
|
+
* This function waits for a nested call. The abort of the signal stops the wait at once with
|
|
159
|
+
* `ABORTED`. The nested call gets the same signal, so a procedure that reads it stops too.
|
|
160
|
+
*/
|
|
161
|
+
function untilAbort<T>(work: Promise<T>, signal: AbortSignal | undefined, path: ProcedurePath): Promise<T> {
|
|
162
|
+
if (signal === undefined) return work;
|
|
163
|
+
return new Promise<T>((resolve, reject) => {
|
|
164
|
+
const onAbort = (): void => reject(new InvocationError("ABORTED", `Procedure was aborted: ${path.join(".")}`, path));
|
|
165
|
+
if (signal.aborted) onAbort();
|
|
166
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
167
|
+
work.then(
|
|
168
|
+
(value) => {
|
|
169
|
+
signal.removeEventListener("abort", onAbort);
|
|
170
|
+
resolve(value);
|
|
171
|
+
},
|
|
172
|
+
(error: unknown) => {
|
|
173
|
+
signal.removeEventListener("abort", onAbort);
|
|
174
|
+
reject(error);
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
155
180
|
/**
|
|
156
181
|
* This function runs one `tool_use` block with the procedure of its tool, through `ctx.client`.
|
|
157
182
|
* It gives the record of the call and the `tool_result` block. An error of the procedure goes to
|
|
@@ -160,7 +185,7 @@ function resultText(output: unknown): string {
|
|
|
160
185
|
export async function runToolUse(use: LlmToolUse, tool: ProcedureTool, ctx: ToolContext): Promise<{ call: LlmToolCall; result: ContentBlock }> {
|
|
161
186
|
const base = { id: use.id, name: use.name, procedure: tool.key, input: use.input };
|
|
162
187
|
try {
|
|
163
|
-
const output = await ctx.client!.call(tool.path, use.input);
|
|
188
|
+
const output = await untilAbort(ctx.client!.call(tool.path, use.input), ctx.signal, tool.path);
|
|
164
189
|
return {
|
|
165
190
|
call: { ...base, isError: false, output },
|
|
166
191
|
result: { type: "tool_result", tool_use_id: use.id, content: resultText(output) },
|
package/src/types.ts
CHANGED
|
@@ -79,6 +79,13 @@ export interface LlmToolInput {
|
|
|
79
79
|
toolChoice?: LlmToolChoice | undefined;
|
|
80
80
|
/** The number of new tries after an error with `retryable: true`: 0 to 10. The default is the option of the module (2). */
|
|
81
81
|
retries?: number | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* The keys of the procedures that the model can use as tools, for example `weather.current`.
|
|
84
|
+
* The procedure starts each one through `ctx.client`, sends the result to the model, and asks again.
|
|
85
|
+
*/
|
|
86
|
+
procedures?: string[] | undefined;
|
|
87
|
+
/** The most requests to the model in one call: 1 to 64. The default is 8. */
|
|
88
|
+
maxRounds?: number | undefined;
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
/** A `tool_use` block of an answer: a call of a tool that the model asks for. */
|
|
@@ -91,7 +98,7 @@ export interface LlmToolUse {
|
|
|
91
98
|
input: unknown;
|
|
92
99
|
}
|
|
93
100
|
|
|
94
|
-
/** A call of a procedure tool that `llm.complete` made for the model. */
|
|
101
|
+
/** A call of a procedure tool that `llm.complete` or `llm.stream` made for the model. */
|
|
95
102
|
export interface LlmToolCall {
|
|
96
103
|
/** The ID of the `tool_use` block. */
|
|
97
104
|
id: string;
|
|
@@ -113,15 +120,7 @@ export interface LlmToolCall {
|
|
|
113
120
|
// llm.complete
|
|
114
121
|
// =============================================================================
|
|
115
122
|
|
|
116
|
-
export interface LlmCompleteInput extends LlmRequestInput, LlmToolInput {
|
|
117
|
-
/**
|
|
118
|
-
* The keys of the procedures that the model can use as tools, for example `weather.current`.
|
|
119
|
-
* `llm.complete` calls each one through `ctx.client`, sends the result to the model, and asks again.
|
|
120
|
-
*/
|
|
121
|
-
procedures?: string[] | undefined;
|
|
122
|
-
/** The most requests to the model in one call: 1 to 64. The default is 8. */
|
|
123
|
-
maxRounds?: number | undefined;
|
|
124
|
-
}
|
|
123
|
+
export interface LlmCompleteInput extends LlmRequestInput, LlmToolInput {}
|
|
125
124
|
|
|
126
125
|
export interface LlmCompleteOutput {
|
|
127
126
|
/** The text of the last answer: its text blocks, joined. */
|
|
@@ -215,20 +214,57 @@ export interface LlmStreamToolUse {
|
|
|
215
214
|
partialJson?: string | undefined;
|
|
216
215
|
}
|
|
217
216
|
|
|
218
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* The start of a procedure tool: `llm.stream` starts the procedure for a `tool_use` block of the
|
|
219
|
+
* model. Only an input with `procedures` gives this item.
|
|
220
|
+
*/
|
|
221
|
+
export interface LlmStreamToolCall {
|
|
222
|
+
type: "tool_call";
|
|
223
|
+
/** The number of the request whose answer asked for the tool. The first request is 1. */
|
|
224
|
+
round: number;
|
|
225
|
+
/** The ID of the `tool_use` block. */
|
|
226
|
+
id: string;
|
|
227
|
+
/** The name of the tool. */
|
|
228
|
+
name: string;
|
|
229
|
+
/** The key of the procedure, for example `weather.current`. */
|
|
230
|
+
procedure: string;
|
|
231
|
+
/** The input that the model gave. */
|
|
232
|
+
input: unknown;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The end of a procedure tool: its output, or its error. The model gets it as a `tool_result`.
|
|
237
|
+
* Only an input with `procedures` gives this item.
|
|
238
|
+
*/
|
|
239
|
+
export interface LlmStreamToolResult extends LlmToolCall {
|
|
240
|
+
type: "tool_result";
|
|
241
|
+
/** The number of the request whose answer asked for the tool. The first request is 1. */
|
|
242
|
+
round: number;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* The last item of a stream, after the event `message_stop` of the last answer: the stop reason,
|
|
247
|
+
* the usage and the text.
|
|
248
|
+
*/
|
|
219
249
|
export interface LlmStreamStop {
|
|
220
250
|
type: "stop";
|
|
221
|
-
/** The model
|
|
251
|
+
/** The model of the last answer. After a fallback, it is the fallback model. */
|
|
222
252
|
model: string;
|
|
223
|
-
/** Why the model stopped. */
|
|
253
|
+
/** Why the model stopped in the last answer. */
|
|
224
254
|
stopReason: string;
|
|
225
|
-
/** The tokens of the
|
|
255
|
+
/** The tokens of all the requests, added together. */
|
|
226
256
|
usage: LlmUsage;
|
|
227
|
-
/** The text of the
|
|
257
|
+
/** The text of all the answers: all the text deltas, joined. */
|
|
228
258
|
text: string;
|
|
229
|
-
/** The `tool_use` blocks of the answer. */
|
|
259
|
+
/** The `tool_use` blocks of the last answer. No procedure started them. */
|
|
230
260
|
toolUses: LlmToolUse[];
|
|
261
|
+
/** The calls of procedure tools, in their sequence. Only an input with `procedures` gives this field. */
|
|
262
|
+
toolCalls?: LlmToolCall[] | undefined;
|
|
263
|
+
/** The number of requests to the model. Only an input with `procedures` gives this field. */
|
|
264
|
+
rounds?: number | undefined;
|
|
265
|
+
/** True when `maxRounds` stopped the loop before the model stopped. Only an input with `procedures` gives this field. */
|
|
266
|
+
roundLimit?: boolean | undefined;
|
|
231
267
|
}
|
|
232
268
|
|
|
233
269
|
/** One item of `llm.stream`. */
|
|
234
|
-
export type LlmStreamOutput = LlmStreamStart | LlmStreamText | LlmStreamToolUse | LlmStreamStop;
|
|
270
|
+
export type LlmStreamOutput = LlmStreamStart | LlmStreamText | LlmStreamToolUse | LlmStreamToolCall | LlmStreamToolResult | LlmStreamStop;
|