@neutrome/lilsdk 0.4.6 → 0.5.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.
- package/README.md +24 -17
- package/etc/api/index.api.md +96 -103
- package/etc/api/loops.api.md +108 -108
- package/etc/api/managed.api.md +102 -102
- package/etc/api/primitives.api.md +39 -39
- package/etc/api/stream.api.md +46 -55
- package/etc/api/tools.api.md +103 -103
- package/neutrome-lilsdk-0.5.0.tgz +0 -0
- package/package.json +2 -4
- package/src/index.ts +41 -15
- package/src/loops/goal.ts +111 -0
- package/src/loops/index.ts +41 -110
- package/src/loops/shared.ts +27 -0
- package/src/managed/attachment-to-text.ts +35 -11
- package/src/managed/capabilities.ts +42 -22
- package/src/observe.ts +21 -6
- package/src/output.ts +13 -25
- package/src/primitives/index.ts +69 -0
- package/src/stream/index.ts +2 -6
- package/src/stream/stages.ts +15 -11
- package/src/tools-support.ts +9 -3
- package/src/tools.ts +36 -19
- package/src/types.ts +129 -4
- package/test/lilsdk-ts.test.ts +47 -45
- package/test/tools.test.ts +22 -20
- package/etc/api/synthetic.api.md +0 -46
- package/etc/api/types.api.md +0 -103
- package/src/synthetic/index.ts +0 -134
package/test/lilsdk-ts.test.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
appendAssistantMessage,
|
|
3
|
+
appendToolInteraction,
|
|
3
4
|
createProgram,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
viewProgram,
|
|
10
|
-
setModel,
|
|
5
|
+
delta,
|
|
6
|
+
emitProviderRequest,
|
|
7
|
+
emitProviderStreamChunk,
|
|
8
|
+
extractAttachments,
|
|
9
|
+
extractContentText,
|
|
11
10
|
Opcode,
|
|
11
|
+
parseProviderRequest,
|
|
12
|
+
parseProviderStreamChunk,
|
|
13
|
+
ProgramView,
|
|
14
|
+
setModel,
|
|
12
15
|
type Program,
|
|
13
16
|
} from "@neutrome/lil-engine";
|
|
14
17
|
import { describe, expect, it } from "vitest";
|
|
@@ -21,15 +24,7 @@ import {
|
|
|
21
24
|
map,
|
|
22
25
|
reduce,
|
|
23
26
|
} from "../src/primitives/index.ts";
|
|
24
|
-
import {
|
|
25
|
-
appendAssistantMessage,
|
|
26
|
-
appendToolInteraction,
|
|
27
|
-
} from "../src/synthetic/index.ts";
|
|
28
|
-
import {
|
|
29
|
-
observeExecutionStream,
|
|
30
|
-
streamTextResponse,
|
|
31
|
-
writeReasoning,
|
|
32
|
-
} from "../src/stream/index.ts";
|
|
27
|
+
import { observeExecutionStream, writeThinking } from "../src/stream/index.ts";
|
|
33
28
|
import { createGoalExecutor, fallback, retry } from "../src/loops/index.ts";
|
|
34
29
|
import { createAttachmentToTextExecutor } from "../src/managed/attachment-to-text.ts";
|
|
35
30
|
import { createCapabilitiesExecutor } from "../src/managed/capabilities.ts";
|
|
@@ -40,7 +35,8 @@ const decoder = new TextDecoder();
|
|
|
40
35
|
|
|
41
36
|
describe("@neutrome/lilsdk", () => {
|
|
42
37
|
it("leaves capability tool prefixes directly available", async () => {
|
|
43
|
-
const request =
|
|
38
|
+
const request = parseProviderRequest(
|
|
39
|
+
"chat-completions",
|
|
44
40
|
encoder.encode(
|
|
45
41
|
JSON.stringify({
|
|
46
42
|
tools: [
|
|
@@ -61,14 +57,14 @@ describe("@neutrome/lilsdk", () => {
|
|
|
61
57
|
|
|
62
58
|
await executor.execute(request, buildExecutorContext());
|
|
63
59
|
|
|
64
|
-
expect(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
]);
|
|
60
|
+
expect(
|
|
61
|
+
new ProgramView(innerRequest!).tools.map((tool) => tool.name),
|
|
62
|
+
).toEqual(["keep_search", "learn_capability"]);
|
|
68
63
|
});
|
|
69
64
|
|
|
70
65
|
it("describes the latest attachment and removes it before the inner executor", async () => {
|
|
71
|
-
const request =
|
|
66
|
+
const request = parseProviderRequest(
|
|
67
|
+
"chat-completions",
|
|
72
68
|
encoder.encode(
|
|
73
69
|
JSON.stringify({
|
|
74
70
|
messages: [
|
|
@@ -113,9 +109,9 @@ describe("@neutrome/lilsdk", () => {
|
|
|
113
109
|
],
|
|
114
110
|
);
|
|
115
111
|
await executor.execute(request, buildExecutorContext());
|
|
116
|
-
expect(
|
|
112
|
+
expect(extractAttachments(innerRequest!)).toHaveLength(0);
|
|
117
113
|
expect(
|
|
118
|
-
|
|
114
|
+
new ProgramView(innerRequest!).messages.at(-1)?.toolResult?.text,
|
|
119
115
|
).toContain("The original binary media is not present in this context.");
|
|
120
116
|
});
|
|
121
117
|
it("provides clone-safe structural primitives", () => {
|
|
@@ -150,7 +146,8 @@ describe("@neutrome/lilsdk", () => {
|
|
|
150
146
|
it("observes tool-call streams", async () => {
|
|
151
147
|
const observed = await observeExecutionStream(
|
|
152
148
|
(async function* () {
|
|
153
|
-
yield
|
|
149
|
+
yield parseProviderStreamChunk(
|
|
150
|
+
"chat-completions",
|
|
154
151
|
encoder.encode(
|
|
155
152
|
JSON.stringify({
|
|
156
153
|
id: "tool-stream",
|
|
@@ -160,7 +157,8 @@ describe("@neutrome/lilsdk", () => {
|
|
|
160
157
|
}),
|
|
161
158
|
),
|
|
162
159
|
);
|
|
163
|
-
yield
|
|
160
|
+
yield parseProviderStreamChunk(
|
|
161
|
+
"chat-completions",
|
|
164
162
|
encoder.encode(
|
|
165
163
|
JSON.stringify({
|
|
166
164
|
id: "tool-stream",
|
|
@@ -184,7 +182,8 @@ describe("@neutrome/lilsdk", () => {
|
|
|
184
182
|
}),
|
|
185
183
|
),
|
|
186
184
|
);
|
|
187
|
-
yield
|
|
185
|
+
yield parseProviderStreamChunk(
|
|
186
|
+
"chat-completions",
|
|
188
187
|
encoder.encode(
|
|
189
188
|
JSON.stringify({
|
|
190
189
|
id: "tool-stream",
|
|
@@ -203,16 +202,18 @@ describe("@neutrome/lilsdk", () => {
|
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
const parsed = observed.chunks.map((chunk) =>
|
|
206
|
-
JSON.parse(
|
|
205
|
+
JSON.parse(
|
|
206
|
+
decoder.decode(emitProviderStreamChunk("chat-completions", chunk)),
|
|
207
|
+
),
|
|
207
208
|
);
|
|
208
209
|
expect(parsed.some((chunk) => chunk.choices?.[0]?.delta?.tool_calls)).toBe(
|
|
209
210
|
true,
|
|
210
211
|
);
|
|
211
212
|
});
|
|
212
213
|
|
|
213
|
-
|
|
214
214
|
it("appends generic synthetic tool interactions", () => {
|
|
215
|
-
const request =
|
|
215
|
+
const request = parseProviderRequest(
|
|
216
|
+
"chat-completions",
|
|
216
217
|
encoder.encode(
|
|
217
218
|
JSON.stringify({
|
|
218
219
|
model: "virtual-model",
|
|
@@ -228,7 +229,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
228
229
|
result: { status: "active" },
|
|
229
230
|
});
|
|
230
231
|
const emitted = JSON.parse(
|
|
231
|
-
decoder.decode(
|
|
232
|
+
decoder.decode(emitProviderRequest("chat-completions", updated)),
|
|
232
233
|
);
|
|
233
234
|
|
|
234
235
|
expect(emitted.messages[1].tool_calls[0].function).toEqual({
|
|
@@ -242,19 +243,20 @@ describe("@neutrome/lilsdk", () => {
|
|
|
242
243
|
});
|
|
243
244
|
});
|
|
244
245
|
|
|
245
|
-
|
|
246
246
|
it("writes reasoning helpers to a sink", async () => {
|
|
247
247
|
const emitted: string[] = [];
|
|
248
248
|
const sink: OutputSink = {
|
|
249
249
|
write(chunk) {
|
|
250
|
-
emitted.push(
|
|
250
|
+
emitted.push(
|
|
251
|
+
decoder.decode(emitProviderStreamChunk("chat-completions", chunk)),
|
|
252
|
+
);
|
|
251
253
|
},
|
|
252
254
|
close() {
|
|
253
255
|
emitted.push("[DONE]");
|
|
254
256
|
},
|
|
255
257
|
};
|
|
256
258
|
|
|
257
|
-
await
|
|
259
|
+
await writeThinking(sink, "thinking");
|
|
258
260
|
|
|
259
261
|
expect(JSON.parse(emitted[0]!).choices[0].delta.reasoning_content).toBe(
|
|
260
262
|
"thinking",
|
|
@@ -279,7 +281,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
279
281
|
);
|
|
280
282
|
|
|
281
283
|
expect(calls).toBe(2);
|
|
282
|
-
expect(
|
|
284
|
+
expect(extractContentText(result)).toBe("ok");
|
|
283
285
|
});
|
|
284
286
|
|
|
285
287
|
it("falls back to the next executor after failure", async () => {
|
|
@@ -297,7 +299,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
297
299
|
buildExecutorContext(),
|
|
298
300
|
);
|
|
299
301
|
|
|
300
|
-
expect(
|
|
302
|
+
expect(extractContentText(result)).toBe("fallback");
|
|
301
303
|
});
|
|
302
304
|
|
|
303
305
|
it("does not retry a stream after exposing a partial chunk", async () => {
|
|
@@ -358,7 +360,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
358
360
|
),
|
|
359
361
|
),
|
|
360
362
|
satisfied(review) {
|
|
361
|
-
return
|
|
363
|
+
return extractContentText(review) === "pass";
|
|
362
364
|
},
|
|
363
365
|
refine(request) {
|
|
364
366
|
return request;
|
|
@@ -371,7 +373,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
371
373
|
);
|
|
372
374
|
|
|
373
375
|
expect(attempts).toBe(2);
|
|
374
|
-
expect(
|
|
376
|
+
expect(extractContentText(result)).toBe("answer 2");
|
|
375
377
|
});
|
|
376
378
|
|
|
377
379
|
it("streams draft and review passes through each goal iteration", async () => {
|
|
@@ -391,7 +393,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
391
393
|
);
|
|
392
394
|
}),
|
|
393
395
|
satisfied(review) {
|
|
394
|
-
return
|
|
396
|
+
return extractContentText(review) === "pass";
|
|
395
397
|
},
|
|
396
398
|
refine(request) {
|
|
397
399
|
return request;
|
|
@@ -406,7 +408,7 @@ describe("@neutrome/lilsdk", () => {
|
|
|
406
408
|
chunks.push(chunk);
|
|
407
409
|
}
|
|
408
410
|
|
|
409
|
-
expect(chunks.map(
|
|
411
|
+
expect(chunks.map(extractContentText).filter(Boolean)).toEqual([
|
|
410
412
|
"answer 1",
|
|
411
413
|
"retry",
|
|
412
414
|
"answer 2",
|
|
@@ -473,14 +475,14 @@ describe("@neutrome/lilsdk", () => {
|
|
|
473
475
|
let reviewedAnswer = "";
|
|
474
476
|
const executor = createGoalExecutor({
|
|
475
477
|
draft: streamingExecutor(async function* () {
|
|
476
|
-
yield*
|
|
478
|
+
yield* delta.textResponse("answer");
|
|
477
479
|
}),
|
|
478
480
|
review: streamingExecutor(async function* (request) {
|
|
479
|
-
reviewedAnswer =
|
|
480
|
-
yield*
|
|
481
|
+
reviewedAnswer = extractContentText(request);
|
|
482
|
+
yield* delta.textResponse("pass");
|
|
481
483
|
}),
|
|
482
484
|
satisfied(review) {
|
|
483
|
-
return
|
|
485
|
+
return extractContentText(review) === "pass";
|
|
484
486
|
},
|
|
485
487
|
refine(request) {
|
|
486
488
|
return request;
|
package/test/tools.test.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
|
-
callData,
|
|
4
3
|
createProgram,
|
|
4
|
+
extractToolCalls,
|
|
5
5
|
Opcode,
|
|
6
|
+
ProgramView,
|
|
6
7
|
type Instruction,
|
|
7
8
|
type Program,
|
|
8
|
-
viewProgram,
|
|
9
9
|
} from "@neutrome/lil-engine";
|
|
10
|
-
import {
|
|
10
|
+
import { createToolsExecutor } from "../src/tools.ts";
|
|
11
11
|
import type { ExecutorContext, Tool } from "../src/types.ts";
|
|
12
12
|
|
|
13
13
|
function buildToolCallResponse(
|
|
@@ -64,7 +64,7 @@ const calculatorTool: Tool = {
|
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
describe("
|
|
67
|
+
describe("createToolsExecutor", () => {
|
|
68
68
|
it("passes the executor cache to connected tools", async () => {
|
|
69
69
|
let callCount = 0;
|
|
70
70
|
const cache = {
|
|
@@ -83,7 +83,7 @@ describe("connectTools", () => {
|
|
|
83
83
|
return (await ctx.cache.get("tool-key")) ?? "missing";
|
|
84
84
|
},
|
|
85
85
|
};
|
|
86
|
-
const executor =
|
|
86
|
+
const executor = createToolsExecutor("test-model", [tool]);
|
|
87
87
|
const ctx = buildCtx({
|
|
88
88
|
async invoke() {
|
|
89
89
|
callCount += 1;
|
|
@@ -105,7 +105,7 @@ describe("connectTools", () => {
|
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
it("passes through when LLM returns no tool calls", async () => {
|
|
108
|
-
const executor =
|
|
108
|
+
const executor = createToolsExecutor("test-model", [calculatorTool]);
|
|
109
109
|
|
|
110
110
|
const request = createProgram({
|
|
111
111
|
code: [
|
|
@@ -136,7 +136,7 @@ describe("connectTools", () => {
|
|
|
136
136
|
});
|
|
137
137
|
|
|
138
138
|
it("executes connected tool and loops until text response", async () => {
|
|
139
|
-
const executor =
|
|
139
|
+
const executor = createToolsExecutor("test-model", [calculatorTool]);
|
|
140
140
|
|
|
141
141
|
let callCount = 0;
|
|
142
142
|
const request = createProgram({
|
|
@@ -175,7 +175,7 @@ describe("connectTools", () => {
|
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
it("returns malformed connected-tool arguments to the model", async () => {
|
|
178
|
-
const executor =
|
|
178
|
+
const executor = createToolsExecutor("test-model", [calculatorTool]);
|
|
179
179
|
let retryRequest: Program | undefined;
|
|
180
180
|
let invocations = 0;
|
|
181
181
|
const ctx = buildCtx({
|
|
@@ -198,9 +198,11 @@ describe("connectTools", () => {
|
|
|
198
198
|
|
|
199
199
|
expect(invocations).toBe(2);
|
|
200
200
|
expect(
|
|
201
|
-
|
|
202
|
-
).toBe(
|
|
203
|
-
|
|
201
|
+
new ProgramView(retryRequest!).messages.at(-1)?.toolResult?.text,
|
|
202
|
+
).toBe(
|
|
203
|
+
'Tool "calculator" failed: Tool "calculator" received invalid JSON object arguments',
|
|
204
|
+
);
|
|
205
|
+
expect(extractToolCalls(result)).toHaveLength(0);
|
|
204
206
|
});
|
|
205
207
|
|
|
206
208
|
it("returns thrown connected-tool errors to the model", async () => {
|
|
@@ -210,7 +212,7 @@ describe("connectTools", () => {
|
|
|
210
212
|
throw new Error("Calculator service is unavailable");
|
|
211
213
|
},
|
|
212
214
|
};
|
|
213
|
-
const executor =
|
|
215
|
+
const executor = createToolsExecutor("test-model", [failingTool]);
|
|
214
216
|
let retryRequest: Program | undefined;
|
|
215
217
|
let invocations = 0;
|
|
216
218
|
const ctx = buildCtx({
|
|
@@ -233,7 +235,7 @@ describe("connectTools", () => {
|
|
|
233
235
|
|
|
234
236
|
expect(invocations).toBe(2);
|
|
235
237
|
expect(
|
|
236
|
-
|
|
238
|
+
new ProgramView(retryRequest!).messages.at(-1)?.toolResult?.text,
|
|
237
239
|
).toBe('Tool "calculator" failed: Calculator service is unavailable');
|
|
238
240
|
});
|
|
239
241
|
|
|
@@ -249,7 +251,7 @@ describe("connectTools", () => {
|
|
|
249
251
|
return `value_of_${key}`;
|
|
250
252
|
},
|
|
251
253
|
};
|
|
252
|
-
const executor =
|
|
254
|
+
const executor = createToolsExecutor("test-model", [multiTool]);
|
|
253
255
|
|
|
254
256
|
let callCount = 0;
|
|
255
257
|
const request = createProgram();
|
|
@@ -276,7 +278,7 @@ describe("connectTools", () => {
|
|
|
276
278
|
});
|
|
277
279
|
|
|
278
280
|
it("returns immediately when outer (non-connected) tool calls are present", async () => {
|
|
279
|
-
const executor =
|
|
281
|
+
const executor = createToolsExecutor("test-model", [calculatorTool]);
|
|
280
282
|
|
|
281
283
|
const request = createProgram();
|
|
282
284
|
const ctx = buildCtx({
|
|
@@ -298,17 +300,17 @@ describe("connectTools", () => {
|
|
|
298
300
|
return calculatorTool.execute(args, ctx);
|
|
299
301
|
},
|
|
300
302
|
};
|
|
301
|
-
const guardedExecutor =
|
|
303
|
+
const guardedExecutor = createToolsExecutor("test-model", [tool]);
|
|
302
304
|
const result = await guardedExecutor.execute(request, ctx);
|
|
303
305
|
|
|
304
|
-
const calls =
|
|
306
|
+
const calls = extractToolCalls(result);
|
|
305
307
|
expect(calls).toHaveLength(2);
|
|
306
308
|
expect(calls.some((c) => c.name === "external_tool")).toBe(true);
|
|
307
309
|
expect(executions).toBe(0);
|
|
308
310
|
});
|
|
309
311
|
|
|
310
312
|
it("respects maxIterations", async () => {
|
|
311
|
-
const executor =
|
|
313
|
+
const executor = createToolsExecutor("test-model", [calculatorTool], {
|
|
312
314
|
maxIterations: 2,
|
|
313
315
|
});
|
|
314
316
|
|
|
@@ -336,7 +338,7 @@ describe("connectTools", () => {
|
|
|
336
338
|
});
|
|
337
339
|
|
|
338
340
|
it("streams final response after tool loop completes", async () => {
|
|
339
|
-
const executor =
|
|
341
|
+
const executor = createToolsExecutor("test-model", [calculatorTool]);
|
|
340
342
|
|
|
341
343
|
let callCount = 0;
|
|
342
344
|
const request = createProgram();
|
|
@@ -395,7 +397,7 @@ describe("connectTools", () => {
|
|
|
395
397
|
return "4";
|
|
396
398
|
},
|
|
397
399
|
};
|
|
398
|
-
const executor =
|
|
400
|
+
const executor = createToolsExecutor("test-model", [tool]);
|
|
399
401
|
let invocation = 0;
|
|
400
402
|
const ctx = buildCtx({
|
|
401
403
|
async invoke() {
|
package/etc/api/synthetic.api.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
## API Report File for "neutrome"
|
|
2
|
-
|
|
3
|
-
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
|
|
7
|
-
import { Program } from '@neutrome/lil-engine';
|
|
8
|
-
|
|
9
|
-
// @public (undocumented)
|
|
10
|
-
export function appendAssistantMessage(program: Program, text: string): Program;
|
|
11
|
-
|
|
12
|
-
// @public (undocumented)
|
|
13
|
-
export function appendToolInteraction(program: Program, interaction: ToolInteraction): Program;
|
|
14
|
-
|
|
15
|
-
// @public (undocumented)
|
|
16
|
-
export function appendUserMessage(program: Program, text: string): Program;
|
|
17
|
-
|
|
18
|
-
// @public (undocumented)
|
|
19
|
-
export function createModelProgram(model: string): Program;
|
|
20
|
-
|
|
21
|
-
// @public (undocumented)
|
|
22
|
-
export function makeMessage(role: TextMessageRole, text: string): Program;
|
|
23
|
-
|
|
24
|
-
// @public (undocumented)
|
|
25
|
-
export function makeToolCall(name: string, args?: unknown, callId?: string): Program;
|
|
26
|
-
|
|
27
|
-
// @public (undocumented)
|
|
28
|
-
export function makeToolResponse(callId: string, result: unknown): Program;
|
|
29
|
-
|
|
30
|
-
// @public (undocumented)
|
|
31
|
-
export function prependSystemPrompt(program: Program, text: string): Program;
|
|
32
|
-
|
|
33
|
-
// @public (undocumented)
|
|
34
|
-
export type TextMessageRole = "system" | "user" | "assistant";
|
|
35
|
-
|
|
36
|
-
// @public (undocumented)
|
|
37
|
-
export type ToolInteraction = {
|
|
38
|
-
callId: string;
|
|
39
|
-
name: string;
|
|
40
|
-
args?: unknown;
|
|
41
|
-
result: unknown;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// (No @packageDocumentation comment for this package)
|
|
45
|
-
|
|
46
|
-
```
|
package/etc/api/types.api.md
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
## API Report File for "neutrome"
|
|
2
|
-
|
|
3
|
-
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
|
4
|
-
|
|
5
|
-
```ts
|
|
6
|
-
|
|
7
|
-
import type { Program } from '@neutrome/lil-engine';
|
|
8
|
-
|
|
9
|
-
// @public (undocumented)
|
|
10
|
-
type Cache_2 = {
|
|
11
|
-
get(key: string): Promise<string | null>;
|
|
12
|
-
put(key: string, value: string, options?: CachePutOptions): Promise<void>;
|
|
13
|
-
delete(key: string): Promise<void>;
|
|
14
|
-
};
|
|
15
|
-
export { Cache_2 as Cache }
|
|
16
|
-
|
|
17
|
-
// @public (undocumented)
|
|
18
|
-
export type CachePutOptions = {
|
|
19
|
-
expiration?: number;
|
|
20
|
-
expirationTtl?: number;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// @public (undocumented)
|
|
24
|
-
export function createExecutionEvent(input: ExecutionEventInput): ExecutionEvent;
|
|
25
|
-
|
|
26
|
-
// @public (undocumented)
|
|
27
|
-
export type ExecutionEvent = {
|
|
28
|
-
kind: string;
|
|
29
|
-
requestId: string;
|
|
30
|
-
executionId: string;
|
|
31
|
-
timestamp: string;
|
|
32
|
-
parentExecutionId?: string;
|
|
33
|
-
target?: {
|
|
34
|
-
kind: "provider" | "executor";
|
|
35
|
-
id: string;
|
|
36
|
-
};
|
|
37
|
-
errorKind?: string;
|
|
38
|
-
data?: Record<string, unknown>;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// @public (undocumented)
|
|
42
|
-
export type ExecutionEventInput = Omit<ExecutionEvent, "timestamp"> & {
|
|
43
|
-
timestamp?: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// @public (undocumented)
|
|
47
|
-
export type Executor = {
|
|
48
|
-
execute(request: Program, ctx: ExecutorContext): Promise<Program>;
|
|
49
|
-
stream(request: Program, ctx: ExecutorContext): AsyncIterable<Program>;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Warning: (ae-forgotten-export) The symbol "RuntimeContext" needs to be exported by the entry point types.d.ts
|
|
53
|
-
//
|
|
54
|
-
// @public (undocumented)
|
|
55
|
-
export type ExecutorContext = RuntimeContext & {
|
|
56
|
-
requestId: string;
|
|
57
|
-
executionId: string;
|
|
58
|
-
parentExecutionId?: string;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// @public (undocumented)
|
|
62
|
-
export type ExecutorInput = string | Executor;
|
|
63
|
-
|
|
64
|
-
// @public (undocumented)
|
|
65
|
-
export type OutputSink = {
|
|
66
|
-
write(chunk: Program): void | Promise<void>;
|
|
67
|
-
close(): void | Promise<void>;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// @public (undocumented)
|
|
71
|
-
export type ProgramTransform = {
|
|
72
|
-
name: string;
|
|
73
|
-
capabilities: TransformCapability[];
|
|
74
|
-
apply(program: Program, ctx: TransformContext): Program | Promise<Program>;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// @public (undocumented)
|
|
78
|
-
type RuntimeContext = {
|
|
79
|
-
cache: Cache_2;
|
|
80
|
-
invoke(executor: ExecutorInput, request: Program): Promise<Program>;
|
|
81
|
-
invokeStream(executor: ExecutorInput, request: Program): AsyncIterable<Program>;
|
|
82
|
-
observe(event: ExecutionEvent): void;
|
|
83
|
-
signal: AbortSignal;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// @public (undocumented)
|
|
87
|
-
export type Tool = {
|
|
88
|
-
name: string;
|
|
89
|
-
description: string;
|
|
90
|
-
schema: Record<string, unknown>;
|
|
91
|
-
systemPromptFragment?: string;
|
|
92
|
-
execute(args: Record<string, unknown>, ctx: ExecutorContext): Promise<string>;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// @public (undocumented)
|
|
96
|
-
export type TransformCapability = "read_messages" | "write_messages" | "write_config" | "write_tools" | "drop_content" | "provider_extension";
|
|
97
|
-
|
|
98
|
-
// @public (undocumented)
|
|
99
|
-
export type TransformContext = RuntimeContext;
|
|
100
|
-
|
|
101
|
-
// (No @packageDocumentation comment for this package)
|
|
102
|
-
|
|
103
|
-
```
|
package/src/synthetic/index.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addTool,
|
|
3
|
-
appendInstructions,
|
|
4
|
-
createProgram,
|
|
5
|
-
insertBefore,
|
|
6
|
-
messages,
|
|
7
|
-
Opcode,
|
|
8
|
-
setModel,
|
|
9
|
-
type Instruction,
|
|
10
|
-
type Opcode as OpcodeValue,
|
|
11
|
-
type Program,
|
|
12
|
-
} from "@neutrome/lil-engine";
|
|
13
|
-
|
|
14
|
-
const encoder = new TextEncoder();
|
|
15
|
-
|
|
16
|
-
export type TextMessageRole = "system" | "user" | "assistant";
|
|
17
|
-
|
|
18
|
-
export type ToolInteraction = {
|
|
19
|
-
callId: string;
|
|
20
|
-
name: string;
|
|
21
|
-
args?: unknown;
|
|
22
|
-
result: unknown;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export function createModelProgram(model: string): Program {
|
|
26
|
-
return setModel(createProgram(), model);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function makeMessage(role: TextMessageRole, text: string): Program {
|
|
30
|
-
return createProgram({ code: buildMessage(role, text) });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function prependSystemPrompt(program: Program, text: string): Program {
|
|
34
|
-
const systemMessage = buildMessage("system", text);
|
|
35
|
-
const spans = messages(program);
|
|
36
|
-
if (spans.length === 0) {
|
|
37
|
-
return appendInstructions(program, systemMessage);
|
|
38
|
-
}
|
|
39
|
-
const firstSpan = spans[0];
|
|
40
|
-
if (!firstSpan) return appendInstructions(program, systemMessage);
|
|
41
|
-
return insertBefore(program, firstSpan.start, systemMessage);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function appendUserMessage(program: Program, text: string): Program {
|
|
45
|
-
return appendInstructions(program, buildMessage("user", text));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function appendAssistantMessage(
|
|
49
|
-
program: Program,
|
|
50
|
-
text: string,
|
|
51
|
-
): Program {
|
|
52
|
-
return appendInstructions(program, buildMessage("assistant", text));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function makeToolCall(
|
|
56
|
-
name: string,
|
|
57
|
-
args: unknown = {},
|
|
58
|
-
callId: string = crypto.randomUUID(),
|
|
59
|
-
): Program {
|
|
60
|
-
return createProgram({
|
|
61
|
-
code: [
|
|
62
|
-
{ opcode: Opcode.MSG_START, value: { kind: "none" } },
|
|
63
|
-
{ opcode: Opcode.ROLE_AST, value: { kind: "none" } },
|
|
64
|
-
{ opcode: Opcode.CALL_START, value: { kind: "string", value: callId } },
|
|
65
|
-
{ opcode: Opcode.CALL_NAME, value: { kind: "string", value: name } },
|
|
66
|
-
{
|
|
67
|
-
opcode: Opcode.CALL_ARGS,
|
|
68
|
-
value: { kind: "json", value: encodeJson(args) },
|
|
69
|
-
},
|
|
70
|
-
{ opcode: Opcode.CALL_END, value: { kind: "none" } },
|
|
71
|
-
{ opcode: Opcode.MSG_END, value: { kind: "none" } },
|
|
72
|
-
],
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function makeToolResponse(callId: string, result: unknown): Program {
|
|
77
|
-
return createProgram({ code: buildToolResponse(callId, result) });
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function appendToolInteraction(
|
|
81
|
-
program: Program,
|
|
82
|
-
interaction: ToolInteraction,
|
|
83
|
-
): Program {
|
|
84
|
-
return appendInstructions(program, [
|
|
85
|
-
...makeToolCall(
|
|
86
|
-
interaction.name,
|
|
87
|
-
interaction.args ?? {},
|
|
88
|
-
interaction.callId,
|
|
89
|
-
).code,
|
|
90
|
-
...buildToolResponse(interaction.callId, interaction.result),
|
|
91
|
-
]);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function buildMessage(role: TextMessageRole, text: string): Instruction[] {
|
|
95
|
-
return [
|
|
96
|
-
{ opcode: Opcode.MSG_START, value: { kind: "none" } },
|
|
97
|
-
{ opcode: roleOpcode(role), value: { kind: "none" } },
|
|
98
|
-
{ opcode: Opcode.TXT_CHUNK, value: { kind: "string", value: text } },
|
|
99
|
-
{ opcode: Opcode.MSG_END, value: { kind: "none" } },
|
|
100
|
-
];
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function buildToolResponse(callId: string, result: unknown): Instruction[] {
|
|
104
|
-
return [
|
|
105
|
-
{ opcode: Opcode.MSG_START, value: { kind: "none" } },
|
|
106
|
-
{ opcode: Opcode.ROLE_TOOL, value: { kind: "none" } },
|
|
107
|
-
{ opcode: Opcode.RESULT_START, value: { kind: "string", value: callId } },
|
|
108
|
-
{
|
|
109
|
-
opcode: Opcode.RESULT_DATA,
|
|
110
|
-
value: { kind: "string", value: stringifyResult(result) },
|
|
111
|
-
},
|
|
112
|
-
{ opcode: Opcode.RESULT_END, value: { kind: "none" } },
|
|
113
|
-
{ opcode: Opcode.MSG_END, value: { kind: "none" } },
|
|
114
|
-
];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function roleOpcode(role: TextMessageRole): OpcodeValue {
|
|
118
|
-
switch (role) {
|
|
119
|
-
case "system":
|
|
120
|
-
return Opcode.ROLE_SYS;
|
|
121
|
-
case "user":
|
|
122
|
-
return Opcode.ROLE_USR;
|
|
123
|
-
case "assistant":
|
|
124
|
-
return Opcode.ROLE_AST;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function encodeJson(value: unknown): Uint8Array {
|
|
129
|
-
return encoder.encode(JSON.stringify(value));
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function stringifyResult(result: unknown): string {
|
|
133
|
-
return typeof result === "string" ? result : JSON.stringify(result);
|
|
134
|
-
}
|