mirror of
https://github.com/akitaonrails/ai-memory.git
synced 2026-10-02 03:24:46 +08:00
OpenCode Zen/Go notified operators that requests missing an
`x-opencode-session` header may start erroring, and reported ai-memory's
traffic as "Unknown client — your requests carry no user agent, so we
can't tell what sends them". Both halves are real: `reqwest` sends no
`User-Agent` unless one is configured, and nothing in the crate could
attach a caller-supplied header.
Add `AI_MEMORY_LLM_HEADERS` (`llm_headers` in config.toml): comma-separated
`Name=Value` / `Name: Value` entries, parsed and validated once at the
configuration boundary into a typed `ExtraHeaders`, then sent on every chat
request. This follows the rule provider auth already obeys — providers
consume typed material and never re-parse operator strings — and means a
malformed entry fails at startup rather than on the first consolidation
pass. Headers ai-memory sets itself are refused rather than duplicated:
`RequestBuilder::header` appends, so a second `authorization` would break
the request instead of overriding it. Values are marked sensitive and never
logged; `Debug` prints names only.
Two defaults ride on the same mechanism, layered *under* the operator's so
an explicit entry always wins:
- `User-Agent: ai-memory/<version>` on every provider. Not opencode-specific:
an unattributable request is the one a rate limiter throttles first, and
any gateway benefits from knowing what called it. Copilot is excluded — it
keeps `GitHubCopilotChat/<version>`, the agent GitHub's API expects.
- `x-opencode-session` on the `opencode` provider, one id per process, since
that header is Zen/Go's own request-correlation field.
Zen/Go permits this. Its documentation ("Where can I use it?", docs/go.mdx)
says Go "is designed to be used with OpenCode and other popular coding
agents that produce a similar types of requests", documents the
`https://opencode.ai/zen/go/v1/...` endpoints for direct use, and asks that
the calling tool "does not generate abusive traffic" and "properly
identifies itself (no broad user agents)". Hence naming ai-memory in the
agent string rather than copying OpenCode's own — identifying the caller is
the requirement, and impersonation would defeat it.
Integration tests drive `build_provider` against wiremock: asserting the
header is on the struct is not the same claim as asserting the right single
value is on the wire.
50 lines
1.7 KiB
YAML
50 lines
1.7 KiB
YAML
# docker-compose.yml for ai-memory.
|
|
#
|
|
# Run from this directory:
|
|
# docker compose up -d
|
|
# Attach Claude Code (or any MCP HTTP client) at
|
|
# http://localhost:49374/mcp
|
|
# State persists in the `ai-memory-data` volume; move it between hosts
|
|
# by stopping the container, `docker volume export` (or rsync the
|
|
# mountpoint), and importing on the target.
|
|
|
|
services:
|
|
ai-memory:
|
|
image: ai-memory:local
|
|
build:
|
|
context: ..
|
|
dockerfile: docker/Dockerfile
|
|
container_name: ai-memory
|
|
restart: unless-stopped
|
|
user: "1000:1000"
|
|
volumes:
|
|
- ai-memory-data:/data
|
|
ports:
|
|
# Bind to loopback by default; flip to 0.0.0.0:49374 when serving
|
|
# the homelab LAN. Keep behind a reverse proxy if you do.
|
|
- "127.0.0.1:49374:49374"
|
|
env_file:
|
|
- path: .env
|
|
required: false
|
|
environment:
|
|
- RUST_LOG=ai_memory=info,ai_memory_store=info,ai_memory_wiki=info,ai_memory_mcp=info,tracing_appender=warn
|
|
# LLM provider configured via docker/.env (gitignored). Options:
|
|
# anthropic | openai | openai-oauth | anthropic-oauth | copilot |
|
|
# gemini | openai-compat | opencode
|
|
# See .env.production.example for the full reference.
|
|
#
|
|
# Extra headers on every LLM chat request, for a gateway that requires
|
|
# a caller-identifying one. Comma-separated `Name=Value` entries; the
|
|
# default `User-Agent: ai-memory/<version>` needs no configuration.
|
|
# - AI_MEMORY_LLM_HEADERS=x-opencode-session=homelab-01
|
|
healthcheck:
|
|
test: ["CMD", "/usr/local/bin/ai-memory", "status"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 5s
|
|
|
|
volumes:
|
|
ai-memory-data:
|
|
name: ai-memory-data
|