@opencode/codemode 0.0.0-dev-19370 → 0.0.0-dev-19372
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.
|
@@ -8,7 +8,7 @@ import { ToolRuntime } from "../tool-runtime.js";
|
|
|
8
8
|
import { normalizeError } from "./errors.js";
|
|
9
9
|
import { InterpreterRuntimeError } from "./model.js";
|
|
10
10
|
import { PromiseRuntime } from "./promises.js";
|
|
11
|
-
import {
|
|
11
|
+
import { Runtime } from "./runtime.js";
|
|
12
12
|
export const executeProgram = (code, prepared, limits, hooks) => {
|
|
13
13
|
if (code.trim().length === 0) {
|
|
14
14
|
return Effect.succeed({
|
|
@@ -27,8 +27,7 @@ export const executeProgram = (code, prepared, limits, hooks) => {
|
|
|
27
27
|
const base = Effect.acquireUseRelease(Scope.make("parallel"), (scope) => Effect.gen(function* () {
|
|
28
28
|
const program = parseProgram(code);
|
|
29
29
|
const promises = new PromiseRuntime(scope);
|
|
30
|
-
const
|
|
31
|
-
const value = yield* interpreter.run(program);
|
|
30
|
+
const value = yield* new Runtime(tools.execute, tools.search, tools.keys, promises, logs).run(program);
|
|
32
31
|
const result = toData(value, "Execution result", "result");
|
|
33
32
|
returned = { value: result, promises };
|
|
34
33
|
const warnings = yield* promises.interrupt();
|
|
@@ -1,86 +1,16 @@
|
|
|
1
1
|
import type { Program } from "acorn";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
+
import { type Runner } from "./runner.js";
|
|
3
4
|
import { PromiseRuntime } from "./promises.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
constructor(executeTool: (path: ReadonlyArray<string>, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>, invokeSearch: (args: Array<unknown>) => Effect.Effect<unknown, unknown, R>, toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>, promises: PromiseRuntime<R>, logs?: Array<string>);
|
|
5
|
+
/** One program execution: the tool bridge, promise scheduler, captured logs, and the global scope built once. */
|
|
6
|
+
export declare class Runtime<R> {
|
|
7
|
+
readonly executeTool: (path: ReadonlyArray<string>, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
8
|
+
readonly search: (args: Array<unknown>) => Effect.Effect<unknown, unknown, R>;
|
|
9
|
+
readonly toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
10
|
+
readonly promises: PromiseRuntime<R>;
|
|
11
|
+
readonly logs: Array<string>;
|
|
12
|
+
readonly runner: Runner<R>;
|
|
13
|
+
private readonly root;
|
|
14
|
+
constructor(executeTool: (path: ReadonlyArray<string>, args: Array<unknown>) => Effect.Effect<unknown, unknown, R>, search: (args: Array<unknown>) => Effect.Effect<unknown, unknown, R>, toolKeys: (path: ReadonlyArray<string>) => ReadonlyArray<string>, promises: PromiseRuntime<R>, logs?: Array<string>);
|
|
15
15
|
run(program: Program): Effect.Effect<unknown, unknown, R>;
|
|
16
|
-
private createToolCallPromise;
|
|
17
|
-
private createPromise;
|
|
18
|
-
private settlePromise;
|
|
19
|
-
private evaluateStatement;
|
|
20
|
-
private evaluateBlock;
|
|
21
|
-
private createFunction;
|
|
22
|
-
private hoistFunctions;
|
|
23
|
-
private predeclareLexical;
|
|
24
|
-
private predeclarePattern;
|
|
25
|
-
private evaluateIfStatement;
|
|
26
|
-
private evaluateSwitchStatement;
|
|
27
|
-
private evaluateWhileStatement;
|
|
28
|
-
private evaluateDoWhileStatement;
|
|
29
|
-
private evaluateForStatement;
|
|
30
|
-
private evaluateForOfStatement;
|
|
31
|
-
private awaitValue;
|
|
32
|
-
private awaitAsyncFromSyncValue;
|
|
33
|
-
private syncIterator;
|
|
34
|
-
private customIterator;
|
|
35
|
-
private nextIteratorResult;
|
|
36
|
-
private closeIterator;
|
|
37
|
-
private requireIteratorObject;
|
|
38
|
-
private requireIterator;
|
|
39
|
-
private requireIteratorMethod;
|
|
40
|
-
private enumerableKeys;
|
|
41
|
-
private evaluateForInStatement;
|
|
42
|
-
private evaluateBreakStatement;
|
|
43
|
-
private evaluateContinueStatement;
|
|
44
|
-
private evaluateLabeledStatement;
|
|
45
|
-
private evaluateThrowStatement;
|
|
46
|
-
private evaluateTryStatement;
|
|
47
|
-
private evaluateVariableDeclaration;
|
|
48
|
-
private declarePattern;
|
|
49
|
-
private assignPattern;
|
|
50
|
-
private destructureArrayPattern;
|
|
51
|
-
private destructuringPropertyKey;
|
|
52
|
-
private destructuringPropertyValue;
|
|
53
|
-
private evaluateExpression;
|
|
54
|
-
private evaluateNewExpression;
|
|
55
|
-
private evaluateBinaryExpression;
|
|
56
|
-
private applyBinaryOperator;
|
|
57
|
-
private evaluateLogicalExpression;
|
|
58
|
-
private evaluateUnaryExpression;
|
|
59
|
-
private evaluateAssignmentExpression;
|
|
60
|
-
private evaluateLogicalAssignment;
|
|
61
|
-
private evaluateUpdateExpression;
|
|
62
|
-
private evaluateCallExpression;
|
|
63
|
-
private invokeCallable;
|
|
64
|
-
private evaluateCallArguments;
|
|
65
|
-
private invokeFunction;
|
|
66
|
-
private createGenerator;
|
|
67
|
-
private completeGeneratorRequests;
|
|
68
|
-
private takeGeneratorRequest;
|
|
69
|
-
private dequeueGeneratorRequest;
|
|
70
|
-
private evaluateYieldExpression;
|
|
71
|
-
private suspendGenerator;
|
|
72
|
-
private delegateYield;
|
|
73
|
-
private evaluateObjectExpression;
|
|
74
|
-
private evaluateArrayExpression;
|
|
75
|
-
private evaluateTemplateLiteral;
|
|
76
|
-
private evaluateConditionalExpression;
|
|
77
|
-
private applyCompoundAssignment;
|
|
78
|
-
private getMemberReference;
|
|
79
|
-
private readMember;
|
|
80
|
-
private writeMember;
|
|
81
|
-
private evaluateDeleteExpression;
|
|
82
|
-
private modifyMember;
|
|
83
|
-
private readReferenceValue;
|
|
84
|
-
private assignToReference;
|
|
85
|
-
private toPropertyKey;
|
|
86
16
|
}
|
|
@@ -97,33 +97,47 @@ const copyIteratorSymbols = (source, target, consumed) => {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
const promiseResolutionNode = { type: "PromiseResolution", start: 0, end: 0 };
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
/** One program execution: the tool bridge, promise scheduler, captured logs, and the global scope built once. */
|
|
101
|
+
export class Runtime {
|
|
102
102
|
executeTool;
|
|
103
|
-
|
|
103
|
+
search;
|
|
104
104
|
toolKeys;
|
|
105
|
-
logs;
|
|
106
105
|
promises;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
invokeCallable: (callable, args, node) => this.invokeCallable(callable, args, node),
|
|
112
|
-
settlePromise: (promise) => this.settlePromise(promise),
|
|
113
|
-
syncIterator: (value, node) => this.syncIterator(value, node),
|
|
114
|
-
};
|
|
115
|
-
constructor(executeTool, invokeSearch, toolKeys, promises, logs = []) {
|
|
116
|
-
const globalScope = new Map();
|
|
117
|
-
this.scopes = new ScopeStack([globalScope]);
|
|
106
|
+
logs;
|
|
107
|
+
runner;
|
|
108
|
+
root;
|
|
109
|
+
constructor(executeTool, search, toolKeys, promises, logs = []) {
|
|
118
110
|
this.executeTool = executeTool;
|
|
119
|
-
this.
|
|
111
|
+
this.search = search;
|
|
120
112
|
this.toolKeys = toolKeys;
|
|
121
|
-
this.logs = logs;
|
|
122
113
|
this.promises = promises;
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
this.logs = logs;
|
|
115
|
+
const globalScope = new Map();
|
|
116
|
+
// Calling back into the program never reads frame state, so any frame serves; the root is always alive.
|
|
117
|
+
this.root = new Frame(this, new ScopeStack([globalScope]));
|
|
118
|
+
this.runner = {
|
|
119
|
+
invokeFunction: (fn, args) => this.root.invokeFunction(fn, args),
|
|
120
|
+
invokeCallable: (callable, args, node) => this.root.invokeCallable(callable, args, node),
|
|
121
|
+
settlePromise: (promise) => this.root.settlePromise(promise),
|
|
122
|
+
syncIterator: (value, node) => this.root.syncIterator(value, node),
|
|
123
|
+
};
|
|
124
|
+
for (const [name, value] of globals(this))
|
|
125
125
|
globalScope.set(name, { mutable: false, value });
|
|
126
126
|
}
|
|
127
|
+
run(program) {
|
|
128
|
+
return this.root.run(program);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** One activation: the top-level program or a single function call, evaluating against its own scope chain. */
|
|
132
|
+
class Frame {
|
|
133
|
+
runtime;
|
|
134
|
+
scopes;
|
|
135
|
+
generatorState;
|
|
136
|
+
generatorAsync = false;
|
|
137
|
+
constructor(runtime, scopes) {
|
|
138
|
+
this.runtime = runtime;
|
|
139
|
+
this.scopes = scopes;
|
|
140
|
+
}
|
|
127
141
|
run(program) {
|
|
128
142
|
const self = this;
|
|
129
143
|
// Keep top-level declarations separate so they can shadow builtins.
|
|
@@ -147,20 +161,20 @@ export class Interpreter {
|
|
|
147
161
|
}
|
|
148
162
|
}
|
|
149
163
|
// The implicit async body adopts returned promises before copy-out.
|
|
150
|
-
value = yield* resolvePromiseValue(self.runner, value, program);
|
|
164
|
+
value = yield* resolvePromiseValue(self.runtime.runner, value, program);
|
|
151
165
|
return value;
|
|
152
166
|
}).pipe(Effect.ensuring(Effect.sync(() => self.scopes.pop())));
|
|
153
167
|
}
|
|
154
168
|
// Fork at the call site so admission and hooks occur when the call is made.
|
|
155
169
|
createToolCallPromise(path, args) {
|
|
156
|
-
return this.createPromise(Effect.suspend(() => this.executeTool(path, args)));
|
|
170
|
+
return this.createPromise(Effect.suspend(() => this.runtime.executeTool(path, args)));
|
|
157
171
|
}
|
|
158
172
|
createPromise(effect) {
|
|
159
|
-
return this.promises.create(effect);
|
|
173
|
+
return this.runtime.promises.create(effect);
|
|
160
174
|
}
|
|
161
175
|
// Fiber exits make settlement idempotent; yielding prevents inline continuation.
|
|
162
176
|
settlePromise(promise) {
|
|
163
|
-
const promises = this.promises;
|
|
177
|
+
const promises = this.runtime.promises;
|
|
164
178
|
return Effect.suspend(() => {
|
|
165
179
|
promises.markObserved(promise);
|
|
166
180
|
return Effect.flatMap(promises.await(promise), (exit) => Effect.andThen(Effect.yieldNow, exit));
|
|
@@ -483,7 +497,7 @@ export class Interpreter {
|
|
|
483
497
|
})));
|
|
484
498
|
}
|
|
485
499
|
awaitValue(value, node = promiseResolutionNode) {
|
|
486
|
-
return Effect.flatMap(resolvePromise(this.runner, this.promises, value, node), (promise) => this.settlePromise(promise));
|
|
500
|
+
return Effect.flatMap(resolvePromise(this.runtime.runner, this.runtime.promises, value, node), (promise) => this.settlePromise(promise));
|
|
487
501
|
}
|
|
488
502
|
awaitAsyncFromSyncValue(iterator, value, node, closeOnRejection) {
|
|
489
503
|
const self = this;
|
|
@@ -630,7 +644,7 @@ export class Interpreter {
|
|
|
630
644
|
}
|
|
631
645
|
enumerableKeys(value) {
|
|
632
646
|
if (value instanceof ToolReference) {
|
|
633
|
-
return [...this.toolKeys(value.path)];
|
|
647
|
+
return [...this.runtime.toolKeys(value.path)];
|
|
634
648
|
}
|
|
635
649
|
if (Array.isArray(value)) {
|
|
636
650
|
return Object.keys(value);
|
|
@@ -1267,10 +1281,10 @@ export class Interpreter {
|
|
|
1267
1281
|
return callable.generator.asynchronous ? yield* self.createPromise(requested) : yield* requested;
|
|
1268
1282
|
}
|
|
1269
1283
|
if (callable instanceof IntrinsicReference) {
|
|
1270
|
-
return yield* invokeIntrinsic(self.runner, callable, args, node);
|
|
1284
|
+
return yield* invokeIntrinsic(self.runtime.runner, callable, args, node);
|
|
1271
1285
|
}
|
|
1272
1286
|
if (callable instanceof PromiseInstanceMethodReference) {
|
|
1273
|
-
return yield* invokePromiseInstanceMethod(self.runner, self.promises, callable, args, node);
|
|
1287
|
+
return yield* invokePromiseInstanceMethod(self.runtime.runner, self.runtime.promises, callable, args, node);
|
|
1274
1288
|
}
|
|
1275
1289
|
if (callable instanceof HostFunction)
|
|
1276
1290
|
return yield* callable.call(args, node);
|
|
@@ -1305,8 +1319,7 @@ export class Interpreter {
|
|
|
1305
1319
|
});
|
|
1306
1320
|
}
|
|
1307
1321
|
invokeFunction(fn, args) {
|
|
1308
|
-
const invocation = new
|
|
1309
|
-
invocation.scopes = new ScopeStack([...fn.capturedScopes, new Map()]);
|
|
1322
|
+
const invocation = new Frame(this.runtime, new ScopeStack([...fn.capturedScopes, new Map()]));
|
|
1310
1323
|
const run = Effect.gen(function* () {
|
|
1311
1324
|
// Seed all parameters first so defaults cannot fall through to same-named outer bindings.
|
|
1312
1325
|
const paramScope = invocation.scopes.current();
|
|
@@ -1334,7 +1347,7 @@ export class Interpreter {
|
|
|
1334
1347
|
return run;
|
|
1335
1348
|
// The initial yield assigns the promise before the body can self-resolve.
|
|
1336
1349
|
const box = {};
|
|
1337
|
-
return Effect.map(this.createPromise(Effect.flatMap(run, (value) => resolvePromiseValue(invocation.runner, value, fn.body, box))), (promise) => {
|
|
1350
|
+
return Effect.map(this.createPromise(Effect.flatMap(run, (value) => resolvePromiseValue(invocation.runtime.runner, value, fn.body, box))), (promise) => {
|
|
1338
1351
|
box.promise = promise;
|
|
1339
1352
|
return promise;
|
|
1340
1353
|
});
|
|
@@ -1355,7 +1368,7 @@ export class Interpreter {
|
|
|
1355
1368
|
if (state.draining)
|
|
1356
1369
|
return Deferred.await(request.response);
|
|
1357
1370
|
state.draining = true;
|
|
1358
|
-
return Effect.andThen(this.promises.fork(invocation
|
|
1371
|
+
return Effect.andThen(this.runtime.promises.fork(invocation
|
|
1359
1372
|
.completeGeneratorRequests(state, true)
|
|
1360
1373
|
.pipe(Effect.ensuring(Effect.sync(() => (state.draining = false))))), Deferred.await(request.response));
|
|
1361
1374
|
}
|
|
@@ -1393,7 +1406,7 @@ export class Interpreter {
|
|
|
1393
1406
|
yield* invocation.completeGeneratorRequests(state, asynchronous);
|
|
1394
1407
|
state.completed = true;
|
|
1395
1408
|
});
|
|
1396
|
-
return Effect.andThen(this.promises.fork(body), Deferred.await(request.response));
|
|
1409
|
+
return Effect.andThen(this.runtime.promises.fork(body), Deferred.await(request.response));
|
|
1397
1410
|
}
|
|
1398
1411
|
return Deferred.await(request.response);
|
|
1399
1412
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@opencode/codemode",
|
|
4
|
-
"version": "0.0.0-dev-
|
|
4
|
+
"version": "0.0.0-dev-19372",
|
|
5
5
|
"description": "Effect-native confined code execution over schema-described tools",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|