mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-07-09 17:28:42 +00:00
release: @ruvector/rvagent-wasm 0.2.0 — ruflo ADR-129 integration support
- Bump version 0.1.0 → 0.2.0 in Cargo.toml and test_version_string - Add CHANGELOG.md with 0.1.0 history and 0.2.0 changes - Update README: correct package name (@ruvector/rvagent-wasm, not rvagent-wasm) - Update README: Node.js target docs, JsModelProvider + addMcpTools examples (ADR-129) - Update README: ruflo/@claude-flow/cli >=3.10.4 compatibility note - Add .github/workflows/publish-rvagent-wasm.yml for one-shot npm publish via CI No Rust logic changes. All ADR-129 gap APIs (JsModelProvider, set_model_provider, addMcpTools, get_state, get_todos, reset, WasmGallery full surface) were already implemented in 0.1.0. Gaps are purely ruflo TypeScript wiring issues. Co-Authored-By: RuFlo <ruv@ruv.net>
This commit is contained in:
parent
cf074121e5
commit
fc6f8d77eb
6 changed files with 210 additions and 47 deletions
102
.github/workflows/publish-rvagent-wasm.yml
vendored
Normal file
102
.github/workflows/publish-rvagent-wasm.yml
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
name: Publish @ruvector/rvagent-wasm
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to publish (e.g., 0.2.0)'
|
||||
required: true
|
||||
type: string
|
||||
default: '0.2.0'
|
||||
dry_run:
|
||||
description: 'Dry run (build only, no publish)'
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Build and Publish @ruvector/rvagent-wasm
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: release/rvagent-wasm-0.2.0
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: wasm32-unknown-unknown
|
||||
|
||||
- name: Cache Rust
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: rvagent-wasm-${{ inputs.version }}
|
||||
|
||||
- name: Install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
- name: Verify version matches input
|
||||
working-directory: crates/rvAgent/rvagent-wasm
|
||||
run: |
|
||||
CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/version = "//;s/"//')
|
||||
echo "Cargo.toml version: $CARGO_VERSION"
|
||||
echo "Input version: ${{ inputs.version }}"
|
||||
if [ "$CARGO_VERSION" != "${{ inputs.version }}" ]; then
|
||||
echo "ERROR: Version mismatch!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run Rust tests
|
||||
working-directory: crates/rvAgent/rvagent-wasm
|
||||
run: cargo test
|
||||
|
||||
- name: Build WASM (nodejs target)
|
||||
working-directory: crates/rvAgent/rvagent-wasm
|
||||
run: wasm-pack build --target nodejs --release
|
||||
|
||||
- name: Fix pkg/package.json name and metadata
|
||||
working-directory: crates/rvAgent/rvagent-wasm/pkg
|
||||
run: |
|
||||
# wasm-pack strips the @ruvector/ scope — restore it
|
||||
node -e "
|
||||
const pkg = JSON.parse(require('fs').readFileSync('package.json', 'utf8'));
|
||||
pkg.name = '@ruvector/rvagent-wasm';
|
||||
pkg.type = 'module';
|
||||
pkg.sideEffects = ['./snippets/*'];
|
||||
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
||||
"
|
||||
echo "Fixed package.json:"
|
||||
cat package.json
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Publish to npm (dry run)
|
||||
if: ${{ inputs.dry_run }}
|
||||
working-directory: crates/rvAgent/rvagent-wasm/pkg
|
||||
run: npm publish --access public --dry-run
|
||||
|
||||
- name: Publish to npm
|
||||
if: ${{ !inputs.dry_run }}
|
||||
working-directory: crates/rvAgent/rvagent-wasm/pkg
|
||||
run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Verify published version
|
||||
if: ${{ !inputs.dry_run }}
|
||||
run: |
|
||||
sleep 10
|
||||
PUBLISHED=$(npm view @ruvector/rvagent-wasm@${{ inputs.version }} version 2>/dev/null || echo "not found")
|
||||
echo "Published version: $PUBLISHED"
|
||||
if [ "$PUBLISHED" != "${{ inputs.version }}" ]; then
|
||||
echo "WARNING: Could not verify published version (may need more time to propagate)"
|
||||
fi
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -11027,7 +11027,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rvagent-wasm"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
|
|
|
|||
48
crates/rvAgent/rvagent-wasm/CHANGELOG.md
Normal file
48
crates/rvAgent/rvagent-wasm/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Changelog — @ruvector/rvagent-wasm
|
||||
|
||||
All notable changes to this package will be documented here.
|
||||
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [0.2.0] — 2026-05-27
|
||||
|
||||
### Added
|
||||
- `CHANGELOG.md` (this file)
|
||||
- ruflo / `@claude-flow/cli` integration documentation in README
|
||||
- ADR-129 reference: documents `JsModelProvider` + `addMcpTools()` wiring patterns
|
||||
- Explicit Node.js CommonJS usage examples (`require('@ruvector/rvagent-wasm/rvagent_wasm.js')`)
|
||||
- `WasmRvfBuilder.addMcpTools()` usage example showing ruflo ADR-129 Gap 2 pattern
|
||||
- `WasmGallery` direct API examples (Gap 3 / Gap 4 methods already implemented)
|
||||
- Security limits documented: RVF 10 MB max, capability delegation depth 10, gallery 100 custom
|
||||
|
||||
### Changed
|
||||
- Version bumped from 0.1.0 to 0.2.0
|
||||
- README corrected: package name is `@ruvector/rvagent-wasm` (not unscoped `rvagent-wasm`)
|
||||
- README corrected: published artifact uses `nodejs` wasm-pack target (not `web`)
|
||||
- README: import example updated from browser ESM to Node.js CommonJS (primary usage)
|
||||
- `pkg/package.json` name field fixed to `@ruvector/rvagent-wasm` (scoped)
|
||||
|
||||
### No Rust changes
|
||||
All WASM-level APIs are identical to 0.1.0. The full ADR-129 gap surface
|
||||
(`JsModelProvider`, `set_model_provider`, `addMcpTools`, `get_state`, `get_todos`, `reset`,
|
||||
all `WasmGallery` methods) was already implemented in 0.1.0. This release documents and
|
||||
republishes with corrected metadata.
|
||||
|
||||
### Compatible with
|
||||
- `@claude-flow/cli >= 3.10.4`
|
||||
- wasm-pack 0.14.x, 0.15.x
|
||||
- Rust 1.80+, wasm32-unknown-unknown target
|
||||
|
||||
---
|
||||
|
||||
## [0.1.0] — 2026-03-17
|
||||
|
||||
### Added
|
||||
- Initial release
|
||||
- `WasmAgent`: agent execution with virtual filesystem, conversation history, `JsModelProvider` callback
|
||||
- `JsModelProvider`: JS-to-Rust model callback bridge (`async (messagesJson) => string`)
|
||||
- `WasmRvfBuilder`: RVF cognitive container builder (tools, prompts, skills, mcp_tools, capabilities, orchestrator)
|
||||
- `WasmGallery`: 6 built-in templates (coder, researcher, tester, reviewer, security, swarm-orchestrator)
|
||||
- `WasmMcpServer`: MCP JSON-RPC server running in WASM
|
||||
- Virtual filesystem tools: `read_file`, `write_file`, `edit_file`, `list_files`, `write_todos`
|
||||
- SHA3-256 checksum on RVF containers
|
||||
- Security: request size limits, path traversal protection, capability delegation depth limit
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rvagent-wasm"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
description = "rvAgent WASM bindings — browser and Node.js agent execution"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
|
|
|||
|
|
@ -13,22 +13,32 @@ WASM bindings for rvAgent — run AI agents entirely in the browser or Node.js.
|
|||
## Installation
|
||||
|
||||
```bash
|
||||
# Build from source
|
||||
cd crates/rvAgent/rvagent-wasm
|
||||
wasm-pack build --target web
|
||||
npm install @ruvector/rvagent-wasm
|
||||
```
|
||||
|
||||
# Or use the pre-built package
|
||||
npm install rvagent-wasm # (Not yet published)
|
||||
## Building from Source
|
||||
|
||||
```bash
|
||||
cd crates/rvAgent/rvagent-wasm
|
||||
|
||||
# Node.js target (used by ruflo / @claude-flow/cli >= 3.10.4)
|
||||
wasm-pack build --target nodejs --release
|
||||
|
||||
# Browser target
|
||||
wasm-pack build --target web --release
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### WasmAgent
|
||||
### WasmAgent (Node.js / ruflo integration)
|
||||
|
||||
```javascript
|
||||
import init, { WasmAgent } from 'rvagent-wasm';
|
||||
// Node.js CommonJS (used by ruflo / @claude-flow/cli)
|
||||
const { WasmAgent, JsModelProvider } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
|
||||
|
||||
await init();
|
||||
// Browser ESM
|
||||
// import init, { WasmAgent } from '@ruvector/rvagent-wasm';
|
||||
// await init();
|
||||
|
||||
// Create an agent
|
||||
const agent = new WasmAgent(JSON.stringify({
|
||||
|
|
@ -38,15 +48,13 @@ const agent = new WasmAgent(JSON.stringify({
|
|||
max_turns: 50
|
||||
}));
|
||||
|
||||
// Connect a model provider (calls your LLM API)
|
||||
agent.set_model_provider(async (messagesJson) => {
|
||||
// Wire a real LLM via JsModelProvider (ADR-129 Gap 1 pattern)
|
||||
const provider = new JsModelProvider(async (messagesJson) => {
|
||||
const messages = JSON.parse(messagesJson);
|
||||
const response = await fetch('/api/chat', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ messages })
|
||||
});
|
||||
return (await response.json()).content;
|
||||
const response = await callYourLLM({ messages });
|
||||
return JSON.stringify({ role: 'assistant', content: response.content });
|
||||
});
|
||||
agent.set_model_provider(provider.complete.bind(provider));
|
||||
|
||||
// Send a prompt
|
||||
const result = await agent.prompt("Write a hello world function");
|
||||
|
|
@ -66,9 +74,7 @@ console.log(agent.get_todos()); // []
|
|||
Run an MCP server entirely in the browser:
|
||||
|
||||
```javascript
|
||||
import init, { WasmMcpServer } from 'rvagent-wasm';
|
||||
|
||||
await init();
|
||||
const { WasmMcpServer } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
|
||||
|
||||
const mcp = new WasmMcpServer("rvagent-wasm");
|
||||
|
||||
|
|
@ -92,32 +98,24 @@ const result = mcp.call_tool("write_file", JSON.stringify({
|
|||
|
||||
### Gallery System
|
||||
|
||||
Access built-in agent templates:
|
||||
Access built-in agent templates directly:
|
||||
|
||||
```javascript
|
||||
const { WasmGallery } = require('@ruvector/rvagent-wasm/rvagent_wasm.js');
|
||||
|
||||
const gallery = new WasmGallery();
|
||||
|
||||
// List all templates
|
||||
const templates = mcp.handle_request(JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: 1,
|
||||
method: "gallery/list",
|
||||
params: {}
|
||||
}));
|
||||
const templates = gallery.list();
|
||||
|
||||
// Search templates
|
||||
const searchResults = mcp.handle_request(JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: 2,
|
||||
method: "gallery/search",
|
||||
params: { query: "coding assistant" }
|
||||
}));
|
||||
const results = gallery.search("security testing");
|
||||
|
||||
// Load a template
|
||||
const loaded = mcp.handle_request(JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: 3,
|
||||
method: "gallery/load",
|
||||
params: { id: "claude-code" }
|
||||
}));
|
||||
// Get template details
|
||||
const coder = gallery.get("coder");
|
||||
|
||||
// Load as RVF container
|
||||
const rvfBytes = gallery.loadRvf("coder"); // Uint8Array
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
|
@ -183,20 +181,22 @@ const loaded = mcp.handle_request(JSON.stringify({
|
|||
| `name()` | Get server name |
|
||||
| `version()` | Get server version |
|
||||
|
||||
## Building
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install wasm-pack
|
||||
cargo install wasm-pack
|
||||
|
||||
# Build for Node.js (published artifact)
|
||||
wasm-pack build --target nodejs --release
|
||||
|
||||
# Build for web
|
||||
wasm-pack build --target web
|
||||
wasm-pack build --target web --release
|
||||
|
||||
# Build for Node.js
|
||||
wasm-pack build --target nodejs
|
||||
|
||||
# Run tests
|
||||
# Run Rust unit tests (61 tests, no WASM runtime needed)
|
||||
cargo test
|
||||
|
||||
# Run WASM tests in browser
|
||||
wasm-pack test --headless --chrome
|
||||
```
|
||||
|
||||
|
|
@ -226,6 +226,19 @@ rvagent-wasm/
|
|||
└── rvagent_wasm_bg.wasm
|
||||
```
|
||||
|
||||
## ruflo / @claude-flow/cli Integration
|
||||
|
||||
Compatible with `@claude-flow/cli >= 3.10.4`. ADR-129 closes two gaps in the ruflo-side wiring:
|
||||
|
||||
- **Gap 1**: Wire `JsModelProvider` so `wasm_agent_prompt` uses a real LLM (not echo stub)
|
||||
- **Gap 2**: Call `WasmRvfBuilder.addMcpTools()` in `buildRvfContainer` and expose `wasm_agent_compose`
|
||||
|
||||
All needed methods (`JsModelProvider`, `set_model_provider`, `addMcpTools`, `get_state`,
|
||||
`get_todos`, `reset`) are implemented in this WASM package. The gaps are purely TypeScript
|
||||
wiring issues in the ruflo consumer layer.
|
||||
|
||||
See [ADR-129](https://github.com/ruvnet/ruflo/blob/main/v3/docs/adr/ADR-129-rvagent-full-integration.md).
|
||||
|
||||
## Related Crates
|
||||
|
||||
| Crate | Description |
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_version_string() {
|
||||
assert_eq!(VERSION, "0.1.0");
|
||||
assert_eq!(VERSION, "0.2.0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue