Skip to content

Latest commit

 

History

History
156 lines (124 loc) · 9.69 KB

File metadata and controls

156 lines (124 loc) · 9.69 KB

Config & environment

One strict YAML struct serves both hosts (the proxy loads a file; the AuthBridge plugin hands its config: subtree to the same loader). A preset expands to a default pipeline; explicit fields override it.

Config shape

The document has six top-level fields (from the Config struct in config/config.go):

Field Type Role
preset string Named default pipeline (see Presets).
pipeline []string Ordered component names — controls order + enablement. Overrides the preset's pipeline when present.
components:<name> map Each component's typed config block, handed to its constructor verbatim.
store object State store options — see store below.
mode string Operating mode: sync (default) | observe. See Operating modes.
observe object Observe-mode tuning; ignored in sync mode.

store

Field Default Purpose
enabled true Toggles the state store. false wires a store.Nop: nothing is stashed, so offloads become one-way and must run marker_mode: off.
ttl_seconds 10000 Entry lifetime, and it slides — a Get refreshes the deadline, so an entry replayed every turn never ages out. Raised from 1800 because Terminal-Bench tasks average ~1975 s of wall clock and run to 4 h, so the old default expired live frozen decisions mid-task.
max_entries 1000 LRU cap. Frozen-decision keys (cg:frz:, cg:res:, cg:len:) are pinned — exempt from LRU eviction, because losing one is cache-destructive rather than merely a miss. The pin is capped at half max_entries, and eviction reclaims expired entries first (pinned included).
max_sessions 100 Cap on per-session sticky-id sets.

The pinned prefixes are a code-level property of the key layout, supplied by their owners via store.Options.PinPrefixes — not a YAML knob.

mode

Value Behavior
sync (default) Compact inline; the caller waits. Byte-identical to the behavior before modes existed.
observe Forward the request untouched and report what compaction would have saved, under potential_* / projected_* keys. The request path never runs the pipeline and skips expand.Inject too (a tool declaration is a modification), so byte-identity is structural.

Always explicit — nothing infers it from the rest of the configuration.

!!! note "An async mode is designed but not shipped" A third mode deferring compaction off the request path is implemented on a separate branch and deliberately held pending a benchmark arm establishing a benefit. sync and observe are the only values the loader accepts.

observe

Field Default Purpose
max_queue 256 Bound on the off-path measurement queue. A full queue drops (counted as dropped) and never blocks the request path.
workers 1 Drain goroutines. One keeps a single measurement's cheap-model call in flight per process, which keeps that spend and gateway rate limits predictable.

!!! warning "Strict: unknown keys are rejected" The YAML loader runs with KnownFields(true), so a typo'd key fails loudly at load time rather than being silently ignored.

Example

preset: balanced
pipeline: [format, dedup, failed_run, cmdfilter, cachesplit]   # order + enable
components:
  collapse:   { max_tokens: 2000, head_lines: 20, tail_lines: 20 }
  smartcrush: { min_items: 5, keep_first: 3, keep_last: 2 }
  cmdfilter:  { min_size: 500 }
store: { ttl_seconds: 10000, max_entries: 1000 }
mode: sync                          # sync | observe

A component registers its constructor + config type via init(), so adding one makes it YAML-configurable with no core edit. See Components for every component's config block.

Flags & environment

Flag / env Default Purpose
--preset / PRESET codesmart Pipeline preset when no --config.
--config / CONFIG YAML config file (overrides preset).
LISTEN_ADDR :4000 Listen address.
--openai-upstream / OPENAI_UPSTREAM https://api.openai.com OpenAI upstream base.
--anthropic-upstream / ANTHROPIC_UPSTREAM https://api.anthropic.com Anthropic upstream base.
OPENAI_API_KEY / ANTHROPIC_API_KEY Real key injected on forward (gateway mode); empty = pass client auth through.
CHEAP_MODEL (+ CHEAP_MODEL_BASE / _KEY / _AUTH / _PROVIDER) Dedicated cheap model for the LLM components (extract_llm, summarize) — the model.source: config client. Without it they no-op.
FORCE_MODEL Overwrite the request model (eval-containers uses EVAL_MODEL).
INJECT_EXPAND auto Whether the context_guru_expand tool is advertised: auto (only when the request already declares tools and the store persists) | always | never.
CACHE_MODE auto Cache-aware compaction: auto (on when the agent sets its own breakpoints) | on | off.
MODEL_INFO_URL / MODEL_INFO LiteLLM map Source for context-window sizes (used by the fractional triggers). MODEL_INFO=off disables the lookup; fractions are then ignored and absolutes apply.
--store / STORE on Enable/disable the state store; --store=false disables offload reversibility. Wins over the file's store: block.
--mode / MODE sync Operating mode: sync | observe. Wins over the file's mode:.

