@executor-js/execution 0.0.2 → 0.2.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/dist/{chunk-I2D2HTXG.js → chunk-HFQPMM6P.js} +139 -57
- package/dist/chunk-HFQPMM6P.js.map +1 -0
- package/dist/core.js +1 -1
- package/dist/description.d.ts.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.test.d.ts +2 -0
- package/dist/engine.test.d.ts.map +1 -0
- package/dist/index.js +30 -8
- package/dist/index.js.map +1 -1
- package/dist/promise.d.ts.map +1 -1
- package/dist/tool-invoker.d.ts +25 -3
- package/dist/tool-invoker.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-I2D2HTXG.js.map +0 -1
|
@@ -5,27 +5,28 @@ var ExecutionToolError = class extends Data.TaggedError("ExecutionToolError") {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/tool-invoker.ts
|
|
8
|
-
import { Effect } from "effect";
|
|
8
|
+
import { Effect, Match, Option, Predicate } from "effect";
|
|
9
9
|
import * as Cause from "effect/Cause";
|
|
10
10
|
var extractSourceNamespace = (path) => {
|
|
11
11
|
const idx = path.indexOf(".");
|
|
12
12
|
return idx === -1 ? path : path.slice(0, idx);
|
|
13
13
|
};
|
|
14
|
-
var stringifyUnknown = (value) => {
|
|
15
|
-
try {
|
|
16
|
-
return JSON.stringify(value) ?? String(value);
|
|
17
|
-
} catch {
|
|
18
|
-
return String(value);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
14
|
var hasStringMessage = (value) => value !== null && typeof value === "object" && "message" in value && typeof value.message === "string";
|
|
22
15
|
var messageFromErrorLike = (value) => {
|
|
23
|
-
if (
|
|
16
|
+
if (hasStringMessage(value)) {
|
|
24
17
|
return value.message;
|
|
25
18
|
}
|
|
26
19
|
return void 0;
|
|
27
20
|
};
|
|
28
|
-
var renderToolErrorMessage = (error) => messageFromErrorLike(error) ?? (typeof error === "undefined" ? "Tool execution failed" :
|
|
21
|
+
var renderToolErrorMessage = (error) => messageFromErrorLike(error) ?? (typeof error === "undefined" ? "Tool execution failed" : renderUnknownPrimitive(error));
|
|
22
|
+
var renderUnknownPrimitive = (value) => Match.value(value).pipe(
|
|
23
|
+
Match.when(Match.string, (s) => s),
|
|
24
|
+
Match.whenOr(Match.number, Match.boolean, Match.bigint, Match.symbol, (x) => x.toString()),
|
|
25
|
+
Match.option,
|
|
26
|
+
Option.getOrElse(() => "Tool execution failed")
|
|
27
|
+
);
|
|
28
|
+
var isToolResultEnvelope = (value) => value !== null && typeof value === "object" && ("error" in value || "data" in value);
|
|
29
|
+
var hasToolResultError = (value) => value.error !== null && value.error !== void 0;
|
|
29
30
|
var makeExecutorToolInvoker = (executor, options) => ({
|
|
30
31
|
invoke: Effect.fn("mcp.tool.dispatch")(function* ({ path, args }) {
|
|
31
32
|
yield* Effect.annotateCurrentSpan({
|
|
@@ -51,23 +52,35 @@ var makeExecutorToolInvoker = (executor, options) => ({
|
|
|
51
52
|
);
|
|
52
53
|
})
|
|
53
54
|
);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const error = r.error;
|
|
57
|
-
return yield* Effect.fail(
|
|
58
|
-
new ExecutionToolError({
|
|
59
|
-
message: renderToolErrorMessage(error),
|
|
60
|
-
cause: error
|
|
61
|
-
})
|
|
62
|
-
);
|
|
55
|
+
if (!isToolResultEnvelope(result)) {
|
|
56
|
+
return result;
|
|
63
57
|
}
|
|
64
|
-
if (
|
|
65
|
-
return
|
|
58
|
+
if (hasToolResultError(result)) {
|
|
59
|
+
return yield* new ExecutionToolError({
|
|
60
|
+
message: renderToolErrorMessage(result.error),
|
|
61
|
+
cause: result.error
|
|
62
|
+
});
|
|
66
63
|
}
|
|
67
|
-
|
|
64
|
+
if ("data" in result) {
|
|
65
|
+
return result.data;
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
68
|
})
|
|
69
69
|
});
|
|
70
|
-
var isElicitationDeclinedError = (value) => value
|
|
70
|
+
var isElicitationDeclinedError = (value) => Predicate.isTagged(value, "ElicitationDeclinedError") && value !== null && typeof value === "object" && "toolId" in value && typeof value.toolId === "string" && "action" in value && (value.action === "cancel" || value.action === "decline");
|
|
71
|
+
var paginate = (all, offset, limit) => {
|
|
72
|
+
const total = all.length;
|
|
73
|
+
const start = Math.min(Math.max(offset, 0), total);
|
|
74
|
+
const items = all.slice(start, start + limit);
|
|
75
|
+
const consumed = start + items.length;
|
|
76
|
+
const hasMore = consumed < total;
|
|
77
|
+
return {
|
|
78
|
+
items,
|
|
79
|
+
total,
|
|
80
|
+
hasMore,
|
|
81
|
+
nextOffset: hasMore ? consumed : null
|
|
82
|
+
};
|
|
83
|
+
};
|
|
71
84
|
var SEARCH_FIELD_WEIGHTS = {
|
|
72
85
|
path: 12,
|
|
73
86
|
sourceId: 8,
|
|
@@ -189,36 +202,69 @@ var scoreToolMatch = (tool, query) => {
|
|
|
189
202
|
};
|
|
190
203
|
};
|
|
191
204
|
var searchTools = Effect.fn("executor.tools.search")(function* (executor, query, limit = 12, options) {
|
|
205
|
+
const offset = options?.offset ?? 0;
|
|
192
206
|
yield* Effect.annotateCurrentSpan({
|
|
193
207
|
"executor.search.query_length": query.length,
|
|
194
208
|
"executor.search.limit": limit,
|
|
209
|
+
"executor.search.offset": offset,
|
|
195
210
|
...options?.namespace ? { "executor.search.namespace": options.namespace } : {}
|
|
196
211
|
});
|
|
212
|
+
const empty = {
|
|
213
|
+
items: [],
|
|
214
|
+
total: 0,
|
|
215
|
+
hasMore: false,
|
|
216
|
+
nextOffset: null
|
|
217
|
+
};
|
|
197
218
|
if (normalizeSearchText(query).length === 0) {
|
|
198
|
-
return
|
|
219
|
+
return empty;
|
|
199
220
|
}
|
|
200
|
-
const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(
|
|
201
|
-
|
|
221
|
+
const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(
|
|
222
|
+
Effect.mapError(
|
|
223
|
+
(cause) => new ExecutionToolError({
|
|
224
|
+
message: "Failed to list tools for search",
|
|
225
|
+
cause
|
|
226
|
+
})
|
|
227
|
+
)
|
|
228
|
+
);
|
|
229
|
+
const ranked = all.filter((tool) => matchesNamespace(tool, options?.namespace)).map((tool) => scoreToolMatch(tool, query)).filter((tool) => tool !== null).sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));
|
|
230
|
+
const page = paginate(ranked, offset, limit);
|
|
202
231
|
yield* Effect.annotateCurrentSpan({
|
|
203
232
|
"executor.search.candidate_count": all.length,
|
|
204
|
-
"executor.search.
|
|
233
|
+
"executor.search.match_count": ranked.length,
|
|
234
|
+
"executor.search.result_count": page.items.length,
|
|
235
|
+
"executor.search.has_more": page.hasMore
|
|
205
236
|
});
|
|
206
|
-
return
|
|
237
|
+
return page;
|
|
207
238
|
});
|
|
208
239
|
var listExecutorSources = Effect.fn("executor.sources.list")(function* (executor, options) {
|
|
209
240
|
const normalizedQuery = normalizeSearchText(options?.query ?? "");
|
|
210
|
-
const limit = options?.limit ??
|
|
211
|
-
const
|
|
241
|
+
const limit = options?.limit ?? 50;
|
|
242
|
+
const offset = options?.offset ?? 0;
|
|
243
|
+
const sources = yield* executor.sources.list().pipe(
|
|
244
|
+
Effect.mapError(
|
|
245
|
+
(cause) => new ExecutionToolError({
|
|
246
|
+
message: "Failed to list executor sources",
|
|
247
|
+
cause
|
|
248
|
+
})
|
|
249
|
+
)
|
|
250
|
+
);
|
|
212
251
|
const filtered = normalizedQuery.length === 0 ? sources : sources.filter((source) => {
|
|
213
252
|
const haystack = normalizeSearchText([source.id, source.name, source.kind].join(" "));
|
|
214
253
|
return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));
|
|
215
254
|
});
|
|
216
|
-
const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(
|
|
255
|
+
const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(
|
|
256
|
+
Effect.mapError(
|
|
257
|
+
(cause) => new ExecutionToolError({
|
|
258
|
+
message: "Failed to list tools for source counts",
|
|
259
|
+
cause
|
|
260
|
+
})
|
|
261
|
+
)
|
|
262
|
+
);
|
|
217
263
|
const toolCountBySource = /* @__PURE__ */ new Map();
|
|
218
264
|
for (const tool of allTools) {
|
|
219
265
|
toolCountBySource.set(tool.sourceId, (toolCountBySource.get(tool.sourceId) ?? 0) + 1);
|
|
220
266
|
}
|
|
221
|
-
const
|
|
267
|
+
const sortedWithCounts = filtered.map(
|
|
222
268
|
(source) => ({
|
|
223
269
|
id: source.id,
|
|
224
270
|
name: source.name,
|
|
@@ -228,13 +274,15 @@ var listExecutorSources = Effect.fn("executor.sources.list")(function* (executor
|
|
|
228
274
|
canRefresh: source.canRefresh,
|
|
229
275
|
toolCount: toolCountBySource.get(source.id) ?? 0
|
|
230
276
|
})
|
|
231
|
-
);
|
|
232
|
-
const
|
|
277
|
+
).sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id));
|
|
278
|
+
const page = paginate(sortedWithCounts, offset, limit);
|
|
233
279
|
yield* Effect.annotateCurrentSpan({
|
|
234
280
|
"executor.sources.candidate_count": sources.length,
|
|
235
|
-
"executor.sources.
|
|
281
|
+
"executor.sources.match_count": sortedWithCounts.length,
|
|
282
|
+
"executor.sources.result_count": page.items.length,
|
|
283
|
+
"executor.sources.has_more": page.hasMore
|
|
236
284
|
});
|
|
237
|
-
return
|
|
285
|
+
return page;
|
|
238
286
|
});
|
|
239
287
|
var describeTool = Effect.fn("executor.tools.describe")(function* (executor, path) {
|
|
240
288
|
yield* Effect.annotateCurrentSpan({ "mcp.tool.name": path });
|
|
@@ -255,7 +303,11 @@ var describeTool = Effect.fn("executor.tools.describe")(function* (executor, pat
|
|
|
255
303
|
// src/description.ts
|
|
256
304
|
import { Effect as Effect2 } from "effect";
|
|
257
305
|
var buildExecuteDescription = (executor) => Effect2.gen(function* () {
|
|
258
|
-
const sources = yield* executor.sources.list().pipe(
|
|
306
|
+
const sources = yield* executor.sources.list().pipe(
|
|
307
|
+
// oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: ExecutionEngine.getDescription currently exposes no error channel; engine typed-error widening is covered separately
|
|
308
|
+
Effect2.orDie,
|
|
309
|
+
Effect2.withSpan("executor.sources.list")
|
|
310
|
+
);
|
|
259
311
|
const description = yield* Effect2.sync(() => formatDescription(sources)).pipe(
|
|
260
312
|
Effect2.withSpan("schema.compile.description", {
|
|
261
313
|
attributes: { "executor.source_count": sources.length }
|
|
@@ -273,7 +325,7 @@ var formatDescription = (sources) => {
|
|
|
273
325
|
"",
|
|
274
326
|
"## Workflow",
|
|
275
327
|
"",
|
|
276
|
-
'1. `const matches = await tools.search({ query: "<intent + key nouns>", limit: 12 });`',
|
|
328
|
+
'1. `const { items: matches } = await tools.search({ query: "<intent + key nouns>", limit: 12 });`',
|
|
277
329
|
'2. `const path = matches[0]?.path; if (!path) return "No matching tools found.";`',
|
|
278
330
|
"3. `const details = await tools.describe.tool({ path });`",
|
|
279
331
|
"4. Use `details.inputTypeScript` / `details.outputTypeScript` and `details.typeScriptDefinitions` for compact shapes.",
|
|
@@ -282,32 +334,36 @@ var formatDescription = (sources) => {
|
|
|
282
334
|
"",
|
|
283
335
|
"## Rules",
|
|
284
336
|
"",
|
|
285
|
-
"- `tools.search()` returns ranked matches,
|
|
337
|
+
"- `tools.search()` returns paginated, ranked matches: `{ items, total, hasMore, nextOffset }`. Best-first. Use short intent phrases like `github issues`, `repo details`, or `create calendar event`.",
|
|
286
338
|
'- When you already know the namespace, narrow with `tools.search({ namespace: "github", query: "issues" })`.',
|
|
287
|
-
"-
|
|
339
|
+
"- `tools.executor.sources.list()` returns the same paged shape: `{ items: [{ id, toolCount, ... }], total, hasMore, nextOffset }`.",
|
|
340
|
+
"- If `hasMore` is true and you didn't find what you need, fetch the next page: `tools.search({ query, offset: nextOffset, limit })`. Same `offset` parameter on `tools.executor.sources.list({ offset, limit })`.",
|
|
288
341
|
"- Always use the namespace prefix when calling tools: `tools.<namespace>.<tool>(args)`. Example: `tools.home_assistant_rest_api.states.getState(...)` \u2014 not `tools.states.getState(...)`.",
|
|
289
342
|
"- The `tools` object is a lazy proxy \u2014 `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.sources.list()` instead.",
|
|
290
343
|
'- Pass an object to system tools, e.g. `tools.search({ query: "..." })`, `tools.executor.sources.list()`, and `tools.describe.tool({ path })`.',
|
|
291
344
|
"- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`.",
|
|
292
345
|
"- For tools that return large collections (e.g. `getStates`, `getAll`), filter results in code rather than calling per-item tools.",
|
|
293
346
|
"- Do not use `fetch` \u2014 all API calls go through `tools.*`.",
|
|
294
|
-
"- If execution pauses for interaction, resume it with the returned `resumePayload`."
|
|
347
|
+
"- If execution pauses for interaction, resume it with the returned `resumePayload`.",
|
|
348
|
+
"- TypeScript type syntax (`: T`, `as T`, generics, interfaces, type aliases) is stripped before execution \u2014 feel free to write idiomatic TypeScript using the shapes from `tools.describe.tool()`. Decorators and `enum` are not supported."
|
|
295
349
|
];
|
|
296
350
|
if (sources.length > 0) {
|
|
297
351
|
lines.push("");
|
|
298
352
|
lines.push("## Available namespaces");
|
|
299
353
|
lines.push("");
|
|
300
|
-
const sorted = [...sources].sort((a, b) => a.id.localeCompare(b.id));
|
|
354
|
+
const sorted = [...sources].sort((a, b) => a.id.localeCompare(b.id)).slice(0, 50);
|
|
301
355
|
for (const source of sorted) {
|
|
302
|
-
|
|
303
|
-
|
|
356
|
+
lines.push(`- \`${source.id}\``);
|
|
357
|
+
}
|
|
358
|
+
if (sources.length > sorted.length) {
|
|
359
|
+
lines.push(`- ... ${sources.length - sorted.length} more`);
|
|
304
360
|
}
|
|
305
361
|
}
|
|
306
362
|
return lines.join("\n");
|
|
307
363
|
};
|
|
308
364
|
|
|
309
365
|
// src/engine.ts
|
|
310
|
-
import { Deferred, Effect as Effect3, Fiber, Ref } from "effect";
|
|
366
|
+
import { Deferred, Effect as Effect3, Fiber, Predicate as Predicate2, Ref } from "effect";
|
|
311
367
|
var MAX_PREVIEW_CHARS = 3e4;
|
|
312
368
|
var truncate = (value, max) => value.length > max ? `${value.slice(0, max)}
|
|
313
369
|
... [truncated ${value.length - max} chars]` : value;
|
|
@@ -339,7 +395,9 @@ ${logText}`] : []
|
|
|
339
395
|
var formatPausedExecution = (paused) => {
|
|
340
396
|
const req = paused.elicitationContext.request;
|
|
341
397
|
const lines = [`Execution paused: ${req.message}`];
|
|
342
|
-
|
|
398
|
+
const isUrlElicitation = Predicate2.isTagged(req, "UrlElicitation");
|
|
399
|
+
const isFormElicitation = Predicate2.isTagged(req, "FormElicitation");
|
|
400
|
+
if (isUrlElicitation) {
|
|
343
401
|
lines.push(`
|
|
344
402
|
Open this URL in a browser:
|
|
345
403
|
${req.url}`);
|
|
@@ -361,10 +419,10 @@ executionId: ${paused.id}`);
|
|
|
361
419
|
status: "waiting_for_interaction",
|
|
362
420
|
executionId: paused.id,
|
|
363
421
|
interaction: {
|
|
364
|
-
kind:
|
|
422
|
+
kind: isUrlElicitation ? "url" : "form",
|
|
365
423
|
message: req.message,
|
|
366
|
-
...
|
|
367
|
-
...
|
|
424
|
+
...isUrlElicitation ? { url: req.url } : {},
|
|
425
|
+
...isFormElicitation ? { requestedSchema: req.requestedSchema } : {}
|
|
368
426
|
}
|
|
369
427
|
}
|
|
370
428
|
};
|
|
@@ -381,6 +439,17 @@ var readOptionalLimit = (value, toolName) => {
|
|
|
381
439
|
}
|
|
382
440
|
return Math.floor(value);
|
|
383
441
|
};
|
|
442
|
+
var readOptionalOffset = (value, toolName) => {
|
|
443
|
+
if (value === void 0) {
|
|
444
|
+
return 0;
|
|
445
|
+
}
|
|
446
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
447
|
+
return new ExecutionToolError({
|
|
448
|
+
message: `${toolName} offset must be a non-negative number when provided`
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
return Math.floor(value);
|
|
452
|
+
};
|
|
384
453
|
var makeFullInvoker = (executor, invokeOptions) => {
|
|
385
454
|
const base = makeExecutorToolInvoker(executor, { invokeOptions });
|
|
386
455
|
return {
|
|
@@ -389,7 +458,7 @@ var makeFullInvoker = (executor, invokeOptions) => {
|
|
|
389
458
|
if (!isRecord(args)) {
|
|
390
459
|
return Effect3.fail(
|
|
391
460
|
new ExecutionToolError({
|
|
392
|
-
message: "tools.search expects an object: { query?: string; namespace?: string; limit?: number }"
|
|
461
|
+
message: "tools.search expects an object: { query?: string; namespace?: string; limit?: number; offset?: number }"
|
|
393
462
|
})
|
|
394
463
|
);
|
|
395
464
|
}
|
|
@@ -408,11 +477,16 @@ var makeFullInvoker = (executor, invokeOptions) => {
|
|
|
408
477
|
);
|
|
409
478
|
}
|
|
410
479
|
const limit = readOptionalLimit(args.limit, "tools.search");
|
|
411
|
-
if (limit
|
|
480
|
+
if (Predicate2.isTagged(limit, "ExecutionToolError")) {
|
|
412
481
|
return Effect3.fail(limit);
|
|
413
482
|
}
|
|
483
|
+
const offset = readOptionalOffset(args.offset, "tools.search");
|
|
484
|
+
if (Predicate2.isTagged(offset, "ExecutionToolError")) {
|
|
485
|
+
return Effect3.fail(offset);
|
|
486
|
+
}
|
|
414
487
|
return searchTools(executor, args.query ?? "", limit, {
|
|
415
|
-
namespace: args.namespace
|
|
488
|
+
namespace: args.namespace,
|
|
489
|
+
offset
|
|
416
490
|
}).pipe(
|
|
417
491
|
Effect3.withSpan("mcp.tool.dispatch", {
|
|
418
492
|
attributes: { "mcp.tool.name": path, "executor.tool.builtin": true }
|
|
@@ -423,7 +497,7 @@ var makeFullInvoker = (executor, invokeOptions) => {
|
|
|
423
497
|
if (args !== void 0 && !isRecord(args)) {
|
|
424
498
|
return Effect3.fail(
|
|
425
499
|
new ExecutionToolError({
|
|
426
|
-
message: "tools.executor.sources.list expects an object: { query?: string; limit?: number }"
|
|
500
|
+
message: "tools.executor.sources.list expects an object: { query?: string; limit?: number; offset?: number }"
|
|
427
501
|
})
|
|
428
502
|
);
|
|
429
503
|
}
|
|
@@ -438,12 +512,20 @@ var makeFullInvoker = (executor, invokeOptions) => {
|
|
|
438
512
|
isRecord(args) ? args.limit : void 0,
|
|
439
513
|
"tools.executor.sources.list"
|
|
440
514
|
);
|
|
441
|
-
if (limit
|
|
515
|
+
if (Predicate2.isTagged(limit, "ExecutionToolError")) {
|
|
442
516
|
return Effect3.fail(limit);
|
|
443
517
|
}
|
|
518
|
+
const offset = readOptionalOffset(
|
|
519
|
+
isRecord(args) ? args.offset : void 0,
|
|
520
|
+
"tools.executor.sources.list"
|
|
521
|
+
);
|
|
522
|
+
if (Predicate2.isTagged(offset, "ExecutionToolError")) {
|
|
523
|
+
return Effect3.fail(offset);
|
|
524
|
+
}
|
|
444
525
|
return listExecutorSources(executor, {
|
|
445
526
|
query: isRecord(args) && typeof args.query === "string" ? args.query : void 0,
|
|
446
|
-
limit
|
|
527
|
+
limit,
|
|
528
|
+
offset
|
|
447
529
|
}).pipe(
|
|
448
530
|
Effect3.withSpan("mcp.tool.dispatch", {
|
|
449
531
|
attributes: { "mcp.tool.name": path, "executor.tool.builtin": true }
|
|
@@ -486,7 +568,7 @@ var createExecutionEngine = (config) => {
|
|
|
486
568
|
const { executor, codeExecutor } = config;
|
|
487
569
|
const pausedExecutions = /* @__PURE__ */ new Map();
|
|
488
570
|
let nextId = 0;
|
|
489
|
-
const awaitCompletionOrPause = (fiber, pauseSignal) => Effect3.
|
|
571
|
+
const awaitCompletionOrPause = (fiber, pauseSignal) => Effect3.raceFirst(
|
|
490
572
|
Fiber.join(fiber).pipe(
|
|
491
573
|
Effect3.map((result) => ({ status: "completed", result }))
|
|
492
574
|
),
|
|
@@ -567,4 +649,4 @@ export {
|
|
|
567
649
|
formatPausedExecution,
|
|
568
650
|
createExecutionEngine
|
|
569
651
|
};
|
|
570
|
-
//# sourceMappingURL=chunk-
|
|
652
|
+
//# sourceMappingURL=chunk-HFQPMM6P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/tool-invoker.ts","../src/description.ts","../src/engine.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\n\nexport class ExecutionToolError extends Data.TaggedError(\"ExecutionToolError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\n// `CodeExecutionError` lives in `@executor-js/codemode-core` — the `CodeExecutor`\n// interface uses it as the default error channel, so the runtime packages\n// can import the same class directly.\nexport { CodeExecutionError } from \"@executor-js/codemode-core\";\n","import { Effect, Match, Option, Predicate } from \"effect\";\nimport * as Cause from \"effect/Cause\";\nimport type {\n Executor,\n ToolId,\n Tool,\n ToolSchema,\n InvokeOptions,\n Source,\n} from \"@executor-js/sdk/core\";\nimport type { SandboxToolInvoker } from \"@executor-js/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\n/**\n * Extract the source namespace from a tool path. Tool paths look like\n * \"<sourceId>.<op>\" or \"<sourceId>.<group>.<op>\" — we take the first\n * segment as a cheap, non-lookup stand-in for the source id so the span\n * attribute is always populated without hitting `executor.sources.list()`\n * per call.\n */\nconst extractSourceNamespace = (path: string): string => {\n const idx = path.indexOf(\".\");\n return idx === -1 ? path : path.slice(0, idx);\n};\n\nconst hasStringMessage = (value: unknown): value is { readonly message: string } =>\n value !== null &&\n typeof value === \"object\" &&\n \"message\" in value &&\n typeof value.message === \"string\";\n\nconst messageFromErrorLike = (value: unknown): string | undefined => {\n if (hasStringMessage(value)) {\n return value.message;\n }\n return undefined;\n};\n\nconst renderToolErrorMessage = (error: unknown): string =>\n messageFromErrorLike(error) ??\n (typeof error === \"undefined\" ? \"Tool execution failed\" : renderUnknownPrimitive(error));\n\nconst renderUnknownPrimitive = (value: unknown): string =>\n Match.value(value).pipe(\n Match.when(Match.string, (s) => s),\n Match.whenOr(Match.number, Match.boolean, Match.bigint, Match.symbol, (x) => x.toString()),\n Match.option,\n Option.getOrElse(() => \"Tool execution failed\"),\n );\n\ntype ToolResultEnvelope = {\n readonly error?: unknown;\n readonly data?: unknown;\n};\n\nconst isToolResultEnvelope = (value: unknown): value is ToolResultEnvelope =>\n value !== null && typeof value === \"object\" && (\"error\" in value || \"data\" in value);\n\nconst hasToolResultError = (\n value: ToolResultEnvelope,\n): value is ToolResultEnvelope & { readonly error: unknown } =>\n value.error !== null && value.error !== undefined;\n\n/**\n * Bridges QuickJS `tools.someSource.someOp(args)` calls into\n * `executor.tools.invoke(toolId, args)`.\n *\n * Wrapped in `Effect.fn(\"mcp.tool.dispatch\")` so every tool call becomes a\n * span in the Effect tracer. Attributes:\n * - `mcp.tool.name` — full tool path (e.g. \"github.repos.get\")\n * - `mcp.tool.source_id` — first segment of the path (namespace)\n *\n * `mcp.tool.kind` (openapi | mcp | graphql | code) is NOT annotated here\n * because it would require a `sources.list()` lookup on every invocation.\n * Callers that already know the source kind can annotate at their own span.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: Effect.fn(\"mcp.tool.dispatch\")(function* ({ path, args }) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.tool.name\": path,\n \"mcp.tool.source_id\": extractSourceNamespace(path),\n });\n\n const result = yield* executor.tools.invoke(path as ToolId, args, options.invokeOptions).pipe(\n Effect.catchCause((cause): Effect.Effect<never, ExecutionToolError> => {\n const err = cause.reasons.find(Cause.isFailReason)?.error;\n if (!isElicitationDeclinedError(err)) {\n return Effect.fail(\n new ExecutionToolError({\n message: renderToolErrorMessage(err),\n cause: err ?? cause,\n }),\n );\n }\n return Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${err.toolId}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n );\n }),\n );\n if (!isToolResultEnvelope(result)) {\n return result;\n }\n if (hasToolResultError(result)) {\n return yield* new ExecutionToolError({\n message: renderToolErrorMessage(result.error),\n cause: result.error,\n });\n }\n if (\"data\" in result) {\n return result.data;\n }\n return result;\n }),\n});\n\nconst isElicitationDeclinedError = (\n value: unknown,\n): value is {\n readonly _tag: \"ElicitationDeclinedError\";\n readonly toolId: string;\n readonly action: \"cancel\" | \"decline\";\n} =>\n Predicate.isTagged(value, \"ElicitationDeclinedError\") &&\n value !== null &&\n typeof value === \"object\" &&\n \"toolId\" in value &&\n typeof value.toolId === \"string\" &&\n \"action\" in value &&\n (value.action === \"cancel\" || value.action === \"decline\");\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly sourceId: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly kind: string;\n readonly runtime?: boolean;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\n/**\n * Page of results from a list-style discovery tool. Shared by\n * `tools.search` and `tools.executor.sources.list` so the model sees one\n * consistent shape:\n *\n * - `items` — the page (slice).\n * - `total` — count after filtering, before pagination. The model\n * can use this to detect truncation.\n * - `hasMore` — convenience flag for `(offset + items.length) < total`.\n * - `nextOffset` — concrete offset for the next page when `hasMore`,\n * `null` otherwise. Pre-computing it removes a class of\n * off-by-one mistakes when the model paginates.\n */\nexport type PagedResult<T> = {\n readonly items: readonly T[];\n readonly total: number;\n readonly hasMore: boolean;\n readonly nextOffset: number | null;\n};\n\nconst paginate = <T>(all: readonly T[], offset: number, limit: number): PagedResult<T> => {\n const total = all.length;\n const start = Math.min(Math.max(offset, 0), total);\n const items = all.slice(start, start + limit);\n const consumed = start + items.length;\n const hasMore = consumed < total;\n return {\n items,\n total,\n hasMore,\n nextOffset: hasMore ? consumed : null,\n };\n};\n\ntype SearchableTool = Pick<Tool, \"id\" | \"sourceId\" | \"name\" | \"description\">;\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n sourceId: 8,\n name: 10,\n description: 5,\n} as const;\n\nconst normalizeSearchText = (value: string): string =>\n value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_./:-]+/g, \" \")\n .toLowerCase()\n .trim();\n\nconst tokenizeSearchText = (value: string): string[] =>\n normalizeSearchText(value)\n .split(/[^a-z0-9]+/)\n .map((token) => token.trim())\n .filter(Boolean);\n\nconst prepareField = (value?: string): PreparedField => ({\n raw: normalizeSearchText(value ?? \"\"),\n tokens: tokenizeSearchText(value ?? \"\"),\n});\n\nconst scorePreparedField = (\n query: string,\n queryTokens: readonly string[],\n field: PreparedField,\n weight: number,\n): {\n readonly score: number;\n readonly matchedTokens: ReadonlySet<string>;\n readonly exactPhraseMatch: boolean;\n} => {\n if (field.raw.length === 0) {\n return {\n score: 0,\n matchedTokens: new Set<string>(),\n exactPhraseMatch: false,\n };\n }\n\n let score = 0;\n const matchedTokens = new Set<string>();\n const exactPhraseMatch = query.length > 0 && field.raw.includes(query);\n\n if (query.length > 0) {\n if (field.raw === query) {\n score += weight * 14;\n } else if (field.raw.startsWith(query)) {\n score += weight * 9;\n } else if (exactPhraseMatch) {\n score += weight * 6;\n }\n }\n\n for (const token of queryTokens) {\n if (field.tokens.includes(token)) {\n score += weight * 4;\n matchedTokens.add(token);\n continue;\n }\n\n if (\n field.tokens.some((candidate) => candidate.startsWith(token) || token.startsWith(candidate))\n ) {\n score += weight * 2;\n matchedTokens.add(token);\n continue;\n }\n\n if (field.raw.includes(token)) {\n score += weight;\n matchedTokens.add(token);\n }\n }\n\n return {\n score,\n matchedTokens,\n exactPhraseMatch,\n };\n};\n\nconst matchesNamespace = (tool: SearchableTool, namespace?: string): boolean => {\n if (!namespace || normalizeSearchText(namespace).length === 0) {\n return true;\n }\n\n const namespaceTokens = tokenizeSearchText(namespace);\n if (namespaceTokens.length === 0) {\n return true;\n }\n\n const sourceTokens = tokenizeSearchText(tool.sourceId);\n const pathTokens = tokenizeSearchText(tool.id);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(sourceTokens) || isPrefixMatch(pathTokens);\n};\n\nconst scoreToolMatch = (tool: SearchableTool, query: string): ToolDiscoveryResult | null => {\n const normalizedQuery = normalizeSearchText(query);\n const queryTokens = tokenizeSearchText(query);\n\n if (normalizedQuery.length === 0 || queryTokens.length === 0) {\n return null;\n }\n\n const path = prepareField(tool.id);\n const sourceId = prepareField(tool.sourceId);\n const name = prepareField(tool.name);\n const description = prepareField(tool.description);\n\n const fieldScores = [\n scorePreparedField(normalizedQuery, queryTokens, path, SEARCH_FIELD_WEIGHTS.path),\n scorePreparedField(normalizedQuery, queryTokens, sourceId, SEARCH_FIELD_WEIGHTS.sourceId),\n scorePreparedField(normalizedQuery, queryTokens, name, SEARCH_FIELD_WEIGHTS.name),\n scorePreparedField(normalizedQuery, queryTokens, description, SEARCH_FIELD_WEIGHTS.description),\n ];\n\n const matchedTokens = new Set<string>();\n let score = 0;\n let exactPhraseMatch = false;\n\n for (const fieldScore of fieldScores) {\n score += fieldScore.score;\n exactPhraseMatch ||= fieldScore.exactPhraseMatch;\n for (const token of fieldScore.matchedTokens) {\n matchedTokens.add(token);\n }\n }\n\n if (matchedTokens.size === 0) {\n return null;\n }\n\n const coverage = matchedTokens.size / queryTokens.length;\n const minimumCoverage = queryTokens.length <= 2 ? 1 : 0.6;\n\n if (coverage < minimumCoverage && !exactPhraseMatch) {\n return null;\n }\n\n if (coverage === 1) {\n score += 25;\n } else {\n score += Math.round(coverage * 10);\n }\n\n if (path.tokens[0] === queryTokens[0] || name.tokens[0] === queryTokens[0]) {\n score += 8;\n }\n\n if (\n normalizeSearchText(tool.id) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.id,\n name: tool.name,\n description: tool.description,\n sourceId: tool.sourceId,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = Effect.fn(\"executor.tools.search\")(function* (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string; readonly offset?: number },\n) {\n const offset = options?.offset ?? 0;\n yield* Effect.annotateCurrentSpan({\n \"executor.search.query_length\": query.length,\n \"executor.search.limit\": limit,\n \"executor.search.offset\": offset,\n ...(options?.namespace ? { \"executor.search.namespace\": options.namespace } : {}),\n });\n\n const empty: PagedResult<ToolDiscoveryResult> = {\n items: [],\n total: 0,\n hasMore: false,\n nextOffset: null,\n };\n\n if (normalizeSearchText(query).length === 0) {\n return empty;\n }\n\n const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for search\",\n cause,\n }),\n ),\n );\n const ranked = all\n .filter((tool: Tool) => matchesNamespace(tool, options?.namespace))\n .map((tool: Tool) => scoreToolMatch(tool, query))\n .filter((tool): tool is ToolDiscoveryResult => tool !== null)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path));\n\n const page = paginate(ranked, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.search.candidate_count\": all.length,\n \"executor.search.match_count\": ranked.length,\n \"executor.search.result_count\": page.items.length,\n \"executor.search.has_more\": page.hasMore,\n });\n return page;\n});\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. */\nexport const listExecutorSources = Effect.fn(\"executor.sources.list\")(function* (\n executor: Executor,\n options?: {\n readonly query?: string;\n readonly limit?: number;\n readonly offset?: number;\n },\n) {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 50;\n const offset = options?.offset ?? 0;\n const sources = yield* executor.sources.list().pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list executor sources\",\n cause,\n }),\n ),\n );\n\n const filtered =\n normalizedQuery.length === 0\n ? sources\n : sources.filter((source: Source) => {\n const haystack = normalizeSearchText([source.id, source.name, source.kind].join(\" \"));\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per source in memory.\n const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(\n Effect.mapError(\n (cause) =>\n new ExecutionToolError({\n message: \"Failed to list tools for source counts\",\n cause,\n }),\n ),\n );\n const toolCountBySource = new Map<string, number>();\n for (const tool of allTools) {\n toolCountBySource.set(tool.sourceId, (toolCountBySource.get(tool.sourceId) ?? 0) + 1);\n }\n\n const sortedWithCounts = filtered\n .map(\n (source: Source) =>\n ({\n id: source.id,\n name: source.name,\n kind: source.kind,\n runtime: source.runtime,\n canRemove: source.canRemove,\n canRefresh: source.canRefresh,\n toolCount: toolCountBySource.get(source.id) ?? 0,\n }) satisfies ExecutorSourceListItem,\n )\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id));\n\n const page = paginate(sortedWithCounts, offset, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.sources.candidate_count\": sources.length,\n \"executor.sources.match_count\": sortedWithCounts.length,\n \"executor.sources.result_count\": page.items.length,\n \"executor.sources.has_more\": page.hasMore,\n });\n return page;\n});\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = Effect.fn(\"executor.tools.describe\")(function* (\n executor: Executor,\n path: string,\n) {\n yield* Effect.annotateCurrentSpan({ \"mcp.tool.name\": path });\n\n // Single tools.schema() call — it already fetches the tool row\n // internally. No need to also call tools.list() just for name/description.\n const schema: ToolSchema | null = yield* executor.tools.schema(path);\n\n // tools.schema() returns null if the tool doesn't exist. Fall back to\n // a minimal stub so callers can still render something.\n if (schema === null) {\n return { path, name: path };\n }\n\n // The schema's id is the tool path; name/description come from the\n // tool row which tools.schema() already loaded.\n return {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: schema.outputTypeScript,\n typeScriptDefinitions: schema.typeScriptDefinitions,\n };\n});\n","import { Effect } from \"effect\";\nimport type { Executor, Source } from \"@executor-js/sdk/core\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available namespaces (bottom)\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const sources: readonly Source[] = yield* executor.sources.list().pipe(\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: ExecutionEngine.getDescription currently exposes no error channel; engine typed-error widening is covered separately\n Effect.orDie,\n Effect.withSpan(\"executor.sources.list\"),\n );\n\n const description = yield* Effect.sync(() => formatDescription(sources)).pipe(\n Effect.withSpan(\"schema.compile.description\", {\n attributes: { \"executor.source_count\": sources.length },\n }),\n );\n\n yield* Effect.annotateCurrentSpan({\n \"executor.source_count\": sources.length,\n \"schema.kind\": \"execute\",\n });\n\n return description;\n }).pipe(Effect.withSpan(\"schema.describe.execute\"));\n\nconst formatDescription = (sources: readonly Source[]): string => {\n const lines: string[] = [\n \"Execute TypeScript in a sandboxed runtime with access to configured API tools.\",\n \"\",\n \"## Workflow\",\n \"\",\n '1. `const { items: matches } = await tools.search({ query: \"<intent + key nouns>\", limit: 12 });`',\n '2. `const path = matches[0]?.path; if (!path) return \"No matching tools found.\";`',\n \"3. `const details = await tools.describe.tool({ path });`\",\n \"4. Use `details.inputTypeScript` / `details.outputTypeScript` and `details.typeScriptDefinitions` for compact shapes.\",\n \"5. Use `tools.executor.sources.list()` when you need configured source inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns paginated, ranked matches: `{ items, total, hasMore, nextOffset }`. Best-first. Use short intent phrases like `github issues`, `repo details`, or `create calendar event`.\",\n '- When you already know the namespace, narrow with `tools.search({ namespace: \"github\", query: \"issues\" })`.',\n \"- `tools.executor.sources.list()` returns the same paged shape: `{ items: [{ id, toolCount, ... }], total, hasMore, nextOffset }`.\",\n \"- If `hasMore` is true and you didn't find what you need, fetch the next page: `tools.search({ query, offset: nextOffset, limit })`. Same `offset` parameter on `tools.executor.sources.list({ offset, limit })`.\",\n \"- Always use the namespace prefix when calling tools: `tools.<namespace>.<tool>(args)`. Example: `tools.home_assistant_rest_api.states.getState(...)` — not `tools.states.getState(...)`.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.sources.list()` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.sources.list()`, and `tools.describe.tool({ path })`.',\n \"- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`.\",\n \"- For tools that return large collections (e.g. `getStates`, `getAll`), filter results in code rather than calling per-item tools.\",\n \"- Do not use `fetch` — all API calls go through `tools.*`.\",\n \"- If execution pauses for interaction, resume it with the returned `resumePayload`.\",\n \"- TypeScript type syntax (`: T`, `as T`, generics, interfaces, type aliases) is stripped before execution — feel free to write idiomatic TypeScript using the shapes from `tools.describe.tool()`. Decorators and `enum` are not supported.\",\n ];\n\n if (sources.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available namespaces\");\n lines.push(\"\");\n const sorted = [...sources].sort((a, b) => a.id.localeCompare(b.id)).slice(0, 50);\n for (const source of sorted) {\n lines.push(`- \\`${source.id}\\``);\n }\n if (sources.length > sorted.length) {\n lines.push(`- ... ${sources.length - sorted.length} more`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Predicate, Ref } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor-js/sdk/core\";\nimport { CodeExecutionError } from \"@executor-js/codemode-core\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor-js/codemode-core\";\n\nimport {\n makeExecutorToolInvoker,\n searchTools,\n listExecutorSources,\n describeTool,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig<E extends Cause.YieldableError = CodeExecutionError> = {\n readonly executor: Executor;\n readonly codeExecutor: CodeExecutor<E>;\n};\n\nexport type ExecutionResult =\n | { readonly status: \"completed\"; readonly result: ExecuteResult }\n | { readonly status: \"paused\"; readonly execution: PausedExecution };\n\nexport type PausedExecution = {\n readonly id: string;\n readonly elicitationContext: ElicitationContext;\n};\n\n/** Internal representation with Effect runtime state for pause/resume. */\ntype InternalPausedExecution<E> = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, E>;\n readonly pauseSignalRef: Ref.Ref<Deferred.Deferred<InternalPausedExecution<E>>>;\n};\n\nexport type ResumeResponse = {\n readonly action: \"accept\" | \"decline\" | \"cancel\";\n readonly content?: Record<string, unknown>;\n};\n\n// ---------------------------------------------------------------------------\n// Result formatting\n// ---------------------------------------------------------------------------\n\nconst MAX_PREVIEW_CHARS = 30_000;\n\nconst truncate = (value: string, max: number): string =>\n value.length > max\n ? `${value.slice(0, max)}\\n... [truncated ${value.length - max} chars]`\n : value;\n\nexport const formatExecuteResult = (\n result: ExecuteResult,\n): {\n text: string;\n structured: Record<string, unknown>;\n isError: boolean;\n} => {\n const resultText =\n result.result != null\n ? typeof result.result === \"string\"\n ? result.result\n : JSON.stringify(result.result, null, 2)\n : null;\n\n const logText = result.logs && result.logs.length > 0 ? result.logs.join(\"\\n\") : null;\n\n if (result.error) {\n const parts = [`Error: ${result.error}`, ...(logText ? [`\\nLogs:\\n${logText}`] : [])];\n return {\n text: truncate(parts.join(\"\\n\"), MAX_PREVIEW_CHARS),\n structured: { status: \"error\", error: result.error, logs: result.logs ?? [] },\n isError: true,\n };\n }\n\n const parts = [\n ...(resultText ? [truncate(resultText, MAX_PREVIEW_CHARS)] : [\"(no result)\"]),\n ...(logText ? [`\\nLogs:\\n${logText}`] : []),\n ];\n return {\n text: parts.join(\"\\n\"),\n structured: { status: \"completed\", result: result.result ?? null, logs: result.logs ?? [] },\n isError: false,\n };\n};\n\nexport const formatPausedExecution = (\n paused: PausedExecution,\n): {\n text: string;\n structured: Record<string, unknown>;\n} => {\n const req = paused.elicitationContext.request;\n const lines: string[] = [`Execution paused: ${req.message}`];\n const isUrlElicitation = Predicate.isTagged(req, \"UrlElicitation\");\n const isFormElicitation = Predicate.isTagged(req, \"FormElicitation\");\n\n if (isUrlElicitation) {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push(\"\\nAfter the browser flow, resume with the executionId below:\");\n } else {\n lines.push(\"\\nResume with the executionId below and a response matching the requested schema:\");\n const schema = req.requestedSchema;\n if (schema && Object.keys(schema).length > 0) {\n lines.push(`\\nRequested schema:\\n${JSON.stringify(schema, null, 2)}`);\n }\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: isUrlElicitation ? \"url\" : \"form\",\n message: req.message,\n ...(isUrlElicitation ? { url: req.url } : {}),\n ...(isFormElicitation ? { requestedSchema: req.requestedSchema } : {}),\n },\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Full invoker (base + discover + describe)\n// ---------------------------------------------------------------------------\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst readOptionalLimit = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 12;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return new ExecutionToolError({\n message: `${toolName} limit must be a positive number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst readOptionalOffset = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 0;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return new ExecutionToolError({\n message: `${toolName} offset must be a non-negative number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst makeFullInvoker = (executor: Executor, invokeOptions: InvokeOptions): SandboxToolInvoker => {\n const base = makeExecutorToolInvoker(executor, { invokeOptions });\n return {\n invoke: ({ path, args }) => {\n if (path === \"search\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.search expects an object: { query?: string; namespace?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search query must be a string when provided\",\n }),\n );\n }\n\n if (args.namespace !== undefined && typeof args.namespace !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search namespace must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(args.limit, \"tools.search\");\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(args.offset, \"tools.search\");\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return searchTools(executor, args.query ?? \"\", limit, {\n namespace: args.namespace,\n offset,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"executor.sources.list\") {\n if (args !== undefined && !isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.executor.sources.list expects an object: { query?: string; limit?: number; offset?: number }\",\n }),\n );\n }\n\n if (isRecord(args) && args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.executor.sources.list query must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(\n isRecord(args) ? args.limit : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(limit, \"ExecutionToolError\")) {\n return Effect.fail(limit);\n }\n\n const offset = readOptionalOffset(\n isRecord(args) ? args.offset : undefined,\n \"tools.executor.sources.list\",\n );\n if (Predicate.isTagged(offset, \"ExecutionToolError\")) {\n return Effect.fail(offset);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\n offset,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"describe.tool\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool expects an object: { path: string }\",\n }),\n );\n }\n\n if (typeof args.path !== \"string\" || args.path.trim().length === 0) {\n return Effect.fail(new ExecutionToolError({ message: \"describe.tool requires a path\" }));\n }\n\n if (\"includeSchemas\" in args) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool no longer accepts includeSchemas\",\n }),\n );\n }\n\n return describeTool(executor, args.path).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: {\n \"mcp.tool.name\": path,\n \"executor.tool.builtin\": true,\n \"executor.tool.target_path\": args.path,\n },\n }),\n );\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine<E extends Cause.YieldableError = CodeExecutionError> = {\n /**\n * Execute code with elicitation handled inline by the provided handler.\n * Use this when the host supports elicitation (e.g. MCP with elicitation capability).\n *\n * Fails with the code executor's typed error `E` (defaults to\n * `CodeExecutionError`). Runtimes surface their own `Data.TaggedError`\n * subclass, which flows through here unchanged.\n */\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Effect.Effect<ExecuteResult, E>;\n\n /**\n * Execute code, intercepting the first elicitation as a pause point.\n * Use this when the host doesn't support inline elicitation.\n * Returns either a completed result or a paused execution that can be resumed.\n */\n readonly executeWithPause: (code: string) => Effect.Effect<ExecutionResult, E>;\n\n /**\n * Resume a paused execution. Returns a completed result, a new pause, or\n * null if the executionId was not found.\n */\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Effect.Effect<ExecutionResult | null, E>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: Effect.Effect<string>;\n};\n\nexport const createExecutionEngine = <E extends Cause.YieldableError = CodeExecutionError>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine<E> => {\n const { executor, codeExecutor } = config;\n const pausedExecutions = new Map<string, InternalPausedExecution<E>>();\n let nextId = 0;\n\n /**\n * Race a running fiber against a pause signal. Returns when either\n * the fiber completes or an elicitation handler fires (whichever\n * comes first). Re-used by both executeWithPause and resume.\n *\n * `Effect.raceFirst` (not `Effect.race`) — `race` has prefer-success\n * semantics in Effect v4 (\"first successful result\"), which means a\n * fiber failure waits indefinitely for the pause Deferred to succeed.\n * For a fast `codeExecutor.execute` failure (e.g. a syntax error\n * inside the dynamic worker) the pause signal never fires, so the\n * outer Effect hangs until the upstream client gives up. `raceFirst`\n * settles on whichever side completes first, success or failure.\n */\n const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, E>,\n pauseSignal: Deferred.Deferred<InternalPausedExecution<E>>,\n ): Effect.Effect<ExecutionResult, E> =>\n Effect.raceFirst(\n Fiber.join(fiber).pipe(\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Deferred.await(pauseSignal).pipe(\n Effect.map((paused): ExecutionResult => ({ status: \"paused\", execution: paused })),\n ),\n );\n\n /**\n * Start an execution in pause/resume mode.\n *\n * The sandbox is forked as a daemon because paused executions can outlive the\n * caller scope that returned the first pause, such as an HTTP request handler.\n */\n const startPausableExecution = Effect.fn(\"mcp.execute\")(function* (code: string) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"pausable\",\n \"mcp.execute.code_length\": code.length,\n });\n\n // Ref holds the current pause signal. The elicitation handler reads\n // it each time it fires, so resume() can swap in a fresh Deferred\n // before unblocking the fiber.\n const pauseSignalRef = yield* Ref.make(yield* Deferred.make<InternalPausedExecution<E>>());\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, E>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n const id = `exec_${++nextId}`;\n\n const paused: InternalPausedExecution<E> = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseSignalRef,\n };\n pausedExecutions.set(id, paused);\n\n const currentSignal = yield* Ref.get(pauseSignalRef);\n yield* Deferred.succeed(currentSignal, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(executor, { onElicitation: elicitationHandler });\n fiber = yield* Effect.forkDetach(\n codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\")),\n );\n\n const initialSignal = yield* Ref.get(pauseSignalRef);\n return (yield* awaitCompletionOrPause(fiber, initialSignal)) as ExecutionResult;\n });\n\n /**\n * Resume a paused execution. Swaps in a fresh pause signal, completes\n * the response Deferred to unblock the fiber, then races completion\n * against the next pause.\n */\n const resumeExecution = Effect.fn(\"mcp.execute.resume\")(function* (\n executionId: string,\n response: ResumeResponse,\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.resume.action\": response.action,\n });\n\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n // Swap in a fresh pause signal BEFORE unblocking the fiber, so the\n // next elicitation handler call signals this new Deferred.\n const nextSignal = yield* Deferred.make<InternalPausedExecution<E>>();\n yield* Ref.set(paused.pauseSignalRef, nextSignal);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action as typeof ElicitationResponse.Type.action,\n content: response.content,\n });\n\n return (yield* awaitCompletionOrPause(paused.fiber, nextSignal)) as ExecutionResult;\n });\n\n /**\n * Inline-elicitation execute path. Wrapped so every call produces an\n * `mcp.execute` span with the inner `executor.code.exec` as a child.\n */\n const runInlineExecution = Effect.fn(\"mcp.execute\")(function* (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"inline\",\n \"mcp.execute.code_length\": code.length,\n });\n const invoker = makeFullInvoker(executor, {\n onElicitation: options.onElicitation,\n });\n return yield* codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\"));\n });\n\n return {\n execute: runInlineExecution,\n executeWithPause: startPausableExecution,\n resume: resumeExecution,\n getDescription: buildExecuteDescription(executor),\n };\n};\n"],"mappings":"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","names":["Effect","Effect","Predicate","parts","Predicate","Effect"]}
|
package/dist/core.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"description.d.ts","sourceRoot":"","sources":["../src/description.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,QAAQ,EAAU,MAAM,uBAAuB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,QAAQ,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"description.d.ts","sourceRoot":"","sources":["../src/description.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,QAAQ,EAAU,MAAM,uBAAuB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,GAAI,UAAU,QAAQ,KAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAoB5B,CAAC"}
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAyB,MAAM,QAAQ,CAAC;AACjE,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EACV,QAAQ,EAGR,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAsB,MAAM,4BAA4B,CAAC;AAelG,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB,IAAI;IACvF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;CAAE,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CACjD,CAAC;AASF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C,CAAC;AAaF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,aAAa,KACpB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;CA6BlB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,QAAQ,eAAe,KACtB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAiCrC,CAAC;AA0KF,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB,IAAI;IACjF;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAA;KAAE,KACpD,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAErC;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAE/E;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,cAAc,KACrB,MAAM,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IAE9C;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB,EACvF,QAAQ,qBAAqB,CAAC,CAAC,CAAC,KAC/B,eAAe,CAAC,CAAC,CAuInB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../src/engine.test.ts"],"names":[],"mappings":""}
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,15 @@ import {
|
|
|
4
4
|
createExecutionEngine,
|
|
5
5
|
formatExecuteResult,
|
|
6
6
|
formatPausedExecution
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HFQPMM6P.js";
|
|
8
8
|
|
|
9
9
|
// src/promise.ts
|
|
10
10
|
import { Effect } from "effect";
|
|
11
11
|
import { ToolId } from "@executor-js/sdk/core";
|
|
12
|
-
var fromPromise = (try_) =>
|
|
12
|
+
var fromPromise = (try_) => (
|
|
13
|
+
// oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: Promise executor facade has already erased the SDK typed error channel
|
|
14
|
+
Effect.tryPromise({ try: try_, catch: (cause) => cause }).pipe(Effect.orDie)
|
|
15
|
+
);
|
|
13
16
|
var toPromiseInvokeOptions = (options) => {
|
|
14
17
|
const onElicitation = options?.onElicitation;
|
|
15
18
|
if (!onElicitation) return void 0;
|
|
@@ -31,29 +34,45 @@ var wrapPromiseExecutor = (pe) => ({
|
|
|
31
34
|
},
|
|
32
35
|
sources: {
|
|
33
36
|
list: () => fromPromise(() => pe.sources.list()),
|
|
34
|
-
remove: (
|
|
35
|
-
refresh: (
|
|
37
|
+
remove: (input) => fromPromise(() => pe.sources.remove(input)),
|
|
38
|
+
refresh: (input) => fromPromise(() => pe.sources.refresh(input)),
|
|
36
39
|
detect: (url) => fromPromise(() => pe.sources.detect(url)),
|
|
37
40
|
definitions: (id) => fromPromise(() => pe.sources.definitions(id))
|
|
38
41
|
},
|
|
39
42
|
secrets: {
|
|
40
43
|
get: (id) => fromPromise(() => pe.secrets.get(id)),
|
|
44
|
+
getAtScope: (id, scope) => fromPromise(() => pe.secrets.getAtScope(id, scope)),
|
|
41
45
|
status: (id) => fromPromise(() => pe.secrets.status(id)),
|
|
42
46
|
set: (input) => fromPromise(() => pe.secrets.set(input)),
|
|
43
|
-
remove: (
|
|
47
|
+
remove: (input) => fromPromise(() => pe.secrets.remove(input)),
|
|
44
48
|
list: () => fromPromise(() => pe.secrets.list()),
|
|
49
|
+
listAll: () => fromPromise(() => pe.secrets.listAll()),
|
|
50
|
+
usages: (id) => fromPromise(() => pe.secrets.usages(id)),
|
|
45
51
|
providers: () => fromPromise(() => pe.secrets.providers())
|
|
46
52
|
},
|
|
47
53
|
connections: {
|
|
48
54
|
get: (id) => fromPromise(() => pe.connections.get(id)),
|
|
55
|
+
getAtScope: (id, scope) => fromPromise(() => pe.connections.getAtScope(id, scope)),
|
|
49
56
|
list: () => fromPromise(() => pe.connections.list()),
|
|
50
57
|
create: (input) => fromPromise(() => pe.connections.create(input)),
|
|
51
58
|
updateTokens: (input) => fromPromise(() => pe.connections.updateTokens(input)),
|
|
52
59
|
setIdentityLabel: (id, label) => fromPromise(() => pe.connections.setIdentityLabel(id, label)),
|
|
53
60
|
accessToken: (id) => fromPromise(() => pe.connections.accessToken(id)),
|
|
54
|
-
|
|
61
|
+
accessTokenAtScope: (id, scope) => fromPromise(() => pe.connections.accessTokenAtScope(id, scope)),
|
|
62
|
+
remove: (input) => fromPromise(() => pe.connections.remove(input)),
|
|
63
|
+
usages: (id) => fromPromise(() => pe.connections.usages(id)),
|
|
55
64
|
providers: () => fromPromise(() => pe.connections.providers())
|
|
56
65
|
},
|
|
66
|
+
credentialBindings: {
|
|
67
|
+
listForSource: (input) => fromPromise(() => pe.credentialBindings.listForSource(input)),
|
|
68
|
+
resolve: (input) => fromPromise(() => pe.credentialBindings.resolve(input)),
|
|
69
|
+
set: (input) => fromPromise(() => pe.credentialBindings.set(input)),
|
|
70
|
+
remove: (input) => fromPromise(() => pe.credentialBindings.remove(input)),
|
|
71
|
+
replaceForSource: (input) => fromPromise(() => pe.credentialBindings.replaceForSource(input)),
|
|
72
|
+
removeForSource: (input) => fromPromise(() => pe.credentialBindings.removeForSource(input)),
|
|
73
|
+
usagesForSecret: (id) => fromPromise(() => pe.credentialBindings.usagesForSecret(id)),
|
|
74
|
+
usagesForConnection: (id) => fromPromise(() => pe.credentialBindings.usagesForConnection(id))
|
|
75
|
+
},
|
|
57
76
|
oauth: {
|
|
58
77
|
probe: (input) => fromPromise(() => pe.oauth.probe(input)),
|
|
59
78
|
start: (input) => fromPromise(() => pe.oauth.start(input)),
|
|
@@ -64,7 +83,7 @@ var wrapPromiseExecutor = (pe) => ({
|
|
|
64
83
|
list: () => fromPromise(() => pe.policies.list()),
|
|
65
84
|
create: (input) => fromPromise(() => pe.policies.create(input)),
|
|
66
85
|
update: (input) => fromPromise(() => pe.policies.update(input)),
|
|
67
|
-
remove: (
|
|
86
|
+
remove: (input) => fromPromise(() => pe.policies.remove(input)),
|
|
68
87
|
resolve: (id) => fromPromise(() => pe.policies.resolve(id))
|
|
69
88
|
},
|
|
70
89
|
close: () => fromPromise(() => pe.close())
|
|
@@ -72,7 +91,10 @@ var wrapPromiseExecutor = (pe) => ({
|
|
|
72
91
|
var toPromiseExecutionEngine = (engine) => ({
|
|
73
92
|
execute: (code, options) => Effect.runPromise(
|
|
74
93
|
engine.execute(code, {
|
|
75
|
-
onElicitation: (ctx) =>
|
|
94
|
+
onElicitation: (ctx) => (
|
|
95
|
+
// oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: host-provided Promise elicitation callback is outside the Effect error model
|
|
96
|
+
Effect.tryPromise(() => options.onElicitation(ctx)).pipe(Effect.orDie)
|
|
97
|
+
)
|
|
76
98
|
})
|
|
77
99
|
),
|
|
78
100
|
executeWithPause: (code) => Effect.runPromise(engine.executeWithPause(code)),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/promise.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/execution/promise — Promise-native surface for the execution\n// engine.\n// ---------------------------------------------------------------------------\n//\n// `engine.ts` is Effect-native; this module runs each method with\n// `Effect.runPromise` at the boundary so hosts that can't compose Effects\n// (the MCP SDK tool handlers, plain async call sites) can still use the\n// engine. Callers already inside an Effect context should import directly\n// from `@executor-js/execution` to keep trace context intact.\n// ---------------------------------------------------------------------------\n\nimport { Effect } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\n\nimport type {\n ElicitationContext,\n ElicitationResponse,\n Executor as EffectExecutor,\n} from \"@executor-js/sdk/core\";\nimport { ToolId } from \"@executor-js/sdk/core\";\nimport type { Executor as PromiseExecutor } from \"@executor-js/sdk/promise\";\nimport type { CodeExecutionError, CodeExecutor, ExecuteResult } from \"@executor-js/codemode-core\";\n\nimport {\n createExecutionEngine as createEffectExecutionEngine,\n type ExecutionEngine as EffectExecutionEngine,\n type ExecutionResult,\n type PausedExecution,\n type ResumeResponse,\n} from \"./engine\";\n\nexport type ElicitationHandler = (\n ctx: ElicitationContext,\n) => Promise<ElicitationResponse>;\n\nexport type ExecutionEngineConfig<\n E extends Cause.YieldableError = CodeExecutionError,\n> = {\n readonly executor: PromiseExecutor;\n readonly codeExecutor: CodeExecutor<E>;\n};\n\nexport type ExecutionEngine = {\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Promise<ExecuteResult>;\n readonly executeWithPause: (code: string) => Promise<ExecutionResult>;\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Promise<ExecutionResult | null>;\n readonly getDescription: () => Promise<string>;\n};\n\n/**\n * Wrap a Promise-style executor into the Effect shape the engine consumes.\n */\nconst fromPromise = <A>(try_: () => Promise<A>): Effect.Effect<A> =>\n Effect.tryPromise({ try: try_, catch: (cause) => cause }).pipe(Effect.orDie);\n\ntype EffectInvokeOptions = Parameters<EffectExecutor[\"tools\"][\"invoke\"]>[2];\ntype PromiseInvokeOptions = Parameters<PromiseExecutor[\"tools\"][\"invoke\"]>[2];\n\nconst toPromiseInvokeOptions = (\n options: EffectInvokeOptions,\n): PromiseInvokeOptions => {\n const onElicitation = options?.onElicitation;\n if (!onElicitation) return undefined;\n if (onElicitation === \"accept-all\") return { onElicitation };\n\n return {\n onElicitation: (ctx) =>\n onElicitation({\n ...ctx,\n toolId: ToolId.make(ctx.toolId),\n }),\n };\n};\n\nconst wrapPromiseExecutor = (pe: PromiseExecutor): EffectExecutor => ({\n scopes: pe.scopes,\n tools: {\n invoke: (id, args, options) =>\n fromPromise(() => pe.tools.invoke(id, args, toPromiseInvokeOptions(options))),\n list: (filter) => fromPromise(() => pe.tools.list(filter)),\n schema: (id) => fromPromise(() => pe.tools.schema(id)),\n definitions: () => fromPromise(() => pe.tools.definitions()),\n },\n sources: {\n list: () => fromPromise(() => pe.sources.list()),\n remove: (id) => fromPromise(() => pe.sources.remove(id)),\n refresh: (id) => fromPromise(() => pe.sources.refresh(id)),\n detect: (url) => fromPromise(() => pe.sources.detect(url)),\n definitions: (id) => fromPromise(() => pe.sources.definitions(id)),\n },\n secrets: {\n get: (id) => fromPromise(() => pe.secrets.get(id)),\n status: (id) => fromPromise(() => pe.secrets.status(id)),\n set: (input) => fromPromise(() => pe.secrets.set(input)),\n remove: (id) => fromPromise(() => pe.secrets.remove(id)),\n list: () => fromPromise(() => pe.secrets.list()),\n providers: () => fromPromise(() => pe.secrets.providers()),\n },\n connections: {\n get: (id) => fromPromise(() => pe.connections.get(id)),\n list: () => fromPromise(() => pe.connections.list()),\n create: (input) => fromPromise(() => pe.connections.create(input)),\n updateTokens: (input) => fromPromise(() => pe.connections.updateTokens(input)),\n setIdentityLabel: (id, label) => fromPromise(() => pe.connections.setIdentityLabel(id, label)),\n accessToken: (id) => fromPromise(() => pe.connections.accessToken(id)),\n remove: (id) => fromPromise(() => pe.connections.remove(id)),\n providers: () => fromPromise(() => pe.connections.providers()),\n },\n oauth: {\n probe: (input) => fromPromise(() => pe.oauth.probe(input)),\n start: (input) => fromPromise(() => pe.oauth.start(input)),\n complete: (input) => fromPromise(() => pe.oauth.complete(input)),\n cancel: (sessionId, tokenScope) => fromPromise(() => pe.oauth.cancel(sessionId, tokenScope)),\n },\n policies: {\n list: () => fromPromise(() => pe.policies.list()),\n create: (input) => fromPromise(() => pe.policies.create(input)),\n update: (input) => fromPromise(() => pe.policies.update(input)),\n remove: (id) => fromPromise(() => pe.policies.remove(id)),\n resolve: (id) => fromPromise(() => pe.policies.resolve(id)),\n },\n close: () => fromPromise(() => pe.close()),\n});\n\n/**\n * Promise-wrap an Effect-native `ExecutionEngine` (from `./engine`).\n * Exposed separately so callers that already hold an Effect engine\n * (apps/cloud's execution-stack composes both) can convert it for hosts\n * that need the Promise surface (host-mcp).\n */\nexport const toPromiseExecutionEngine = <E extends Cause.YieldableError>(\n engine: EffectExecutionEngine<E>,\n): ExecutionEngine => ({\n execute: (code, options) =>\n Effect.runPromise(\n engine.execute(code, {\n onElicitation: (ctx) =>\n Effect.tryPromise(() => options.onElicitation(ctx)).pipe(Effect.orDie),\n }),\n ),\n executeWithPause: (code) => Effect.runPromise(engine.executeWithPause(code)),\n resume: (executionId, response) => Effect.runPromise(engine.resume(executionId, response)),\n getDescription: () => Effect.runPromise(engine.getDescription),\n});\n\nexport const createExecutionEngine = <\n E extends Cause.YieldableError = CodeExecutionError,\n>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine =>\n toPromiseExecutionEngine(\n createEffectExecutionEngine({\n executor: wrapPromiseExecutor(config.executor),\n codeExecutor: config.codeExecutor,\n }),\n );\n\n// ---------------------------------------------------------------------------\n// Re-exports — plain types/helpers that don't carry Effect signatures.\n// ---------------------------------------------------------------------------\n\nexport { formatExecuteResult, formatPausedExecution } from \"./engine\";\n\nexport type { ExecutionResult, PausedExecution, ResumeResponse };\n\nexport { buildExecuteDescription } from \"./description\";\nexport { ExecutionToolError } from \"./errors\";\n"],"mappings":";;;;;;;;;AAYA,SAAS,cAAc;AAQvB,SAAS,cAAc;AAuCvB,IAAM,cAAc,CAAI,SACtB,OAAO,WAAW,EAAE,KAAK,MAAM,OAAO,CAAC,UAAU,MAAM,CAAC,EAAE,KAAK,OAAO,KAAK;AAK7E,IAAM,yBAAyB,CAC7B,YACyB;AACzB,QAAM,gBAAgB,SAAS;AAC/B,MAAI,CAAC,cAAe,QAAO;AAC3B,MAAI,kBAAkB,aAAc,QAAO,EAAE,cAAc;AAE3D,SAAO;AAAA,IACL,eAAe,CAAC,QACd,cAAc;AAAA,MACZ,GAAG;AAAA,MACH,QAAQ,OAAO,KAAK,IAAI,MAAM;AAAA,IAChC,CAAC;AAAA,EACL;AACF;AAEA,IAAM,sBAAsB,CAAC,QAAyC;AAAA,EACpE,QAAQ,GAAG;AAAA,EACX,OAAO;AAAA,IACL,QAAQ,CAAC,IAAI,MAAM,YACjB,YAAY,MAAM,GAAG,MAAM,OAAO,IAAI,MAAM,uBAAuB,OAAO,CAAC,CAAC;AAAA,IAC9E,MAAM,CAAC,WAAW,YAAY,MAAM,GAAG,MAAM,KAAK,MAAM,CAAC;AAAA,IACzD,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;AAAA,IACrD,aAAa,MAAM,YAAY,MAAM,GAAG,MAAM,YAAY,CAAC;AAAA,EAC7D;AAAA,EACA,SAAS;AAAA,IACP,MAAM,MAAM,YAAY,MAAM,GAAG,QAAQ,KAAK,CAAC;AAAA,IAC/C,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,OAAO,EAAE,CAAC;AAAA,IACvD,SAAS,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACzD,QAAQ,CAAC,QAAQ,YAAY,MAAM,GAAG,QAAQ,OAAO,GAAG,CAAC;AAAA,IACzD,aAAa,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,YAAY,EAAE,CAAC;AAAA,EACnE;AAAA,EACA,SAAS;AAAA,IACP,KAAK,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,IAAI,EAAE,CAAC;AAAA,IACjD,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,OAAO,EAAE,CAAC;AAAA,IACvD,KAAK,CAAC,UAAU,YAAY,MAAM,GAAG,QAAQ,IAAI,KAAK,CAAC;AAAA,IACvD,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,QAAQ,OAAO,EAAE,CAAC;AAAA,IACvD,MAAM,MAAM,YAAY,MAAM,GAAG,QAAQ,KAAK,CAAC;AAAA,IAC/C,WAAW,MAAM,YAAY,MAAM,GAAG,QAAQ,UAAU,CAAC;AAAA,EAC3D;AAAA,EACA,aAAa;AAAA,IACX,KAAK,CAAC,OAAO,YAAY,MAAM,GAAG,YAAY,IAAI,EAAE,CAAC;AAAA,IACrD,MAAM,MAAM,YAAY,MAAM,GAAG,YAAY,KAAK,CAAC;AAAA,IACnD,QAAQ,CAAC,UAAU,YAAY,MAAM,GAAG,YAAY,OAAO,KAAK,CAAC;AAAA,IACjE,cAAc,CAAC,UAAU,YAAY,MAAM,GAAG,YAAY,aAAa,KAAK,CAAC;AAAA,IAC7E,kBAAkB,CAAC,IAAI,UAAU,YAAY,MAAM,GAAG,YAAY,iBAAiB,IAAI,KAAK,CAAC;AAAA,IAC7F,aAAa,CAAC,OAAO,YAAY,MAAM,GAAG,YAAY,YAAY,EAAE,CAAC;AAAA,IACrE,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,YAAY,OAAO,EAAE,CAAC;AAAA,IAC3D,WAAW,MAAM,YAAY,MAAM,GAAG,YAAY,UAAU,CAAC;AAAA,EAC/D;AAAA,EACA,OAAO;AAAA,IACL,OAAO,CAAC,UAAU,YAAY,MAAM,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,IACzD,OAAO,CAAC,UAAU,YAAY,MAAM,GAAG,MAAM,MAAM,KAAK,CAAC;AAAA,IACzD,UAAU,CAAC,UAAU,YAAY,MAAM,GAAG,MAAM,SAAS,KAAK,CAAC;AAAA,IAC/D,QAAQ,CAAC,WAAW,eAAe,YAAY,MAAM,GAAG,MAAM,OAAO,WAAW,UAAU,CAAC;AAAA,EAC7F;AAAA,EACA,UAAU;AAAA,IACR,MAAM,MAAM,YAAY,MAAM,GAAG,SAAS,KAAK,CAAC;AAAA,IAChD,QAAQ,CAAC,UAAU,YAAY,MAAM,GAAG,SAAS,OAAO,KAAK,CAAC;AAAA,IAC9D,QAAQ,CAAC,UAAU,YAAY,MAAM,GAAG,SAAS,OAAO,KAAK,CAAC;AAAA,IAC9D,QAAQ,CAAC,OAAO,YAAY,MAAM,GAAG,SAAS,OAAO,EAAE,CAAC;AAAA,IACxD,SAAS,CAAC,OAAO,YAAY,MAAM,GAAG,SAAS,QAAQ,EAAE,CAAC;AAAA,EAC5D;AAAA,EACA,OAAO,MAAM,YAAY,MAAM,GAAG,MAAM,CAAC;AAC3C;AAQO,IAAM,2BAA2B,CACtC,YACqB;AAAA,EACrB,SAAS,CAAC,MAAM,YACd,OAAO;AAAA,IACL,OAAO,QAAQ,MAAM;AAAA,MACnB,eAAe,CAAC,QACd,OAAO,WAAW,MAAM,QAAQ,cAAc,GAAG,CAAC,EAAE,KAAK,OAAO,KAAK;AAAA,IACzE,CAAC;AAAA,EACH;AAAA,EACF,kBAAkB,CAAC,SAAS,OAAO,WAAW,OAAO,iBAAiB,IAAI,CAAC;AAAA,EAC3E,QAAQ,CAAC,aAAa,aAAa,OAAO,WAAW,OAAO,OAAO,aAAa,QAAQ,CAAC;AAAA,EACzF,gBAAgB,MAAM,OAAO,WAAW,OAAO,cAAc;AAC/D;AAEO,IAAMA,yBAAwB,CAGnC,WAEA;AAAA,EACE,sBAA4B;AAAA,IAC1B,UAAU,oBAAoB,OAAO,QAAQ;AAAA,IAC7C,cAAc,OAAO;AAAA,EACvB,CAAC;AACH;","names":["createExecutionEngine"]}
|
|
1
|
+
{"version":3,"sources":["../src/promise.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/execution/promise — Promise-native surface for the execution\n// engine.\n// ---------------------------------------------------------------------------\n//\n// `engine.ts` is Effect-native; this module runs each method with\n// `Effect.runPromise` at the boundary so hosts that can't compose Effects\n// (the MCP SDK tool handlers, plain async call sites) can still use the\n// engine. Callers already inside an Effect context should import directly\n// from `@executor-js/execution` to keep trace context intact.\n// ---------------------------------------------------------------------------\n\nimport { Effect } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\n\nimport type {\n ElicitationContext,\n ElicitationResponse,\n Executor as EffectExecutor,\n} from \"@executor-js/sdk/core\";\nimport { ToolId } from \"@executor-js/sdk/core\";\nimport type { Executor as PromiseExecutor } from \"@executor-js/sdk/promise\";\nimport type { CodeExecutionError, CodeExecutor, ExecuteResult } from \"@executor-js/codemode-core\";\n\nimport {\n createExecutionEngine as createEffectExecutionEngine,\n type ExecutionEngine as EffectExecutionEngine,\n type ExecutionResult,\n type PausedExecution,\n type ResumeResponse,\n} from \"./engine\";\n\nexport type ElicitationHandler = (ctx: ElicitationContext) => Promise<ElicitationResponse>;\n\nexport type ExecutionEngineConfig<E extends Cause.YieldableError = CodeExecutionError> = {\n readonly executor: PromiseExecutor;\n readonly codeExecutor: CodeExecutor<E>;\n};\n\nexport type ExecutionEngine = {\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Promise<ExecuteResult>;\n readonly executeWithPause: (code: string) => Promise<ExecutionResult>;\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Promise<ExecutionResult | null>;\n readonly getDescription: () => Promise<string>;\n};\n\n/**\n * Wrap a Promise-style executor into the Effect shape the engine consumes.\n */\nconst fromPromise = <A>(try_: () => Promise<A>): Effect.Effect<A> =>\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: Promise executor facade has already erased the SDK typed error channel\n Effect.tryPromise({ try: try_, catch: (cause) => cause }).pipe(Effect.orDie);\n\ntype EffectInvokeOptions = Parameters<EffectExecutor[\"tools\"][\"invoke\"]>[2];\ntype PromiseInvokeOptions = Parameters<PromiseExecutor[\"tools\"][\"invoke\"]>[2];\n\nconst toPromiseInvokeOptions = (options: EffectInvokeOptions): PromiseInvokeOptions => {\n const onElicitation = options?.onElicitation;\n if (!onElicitation) return undefined;\n if (onElicitation === \"accept-all\") return { onElicitation };\n\n return {\n onElicitation: (ctx) =>\n onElicitation({\n ...ctx,\n toolId: ToolId.make(ctx.toolId),\n }),\n };\n};\n\nconst wrapPromiseExecutor = (pe: PromiseExecutor): EffectExecutor => ({\n scopes: pe.scopes,\n tools: {\n invoke: (id, args, options) =>\n fromPromise(() => pe.tools.invoke(id, args, toPromiseInvokeOptions(options))),\n list: (filter) => fromPromise(() => pe.tools.list(filter)),\n schema: (id) => fromPromise(() => pe.tools.schema(id)),\n definitions: () => fromPromise(() => pe.tools.definitions()),\n },\n sources: {\n list: () => fromPromise(() => pe.sources.list()),\n remove: (input) => fromPromise(() => pe.sources.remove(input)),\n refresh: (input) => fromPromise(() => pe.sources.refresh(input)),\n detect: (url) => fromPromise(() => pe.sources.detect(url)),\n definitions: (id) => fromPromise(() => pe.sources.definitions(id)),\n },\n secrets: {\n get: (id) => fromPromise(() => pe.secrets.get(id)),\n getAtScope: (id, scope) => fromPromise(() => pe.secrets.getAtScope(id, scope)),\n status: (id) => fromPromise(() => pe.secrets.status(id)),\n set: (input) => fromPromise(() => pe.secrets.set(input)),\n remove: (input) => fromPromise(() => pe.secrets.remove(input)),\n list: () => fromPromise(() => pe.secrets.list()),\n listAll: () => fromPromise(() => pe.secrets.listAll()),\n usages: (id) => fromPromise(() => pe.secrets.usages(id)),\n providers: () => fromPromise(() => pe.secrets.providers()),\n },\n connections: {\n get: (id) => fromPromise(() => pe.connections.get(id)),\n getAtScope: (id, scope) => fromPromise(() => pe.connections.getAtScope(id, scope)),\n list: () => fromPromise(() => pe.connections.list()),\n create: (input) => fromPromise(() => pe.connections.create(input)),\n updateTokens: (input) => fromPromise(() => pe.connections.updateTokens(input)),\n setIdentityLabel: (id, label) => fromPromise(() => pe.connections.setIdentityLabel(id, label)),\n accessToken: (id) => fromPromise(() => pe.connections.accessToken(id)),\n accessTokenAtScope: (id, scope) =>\n fromPromise(() => pe.connections.accessTokenAtScope(id, scope)),\n remove: (input) => fromPromise(() => pe.connections.remove(input)),\n usages: (id) => fromPromise(() => pe.connections.usages(id)),\n providers: () => fromPromise(() => pe.connections.providers()),\n },\n credentialBindings: {\n listForSource: (input) => fromPromise(() => pe.credentialBindings.listForSource(input)),\n resolve: (input) => fromPromise(() => pe.credentialBindings.resolve(input)),\n set: (input) => fromPromise(() => pe.credentialBindings.set(input)),\n remove: (input) => fromPromise(() => pe.credentialBindings.remove(input)),\n replaceForSource: (input) => fromPromise(() => pe.credentialBindings.replaceForSource(input)),\n removeForSource: (input) => fromPromise(() => pe.credentialBindings.removeForSource(input)),\n usagesForSecret: (id) => fromPromise(() => pe.credentialBindings.usagesForSecret(id)),\n usagesForConnection: (id) => fromPromise(() => pe.credentialBindings.usagesForConnection(id)),\n },\n oauth: {\n probe: (input) => fromPromise(() => pe.oauth.probe(input)),\n start: (input) => fromPromise(() => pe.oauth.start(input)),\n complete: (input) => fromPromise(() => pe.oauth.complete(input)),\n cancel: (sessionId, tokenScope) => fromPromise(() => pe.oauth.cancel(sessionId, tokenScope)),\n },\n policies: {\n list: () => fromPromise(() => pe.policies.list()),\n create: (input) => fromPromise(() => pe.policies.create(input)),\n update: (input) => fromPromise(() => pe.policies.update(input)),\n remove: (input) => fromPromise(() => pe.policies.remove(input)),\n resolve: (id) => fromPromise(() => pe.policies.resolve(id)),\n },\n close: () => fromPromise(() => pe.close()),\n});\n\n/**\n * Promise-wrap an Effect-native `ExecutionEngine` (from `./engine`).\n * Exposed separately so callers that already hold an Effect engine\n * (apps/cloud's execution-stack composes both) can convert it for hosts\n * that need the Promise surface (host-mcp).\n */\nexport const toPromiseExecutionEngine = <E extends Cause.YieldableError>(\n engine: EffectExecutionEngine<E>,\n): ExecutionEngine => ({\n execute: (code, options) =>\n Effect.runPromise(\n engine.execute(code, {\n onElicitation: (ctx) =>\n // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: host-provided Promise elicitation callback is outside the Effect error model\n Effect.tryPromise(() => options.onElicitation(ctx)).pipe(Effect.orDie),\n }),\n ),\n executeWithPause: (code) => Effect.runPromise(engine.executeWithPause(code)),\n resume: (executionId, response) => Effect.runPromise(engine.resume(executionId, response)),\n getDescription: () => Effect.runPromise(engine.getDescription),\n});\n\nexport const createExecutionEngine = <E extends Cause.YieldableError = CodeExecutionError>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine =>\n toPromiseExecutionEngine(\n createEffectExecutionEngine({\n executor: wrapPromiseExecutor(config.executor),\n codeExecutor: config.codeExecutor,\n }),\n );\n\n// ---------------------------------------------------------------------------\n// Re-exports — plain types/helpers that don't carry Effect signatures.\n// ---------------------------------------------------------------------------\n\nexport { formatExecuteResult, formatPausedExecution } from \"./engine\";\n\nexport type { ExecutionResult, PausedExecution, ResumeResponse };\n\nexport { buildExecuteDescription } from \"./description\";\nexport { ExecutionToolError } from \"./errors\";\n"],"mappings":"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","names":["createExecutionEngine"]}
|
package/dist/promise.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAElG,OAAO,EAEL,KAAK,eAAe,IAAI,qBAAqB,EAC7C,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAElG,OAAO,EAEL,KAAK,eAAe,IAAI,qBAAqB,EAC7C,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE3F,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB,IAAI;IACvF,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAA;KAAE,KACpD,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,EAAE,CACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,cAAc,KACrB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAChD,CAAC;AA6FF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,CAAC,SAAS,KAAK,CAAC,cAAc,EACrE,QAAQ,qBAAqB,CAAC,CAAC,CAAC,KAC/B,eAYD,CAAC;AAEH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,KAAK,CAAC,cAAc,GAAG,kBAAkB,EACvF,QAAQ,qBAAqB,CAAC,CAAC,CAAC,KAC/B,eAMA,CAAC;AAMJ,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC;AAEjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/tool-invoker.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type { Executor, InvokeOptions } from "@executor-js/sdk/core";
|
|
3
3
|
import type { SandboxToolInvoker } from "@executor-js/codemode-core";
|
|
4
|
+
import { ExecutionToolError } from "./errors";
|
|
4
5
|
/**
|
|
5
6
|
* Bridges QuickJS `tools.someSource.someOp(args)` calls into
|
|
6
7
|
* `executor.tools.invoke(toolId, args)`.
|
|
@@ -33,15 +34,36 @@ export type ExecutorSourceListItem = {
|
|
|
33
34
|
readonly canRefresh?: boolean;
|
|
34
35
|
readonly toolCount: number;
|
|
35
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Page of results from a list-style discovery tool. Shared by
|
|
39
|
+
* `tools.search` and `tools.executor.sources.list` so the model sees one
|
|
40
|
+
* consistent shape:
|
|
41
|
+
*
|
|
42
|
+
* - `items` — the page (slice).
|
|
43
|
+
* - `total` — count after filtering, before pagination. The model
|
|
44
|
+
* can use this to detect truncation.
|
|
45
|
+
* - `hasMore` — convenience flag for `(offset + items.length) < total`.
|
|
46
|
+
* - `nextOffset` — concrete offset for the next page when `hasMore`,
|
|
47
|
+
* `null` otherwise. Pre-computing it removes a class of
|
|
48
|
+
* off-by-one mistakes when the model paginates.
|
|
49
|
+
*/
|
|
50
|
+
export type PagedResult<T> = {
|
|
51
|
+
readonly items: readonly T[];
|
|
52
|
+
readonly total: number;
|
|
53
|
+
readonly hasMore: boolean;
|
|
54
|
+
readonly nextOffset: number | null;
|
|
55
|
+
};
|
|
36
56
|
/** What `tools.search()` calls inside the sandbox. */
|
|
37
57
|
export declare const searchTools: (executor: Executor, query: string, limit?: any, options?: {
|
|
38
58
|
readonly namespace?: string;
|
|
39
|
-
|
|
59
|
+
readonly offset?: number;
|
|
60
|
+
} | undefined) => Effect.Effect<PagedResult<ToolDiscoveryResult>, ExecutionToolError, never>;
|
|
40
61
|
/** What `tools.executor.sources.list()` calls inside the sandbox. */
|
|
41
62
|
export declare const listExecutorSources: (executor: Executor, options?: {
|
|
42
63
|
readonly query?: string;
|
|
43
64
|
readonly limit?: number;
|
|
44
|
-
|
|
65
|
+
readonly offset?: number;
|
|
66
|
+
} | undefined) => Effect.Effect<PagedResult<{
|
|
45
67
|
id: string;
|
|
46
68
|
name: string;
|
|
47
69
|
kind: string;
|
|
@@ -49,7 +71,7 @@ export declare const listExecutorSources: (executor: Executor, options?: {
|
|
|
49
71
|
canRemove: boolean;
|
|
50
72
|
canRefresh: boolean;
|
|
51
73
|
toolCount: number;
|
|
52
|
-
}
|
|
74
|
+
}>, ExecutionToolError, never>;
|
|
53
75
|
/** What `tools.describe.tool()` calls inside the sandbox. */
|
|
54
76
|
export declare const describeTool: (executor: Executor, path: string) => Effect.Effect<{
|
|
55
77
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-invoker.d.ts","sourceRoot":"","sources":["../src/tool-invoker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"tool-invoker.d.ts","sourceRoot":"","sources":["../src/tool-invoker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA4B,MAAM,QAAQ,CAAC;AAE1D,OAAO,KAAK,EACV,QAAQ,EAIR,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAoD9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,QAAQ,EAClB,SAAS;IAAE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAA;CAAE,KACjD,kBAwCD,CAAC;AAiBH,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC,CAAC;AAoMF,sDAAsD;AACtD,eAAO,MAAM,WAAW;yBAIW,MAAM;sBAAoB,MAAM;4FA6CjE,CAAC;AAEH,qEAAqE;AACrE,eAAO,MAAM,mBAAmB;qBAGX,MAAM;qBACN,MAAM;sBACL,MAAM;;;;;;;;;8BA+D1B,CAAC;AAEH,6DAA6D;AAC7D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;6DA0BvB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executor-js/execution",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"homepage": "https://github.com/RhysSullivan/executor/tree/main/packages/core/execution",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/RhysSullivan/executor/issues"
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"typecheck:slow": "bunx tsc --noEmit -p tsconfig.json"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@executor-js/codemode-core": "0.
|
|
43
|
-
"@executor-js/sdk": "0.
|
|
42
|
+
"@executor-js/codemode-core": "0.2.1",
|
|
43
|
+
"@executor-js/sdk": "0.2.1",
|
|
44
44
|
"effect": "4.0.0-beta.59"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@effect/vitest": "4.0.0-beta.59",
|
|
48
|
-
"@executor-js/runtime-quickjs": "0.
|
|
48
|
+
"@executor-js/runtime-quickjs": "0.2.1",
|
|
49
49
|
"@types/node": "^24.3.1",
|
|
50
50
|
"bun-types": "^1.2.22",
|
|
51
51
|
"tsup": "^8.5.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/tool-invoker.ts","../src/description.ts","../src/engine.ts"],"sourcesContent":["import * as Data from \"effect/Data\";\n\nexport class ExecutionToolError extends Data.TaggedError(\"ExecutionToolError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\n// `CodeExecutionError` lives in `@executor-js/codemode-core` — the `CodeExecutor`\n// interface uses it as the default error channel, so the runtime packages\n// can import the same class directly.\nexport { CodeExecutionError } from \"@executor-js/codemode-core\";\n","import { Effect } from \"effect\";\nimport * as Cause from \"effect/Cause\";\nimport type {\n Executor,\n ToolId,\n Tool,\n ToolSchema,\n InvokeOptions,\n Source,\n} from \"@executor-js/sdk/core\";\nimport type { SandboxToolInvoker } from \"@executor-js/codemode-core\";\nimport { ExecutionToolError } from \"./errors\";\n\n/**\n * Extract the source namespace from a tool path. Tool paths look like\n * \"<sourceId>.<op>\" or \"<sourceId>.<group>.<op>\" — we take the first\n * segment as a cheap, non-lookup stand-in for the source id so the span\n * attribute is always populated without hitting `executor.sources.list()`\n * per call.\n */\nconst extractSourceNamespace = (path: string): string => {\n const idx = path.indexOf(\".\");\n return idx === -1 ? path : path.slice(0, idx);\n};\n\nconst stringifyUnknown = (value: unknown): string => {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n};\n\nconst hasStringMessage = (value: unknown): value is { readonly message: string } =>\n value !== null &&\n typeof value === \"object\" &&\n \"message\" in value &&\n typeof value.message === \"string\";\n\nconst messageFromErrorLike = (value: unknown): string | undefined => {\n if (value instanceof Error || hasStringMessage(value)) {\n return value.message;\n }\n return undefined;\n};\n\nconst renderToolErrorMessage = (error: unknown): string =>\n messageFromErrorLike(error) ??\n (typeof error === \"undefined\" ? \"Tool execution failed\" : stringifyUnknown(error));\n\n/**\n * Bridges QuickJS `tools.someSource.someOp(args)` calls into\n * `executor.tools.invoke(toolId, args)`.\n *\n * Wrapped in `Effect.fn(\"mcp.tool.dispatch\")` so every tool call becomes a\n * span in the Effect tracer. Attributes:\n * - `mcp.tool.name` — full tool path (e.g. \"github.repos.get\")\n * - `mcp.tool.source_id` — first segment of the path (namespace)\n *\n * `mcp.tool.kind` (openapi | mcp | graphql | code) is NOT annotated here\n * because it would require a `sources.list()` lookup on every invocation.\n * Callers that already know the source kind can annotate at their own span.\n */\nexport const makeExecutorToolInvoker = (\n executor: Executor,\n options: { readonly invokeOptions: InvokeOptions },\n): SandboxToolInvoker => ({\n invoke: Effect.fn(\"mcp.tool.dispatch\")(function* ({ path, args }) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.tool.name\": path,\n \"mcp.tool.source_id\": extractSourceNamespace(path),\n });\n\n const result = yield* executor.tools.invoke(path as ToolId, args, options.invokeOptions).pipe(\n Effect.catchCause((cause): Effect.Effect<never, ExecutionToolError> => {\n const err = cause.reasons.find(Cause.isFailReason)?.error;\n if (!isElicitationDeclinedError(err)) {\n return Effect.fail(\n new ExecutionToolError({\n message: renderToolErrorMessage(err),\n cause: err ?? cause,\n }),\n );\n }\n return Effect.fail(\n new ExecutionToolError({\n message: `Tool \"${err.toolId}\" requires approval but the request was ${err.action === \"cancel\" ? \"cancelled\" : \"declined\"} by the user.`,\n cause: err,\n }),\n );\n }),\n );\n const r = result as { readonly error?: unknown; readonly data?: unknown } | unknown;\n if (\n r !== null &&\n typeof r === \"object\" &&\n \"error\" in r &&\n (r as { error?: unknown }).error !== null &&\n (r as { error?: unknown }).error !== undefined\n ) {\n const error = (r as { error: unknown }).error;\n return yield* Effect.fail(\n new ExecutionToolError({\n message: renderToolErrorMessage(error),\n cause: error,\n }),\n );\n }\n if (r !== null && typeof r === \"object\" && \"data\" in r) {\n return (r as { data: unknown }).data;\n }\n return r;\n }),\n});\n\nconst isElicitationDeclinedError = (\n value: unknown,\n): value is { readonly _tag: \"ElicitationDeclinedError\"; readonly toolId: string; readonly action: \"cancel\" | \"decline\" } =>\n value !== null &&\n typeof value === \"object\" &&\n \"_tag\" in value &&\n value._tag === \"ElicitationDeclinedError\" &&\n \"toolId\" in value &&\n typeof value.toolId === \"string\" &&\n \"action\" in value &&\n (value.action === \"cancel\" || value.action === \"decline\");\n\nexport type ToolDiscoveryResult = {\n readonly path: string;\n readonly name: string;\n readonly description?: string;\n readonly sourceId: string;\n readonly score: number;\n};\n\nexport type ExecutorSourceListItem = {\n readonly id: string;\n readonly name: string;\n readonly kind: string;\n readonly runtime?: boolean;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly toolCount: number;\n};\n\ntype SearchableTool = Pick<Tool, \"id\" | \"sourceId\" | \"name\" | \"description\">;\n\ntype PreparedField = {\n readonly raw: string;\n readonly tokens: readonly string[];\n};\n\nconst SEARCH_FIELD_WEIGHTS = {\n path: 12,\n sourceId: 8,\n name: 10,\n description: 5,\n} as const;\n\nconst normalizeSearchText = (value: string): string =>\n value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .replace(/[_./:-]+/g, \" \")\n .toLowerCase()\n .trim();\n\nconst tokenizeSearchText = (value: string): string[] =>\n normalizeSearchText(value)\n .split(/[^a-z0-9]+/)\n .map((token) => token.trim())\n .filter(Boolean);\n\nconst prepareField = (value?: string): PreparedField => ({\n raw: normalizeSearchText(value ?? \"\"),\n tokens: tokenizeSearchText(value ?? \"\"),\n});\n\nconst scorePreparedField = (\n query: string,\n queryTokens: readonly string[],\n field: PreparedField,\n weight: number,\n): {\n readonly score: number;\n readonly matchedTokens: ReadonlySet<string>;\n readonly exactPhraseMatch: boolean;\n} => {\n if (field.raw.length === 0) {\n return {\n score: 0,\n matchedTokens: new Set<string>(),\n exactPhraseMatch: false,\n };\n }\n\n let score = 0;\n const matchedTokens = new Set<string>();\n const exactPhraseMatch = query.length > 0 && field.raw.includes(query);\n\n if (query.length > 0) {\n if (field.raw === query) {\n score += weight * 14;\n } else if (field.raw.startsWith(query)) {\n score += weight * 9;\n } else if (exactPhraseMatch) {\n score += weight * 6;\n }\n }\n\n for (const token of queryTokens) {\n if (field.tokens.includes(token)) {\n score += weight * 4;\n matchedTokens.add(token);\n continue;\n }\n\n if (\n field.tokens.some((candidate) => candidate.startsWith(token) || token.startsWith(candidate))\n ) {\n score += weight * 2;\n matchedTokens.add(token);\n continue;\n }\n\n if (field.raw.includes(token)) {\n score += weight;\n matchedTokens.add(token);\n }\n }\n\n return {\n score,\n matchedTokens,\n exactPhraseMatch,\n };\n};\n\nconst matchesNamespace = (tool: SearchableTool, namespace?: string): boolean => {\n if (!namespace || normalizeSearchText(namespace).length === 0) {\n return true;\n }\n\n const namespaceTokens = tokenizeSearchText(namespace);\n if (namespaceTokens.length === 0) {\n return true;\n }\n\n const sourceTokens = tokenizeSearchText(tool.sourceId);\n const pathTokens = tokenizeSearchText(tool.id);\n\n const isPrefixMatch = (tokens: readonly string[]): boolean =>\n namespaceTokens.every((token, index) => tokens[index] === token);\n\n return isPrefixMatch(sourceTokens) || isPrefixMatch(pathTokens);\n};\n\nconst scoreToolMatch = (tool: SearchableTool, query: string): ToolDiscoveryResult | null => {\n const normalizedQuery = normalizeSearchText(query);\n const queryTokens = tokenizeSearchText(query);\n\n if (normalizedQuery.length === 0 || queryTokens.length === 0) {\n return null;\n }\n\n const path = prepareField(tool.id);\n const sourceId = prepareField(tool.sourceId);\n const name = prepareField(tool.name);\n const description = prepareField(tool.description);\n\n const fieldScores = [\n scorePreparedField(normalizedQuery, queryTokens, path, SEARCH_FIELD_WEIGHTS.path),\n scorePreparedField(normalizedQuery, queryTokens, sourceId, SEARCH_FIELD_WEIGHTS.sourceId),\n scorePreparedField(normalizedQuery, queryTokens, name, SEARCH_FIELD_WEIGHTS.name),\n scorePreparedField(normalizedQuery, queryTokens, description, SEARCH_FIELD_WEIGHTS.description),\n ];\n\n const matchedTokens = new Set<string>();\n let score = 0;\n let exactPhraseMatch = false;\n\n for (const fieldScore of fieldScores) {\n score += fieldScore.score;\n exactPhraseMatch ||= fieldScore.exactPhraseMatch;\n for (const token of fieldScore.matchedTokens) {\n matchedTokens.add(token);\n }\n }\n\n if (matchedTokens.size === 0) {\n return null;\n }\n\n const coverage = matchedTokens.size / queryTokens.length;\n const minimumCoverage = queryTokens.length <= 2 ? 1 : 0.6;\n\n if (coverage < minimumCoverage && !exactPhraseMatch) {\n return null;\n }\n\n if (coverage === 1) {\n score += 25;\n } else {\n score += Math.round(coverage * 10);\n }\n\n if (path.tokens[0] === queryTokens[0] || name.tokens[0] === queryTokens[0]) {\n score += 8;\n }\n\n if (\n normalizeSearchText(tool.id) === normalizedQuery ||\n normalizeSearchText(tool.name) === normalizedQuery\n ) {\n score += 20;\n }\n\n return {\n path: tool.id,\n name: tool.name,\n description: tool.description,\n sourceId: tool.sourceId,\n score,\n };\n};\n\n/** What `tools.search()` calls inside the sandbox. */\nexport const searchTools = Effect.fn(\"executor.tools.search\")(function* (\n executor: Executor,\n query: string,\n limit = 12,\n options?: { readonly namespace?: string },\n) {\n yield* Effect.annotateCurrentSpan({\n \"executor.search.query_length\": query.length,\n \"executor.search.limit\": limit,\n ...(options?.namespace ? { \"executor.search.namespace\": options.namespace } : {}),\n });\n\n if (normalizeSearchText(query).length === 0) {\n return [] as ReadonlyArray<ToolDiscoveryResult>;\n }\n\n const all = yield* executor.tools.list({ includeAnnotations: false }).pipe(Effect.orDie);\n const results = all\n .filter((tool: Tool) => matchesNamespace(tool, options?.namespace))\n .map((tool: Tool) => scoreToolMatch(tool, query))\n .filter((tool): tool is ToolDiscoveryResult => tool !== null)\n .sort((left, right) => right.score - left.score || left.path.localeCompare(right.path))\n .slice(0, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.search.candidate_count\": all.length,\n \"executor.search.result_count\": results.length,\n });\n return results;\n});\n\n/** What `tools.executor.sources.list()` calls inside the sandbox. */\nexport const listExecutorSources = Effect.fn(\"executor.sources.list\")(function* (\n executor: Executor,\n options?: { readonly query?: string; readonly limit?: number },\n) {\n const normalizedQuery = normalizeSearchText(options?.query ?? \"\");\n const limit = options?.limit ?? 200;\n const sources = yield* executor.sources.list().pipe(Effect.orDie);\n\n const filtered =\n normalizedQuery.length === 0\n ? sources\n : sources.filter((source: Source) => {\n const haystack = normalizeSearchText([source.id, source.name, source.kind].join(\" \"));\n return tokenizeSearchText(normalizedQuery).every((token) => haystack.includes(token));\n });\n\n // Single query for all tools, then count per source in memory.\n const allTools = yield* executor.tools.list({ includeAnnotations: false }).pipe(Effect.orDie);\n const toolCountBySource = new Map<string, number>();\n for (const tool of allTools) {\n toolCountBySource.set(tool.sourceId, (toolCountBySource.get(tool.sourceId) ?? 0) + 1);\n }\n\n const withCounts = filtered.map(\n (source: Source) =>\n ({\n id: source.id,\n name: source.name,\n kind: source.kind,\n runtime: source.runtime,\n canRemove: source.canRemove,\n canRefresh: source.canRefresh,\n toolCount: toolCountBySource.get(source.id) ?? 0,\n }) satisfies ExecutorSourceListItem,\n );\n\n const results = withCounts\n .sort((left, right) => left.name.localeCompare(right.name) || left.id.localeCompare(right.id))\n .slice(0, limit);\n\n yield* Effect.annotateCurrentSpan({\n \"executor.sources.candidate_count\": sources.length,\n \"executor.sources.result_count\": results.length,\n });\n return results;\n});\n\n/** What `tools.describe.tool()` calls inside the sandbox. */\nexport const describeTool = Effect.fn(\"executor.tools.describe\")(function* (\n executor: Executor,\n path: string,\n) {\n yield* Effect.annotateCurrentSpan({ \"mcp.tool.name\": path });\n\n // Single tools.schema() call — it already fetches the tool row\n // internally. No need to also call tools.list() just for name/description.\n const schema: ToolSchema | null = yield* executor.tools.schema(path);\n\n // tools.schema() returns null if the tool doesn't exist. Fall back to\n // a minimal stub so callers can still render something.\n if (schema === null) {\n return { path, name: path };\n }\n\n // The schema's id is the tool path; name/description come from the\n // tool row which tools.schema() already loaded.\n return {\n path,\n name: schema.name ?? path,\n description: schema.description,\n inputTypeScript: schema.inputTypeScript,\n outputTypeScript: schema.outputTypeScript,\n typeScriptDefinitions: schema.typeScriptDefinitions,\n };\n});\n","import { Effect } from \"effect\";\nimport type { Executor, Source } from \"@executor-js/sdk/core\";\n\n/**\n * Builds a tool description dynamically.\n *\n * Structure:\n * 1. Workflow (top — critical, least likely to be truncated)\n * 2. Available namespaces (bottom)\n */\nexport const buildExecuteDescription = (executor: Executor): Effect.Effect<string> =>\n Effect.gen(function* () {\n const sources: readonly Source[] = yield* executor.sources\n .list()\n .pipe(Effect.orDie, Effect.withSpan(\"executor.sources.list\"));\n\n const description = yield* Effect.sync(() => formatDescription(sources)).pipe(\n Effect.withSpan(\"schema.compile.description\", {\n attributes: { \"executor.source_count\": sources.length },\n }),\n );\n\n yield* Effect.annotateCurrentSpan({\n \"executor.source_count\": sources.length,\n \"schema.kind\": \"execute\",\n });\n\n return description;\n }).pipe(Effect.withSpan(\"schema.describe.execute\"));\n\nconst formatDescription = (sources: readonly Source[]): string => {\n const lines: string[] = [\n \"Execute TypeScript in a sandboxed runtime with access to configured API tools.\",\n \"\",\n \"## Workflow\",\n \"\",\n '1. `const matches = await tools.search({ query: \"<intent + key nouns>\", limit: 12 });`',\n '2. `const path = matches[0]?.path; if (!path) return \"No matching tools found.\";`',\n \"3. `const details = await tools.describe.tool({ path });`\",\n \"4. Use `details.inputTypeScript` / `details.outputTypeScript` and `details.typeScriptDefinitions` for compact shapes.\",\n \"5. Use `tools.executor.sources.list()` when you need configured source inventory.\",\n \"6. Call the tool: `const result = await tools.<path>(input);`\",\n \"\",\n \"## Rules\",\n \"\",\n \"- `tools.search()` returns ranked matches, best-first. Use short intent phrases like `github issues`, `repo details`, or `create calendar event`.\",\n '- When you already know the namespace, narrow with `tools.search({ namespace: \"github\", query: \"issues\" })`.',\n \"- Use `tools.executor.sources.list()` to inspect configured sources and their tool counts. Returns `[{ id, toolCount, ... }]`.\",\n \"- Always use the namespace prefix when calling tools: `tools.<namespace>.<tool>(args)`. Example: `tools.home_assistant_rest_api.states.getState(...)` — not `tools.states.getState(...)`.\",\n \"- The `tools` object is a lazy proxy — `Object.keys(tools)` won't work. Use `tools.search()` or `tools.executor.sources.list()` instead.\",\n '- Pass an object to system tools, e.g. `tools.search({ query: \"...\" })`, `tools.executor.sources.list()`, and `tools.describe.tool({ path })`.',\n \"- `tools.describe.tool()` returns compact TypeScript shapes. Use `inputTypeScript`, `outputTypeScript`, and `typeScriptDefinitions`.\",\n \"- For tools that return large collections (e.g. `getStates`, `getAll`), filter results in code rather than calling per-item tools.\",\n \"- Do not use `fetch` — all API calls go through `tools.*`.\",\n \"- If execution pauses for interaction, resume it with the returned `resumePayload`.\",\n ];\n\n if (sources.length > 0) {\n lines.push(\"\");\n lines.push(\"## Available namespaces\");\n lines.push(\"\");\n const sorted = [...sources].sort((a, b) => a.id.localeCompare(b.id));\n for (const source of sorted) {\n const label = source.name;\n lines.push(`- \\`${source.id}\\`${label !== source.id ? ` — ${label}` : \"\"}`);\n }\n }\n\n return lines.join(\"\\n\");\n};\n","import { Deferred, Effect, Fiber, Ref } from \"effect\";\nimport type * as Cause from \"effect/Cause\";\n\nimport type {\n Executor,\n InvokeOptions,\n ElicitationResponse,\n ElicitationHandler,\n ElicitationContext,\n} from \"@executor-js/sdk/core\";\nimport { CodeExecutionError } from \"@executor-js/codemode-core\";\nimport type { CodeExecutor, ExecuteResult, SandboxToolInvoker } from \"@executor-js/codemode-core\";\n\nimport {\n makeExecutorToolInvoker,\n searchTools,\n listExecutorSources,\n describeTool,\n} from \"./tool-invoker\";\nimport { ExecutionToolError } from \"./errors\";\nimport { buildExecuteDescription } from \"./description\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngineConfig<\n E extends Cause.YieldableError = CodeExecutionError,\n> = {\n readonly executor: Executor;\n readonly codeExecutor: CodeExecutor<E>;\n};\n\nexport type ExecutionResult =\n | { readonly status: \"completed\"; readonly result: ExecuteResult }\n | { readonly status: \"paused\"; readonly execution: PausedExecution };\n\nexport type PausedExecution = {\n readonly id: string;\n readonly elicitationContext: ElicitationContext;\n};\n\n/** Internal representation with Effect runtime state for pause/resume. */\ntype InternalPausedExecution<E> = PausedExecution & {\n readonly response: Deferred.Deferred<typeof ElicitationResponse.Type>;\n readonly fiber: Fiber.Fiber<ExecuteResult, E>;\n readonly pauseSignalRef: Ref.Ref<Deferred.Deferred<InternalPausedExecution<E>>>;\n};\n\nexport type ResumeResponse = {\n readonly action: \"accept\" | \"decline\" | \"cancel\";\n readonly content?: Record<string, unknown>;\n};\n\n// ---------------------------------------------------------------------------\n// Result formatting\n// ---------------------------------------------------------------------------\n\nconst MAX_PREVIEW_CHARS = 30_000;\n\nconst truncate = (value: string, max: number): string =>\n value.length > max\n ? `${value.slice(0, max)}\\n... [truncated ${value.length - max} chars]`\n : value;\n\nexport const formatExecuteResult = (\n result: ExecuteResult,\n): {\n text: string;\n structured: Record<string, unknown>;\n isError: boolean;\n} => {\n const resultText =\n result.result != null\n ? typeof result.result === \"string\"\n ? result.result\n : JSON.stringify(result.result, null, 2)\n : null;\n\n const logText = result.logs && result.logs.length > 0 ? result.logs.join(\"\\n\") : null;\n\n if (result.error) {\n const parts = [`Error: ${result.error}`, ...(logText ? [`\\nLogs:\\n${logText}`] : [])];\n return {\n text: truncate(parts.join(\"\\n\"), MAX_PREVIEW_CHARS),\n structured: { status: \"error\", error: result.error, logs: result.logs ?? [] },\n isError: true,\n };\n }\n\n const parts = [\n ...(resultText ? [truncate(resultText, MAX_PREVIEW_CHARS)] : [\"(no result)\"]),\n ...(logText ? [`\\nLogs:\\n${logText}`] : []),\n ];\n return {\n text: parts.join(\"\\n\"),\n structured: { status: \"completed\", result: result.result ?? null, logs: result.logs ?? [] },\n isError: false,\n };\n};\n\nexport const formatPausedExecution = (\n paused: PausedExecution,\n): {\n text: string;\n structured: Record<string, unknown>;\n} => {\n const req = paused.elicitationContext.request;\n const lines: string[] = [`Execution paused: ${req.message}`];\n\n if (req._tag === \"UrlElicitation\") {\n lines.push(`\\nOpen this URL in a browser:\\n${req.url}`);\n lines.push(\"\\nAfter the browser flow, resume with the executionId below:\");\n } else {\n lines.push(\"\\nResume with the executionId below and a response matching the requested schema:\");\n const schema = req.requestedSchema;\n if (schema && Object.keys(schema).length > 0) {\n lines.push(`\\nRequested schema:\\n${JSON.stringify(schema, null, 2)}`);\n }\n }\n\n lines.push(`\\nexecutionId: ${paused.id}`);\n\n return {\n text: lines.join(\"\\n\"),\n structured: {\n status: \"waiting_for_interaction\",\n executionId: paused.id,\n interaction: {\n kind: req._tag === \"UrlElicitation\" ? \"url\" : \"form\",\n message: req.message,\n ...(req._tag === \"UrlElicitation\" ? { url: req.url } : {}),\n ...(req._tag === \"FormElicitation\" ? { requestedSchema: req.requestedSchema } : {}),\n },\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Full invoker (base + discover + describe)\n// ---------------------------------------------------------------------------\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst readOptionalLimit = (value: unknown, toolName: string): number | ExecutionToolError => {\n if (value === undefined) {\n return 12;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) {\n return new ExecutionToolError({\n message: `${toolName} limit must be a positive number when provided`,\n });\n }\n\n return Math.floor(value);\n};\n\nconst makeFullInvoker = (executor: Executor, invokeOptions: InvokeOptions): SandboxToolInvoker => {\n const base = makeExecutorToolInvoker(executor, { invokeOptions });\n return {\n invoke: ({ path, args }) => {\n if (path === \"search\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.search expects an object: { query?: string; namespace?: string; limit?: number }\",\n }),\n );\n }\n\n if (args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search query must be a string when provided\",\n }),\n );\n }\n\n if (args.namespace !== undefined && typeof args.namespace !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.search namespace must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(args.limit, \"tools.search\");\n if (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return searchTools(executor, args.query ?? \"\", limit, {\n namespace: args.namespace,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"executor.sources.list\") {\n if (args !== undefined && !isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message:\n \"tools.executor.sources.list expects an object: { query?: string; limit?: number }\",\n }),\n );\n }\n\n if (isRecord(args) && args.query !== undefined && typeof args.query !== \"string\") {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.executor.sources.list query must be a string when provided\",\n }),\n );\n }\n\n const limit = readOptionalLimit(\n isRecord(args) ? args.limit : undefined,\n \"tools.executor.sources.list\",\n );\n if (limit instanceof ExecutionToolError) {\n return Effect.fail(limit);\n }\n\n return listExecutorSources(executor, {\n query: isRecord(args) && typeof args.query === \"string\" ? args.query : undefined,\n limit,\n }).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: { \"mcp.tool.name\": path, \"executor.tool.builtin\": true },\n }),\n );\n }\n if (path === \"describe.tool\") {\n if (!isRecord(args)) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool expects an object: { path: string }\",\n }),\n );\n }\n\n if (typeof args.path !== \"string\" || args.path.trim().length === 0) {\n return Effect.fail(new ExecutionToolError({ message: \"describe.tool requires a path\" }));\n }\n\n if (\"includeSchemas\" in args) {\n return Effect.fail(\n new ExecutionToolError({\n message: \"tools.describe.tool no longer accepts includeSchemas\",\n }),\n );\n }\n\n return describeTool(executor, args.path).pipe(\n Effect.withSpan(\"mcp.tool.dispatch\", {\n attributes: {\n \"mcp.tool.name\": path,\n \"executor.tool.builtin\": true,\n \"executor.tool.target_path\": args.path,\n },\n }),\n );\n }\n return base.invoke({ path, args });\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Execution Engine\n// ---------------------------------------------------------------------------\n\nexport type ExecutionEngine<E extends Cause.YieldableError = CodeExecutionError> = {\n /**\n * Execute code with elicitation handled inline by the provided handler.\n * Use this when the host supports elicitation (e.g. MCP with elicitation capability).\n *\n * Fails with the code executor's typed error `E` (defaults to\n * `CodeExecutionError`). Runtimes surface their own `Data.TaggedError`\n * subclass, which flows through here unchanged.\n */\n readonly execute: (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) => Effect.Effect<ExecuteResult, E>;\n\n /**\n * Execute code, intercepting the first elicitation as a pause point.\n * Use this when the host doesn't support inline elicitation.\n * Returns either a completed result or a paused execution that can be resumed.\n */\n readonly executeWithPause: (code: string) => Effect.Effect<ExecutionResult, E>;\n\n /**\n * Resume a paused execution. Returns a completed result, a new pause, or\n * null if the executionId was not found.\n */\n readonly resume: (\n executionId: string,\n response: ResumeResponse,\n ) => Effect.Effect<ExecutionResult | null, E>;\n\n /**\n * Get the dynamic tool description (workflow + namespaces).\n */\n readonly getDescription: Effect.Effect<string>;\n};\n\nexport const createExecutionEngine = <\n E extends Cause.YieldableError = CodeExecutionError,\n>(\n config: ExecutionEngineConfig<E>,\n): ExecutionEngine<E> => {\n const { executor, codeExecutor } = config;\n const pausedExecutions = new Map<string, InternalPausedExecution<E>>();\n let nextId = 0;\n\n /**\n * Race a running fiber against a pause signal. Returns when either\n * the fiber completes or an elicitation handler fires (whichever\n * comes first). Re-used by both executeWithPause and resume.\n */\n const awaitCompletionOrPause = (\n fiber: Fiber.Fiber<ExecuteResult, E>,\n pauseSignal: Deferred.Deferred<InternalPausedExecution<E>>,\n ): Effect.Effect<ExecutionResult, E> =>\n Effect.race(\n Fiber.join(fiber).pipe(\n Effect.map((result): ExecutionResult => ({ status: \"completed\", result })),\n ),\n Deferred.await(pauseSignal).pipe(\n Effect.map((paused): ExecutionResult => ({ status: \"paused\", execution: paused })),\n ),\n );\n\n /**\n * Start an execution in pause/resume mode.\n *\n * The sandbox is forked as a daemon because paused executions can outlive the\n * caller scope that returned the first pause, such as an HTTP request handler.\n */\n const startPausableExecution = Effect.fn(\"mcp.execute\")(function* (code: string) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"pausable\",\n \"mcp.execute.code_length\": code.length,\n });\n\n // Ref holds the current pause signal. The elicitation handler reads\n // it each time it fires, so resume() can swap in a fresh Deferred\n // before unblocking the fiber.\n const pauseSignalRef = yield* Ref.make(yield* Deferred.make<InternalPausedExecution<E>>());\n\n // Will be set once the fiber is forked.\n let fiber: Fiber.Fiber<ExecuteResult, E>;\n\n const elicitationHandler: ElicitationHandler = (ctx) =>\n Effect.gen(function* () {\n const responseDeferred = yield* Deferred.make<typeof ElicitationResponse.Type>();\n const id = `exec_${++nextId}`;\n\n const paused: InternalPausedExecution<E> = {\n id,\n elicitationContext: ctx,\n response: responseDeferred,\n fiber: fiber!,\n pauseSignalRef,\n };\n pausedExecutions.set(id, paused);\n\n const currentSignal = yield* Ref.get(pauseSignalRef);\n yield* Deferred.succeed(currentSignal, paused);\n\n // Suspend until resume() completes responseDeferred.\n return yield* Deferred.await(responseDeferred);\n });\n\n const invoker = makeFullInvoker(executor, { onElicitation: elicitationHandler });\n fiber = yield* Effect.forkDetach(\n codeExecutor.execute(code, invoker).pipe(Effect.withSpan(\"executor.code.exec\")),\n );\n\n const initialSignal = yield* Ref.get(pauseSignalRef);\n return (yield* awaitCompletionOrPause(fiber, initialSignal)) as ExecutionResult;\n });\n\n /**\n * Resume a paused execution. Swaps in a fresh pause signal, completes\n * the response Deferred to unblock the fiber, then races completion\n * against the next pause.\n */\n const resumeExecution = Effect.fn(\"mcp.execute.resume\")(function* (\n executionId: string,\n response: ResumeResponse,\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.resume.action\": response.action,\n });\n\n const paused = pausedExecutions.get(executionId);\n if (!paused) return null;\n pausedExecutions.delete(executionId);\n\n // Swap in a fresh pause signal BEFORE unblocking the fiber, so the\n // next elicitation handler call signals this new Deferred.\n const nextSignal = yield* Deferred.make<InternalPausedExecution<E>>();\n yield* Ref.set(paused.pauseSignalRef, nextSignal);\n\n yield* Deferred.succeed(paused.response, {\n action: response.action as typeof ElicitationResponse.Type.action,\n content: response.content,\n });\n\n return (yield* awaitCompletionOrPause(paused.fiber, nextSignal)) as ExecutionResult;\n });\n\n /**\n * Inline-elicitation execute path. Wrapped so every call produces an\n * `mcp.execute` span with the inner `executor.code.exec` as a child.\n */\n const runInlineExecution = Effect.fn(\"mcp.execute\")(function* (\n code: string,\n options: { readonly onElicitation: ElicitationHandler },\n ) {\n yield* Effect.annotateCurrentSpan({\n \"mcp.execute.mode\": \"inline\",\n \"mcp.execute.code_length\": code.length,\n });\n const invoker = makeFullInvoker(executor, {\n onElicitation: options.onElicitation,\n });\n return yield* codeExecutor\n .execute(code, invoker)\n .pipe(Effect.withSpan(\"executor.code.exec\"));\n });\n\n return {\n execute: runInlineExecution,\n executeWithPause: startPausableExecution,\n resume: resumeExecution,\n getDescription: buildExecuteDescription(executor),\n };\n};\n"],"mappings":"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","names":["Effect","Effect","parts","Effect"]}
|