惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 司徒正美
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
宝玉的分享
宝玉的分享
量子位
V
Visual Studio Blog
罗磊的独立博客
Vercel News
Vercel News
B
Blog
J
Java Code Geeks
S
SegmentFault 最新的问题
Recent Announcements
Recent Announcements
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
GbyAI
GbyAI
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
refactor(code-mode): share VM execution lifecycle · openc...
vincentkoc · 2026-06-22 · via Recent Commits to openclaw:main

@@ -578,102 +578,113 @@ function waitingResult(params: {

578578

};

579579

}

580580581-

async function runExec(input: Extract<CodeModeWorkerInput, { kind: "exec" }>) {

582-

const pendingRequests: PendingBridgeRequest[] = [];

583-

const { vm, didTimeout } = await createVm({

584-

catalog: input.catalog,

585-

apiFiles: input.apiFiles ?? [],

586-

namespaces: input.namespaces,

587-

config: input.config,

588-

pendingRequests,

589-

});

581+

async function runVmExecution(params: {

582+

vm: QuickJS;

583+

didTimeout: () => boolean;

584+

pendingRequests: PendingBridgeRequest[];

585+

config: CodeModeConfig;

586+

prepare: () => void;

587+

}): Promise<CodeModeWorkerResult> {

590588

let output: unknown[] = [];

591589

try {

592-

vm.evalCode(

593-

buildUserSource(input.source),

594-

"openclaw-code-mode:user.js",

595-

EvalFlags.ASYNC,

596-

).dispose();

597-

drainPendingJobs(vm);

598-

output = takeOutput(vm);

599-

const resultHandle = getResultHandle(vm);

590+

params.prepare();

591+

drainPendingJobs(params.vm);

592+

output = takeOutput(params.vm);

593+

const resultHandle = getResultHandle(params.vm);

600594

try {

601-

if (pendingRequests.length > 0) {

595+

if (params.pendingRequests.length > 0) {

602596

// Pending host work suspends the VM instead of blocking in-worker; the

603597

// host resumes with settled bridge results via runResume.

604-

return waitingResult({ vm, pendingRequests, output, config: input.config });

598+

return waitingResult({

599+

vm: params.vm,

600+

pendingRequests: params.pendingRequests,

601+

output,

602+

config: params.config,

603+

});

605604

}

606605

if (resultHandle.isPromise && resultHandle.promiseState === 0) {

607606

throw new Error("code mode promise is pending without host work");

608607

}

609608

return {

610-

status: "completed" as const,

611-

value: await readCompletedResult(vm, resultHandle),

609+

status: "completed",

610+

value: await readCompletedResult(params.vm, resultHandle),

612611

output,

613612

};

614613

} finally {

615614

resultHandle.dispose();

616615

}

617616

} catch (error) {

618-

return throwWorkerFailureWithOutput({ error, didTimeout, output, vm });

617+

return throwWorkerFailureWithOutput({

618+

error,

619+

didTimeout: params.didTimeout,

620+

output,

621+

vm: params.vm,

622+

});

619623

} finally {

620-

vm.dispose();

624+

params.vm.dispose();

621625

}

622626

}

623627628+

async function runExec(input: Extract<CodeModeWorkerInput, { kind: "exec" }>) {

629+

const pendingRequests: PendingBridgeRequest[] = [];

630+

const { vm, didTimeout } = await createVm({

631+

catalog: input.catalog,

632+

apiFiles: input.apiFiles ?? [],

633+

namespaces: input.namespaces,

634+

config: input.config,

635+

pendingRequests,

636+

});

637+

return runVmExecution({

638+

vm,

639+

didTimeout,

640+

pendingRequests,

641+

config: input.config,

642+

prepare: () => {

643+

vm.evalCode(

644+

buildUserSource(input.source),

645+

"openclaw-code-mode:user.js",

646+

EvalFlags.ASYNC,

647+

).dispose();

648+

},

649+

});

650+

}

651+624652

async function runResume(input: Extract<CodeModeWorkerInput, { kind: "resume" }>) {

625653

const pendingRequests: PendingBridgeRequest[] = [];

626654

const { vm, didTimeout } = await restoreVm({

627655

snapshotBytes: input.snapshotBytes,

628656

config: input.config,

629657

pendingRequests,

630658

});

631-

let output: unknown[] = [];

632-

try {

633-

const settle = vm.global.getProp("__openclawSettleBridge");

634-

try {

635-

for (const request of input.settledRequests) {

636-

const id = vm.newString(request.id);

637-

const payload = vm.newString(JSON.stringify(request.ok ? request.value : request.error));

638-

try {

639-

vm.callFunction(

640-

settle,

641-

vm.undefined,

642-

id,

643-

request.ok ? vm.true : vm.false,

644-

payload,

645-

).dispose();

646-

} finally {

647-

id.dispose();

648-

payload.dispose();

659+

return runVmExecution({

660+

vm,

661+

didTimeout,

662+

pendingRequests,

663+

config: input.config,

664+

prepare: () => {

665+

const settle = vm.global.getProp("__openclawSettleBridge");

666+

try {

667+

for (const request of input.settledRequests) {

668+

const id = vm.newString(request.id);

669+

const payload = vm.newString(JSON.stringify(request.ok ? request.value : request.error));

670+

try {

671+

vm.callFunction(

672+

settle,

673+

vm.undefined,

674+

id,

675+

request.ok ? vm.true : vm.false,

676+

payload,

677+

).dispose();

678+

} finally {

679+

id.dispose();

680+

payload.dispose();

681+

}

649682

}

683+

} finally {

684+

settle.dispose();

650685

}

651-

} finally {

652-

settle.dispose();

653-

}

654-

drainPendingJobs(vm);

655-

output = takeOutput(vm);

656-

const resultHandle = getResultHandle(vm);

657-

try {

658-

if (pendingRequests.length > 0) {

659-

return waitingResult({ vm, pendingRequests, output, config: input.config });

660-

}

661-

if (resultHandle.isPromise && resultHandle.promiseState === 0) {

662-

throw new Error("code mode promise is pending without host work");

663-

}

664-

return {

665-

status: "completed" as const,

666-

value: await readCompletedResult(vm, resultHandle),

667-

output,

668-

};

669-

} finally {

670-

resultHandle.dispose();

671-

}

672-

} catch (error) {

673-

return throwWorkerFailureWithOutput({ error, didTimeout, output, vm });

674-

} finally {

675-

vm.dispose();

676-

}

686+

},

687+

});

677688

}

678689679690

async function main(): Promise<CodeModeWorkerResult> {