Extraction-model pricing

extract_llm's economic gate only calls the LLM when the expected saving exceeds the expected cost, so it needs the real price of a call. The cost is computed from observed token usage × these rates — never a hard-coded per-call constant. Defaults are claude-haiku-4-5 list rates; override them to match your contract.

Env Default Purpose
CHEAP_MODEL_PRICE_IN 1.00 Extraction-model input price, dollars per million tokens.
CHEAP_MODEL_PRICE_OUT 5.00 Output price per MTok.
CHEAP_MODEL_PRICE_CACHE_WRITE 1.25 Cache-write price per MTok (1.25× input).
CHEAP_MODEL_PRICE_CACHE_READ 0.10 Cache-read price per MTok (0.1× input).

An unparseable or absent value silently keeps the default — pricing must never fail a request.

!!! note "extract_llm is off by default on caching backends" Independently of pricing, the component declines to run on prompt-caching traffic unless allow_on_caching_backend: true is set — measured net-negative there. See extract_llm.

Dashboard

The dashboard is off by default. Enabling it adds /dashboard/ and /api/*; nothing else about the proxy changes.

Flag / env Default Purpose
--dashboard / DASHBOARD off Enable the persistent dashboard (embedded UI + JSON/SSE API).
--dashboard-db / DASHBOARD_DB ./context-guru-dashboard.db SQLite path. :memory: keeps history in RAM only (the no-persistence mode). An unwritable path falls back to in-memory with a warning rather than failing to start.
--dashboard-retention / DASHBOARD_RETENTION 168h (7 days) Drop rows older than this. 0 disables the age rule.
--dashboard-max-bytes / DASHBOARD_MAX_BYTES 536870912 (512 MiB) Cap the database size, dropping the oldest requests first. 0 disables the size rule.
--dashboard-content / DASHBOARD_CONTENT false Capture before/after message text for the diff view. Opt-in: it stores arbitrary agent output on disk, scrubbed of known credential shapes and size-capped before storage — but content cannot be allowlisted the way headers and config keys are, so the safe default is off.
--dashboard-content-cap / DASHBOARD_CONTENT_CAP 16384 Maximum bytes stored per captured before/after blob.
--dashboard-queue / DASHBOARD_QUEUE 4096 Capture-channel depth. A full channel drops events (counted, and shown in the UI) rather than delaying a request.
--dashboard-trusted-cidrs / DASHBOARD_TRUSTED_CIDRS Comma-separated CIDRs allowed to view per-request content and the effective config. Loopback always is; aggregates are open to everyone.
--dashboard-bench-dirs / DASHBOARD_BENCH_DIRS Comma-separated directories of benchmark runs (each with summary.json + rows-*.json) to ingest at startup. Re-ingesting replaces a run rather than duplicating it.

!!! note "Retention is bounded by age AND size" Age alone cannot bound a burst of traffic; size alone silently erases a quiet week. The age rule runs first, then the size rule drops the oldest remaining requests until the file fits.

!!! warning "There is deliberately no 'disable observability in production' switch" For a tool whose value is observability, that would be backwards. What is gated is per-request content and the effective configuration — not the metrics.

Example (container)

DASHBOARD=true \
DASHBOARD_DB=/var/lib/context-guru/dashboard.db \
DASHBOARD_RETENTION=720h \
DASHBOARD_MAX_BYTES=2147483648 \
DASHBOARD_TRUSTED_CIDRS=10.0.0.0/8,192.168.0.0/16 \
context-guru-proxy --preset codesmart

Diagnostics

Env Effect
CONTEXT_GURU_DEBUG=1 Logs each tool output's token count + first line.
CONTEXT_GURU_DUMP=<file> Appends a before → after JSON record per rewritten message. The dashboard captures the same material into a queryable store with a diff view.
CONTEXT_GURU_CAPTURE=<file> Appends each pristine inbound request as one JSONL record, for offline replay through /compact.