npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@three-ws/agent-runtime

v0.1.1

Published

The three.ws agent engine: a plan/execute decision loop with human-approval gates, a seven-layer GuardChain (security blacklist, intervention, capability, permission, trade guard, spend envelope, x402 budget), a tamper-evident hash-chained action ledger,

Readme


The runtime that sits between a model and anything irreversible. The decision loop turns an LLM into an agent (plan, call tools, pause for humans, finish); the GuardChain composes every enforcement layer into one deterministic verdict with a per-layer trace; the action ledger makes the resulting history tamper-evident. It is pure engine: no chain SDKs, no database, no HTTP - every external fact is injected, which is why the same code path serves the live /api/agent/guard preflight, simulators, and tests. Powers the transaction-guard preflight in three.ws/chat.

Why

An agent that can call solana_transfer is one bad tool call away from an empty wallet. Most stacks scatter their defenses: an approval modal here, a spend cap there, a blacklist somewhere else - each invoked from a different place, with different inputs, and nothing that can answer which layer would stop a given call, or which layers would silently not evaluate it at all. A guard that never runs looks exactly like a guard that passed.

This package makes enforcement composable and observable:

| Piece | What it does | |---|---| | AgentRuntime | Plan → execute loop: call_llm, call_tool, batches, finish, and three human-in-the-loop instructions (approve / prompt / select), with cost limits, interrupts, and resume | | GeneralChatAgent | The default "brain": routes phases to instructions, splits tool calls into execute-now vs. needs-approval, compresses context when it outgrows the window | | GuardChain | Runs all seven layers over one call, returns decision + per-layer trace + blind spots (enforcement that should have applied but didn't) + a coverage score | | TradeGuard | Default domain guard: tier per-tx caps, rolling 24h/7d windows, auto-execute ceiling, MEV slippage clamp, protocol audit lookup | | SpendGuard | Per-agent spend envelope: per-tx / rolling / daily caps, reserve floor, token + destination firewall, custody-breach latch | | InterventionChecker | Policy engine for human approval (never / required / always, argument-level rules, security blacklist) | | ActionLedger | Hash-chained (sha256) append-only ledger primitives: computeEntryHash, verifyChain, drift audits | | TransactionPipeline | Multi-step plan execution: dependency order, parallel independent steps, rollback on failure, approval gates | | DecisionJournal | Fire-and-forget reasoning journal with an injected sink | | Reasoning utilities | SelfReflection (structured retry prompts), ExitDecisionEngine, ResponseQualityEvaluator, ToolRelevanceScorer, token counting + context-compression checks |

Install

npm install @three-ws/agent-runtime

ESM, Node 18+. One runtime dependency (tokenx, for token estimation).

Quick start

Preflight a tool call through every guard layer

import { GuardChain, SpendGuard, TradeGuard, createX402Hook } from '@three-ws/agent-runtime';

const chain = new GuardChain({
  defiGuard: new TradeGuard(),                       // tier caps + slippage clamp
  spendGuard: new SpendGuard({ perTxMaxUsd: 5_000 }), // hard envelope
  x402Hook: createX402Hook(5),                        // $5/hour autonomy budget
});

const verdict = await chain.evaluate({
  identifier: 'solana_swap',
  apiName: 'solana_swap',
  arguments: { inputMint: 'So11111111111111111111111111111111111111112', amount: 120, slippageBps: 300 },
  valueUsd: 18_400,
  userTier: 'pro',
});

verdict.decision;      // 'block'        ($18,400 is over the $5,000 per-tx envelope)
verdict.blockedBy;     // 'spend_guard'  the layer that decided it
verdict.modifiedArguments; // { ..., slippageBps: 100 }  (MEV clamp, still applied)
verdict.coverageScore; // 74   two layers were left unwired below
verdict.blindSpots;    // [CAPABILITY_UNWIRED, PERMISSION_UNWIRED]

The capability and permission layers report themselves as blind spots because this chain was built without a checkCapability / checkPermission resolver. Inject both (each an async (request) => ({ allowed }) backed by your capability-token and permission records) and the same call scores 100 with no blind spots. Raise perTxMaxUsd above the notional and the decision becomes require_approval instead of block, driven by the trade guard's auto-execute ceiling.

The layer order is security_blacklist → intervention → capability → permission → defi_guard → spend_guard → x402. The chain never short-circuits: a call blocked by the spend envelope still reports the MEV exposure the trade guard saw, and every layer that could not evaluate the call says so instead of reading as "green".

Run the decision loop

import { AgentRuntime, GeneralChatAgent } from '@three-ws/agent-runtime';

const agent = new GeneralChatAgent({
  modelRuntimeConfig: { model: 'llama-3.3-70b-versatile', provider: 'groq' },
});
agent.modelRuntime = myStreamingLlm; // async generator: yields { content?, tool_calls? }
agent.tools = { get_price: async (args) => fetchPrice(args) };

let state = AgentRuntime.createInitialState({ operationId: 'op-1' });
state.messages.push({ role: 'user', content: 'What is SOL at?' });

const runtime = new AgentRuntime(agent);
let context;
while (state.status !== 'done' && state.status !== 'error') {
  const step = await runtime.step(state, context);
  state = step.newState;
  context = step.nextContext;
  if (state.status === 'waiting_for_human') break; // surface state.pendingToolsCalling to the user
}

When the user approves a pending call, continue with runtime.approveToolCall(state, approvedCall). runtime.interrupt() / runtime.resume() cover cancellation.

Verify a ledger

import { computeEntryHash, verifyChain } from '@three-ws/agent-runtime';

// Each row is a ledger entry plus the two chain columns: `entryHash`
// (computeEntryHash(entry, prevHash)) and `prevHash`, the first seeded with
// LEDGER_GENESIS_HASH. verifyChain sorts by `seq`, so store order is fine.
const rows = await loadAgentLedger(agentId);
const result = verifyChain(rows);
result.valid;         // false if any historical row was edited or deleted
result.brokenAtIndex; // index of the first broken link, -1 when the chain is intact
result.brokenAtSeq;   // that row's `seq`, or null when intact
result.reason;        // why it broke (null when intact)

The hashed fields are fixed and ordered (LEDGER_CANONICAL_FIELD_ORDER: seq, ts, userId, agentId, event, target, amountWei, valueUsd, txHash, reason, balanceBeforeWei, balanceAfterWei, network, detail), so editing any one of them after the fact breaks that row's link and every link after it.

Registering your tools

The guard layers key off two module-level registries seeded with the three.ws tool surface (solana_transfer, solana_swap, pumpfunBuy, ...). A host adding a new fund-moving tool registers it at boot:

import { registerFundMovingTool, registerMutatingApi } from '@three-ws/agent-runtime';

registerFundMovingTool('my_bridge_tool');
registerMutatingApi('executeBridgeV2');

An unregistered fund-moving tool is not "unguarded by design" - the GuardChain reports it as a critical TOOL_UNREGISTERED blind spot.

Where it runs on three.ws

  • POST /api/agent/guard preflights tool calls for the chat client: the chat wallet tools (solana_transfer, solana_swap, evm_*, pump.fun trades) are evaluated through this exact chain before their tool body runs, a block verdict never reaches the wallet, and the transaction-approval modal renders the verdict (decision, warnings, unchecked blind spots).
  • The server resolves SOL notionals (amount × live SOL price) before evaluating, so dollar caps compare against real numbers.

Relation to @three-ws/agent-guards

@three-ws/agent-guards is the client for the platform's custodial wallet policy (it wraps /api/agents/:id/trade limits). This package is the engine: it evaluates arbitrary tool calls before execution anywhere - client wallets, custodial paths, simulators - and is what /api/agent/guard runs. The custodial trade path keeps its own enforcement; both speak the same language of per-tx/daily caps and deny-lists.

Provenance

Core of the engine (decision loop, guard composition, spend envelope, pipeline) was battle-tested in a sibling project of the same author and ported here de-branded; the action ledger's hash-chain construction originated in the three.ws economy master ledger, so this is that design coming home. All chain-specific analysis was left behind: this package is chain-agnostic by construction, and three.ws wires Solana-first specifics (notional resolution, tool registries) at the edges.

License

See LICENSE.