Files
Algis DumbrisandClaude Opus 4.7 069a985af5 feat(020): 14d window + token-budget circuit breaker + dream-agent + dashboard
Backend (Go, in this commit):
- migration 029_memory_dream_usage: per (date, owner) counters for
  tokens_in/out, jobs_started/succeeded/failed/circuit_broken
- DreamUsageStore + UsageGate (internal/messaging/dream_usage.go).
  Gate inspects today's usage against new env knobs:
  - SYNAPBUS_DREAM_RECENT_WINDOW (default 336h / 14d)
  - SYNAPBUS_DREAM_DAILY_TOKEN_LIMIT_IN (default 1M)
  - SYNAPBUS_DREAM_DAILY_TOKEN_LIMIT_OUT (default 200k)
  - SYNAPBUS_DREAM_DAILY_JOB_LIMIT (default 100)
- Consolidator now bounds watermarks + core_rewrite eligibility by the
  recency window. core_rewrite skipped for owners with no in-window
  activity. ForceRun honors the breaker.
- Recency fallback in BuildContextPacket + memory_list_unprocessed now
  accept RecentWindowDays so injection and dream queries see the same
  14d slice.
- Prometheus metrics registered (internal/metrics/metrics.go):
  synapbus_dream_jobs_total{owner,job_type,status},
  synapbus_dream_tokens_total{owner,direction},
  synapbus_dream_job_duration_seconds{owner,job_type},
  synapbus_dream_circuit_broken_total{owner,reason},
  synapbus_injection_packets_total{tool},
  synapbus_injection_memories_per_packet{tool},
  synapbus_injection_packet_chars{tool},
  synapbus_injection_skipped_total{tool,reason}.
- deploy/kubic/deployment.yaml: liveness/readiness timeoutSeconds: 1→5
  (root-causes the "connection refused" mcpproxy errors at 13:02 today —
  /readyz occasionally exceeded 1s under dream-worker tick load, so the
  pod fell out of the Service endpoints intermittently).

Dream-claude agent (Python, in /dream-agent/):
- dream_runner.py uses claude-agent-sdk 0.1.48 to drive Claude Code
  against SynapBus's MCP server. MCP transport carries
  Authorization: Bearer <api_key> AND X-Synapbus-Dispatch-Token from env
  via the SDK's McpHttpServerConfig.headers field — confirmed supported.
- Tools restricted via allowed_tools to mcp__synapbus__memory_*.
- Final JSON envelope reports tokens_in/out so harness.Usage stays
  populated and the circuit breaker can count consumption.
- Dockerfile builds linux/amd64 at 189 MB, mirroring searcher's
  agents/universal recipe.
- k8s-job-template.yaml: backoffLimit 0, ttl 600s, 512Mi/1CPU,
  Anthropic credentials via secret-ref.

Grafana dashboard (deploy/kubic/grafana/):
- dream-dashboard.json — 14 panels across 5 rows (dream activity,
  token usage vs limit, circuit breaker, injection layer, MCP
  transport health), all templated to ${DS_PROMETHEUS}.
- import.sh: resolves the cluster's Prometheus DS uid and POSTs the
  dashboard via Grafana API.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:58:28 +03:00

2.2 KiB

synapbus-dream-agent

A slim Python container that performs memory consolidation for SynapBus, dispatched on demand by the in-server ConsolidatorWorker via the k8sjob harness backend.

What it does

  1. Reads its job context from env vars (dispatch token, job id, job type, owner id, prompt).
  2. Connects to SynapBus's MCP endpoint over streamable-http, passing the agent's API key (Authorization: Bearer ...) and the dispatch token (X-Synapbus-Dispatch-Token: ...) on every request.
  3. Runs Claude Code (via claude-agent-sdk) constrained to the six memory_* MCP tools defined in specs/020-proactive-memory-dream-worker/contracts/mcp-memory-tools.md.
  4. Streams structured JSON logs to stdout (Loki-friendly) and emits a final {"final": true, ...} envelope so the harness can parse Usage.

How the worker invokes it

internal/messaging/consolidator.go builds an HarnessExecRequest with:

Env var Set by
SYNAPBUS_DISPATCH_TOKEN ConsolidatorWorker
SYNAPBUS_CONSOLIDATION_JOB_ID ConsolidatorWorker
SYNAPBUS_JOB_TYPE ConsolidatorWorker
SYNAPBUS_OWNER_ID ConsolidatorWorker
SYNAPBUS_DREAM_PROMPT ConsolidatorWorker
SYNAPBUS_RUN_ID k8sjob harness
SYNAPBUS_URL, SYNAPBUS_API_KEY, ANTHROPIC_API_KEY Pod spec / Secret

Build

docker buildx build --platform=linux/amd64 \
  -t kubic.home.arpa:32000/synapbus-dream-agent:v0.1.0 \
  --load /Users/user/repos/synapbus/dream-agent/

Push:

docker push kubic.home.arpa:32000/synapbus-dream-agent:v0.1.0

Local smoke test

The --mock flag validates the env contract and exits without invoking the SDK or hitting the network:

SYNAPBUS_URL=http://localhost:8080 \
SYNAPBUS_API_KEY=fake \
SYNAPBUS_DISPATCH_TOKEN=fake \
SYNAPBUS_CONSOLIDATION_JOB_ID=1 \
SYNAPBUS_JOB_TYPE=reflection \
SYNAPBUS_OWNER_ID=algis \
SYNAPBUS_DREAM_PROMPT="test" \
SYNAPBUS_RUN_ID=r-test \
python3 dream_runner.py --mock

Deploy

See k8s-job-template.yaml. The harness clones the template and overlays req.Env into containers[0].env.