Skip to main content
Glama
knowledge-bridge-labs

llmwiki-agent-bridge

README.md
# LLMWiki Agent Bridge

[![CI](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/actions/workflows/ci.yml)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)
[![Node.js >=22.12](https://img.shields.io/badge/node-%3E%3D22.12-339933.svg)](https://nodejs.org/)

`llmwiki-agent-bridge` is the optional LLMWiki Knowledge Gateway: a
gateway-compatible bridge for source fan-out, evidence bundling, and
runtime-synthesis artifacts in the LLMWiki toolchain. It runs as a local HTTP
service, gathers evidence from one or more `llmwiki-serve` Knowledge Sources,
and returns one normalized answer artifact with citations, optional graph
context, source metadata, and trace steps. It can run evidence-only for a first
smoke test, or call a configured runtime adapter for synthesized answers. The
default adapter targets OpenAI-compatible chat completions.

Gateway-compatible means the bridge can be called directly by local clients or
placed behind an external agent/API gateway as a target or companion for
LLMWiki evidence assembly. External gateways still own ingress, identity,
policy, tenancy, deployment, scaling, network exposure, and operator controls.
This package is not a substitute for Docker, agentgateway, AWS AgentCore, API
gateways, runtime hosts, or deployment platforms.

Use it when:

- A client wants one Knowledge Gateway endpoint instead of managing source
  fan-out, prompting, runtime calls, citations, and trace shaping itself.
- An external gateway or local runtime needs a target/companion that normalizes
  LLMWiki evidence and answer artifacts.
- You are connecting Hermes, DeepAgents, or a generic local runtime to LLMWiki
  evidence.
- `llmwiki-chat` or another UI needs Agent Bridge A2A or MCP endpoints backed
  by local Knowledge Sources.

Skip it when your agent or script can call `llmwiki-serve` directly and manage
its own answer synthesis.

[Quick Start](#quick-start) | [Choose a Path](#choose-a-path) | [Demo](https://knowledge-bridge-labs.github.io/llmwiki-docs/demo) | [Runtime Profiles](./docs/runtime-profiles.md) | [Message Contract](./docs/message-send-contract.md) | [External Gateways](./docs/external-gateways.md) | [OpenAPI](./docs/openapi.json) | [Integrations](./integrations/README.md) | [Examples](./examples/README.md) | [Docs portal](https://knowledge-bridge-labs.github.io/llmwiki-docs/) | [Contributing](./CONTRIBUTING.md) | [Security](./SECURITY.md) | [Support](./SUPPORT.md) | [Changelog](./CHANGELOG.md)

> Public-preview note: npm install is available for
> `llmwiki-agent-bridge@latest`; source checkout remains supported for local
> development and release checks.

For a visual first-run walkthrough, see the
[docs demo](https://knowledge-bridge-labs.github.io/llmwiki-docs/demo). It
shows the toolchain boundary: upstream workflows create compatible
Markdown/wiki files, `llmwiki-serve` projects them read-only as Knowledge
Sources, and the optional bridge can query selected served sources together.

It is not a Hermes-only bridge. Hermes is one supported runtime profile beside
`generic` and `deepagents`; all profiles use the same message contract and
return the same `llmwiki_agent_result` artifact shape. Runtime profiles identify
the runtime family; runtime adapters choose how the bridge invokes it.

It is independent community tooling for LLM Wiki-style Markdown knowledge
folders and agent-readable context. It is not an official project from Andrej
Karpathy or any upstream producer named in compatibility examples.

## Choose a Path

Start with the direct path whenever your client can call `llmwiki-serve`
itself. Add the bridge when you need the Knowledge Gateway path: fan-out,
evidence bundling, runtime synthesis, or a single normalized result behind one
local service. Put the bridge behind an external gateway only when that gateway
already owns ingress and policy and needs a LLMWiki evidence target.

| Path | Use when | Flow |
| --- | --- | --- |
| Direct to `llmwiki-serve` | Codex, Claude Code, Copilot, an IDE agent, or a script can safely call the Knowledge Source and handle its own prompting or synthesis. | `client -> llmwiki-serve` |
| Through `llmwiki-agent-bridge` Knowledge Gateway | The client wants source fan-out, evidence bundling, runtime synthesis, citations, graph context, source registry use, and trace steps returned as one artifact. | `client -> bridge -> sources -> runtime -> artifact` |
| External gateway to bridge | An existing gateway handles ingress, identity, policy, tenancy, deployment, or network controls and needs the bridge as a target/companion for LLMWiki evidence assembly. | `client -> external gateway -> bridge -> sources -> runtime -> artifact` |

Direct-client templates live in [integrations](./integrations/README.md). The
bridge request and artifact contract is documented in
[docs/message-send-contract.md](./docs/message-send-contract.md) and generated
as [docs/openapi.json](./docs/openapi.json).
External gateway placement notes and sketches live in
[docs/external-gateways.md](./docs/external-gateways.md) and
[examples/gateways](./examples/gateways/README.md).

## Component Boundaries

| Component | Boundary |
| --- | --- |
| `llmwiki-serve` | Source projection layer. It reads approved source folders and exposes read-only context, search, graph, retrieval guidance, and source-bundle metadata. Source-side projections, indexes, and retrieval capabilities live here. |
| `llmwiki-agent-bridge` | Knowledge Gateway layer. It owns source registry use, bounded source fan-out, evidence bundling, citations, graph context, diagnostics, optional runtime delegation, and the normalized answer artifact. It does not mutate source content or own source projections. |
| `llmwiki-chat` | Browser UI/workbench for source selection, runtime settings, traces, citations, and graph context. It consumes bridge and source surfaces rather than replacing them. |
| `llmwiki-bridge-start` | Setup/start harness for local workflow assembly. It can help launch or hand off source, bridge, and chat processes; it is not the gateway runtime and does not own source projection. |

## Quick Start

Requirements:

- Node.js `>=22.12`
- npm `>=10`
- One or more running `llmwiki-serve` Knowledge Source endpoints
- Optional: a runtime for synthesis. Packaged runs currently default to an
  OpenAI-compatible `/v1/chat/completions` adapter.
- `uv` and Python 3.11 or newer when starting the sample source from a checkout

This quickstart starts a source-server checkout in Terminal 1. In Terminal 2,
use the published bridge package for normal local runs, or use a bridge source
checkout when you want to run repository checks, inspect packaged examples, or
develop the bridge.

### Terminal 1: source server

Clone and start the sample `llmwiki-serve` Knowledge Source. Leave this process
running:

```sh
git clone https://github.com/knowledge-bridge-labs/llmwiki-serve.git
cd llmwiki-serve
uv sync --extra dev
uv run llmwiki-serve serve ./examples/sample-wiki --host 127.0.0.1 --port 8765
```

### Terminal 2: bridge

From any terminal, verify that Terminal 1 is serving the sample source:

```sh
curl -s http://127.0.0.1:8765/manifest
```

Start the published public-preview package:

```sh
npx llmwiki-agent-bridge@latest
```

For source-checkout development instead, open Terminal 2 in the same parent
workspace that contains the `llmwiki-serve` checkout, clone the bridge, install
dependencies, run the local checks, and start the checkout CLI:

```sh
git clone https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge.git
cd llmwiki-agent-bridge
npm ci
npm run check
node ./bin/llmwiki-agent-bridge.mjs
```

The CLI writes a JSON `ready` event when the bridge is listening:

```json
{
  "event": "ready",
  "url": "http://127.0.0.1:8788",
  "sourcePolicy": "private-http"
}
```

For runtime-backed answer synthesis, restart the bridge with the runtime profile
that matches your local runtime. This generic example works for any runtime that
implements OpenAI-compatible chat completions.

macOS/Linux:

```sh
LLMWIKI_AGENT_BRIDGE_BASE_URL=http://127.0.0.1:8642/v1 \
LLMWIKI_AGENT_BRIDGE_MODEL=local-model \
LLMWIKI_AGENT_BRIDGE_RUNTIME_PROFILE=generic \
npx llmwiki-agent-bridge@latest
```

Windows PowerShell:

```powershell
$env:LLMWIKI_AGENT_BRIDGE_BASE_URL = 'http://127.0.0.1:8642/v1'
$env:LLMWIKI_AGENT_BRIDGE_MODEL = 'local-model'
$env:LLMWIKI_AGENT_BRIDGE_RUNTIME_PROFILE = 'generic'
npx llmwiki-agent-bridge@latest
```

From a source checkout, use `node ./bin/llmwiki-agent-bridge.mjs` or
`node .\bin\llmwiki-agent-bridge.mjs` in place of the final `npx` command.

For Hermes or a compatible OpenAI-style runtime, keep the same command shape
and change `LLMWIKI_AGENT_BRIDGE_RUNTIME_PROFILE` plus the model name:

| Profile | Use when | Example model |
| --- | --- | --- |
| `generic` | Any local runtime that implements `/v1/chat/completions`. | `local-model` |
| `hermes` | Hermes or a Hermes-compatible local gateway. | `hermes-agent` |
| `deepagents` | DeepAgents identity metadata. Defaults to chat completions for compatibility unless an explicit adapter is selected. | `deepagents-local` |

DeepAgents direct-provider integration should be ACP-first. Official DeepAgents
documentation describes `deepagents-acp` as an ACP stdio CLI/programmatic API.
This package ships an opt-in live ACP subprocess adapter behind
`runtimeAdapter=deepagents-acp`. The default remains chat completions; the ACP
adapter starts one `deepagents-acp` stdio process per bridge runtime request,
fails permission prompts closed with ACP `cancelled`, and applies the bridge
request timeout to child cleanup.

For DGX Spark or another host running vLLM behind an OpenAI-compatible `/v1`
endpoint, validate the default `chat-completions` adapter first with
`runtimeProfile=deepagents`. Use `runtimeAdapter=deepagents-acp` only when the
DeepAgents ACP subprocess and its provider configuration are intentionally set
up; the ACP subprocess owns provider config separately from the bridge. The
npm `deepagents-acp` CLI does not currently document a `baseURL` flag, so
vLLM-backed ACP checks should use a programmatic DeepAgents wrapper that
injects a `ChatOpenAICompletions` model with `configuration.baseURL`.

Leave the bridge running. The following commands are also bridge-checkout
commands; if Terminal 2 is occupied by the bridge process, open another prompt
and run `cd llmwiki-agent-bridge` first.

Check the local surface:

```sh
curl -s http://127.0.0.1:8788/health
curl -s http://127.0.0.1:8788/.well-known/agent-card.json
curl -s http://127.0.0.1:8788/settings.json
```

For the first run, open `http://127.0.0.1:8788/settings` and follow the guided
setup:

1. Connect runtime when you want synthesis. Set the runtime profile, base URL,
   and model. The page saves these fields through `PUT /settings/config.json`.
2. Register Knowledge Sources. Add the sample source at
   `http://127.0.0.1:8765`, mark it ready and selected, then save it through
   `GET/PUT /settings/sources.json`.
3. Verify Bridge. Run the settings-page verification, which sends
   `POST /message:send` using the registered source and shows the returned
   answer artifact, citations, graph, and trace steps. `/message:send`
   defaults to `delegated-runtime`, so this settings-page check expects the
   configured runtime to be reachable. Use the evidence-only sample request
   below for a no-runtime smoke test.

Runtime credentials, network, auth, CORS, timeout, and source-policy controls live under
diagnostics/advanced. Most local OSS users only need the three setup steps
above.

For a no-runtime smoke test from a package-only launch, send an inline
evidence-only request:

```sh
curl -s http://127.0.0.1:8788/message:send \
  -H 'content-type: application/json' \
  -d '{"data":{"query":"release readiness","mode":"evidence-only","knowledgeSources":[{"id":"sample-wiki","name":"Sample Wiki","protocol":"llmwiki-http","status":"ready","url":"http://127.0.0.1:8765","selected":true}]}}'
```

From a `llmwiki-agent-bridge` source checkout, you can send the bundled
equivalent request so the `--data @examples/message-send.local.json` path
resolves to this repository:

```sh
curl -s http://127.0.0.1:8788/message:send \
  -H 'content-type: application/json' \
  --data @examples/message-send.local.json
```

The bundled `examples/message-send.local.json` points at
`http://127.0.0.1:8765` and sets `mode` to `evidence-only`. If your
`llmwiki-serve` or bridge process uses a different port, copy that file to a
temporary path, update the source URL, and post it to the bridge URL you
started.

MCP-style clients can complete the basic lifecycle on `/mcp` with
`initialize`, `notifications/initialized`, and `ping`, then list bridge tools.
Use `llmwiki_agent_run` when you want the bridge to produce a full grounded
answer, or use the read-only source tools when your host agent wants to inspect
sources progressively:

```sh
curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}'

curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"ping"}'

curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/list"}'

curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"llmwiki_agent_run","arguments":{"query":"release readiness"}}}'

curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"llmwiki_context","arguments":{"sourceId":"sample-wiki","query":"release readiness","limit":5}}}'

curl -s http://127.0.0.1:8788/mcp \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"llmwiki_graph_neighbors","arguments":{"sourceId":"sample-wiki","nodeId":"sample-wiki:overview","direction":"out","relation":"supports","limit":20}}}'
```

For hosts that support tool search or want a smaller initial `tools/list`
payload, start the bridge with progressive gateway exposure:

```sh
LLMWIKI_AGENT_BRIDGE_MCP_TOOL_EXPOSURE=gateway llmwiki-agent-bridge
```

In `gateway` mode, `tools/list` returns only
`llmwiki_gateway_search_tools`, `llmwiki_gateway_get_tool_details`, and
`llmwiki_gateway_call_tool`. The model can search a compact catalog first,
inspect one selected source tool schema, then call that tool by source/tool
name. The default remains `direct` for existing MCP clients; `both` is accepted
only when an operator intentionally wants both direct and gateway tools listed.

Omit `knowledgeSources` to use sources registered through `/settings`. Passing
`knowledgeSources: []` means "run with no sources" and is useful only for
negative tests.
The human-readable source list omits endpoint URLs. The structured
`llmwiki_sources.sources` descriptors include source URLs so local workbenches
can select bridge-managed sources and pass them back to `/message:send`.
Do not copy private local URLs into public docs, issues, or examples.

The sample request asks `release readiness`. Exact answer wording may vary by
runtime; the stable integration target is the completed task plus the
`llmwiki_agent_result` data artifact fields:

```json
{
  "answer": "Grounded answer text from the configured runtime.",
  "citations": [
    {
      "sourceId": "sample-wiki",
      "pageId": "release-readiness",
      "title": "Release Readiness",
      "score": 0.92
    }
  ],
  "graph": {
    "nodes": [],
    "edges": []
  },
  "steps": [
    {
      "id": "bridge-evidence",
      "label": "Prepare evidence",
      "status": "done"
    },
    {
      "id": "runtime-chat-completions",
      "label": "Call chat completions",
      "status": "done"
    }
  ]
}
```

For complete payloads and local setup notes, use
[examples](./examples/README.md), [runtime profiles](./docs/runtime-profiles.md),
the [message contract](./docs/message-send-contract.md), and
[client paths](./docs/client-paths.md). For external gateway placements, see
[docs/external-gateways.md](./docs/external-gateways.md) and
[examples/gateways](./examples/gateways/README.md).

## What It Does

As the LLMWiki Knowledge Gateway layer, the bridge exposes one small local HTTP
surface:

| Endpoint | Purpose |
| --- | --- |
| `GET /health` | Runtime, configuration, source policy, and redacted source-registry readiness snapshot. |
| `GET /sources` | Redacted source registry view. Add `?probe=1` for live source health and safe manifest metadata. |
| `GET /.well-known/agent-card.json` | Local A2A-style agent card metadata with supported interfaces, protocol version metadata, skills, optional bearer-auth security metadata, and redacted source-registry readiness counts. |
| `GET /settings` | Guided local setup UI: connect runtime, register Knowledge Sources, and verify with `POST /message:send`. |
| `GET /settings.json` | Redacted runtime, bridge, persistence, and endpoint metadata. |
| `PUT /settings/config.json` | Persists runtime configuration plus advanced access, CORS, timeout, and source-policy settings. |
| `GET/PUT /settings/sources.json` | Reads or persists registered Knowledge Sources. |
| `POST /message:send` | A2A-style request that returns a completed task artifact; explicit `A2A-Version: 1.0` stores a process-local task snapshot. |
| `POST /message:stream` | A2A 1.0 SSE stream for submitted, working, and terminal task events. |
| `GET /tasks`, `GET /tasks/{id}` | A2A 1.0 process-local task listing and lookup for recent bridge runs. |
| `POST /tasks/{id}:cancel`, `GET/POST /tasks/{id}:subscribe` | A2A lifecycle routes with clean unsupported/not-cancelable errors for this synchronous local bridge. |
| `GET/POST/DELETE /tasks/{id}/pushNotificationConfigs` | A2A push-notification routes that return a protocol-shaped unsupported error because push notifications are not advertised. |
| `GET /extendedAgentCard` | A2A 1.0 extended card route; bearer auth is enforced when the bridge bearer token is configured. |
| `POST /mcp` | MCP-style JSON-RPC endpoint with lifecycle methods, `llmwiki_agent_run`, and read-only source tools. |

For each `POST /message:send` request, the bridge:

1. Selects ready Knowledge Source descriptors from the request.
2. Fetches context over `llmwiki-http`, MCP-style JSON-RPC, or A2A-style HTTP.
3. Packages citations, graph context, source bundle metadata, and trace steps.
4. In `delegated-runtime` or `hybrid`, renders the evidence bundle as compact
   JSON and calls the configured OpenAI-compatible `/v1/chat/completions`
   endpoint.
5. In `evidence-only`, skips the runtime call and returns a bridge-generated
   evidence summary.
6. Returns answer text plus the `llmwiki_agent_result` artifact.

`POST /mcp` exposes two layers. `llmwiki_agent_run` calls the same internal run
path as `/message:send` and returns text content plus
`structuredContent.llmwiki_agent_result`. The read-only source tools
`llmwiki_list_sources`, `llmwiki_context`, `llmwiki_search`, `llmwiki_read`,
`llmwiki_graph`, `llmwiki_graph_neighbors`, and `llmwiki_source_bundle` do not
call the configured runtime; they let a host agent list sources, read
orientation-first context, search, open a page, inspect graph data, traverse a
bounded neighborhood, or read safe source-bundle metadata before deciding
whether more source exploration or a full answer run is needed.

Set `LLMWIKI_AGENT_BRIDGE_MCP_TOOL_EXPOSURE=gateway` when the MCP host should
avoid loading every direct source-tool schema up front. Gateway exposure keeps
the listed tool surface to compact catalog, detail, and call meta-tools while
still routing execution through the same read-only source-tool handlers.

For local operator checks without starting the HTTP service, use
`llmwiki-agent-bridge sources --json`, `llmwiki-agent-bridge ls`, or
`llmwiki-agent-bridge status --probe`. CLI output reads the local settings file
and may show stored local roots for diagnostics. HTTP registry responses redact
absolute roots to safe labels and reject duplicate source IDs on
`PUT /settings/sources.json`.

Requests may supply `knowledgeSources` directly, or omit them and use the
bridge's registered Knowledge Sources. Register sources in Step 2 of
`/settings` or by calling `PUT /settings/sources.json` with a `sources` array.
Multiple ready, selected sources can be registered and queried in one run.
Source calls are bounded internally rather than sent with unbounded parallelism.
The returned artifact is normalized back to the selected source order for
citations, graph data, source bundles, trace steps, diagnostics, and per-source
failures.

`/message:send` keeps the legacy `data.query` contract and also accepts
additive conversation runtime context: `data.message` or top-level A2A
`message`, `data.messages`, `data.threadId`, `data.sessionId`, `data.turnId`,
`data.runtimeContext.conversation`, A2A-style `configuration.historyLength`,
and A2A-style `metadata.threadId/sessionId/turnId`. The bridge uses the current
query from `data.query` or A2A message text for source retrieval, then includes
bounded user/assistant conversation history in the runtime chat-completions call
after the evidence system prompt.

The bridge exports its A2A wire-version constants from the package and uses the
current SDK protocol version on `/.well-known/agent-card.json` and
`A2A-Version` response headers for `/message:send`. Missing or empty
`A2A-Version` request headers remain accepted as legacy `0.3`; explicit
unsupported versions fail before source fan-out or runtime calls. Explicit
`A2A-Version: 1.0` requests receive `application/a2a+json` with the current
HTTP+JSON wrapper shape, while legacy requests keep the direct completed task
response.

For A2A 1.0 callers, the bridge also exposes `/message:stream`,
process-local `/tasks` lookup, `/extendedAgentCard`, and protocol-shaped
lifecycle error responses. The task store is bounded memory only; it is for
local polling and debugging, not durable workflow persistence. Push
notifications are advertised as unsupported and return the A2A
`PUSH_NOTIFICATION_NOT_SUPPORTED` error shape.

### Retrieval mode routing

Clients can optionally request a source retrieval mode with `data.retrieval`.
This is separate from `data.mode`: `data.mode` and `data.orchestrationMode`
control bridge orchestration, while `data.retrieval.searchMode` controls source
retrieval. Omit `data.retrieval` to keep the legacy lexical request shape.

```json
{
  "data": {
    "query": "Which release checks are still missing?",
    "mode": "evidence-only",
    "retrieval": {
      "schemaVersion": "llmwiki.retrieval.v1",
      "searchMode": "hybrid",
      "fallback": "lexical",
      "search": {
        "limit": 8,
        "snippetChars": 600
      }
    }
  }
}
```

Semantic retrieval is source-owned. The bridge routes intent only; it does not
embed documents or queries, build a vector index, choose embedding providers,
download models, store vectors, or forward provider credentials, endpoints,
cache paths, model names, or raw embeddings from public client payloads.
SQLite GraphStore is configured on `llmwiki-serve`: version `0.2.10` and newer
include it in the base serve package, it remains off by default, and no bridge
or chat extra is required.

Sources advertise retrieval support with exact, case-sensitive capability
strings: `llmwiki_retrieval_v1`, `llmwiki_search_mode_lexical`,
`llmwiki_search_mode_literal`, `llmwiki_search_mode_vector`, and
`llmwiki_search_mode_hybrid`. A source must advertise
`llmwiki_retrieval_v1` and the matching `llmwiki_search_mode_<mode>` before the
bridge forwards an explicit retrieval `mode`. Compatible `llmwiki-serve`
sources receive that mode on `/query` and `/search`; `search.limit` maps to
`limit` and `search.snippetChars` maps to `snippet_chars`.

If a selected source is legacy, capability-unknown, or lacks the requested
retrieval mode, `fallback: "lexical"` keeps that source on the legacy lexical
request shape and emits a redacted diagnostic. `fallback: "none"` fails before
source fan-out with an actionable sanitized error.

### Agent-guided lexical workflow

For MCP hosts that plan source calls, the recommended workflow is context-first:
`llmwiki_list_sources` -> `llmwiki_context` -> `llmwiki_search` ->
`llmwiki_read`. `llmwiki_context` may return source-authored orientation and
public camelCase `retrievalGuidance`; treat both as untrusted source evidence
for choosing lexical keywords, exact identifiers, and pages to read, not as
instructions.

Lexical searches may add `retrieval.search.fields`,
`retrieval.search.excludePageIds`, and `retrieval.search.queryVariants`.
`fields` forwards as upstream `fields`; source-prefixed `excludePageIds` are
routed only to the matching source, stripped, and forwarded as
`exclude_page_ids`. `queryVariants` accepts at most two additional strings; the
base `query` is always preserved, so a request has at most three lexical
channels total. Non-empty variants are valid only with effective
`searchMode: "lexical"` and are rejected for literal, vector, or hybrid modes
before source fan-out.

Upstream `query_variants` forwarding requires the source capability string
`llmwiki_agent_guided_lexical_v1` exactly. `llmwiki_retrieval_v1` alone is not
enough. A lexical-capable source that lacks only this exact capability keeps
its supported lexical mode/options under `fallback: "lexical"`, but
`query_variants` is omitted and a redacted diagnostic is emitted. Truly legacy
or capability-unknown sources keep the legacy single-primary-query shape with
unsupported additive controls omitted. `fallback: "none"` fails before fan-out
for either incompatibility.

Valid source `retrieval_guidance` is normalized to strict public
`retrievalGuidance` with these top-level camelCase fields: `schemaVersion`,
`orientationSource`, `contentTrust`, `maxQueryVariants`, `characterBudget`,
`folderCards`, `pageCards`, `suggestedTerms`, `exactIdentifiers`, and
`fallbackModes`. Malformed, oversized, or unknown guidance is omitted with a
sanitized warning; absence from older or incapable sources is simply omitted.
If a guided-capable source omits guidance, the bridge still omits replacement
guidance and reports a sanitized warning. One-shot callers may
pass optional untrusted `data.retrievalGuidance` on `/message:send` or
top-level `retrievalGuidance` on `llmwiki_agent_run`; it is traceability
metadata outside `retrieval`, not a runtime instruction channel. One-shot runs
still gather evidence once and do not imply a runtime tool loop.

### Safe request audit logging

Set `LLMWIKI_AGENT_BRIDGE_AUDIT_LOG=1` or pass `auditLog: true` to emit one
JSON line per audited bridge request through the existing logger (`stdout` by
default). Audited routes are `/message:send`, `/mcp`, `/settings`,
`/settings.json`, `/settings/config.json`, `/settings/sources.json`,
`/.well-known/agent-card.json`, and `/health`.

Audit events are intentionally allowlisted. They include route patterns, status,
duration, request/trace IDs, orchestration mode, runtime-called state, source and
artifact counts, conversation count/boolean fields, and redaction flags. They do
not include raw prompts, runtime answers, request or response bodies, query
strings, source URLs, runtime base URLs, model names, API keys, bearer tokens,
local paths, thread/session IDs, or conversation message content.

### Default I/O debug logging

The bridge also emits a separate default-on JSONL I/O debug stream to
`.runtime-logs/llmwiki-agent-bridge-io.jsonl` by default. These events use
`llmwiki.agent_bridge.io` and are meant for local troubleshooting of
`/message:send` request, source, runtime, and final artifact flow.

I/O logs may include prompts, source request/response bodies, runtime messages,
runtime answers, and bridge response artifacts after redaction. They always
redact Authorization and credential-like headers, API keys, bearer tokens, raw
source/runtime URLs, URL query secrets, and obvious local absolute paths. This
stream is intentionally separate from safe audit logging.

Set `LLMWIKI_AGENT_BRIDGE_IO_LOG=off` or persist `"ioLog": false` to disable
I/O logs. Set `LLMWIKI_AGENT_BRIDGE_IO_LOG=logger` or `stdout` to route JSONL
through the process logger instead. `LLMWIKI_AGENT_BRIDGE_IO_LOG_PATH` chooses a
different file path.

```mermaid
flowchart LR
  client["client or chat workbench"]
  bridge["llmwiki-agent-bridge"]
  sources["selected Knowledge Sources"]
  runtime["OpenAI-compatible runtime"]
  artifact["answer artifact<br/>citations, graph, trace"]

  client --> bridge
  bridge --> sources
  sources --> bridge
  bridge --> runtime
  runtime --> bridge
  bridge --> artifact
```

Supported Knowledge Source protocols:

| Protocol | Behavior |
| --- | --- |
| `llmwiki-http` | Calls `GET /source-bundle` or legacy `GET /manifest` for safe bundle metadata, then calls `POST /query` and augments evidence with compact search variants. |
| `mcp` | Calls `llmwiki_source_bundle` for safe bundle metadata when available, then calls `llmwiki_context` through a JSON-RPC MCP-style endpoint. Source URLs that already end in `/mcp` or `/mcp/stream` are used as-is; base service URLs keep the legacy `/mcp` fallback. |
| `a2a` | Reads `/.well-known/agent-card.json`, posts a message, and prefers a `llmwiki_context` artifact when present. |

The generated OpenAPI contract is committed at
[docs/openapi.json](./docs/openapi.json). It covers the bridge's local HTTP
surface and the `llmwiki_agent_result` artifact shape as a public-preview
compatibility contract, not as certified A2A conformance.

The package includes `@a2a-js/sdk@1.1.0` for A2A discovery compatibility
checks while keeping the existing `/message:send` route stable.

## Runtime Profiles

Profiles are conservative configuration presets over the same bridge contract.
They change runtime identity metadata, default model naming, and
operator-facing configuration; they do not change the LLMWiki evidence format.
Compact JSON is the current runtime prompt evidence encoding. Broad
production-default approval is an evidence claim gated by the tracked runtime
prompt approval e2e, not a profile switch.

| Profile | Use when | Typical model variable |
| --- | --- | --- |
| `generic` | Running any local runtime that implements OpenAI-compatible `/v1/chat/completions`. | `LLMWIKI_AGENT_BRIDGE_MODEL=local-model` |
| `hermes` | Running Hermes or a Hermes-compatible local gateway. | `LLMWIKI_AGENT_BRIDGE_MODEL=hermes-agent` |
| `deepagents` | Identifying the bridge as DeepAgents-backed. Defaults to chat completions unless an explicit adapter is selected. | `LLMWIKI_AGENT_BRIDGE_MODEL=deepagents-local` |

Legacy `HERMES_*` and `HERMES_A2A_BRIDGE_*` environment aliases remain
available for migration. New deployments should prefer the
`LLMWIKI_AGENT_BRIDGE_*` variables.

More detail: [docs/runtime-profiles.md](./docs/runtime-profiles.md).

## Package Surface

`llmwiki-agent-bridge` ships one Node package with these public entry points:

| Surface | Purpose |
| --- | --- |
| `llmwiki-agent-bridge` CLI | Starts the local bridge from `npx`, a package install, or a source checkout. |
| `startAgentBridge` | Programmatic API for tests, local tooling, or embedded bridge processes. |
| `docs/openapi.json` | Generated local HTTP and artifact contract. |
| `examples/message-send.local.json` | Minimal local request for smoke testing. |
| `integrations/` | Direct-client templates and routing guidance for Codex, Claude Code, and Copilot. |

The public-preview package is available through
`llmwiki-agent-bridge@latest`. Run it without installing globally:

```sh
npx llmwiki-agent-bridge@latest
```

Or install the package and run the CLI:

```sh
npm install --global llmwiki-agent-bridge@latest
llmwiki-agent-bridge
```

Source checkout remains a supported development path:

```sh
npm ci
npm run check
node ./bin/llmwiki-agent-bridge.mjs
```

## Integration Paths

Direct-client integrations are the best first choice when the agent can safely
retrieve context from `llmwiki-serve` itself. Bridge integrations are the
Knowledge Gateway path and are a better fit when a client wants one local
service to gather evidence, call a runtime, and return a normalized result.
When an external gateway is already in the deployment, keep that gateway
responsible for ingress and policy and use `llmwiki-agent-bridge` as the
LLMWiki evidence target behind it.

- [Client path guide](./docs/client-paths.md)
- [External gateway placement](./docs/external-gateways.md)
- [Gateway examples](./examples/gateways/README.md)
- [Integrations overview](./integrations/README.md)
- [Codex skill example](./integrations/codex/skills/llmwiki-serve/SKILL.md)
- [Claude Code command example](./integrations/claude-code/commands/llmwiki-query.md)
- [Copilot instructions example](./integrations/copilot/copilot-instructions.md)

For direct agent use, run `llmwiki-serve`, set `LLMWIKI_SERVE_URL`, and adapt
the templates in `integrations/`. The examples call `/query` first, then
`/search`, `/read/{page_id}`, `/graph`, or `/mcp` for narrower inspection.

```sh
export LLMWIKI_SERVE_URL=http://127.0.0.1:8765
```

Use `llmwiki-agent-bridge` when the workflow also needs source fan-out,
evidence bundling, runtime synthesis, and one normalized answer artifact.

## Configuration

Most local runs only need the runtime base URL, model, profile, and optional
bridge bearer token. Keep `runtimeAdapter` at its default unless you are
testing an explicit adapter integration:

| Variable | Default | Purpose |
| --- | --- | --- |
| `LLMWIKI_AGENT_BRIDGE_BASE_URL` | `http://127.0.0.1:8642/v1` | OpenAI-compatible chat completions base URL. |
| `LLMWIKI_AGENT_BRIDGE_MODEL` | `hermes-agent` | Chat completions model name. |
| `LLMWIKI_AGENT_BRIDGE_RUNTIME_PROFILE` | `hermes` | Runtime profile preset: `hermes`, `deepagents`, or `generic`. |
| `LLMWIKI_AGENT_BRIDGE_RUNTIME_ADAPTER` | `chat-completions` | Runtime invocation adapter. Set `deepagents-acp` to use the opt-in DeepAgents ACP subprocess adapter. |
| `LLMWIKI_AGENT_BRIDGE_DEEPAGENTS_ACP_COMMAND` | `npx`; Windows uses `node` plus npm's `npx-cli.js` when available, then falls back to `npx.cmd` | Command spawned for `runtimeAdapter=deepagents-acp`; executed without a shell. |
| `LLMWIKI_AGENT_BRIDGE_DEEPAGENTS_ACP_ARGS` | `--yes deepagents-acp` | Arguments for the ACP command. Use a JSON string array when arguments contain spaces. |
| `LLMWIKI_AGENT_BRIDGE_DEEPAGENTS_ACP_CWD` | current working directory | Working directory for the ACP subprocess and per-request ACP session. |
| `LLMWIKI_AGENT_BRIDGE_HOST` | `127.0.0.1` | Bridge bind host; non-loopback values require explicit opt-in. Host changes saved from `/settings` require restart. |
| `LLMWIKI_AGENT_BRIDGE_PORT` | `8788` | Bridge HTTP port. Port changes saved from `/settings` require restart. |
| `LLMWIKI_AGENT_BRIDGE_API_KEY` | unset | Optional runtime API key sent only to the configured runtime. |
| `LLMWIKI_AGENT_BRIDGE_BEARER_TOKEN` | unset | Optional bearer token required by bridge HTTP requests. |
| `LLMWIKI_AGENT_BRIDGE_ALLOWED_ORIGINS` | unset | Extra browser CORS origins allowed to call the bridge. |
| `LLMWIKI_AGENT_BRIDGE_SOURCE_POLICY` | `private-http` | Outbound Knowledge Source URL policy. |
| `LLMWIKI_AGENT_BRIDGE_ALLOWED_SOURCE_ORIGINS` | unset | Exact Knowledge Source origins for allowlist or stricter policies. |
| `LLMWIKI_AGENT_BRIDGE_IO_LOG` | `file` | Default-on I/O debug logging. Set `off` to disable, `logger`/`stdout` to route through process logs, or `file` to append JSONL to a file sink. |
| `LLMWIKI_AGENT_BRIDGE_IO_LOG_PATH` | `.runtime-logs/llmwiki-agent-bridge-io.jsonl` | Optional file path for I/O JSONL logs. |
| `LLMWIKI_AGENT_BRIDGE_ALLOW_PUBLIC_BIND` | unset | Set to `1` before binding to a non-loopback host. |
| `LLMWIKI_AGENT_BRIDGE_CONFIG_PATH` | user config file in the CLI | Persistent settings file for `/settings/config.json` and `/settings/sources.json`; programmatic callers can pass `configPath`. |

Source policy, CORS, bind-host, and migration alias details are documented in
[runtime profiles](./docs/runtime-profiles.md) and
[client paths](./docs/client-paths.md).

The implementation keeps Hermes defaults for backward compatibility. For a new
OSS install, set `LLMWIKI_AGENT_BRIDGE_RUNTIME_PROFILE=generic` explicitly
unless you are connecting Hermes or DeepAgents, and set the model name expected
by that runtime.

Do not expose the bridge on a public or shared interface without
`LLMWIKI_AGENT_BRIDGE_BEARER_TOKEN`. Non-loopback binds require an explicit
opt-in, and public unauthenticated binds are a development-only escape hatch.

The `/settings` page is the guided first-run UI over the same configuration.
Step 1 connects the runtime and saves profile, base URL, and model through
`PUT /settings/config.json`. Step 2 saves reusable Knowledge Source descriptors
through `GET/PUT /settings/sources.json`. Step 3 verifies the bridge by sending
`POST /message:send` from the page and showing the returned artifact. Runtime
credentials, advanced network, auth, CORS, timeout, and source-policy fields
are still available under diagnostics/advanced; changes to live runtime fields
apply to the running process. Bind `host` and `port` are saved for the next
start and the save response lists them under `restartRequired`.

## Programmatic API

```js
import { startAgentBridge } from 'llmwiki-agent-bridge'

const { server, url } = await startAgentBridge({
  port: 0,
  baseUrl: 'http://127.0.0.1:8642/v1',
  model: 'local-model',
  runtimeProfile: 'generic',
})

console.log(url)
server.close()
```

Legacy `createHermesA2aBridge` and `startHermesA2aBridge` exports are available
during migration.

## Repository Structure

| Path | Purpose |
| --- | --- |
| `bin/` | CLI entry point for starting the bridge from a checkout or package. |
| `src/` | Bridge server, source clients, runtime call path, and result shaping. |
| `examples/` | Sample local A2A-style request payloads. |
| `integrations/` | Direct agent templates for Codex, Claude Code, Copilot, and bridge routing guidance. |
| `docs/` | Runtime profiles, OpenAPI contract, client paths, and release guidance. |
| `test/` | Bridge behavior and contract tests. |
| `scripts/` | Maintenance and release helper scripts. |
| `package.json`, `package-lock.json` | Node package metadata and locked development environment. |

## Release Status

`llmwiki-agent-bridge` is in public preview. The npm package is published, and
package-based `npx llmwiki-agent-bridge@latest` or
`npm install --global llmwiki-agent-bridge@latest` runs are supported for local
use. Source checkout remains supported for development, repository validation,
and release checks.

Repository, issue, CI badge, package, and hosted docs URLs intentionally target
the Knowledge Bridge Labs organization. The hosted Release Status &
Compatibility matrix records which package and runtime paths are currently
available.

See [docs/release.md](./docs/release.md) before preparing, publishing, or
tagging the next public-preview release.

## Development

```sh
npm run lint
npm run contracts:check
npm test
npm run pack:dry-run
npm run audit
```

`npm run check` runs lint, generated-contract drift checks, tests, and dry
packaging.

## Toolchain

| Repo/package | Role | Validation command |
| --- | --- | --- |
| `llmwiki-serve` | Read-only Knowledge Source server for Markdown or LLMWiki-style folders. | `uv run python scripts/release_smoke.py` |
| `llmwiki-agent-bridge` | Local runtime companion bridge for cited answer artifacts. | `npm run check` |
| `llmwiki-chat` | Browser workbench for sources, runtime selection, traces, citations, and graph context. | `npm run check` |
| `llmwiki-docs` | Cross-repo documentation portal. | `npm run check` |

## Community

Before opening a pull request, read [CONTRIBUTING.md](./CONTRIBUTING.md), keep
changes focused on the bridge contract, and include validation results.

Use GitHub issues for reproducible bugs, focused feature requests, runtime or
protocol compatibility notes, and documentation gaps. Keep examples public and
sanitized; do not include credentials, bearer tokens, private endpoint URLs, raw
sensitive wiki content, or private runtime logs.

- [Bug reports](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/issues/new?template=bug_report.yml)
- [Runtime or protocol compatibility](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/issues/new?template=runtime_protocol.yml)
- [Feature requests](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/issues/new?template=feature_request.yml)
- [Documentation issues](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/issues/new?template=documentation.yml)
- [Security policy](./SECURITY.md)
- [Support guide](./SUPPORT.md)
- [Code of conduct](https://github.com/knowledge-bridge-labs/llmwiki-agent-bridge/blob/main/CODE_OF_CONDUCT.md)

For vulnerabilities, follow [SECURITY.md](./SECURITY.md) instead of opening a
detailed public issue.

## License

Apache-2.0. See [LICENSE](./LICENSE).