@rafads/execution 1.5.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # @rafads/execution
2
+
3
+ Sandboxed JavaScript execution for an executor. Hands a `tools.<namespace>.<name>(...)` proxy into a code sandbox so an agent (or any caller) can run generated TypeScript/JavaScript that invokes the executor's registered tools.
4
+
5
+ Supports pause/resume for elicitation-driven flows: tools that need user input (OAuth, form fill, approval) suspend the sandbox, surface a `PausedExecution`, and resume on a `ResumeResponse`.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ bun add @rafads/sdk @rafads/execution @rafads/runtime-quickjs
11
+ # or
12
+ npm install @rafads/sdk @rafads/execution @rafads/runtime-quickjs
13
+ ```
14
+
15
+ `@rafads/runtime-quickjs` is the sandbox runtime. It's not a dependency of `@rafads/execution` — you bring your own so consumers with a different runtime don't ship ~13 MB of WASM they never use.
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { createExecutor } from "@rafads/sdk";
21
+ import { createExecutionEngine } from "@rafads/execution";
22
+ import { makeQuickJsExecutor } from "@rafads/runtime-quickjs";
23
+
24
+ const executor = await createExecutor({
25
+ onElicitation: "accept-all",
26
+ });
27
+
28
+ const engine = createExecutionEngine({
29
+ executor,
30
+ codeExecutor: makeQuickJsExecutor({
31
+ timeoutMs: 2_000,
32
+ memoryLimitBytes: 32 * 1024 * 1024,
33
+ }),
34
+ });
35
+
36
+ const result = await engine.execute(
37
+ `
38
+ const pets = await tools.petstore.findPetsByStatus({ status: "available" });
39
+ return pets.length;
40
+ `,
41
+ {
42
+ onElicitation: async (ctx) => {
43
+ // A tool asked for user input mid-execution. Your UI decides what to do.
44
+ console.log("tool needs input:", ctx.request);
45
+ return { action: "decline" };
46
+ },
47
+ },
48
+ );
49
+
50
+ console.log(result);
51
+ // { result: 12, logs: [...] }
52
+ ```
53
+
54
+ ## Custom tool discovery
55
+
56
+ `tools.search(...)` uses Executor's built-in lexical tool discovery by default. Hosts can provide their own implementation, such as an indexed or semantic search provider, without replacing the sandbox runtime:
57
+
58
+ ```ts
59
+ import { createExecutionEngine, type ToolDiscoveryProvider } from "@rafads/execution";
60
+
61
+ const toolDiscoveryProvider: ToolDiscoveryProvider = {
62
+ searchTools: ({ query, namespace, limit, offset }) =>
63
+ mySearchIndex.searchTools({ query, namespace, limit, offset }),
64
+ };
65
+
66
+ const engine = createExecutionEngine({
67
+ executor,
68
+ codeExecutor: makeQuickJsExecutor(),
69
+ toolDiscoveryProvider,
70
+ });
71
+ ```
72
+
73
+ ## Pause/resume for elicitation
74
+
75
+ When the host doesn't support inline elicitation, use `executeWithPause` to intercept the first request as a pause point:
76
+
77
+ ```ts
78
+ import type { ExecutionEngine } from "@rafads/execution";
79
+
80
+ declare const engine: ExecutionEngine;
81
+ declare const code: string;
82
+
83
+ const started = await engine.executeWithPause(code);
84
+
85
+ if (started.status === "paused") {
86
+ const { id, elicitationContext } = started.execution;
87
+ // Render the elicitation request in your UI. Later:
88
+ const resumed = await engine.resume(id, {
89
+ action: "accept",
90
+ content: { name: "Ada" },
91
+ });
92
+ }
93
+ ```
94
+
95
+ ## Workflow description for LLMs
96
+
97
+ ```ts
98
+ import type { ExecutionEngine } from "@rafads/execution";
99
+
100
+ declare const engine: ExecutionEngine;
101
+
102
+ const description = await engine.getDescription();
103
+ // Returns the short `execute` tool description: a one-line intro, a pointer to
104
+ // the `execute` skill, and the live connection-prefix inventory. Feed this to
105
+ // an LLM as the execute tool's description.
106
+ ```
107
+
108
+ The full "use tools.search(), then tools.describe.tool(), then call ..." workflow
109
+ prose lives in the `execute` skill rather than the always-loaded description, so a
110
+ model that never runs code does not pay for it. MCP hosts expose it through the
111
+ `skills` tool; to read it directly:
112
+
113
+ ```ts
114
+ import { EXECUTE_SKILL } from "@rafads/execution";
115
+
116
+ const howTo = EXECUTE_SKILL.body;
117
+ ```
118
+
119
+ ## Using with Effect
120
+
121
+ If you're building on `@rafads/sdk/core` (the raw Effect entry), import from the `/core` subpath. The returned engine is Effect-native: `execute`, `executeWithPause`, and `resume` all become `Effect.Effect<...>`, and `onElicitation` is an `ElicitationHandler` returning `Effect.Effect<ElicitationResponse>`.
122
+
123
+ ```ts
124
+ import { createExecutionEngine } from "@rafads/execution/core";
125
+ ```
126
+
127
+ ## Status
128
+
129
+ Pre-`1.0`. APIs may still change between beta releases. Part of the [executor monorepo](https://github.com/UsefulSoftwareCo/executor).
130
+
131
+ ## License
132
+
133
+ MIT