Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

example-extension-wasm-summarise

Reference Phase B (WASM) community extension for the CueCrux Crux daemon. Single tool — ext.summarise.prefix(prefix, top_sentences?) — that:

  1. Reads every fact under args.prefix via the host's crux::query_facts.
  2. Computes a frequency-based extractive summary.
  3. Writes the summary back to the fact store under summarise::{prefix}, key summary.

Use it as a starting template for community-contributed Wasm extensions.

What this demonstrates

  • A kind: wasm manifest with wasm_module_path + wasm_module_sha256 pinning.
  • The full Wasm host ABI surface (log, now_unix_ms, read_fact, store_fact, query_facts) called from Rust via #[link(wasm_import_module = "crux")] extern bindings.
  • The extension_call(req_ptr, req_len, resp_ptr, resp_cap) -> i32 entry point and how to round-trip JSON through linear memory.
  • An end-to-end build pipeline: cargo build → SHA-256 → Ed25519 manifest signing → install via the daemon's POST /v1/extensions/register.

Layout

.
├── Cargo.toml              # workspace root
├── module/                 # the .wasm crate
│   ├── Cargo.toml          # crate-type = ["cdylib"]
│   └── src/lib.rs          # extension_call + summariser logic
├── signer/                 # native signing helper
│   ├── Cargo.toml
│   └── src/main.rs         # builds + signs manifest.json
├── dev-keypair.json        # PUBLIC dev seed (safe to commit)
├── manifest.json           # signed manifest (regenerated by signer)
├── extension.wasm          # built artefact (regenerated by signer)
├── LICENSE                 # MIT
└── README.md

Quick start

1. Add the wasm32 target (one-time)

rustup target add wasm32-unknown-unknown

2. Build + sign

cargo build --release -p summarise-module --target wasm32-unknown-unknown
cargo run -p summarise-signer

The signer:

  • reads the freshly-built target/wasm32-unknown-unknown/release/summarise_module.wasm,
  • copies it to extension.wasm,
  • computes SHA-256 of the bytes,
  • builds the manifest with kind: wasm, wasm_module_path: extension.wasm, and the computed sha,
  • signs it with the dev keypair from dev-keypair.json,
  • writes the result to manifest.json.

3. Install into a Crux daemon (built with --features wasm-extensions)

The daemon must be built with the wasm feature:

cargo build --release -p corecruxd --features wasm-extensions

Then through the Console (http://127.0.0.1:14800/console → Extensions):

a. Trusted keys → add the dev fingerprint + public key from the signer output (p_… and the 64-char hex). Trust tier LocallySigned.

b. + Install → paste the contents of manifest.json.

c. Place the wasm bytes where the daemon expects them. By default that's <data_dir>/extensions/ext.summarise/extension.wasm. Either:

  • Copy extension.wasm from this repo into that directory yourself.
  • Or use the URL form: edit manifest.json to swap wasm_module_path for wasm_module_url: "https://your-host/extension.wasm", re-sign, and the daemon will download + verify at install time (M6.4 download path).

d. + Issue grant to a passport with these scopes:

Field Value
Allowed tools ext.summarise.prefix
Read prefixes personal::notes:: (or whatever you want to summarise)
Write prefixes summarise::personal::notes::
Rate (per min) 30

e. Test call (or use raw curl):

DAEMON=http://127.0.0.1:14800
curl -s -X POST "$DAEMON/v1/extensions/ext.summarise/tools/ext.summarise.prefix/invoke" \
  -H 'content-type: application/json' \
  -d '{"args":{"prefix":"personal::notes::","top_sentences":3},"passport_fpr":"<your-passport-fpr>"}'

Response shape:

{
  "result": {
    "summary": "<top-3 sentences joined by '. '>",
    "fact_count": 12,
    "stored_under": "summarise::personal::notes",
    "stored_fact_id": "<host-assigned>",
    "at_unix_ms": 1714938000000,
    "top_sentences": 3
  },
  "elapsed_ms": 3,
  "fuel_consumed": 84120,
  "log": [{"level": "info", "message": "summarising prefix=personal::notes:: top=3", "at_unix_ms": }],
  "request_id": "req-…"
}

Wire contract recap

The Wasm module exports:

(extension_call (param i32 i32 i32 i32) (result i32))
(memory (export "memory") 1)

The daemon writes the request JSON at req_ptr..req_ptr+req_len. The module reads it, does its work, writes a JSON response at resp_ptr..resp_ptr+resp_cap, and returns bytes-written (or -1 on overflow).

Imports (from module "crux"):

log(level_ptr, level_len, msg_ptr, msg_len) -> ()
now_unix_ms() -> u64
current_passport_json(ptr, cap) -> i32
read_fact(entity_ptr, entity_len, key_ptr, key_len, resp_ptr, resp_cap) -> i32
store_fact(entity_ptr, entity_len, key_ptr, key_len, value_ptr, value_len,
           confidence_thousandths, resp_ptr, resp_cap) -> i32
query_facts(prefix_ptr, prefix_len, query_ptr, query_len, top_k,
            resp_ptr, resp_cap) -> i32
get_secret_decrypted(...) -> i32   [stub: -6 NOT_IMPLEMENTED]
emit_receipt(...) -> i32           [stub: -6 NOT_IMPLEMENTED]

Negative return codes (stable wire contract):

rc meaning
-1 not found
-2 no grant
-3 scope violation
-4 response buffer too small
-5 fact_store unavailable
-6 host fn not implemented
-10 host internal error
-11 bad input (utf-8, OOB pointer)
-12 serialise error

Resource limits (per call)

Limit Default Env override
Fuel 1,000,000 instructions CORECRUXD_WASM_FUEL_DEFAULT
Linear memory 16 MiB CORECRUXD_WASM_MEMORY_BYTES_DEFAULT
Wall clock 1 second CORECRUXD_WASM_WALL_MS_DEFAULT
Epoch tick 10 ms CORECRUXD_WASM_EPOCH_TICK_MS

Forking this repo

  1. Change dev-keypair.json's signing_key_seed_hex to a new random 32-byte hex string (head -c 32 /dev/urandom | xxd -p -c 64) and update passport_fpr_label accordingly.
  2. Edit module/src/lib.rs to implement your tool. The extension_call, host_* wrappers, and write_response boilerplate should remain stable; everything inside run(...) is your tool's logic.
  3. Update the manifest fields in signer/src/main.rs (id, name, summary, tools[].name, tools[].input_schema).
  4. cargo build --release -p summarise-module --target wasm32-unknown-unknown && cargo run -p summarise-signer.

Licence

MIT — see LICENSE. The dev keypair seed in dev-keypair.json is public and reproducible from a label; do not use it to sign production manifests.

About

Reference Phase B (WASM) community extension for the CueCrux Crux daemon — single ext.summarise.prefix tool, signed manifest, end-to-end walkthrough.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages