Repository navigation
feat(runtime): add LLVM Wasm plugin runtime and Rust Arrow example - #6069
likun666661 wants to merge 1 commit into
Conversation
Add the experimental maka:plugin/runtime@1 core-Wasm ABI, Rust/C/Zig SDK templates, and a Rust Apache Arrow Compute Tool example. Keep the existing JavaScript loader path intact while allowing Rust-generated Wasm modules to register ordinary Maka Tools. Remove the plugin package file-count cap while retaining per-file and total package byte limits. Add Runtime Host, package lifecycle, Arrow, and DeepSeek Tool Calling verification. Generated-by: Codex
7912df6 to
b9188dc
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.
I found two P2 issues at b9188dc761bb25ab0b1c7c8e161fbf8d60a38a5f.
- P2 — preserve the memory limit through guest cleanup (
packages/runtime-host/src/server/wasm-plugin-worker.ts:124–125). The memory check occurs before the guest's twomaka_plugin_freecalls. A controlled module grows its memory to 128 MiB infree, yet the real runtime returns a successful first invocation; only the next invocation reports the exceeded 64 MiB limit. Thus the check neither bounds guest execution nor guarantees the retained worker satisfies the advertised limit. Enforce a maximum before guest execution, including module instantiation/start, initialization, allocation, invocation, and cleanup. Adding a post-cleanup check catches this reproduction but is not sufficient to prevent allocation above the limit. A Worker shares the host process's resource exposure; Node's documentation also explains that JavaScript heap limits do not limit ArrayBuffers. - P2 — do not forward unsupported parent-process flags to the Worker (
packages/runtime-host/src/server/wasm-plugin-runtime.ts:88). Filtering only--input-typeleaves ordinary Node/V8 flags such as--stack-trace-limit=10. Running the new test with that flag reproducesERR_WORKER_INVALID_EXEC_ARGVbefore the plugin initializes. Exact-head CI run 38147503774 fails in this newly added test with the same error and additional inherited flags. An isolated generated-code control using an empty argument list passes the same test. Use an explicit supported argument policy rather than copying the parent list.
I cannot support production integration of this new runtime on the current evidence. The Arrow example can demonstrate feasibility, but does not establish why a new permanent plugin ABI and three-language SDK are needed instead of the existing Tool integration or a separate computation service. Please provide that requirement and the intended compatibility/maintenance commitment, or keep the prototype outside production loading. Also justify removing the file-count limit from all plugin packages: the remaining byte budget counts file contents, not empty files or path metadata.
Validation and limits:
- Fresh dependency installation and the normal full root build passed. The two complete Wasm/platform test files passed all 46 tests; Host type checking and ASF header checks passed.
- Independent controlled modules verified rejection of an unavailable host import, cancellation of an infinite invocation, and rejection of an oversized initial memory after instantiation. They also reproduced the cleanup bypass above. I did not perform an out-of-memory stress test or verify a pre-instantiation resource bound.
- The complete local Host run was not green: 2,130 passed, one sandbox-execution assertion failed, six resumable-stream tests were cancelled, and 19 were skipped. I have not independently established those failures on the parent checkout and do not present them as additional PR findings.
- No Wasm/object binaries or vendored crates are committed in the added experiment tree. I retrieved declared license metadata for all 105 registry packages in the Cargo lock; that is not a target-resolved binary dependency or NOTICE audit. Permissive license alternatives must be selected and any required notices retained under the ASF third-party policy. I found no basis here for asserting a prohibited dependency, but cannot claim full binary-license closure.
- Rust, LLVM, and Zig compilers are unavailable locally. I did not independently build the Arrow/template binaries or run the live DeepSeek example; the author's results are not my verification.
- The branch's parent advertises epoch 191. Its merge with current main
6b9457f5bb3c1af96e65ec9a12cc6bae63f49aaais clean and passes the epoch-217 guard; no protocol-file change requires another epoch on that merged tree. Exact head remains unchanged and CI is failing as described above.
| checkMemory(wasm.memory); | ||
| return response; | ||
| } finally { | ||
| wasm.maka_plugin_free(inputPtr, encoded.byteLength); |
There was a problem hiding this comment.
P2: The memory check above precedes both calls into guest maka_plugin_free. I reproduced a module whose free grows linear memory to 128 MiB: the first real runtime invocation still succeeds and retains the oversized worker, while only a later invocation detects the exceeded 64 MiB limit. Bound memory before executing guest code and cover cleanup/start/init/exception paths as well. A post-free check catches the successful-response hole, but alone cannot prevent excessive allocation inside guest code.
| throw new Error('Wasm plugin entry exceeds its size limit'); | ||
| } | ||
| const worker = new Worker(new URL('./wasm-plugin-worker.js', import.meta.url), { | ||
| execArgv: process.execArgv.filter((argument) => !argument.startsWith('--input-type')), |
There was a problem hiding this comment.
P2: --input-type is not the only parent flag rejected by Worker. node --stack-trace-limit=10 --test packages/runtime-host/dist/__tests__/wasm-plugin-runtime.test.js fails with ERR_WORKER_INVALID_EXEC_ARGV at this constructor. Exact-head CI 38147503774 fails in the added test for the same reason. A generated-code control with execArgv: [] passes the same test. Do not copy arbitrary process.execArgv; select only explicitly supported worker arguments.
Summary
This PR adds an experimental language-neutral core-Wasm plugin path to Maka and uses a Rust Apache Arrow Compute plugin as the first real example.
The current JavaScript/TypeScript plugin loader remains unchanged. A package opts into the new path with
runtime.format = "wasm"andruntime.abi = "maka:plugin/runtime@1".Why LLVM makes Rust plugins possible
Maka does not need to understand Rust source code or embed a Rust runtime. Rust code is compiled by
rustc, whose backend lowers the program through LLVM towasm32-unknown-unknown. The resulting Wasm core module exports the small Maka ABI:memoryi64The Runtime Host validates the manifest, starts the module in a worker with no imports, enforces memory/input/output/time limits, and adapts each manifest contribution into the existing
PluginToolService. The resulting Tool is indistinguishable from a JavaScript plugin Tool to the rest of Maka.This is why the approach extends beyond Rust: C, C++, Zig, Swift, or another LLVM frontend can target the same Wasm ABI. LLVM is the compilation and audit layer; it is not a Runtime Host dependency.
Arrow example
experiments/llvm-plugin/arrow-data-analysisis a complete Rust plugin package:summarybuilds an ArrowFloat64Arrayand computes sum, min, max, mean, and null statistics.group_sumbuilds Arrow numeric/string arrays and computes per-group aggregates.maka.extension.jsondeclares the Wasm runtime.maka.composition.ymlinstalls thearrow_analyzeTool at profile scope.e2e.mjsinstalls the package through the realHostPluginPlatform, invokes it, and uninstalls it.deepseek-e2e.mjsoptionally exercises DeepSeek function calling through the same Tool. It only readsDEEPSEEK_API_KEYfrom the environment and never prints it.The local DeepSeek run completed successfully: DeepSeek selected
group_sum, the Arrow plugin returned east = 120 and west = 280, and DeepSeek generated a follow-up explanation from the Tool result.Package boundary change
The hard 256-file plugin package limit is removed. The package store still enforces:
A regression test installs a package with 300 files successfully.
Design and scope
Verification
npm --workspace @maka/runtime-host run typecheck— passednpm --workspace @maka/runtime-host run build— passednode --test --test-name-pattern="loads the versioned Wasm tool ABI" packages/runtime-host/dist/__tests__/wasm-plugin-runtime.test.js— passednode --test --test-name-pattern="Plugin packages do not impose a file-count cap" packages/runtime-host/dist/__tests__/plugin-platform.test.js— passedcargo check --manifest-path experiments/llvm-plugin/arrow-data-analysis/Cargo.toml— passedcd experiments/llvm-plugin && node sdk/build.mjs rust ../arrow-data-analysis— produceddist/plugin.wasmnode experiments/llvm-plugin/arrow-data-analysis/e2e.mjs— passed summary and group_sum installation/invocation/uninstall flownode experiments/llvm-plugin/arrow-data-analysis/deepseek-e2e.mjs— passed with the local DeepSeek API keynode scripts/asf-license-headers.mjs check— passedgit diff --checkand targeted Biome checks — passedThe full Runtime Host suite was not used as the acceptance gate because the existing checkout has unrelated baseline failures in ACP/deep-research fixtures and hosted execution metadata.
AI use
Tool(s) and scope: OpenAI Codex authored the implementation, tests, architecture documentation, and verification commands under human direction. The commit retains
Generated-by: Codex.Checklist
Does this PR entail a change in behavior?