plugin: implement component model runtime
This commit is contained in:
@@ -121,3 +121,47 @@ For example, `https` should be modeled as typed request/response data with expli
|
||||
- It does not replace Plugin grants with WIT imports.
|
||||
- It does not introduce Service, Ingress, WebSocket, or inbound HTTP by itself.
|
||||
- It does not merge Plugin and MCP. MCP remains a separate untrusted tool/resource/prompt bridge with its own policy.
|
||||
|
||||
## Implemented runtime boundary
|
||||
|
||||
Plugin Tool packages now select the runtime explicitly in `plugin.toml`:
|
||||
|
||||
```toml
|
||||
[runtime]
|
||||
kind = "wasm-component"
|
||||
component = "plugin.component.wasm"
|
||||
world = "yoi:plugin/tool@1.0.0"
|
||||
```
|
||||
|
||||
The legacy core-Wasm ABI remains explicit and is not reinterpreted as a
|
||||
component:
|
||||
|
||||
```toml
|
||||
[runtime]
|
||||
kind = "wasm"
|
||||
entry = "plugin.wasm"
|
||||
abi = "yoi-plugin-wasm-1"
|
||||
```
|
||||
|
||||
The component runtime uses `wasmtime::component` and expects the exported world
|
||||
`yoi:plugin/tool@1.0.0` with a `call(tool-name: string, input-json: string) ->
|
||||
string` export. The returned string is the same ToolOutput JSON used by the raw
|
||||
runtime, so registration and execution still flow through the existing
|
||||
ToolRegistry and Worker Tool-result history path.
|
||||
|
||||
Host imports are stable names under `yoi:host/*@1.0.0`; the repository WIT files
|
||||
live in `resources/plugin/wit/`. Importing `yoi:host/https@1.0.0` or
|
||||
`yoi:host/fs@1.0.0` is not authority. The runtime checks package grants before
|
||||
component instantiation and checks again on every host call. No WASI filesystem,
|
||||
network, environment, or other ambient imports are linked.
|
||||
|
||||
Static discovery and `yoi plugin list/show` only parse package manifests and
|
||||
reported runtime metadata. They do not instantiate or execute the component.
|
||||
Wrong `world`, missing artifact metadata, missing `call` export, unsupported
|
||||
imports, or core-Wasm bytes in a component package all fail closed with bounded
|
||||
Plugin diagnostics or ordinary Tool errors.
|
||||
|
||||
See `docs/examples/plugin-component-tool/lib.rs` for a minimal
|
||||
`wit-bindgen`/SDK-style authoring sketch. Package authors should generate
|
||||
bindings from `resources/plugin/wit`, build a component artifact, and set the
|
||||
component runtime metadata above.
|
||||
|
||||
@@ -204,3 +204,29 @@ Good follow-up Tickets are intentionally separable:
|
||||
6. WASM package ABI, initialization limits, host-function grants, and Tool/Hook contribution plumbing.
|
||||
7. Optional lock-file or pin update workflow for reproducible fresh startup.
|
||||
8. Future MCP/plugin bridge, only if explicitly approved as a separate design and implementation effort.
|
||||
|
||||
### Component Model Tool runtime
|
||||
|
||||
Tool packages may use WebAssembly Component Model runtime metadata:
|
||||
|
||||
```toml
|
||||
[runtime]
|
||||
kind = "wasm-component"
|
||||
component = "plugin.component.wasm"
|
||||
world = "yoi:plugin/tool@1.0.0"
|
||||
```
|
||||
|
||||
This is separate from the legacy raw core-Wasm runtime:
|
||||
|
||||
```toml
|
||||
[runtime]
|
||||
kind = "wasm"
|
||||
entry = "plugin.wasm"
|
||||
abi = "yoi-plugin-wasm-1"
|
||||
```
|
||||
|
||||
Component packages must not use `entry`/`abi`; raw packages must not use
|
||||
`component`/`world`. Discovery reports the selected runtime kind/world without
|
||||
executing the artifact. Component execution still requires explicit package
|
||||
enablement, exact source/version/digest grants, and matching Tool/host API
|
||||
permissions.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//! Minimal Component Model Tool plugin authoring sketch.
|
||||
//!
|
||||
//! Build this as a `wasm32-unknown-unknown` cdylib with `wit-bindgen`-generated
|
||||
//! exports and package the adapted component as `plugin.component.wasm`.
|
||||
|
||||
wit_bindgen::generate!({
|
||||
world: "tool",
|
||||
path: "../../../resources/plugin/wit",
|
||||
});
|
||||
|
||||
struct Plugin;
|
||||
|
||||
impl Guest for Plugin {
|
||||
fn call(tool_name: String, input_json: String) -> String {
|
||||
// Ordinary ToolOutput JSON. The runtime routes this through the normal
|
||||
// Worker/Tool result path; no context is injected by the component.
|
||||
format!(
|
||||
r#"{{"summary":"component tool {tool_name}","content":"input was {input_json}"}}"#
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export!(Plugin);
|
||||
Reference in New Issue
Block a user