@archyai/agent-runtime
v0.2.0
Published
Archy agent-runtime middleware — intercept built-in Read/Grep/Bash/Edit/commit tool calls and surface structured suggestions that route the agent to the indexed plane (no model coupling, no execution).
Maintainers
Readme
@archyai/agent-runtime
Middleware that any MCP-speaking agent runtime can adopt to hook
tool-call dispatch and intercept built-in Read / Grep / Bash /
Edit / commit operations BEFORE they execute, emitting a structured
suggestion when the indexed Archy plane already has data the agent
could use instead.
This is the third Archy nudge layer:
- M1 — gated onboarding (the agent is told the plane exists at session start).
- M2 — per-runner rules (allow / suggest / deny lists).
- M3 — runtime middleware (this package).
What this is — and is not
- It IS opt-in middleware: a runtime that doesn't call
wrapToolCallgets no interception. - It IS model-agnostic: zero coupling to Anthropic / OpenAI / LangChain / Mastra / any vendor SDK.
- It IS deterministic: identical inputs produce identical
ArchyToolSuggestionobjects (including thewhytext). - It is NOT a runtime. It does not connect to a model.
- It does NOT execute the suggested Archy MCP tool. It only proposes one. The embedding runtime is the policy layer.
- It does NOT block the built-in tool call. The built-in executor always runs and its result is always returned.
Install
npm install @archyai/agent-runtime @archyai/mcp-serverThe package depends only on @archyai/mcp-server (for the local SQLite
storage adapter and the workspace-id derivation helper). No other
workspace dependencies.
Public surface
import { wrapToolCall } from "@archyai/agent-runtime";
const result = await wrapToolCall(
{
toolName: "Read",
args: { file_path: "packages/cli/src/index.ts" },
workspaceRoot: "/abs/path/to/repo",
dbPath: "/abs/path/to/repo/.archy/plane.sqlite",
},
async () => /* run the built-in Read */ "file contents...",
);
// result.suggestion → ArchyToolSuggestion | null
// result.passthrough_result → whatever the built-in returned
// result.latency_ms_for_archy_suggestion_lookup → numberIf result.suggestion is non-null the runtime decides whether to
short-circuit (call the suggested Archy tool instead) or keep the
built-in result.
Interceptors
| Tool call | When it fires | Suggested Archy tool |
|----------------------------------------|----------------------------------------------------|------------------------|
| Read({ file_path }) | the file is indexed in the plane | get_invariants |
| Grep({ pattern }) (identifier-shape) | the workspace is indexed | query_wiki |
| Grep({ pattern }) (sentence-shape) | the workspace is indexed | get_relevant_context |
| Bash({ command: "grep \| rg \| ag \| fd ..." }) | same as Grep — pattern is parsed from the command | same as Grep |
| Edit/Write/MultiEdit/NotebookEdit | the file has more than 2 callers in the graph | get_blast_radius |
| Bash({ command: "git commit \| add \| stage ..." }) | workspace is indexed | simulate_patch |
Most-specific match wins. The pipeline order is commit → bash-grep →
edit → read → grep.
Graceful degradation
If dbPath is undefined, or the file is missing, or SQLite cannot open
it, the middleware returns suggestion: null and the runtime still
gets its built-in result. The wrap function never throws on plane
unavailability.
Extending the interceptor pipeline
Bring your own probe or interceptor list via the third argument:
import { wrapToolCall, interceptRead } from "@archyai/agent-runtime";
await wrapToolCall(ctx, builtIn, {
probe: myCustomProbe,
interceptors: [interceptRead, /* ... your own ... */],
});Each interceptor is a pure function (ctx, probe) => ArchyToolSuggestion | null
— stateless, easy to compose.
Adapter examples
See examples/:
langchain-adapter.mdmastra-adapter.mdmcp-client-adapter.md
These are documentation, not runtime code. Each shows how a real-world
runtime can wire wrapToolCall into its tool-dispatch path.
Rules files (companion to this middleware)
The per-runner rules files under
docs/mcp-install/rules/ are
the system-prompt nudge layer. This middleware is the runtime layer.
They are complementary: install both for a runner that supports both.
License
Apache-2.0. Copyright 2026 Archy AI. See LICENSE at the repository root.
