@neutrome/open-ai-router 0.4.1 → 0.4.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neutrome/open-ai-router",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
@@ -9,7 +9,7 @@
9
9
  "@modelcontextprotocol/sdk": "^1.29.0",
10
10
  "hono": "^4.12.18",
11
11
  "@neutrome/lil-engine": "0.2.1",
12
- "@neutrome/lilsdk-ts": "0.2.4"
12
+ "@neutrome/lilsdk-ts": "0.2.5"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@types/node": "^25.9.3",
@@ -167,6 +167,109 @@ describe("router execution runtime", () => {
167
167
  expect(providerCalls).toEqual(["slwin"]);
168
168
  });
169
169
 
170
+ it("lets transforms invoke and stream nested targets", async () => {
171
+ const providerCalls: string[] = [];
172
+ const finalMarkers: Record<string, string> = {};
173
+ const runtime = createExecutionRuntime({
174
+ providerInvoker: {
175
+ async execute(request, ctx) {
176
+ providerCalls.push(`execute:${ctx.target.model}`);
177
+ if (ctx.target.model === "final") {
178
+ for (const instruction of request.code) {
179
+ if (instruction.opcode === Opcode.SET_META && instruction.value.kind === "key_string") {
180
+ finalMarkers[instruction.value.key] = instruction.value.value;
181
+ }
182
+ }
183
+ }
184
+
185
+ const result = cloneProgram(request);
186
+ result.code.push({
187
+ opcode: Opcode.SET_META,
188
+ value: { kind: "key_string", key: "nested-invoke", value: ctx.target.model },
189
+ });
190
+ return result;
191
+ },
192
+ async *stream(_request, ctx) {
193
+ providerCalls.push(`stream:${ctx.target.model}`);
194
+ yield createProgram({
195
+ code: [{
196
+ opcode: Opcode.STREAM_DELTA,
197
+ value: { kind: "string", value: ctx.target.model },
198
+ }],
199
+ });
200
+ },
201
+ },
202
+ transforms: {
203
+ enrich: {
204
+ name: "enrich",
205
+ capabilities: ["write_messages"],
206
+ async apply(program, ctx) {
207
+ const invoked = await ctx.invoke(createProgram(), {
208
+ target: { kind: "provider", provider: "openrouter", model: "nested-exec" },
209
+ });
210
+ let invokeModel = "";
211
+ for (const instruction of invoked.code) {
212
+ if (
213
+ instruction.opcode === Opcode.SET_META &&
214
+ instruction.value.kind === "key_string" &&
215
+ instruction.value.key === "nested-invoke"
216
+ ) {
217
+ invokeModel = instruction.value.value;
218
+ }
219
+ }
220
+
221
+ let streamModel = "";
222
+ for await (const chunk of ctx.invokeStream(createProgram(), {
223
+ target: { kind: "provider", provider: "openrouter", model: "nested-stream" },
224
+ })) {
225
+ const instruction = chunk.code[0];
226
+ if (
227
+ instruction?.opcode === Opcode.STREAM_DELTA &&
228
+ instruction.value.kind === "string"
229
+ ) {
230
+ streamModel = instruction.value.value;
231
+ }
232
+ }
233
+
234
+ const result = cloneProgram(program);
235
+ result.code.push(
236
+ {
237
+ opcode: Opcode.SET_META,
238
+ value: { kind: "key_string", key: "from-invoke", value: invokeModel },
239
+ },
240
+ {
241
+ opcode: Opcode.SET_META,
242
+ value: { kind: "key_string", key: "from-stream", value: streamModel },
243
+ },
244
+ );
245
+ return result;
246
+ },
247
+ },
248
+ },
249
+ });
250
+
251
+ await runtime.execute(createProgram(), {
252
+ target: {
253
+ kind: "provider",
254
+ provider: "openrouter",
255
+ model: "final",
256
+ transforms: ["enrich"],
257
+ },
258
+ requestId: "req_transform_nested",
259
+ executionId: "exec_transform",
260
+ });
261
+
262
+ expect(providerCalls).toEqual([
263
+ "execute:nested-exec",
264
+ "stream:nested-stream",
265
+ "execute:final",
266
+ ]);
267
+ expect(finalMarkers).toMatchObject({
268
+ "from-invoke": "nested-exec",
269
+ "from-stream": "nested-stream",
270
+ });
271
+ });
272
+
170
273
  it("streams through the provider invoker", async () => {
171
274
  const runtime = createExecutionRuntime({
172
275
  providerInvoker: {
@@ -64,7 +64,7 @@ export function createExecutionRuntime(options: ExecutionRuntimeOptions = {}): E
64
64
  emitSuccess: true,
65
65
  });
66
66
 
67
- const transformed = applyTransforms(
67
+ const transformed = await applyTransforms(
68
68
  request,
69
69
  target,
70
70
  requestId,
@@ -216,7 +216,7 @@ export function createExecutionRuntime(options: ExecutionRuntimeOptions = {}): E
216
216
  emitSuccess: true,
217
217
  });
218
218
 
219
- const transformed = applyTransforms(
219
+ const transformed = await applyTransforms(
220
220
  request,
221
221
  target,
222
222
  requestId,
@@ -377,7 +377,7 @@ export function createExecutionRuntime(options: ExecutionRuntimeOptions = {}): E
377
377
  };
378
378
  }
379
379
 
380
- function applyTransforms(
380
+ async function applyTransforms(
381
381
  program: ReturnType<typeof cloneProgram>,
382
382
  target: ExecutionTarget,
383
383
  requestId: string,
@@ -387,6 +387,13 @@ export function createExecutionRuntime(options: ExecutionRuntimeOptions = {}): E
387
387
  depth: number,
388
388
  ) {
389
389
  let current = cloneProgram(program);
390
+ const transformContext = createExecutionContext(
391
+ requestId,
392
+ executionId,
393
+ parentExecutionId,
394
+ signal,
395
+ depth,
396
+ );
390
397
  for (const transformName of target.transforms ?? []) {
391
398
  const transform = transforms.get(transformName);
392
399
  if (!transform) {
@@ -400,7 +407,7 @@ export function createExecutionRuntime(options: ExecutionRuntimeOptions = {}): E
400
407
  );
401
408
  }
402
409
  try {
403
- current = transform.apply(current, { observe, signal });
410
+ current = await transform.apply(current, transformContext);
404
411
  } catch (error) {
405
412
  throw new ExecutionError(
406
413
  "transform",