capsule-runtime 0.7.0

The runtime that executes Murmur capsules. Runs packaged AI agents in isolation, enforcing WASI capability grants on a Wasmtime component sandbox.
Documentation
package murmur:runtime@0.4.0;

/// Host-provided capability available to any hook component.
///
/// A hook that imports this interface can run exactly **one** LLM completion
/// through the capsule's already-configured inference driver — the same WASM
/// driver artifact (`inference.driver.artifact` in `murmur.yaml`) the agent
/// loop dispatches its own turns through. There is no second HTTP client and no
/// separate credential path: the host reuses the driver-component invocation it
/// already performs for an ordinary turn.
interface inference {
    use murmur:hook/lifecycle@0.9.0.{message};

    /// One completion request.
    ///
    /// `system-prompt` and `model` are genuinely optional — `none` means "the
    /// host decides", not "empty string".
    record inference-request {
        /// Conversation to complete. Same `{role, content}` shape the
        /// `compaction-event` hands a hook, so a compaction hook can forward
        /// (a summarized slice of) what it was given without translation.
        messages: list<message>,
        /// System prompt for this call. `none` sends no system prompt at all.
        system-prompt: option<string>,
        /// Model to run with. `none` resolves to the manifest's primary
        /// `inference.model`.
        ///
        /// A `some(m)` the driver or provider rejects returns `err` — the host
        /// **never** silently falls back to the primary model. A caller that
        /// wants fallback-on-failure must call `run-inference` a second time
        /// with `model: none`, so each attempt produces its own truthful trace
        /// record and OTel span rather than one span quietly relabelled.
        model: option<string>,
    }

    /// One completion result.
    ///
    /// Both token counts are host measurements, not provider-reported figures:
    /// the host counts the outgoing payload and the raw driver response with the
    /// same tiktoken convention the agent loop uses for its own turns. A driver
    /// that reports a `usage` block reaches the session trace with it, never
    /// these fields. `model-used` is likewise the model string the host sent —
    /// the driver wire format never echoes back a confirmed model name.
    record inference-response {
        /// Concatenated text content of the driver's response.
        text: string,
        /// The model string the host sent for this call.
        model-used: string,
        /// Host-side token count of the outgoing request payload.
        input-tokens: u64,
        /// Host-side token count of the raw driver response.
        output-tokens: u64,
    }

    /// Run one completion. `err` carries a human-readable reason: no driver
    /// configured, driver dispatch failure, or a driver-reported error.
    run-inference: func(request: inference-request) -> result<inference-response, string>;
}