Skip to content

Configuration Reference

cycgraph exposes operational tuning through environment variables (read once at module load, Zod-validated) and constructor options (passed when wiring components). This page is the single reference for both.

Where to override. Env vars are easiest for ops; constructor options are easiest for tests and embedded deployments. They never conflict — env vars set the defaults, constructor options override per-instance.

All values are validated against RuntimeConfigSchema in @cycgraph/orchestrator/runtime-config. Out-of-bounds values throw at module load rather than producing a broken cache size or negative timeout.

Env varDefaultBoundsPurpose
AGENT_CONFIG_CACHE_TTL_MS300000 (5 min)1s – 1hTTL for cached agent configs in the factory
MAX_AGENT_CONFIG_CACHE_SIZE1001 – 10,000Max cached agent configs
FALLBACK_CONFIG_CACHE_TTL_MS30000 (30s)1s – 1hShorter TTL for fallback configs so DB recovery is detected sooner
AGENT_TIMEOUT_MS120000 (2 min)1s – 1hTimeout for a single agent LLM invocation
MAX_MEMORY_PROMPT_BYTES51200 (50 KB)1 KB – 10 MBMax serialized memory injected into the system prompt
MAX_MEMORY_VALUE_BYTES1048576 (1 MB)1 KB – 100 MBMax bytes for a single memory value — reducer drops oversized values into state.memory_drops
MAX_VISITED_NODES100010 – 1,000,000Ring-buffer cap on state.visited_nodes
MAX_SUPERVISOR_HISTORY10010 – 100,000Ring-buffer cap on state.supervisor_history
MAX_MEMORY_DROPS501 – 10,000Ring-buffer cap on state.memory_drops
FILTREX_CACHE_SIZE2568 – 100,000LRU cap on the filtrex expression compile cache
SymptomLikely lever
Workflow logs say memory_dropped every runRaise MAX_MEMORY_VALUE_BYTES, or trim the agent’s output. Confirm in state.memory_drops.
LLM 504s under loadIncrease AGENT_TIMEOUT_MS. Verify it’s the LLM that’s slow, not your network.
OOM on large graphs with deep visited pathsLower MAX_VISITED_NODES (ring buffer).
Memory grows over hours of supervisor loopsLower MAX_SUPERVISOR_HISTORY.
Cold start latency dominated by graph loadIncrease FILTREX_CACHE_SIZE if you have many distinct edge conditions.

Passed to new GraphRunner(graph, state, options). Source: runner/graph-runner.ts.

OptionTypeDefaultPurpose
persistencePersistenceProviderin-memoryGraph + state storage backend
eventLogEventLogWriterin-memoryAppend-only event log + checkpoints
usageRecorderUsageRecordernoopCost / token recorder
toolResolverToolResolvernoneMCP tool resolution (MCPConnectionManager recommended)
contextCompressorContextCompressornoneCompress memory before prompt injection
memoryRetrieverMemoryRetrievernonePull facts from the hierarchical memory graph. Only fires for nodes that declare a memory_query directive.
memoryWriterMemoryWriternonePersist facts produced by reflection nodes. Required for reflection nodes to function.
factSanitizerFactSanitizernonePre-write hook applied to every reflection fact. Return null to drop, or a modified fact to substitute. Fails closed: a thrown sanitizer drops the fact (see factSanitizerFailMode).
factSanitizerFailMode'drop' | 'pass''drop'What to do when factSanitizer throws. 'drop' (default) discards the fact so unredacted PII is never persisted; 'pass' writes the original fact (fail open).
rateLimiterRateLimiternoneAwaited before every LLM call (agent / supervisor / evaluator) to pace a run inside a provider’s budget. The implementation may delay (throttle) or throw (hard ceiling — surfaces as the node’s error, follows its failure_policy). Abortable; propagated into subgraphs.
compaction_intervalnumber1000Events between automatic event-log compactions (checkpoint + delete-behind, recovery-safe) when an eventLog is wired. Defaults on so a long run can’t grow the log unbounded; set 0 to retain full history and compact manually via compactEvents().
persistDeltaFn(patch: StatePatch) => Promise<void>noneDifferential persistence — when set with persistStateFn, the runner sends patches here and full snapshots to persistStateFn. A failed write rolls back the delta baseline so no patch is lost.
middlewareRunnerMiddleware[][]beforeNodeExecute / afterReduce hooks
allow_implicit_completionbooleanfalseWhen a non-end node has no outgoing edge whose condition matches, the runner fails the run with NoMatchingEdgeError (a dead-end is almost always a routing bug). Set true to restore the legacy behavior of silently completing the workflow at that node.

A pre-flight wiring check runs at the start of every run(): a graph containing a reflection node with no memoryWriter, or a node declaring MCP tool sources with no toolResolver, fails immediately (before any node executes) instead of mid-run. A memory_query directive with no memoryRetriever logs a warning.

The agent factory fails closed on an unknown agent_id (throws AgentNotFoundError). Opt into the legacy default-agent fallback with configureAgentFactory(registry, { allowDefaultFallback: true }) — see Agents.

Source: mcp/connection-manager.ts.

OptionTypeDefaultPurpose
cache_ttl_msnumber300000 (5 min)TTL for cached tool manifests. 0 disables.
default_tool_timeout_msnumber30000 (30s)Per-tool execution timeout. Overridable per-server via MCPServerEntry.tool_timeout_ms.
default_max_concurrent_callsnumber0 (unlimited)Default cap on concurrent tool calls per MCP server. Overridable per-server via MCPServerEntry.max_concurrent_calls. A FIFO semaphore bounds in-flight calls so a wide fan-out (evolution / voting / map candidates all hitting one server) can’t overwhelm it.
tool_circuit_breakerToolCircuitBreakerOptions | nullenabled with defaultsPer-tool breaker. Pass null to disable entirely.
OptionDefaultPurpose
failure_threshold5Consecutive failures that open the breaker
success_threshold2Consecutive successes in half_open to close
cooldown_ms30000 (30s)Window the breaker stays open before transitioning to half_open

Snapshot metrics via manager.getToolCircuitMetrics() — wire to a /metrics endpoint or middleware.

Source: @cycgraph/orchestrator-postgres.

OptionDefaultPurpose
retain_checkpoints3How many checkpoints per run to keep. Older ones are pruned inside the same transaction as each new write. Minimum 1 enforced.

Source: @cycgraph/memory.

OptionDefaultPurpose
expectedDimensionsunsetStrict dimension check — every embedding indexed or queried must match. Mismatch throws EmbeddingDimensionMismatchError. Wire from EmbeddingProvider.dimensions.
silenceScaleWarningfalseSuppress the one-shot console warning when the brute-force index crosses 10K entries. Set true only for stress tests.

Misconfiguration fails loud, not silent:

  • Setting MAX_MEMORY_VALUE_BYTES=0 would silently drop every memory update. The Zod schema rejects it at startup with a descriptive error.
  • Setting retain_checkpoints=0 would orphan the run from any usable replay anchor. DrizzleEventLogWriter throws in its constructor.
  • A 512-dim EmbeddingProvider talking to a 1536-dim pgvector schema produced silently wrong cosine scores. With expectedDimensions set, the first query throws.

Every default above is also the recommended starting point — change one knob at a time, watch for the symptom listed in When to tune.