Skip to main content

TruvaG3 Framework Environment Variables Guide

This document provides a comprehensive reference for all environment variables supported by the TruvaG3 framework. Variables are organized by module/functionality with their default values, descriptions, and verification status.

Table of Contents​

  1. Kubernetes Deployment Requirements (Start here for K8s)
  2. Core Configuration
  3. HTTP Server Configuration
  4. CORS Configuration
  5. Discovery Configuration
  6. AI Configuration
  7. AI Provider-Specific Variables
  8. Telemetry Configuration
  9. Memory Configuration
  10. Shared Memory Configuration
  11. Activity Coordination Configuration
  12. Logging Configuration
  13. Development Configuration
  14. Kubernetes Configuration
  15. Orchestration Configuration
  16. LLM Debug Configuration
  17. Execution Debug Store Configuration
  18. Human-in-the-Loop (HITL) Configuration
  19. Async Task Configuration
  20. Prompt Configuration
  21. Agent Skills Configuration
  22. Quick Reference Table

Important Notes​

Variable Status Legend:

  • Implemented - Read by the documented owning constructor/configuration path (Getenv or presence-aware LookupEnv); setting it does not automatically wire that feature into an application
  • Struct Tag Only - Defined in struct tags but NOT currently loaded (requires code changes to work)
  • Example Only - Used in example applications, not core framework

The following controls have no dedicated environment variable. Use the owning API; setting a similarly named env key does not configure them.

BehaviorProgrammatic controlDefault / scope
Reasoning-as-answer compatibilityai.WithReasoningContentFallback(bool), ai.WithChainReasoningContentFallback(bool), direct codec ReasoningContentFallbackfalse; compatible-codec response policy, not a model/token limit
Shared-memory lookbackWithMemoryLookback(d) / direct WithEnrichmentLookback(d)24h; independent of event retention and digest TTL
Event-summary batch sizeWithSummarizerMaxStepsPerBatch(n)20; excess steps get heuristic fallback
Calculated summary tokens per stepWithSummarizerTokensPerStep(n)Explicit option selects calculated budgeting (floor 300 per call); otherwise 10000 fixed; explicit fixed override wins
Failed-input disclosure restrictionFailedOperationViewConfig.InputPolicynil permits bounded views; applications can restrict or disable
Recording-only request entitiesWithBuilderRecordRequestEntityExtractor / direct WithRecordRequestEntityExtractorunset; enrichment/claim acquisition unchanged
Per-acquisition claim expirycore.InvestigationLeaseRequest.TTL0 selects provider default; negative invalid

The reasoning token multiplier is configurable by environment: TRUVAG3_AI_REASONING_TOKEN_MULTIPLIER (default 3). A positive ai.WithReasoningTokenMultiplier(int) or ai.WithChainReasoningTokenMultiplier(int) overrides it; explicit 1 keeps caps exact. Reviewed-model ceiling checks still apply. See AI Configuration.

Returned completion provenance, request lifecycle revisions and physical dispatch counts need no new enablement flag. Existing debug-store enablement, access and retention settings still govern persistence. There is no env knob for rewriting provider finish reasons or turning empty completion into success.

Kubernetes Deployment Requirements​

This section provides a quick reference for deploying TruvaG3 agents and tools in Kubernetes. Variables are categorized by requirement level to help you configure deployments correctly.

Working Examples: See agent-example/k8-deployment.yaml for a complete agent deployment and tool-example/k8-deployment.yaml for a complete tool deployment.

Required Variables (All Deployments)​

These variables are mandatory for proper operation in Kubernetes:

VariableWhy RequiredHow to Set
TRUVAG3_AGENT_NAMEValidation fails without it (core/config.go — if c.Name == "" check in Validate)Static value
Redis connection sourceRequired when discovery is enabled (auto-enabled in K8s): use either standalone REDIS_URL or structured TRUVAG3_REDIS_MODE + TRUVAG3_REDIS_ADDRSConfigMap, Secret, or static value as appropriate
TRUVAG3_K8S_SERVICE_NAMECritical for service-fronted discovery URL registrationMust match your K8s Service name
TRUVAG3_K8S_SERVICE_PORTService port for discovery URL (default: 80)Must match your K8s Service port

Required Variables (via fieldRef)​

These are populated automatically by Kubernetes using fieldRef:

VariablefieldRef SourcePurpose
TRUVAG3_K8S_NAMESPACEmetadata.namespacePod namespace for service URL construction
TRUVAG3_K8S_POD_IPstatus.podIPPod IP address for health checks
TRUVAG3_K8S_NODE_NAMEspec.nodeNameNode placement info for debugging

Required for AI Agents Only​

Tools don't need AI configuration, but agents using AI features require:

VariablePurpose
OPENAI_API_KEYOr any other AI provider key (see AI Provider-Specific Variables)
VariableDefaultWhy Recommended
TRUVAG3_DISCOVERY_RETRYfalseSet to true to handle Redis startup race conditions
TRUVAG3_DISCOVERY_RETRY_INTERVAL30sBackground retry interval when Redis unavailable
TRUVAG3_DEV_MODEfalseExplicitly disable for production

Auto-Detected (No Need to Set)​

VariableAuto-Detection
KUBERNETES_SERVICE_HOSTSet by K8s automatically, triggers K8s mode
HOSTNAMESet by K8s to pod name
TRUVAG3_ADDRESSAuto-set to 0.0.0.0 in K8s mode
TRUVAG3_LOG_FORMATAuto-set to json in K8s mode

Minimal Tool Deployment​

env:
# REQUIRED - Core Identity
- name: TRUVAG3_AGENT_NAME
value: "weather-tool"

# REQUIRED - Service Discovery
- name: REDIS_URL
value: "redis://redis.truvag3-examples:6379"

# REQUIRED - Service-Fronted Discovery (must match Service definition)
- name: TRUVAG3_K8S_SERVICE_NAME
value: "weather-tool-service"
- name: TRUVAG3_K8S_SERVICE_PORT
value: "80"

# REQUIRED - K8s Metadata (via fieldRef)
- name: TRUVAG3_K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: TRUVAG3_K8S_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: TRUVAG3_K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName

# RECOMMENDED - Resilience
- name: TRUVAG3_DISCOVERY_RETRY
value: "true"
- name: TRUVAG3_DISCOVERY_RETRY_INTERVAL
value: "30s"

Minimal Agent Deployment (with AI)​

env:
# Same as Tool (above), plus:

# REQUIRED - AI Provider Key
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: ai-provider-keys
key: OPENAI_API_KEY

# OPTIONAL - Telemetry
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://otel-collector.truvag3-examples:4318"

Common Mistakes to Avoid​

  1. Missing TRUVAG3_K8S_SERVICE_NAME: Without this, discovery registers the wrong URL and other services can't find your tool/agent.

  2. Mismatched Service Name/Port: The TRUVAG3_K8S_SERVICE_NAME must exactly match your Kubernetes Service's metadata.name, and TRUVAG3_K8S_SERVICE_PORT must match the Service's port (not targetPort).

  3. Combining Redis connection sources: Set exactly one of REDIS_URL, the structured TRUVAG3_REDIS_* topology form. The removed TRUVAG3_REDIS_URL alias is rejected. Contradictory forms fail startup rather than using precedence. Prefer REDIS_URL for standalone deployments and structured configuration for Sentinel or cluster.

  4. Setting TRUVAG3_ADDRESS: This is auto-detected as 0.0.0.0 in K8s - no need to set it.


Core Configuration​

These variables configure the fundamental settings of a TruvaG3 agent or tool.

The resilience-shaped declarations below are struct tags only, not env inputs consumed by core.Config.LoadFromEnv. They are listed to avoid confusing them with the implemented AI and orchestration retry budgets. Configure the owning component programmatically instead.

Reserved declarationDefault in core configurationStatus
TRUVAG3_CB_ENABLEDfalseStruct Tag Only
TRUVAG3_CB_THRESHOLD5Struct Tag Only
TRUVAG3_CB_TIMEOUT30sStruct Tag Only
TRUVAG3_CB_HALF_OPEN3Struct Tag Only
TRUVAG3_RETRY_MAX_ATTEMPTS3Struct Tag Only
TRUVAG3_RETRY_INITIAL_INTERVAL1sStruct Tag Only
TRUVAG3_RETRY_MAX_INTERVAL30sStruct Tag Only
TRUVAG3_RETRY_MULTIPLIER2.0Struct Tag Only
TRUVAG3_TIMEOUT_DEFAULT30sStruct Tag Only
TRUVAG3_TIMEOUT_MAX5mStruct Tag Only
VariableDefaultStatusDescriptionSource
TRUVAG3_AGENT_NAMEtruvag3-agentImplementedName of the agentcore/config.go
TRUVAG3_AGENT_ID(auto-generated)ImplementedUnique identifier for the agent instancecore/config.go
TRUVAG3_PORT8080ImplementedHTTP server portcore/config.go
TRUVAG3_ADDRESSlocalhost (local) / 0.0.0.0 (K8s)ImplementedBind address for the HTTP servercore/config.go
TRUVAG3_NAMESPACEdefaultImplementedLogical namespace for multi-tenancycore/config.go

Example​

export TRUVAG3_AGENT_NAME="weather-tool"
export TRUVAG3_PORT=8085
export TRUVAG3_NAMESPACE="production"

HTTP Server Configuration​

Configure HTTP server timeouts and health check settings.

VariableDefaultStatusDescriptionSource
TRUVAG3_HTTP_READ_TIMEOUT300s in DefaultConfigImplementedMaximum duration for reading the entire requestcore/config.go
TRUVAG3_HTTP_WRITE_TIMEOUT35mImplementedMaximum duration for writing the responsecore/config.go
TRUVAG3_HTTP_READ_HEADER_TIMEOUT10sStruct Tag OnlyMaximum duration for reading request headerscore/config.go
TRUVAG3_HTTP_IDLE_TIMEOUT120sStruct Tag OnlyMaximum duration to wait for the next requestcore/config.go
TRUVAG3_HTTP_MAX_HEADER_BYTES1048576 (1MB)Struct Tag OnlyMaximum size of request headerscore/config.go
TRUVAG3_HTTP_SHUTDOWN_TIMEOUT10sImplementedJoined HTTP shutdown budget for built-in agents/tools. Present values must be positive Go durations; empty, malformed and non-positive values fail loading. Explicit code configuration overrides valid env values; zero typed value selects 10s. This does not forcibly terminate active handlers or hijacked connections.core/config.go
TRUVAG3_HTTP_HEALTH_CHECKtrueStruct Tag OnlyEnable health check endpointcore/config.go
TRUVAG3_HTTP_HEALTH_PATH/healthStruct Tag OnlyPath for health check endpointcore/config.go

Example​

# Explicit overrides; the write timeout below is shorter than the 35m default
export TRUVAG3_HTTP_READ_TIMEOUT="5m"
export TRUVAG3_HTTP_WRITE_TIMEOUT="5m"

CORS Configuration​

Configure Cross-Origin Resource Sharing settings.

VariableDefaultStatusDescriptionSource
TRUVAG3_CORS_ENABLEDfalseImplementedEnable CORS supportcore/config.go
TRUVAG3_CORS_ORIGINS(none)ImplementedComma-separated list of allowed originscore/config.go
TRUVAG3_CORS_METHODSGET,POST,PUT,DELETE,OPTIONSImplementedAllowed HTTP methodscore/config.go
TRUVAG3_CORS_HEADERSContent-Type,AuthorizationImplementedAllowed request headerscore/config.go
TRUVAG3_CORS_CREDENTIALSfalseImplementedAllow credentials (cookies, auth headers)core/config.go
TRUVAG3_CORS_EXPOSED_HEADERS(none)Struct Tag OnlyHeaders exposed to the browsercore/config.go
TRUVAG3_CORS_MAX_AGE86400 (24h)Struct Tag OnlyPreflight cache duration in secondscore/config.go

Example​

export TRUVAG3_CORS_ENABLED=true
export TRUVAG3_CORS_ORIGINS="https://app.example.com,https://*.example.com"
export TRUVAG3_CORS_CREDENTIALS=true

Discovery Configuration​

Configure service discovery for agent/tool registration and lookup.

VariableDefaultStatusDescriptionSource
TRUVAG3_DISCOVERY_ENABLEDfalse (local) / true (K8s)ImplementedEnable service discoverycore/config.go
TRUVAG3_DISCOVERY_PROVIDERredisImplementedDiscovery backend providercore/config.go
TRUVAG3_REDIS_NAMESPACEdefaultImplementedValidated deployment segment shared by every versioned DB-0 key (1–128 ASCII letters, digits, ., _, or -)core/redis_keyspace.go
REDIS_URLredis://localhost:6379ImplementedStandard DB-0 standalone Redis/Valkey URL shorthandcore/redis_connection.go
TRUVAG3_REDIS_MODEstandaloneImplementedStructured topology: standalone, sentinel, or clustercore/redis_connection.go
TRUVAG3_REDIS_ADDRSlocalhost:6379ImplementedComma-separated standalone address, Sentinel addresses, or cluster seed addresses. Required with structured modecore/redis_connection.go
TRUVAG3_REDIS_MASTER_NAME—ImplementedSentinel master name; required only in Sentinel modecore/redis_connection.go
TRUVAG3_REDIS_USERNAME—ImplementedData-node ACL usernamecore/redis_connection.go
TRUVAG3_REDIS_PASSWORD—ImplementedData-node password; supply via a Secretcore/redis_connection.go
TRUVAG3_REDIS_SENTINEL_USERNAME—ImplementedSentinel ACL usernamecore/redis_connection.go
TRUVAG3_REDIS_SENTINEL_PASSWORD—ImplementedSentinel password; supply via a Secretcore/redis_connection.go
TRUVAG3_REDIS_DB0ImplementedShared logical DB; only 0 is accepted in standalone, Sentinel, and cluster modecore/redis_connection.go
TRUVAG3_REDIS_TLS_ENABLEDfalseImplementedEnables TLS with a minimum of TLS 1.2core/redis_connection.go
TRUVAG3_REDIS_TLS_SERVER_NAME—ImplementedTLS server name; requires TLS enabledcore/redis_connection.go
TRUVAG3_REDIS_CA_FILE—ImplementedMounted PEM CA file, read once at startup; requires TLS enabledcore/redis_connection.go
TRUVAG3_REDIS_POOL_SIZE10ImplementedMaximum connections per node (1–10000)core/redis_connection.go
TRUVAG3_REDIS_MIN_IDLE_CONNS5ImplementedMinimum idle connections per node (0 through pool size)core/redis_connection.go
TRUVAG3_REDIS_DIAL_TIMEOUT5sImplementedPositive connection timeout, at most 10mcore/redis_connection.go
TRUVAG3_REDIS_READ_TIMEOUT3sImplementedRead timeout, at most 10m; exact go-redis sentinels -1ns and -2ns are preservedcore/redis_connection.go
TRUVAG3_REDIS_WRITE_TIMEOUT3sImplementedWrite timeout, at most 10m; exact go-redis sentinels -1ns and -2ns are preservedcore/redis_connection.go
TRUVAG3_REDIS_MAX_RETRIES3ImplementedPer-command retry count (-1 disables; maximum 100)core/redis_connection.go
TRUVAG3_DISCOVERY_CACHEtrueImplementedEnable local caching of discovery resultscore/config.go
TRUVAG3_DISCOVERY_RETRYfalseImplementedEnable background retry on initial connection failurecore/config.go
TRUVAG3_DISCOVERY_RETRY_INTERVAL30sImplementedStarting retry interval (increases exponentially)core/config.go
TRUVAG3_DISCOVERY_TTL30sImplementedRegistration TTL for service keys (min 5s)core/config.go
TRUVAG3_DISCOVERY_HEARTBEAT0 (= TTL/2)ImplementedHeartbeat interval for registration refresh (min 2s)core/config.go
TRUVAG3_DISCOVERY_CACHE_TTL5mStruct Tag OnlyCache time-to-livecore/config.go

Variable Precedence​

The development-stage cleanup removed TRUVAG3_REDIS_URL, role-specific TRUVAG3_*_REDIS_DB routing variables, and raw Redis HITL/LLM-debug prefixes. A non-empty removed setting fails construction for its selected backend role; an unselected role's settings are ignored. Empty values count as absent. Use TRUVAG3_REDIS_NAMESPACE and typed keyspace options for isolation. TRUVAG3_EXECUTION_DEBUG_KEY_PREFIX applies only to the generic storage adapter, not Redis.

Redis connection selection is:

  1. Complete explicit Go configuration (WithRedisConnection or a direct constructor), without merging environment connection fields.
  2. Exactly one environment form: REDIS_URL, structured TRUVAG3_REDIS_MODE + related connection fields.
  3. Local DB-0 standalone default.

Operational pool, timeout, and retry variables may accompany either standard environment form. REDIS_URL and structured topology fields are different, mutually exclusive representations; combining them fails validation. Cluster mode, standalone, and Sentinel all require DB 0. A single seed address is valid when cluster mode is explicit—the framework never infers topology from address count.

Example​

export REDIS_URL="redis://redis:6379"
export TRUVAG3_DISCOVERY_CACHE=true
export TRUVAG3_DISCOVERY_RETRY=true
export TRUVAG3_DISCOVERY_RETRY_INTERVAL="30s"
export TRUVAG3_DISCOVERY_TTL="60s"
export TRUVAG3_DISCOVERY_HEARTBEAT="20s"

Sentinel example:

export TRUVAG3_REDIS_MODE="sentinel"
export TRUVAG3_REDIS_ADDRS="sentinel-a:26379,sentinel-b:26379,sentinel-c:26379"
export TRUVAG3_REDIS_MASTER_NAME="mymaster"
export TRUVAG3_REDIS_PASSWORD="${REDIS_DATA_PASSWORD}"
export TRUVAG3_REDIS_SENTINEL_PASSWORD="${REDIS_SENTINEL_PASSWORD}"

Cluster/Valkey cluster example:

export TRUVAG3_REDIS_MODE="cluster"
export TRUVAG3_REDIS_ADDRS="cache-a:6379,cache-b:6379,cache-c:6379"
export TRUVAG3_REDIS_DB="0"
export TRUVAG3_REDIS_POOL_SIZE="20" # per cluster node

Code equivalent (functional options override env vars):

core.NewConfig(
core.WithRedisDiscovery("redis://redis:6379"),
core.WithDiscoveryCacheEnabled(true),
core.WithDiscoveryTTL(60 * time.Second),
core.WithHeartbeatInterval(20 * time.Second),
)

AI Configuration​

Configure AI client settings for LLM integration.

This table distinguishes the core configuration object from direct provider construction. core.Config.LoadFromEnv reads rows marked Implemented into core.Config.AI; it does not automatically pass those values to ai.NewClient or ai.NewRequestClient. Applications using the direct constructors must pass the corresponding ai.With* options. Rows marked Struct Tag Only are metadata declarations that LoadFromEnv does not currently read. Provider-specific variables in the next section and TRUVAG3_AI_RETRY_ATTEMPTS, TRUVAG3_AI_RETRY_DELAY, TRUVAG3_AI_SSE_EVENT_MAX_BYTES, and TRUVAG3_AI_REASONING_TOKEN_MULTIPLIER are read directly by the ai module as documented.

VariableDefaultStatusDescriptionSource
TRUVAG3_AI_ENABLEDfalseImplementedEnable AI featurescore/config.go
TRUVAG3_AI_API_KEY(none)ImplementedAPI key for the provider (auto-enables AI)core/config.go
OPENAI_API_KEY(fallback)ImplementedFallback API key (auto-enables AI)core/config.go
TRUVAG3_AI_MODELgpt-4ImplementedModel name to usecore/config.go
TRUVAG3_AI_BASE_URLProvider-specificImplementedCustom base URL for API callscore/config.go
TRUVAG3_AI_REASONING_TOKEN_MULTIPLIER3ImplementedReasoning headroom on reviewed scaling profiles. Positive code values win; code zero is unset. Empty, malformed, non-positive or overflowing environment values and negative code values fail construction. Explicit 1 keeps budgets exact. Active scaling binds the resolved multiplier into AI-output cache identity.ai/reasoning_budget.go
TRUVAG3_AI_PROVIDERopenaiStruct Tag OnlyAI providercore/config.go
TRUVAG3_AI_TEMPERATURE0.7Struct Tag OnlySampling temperature declaration; permitted values and field support are provider/model-specificcore/config.go
TRUVAG3_AI_MAX_TOKENS2000Struct Tag OnlyMaximum tokens in responsecore/config.go
TRUVAG3_AI_TIMEOUT5m; explicit standalone Bedrock 60mImplemented in AI constructorsRead by ai.NewClient, ai.NewRequestClient, ai.NewChainClient and managed ProviderEntry construction, not core.Config.LoadFromEnv or direct provider constructors/factory calls. Positive code > environment > applicable default. A present value must be a positive Go duration (for example 12m); empty, malformed, zero, negative and overflowing values fail construction even with a code override. Nonpositive code means unset. Injected clients remain caller-owned; earlier caller/phase/HTTP-client deadlines still win.ai/request_timeout.go, ai/client.go
TRUVAG3_AI_RETRY_ATTEMPTS3 for independently constructed clients and heterogeneous ProviderEntry; 0 per provider in legacy NewChainClientImplementedPer-provider retry budget. ai/providers/openai and its registered aliases share this one budget across transport/HTTP and eligible decoded/in-body failures; direct Azure remains transport-only. Retry permission comes from the adapter classifier, and Retry-After can affect delay without adding attempts. Precedence is explicit WithMaxRetries(n) / WithChainMaxRetries(n) > positive environment value > constructor-specific default. NewClient, NewRequestClient, and each NewChain ProviderEntry default to 3. Legacy NewChainClient defaults each provider to 0 so provider retries do not multiply ordered failover attempts. ClientEntry is caller-owned. Zero, negative, and non-integer environment values are rejected and fall through; use an explicit programmatic 0 to disable retries.ai/client.go, ai/chain_client.go, ai/chain_entries.go
TRUVAG3_AI_SSE_EVENT_MAX_BYTES1048576 (1 MiB)ImplementedMaximum bytes in one OpenAI-compatible server-sent event. A positive AIConfig.SSEEventMaxBytes wins; invalid, zero, and negative environment values fall back to 1 MiB. The ceiling is per event, not per response.ai/client.go, ai/providerkit/openaiwire/sse.go
TRUVAG3_AI_RETRY_DELAY1sImplementedInitial exponential delay between provider attempts, including eligible decoded retries in adopting adapters. A positive AIConfig.RetryDelay wins over a positive Go-duration environment value, then the one-second default. Invalid, zero, and negative environment values fall back safely. For an eligible HTTP 429/503 or decoded semantic 429/503, a valid response Retry-After seconds/date value is honored only when it is greater than exponential backoff. It does not grant retry permission or add attempts. Every retry wait ends at the earlier caller deadline or an absolute wait cap: the positive HTTP-client timeout, or the 180-second framework fallback when that timeout is disabled. The cap applies to the wait timer rather than the transport context, so it does not make a successful streaming response body unreadable.ai/client.go, ai/providers/base.go

Example​

export TRUVAG3_AI_ENABLED=true
export TRUVAG3_AI_MODEL="smart"
export TRUVAG3_AI_BASE_URL="https://api.openai.com/v1"

Reaching the provider retry-wait cap returns context.DeadlineExceeded; it does not shorten a required cooldown and then resend early. A caller deadline or cancellation also stops the wait without another provider attempt.


AI Provider-Specific Variables​

The framework supports multiple AI providers with automatic detection based on available API keys and provider-specific indicators. Detection considers only factories linked into the application; import each selected provider package, normally as a blank import. Bedrock must also be compiled with -tags bedrock. See the AI Providers Setup Guide for the registration pattern.

OpenAI (Priority: 1000)​

For the ai/providers/openai implementation and its registered aliases (including OpenRouter), the existing provider retry settings also cover eligible decoded/in-body failures, sharing one budget with HTTP/transport errors. Direct Azure OpenAI adapters retain transport-only retries. These settings do not configure orchestration tool-step retries or outer-chain failover. Adapters opting into ExecuteWithRetryDecoded own the retry decision for actual HTTP 429/5xx as well. OpenRouter uses its conservative typed/status classifier; no new retry env setting enables rejected error types. Eligible decoded semantic 429/503 can use the existing Retry-After wait handling.

The same configured budget covers eligible OpenRouter HTTP/in-body 408 timeouts. Known terminal and unknown nonempty types remain conservative, and other compatible aliases keep their existing 408 behavior. Zero chain retries still permit no same-provider retry; another entry is needed for failover. Caller cancellation, caller/provider-call deadlines and delivered stream output stop recovery. A provider's own TRUVAG3_AI_TIMEOUT expiration stops chain recovery even if the outer caller remains active: returned deadline identity is authoritative. A provider-returned 408 while the attempt context is active remains eligible. No new environment setting or timeout/default change accompanies this classification.

VariableDefaultStatusDescriptionSource
OPENAI_API_KEY(none)ImplementedOpenAI API keyai/providers/openai/factory.go
OPENAI_BASE_URLhttps://api.openai.com/v1ImplementedOpenAI API base URLai/providers/openai/factory.go

Anthropic Claude (Priority: 900)​

VariableDefaultStatusDescriptionSource
ANTHROPIC_API_KEY(none)ImplementedAnthropic API keyai/providers/anthropic/factory.go
ANTHROPIC_BASE_URLhttps://api.anthropic.com/v1ImplementedAnthropic API base URLai/providers/anthropic/client.go, ai/providers/anthropic/factory.go

OpenRouter (Priority: 850)​

VariableDefaultStatusDescriptionSource
OPENROUTER_API_KEY(none)ImplementedOpenRouter API key; activates openai.openrouter auto-detectionai/providers/openai/factory.go
OPENROUTER_BASE_URLhttps://openrouter.ai/api/v1ImplementedOpenRouter API base URLai/providers/openai/factory.go

Built-in aliases are default=smart=openrouter/auto, fast=openai/gpt-6-luna, and code=openrouter/pareto-code. Every alias can be overridden independently without code changes:

OPENROUTER_API_KEY=...
TRUVAG3_OPENROUTER_MODEL_DEFAULT=openai/gpt-5.6-sol
TRUVAG3_OPENROUTER_MODEL_SMART=moonshotai/kimi-k3
TRUVAG3_OPENROUTER_MODEL_FAST=google/gemini-2.5-flash
TRUVAG3_OPENROUTER_MODEL_CODE=moonshotai/kimi-k3

_DEFAULT applies when a call leaves its model unspecified or selects default; _SMART, _FAST, and _CODE apply only when that alias is selected. A per-request exact model wins over the constructor default. See the OpenRouter configuration examples for programmatic and request-aware forms.

Repository example setup scripts also accept the shell-only selector below for an isolated live test when .env contains multiple provider keys:

TRUVAG3_SETUP_AI_PROVIDER=together ./setup.sh rollout

The shared setup helper excludes this selector from application ConfigMaps. Without it, all configured provider keys are deployed for normal failover.

The framework intentionally has no built-in free alias at this time: the protected privacy probe failed for the tested free routes. Exact :free IDs or TRUVAG3_OPENROUTER_MODEL_FREE remain experimental pass-through options, and must support the framework's mandatory data_collection=deny and zdr=true request constraints. Their availability and quotas follow OpenRouter's current free-model and account limits.

Google Gemini (Priority: 800)​

VariableDefaultStatusDescriptionSource
GEMINI_API_KEY(none)ImplementedGoogle Gemini API keyai/providers/gemini/factory.go
GOOGLE_API_KEY(fallback)ImplementedAlternative Google API key (either activates Gemini)ai/providers/gemini/factory.go
GEMINI_BASE_URLhttps://generativelanguage.googleapis.com/v1betaImplementedGemini API base URLai/providers/gemini/client.go, ai/providers/gemini/factory.go

Groq (Priority: 700)​

VariableDefaultStatusDescriptionSource
GROQ_API_KEY(none)ImplementedGroq API keyai/providers/openai/factory.go
GROQ_BASE_URLhttps://api.groq.com/openai/v1ImplementedGroq API base URLai/providers/openai/factory.go

DeepSeek (Priority: 600)​

VariableDefaultStatusDescriptionSource
DEEPSEEK_API_KEY(none)ImplementedDeepSeek API keyai/providers/openai/factory.go
DEEPSEEK_BASE_URLhttps://api.deepseek.comImplementedDeepSeek API base URLai/providers/openai/factory.go

xAI Grok (Priority: 500)​

VariableDefaultStatusDescriptionSource
XAI_API_KEY(none)ImplementedxAI API keyai/providers/openai/factory.go
XAI_BASE_URLhttps://api.x.ai/v1ImplementedxAI API base URLai/providers/openai/factory.go

Mistral AI (Priority: 450)​

VariableDefaultStatusDescriptionSource
MISTRAL_API_KEY(none)ImplementedMistral AI API keyai/providers/openai/factory.go
MISTRAL_BASE_URLhttps://api.mistral.ai/v1ImplementedMistral AI API base URLai/providers/openai/factory.go

Alibaba Qwen (Priority: 400)​

VariableDefaultStatusDescriptionSource
QWEN_API_KEY(none)ImplementedQwen API keyai/providers/openai/factory.go
QWEN_BASE_URLhttps://dashscope-intl.aliyuncs.com/compatible-mode/v1ImplementedQwen API base URLai/providers/openai/factory.go

Together AI (Priority: 300)​

VariableDefaultStatusDescriptionSource
TOGETHER_API_KEY(none)ImplementedTogether AI API keyai/providers/openai/factory.go
TOGETHER_BASE_URLhttps://api.together.ai/v1ImplementedTogether AI API base URLai/providers/openai/factory.go

The built-in Together aliases, authenticated and live-tested on August 20, 2026, are default=deepseek-ai/DeepSeek-V4-Flash-0731, fast=google/gemma-4-31B-it, and smart=code=moonshotai/Kimi-K3. Exact caller-supplied model IDs continue to pass through unchanged.

Ollama (Priority: 100 - Local)​

VariableDefaultStatusDescriptionSource
OLLAMA_BASE_URLhttp://localhost:11434/v1ImplementedOllama local server URL (must be explicitly set to activate detection)ai/providers/openai/factory.go

Note: Ollama is only auto-detected when OLLAMA_BASE_URL is explicitly set. The framework does not probe localhost:11434 by default to avoid a 2-second timeout penalty in environments where Ollama is not running.

AWS Bedrock (Priority: 200, or 250 for detected Lambda/ECS environments)​

Bedrock support is compiled only when the application is built with -tags bedrock. Without that tag the provider is not registered and none of the detection rows below can select it.

VariableDefaultStatusDescriptionSource
AWS_ACCESS_KEY_ID(none)ImplementedAWS access key; triggers framework auto-detection only when AWS_SECRET_ACCESS_KEY is also non-emptyai/providers/bedrock/factory.go
AWS_SECRET_ACCESS_KEY(none)ImplementedAWS secret key; triggers framework auto-detection only when AWS_ACCESS_KEY_ID is also non-emptyai/providers/bedrock/factory.go
AWS_SESSION_TOKEN(none)Implemented by AWS SDKOptional session token used with temporary static credentials; does not trigger framework auto-detection by itselfAWS SDK for Go v2 configuration
AWS_REGIONus-east-1ImplementedAWS region. If this resolves outside us-east-1, request preparation rejects an invocation that would use the implicit Sonnet 5 default; configure an explicit framework client or per-request model/profile, an endpoint resolver, or direct-package Client.SetDefaultModel.ai/providers/bedrock/factory.go, ai/providers/bedrock/client.go
AWS_DEFAULT_REGION(fallback)ImplementedAlternative region variable; the same post-model-selection implicit Sonnet 5 guard appliesai/providers/bedrock/factory.go, ai/providers/bedrock/client.go
AWS_PROFILE(none)ImplementedAWS CLI profile nameai/providers/bedrock/factory.go
AWS_EXECUTION_ENV(auto)ImplementedManaged AWS runtime indicator, including Lambda/ECS environmentsai/providers/bedrock/factory.go
AWS_LAMBDA_FUNCTION_NAME(auto)ImplementedSet in Lambda environmentai/providers/bedrock/factory.go
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI(auto)ImplementedSet in ECS environmentai/providers/bedrock/factory.go

The factory returns priority 250 when availability is established by AWS_EXECUTION_ENV, AWS_LAMBDA_FUNCTION_NAME, or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI. A static environment credential pair or AWS_PROFILE is checked first and yields priority 200 even if a managed runtime indicator is also present; a detected ~/.aws/credentials file also uses priority 200. Credential loading then delegates to the AWS SDK default credential chain unless explicit ai.WithAWSCredentials values were supplied.

Framework auto-detection is intentionally narrower than the AWS SDK credential chain. Explicit ai.WithProvider("bedrock") construction can use other SDK-supported sources—such as web identity, ECS/EKS container credentials, or an EC2 instance role—even when those sources alone do not satisfy TruvaG3's detector. See the official AWS SDK for Go v2 configuration guide.

Semantic Model Alias Overrides​

Model override variables change the semantic model selected for a portable alias. They do not rewrite route-owned Azure deployment names, Vertex publisher-model IDs, Bedrock modelId values, inference-profile IDs, or ARNs. Only a non-empty environment value overrides the built-in mapping.

The OpenAI default alias maps to gpt-6.1-sol; this applies to all calls inheriting it, including planning and synthesis. Existing pins still win. Use TRUVAG3_OPENAI_MODEL_DEFAULT=gpt-5.6-terra to retain the previous default. The fast aliases now map to gpt-6-luna (OpenAI) and openai/gpt-6-luna (OpenRouter). Pin the previous choices with TRUVAG3_OPENAI_MODEL_FAST=gpt-5.6-luna and TRUVAG3_OPENROUTER_MODEL_FAST=openai/gpt-5.6-luna if required. Other aliases are unchanged. Azure and other shared-catalog consumers resolve both new models; their application-owned deployment mappings must support it or use a pin. GPT-6.1 Sol does not accept reasoning effort none; this alias setting does not change effort, token budgets or phase-specific model overrides.

Provider/profileOverride patternExamples and route behavior
OpenAI, Azure OpenAI, Google-hosted OpenAI compatibilityTRUVAG3_OPENAI_MODEL_{ALIAS}TRUVAG3_OPENAI_MODEL_SMART=gpt-5.6-sol; Azure resolver maps are keyed by the resulting semantic model
DeepSeekTRUVAG3_DEEPSEEK_MODEL_{ALIAS}Applies to openai.deepseek
GroqTRUVAG3_GROQ_MODEL_{ALIAS}Applies to openai.groq
OpenRouterTRUVAG3_OPENROUTER_MODEL_{ALIAS}Applies to openai.openrouter; e.g. TRUVAG3_OPENROUTER_MODEL_DEFAULT=openai/gpt-5.6-sol
Together AITRUVAG3_TOGETHER_MODEL_{ALIAS}Applies to openai.together
xAITRUVAG3_XAI_MODEL_{ALIAS}Applies to openai.xai
MistralTRUVAG3_MISTRAL_MODEL_{ALIAS}Applies to openai.mistral
QwenTRUVAG3_QWEN_MODEL_{ALIAS}Applies to openai.qwen
OllamaTRUVAG3_OLLAMA_MODEL_{ALIAS}Applies to openai.ollama
Anthropic direct and Vertex-hosted ClaudeTRUVAG3_ANTHROPIC_MODEL_{ALIAS}Vertex resolver maps are keyed by the resulting semantic model
Google GeminiTRUVAG3_GEMINI_MODEL_{ALIAS}Applies to the native Gemini provider
AWS BedrockNo provider-specific alias environment variableUse ai.WithModel or an SDK-destination EndpointResolver

Resolver maps receive EndpointRequest.ResolvedModel, which is the concrete post-alias semantic model. For example, a map must use "gpt-5.6-sol" rather than "smart" after TRUVAG3_OPENAI_MODEL_SMART=gpt-5.6-sol.

Azure semantic resolution uses the immutable built-in OpenAI catalog plus the environment overrides above. Runtime mutations of the compatibility variable openai.ModelAliases apply to the OpenAI provider, but not to Azure.

Hosted Enterprise Profiles Without Auto-Detection​

The following profiles intentionally have no framework-owned API-key or base-URL environment shortcut:

SurfaceSelectionRequired construction
Azure OpenAI v1ai.WithProviderAlias("azureopenai.v1")ai.NewRequestClient with WithEndpointResolver plus WithAPIKey, WithCredentialSource, or WithAuthHeader
Azure OpenAI classicai.WithProviderAlias("azureopenai.classic")Same as v1; resolver must supply the deployment URL and exactly one non-empty api-version
Vertex-hosted Claudeai.WithProviderAlias("anthropic.vertex")ai.NewRequestClient with a Vertex route and Google bearer-token credential source
Google Cloud OpenAI compatibilityai.WithProviderAlias("openai")ai.NewRequestClient with the Google OpenAI-compatible route and bearer-token credential source

The Azure factory returns (0, false) from provider auto-detection. Anthropic auto-detection can select only the direct anthropic profile; it never proposes anthropic.vertex. Vertex also rejects direct Anthropic APIKey and BaseURL configuration, so setting ANTHROPIC_API_KEY or ANTHROPIC_BASE_URL does not configure that profile. Provider SDKs used inside application-owned token sources may honor their own environment variables, but those variables are not read or interpreted by TruvaG3.

Official provider contracts: Azure OpenAI v1 chat completions, Azure OpenAI classic versioned REST endpoints, OpenAI compatibility on Google Cloud, and Claude request predictions on Google Cloud.

Auto-Detection Priority​

When no explicit provider is specified, the framework auto-detects available, linked providers:

  1. OpenAI (1000) - OPENAI_API_KEY
  2. Anthropic (900) - ANTHROPIC_API_KEY
  3. OpenRouter (850) - OPENROUTER_API_KEY
  4. Gemini (800) - GOOGLE_API_KEY or GEMINI_API_KEY; GOOGLE_API_KEY wins when both are set
  5. Groq (700) - GROQ_API_KEY
  6. DeepSeek (600) - DEEPSEEK_API_KEY
  7. xAI (500) - XAI_API_KEY
  8. Mistral (450) - MISTRAL_API_KEY
  9. Qwen (400) - QWEN_API_KEY
  10. Together AI (300) - TOGETHER_API_KEY
  11. Bedrock (200, or 250 when detected through Lambda/ECS indicators) - AWS credentials; static credential/profile indicators take precedence; available only with -tags bedrock
  12. Ollama (100) - Requires OLLAMA_BASE_URL to be explicitly set

Azure OpenAI, Vertex-hosted Claude, and Google Cloud OpenAI compatibility are not additional auto-detection candidates. They require explicit request-aware construction as described above.

Adding OPENROUTER_API_KEY can therefore change an unpinned ai.NewClient() or ai.NewRequestClient() selection: when neither OpenAI nor Anthropic is available, OpenRouter wins over Gemini and every lower-priority provider. Pin ai.WithProviderAlias("openai.openrouter") when that selection must not depend on the process environment.

Overriding Auto-Detection Priority​

The priority values above are hardcoded defaults used only during auto-detection (when calling ai.NewClient() without specifying a provider). Developers can override this behavior in several ways:

1. Explicit Provider Selection - Bypasses auto-detection entirely:

// Use Anthropic regardless of OpenAI having higher priority
client, _ := ai.NewClient(ai.WithProvider("anthropic"))

2. Provider Aliases - Select specific OpenAI-compatible services:

// Use DeepSeek even if OPENAI_API_KEY is also set
client, _ := ai.NewClient(ai.WithProviderAlias("openai.deepseek"))

3. Chain Client - Define your own failover order:

// Your order: Groq → DeepSeek → OpenAI (ignores default priorities)
client, _ := ai.NewChainClient(
ai.WithProviderChain("openai.groq", "openai.deepseek", "openai"),
)

4. Custom Provider with Higher Priority - Become the default:

func (p *CustomProvider) DetectEnvironment() (priority int, available bool) {
if os.Getenv("CUSTOM_LLM_KEY") != "" {
return 1100, true // Higher than OpenAI's 1000
}
return 0, false
}

Note: There is no environment variable to change the priority order. To use a specific provider, use explicit selection or provider aliases in your code. See AI Module README for detailed examples.


Telemetry Configuration​

Configure OpenTelemetry-based observability (metrics and tracing).

VariableDefaultStatusDescriptionSource
TRUVAG3_TELEMETRY_ENABLEDfalseImplementedEnable telemetry collectioncore/config.go
TRUVAG3_TELEMETRY_ENDPOINT(none)ImplementedOTLP receiver endpoint (auto-enables telemetry)core/config.go
OTEL_EXPORTER_OTLP_ENDPOINT(fallback)ImplementedStandard OTEL endpoint variable (auto-enables telemetry)core/config.go
TRUVAG3_TELEMETRY_SERVICE_NAMEAgent nameImplementedService name for traces/metricscore/config.go
TRUVAG3_TELEMETRY_SERVICE_INSTANCE_IDGenerated UUID v4ImplementedIdentity per emitting OpenTelemetry provider, shared by traces and metrics. Non-empty telemetry.Config.ServiceInstanceID / WithServiceInstanceID overrides it. Read once at construction; present-empty, invalid UTF-8, surrounding whitespace and control characters are rejected. Explicit IDs must differ across concurrent service replicas.telemetry/otel.go
OTEL_SERVICE_NAME(fallback)ImplementedStandard OTEL service namecore/config.go
TRUVAG3_TELEMETRY_PROVIDERotelStruct Tag OnlyTelemetry providercore/config.go
TRUVAG3_TELEMETRY_METRICStrueStruct Tag OnlyEnable metrics collectioncore/config.go
TRUVAG3_TELEMETRY_TRACINGtrueStruct Tag OnlyEnable distributed tracingcore/config.go
TRUVAG3_TELEMETRY_INSECUREtrueStruct Tag OnlyUse insecure connection (no TLS)core/config.go

The endpoint/name rows configure core.Config.Telemetry; applications still initialize the optional telemetry module and pass the resolved values. Direct telemetry.Initialize(Config) uses its supplied endpoint (empty defaults to localhost:4318) and does not read those endpoint/name variables automatically. EnableTelemetry(agent, "") reads the standard endpoint variable as its fallback. Instance identity is resolved directly by the telemetry constructor as described in its row.

TRUVAG3_TELEMETRY_SAMPLING_RATE has no current config field or reader. The stock provider explicitly uses AlwaysSample, so OTEL_TRACES_SAMPLER and OTEL_TRACES_SAMPLER_ARG also do not change its trace sampler. Profile selection does not reduce trace sampling. Generic OTEL_RESOURCE_ATTRIBUTES does not merge into the constructor's explicit resource.

Telemetry Logger Variables​

These are used by the telemetry module's internal logger:

VariableDefaultStatusDescriptionSource
TRUVAG3_LOG_LEVELINFOImplementedLog level for telemetry loggertelemetry/logger.go
TRUVAG3_DEBUGfalseImplementedEnable debug loggingtelemetry/logger.go
TELEMETRY_DEBUGfalseImplementedEnable telemetry-specific debugtelemetry/logger.go
TRUVAG3_LOG_FORMATtext (local) / json (K8s)ImplementedLog format overridetelemetry/logger.go
KUBERNETES_SERVICE_HOST(auto)ImplementedAuto-detect K8s for JSON loggingtelemetry/logger.go

Example​

export OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4318"
export OTEL_SERVICE_NAME="weather-tool"

Memory Configuration​

Configure state storage for agents.

VariableDefaultStatusDescriptionSource
TRUVAG3_MEMORY_MAX_SIZE1000Reserved (struct tag only)Reserved for future use; not yet consumed at runtime.core/config.go — MemoryConfig.MaxSize
TRUVAG3_MEMORY_DEFAULT_TTL1hReserved (struct tag only)Reserved for future use; not yet consumed at runtime.core/config.go — MemoryConfig.DefaultTTL
TRUVAG3_MEMORY_CLEANUP_INTERVAL10mImplementedSweep interval for the in-process *core.MemoryStore eviction sweeper, used by Framework.AutoRegisterMemorySweeper() and tools that register core.NewMemoryStoreSweeper(...) directly. Format: time.Duration (e.g. 5m, 30s).core/config.go LoadFromEnv

Removed env vars (no longer parsed as of the InMemoryStore cleanup): TRUVAG3_MEMORY_PROVIDER, TRUVAG3_MEMORY_REDIS_URL. The framework only ships one Memory implementation today (*core.MemoryStore, in-process); the prior "redis" provider option was unimplemented. To use Redis-backed memory, inject a custom core.Memory implementation by setting agent.Memory = redisStore before calling core.NewFramework.


Shared Memory Configuration​

Configure cross-agent shared memory — episodic events, knowledge extraction, activity compaction, and digest caching. Shared memory enables agents in the same domain to see each other's actions and coordinate.

Core configuration validation: Config.LoadFromEnv/NewConfig now reject explicitly empty, malformed, non-positive or overflowing core-owned numeric memory/activity settings, including when disabled. Compaction recent detail allows zero. Absent settings use DefaultConfig values; the enrichment budget also checks the four-byte conversion bound. File and typed configuration receive the same range checks. This startup rule does not alter runtime fail-open behavior. The hook builder also validates generic parsing and ranges for hook-owned numeric settings before checking optional dependencies; invalid input returns an error, not a partial hook bundle. Implementation-specific arithmetic bounds, such as the built-in compactor's five-times-target allowance, are additionally checked when that implementation is selected. The event-summarizer override is hook-owned, not parsed by core. Core validation alone is not backend wiring: BuildMemoryHooks and NewSharedBackends do not accept core.Config, and they do not consume SharedMemory or ActivityCoordination values assigned in Go or loaded from JSON. Those fields are loaded/validated data, not an automatic runtime override. Until an explicit handoff is implemented, configure the standard bundles through their documented environment variables/options, or construct hooks/backends directly with their typed options. Direct composition must also carry any desired environment tuning; it does not inherit tuning from an independently built bundle.

Ownership and precedence matter: BuildMemoryHooks reads hook-owned overrides and otherwise keeps direct-constructor defaults. Its behavioral options include entity extractors and lookback, but it does not accept direct-hook numeric options. NewSharedBackends validates its own stream/claim settings before I/O. Direct constructors do not inherit these environment overrides automatically. Changing env after construction does not reconfigure existing instances.

JSON null, malformed numeric types and empty env values are explicit invalid settings, not “unset.” Relative retrieval weights must be finite but may be signed/zero and need not sum to one. This strict numeric-memory rule is separate from general orchestration compatible-mode fallback and from skills' own precedence rules.

VariableDefaultStatusDescriptionSource
TRUVAG3_SHARED_MEMORY_PROVIDERnoopImplementedStorage provider (redis, noop). Agents must use redis for cross-agent memory.core/config.go
TRUVAG3_VECTOR_DB_URLlocalhost:6334 for direct vector constructionImplementedQdrant gRPC address used by memory vector configuration; backend/embedding wiring remains explicit. Setting an address alone does not enable every memory hook.memory/vector_config.go
TRUVAG3_AGENT_DOMAINdefaultImplementedGroups agents for memory scoping. Agents in the same domain see each other's events.core/config.go
TRUVAG3_SHARED_MEMORY_STREAM_MAXLEN100000ImplementedMax events in the Redis domain stream (approximate, uses ~MAXLEN).core/config.go
TRUVAG3_SHARED_MEMORY_INVESTIGATION_TTL30mImplementedPositive advisory investigation-claim expiry, not renewed. Managed request cleanup releases on exit/HITL suspension; resume acquires fresh ownership. It need not span the human wait. Legacy/direct-hook callers own their lifecycle.core/config.go
TRUVAG3_SHARED_MEMORY_ENRICHMENT_MAX_TOKENS2000ImplementedBuildMemoryHooks reads this at startup for both raw and compacted memory views. Bounds the hook's own contribution at four encoded bytes per token; complete records and omission markers fit inside that budget. Invalid/empty/non-positive/overflowing values fail construction. Direct construction uses WithEnrichmentMaxTokens, which rejects invalid values.memory_hook_builder.go
TRUVAG3_SHARED_MEMORY_RECENT_EVENTS_LIMIT20ImplementedRecent domain events for baseline situational awareness (without compactor). Higher values show more cross-agent activity but consume more prompt tokens.core/config.go
TRUVAG3_SHARED_MEMORY_SUMMARIZER_MODEL"" (agent default)ImplementedModel for LLM event summarization and activity compaction calls. Accepts aliases such as fast and smart only when the selected provider defines them, or a concrete model ID.core/config.go
TRUVAG3_SHARED_MEMORY_EVENT_SUMMARIZER_MAX_TOKENS10000ImplementedPositive fixed base output-token allowance per event-summary batch, before provider reasoning expansion. Read at startup by BuildMemoryHooks; invalid explicit values fail construction, including without an AI client. Independent of synthesis, compaction and stored summary size. Direct constructors use WithSummarizerMaxTokens(n) instead.orchestration/memory_hook_builder.go
TRUVAG3_SHARED_MEMORY_EVENT_SUMMARIZER_SUMMARY_MAX_BYTES1024ImplementedPer-entry stored derived prose limit (minimum 32 UTF-8 bytes). Overlong prose is explicitly marked shortened; exact entity IDs and raw LLM debug completions remain intact. Invalid explicit values fail builder construction. Direct constructor: WithSummarizerSummaryMaxBytes(n).orchestration/event_summarizer.go
TRUVAG3_SHARED_MEMORY_EVENT_SUMMARIZER_TIMEOUT2mImplementedPositive builtin AI-invocation deadline, not a memory-write timeout. Earlier parent deadline wins; invalid/empty/non-positive values fail BuildMemoryHooks even without dependencies. Direct constructor: WithSummarizerTimeout(d).orchestration/memory_hook_tuning.go
TRUVAG3_SHARED_MEMORY_EVENT_SUMMARIZER_MAX_RESPONSE_BYTES4000ImplementedPositive per-step encoded payload allowance shared by failure facts and response in the built-in summary prompt. Invalid/empty/overflow values fail builder construction, including without AI/memory dependencies. Direct construction uses WithSummarizerMaxResponseChars(n) (legacy name; byte units). Independent of output-token limits.orchestration/event_summarizer.go
TRUVAG3_SHARED_MEMORY_RECORD_FAILURE_CAUSE_MAX_BYTES256ImplementedPositive UTF-8 byte allowance for the cause in heuristic failure summaries. Framing and explicit shortening marker are additional. Invalid/empty/overflow values fail builder construction even without AI/memory dependencies. Direct option: WithRecordFailureCauseMaxBytes(n). Original execution errors and model/custom summaries stay unchanged.orchestration/memory_hooks.go
TRUVAG3_SHARED_MEMORY_ENRICHMENT_SUMMARY_MAX_TOKENS500ImplementedRequested digest length in the built-in compactor prompt. Full and incremental calls supply AIOptions.MaxTokens = 5 × target (2500 by default), before any provider reasoning scaling. A selected built-in compactor requires target ≤ math.MaxInt / 5; hook construction rejects overflow, and direct non-empty compaction calls enforce the same check before invoking AI. Custom compactors retain their own generation rules. The target is not a tokenizer-enforced cap; the final enrichment view has a separate byte budget.orchestration/activity_compactor.go
TRUVAG3_SHARED_MEMORY_COMPACTION_RAW_LIMIT200ImplementedMax raw events fetched before compaction. Higher values give the compactor more context but increase LLM input size.core/config.go
TRUVAG3_SHARED_MEMORY_COMPACTION_RECENT_DETAIL15ImplementedRaw events appended after the compacted digest for immediate detail access. Set to 0 to disable.core/config.go
TRUVAG3_SHARED_MEMORY_DIGEST_CACHE_TTL5mImplementedTTL for cached domain activity digests. When expired, next request triggers full compaction. Go duration format.core/config.go
TRUVAG3_SHARED_MEMORY_DIGEST_INCREMENTAL_THRESHOLD20ImplementedMax new events for incremental digest update. Above this threshold, full recompaction is triggered instead.core/config.go
TRUVAG3_SHARED_MEMORY_COMPACTION_ENABLEDfalseParsed; application wiring requiredLoads Config.SharedMemory.CompactionEnabled. Applications must pass it through WithCompactorEnabled when constructing MemoryCompactor, then invoke RunCompaction on their chosen schedule. No background worker is started by this flag. It does not control the request-time activity digest that BuildMemoryHooks installs when an AI client is supplied.core/config.go, orchestration/memory_compaction.go

Builtin event-summary deadline​

TRUVAG3_SHARED_MEMORY_EVENT_SUMMARIZER_TIMEOUT: positive Go duration, default 2m, resolved by orchestration.BuildMemoryHooks. Explicit empty, malformed, non-positive or overflowing values fail construction even when AI or memory is absent. Only the builtin AI invocation gets a child deadline; shorter enclosing contexts win. Custom summarizers are unchanged. Direct constructor users choose WithSummarizerTimeout; that layer does not read this environment variable.


User Memory Configuration​

Configure per-user private memory for personal assistant agents. User memory stores learned facts (preferences, identity, constraints) across sessions and injects them into the planning prompt via a <user_profile> enrichment tag — enabling personalized agent responses without replaying raw conversation history. Numeric tuning uses environment variables; behavioural plugs (custom extractors, reconcilers) use WithXXX() options on BuildUserMemoryHooks.

VariableDefaultStatusDescriptionSource
TRUVAG3_USER_MEMORY_COLLECTIONtruvag3_user_memoryImplementedVector DB collection name for user facts. Separate from shared knowledge collection. Used by the reference implementation (VectorUserMemory).memory/vector_user_memory.go
TRUVAG3_USER_MEMORY_MAX_FACTS_IN_PROMPT15ImplementedOverall cap on facts injected into the <user_profile> enrichment tag after lifetime-aware selection. Higher values give the LLM more personalization context but consume more prompt tokens.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_IDENTITY_FACTS5ImplementedMax identity facts (name, location, language) always included regardless of query relevance.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_DURABLE_FACTS_IN_PROMPT8ImplementedSoft ceiling for durable facts (identity, preferences, constraints, relationships) selected before transient and summary facts compete for prompt space.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_TRANSIENT_FACTS_IN_PROMPT4ImplementedSoft ceiling for transient/context facts in prompt selection after durable facts are considered.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_SUMMARY_FACTS_IN_PROMPT3ImplementedSoft ceiling for summary facts included for cross-session continuity after durable and transient selection.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_CONTEXT_FACTS—Legacy CompatibilityLegacy fallback for transient prompt-budget configuration. Used only when TRUVAG3_USER_MEMORY_MAX_TRANSIENT_FACTS_IN_PROMPT is unset. Prefer the lifetime-aware variable instead.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_SUMMARY_FACTS—Legacy CompatibilityLegacy fallback for summary prompt-budget configuration. Used only when TRUVAG3_USER_MEMORY_MAX_SUMMARY_FACTS_IN_PROMPT is unset. Prefer the lifetime-aware variable instead.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_STABLE_FACTS_PER_CATEGORY2ImplementedMax stable namespace facts (constraints, preferences, relationships) fetched per category via category-based retrieval — bypasses semantic similarity so durable user attributes (e.g., home airport, dietary restrictions) are always injected regardless of query relevance. Applied only in non-universal namespaces.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MAX_UNIVERSAL_FACTS5ImplementedMax universal-namespace facts (cross-agent preferences, constraints) retrieved per request.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_MIN_CONFIDENCE0.3ImplementedMinimum confidence threshold for fact inclusion. Facts below this are excluded from enrichment.orchestration/user_memory_hooks.go
TRUVAG3_USER_MEMORY_RECONCILIATION_THRESHOLD0.75ImplementedCosine similarity threshold for triggering LLM reconciliation. Below this, candidate facts are treated as new (ADD).orchestration/user_memory_hook_builder.go
TRUVAG3_USER_MEMORY_EXTRACTION_MODEL"" (agent default)ImplementedModel for fact extraction and session summary LLM calls. Use a fast/cheap model — these are high-volume, low-complexity calls.orchestration/user_memory_hook_builder.go
TRUVAG3_USER_MEMORY_RECONCILIATION_MODELextraction modelImplementedModel for reconciliation LLM calls. Falls back to extraction model if unset.orchestration/user_memory_hook_builder.go
TRUVAG3_USER_MEMORY_SUMMARY_MAX_RESPONSE_LEN500ImplementedMax characters of agent response included in the session summary prompt. Truncated at UTF-8 rune boundary.orchestration/user_memory_extraction.go
TRUVAG3_USER_MEMORY_BATCH_TOKENS_PER_CANDIDATE400ImplementedOutput token budget per candidate in the batched reconciliation LLM call (default reconciler collapses N per-candidate calls into one). Floors at 500 tokens for tiny batches. Increase if you see truncated merged_content on UPDATE-heavy turns; decrease for tighter cost control.orchestration/user_memory_extraction.go
TRUVAG3_USER_MEMORY_RECALL_OVERFETCH_MULTIPLIER3ImplementedOver-fetch multiplier used by vector-backed recall before lifetime filtering so transient cleanup and bucket selection do not under-fill results.memory/vector_user_memory.go
TRUVAG3_USER_MEMORY_TRANSIENT_MAX_AGE_HOURS168ImplementedMax age in hours for transient/context facts during recall-time filtering. Unset, invalid, or non-positive values fall back to 168 hours (7 days).memory/user_memory_backend.go
TRUVAG3_USER_MEMORY_MAX_SPLIT_CLAUSES3ImplementedMax number of clauses emitted when Phase 4 splitting expands a mixed extracted fact before storage/reconciliation.orchestration/user_memory_extraction.go

Framework Runnable Lifecycle​

Background components implementing core.Runnable are registered with the framework via framework.RegisterRunnable(r). They start in goroutines when Run(ctx) is called and shut down when ctx is cancelled (typically by SIGTERM in Kubernetes). In-tree consumers include memory reflection/sweeping, schedulers and queue workers, Redis Streams reaping, and the provider-neutral HITL checkpoint-expiry processor. Any long-running background work an agent needs can implement the same lifecycle contract.

Because Go provides no mechanism for forcibly terminating goroutines, the framework gives each runnable a bounded grace period to honour ctx.Done() and exit cleanly. After the grace period, the framework logs a warning, returns from Run, and lets the OS reap any remaining goroutines on process exit. Buggy runnables that ignore ctx will leak until process exit — the framework cannot recover from this.

VariableDefaultStatusDescriptionSource
TRUVAG3_FRAMEWORK_RUNNABLE_DRAIN_TIMEOUT10sImplementedMaximum time Framework.Run waits for registered core.Runnable instances to exit after ctx is cancelled. Go duration format (5s, 30s, 2m). Only positive values are honored — invalid or zero values fall back to the default. Shorter values trade clean shutdown for faster pod termination; longer values give in-flight reflection passes or other long-running jobs more time to finish their current iteration.core/agent.go

If you have a runnable that may legitimately need more than 10 seconds to wind down (e.g., a reflection pass mid-LLM-call), raise this. Conversely, if Kubernetes is killing your pods because shutdown takes too long, lower it — but be aware that runnables may be terminated mid-operation and any in-flight LLM calls or Redis writes will be abandoned.

The corresponding lifecycle log events are documented in LOGGING_IMPLEMENTATION_GUIDE.md under the framework_runnable_* operations and the runnable_drain_timeout error_type.


Reflection Job Configuration​

Configure the background reflection job that bridges Tier 2 (episodic events in Redis) to Tier 3 (semantic knowledge fragments in Qdrant). The job runs on a periodic schedule, discovers entities with accumulated old events, asks an LLM to extract reusable patterns, embeds them, and stores them in the vector knowledge collection.

Configuration follows the Configuration Split principle from FRAMEWORK_DESIGN_PRINCIPLES.md: numeric tuning is via environment variables, behavioural plugs are via Go options. The available With* options are:

  • On NewReflectionJob / BuildReflectionJob (ReflectionJobOption): WithReflectionLock(core.DistributedLock), WithReflectionTelemetry(core.Telemetry). See memory/reflection_job.go.
  • On NewLLMMemoryReflector (ReflectorOption): WithReflectorLogger(core.Logger), WithReflectorTelemetry(core.Telemetry), WithReflectorMinEvents(int), WithReflectorModel(string). See memory/reflector.go.

The reflection job is wired automatically by BuildReflectionJob when Phase 2 backends (SharedKnowledge + EmbeddingClient) are available. It is registered with the framework via framework.RegisterRunnable(job) and managed by the framework lifecycle (started on Run, stopped on context cancel).

VariableDefaultStatusDescriptionSource
TRUVAG3_REFLECTION_INTERVAL24hImplementedHow often the reflection pass runs. Go duration format (5m, 6h, 24h). Shorter intervals increase LLM cost; longer intervals delay knowledge accumulation.memory/reflection_job.go
TRUVAG3_REFLECTION_AGE_THRESHOLD168h (7 days)ImplementedOnly events older than this are eligible for reflection. Should be longer than the activity compactor's window — events younger than this are still represented in the per-request activity digest, so reflecting them prematurely spends LLM tokens on under-developed patterns. Go duration format.memory/reflection_job.go
TRUVAG3_REFLECTION_MIN_EVENTS5ImplementedMinimum events per entity required to trigger reflection. Below this, the entity is skipped. Propagated to both the job's discovery pass and the LLM reflector — they share the same threshold. Lower values produce more fragments from less data (riskier); higher values produce fewer, more confident fragments.memory/reflection_job.go, memory/reflection_job_builder.go
TRUVAG3_REFLECTION_MODEL"" (AIClient default)ImplementedModel used for the reflection LLM call. Accepts a portable alias (fast, smart, default) when the selected provider defines that alias, or a concrete model ID. The selected provider performs alias resolution; Bedrock has no portable-alias catalog. Empty string means "use the AIClient's default selection." Reflection is durable—fragments influence every future request—so this is a real cost-vs-quality trade-off. See Choosing a model for reflection below.memory/reflector.go, memory/reflection_job_builder.go

Choosing a model for reflection​

Reflection runs periodically (default: once per 24 hours, configurable via TRUVAG3_REFLECTION_INTERVAL) and writes durable knowledge fragments into Qdrant. Those fragments are recalled by semantic search and injected into <agent_memory> for every future request. The cost-vs-quality trade-off is therefore unlike per-request orchestration calls — a sloppy fragment isn't a one-off mistake, it lingers and surfaces as confident "prior knowledge" for as long as it remains in Qdrant.

Recommended configurations:

Use caseTRUVAG3_REFLECTION_MODELTRUVAG3_REFLECTION_MIN_EVENTSReasoning
Default (production)unset (uses agent default)5Best fragment quality. Reflection runs infrequently so cost is bounded.
High volume / cost-sensitivefast5Cheaper and faster per pass. min_events=5 ensures the cheap model only sees entities with strong signal.
Aggressive learningunset2Captures patterns from sparse-event entities. Use only with the strongest model — low signal × weak model = noise.
Bulk indexing of historical datafast10When backfilling reflection over a large existing event log, the cheap model handles the volume and the high min_events floor filters out low-signal entities.

Where supported, aliases (fast, smart, default, code, vision) are resolved by the selected AI provider at call time. Bedrock does not define portable alias mappings. The authoritative alias-to-model mappings live in the provider source files, not in this guide—copying the concrete mappings here would silently desynchronize them from code on every model release. See:

Providers with an environment-backed model catalog can override an alias without recompiling—for example, TRUVAG3_ANTHROPIC_MODEL_FAST=claude-haiku-4-5 or TRUVAG3_GROQ_MODEL_FAST=llama-3.1-8b-instant. See Semantic Model Alias Overrides for the exact supported prefixes and the hosted-provider semantic/wire boundary.

The Anthropic example above deliberately pins the previous fast model. The built-in fast model is now Haiku 5.5; smart/code/vision select Opus 5.5. For migration requirements and Vertex mapping impact, see the Anthropic alias refresh.

To set the model programmatically (Layer 3, bypassing the env var):

reflector, err := memory.NewLLMMemoryReflector(
aiClient, episodic, "infrastructure", logger,
memory.WithReflectorModel("fast"),
)
if err != nil {
return err
}

Activity Coordination Configuration​

Configure real-time agent coordination signals. Activity signals are transient Redis KV entries with TTL that allow agents to see what other agents are currently working on — enabling coordination without waiting for episodic events (which are only written after execution completes).

VariableDefaultStatusDescriptionSource
TRUVAG3_ACTIVITY_COORDINATION_ENABLEDtrueImplementedEnable/disable the activity coordination layer. When false, no signals are emitted or read.core/config.go
TRUVAG3_ACTIVITY_SIGNAL_TTL5mImplementedPositive expiry for transient activity signals. Managed request segments renew at TTL/3 and join renewal before cleanup, so TTL need not exceed the request duration. Direct/unmanaged callers own renewal.orchestration/execution_activity.go
TRUVAG3_ACTIVITY_SIGNAL_MAX_IN_PROMPT10ImplementedMax activity signals shown in the <agent_coordination> prompt section. Most recent first after filtering.core/config.go
TRUVAG3_ACTIVITY_SIGNAL_QUERY_MAX_LEN200ImplementedRequest-query byte prefix retained in activity signals; legacy helper appends ... when truncated. This is not a rune count or an exact final-size cap.orchestration/activity_hooks.go

Logging Configuration​

Configure logging output format and level.

VariableDefaultStatusDescriptionSource
TRUVAG3_LOG_LEVELinfoImplementedMinimum log level (debug, info, warn, error)core/config.go
TRUVAG3_LOG_FORMATjson (K8s) / text (local)ImplementedOutput formatcore/config.go
TRUVAG3_LOG_OUTPUTstdoutStruct Tag OnlyOutput destinationcore/config.go
TRUVAG3_LOG_TIME_FORMATRFC3339NanoStruct Tag OnlyTimestamp formatcore/config.go

Development Configuration​

Configure development-mode settings.

VariableDefaultStatusDescriptionSource
TRUVAG3_DEV_MODEfalseImplementedEnable development mode (sets debug logging, text format)core/config.go
TRUVAG3_MOCK_AIfalseImplementedUse mock AI responsescore/config.go
TRUVAG3_MOCK_DISCOVERYfalseImplementedUse in-memory mock discoverycore/config.go
TRUVAG3_DEBUGfalseImplementedEnable debug loggingcore/config.go
TRUVAG3_PRETTY_LOGSfalseStruct Tag OnlyEnable human-readable logscore/config.go

Effects of TRUVAG3_DEV_MODE=true​

When enabled, automatically sets:

  • TRUVAG3_LOG_LEVEL to debug
  • TRUVAG3_LOG_FORMAT to text
  • Pretty logs enabled

Kubernetes Configuration​

Kubernetes-specific settings. Most are auto-detected when running in K8s.

VariableDefaultStatusDescriptionSource
KUBERNETES_SERVICE_HOST(auto)ImplementedAuto-set by K8s, triggers K8s modecore/config.go
HOSTNAME(auto)ImplementedPod name, auto-set by K8score/config.go
TRUVAG3_K8S_NAMESPACE(auto-detected)ImplementedPod namespacecore/config.go
TRUVAG3_K8S_SERVICE_NAMEAgent nameImplementedKubernetes service namecore/config.go
TRUVAG3_K8S_SERVICE_PORT80ImplementedKubernetes service portcore/config.go
TRUVAG3_K8S_POD_IP(auto)ImplementedPod IP addresscore/config.go
TRUVAG3_K8S_NODE_NAME(auto)ImplementedNode name where pod is runningcore/config.go
TRUVAG3_K8S_SA_PATH/var/run/secrets/kubernetes.io/serviceaccountStruct Tag OnlyService account mount pathcore/config.go
TRUVAG3_K8S_SERVICE_DISCOVERYtrueStruct Tag OnlyEnable K8s service discoverycore/config.go
TRUVAG3_K8S_LEADER_ELECTIONfalseStruct Tag OnlyEnable leader electioncore/config.go

Kubernetes Deployment Example​

env:
- name: TRUVAG3_AGENT_NAME
value: "weather-tool"
- name: TRUVAG3_K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: TRUVAG3_K8S_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: TRUVAG3_K8S_SERVICE_NAME
value: "weather-tool"
- name: TRUVAG3_K8S_SERVICE_PORT
value: "8080"

Orchestration Configuration​

Configure the AI orchestrator for multi-agent coordination.

Failed-operation evidence (implemented)​

TRUVAG3_FAILED_OPERATION_VIEW_DISABLED defaults to false. TRUVAG3_FAILED_OPERATION_MAX_VALUE_BYTES, TRUVAG3_FAILED_OPERATION_MAX_STEP_BYTES, and TRUVAG3_FAILED_OPERATION_MAX_PROMPT_BYTES default to 4096, 16384, and 32768. Numeric values must be positive; canonical orchestration EnvironmentStrict rejects invalid values and EnvironmentCompatible reports ignored invalid overrides. Code zero means unset; negative code limits fail validation. WithFailedOperationView replaces the entire environment-resolved configuration. Omitted code fields resolve to defaults; they do not retain env values. These are final-encoded child ceilings inside continuation's existing failure share, not a way to raise its parent budget. See the Limits Cheatsheet and Result Compaction Guide for measurement and omission semantics.

Execution and planning variables​

Related controls used by the current planning/execution paths:

VariableDefaultScope and validation
TRUVAG3_STEP_RETRY_MAX_ATTEMPTS3 total attemptsPositive integer; ExecutionOptions.RetryAttempts in canonical construction. Direct NewSmartExecutor also reads it; SetMaxAttempts(n) is the direct code seam (values below 1 become 1). Orchestrator capabilities remain single dispatch
TRUVAG3_PLAN_REFINEMENT_ENABLEDfalseEnables the post-orchestrator refinement pass; standard orchestration boolean resolution, not a provider setting
TRUVAG3_EXCLUDED_CAPABILITIESemptyComma-separated capability names, trimmed and empty entries discarded; populates OrchestratorConfig.ExcludedCapabilities. Separate from capabilities marked Internal

These existing controls are not new feature flags for the hardening work. Explicit ToolError.Retryable=false stops all same-step retries, including transient resends. Transient 408/429/5xx preserves admitted inputs; eligible non-transient 4xx may be corrected, never resent unchanged. Increasing a retry budget does not bypass refusal, immutable inputs or the delegated-call limit.

VariableDefaultStatusDescriptionSource
TRUVAG3_ORCHESTRATION_TIMEOUT20mImplementedBase shared HTTP-client timeout per tool/agent call, not the whole execution. Orchestrator construction raises it to HITL.DefaultTimeout + ExecutionOptions.StepTimeout when that allowance is larger. Earlier enclosing deadlines still apply.orchestration/orchestrator.go
TRUVAG3_EXECUTION_MAX_CONCURRENCY25ImplementedMax parallel step executions in DAG. Controls goroutine concurrency during plan execution.orchestration/interfaces.go
TRUVAG3_EXECUTION_STEP_TIMEOUT15mImplementedGo-duration execution allowance added to HITL.DefaultTimeout for an orchestrator capability's per-call context deadline. Ordinary tool calls have no separate deadline from this setting; they use the shared HTTP timeout and enclosing context. The delegation allowance can also enlarge the shared client timeout and phase budget.orchestration/executor.go, orchestration/orchestrator.go
TRUVAG3_CONVERSATION_TOKEN_BUDGET48000ImplementedMaximum estimated tokens allowed for prepared <conversation_history> before Tier 1 truncation/elision. Default-on safety net for metadata and hook ingress paths.orchestration/interfaces.go
TRUVAG3_CONVERSATION_RECENT_TURNS_PRESERVED4ImplementedNumber of newest turns always kept verbatim when turn-aware conversation preparation needs to shed context.orchestration/interfaces.go
TRUVAG3_CONVERSATION_SUMMARY_CACHE_SIZE256ImplementedLRU capacity for the optional Tier 2 recursive conversation-summary cache. Only used when the application injects a compaction-enabled conversation-history preparer.orchestration/interfaces.go
TRUVAG3_STEP_RETRY_INITIAL_DELAY500msImplementedInitial step-retry backoff, with 2× growth and jitter. Canonical construction requires a positive Go duration: strict mode rejects invalid values; compatible mode diagnoses ignored overrides. Direct NewSmartExecutor retains compatibility with zero/negative delays.orchestration/config_resolution.go, orchestration/executor.go
TRUVAG3_STEP_RETRY_MAX_DELAY10sImplementedMaximum step-retry backoff. Canonical construction requires a positive Go duration: strict mode rejects invalid values; compatible mode diagnoses ignored overrides. Direct NewSmartExecutor retains compatibility with zero/negative delays.orchestration/config_resolution.go, orchestration/executor.go
TRUVAG3_OAUTH_TOKEN(empty)ImplementedOAuth Bearer token for outbound HTTP calls to tool/agent endpoints. Per-request tokens via WithOAuthToken() take priority. When set, executor requests include Authorization: Bearer <token>.orchestration/executor.go
TRUVAG3_TIERED_RESOLUTION_ENABLEDtrueImplementedEnable tiered capability resolution for LLM token optimization. Uses 2-phase approach to reduce tokens by 50-75%.orchestration/interfaces.go
TRUVAG3_TIERED_MIN_TOOLS20ImplementedMinimum tool count to trigger tiered resolution. Below this threshold, all tools are sent directly. Research-backed default.orchestration/tiered_capability_provider.go
TRUVAG3_TIERED_SELECTION_MAX_TOKENS2000ImplementedMax output tokens for tiered selection LLM calls. Higher values allow complex multi-tool selections but cost more tokens.orchestration/tiered_capability_provider.go
TRUVAG3_TIERED_SELECTION_RETRY_ENABLEDtrueImplementedEnable retry on empty LLM responses and parse failures during tiered tool selection. Set to false to disable.orchestration/interfaces.go
TRUVAG3_TIERED_SELECTION_RETRY_MAX2ImplementedMax retry attempts for tiered selection (0 = disabled). 2 means up to 3 total attempts (1 initial + 2 retries).orchestration/interfaces.go
TRUVAG3_CAPABILITY_SERVICE_URL(none)ImplementedExternal capability service URLorchestration/capability_provider.go
CAPABILITY_SERVICE_URL(fallback)ImplementedAlternative capability service URLorchestration/capability_provider.go
TRUVAG3_CAPABILITY_TOP_K20ImplementedNumber of capabilities to returnorchestration/capability_provider.go
TRUVAG3_CAPABILITY_THRESHOLD0.7ImplementedMinimum similarity thresholdorchestration/capability_provider.go
TRUVAG3_PLAN_RETRY_ENABLEDtrueImplementedRetry initial/continuation generation on syntax or routing-intent decoding failures; other recovery paths have their own budgetsorchestration/interfaces.go
TRUVAG3_PLAN_RETRY_MAX2ImplementedMaximum retry attempts for plan parsing (0 = disabled)orchestration/interfaces.go
TRUVAG3_PLAN_MAX_TOKENS20000ImplementedMax output tokens for plan generation LLM calls (including hallucination and validation retries)orchestration/interfaces.go
TRUVAG3_SYNTHESIS_MAX_TOKENS30000ImplementedMax output tokens for response synthesis LLM callsorchestration/interfaces.go
TRUVAG3_SYNTHESIS_TEMPERATURE0.5ImplementedLLM temperature for response synthesis (0.0–2.0). Lower = more deterministicorchestration/interfaces.go
TRUVAG3_PLAN_MODEL""ImplementedPortable alias or model name for plan generation LLM calls. Aliases work across catalog-backed chain entries; leave unset for a chain containing Bedrock so each entry uses its configured defaultorchestration/interfaces.go
TRUVAG3_SYNTHESIS_MODEL""ImplementedPortable alias or model name for response synthesis LLM calls (streaming + non-streaming)orchestration/interfaces.go
TRUVAG3_MICRO_RESOLUTION_MODEL""ImplementedPortable alias or model name for micro-resolution and Layer 4 semantic retry (contextual re-resolution) LLM calls. When unset, both use the provider-default modelorchestration/interfaces.go
TRUVAG3_MICRO_RESOLUTION_MAX_TOKENS2000ImplementedMaximum output tokens for micro-resolution (base default 2000) and Layer 4 semantic retry (base default 1000); setting this overrides bothorchestration/interfaces.go
TRUVAG3_HALLUCINATION_VALIDATION_ENABLEDtrueImplementedValidate that LLM-generated plans only reference agents from the allowed listorchestration/interfaces.go
TRUVAG3_HALLUCINATION_RETRY_ENABLEDtrueImplementedRetry plan generation with enhanced context when hallucination is detectedorchestration/interfaces.go
TRUVAG3_HALLUCINATION_MAX_RETRIES1ImplementedMaximum retry attempts for hallucination correction (0 = disabled)orchestration/interfaces.go
TRUVAG3_ITERATIVE_PLANNING_ENABLEDtrueImplementedEnable multi-phase iterative planning. LLM planner can generate partial plans that execute in phases.orchestration/interfaces.go
TRUVAG3_ITERATIVE_MAX_PHASES20ImplementedMaximum planning phases per request. Forces termination with synthesis if reached.orchestration/interfaces.go
TRUVAG3_ITERATIVE_MAX_TOTAL_STEPS200ImplementedMaximum total steps across all phases. Prevents runaway plan generation.orchestration/interfaces.go
TRUVAG3_ITERATIVE_PHASE_TIMEOUT25mImplementedConfigured phase budget (plan generation + execution). The phase loop raises it to the delegation allowance (HITL.DefaultTimeout + StepTimeout) when larger, even if the plan has no delegated step. Earlier parent deadlines still apply.orchestration/orchestrator.go
TRUVAG3_ITERATIVE_MAX_VALIDATION_ROUNDS4ImplementedRegeneration attempts after the first validation failure; at most 1 + N validations. Malformed or intent-invalid regenerated JSON spends a round without validation; provider/boundary/cancellation errors and persistent continuation step-ID conflicts can stop earlier.orchestration/interfaces.go
TRUVAG3_ITERATIVE_REGENERATION_FEEDBACK_MAX_BYTES16384ImplementedByte limit on encoded correction context added to a selected phase prompt. The effective value must be greater than zero when validated; environment handling follows the selected configuration-resolution mode. Omitted prior evidence is marked; failure to fit required feedback stops preparation. Not a whole-prompt/token limit.orchestration/plan_attempt.go
TRUVAG3_CONTINUATION_RESULT_MAX_CHARS10000ImplementedFloor-preview size in bytes (legacy setting name) for a non-JSON completed-step result. JSON results use a structural digest; delegation summaries have a separate projection. Visibility remains subject to digest and enclosing budgets.orchestration/interfaces.go
TRUVAG3_CONTINUATION_RESULT_MAX_TOTAL_CHARS196608ImplementedSoft byte target (legacy setting name) for completed-step views before enclosing prompt encoding. Older successful steps may be omitted; failed steps and the newest successful step are retained, and markers can exceed the target. Failed-operation evidence is sub-allocated and also bounded by its own encoded-byte limits.orchestration/interfaces.go
TRUVAG3_CONTINUATION_MAX_ESCALATIONS8ImplementedPhase 14: max non-JSON steps escalated to the continuation distiller (a fast-model summary) per phase, newest-first. Sequential fast-model calls on the phase-gating path, so the cap bounds latency. 0 disables; fires ~never on all-JSON workloads.orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_ARRAY_SAMPLE3ImplementedPhase 14: per-array head-sample size in a continuation digest (arrays render as the first N elements + a length sentinel).orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_SCALAR_MAX200ImplementedPhase 14: max length of a string value kept inline in a digest before elision. Raise it so the planner sees longer salient values (status/error strings) at plan time.orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_MAX_KEYS50ImplementedPhase 14: per-object key cap in a digest. Schema objects kept whole; map-shaped objects (many dynamic-ID keys) sampled to this many sorted keys + a sentinel.orchestration/interfaces.go
TRUVAG3_FAILURE_PATTERN_MIN_FAILURES2ImplementedMinimum distinct failed upstream steps required for the remediation continuation prompt to embed a shared-error pattern summary. 1 would make every skip emit a summary (noisy); raise to make the analyzer more conservative.orchestration/interfaces.go
TRUVAG3_FAILURE_PATTERN_SIGNATURE_LEN120ImplementedMax chars of error text used to bucket failures into a shared signature for classification. Wider than the display cap to reduce false-positive collisions between distinct errors that share a common prefix.orchestration/interfaces.go
TRUVAG3_FAILURE_PATTERN_DISPLAY_LEN80ImplementedMax chars of the shared error rendered into the remediation prompt (trailing … on truncation). Kept short so the continuation prompt stays slim per EFFECTIVE_PROMPTS_GUIDE §4.5.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_ENABLEDtrueImplementedEnable structural trimming of large step results before prompt construction. Prevents token budget overflow.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_BYTES65536ImplementedMaximum bytes per individual step result (~16K tokens). Results exceeding this are structurally trimmed.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_TOTAL_BYTES196608ImplementedMaximum total bytes across all step results in a synthesis prompt (~48K tokens).orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_MICRO_BYTES65536ImplementedMaximum bytes for source data in micro-resolution and semantic retry prompts (~26K tokens).orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_AGENT_INPUT_BYTES0ImplementedMaximum bytes per parameter value for agent/tool HTTP calls. Default 0 = no cap (fidelity-first): tool→tool data flows raw so downstream steps receive the full upstream output. Set > 0 (or supply deps.AgentInputProcessor) to enable the byte-budget guard.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_SCHEMA_MAPPING_THRESHOLD16384ImplementedResult size threshold above which schema-guided mapping replaces direct value extraction. Set to 0 to disable.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_ENABLEDtrueImplementedDefault-on LLM-based result distillation (two-stage: structural pre-filter → LLM distill). Active when an AIClient is configured and TRUVAG3_RESULT_TRIM_ENABLED is true; otherwise the structural floor is used. Set =false to opt out.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_THRESHOLD16384ImplementedMinimum result size (bytes) to trigger LLM distillation. Below this, structural trimming only.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_PREFILTER131072ImplementedStructuralTrimmer budget (bytes) applied before LLM distillation (Stage 1 pre-filter). 128 KB — fits the 64K fast-tier context floor.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_TARGET4096ImplementedTarget output size for LLM distillation (Stage 2).orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MODELfastImplementedPortable alias or model name for LLM distillation calls. Default fast resolves for catalog-backed providers. For a chain containing Bedrock, set ResultDistill.Model or WithResultDistillModel to an empty string programmatically so each entry uses its configured default; the environment loader ignores an empty value.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_CACHE_TTL5mImplementedHow long a distillation result stays cached (keyed by result content + instruction + query + budget). Fail-open. Go duration format.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_DEADLINE45sImplementedWall-clock bound on a single compaction in the synthesis hot path. On timeout, fails open to the structural floor (single-call) or returns completed chunks + a "partial" disclosure (map-reduce). Go duration format; the env var accepts only positive values — disable the deadline via the programmatic CompactionDeadline: 0. Keep it under the HTTP gateway timeout.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_CONTEXT_TOKENS150000ImplementedUsable context (tokens) of the compaction model. Results estimated above this are chunked and map-reduced instead of sent in one call (~525 KB at the default, using the framework's ≈3.5 bytes/token counter).orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MAP_CONCURRENCY8ImplementedMax chunks compacted concurrently in the map-reduce path. ≤ 0 falls back to the default.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MAPREDUCE_THRESHOLD0ImplementedRoutes results larger than this (bytes) to map-reduce even when they fit the model context, so the whole result reaches an LLM instead of only the pre-filtered head. Independent of CONTEXT_TOKENS. 0 = disabled (context-only routing) — a deliberate deviation from the repo-wide > 0 convention so an explicit 0 can disable a future nonzero default. A positive value below PREFILTER is ignored with a factory warning (a result that small is one chunk — no fan-out benefit over the single-call distill).orchestration/interfaces.go

For every orchestration model override above, aliases are portable only across providers with alias catalogs. Leave the plan, synthesis, and micro-resolution model variables unset for a chain containing Bedrock so each entry can use its configured default. Result distillation is the exception because its built-in model is "fast"; use the programmatic empty override described in its row.

Tiered Capability Resolution​

Tiered resolution is a research-backed optimization that reduces LLM token usage by 50-75% for deployments with 20+ tools. It works by first sending lightweight tool summaries to select relevant tools, then fetching full schemas only for selected tools.

# Tiered resolution is enabled by default
export TRUVAG3_TIERED_RESOLUTION_ENABLED=true

# Adjust threshold for when tiering kicks in (default: 20)
export TRUVAG3_TIERED_MIN_TOOLS=25

# Increase selection output tokens for complex multi-tool registries (default: 2000)
export TRUVAG3_TIERED_SELECTION_MAX_TOKENS=3000

# Disable for small deployments (< 20 tools)
export TRUVAG3_TIERED_RESOLUTION_ENABLED=false

# Retry on empty responses / parse failures (default: enabled, 2 retries)
export TRUVAG3_TIERED_SELECTION_RETRY_ENABLED=true
export TRUVAG3_TIERED_SELECTION_RETRY_MAX=2

When to use:

  • < 20 tools: Disable tiered resolution (overhead not worth it)
  • 20-100 tools: Use tiered resolution (default, 50-75% token savings)
  • 100s+ tools: Consider ServiceCapabilityProvider for semantic search

Conversation History Preparation​

Conversation history now has a framework-owned preparation layer that runs before planning. Tier 1 token protection is default-on; Tier 2 recursive compaction is opt-in.

# Raise/lower the default-on conversation-history budget (default: 48000)
export TRUVAG3_CONVERSATION_TOKEN_BUDGET=64000

# Keep more or fewer recent turns verbatim when history comes in as raw turns
export TRUVAG3_CONVERSATION_RECENT_TURNS_PRESERVED=6

# Only relevant when you inject a compaction-enabled preparer
export TRUVAG3_CONVERSATION_SUMMARY_CACHE_SIZE=512

How these settings apply:

  • TRUVAG3_CONVERSATION_TOKEN_BUDGET protects both legacy formatted history and raw-turn metadata.
  • TRUVAG3_CONVERSATION_RECENT_TURNS_PRESERVED matters only on the turn-aware path.
  • TRUVAG3_CONVERSATION_SUMMARY_CACHE_SIZE matters only when the application enables Tier 2 recursive compaction by injecting a preparer with a summary cache and compactor.

Plan Parse Retry​

When LLMs generate execution plans, JSON parsing may fail due to:

  • Missing or invalid routing-plan intent, including ambiguous empty plans
  • Arithmetic expressions in values (e.g., "amount": 100 * price)
  • Malformed JSON syntax (trailing commas, missing quotes)
  • Invalid JSON structures

Initial/continuation generation uses the parse-retry mechanism for these failures. Initial unavailable-agent replacements use the hallucination-recovery budget; validation-regeneration outputs instead spend validation rounds. A continuation unknown-agent recovery has only one regeneration attempt within that path; the outer phase loop may subsequently attempt fallback regeneration, subject to context and request-preparation success. These paths are distinct.

The parse-retry mechanism provides error feedback to the LLM:

# Disable retry (fail fast on parse errors)
export TRUVAG3_PLAN_RETRY_ENABLED=false

# Increase retry attempts (default: 2)
export TRUVAG3_PLAN_RETRY_MAX=3

# Disable by setting max retries to 0
export TRUVAG3_PLAN_RETRY_MAX=0

LLM Synthesis Parameters​

Controls the base output-token allowance and temperature for LLM calls during plan generation and response synthesis. Planning defaults to 20000 tokens; synthesis defaults to 30000 tokens at temperature 0.5. These are base allowances, not guarantees against truncation: active reasoning profiles may expand them, reviewed model ceilings may bound the result, and hidden reasoning can consume the same output budget. Provider deadlines and model/context capacity still apply. Sampling controls are subject to the selected model's compatibility policy; a requested temperature is not guaranteed to reach every provider.

# Increase plan generation token limit (default: 20000)
export TRUVAG3_PLAN_MAX_TOKENS=60000

# Increase synthesis token limit (default: 30000)
export TRUVAG3_SYNTHESIS_MAX_TOKENS=40000

# Adjust synthesis temperature (default: 0.5, range: 0.0-2.0)
# Higher values produce more creative responses (good for streaming chat)
export TRUVAG3_SYNTHESIS_TEMPERATURE=0.7

# Reduce plan generation for cost savings
export TRUVAG3_PLAN_MAX_TOKENS=5000

# Model overrides — aliases are portable across catalog-backed chain entries;
# leave them unset for a chain containing Bedrock
export TRUVAG3_PLAN_MODEL=smart
export TRUVAG3_SYNTHESIS_MODEL=default
export TRUVAG3_MICRO_RESOLUTION_MODEL=fast

Hallucination Detection​

LLMs can hallucinate non-existent agents when generating execution plans. For example, when asked about "time in CST", the LLM might invent a time-tool-v1 agent even though only weather-tool-v2 was provided in the prompt. Hallucination detection validates that all agents referenced in the plan were actually included in the capability information shown to the LLM.

When validation fails, the retry mechanism provides explicit error feedback with the list of allowed agents, giving the LLM a chance to self-correct:

# Disable hallucination validation entirely (not recommended)
export TRUVAG3_HALLUCINATION_VALIDATION_ENABLED=false

# Disable retry (fail immediately when hallucination detected)
export TRUVAG3_HALLUCINATION_RETRY_ENABLED=false

# Increase retry attempts (default: 1, usually sufficient for self-correction)
export TRUVAG3_HALLUCINATION_MAX_RETRIES=2

How it works:

  1. Plan Generated: LLM produces an execution plan with agent references
  2. Validation: Each agent name is checked against the allowed list (agents shown in the prompt)
  3. Hallucination Detected: If an agent name isn't in the allowed list, validation fails
  4. Enhanced Retry: The LLM receives error feedback with the exact hallucinated name and the complete allowed agent list
  5. Self-Correction: LLM regenerates the plan using only valid agents

When to disable:

  • Testing/Development: When using mock agents not in the catalog
  • Custom Validation: When implementing your own agent validation logic
  • Debugging: To see raw LLM output without intervention

Semantic Retry Configuration (Layer 4)​

Semantic Retry is an advanced error recovery feature that uses LLM analysis to compute corrected parameters when standard error analysis cannot fix the issue. When a tool call fails (e.g., amount: 0 instead of amount: 46828.5), the contextual re-resolver uses full execution context—including the user's original query and source data from dependent steps—to compute the correct value.

VariableDefaultStatusDescriptionSource
TRUVAG3_SEMANTIC_RETRY_ENABLEDtrueImplementedEnable Layer 4 semantic retry with LLM-based parameter re-computationorchestration/interfaces.go
TRUVAG3_SEMANTIC_RETRY_MAX_ATTEMPTS2ImplementedMaximum semantic retry attempts per step (0 = disabled)orchestration/interfaces.go
TRUVAG3_SEMANTIC_RETRY_INDEPENDENT_STEPStrueImplementedEnable semantic retry for steps without dependencies (first steps, parallel steps)orchestration/interfaces.go

How Semantic Retry Works:

  1. Error Detected: Tool returns an eligible, correction-permitted 4xx error (e.g. 400, 404, 409, 422); explicit retryable:false stops all same-step retries first
  2. Layer 3 Analysis: ErrorAnalyzer determines it cannot fix the issue
  3. Layer 4 Activation: ContextualReResolver receives full execution context:
    • User's original query (intent)
    • Source data from dependent steps (what to compute from)
    • Failed parameters and error message
  4. LLM Computation: The LLM analyzes the context and computes corrected parameters
  5. Retry: The step is retried with computed parameters

Hypothetical opt-in scenario: The shipped currency-tool sends retryable:false for amount validation, so it stops rather than following this flow. This example assumes explicit retryable:true permission for that correctable condition and all executor correction gates passing.

User: "Sell 100 Tesla shares and convert proceeds to EUR"
Step 1 (stock-tool): Returns {price: 468.285}
Step 2 (currency-tool): Fails with "amount must be > 0" (amount: 0)

→ Layer 4 computes: amount = 100 × 468.285 = 46828.5
→ Retries currency conversion with corrected amount

Disabling Semantic Retry:

# Disable semantic retry entirely
export TRUVAG3_SEMANTIC_RETRY_ENABLED=false

# Or limit retry attempts
export TRUVAG3_SEMANTIC_RETRY_MAX_ATTEMPTS=1

# Disable only for independent steps (revert to old behavior)
export TRUVAG3_SEMANTIC_RETRY_INDEPENDENT_STEPS=false

Iterative Planning (Multi-Phase DAG)​

Iterative planning allows the LLM planner to generate partial plans (terminal: false) and continue planning after intermediate results are available. This enables "discovery → action" queries like "find famous tourist destinations in Germany and get their weather" where later steps depend on the semantic content of earlier results.

VariableDefaultStatusDescriptionSource
TRUVAG3_ITERATIVE_PLANNING_ENABLEDtrueImplementedEnable multi-phase iterative planning. When enabled, the LLM planner can signal partial plans that execute in phases.orchestration/interfaces.go
TRUVAG3_ITERATIVE_MAX_PHASES20ImplementedMaximum number of planning phases per request. If reached without a terminal plan, the orchestrator forces termination and synthesizes with available results. Most queries need at most 2.orchestration/interfaces.go
TRUVAG3_ITERATIVE_MAX_TOTAL_STEPS200ImplementedMaximum total steps across all phases. Prevents runaway plan generation.orchestration/interfaces.go
TRUVAG3_ITERATIVE_PHASE_TIMEOUT25mImplementedConfigured phase budget (plan generation + execution), raised to the delegation allowance when larger. Earlier parent deadlines still apply; see Execution Limits.orchestration/orchestrator.go
TRUVAG3_ITERATIVE_MAX_VALIDATION_ROUNDS4ImplementedRegeneration attempts after the first validation failure; at most 1 + N validations. Malformed or intent-invalid regenerated JSON spends a round without validation; provider/boundary/cancellation errors and persistent continuation step-ID conflicts can stop earlier.orchestration/interfaces.go
TRUVAG3_ITERATIVE_REGENERATION_FEEDBACK_MAX_BYTES16384ImplementedByte limit on encoded correction context added to a selected phase prompt. The effective value must be greater than zero when validated; environment handling follows the selected configuration-resolution mode. Omitted prior evidence is marked; failure to fit required feedback stops preparation. Not a whole-prompt/token limit.orchestration/plan_attempt.go

How Iterative Planning Works:

  1. Phase 1: LLM generates a partial plan (terminal: false) with steps it can confidently plan
  2. Execution: Orchestrator executes Phase 1 steps (parallel where possible)
  3. Phase 2: LLM receives Phase 1 results and plans next steps based on actual data
  4. Repeat: Until the LLM sets terminal: true or budget limits are reached

Example scenario:

User: "Tell me about Canada - weather at famous destinations and latest news"
Phase 1: country-info + web-search("famous destinations") + news → terminal: false
Phase 2: geocode(Vancouver, Banff, ...) + weather(coordinates) → terminal: true

Configuration:

# Enable iterative planning (default: true)
export TRUVAG3_ITERATIVE_PLANNING_ENABLED=true

# Allow up to 5 phases for complex queries
export TRUVAG3_ITERATIVE_MAX_PHASES=20

# Allow up to 30 total steps across all phases
export TRUVAG3_ITERATIVE_MAX_TOTAL_STEPS=30

# Increase phase timeout for slow external APIs
export TRUVAG3_ITERATIVE_PHASE_TIMEOUT=60s

# Disable iterative planning (all plans treated as single-shot)
export TRUVAG3_ITERATIVE_PLANNING_ENABLED=false

When to adjust:

  • Increase MAX_PHASES: Complex research queries requiring multiple discovery rounds
  • Increase MAX_TOTAL_STEPS: Queries that fan out to many services (e.g., weather for 10+ cities)
  • Decrease MAX_PHASES: Cost-sensitive deployments (each phase costs an LLM planning call)
  • Disable entirely: When all queries are closed-form with known parameters upfront

Result Trimming (Large Result Data Management)​

When tool/agent responses are large (e.g., full web pages, large API payloads), they can overflow the LLM's token budget during synthesis. Result trimming uses a StructuralTrimmer to intelligently reduce result sizes before they are embedded in prompts — preserving JSON structure, key names, and representative samples while dropping repetitive array elements and deeply nested data.

VariableDefaultStatusDescriptionSource
TRUVAG3_CONTINUATION_RESULT_MAX_CHARS10000ImplementedNon-JSON floor-preview size in continuation prompts (JSON is digested).orchestration/interfaces.go
TRUVAG3_CONTINUATION_RESULT_MAX_TOTAL_CHARS196608ImplementedSoft target for all step digests in the continuation prompt (newest-first; N-of-M eviction) — not a hard cap: failed steps and the newest successful step are always kept, and notes are appended after the budget decision.orchestration/interfaces.go
TRUVAG3_CONTINUATION_MAX_ESCALATIONS8ImplementedMax non-JSON→fast-model-summary escalations per continuation phase (0 disables).orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_ARRAY_SAMPLE3ImplementedDigest array head-sample size.orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_SCALAR_MAX200ImplementedDigest inline-string elision threshold.orchestration/interfaces.go
TRUVAG3_CONTINUATION_DIGEST_MAX_KEYS50ImplementedDigest per-object key cap.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_ENABLEDtrueImplementedEnable structural trimming of large step results before prompt construction.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_BYTES65536ImplementedMaximum bytes per individual step result (~16K tokens). Results exceeding this are structurally trimmed.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_TOTAL_BYTES196608ImplementedMaximum total bytes across all step results in a synthesis prompt (~48K tokens).orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_MICRO_BYTES65536ImplementedMaximum bytes for source data in micro-resolution and semantic retry prompts (64 KiB, not a token allowance). Controls how much of the original step result is included when the LLM resolves missing parameters or retries failed steps.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_MAX_AGENT_INPUT_BYTES0ImplementedMaximum bytes per parameter value for agent/tool HTTP calls. Default 0 = no cap (fidelity-first): tool→tool data flows raw so downstream steps receive the full upstream output. Set > 0 (or supply deps.AgentInputProcessor) to enable the byte-budget guard that trims large parameter values before they are sent to downstream agents or tools.orchestration/interfaces.go
TRUVAG3_RESULT_TRIM_SCHEMA_MAPPING_THRESHOLD16384ImplementedResult size threshold (bytes) above which schema-guided mapping is used instead of direct value extraction for micro-resolution. Set to 0 to disable schema-guided mapping entirely.orchestration/interfaces.go

How it works:

  1. Per-result trimming: Each step result is individually limited to MaxResultBytes. The StructuralTrimmer preserves JSON structure while dropping array elements beyond the first few and truncating deeply nested objects.
  2. Total budget enforcement: After individual trimming, if the combined results still exceed MaxTotalPromptBytes, the BudgetAllocator reduces them proportionally. Allocation is distillation-aware: a result that will be distilled is counted at its post-distill footprint (~TargetSize, via EffectiveSizer), not its raw size, so one large distillable result doesn't starve the others' budgets.
  3. Micro-resolution budgets: When the LLM needs to resolve missing parameters from prior step results, MaxMicroResolutionBytes controls how much source data is included in the prompt. For very large results, schema-guided mapping (triggered above SchemaGuidedMappingThreshold) uses JSON schema analysis instead of passing raw data.
  4. Agent input trimming (opt-in): MaxAgentInputBytes defaults to 0 (no cap) — tool→tool data flows raw so downstream steps receive the full upstream output (fidelity-first). Set it > 0 to trim individual parameter values before they are sent to downstream agents/tools via HTTP, or supply deps.AgentInputProcessor for custom input shaping.
  5. Fallback: Non-JSON results are truncated with a ... [trimmed] suffix.

Configuration:

# Disable result trimming (not recommended for production — may cause token overflow)
export TRUVAG3_RESULT_TRIM_ENABLED=false

# Example of a smaller per-result limit for tighter contexts
export TRUVAG3_RESULT_TRIM_MAX_BYTES=32768 # 32 KB per result

# Example of a smaller total result budget
export TRUVAG3_RESULT_TRIM_MAX_TOTAL_BYTES=65536 # 64 KB total

# Increase micro-resolution budget for complex data dependencies
export TRUVAG3_RESULT_TRIM_MAX_MICRO_BYTES=131072 # 128 KB for resolution prompts

# Increase agent input budget for data-heavy tool calls
export TRUVAG3_RESULT_TRIM_MAX_AGENT_INPUT_BYTES=131072 # 128 KB per parameter value

# Disable schema-guided mapping (always use direct value extraction)
export TRUVAG3_RESULT_TRIM_SCHEMA_MAPPING_THRESHOLD=0

Programmatic configuration:

config := orchestration.DefaultConfig()
config.ResultTrim = orchestration.ResultTrimConfig{
Enabled: true,
MaxResultBytes: 65536, // 64 KiB per result
MaxTotalPromptBytes: 196608, // 192 KiB total
MaxMicroResolutionBytes: 65536, // 64 KB for micro-resolution source data
MaxAgentInputBytes: 0, // 0 = no cap (fidelity-first); set > 0 to enable the guard
SchemaGuidedMappingThreshold: 16384, // 16 KB — use schema mapping above this
}

When to adjust:

  • Increase limits: When LLM synthesis responses lack detail because results were trimmed too aggressively
  • Decrease limits: When hitting token limits or getting slow synthesis responses
  • Disable: Only for debugging — production deployments should always have trimming enabled

Result Distillation (Default-On LLM Summarization)​

For results that are extremely large or contain domain-specific content that structural trimming cannot adequately compress, LLM distillation provides a two-stage pipeline: structural pre-filtering followed by LLM-based summarization. It is on by default (opt-out) and serves as the primary compaction path for oversized results when the orchestrator has an AIClient and Result Trimming is enabled; without an AIClient the framework falls back to the structural floor.

VariableDefaultStatusDescriptionSource
TRUVAG3_RESULT_DISTILL_ENABLEDtrueImplementedDefault-on LLM-based result distillation. Active when an AIClient is configured and TRUVAG3_RESULT_TRIM_ENABLED is true; otherwise the structural floor is used. Set =false to opt out (e.g. for cost- or latency-sensitive deployments).orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_THRESHOLD16384ImplementedMinimum result size (bytes) to trigger distillation. Below this threshold, structural trimming is used instead.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_PREFILTER131072ImplementedStructuralTrimmer budget (bytes) for Stage 1 pre-filtering. Reduces input to the LLM before distillation. 128 KB — fits the 64K fast-tier context floor.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_TARGET4096ImplementedTarget output size for the LLM distillation (Stage 2). The LLM summarizes the pre-filtered result to approximately this size.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MODELfastImplementedPortable alias or model name for distillation LLM calls. Default fast resolves for Anthropic, OpenAI-compatible, and Gemini providers. Bedrock has no alias catalog; for a chain containing Bedrock, set ResultDistill.Model or WithResultDistillModel to an empty string programmatically so each entry uses its configured default. The environment loader ignores an empty value.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_CACHE_TTL5mImplementedHow long a distillation result stays cached (keyed by result content + instruction + query + budget). Fail-open — a nil cache disables it with no overhead. Go duration format.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_DEADLINE45sImplementedWall-clock bound on a single compaction in the synthesis hot path. On timeout, fails open to the structural floor (single-call path) or returns the chunks that completed plus a "partial" disclosure (map-reduce path). Go duration format; the env var accepts only positive values — disable the deadline via the programmatic CompactionDeadline: 0. Keep it under the HTTP gateway timeout.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_CONTEXT_TOKENS150000ImplementedUsable context (tokens) of the compaction model. Results estimated above this are chunked and map-reduced instead of sent in one call (~525 KB at the default, using the framework's ≈3.5 bytes/token counter).orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MAP_CONCURRENCY8ImplementedMax chunks compacted concurrently in the map-reduce path. ≤ 0 falls back to the default.orchestration/interfaces.go
TRUVAG3_RESULT_DISTILL_MAPREDUCE_THRESHOLD0ImplementedRoutes results larger than this (bytes) to map-reduce even when they fit the model context, so the whole result reaches an LLM instead of only the pre-filtered head. Independent of CONTEXT_TOKENS. 0 = disabled (context-only routing) — a deliberate deviation from the repo-wide > 0 convention so an explicit 0 can disable a future nonzero default. A positive value below PREFILTER is ignored with a factory warning (a result that small is one chunk — no fan-out benefit over the single-call distill).orchestration/interfaces.go

How the two-stage pipeline works:

  1. Stage 1 — Structural Pre-Filter: The StructuralTrimmer reduces the large result to PreFilterBudget bytes, preserving JSON structure and key data points.
  2. Stage 2 — LLM Distillation: An LLM call summarizes the pre-filtered result to approximately TargetSize bytes, preserving the most relevant information for the user's query.
  3. Map-reduce (very large results): When a result is estimated above the model's usable context (ModelContextTokens) — or exceeds the opt-in MapReduceThresholdBytes byte threshold (0/disabled by default), independent of the token estimate — it is chunked and each chunk is distilled concurrently (capped by MapConcurrency), then the chunk outputs are reduced into a final distillation. The byte threshold forces the whole result through map-reduce so an LLM sees all of it, not just the pre-filtered head.
  4. Caching (opt-in): When a DigestCache is supplied via deps.DistillCache — there is no cache by default — identical (result + instruction + query + budget) inputs reuse a prior distillation for CacheTTL, so scheduled and repetitive runs become cache hits instead of repeat LLM calls. Failed or partial outputs are not cached. (CacheTTL=0 does not reliably disable caching — a Redis-backed cache treats 0 as "no expiration"; to disable, don't supply a cache.)
  5. Deadline & fallback: Each compaction is bounded by CompactionDeadline. On timeout or LLM error, the call fails open — the single-call path uses the Stage 1 pre-filtered result directly; the map-reduce path returns the chunks that completed plus an honest "partial" disclosure.

Configuration:

# Distillation is on by default — set =false to opt out
export TRUVAG3_RESULT_DISTILL_ENABLED=true

# Only distill results larger than 64 KB (default 16384 / 16 KB)
export TRUVAG3_RESULT_DISTILL_THRESHOLD=65536

# Pre-filter budget fed into the LLM (default 131072 / 128 KB)
export TRUVAG3_RESULT_DISTILL_PREFILTER=131072

# Target smaller output from LLM
export TRUVAG3_RESULT_DISTILL_TARGET=2048
export TRUVAG3_RESULT_DISTILL_MODEL=fast

# Cache identical distillations for longer (default 5m)
export TRUVAG3_RESULT_DISTILL_CACHE_TTL=10m

# Bound a single compaction in the synthesis hot path (default 45s; env accepts positive durations only)
export TRUVAG3_RESULT_DISTILL_DEADLINE=30s

# Above this model context (tokens), chunk → map-reduce (default 150000)
export TRUVAG3_RESULT_DISTILL_CONTEXT_TOKENS=150000

# Concurrent chunk distillations in the map-reduce path (default 8)
export TRUVAG3_RESULT_DISTILL_MAP_CONCURRENCY=8

# Byte threshold that routes a result to map-reduce even when it fits the model
# context, so the whole result reaches an LLM (0 = disabled; default 0)
export TRUVAG3_RESULT_DISTILL_MAPREDUCE_THRESHOLD=0

Programmatic configuration:

config := orchestration.DefaultConfig()
config.ResultDistill = orchestration.ResultDistillConfig{
Enabled: true,
DistillThreshold: 65536, // Only distill results > 64 KB
PreFilterBudget: 131072, // 128 KB pre-filter budget (default)
TargetSize: 2048, // 2 KB target output
Model: "fast", // Portable across catalog-backed providers
CacheTTL: 5 * time.Minute, // Reuse identical distillations (default 5m)
CompactionDeadline: 45 * time.Second, // Hot-path bound; 0 disables (default 45s)
ModelContextTokens: 150000, // Above this (tokens), chunk → map-reduce (default)
MapReduceThresholdBytes: 0, // Byte threshold → map-reduce even if it fits context; 0 = disabled (default)
MapConcurrency: 8, // Concurrent chunk distillations (default)
}

Why it's on by default:

  • Large API responses: When tools return full web pages, large JSON payloads, or document content
  • Quality over structural trimming: An LLM preserves semantically relevant content that structural trimming would drop
  • Domain-specific content: When structural trimming loses important semantic content that only an LLM can preserve

When to opt out (=false):

  • Cost-sensitive deployments: Each oversized result adds an LLM distillation call
  • Low-latency requirements: The extra LLM call adds latency
  • No AIClient configured: Distillation needs an AIClient; without one the framework already falls back to the structural floor, so nothing extra is needed

Example​

# Base HTTP timeout per tool/agent call; enclosing request deadlines still apply
export TRUVAG3_ORCHESTRATION_TIMEOUT=5m

# For high-concurrency execution
export TRUVAG3_EXECUTION_MAX_CONCURRENCY=10

# Execution allowance added to the HITL timeout for delegated orchestrator calls
export TRUVAG3_EXECUTION_STEP_TIMEOUT=180s

# For step retry backoff tuning (exponential backoff between retries)
export TRUVAG3_STEP_RETRY_INITIAL_DELAY=500ms
export TRUVAG3_STEP_RETRY_MAX_DELAY=10s

# For capability service integration
export TRUVAG3_CAPABILITY_SERVICE_URL="http://capability-service:8080"
export TRUVAG3_CAPABILITY_TOP_K=30
export TRUVAG3_CAPABILITY_THRESHOLD=0.75

# For plan parse retry configuration
export TRUVAG3_PLAN_RETRY_ENABLED=true
export TRUVAG3_PLAN_RETRY_MAX=2

# For hallucination detection (validates LLM doesn't invent agents)
export TRUVAG3_HALLUCINATION_VALIDATION_ENABLED=true
export TRUVAG3_HALLUCINATION_RETRY_ENABLED=true
export TRUVAG3_HALLUCINATION_MAX_RETRIES=1

# For semantic retry configuration (Layer 4)
export TRUVAG3_SEMANTIC_RETRY_ENABLED=true
export TRUVAG3_SEMANTIC_RETRY_MAX_ATTEMPTS=2
export TRUVAG3_SEMANTIC_RETRY_INDEPENDENT_STEPS=true

# For iterative planning (multi-phase DAG)
export TRUVAG3_ITERATIVE_PLANNING_ENABLED=true
export TRUVAG3_ITERATIVE_MAX_PHASES=20
export TRUVAG3_ITERATIVE_MAX_TOTAL_STEPS=200
export TRUVAG3_ITERATIVE_PHASE_TIMEOUT=25m

# Continuation prompt budgeting (Phase 14: JSON results are digested; non-JSON gets a floor preview)
export TRUVAG3_CONTINUATION_RESULT_MAX_CHARS=10000 # non-JSON floor-preview size
export TRUVAG3_CONTINUATION_RESULT_MAX_TOTAL_CHARS=196608 # soft target (192 KiB); newest-first, N-of-M eviction (failed + newest kept)
export TRUVAG3_CONTINUATION_MAX_ESCALATIONS=8 # max non-JSON→fast-model-summary escalations/phase (0 disables)
export TRUVAG3_CONTINUATION_DIGEST_ARRAY_SAMPLE=3 # digest array head-sample size
export TRUVAG3_CONTINUATION_DIGEST_SCALAR_MAX=200 # digest inline-string elision threshold
export TRUVAG3_CONTINUATION_DIGEST_MAX_KEYS=50 # digest per-object key cap

# For result trimming (enabled by default)
export TRUVAG3_RESULT_TRIM_ENABLED=true
export TRUVAG3_RESULT_TRIM_MAX_BYTES=65536
export TRUVAG3_RESULT_TRIM_MAX_TOTAL_BYTES=196608
export TRUVAG3_RESULT_TRIM_MAX_MICRO_BYTES=65536
export TRUVAG3_RESULT_TRIM_MAX_AGENT_INPUT_BYTES=0 # 0 = no cap (fidelity-first); set > 0 to enable the guard
export TRUVAG3_RESULT_TRIM_SCHEMA_MAPPING_THRESHOLD=16384

# For result distillation (on by default; opt out with =false)
export TRUVAG3_RESULT_DISTILL_ENABLED=true
export TRUVAG3_RESULT_DISTILL_THRESHOLD=16384
export TRUVAG3_RESULT_DISTILL_PREFILTER=131072
export TRUVAG3_RESULT_DISTILL_TARGET=4096
export TRUVAG3_RESULT_DISTILL_MODEL=fast
export TRUVAG3_RESULT_DISTILL_CACHE_TTL=5m
export TRUVAG3_RESULT_DISTILL_DEADLINE=45s
export TRUVAG3_RESULT_DISTILL_CONTEXT_TOKENS=150000
export TRUVAG3_RESULT_DISTILL_MAP_CONCURRENCY=8
export TRUVAG3_RESULT_DISTILL_MAPREDUCE_THRESHOLD=0

LLM Debug Configuration​

The removed TRUVAG3_LLM_DEBUG_REDIS_DB and TRUVAG3_LLM_DEBUG_KEY_PREFIX are rejected when nonempty by owning Redis LLM recorder/debug-store constructors. Use the canonical DB-0 deployment namespace or typed keyspace option; empty values are absent, not a request for a legacy key layout. New completion fields reuse existing enablement/retention settings.

Configure LLM debug payload storage for debugging orchestration issues. This feature captures full LLM request/response payloads to help diagnose planning failures, parse errors, and unexpected AI behavior.

Important: This feature is disabled by default to minimize storage overhead. Enable only when debugging is needed.

LLM Debug Variables​

VariableDefaultStatusDescriptionSource
TRUVAG3_LLM_DEBUG_ENABLEDfalseImplementedEnable LLM debug payload storageorchestration/interfaces.go
TRUVAG3_LLM_DEBUG_TTL72h (3 days)ImplementedBase retention for successful debug records; a longer execution-lineage floor is preservedorchestration/redis_llm_debug_store.go
TRUVAG3_LLM_DEBUG_ERROR_TTL72h (3 days)ImplementedBase retention for error debug records; lineage, HITL, or investigation retention may extend itorchestration/redis_llm_debug_store.go

How It Works​

When enabled, the orchestrator automatically captures:

  • Request payloads: Full prompts sent to the LLM
  • Response payloads: Complete LLM responses (parsed and raw)
  • Timing metadata: Duration, timestamps, retry attempts
  • Error context: The error value supplied to the recorder. A small set of legacy executor, skills, and provider paths still transforms errors before recording; this is not a general sanitization guarantee.

The built-in recorder preserves the prompt and response values it receives. This feature is therefore an informed opt-in: applications own access control, encryption, retention policy, and any explicit sanitization required for their data.

Example: Enable Debug Storage​

# Enable LLM debug storage
export TRUVAG3_LLM_DEBUG_ENABLED=true

# Customize retention for debugging (optional; defaults are 72h for both)
export TRUVAG3_LLM_DEBUG_TTL=48h
export TRUVAG3_LLM_DEBUG_ERROR_TTL=168h

Example: Kubernetes Deployment​

env:
- name: TRUVAG3_LLM_DEBUG_ENABLED
value: "true"
- name: TRUVAG3_LLM_DEBUG_TTL
value: "48h"
- name: TRUVAG3_LLM_DEBUG_ERROR_TTL
value: "168h"

Viewing Debug Records​

Use the Registry Viewer App to view captured debug records:

  1. Navigate to the "LLM Debug" tab in the sidebar
  2. Browse records by agent, timestamp, or status (success/error)
  3. Inspect full request/response payloads for troubleshooting

Execution Debug Store Configuration​

Configure execution debug storage for DAG visualization and debugging. This feature stores complete plan execution records (plan + result) to enable visualization of LLM-based plan execution as a directed acyclic graph (DAG).

Important: This feature is disabled by default to minimize storage overhead. Enable only when DAG visualization or execution debugging is needed.

Execution Debug Store Variables​

VariableDefaultStatusDescriptionSource
TRUVAG3_EXECUTION_DEBUG_STORE_ENABLEDfalseImplementedEnable/disable execution debug storageorchestration/interfaces.go
TRUVAG3_EXECUTION_DEBUG_TTL72h (3 days)ImplementedBase retention for successful execution records; related-lineage promotion may extend itorchestration/redis_execution_store.go
TRUVAG3_EXECUTION_DEBUG_ERROR_TTL72h (3 days)ImplementedBase retention when the execution result fails or request lifecycle is failed/cancelled, including post-tool synthesis failures with successful steps. Existing longer/persistent retention, HITL approval windows and investigation extensions may retain records longerorchestration/redis_execution_store.go
TRUVAG3_EXECUTION_DEBUG_KEY_PREFIXtruvag3:v1:default:execution-debug:Generic provider onlyLogical prefix for generic StorageProvider execution keys; rejected by selected Redis backends. Use TRUVAG3_REDIS_NAMESPACE or typed Redis keyspace options for Redis isolation.orchestration/execution_store.go
TRUVAG3_EXECUTION_DEBUG_CONVERSATION_QUERY_LIMIT1000ImplementedMaximum executions returned by one framework conversation lookuporchestration/interfaces.go
TRUVAG3_EXECUTION_DEBUG_INDEX_SCAN_LIMIT5000ImplementedMaximum conversation-index members scanned by one framework lookup, including stale membersorchestration/interfaces.go
TRUVAG3_EXECUTION_STORE_WRITE_TIMEOUT5sImplementedPer-write timeout for asynchronous execution-debug persistence. Code configuration through WithExecutionStoreWriteTimeout has higher precedence.orchestration/config_resolution.go
TRUVAG3_EXECUTION_CLEANUP_TIMEOUT5sImplementedJoined request-resource cleanup deadline, independent of caller cancellation. Explicit empty/invalid/non-positive values fail in strict and compatible modes. Error-returning factories reject before bootstrap; legacy errorless constructors retain the error and reject Start/execution. WithExecutionCleanupTimeout overrides valid env settings.orchestration/execution_resources.go

The two conversation limits accept only positive integers. Missing, malformed, zero, or negative values retain the safe defaults. Environment values populate DefaultOrchestratorConfig. A positive programmatic value applied after default construction, or passed directly in ExecutionStoreConfig, is authoritative. The per-call limit passed to ListByConversationID is clamped to ConversationQueryLimit; stale-index work is independently bounded by ConversationIndexScanLimit.

The TTL variables select the initial minimum, not an absolute deletion time. An interrupted record receives at least the larger of the normal TTL, error TTL, and remaining approval window. Storing or explicitly extending a related execution promotes the available lineage without shortening an existing longer or persistent lifetime. Final execution recording applies the corresponding minimum to current and root LLM-debug evidence, including late writes.

Correlation and baggage protocol limits​

These limits are protocol constants rather than environment settings:

ValueLimitContract
conversation_id1–512 bytesVisible-ASCII W3C-safe subset validated by core.ValidateConversationID
W3C baggage members64telemetry.MaxBaggageItems
Baggage key128 bytestelemetry.MaxBaggageKeyLength
Baggage value512 bytestelemetry.MaxBaggageValueLength
Complete serialized W3C baggage value8192 bytesIncludes separators, encoding, and member properties

conversation_id is framework correlation metadata, not an application session_id. A chat application may deliberately use the same opaque value for both, but the framework does not infer that mapping. Conversation identity is established on the first turn even when conversation_turns is empty.

Features (Same as LLM Debug Store)​

The execution debug store has full feature parity with the LLM Debug Store:

  • Gzip compression: Large payloads (>100KB) are automatically compressed
  • Layer 1 resilience: Built-in retry with exponential backoff (3 retries, 100ms-2s backoff)
  • Layer 2 resilience: Optional circuit breaker injection via WithExecutionDebugCircuitBreaker()
  • Layer 3 resilience: NoOp fallback when Redis is unavailable

How It Works​

When enabled, the orchestrator automatically stores:

  • Plan data: LLM-generated routing plans with step dependencies
  • Execution results: Step-by-step results with timing, status, and responses
  • Trace correlation: Links to distributed tracing (Jaeger) via trace IDs
  • Metadata: Investigation notes and custom annotations

Storage Key Patterns​

Canonical provider composition derives execution-debug keys from TRUVAG3_REDIS_NAMESPACE:

Key PatternPurpose
truvag3:v1:<deployment>:execution-debug:{<deployment>:execution-debug:<request_id>}:recordMain execution record (plan + result)
truvag3:v1:<deployment>:execution-debug:index:recentSorted index for listing recent executions
truvag3:v1:<deployment>:execution-debug:index:trace:<trace_id>Trace ID → Request ID mapping
truvag3:v1:<deployment>:execution-debug:index:conversation:<sha256(conversation_id)>Chronological execution membership for one conversation

The execution record's metadata.conversation_id is authoritative. The hashed conversation index is a bounded lookup accelerator and may be lazily cleaned when records expire; index maintenance never changes the execution record.

Request-local record and retention keys share a Redis Cluster slot. The recent, trace, and conversation indexes are repairable projections and are updated as separate single-key operations when they cannot participate in that slot.

Example: Enable Execution Debug Storage​

# Enable execution debug storage
export TRUVAG3_EXECUTION_DEBUG_STORE_ENABLED=true

# Use default TTLs (72h / 3 days for both success and errors)
# Or customize retention:
export TRUVAG3_EXECUTION_DEBUG_TTL=48h
export TRUVAG3_EXECUTION_DEBUG_ERROR_TTL=336h # 14 days

# Optional bounded conversation lookup limits
export TRUVAG3_EXECUTION_DEBUG_CONVERSATION_QUERY_LIMIT=1000
export TRUVAG3_EXECUTION_DEBUG_INDEX_SCAN_LIMIT=5000

Example: Multi-Tenant Deployment​

# Keep cooperating producers and viewers in the same versioned deployment scope.
export TRUVAG3_EXECUTION_DEBUG_STORE_ENABLED=true
export TRUVAG3_REDIS_NAMESPACE=myapp-prod

# Request-local records use the canonical execution-debug hash-tagged layout.

Example: Kubernetes Deployment​

env:
# Enable execution debug storage
- name: TRUVAG3_EXECUTION_DEBUG_STORE_ENABLED
value: "true"

# Custom retention (optional)
- name: TRUVAG3_EXECUTION_DEBUG_TTL
value: "48h"
- name: TRUVAG3_EXECUTION_DEBUG_ERROR_TTL
value: "168h"

# Versioned deployment namespace isolation (optional)
- name: TRUVAG3_REDIS_NAMESPACE
value: "myteam"
- name: TRUVAG3_EXECUTION_DEBUG_CONVERSATION_QUERY_LIMIT
value: "1000"
- name: TRUVAG3_EXECUTION_DEBUG_INDEX_SCAN_LIMIT
value: "5000"

Viewing Execution Records​

Use the Registry Viewer App to visualize execution DAGs:

  1. Navigate to the "Executions" tab in the sidebar
  2. Browse recent executions with success/failure status
  3. Click on an execution to view the DAG visualization
  4. Inspect step details, timing, and results
  5. Link to Jaeger traces for distributed tracing correlation

Storage Provider​

The provider-neutral request-path contract is ExecutionStore. New application bootstrap code should supply that capability through OrchestrationBackends; the included redisprovider package is the default Redis composition, while a PostgreSQL, DynamoDB, or other provider implements the same narrow contract.

NewRedisExecutionDebugStore() remains an environment-aware compatibility constructor. NewExecutionStoreWithProvider() is a separate adapter for the older generic StorageProvider interface; the direct Redis store does not use that interface. Applications that already own Redis connection routing can use NewRedisExecutionDebugStoreWithClient, which does not read Redis connection or database environment variables and leaves the supplied client open.


Human-in-the-Loop (HITL) Configuration​

Configure Human-in-the-Loop (HITL) checkpoints for human oversight of AI-generated plans and sensitive operations. HITL enables pausing execution for human approval before proceeding with critical steps.

Important: HITL is disabled by default. Enable it via TRUVAG3_HITL_ENABLED=true when human oversight is required.

Core HITL Variables​

Source: all HITL variables below are loaded by DefaultConfig() in orchestration/interfaces.go — look for the HITLConfig struct and the "HITL configuration from environment" block.

VariableDefaultStatusDescriptionSource
TRUVAG3_HITL_ENABLEDfalseImplementedEnable/disable HITL globallyorchestration/interfaces.go
TRUVAG3_HITL_REQUIRE_PLAN_APPROVALfalseImplementedRequire human approval for all LLM-generated plansorchestration/interfaces.go
TRUVAG3_HITL_SENSITIVE_CAPABILITIES(empty)ImplementedComma-separated list of capabilities requiring both plan AND step approvalorchestration/interfaces.go
TRUVAG3_HITL_SENSITIVE_AGENTS(empty)ImplementedComma-separated list of agents requiring both plan AND step approvalorchestration/interfaces.go
TRUVAG3_HITL_STEP_SENSITIVE_CAPABILITIES(empty)ImplementedComma-separated list of capabilities requiring step-only approval (no plan approval)orchestration/interfaces.go
TRUVAG3_HITL_STEP_SENSITIVE_AGENTS(empty)ImplementedComma-separated list of agents requiring step-only approval (no plan approval)orchestration/interfaces.go
TRUVAG3_HITL_DEFAULT_TIMEOUT5mImplementedTimeout for human response before auto-actionorchestration/interfaces.go
TRUVAG3_HITL_ESCALATE_AFTER_RETRIES3ImplementedNumber of retries before escalating to humanorchestration/interfaces.go

HITL Storage Variables​

VariableDefaultStatusDescriptionSource

HITL Handler Variables​

VariableDefaultStatusDescriptionSource
TRUVAG3_HITL_WEBHOOK_URL(none)ImplementedWebhook URL for checkpoint notificationsApplication-specific

HITL Expiry Behavior Variables​

These variables control what happens when a checkpoint times out (expires) without a human response. See HITL User Guide: Expiry Behavior for detailed usage.

VariableDefaultValuesStatusDescriptionSource
TRUVAG3_HITL_DEFAULT_ACTIONrejectapprove, reject, abortImplementedAction to take when apply_default expiry behavior is used. Fail-safe default is reject (HITL enabled = require explicit approval).orchestration/interfaces.go
TRUVAG3_HITL_STREAMING_EXPIRYimplicit_denyimplicit_deny, apply_defaultImplementedExpiry behavior for streaming (SSE) requests. implicit_deny = status→expired, no action. apply_default = auto-resume with DefaultAction.orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_NON_STREAMING_EXPIRYapply_defaultimplicit_deny, apply_defaultImplementedExpiry behavior for non-streaming (HTTP 202) requests. apply_default = auto-apply DefaultAction on timeout.orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_DEFAULT_REQUEST_MODEnon_streamingstreaming, non_streamingImplementedDefault request mode when not explicitly set via WithRequestMode(). A warning is logged when this fallback is used.orchestration/hitl_checkpoint_store.go

Expiry Behavior Matrix (see HITL User Guide: Expiry Behavior Matrix):

Request ModeExpiry BehaviorWhat Happens
Streaming + implicit_denyStatus → expiredUser saw dialog but didn't respond. No action taken.
Streaming + apply_defaultStatus → expired_approved/rejectedAuto-resume enabled (see Auto-Resume)
Non-Streaming + apply_defaultStatus → expired_approved/rejectedDefaultAction applied automatically
Non-Streaming + implicit_denyStatus → expiredRequire manual intervention

HITL Expiry Processor Variables​

The expiry processor is a lifecycle-owned core.Runnable that scans a provider-neutral ExpiredCheckpointSource and processes claimed checkpoints according to the configured action. Register it before Framework.Run(). See HITL User Guide: Auto-Resume for the auto-approval flow.

VariableDefaultStatusDescriptionSource
TRUVAG3_HITL_EXPIRY_ENABLEDtrueImplementedEnable/disable the lifecycle-owned expiry processor. Set to false to disable automatic checkpoint expiration.orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_EXPIRY_INTERVAL10sImplementedHow often the processor scans the configured expiry source. Lower values mean faster detection but more backend load.orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_EXPIRY_BATCH_SIZE100ImplementedMaximum checkpoints processed per scan cycle. Prevents overwhelming the system when many expire simultaneously.orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_EXPIRY_DELIVERYat_most_onceImplementedCallback delivery guarantee: at_most_once (safe default, no retries) or at_least_once (may retry, callback must be idempotent).orchestration/hitl_checkpoint_store.go
TRUVAG3_HITL_EXPIRY_CLAIM_LEASE30sImplementedPositive lease duration for an atomic expired-checkpoint claim. Load with LoadCheckpointExpiryRuntimeConfigFromEnvironment; a later WithCheckpointExpiryRuntimeConfig option wins.orchestration/checkpoint_expiry_processor.go

HITL Approval Modes​

HITL supports two approval modes based on risk level:

ModeVariablesBehavior
Full HITL (Plan + Step)TRUVAG3_HITL_SENSITIVE_CAPABILITIES, TRUVAG3_HITL_SENSITIVE_AGENTSPauses at plan generation for approval, then pauses again at each matching step
Step-OnlyTRUVAG3_HITL_STEP_SENSITIVE_CAPABILITIES, TRUVAG3_HITL_STEP_SENSITIVE_AGENTSSkips plan approval, only pauses when the specific step is about to execute

Use Full HITL for high-risk operations (e.g., transfer_funds, delete_account) where you want to review the entire plan before any execution.

Use Step-Only for medium-risk operations (e.g., get_balance, view_orders) where you trust the plan but want confirmation before each action.

Example: Full HITL Configuration​

# Enable HITL with plan approval
export TRUVAG3_HITL_ENABLED=true
export TRUVAG3_HITL_REQUIRE_PLAN_APPROVAL=true

# Configure high-risk operations (plan + step approval)
export TRUVAG3_HITL_SENSITIVE_CAPABILITIES=transfer_funds,delete_account,send_email
export TRUVAG3_HITL_SENSITIVE_AGENTS=payment-service,admin-tool

# Timeout and escalation
export TRUVAG3_HITL_DEFAULT_TIMEOUT=5m
export TRUVAG3_HITL_ESCALATE_AFTER_RETRIES=3

# Redis storage (shared DB 0, isolated by deployment and HITL hash tag)
export TRUVAG3_REDIS_NAMESPACE=production

# Webhook for notifications
export TRUVAG3_HITL_WEBHOOK_URL=https://my-service/internal/hitl-webhook

Example: Step-Only HITL Configuration​

# Enable HITL (plan approval NOT required globally)
export TRUVAG3_HITL_ENABLED=true
export TRUVAG3_HITL_REQUIRE_PLAN_APPROVAL=false

# Full HITL (plan + step approval) for high-risk operations
export TRUVAG3_HITL_SENSITIVE_CAPABILITIES=transfer_funds,delete_account
export TRUVAG3_HITL_SENSITIVE_AGENTS=payment-service

# Step-only approval (no plan pause) for medium-risk operations
export TRUVAG3_HITL_STEP_SENSITIVE_CAPABILITIES=get_balance,view_orders,send_notification
export TRUVAG3_HITL_STEP_SENSITIVE_AGENTS=read-service,notification-tool

# Timeout and storage
export TRUVAG3_HITL_DEFAULT_TIMEOUT=5m

Example: Kubernetes Deployment​

env:
# Enable HITL
- name: TRUVAG3_HITL_ENABLED
value: "true"
- name: TRUVAG3_HITL_REQUIRE_PLAN_APPROVAL
value: "true"

# Sensitive operations
- name: TRUVAG3_HITL_SENSITIVE_CAPABILITIES
value: "transfer_funds,delete_account"
- name: TRUVAG3_HITL_SENSITIVE_AGENTS
value: "payment-service"

# Step-only operations
- name: TRUVAG3_HITL_STEP_SENSITIVE_CAPABILITIES
value: "get_balance,view_orders"

# Timeout
- name: TRUVAG3_HITL_DEFAULT_TIMEOUT
value: "10m"

# Webhook
- name: TRUVAG3_HITL_WEBHOOK_URL
value: "http://notification-service/hitl-webhook"

Viewing HITL Checkpoints​

Use the Registry Viewer App or the HITL API endpoints to monitor pending checkpoints:

  • GET /hitl/checkpoints - List pending checkpoints
  • GET /hitl/checkpoints/{id} - Get checkpoint details
  • POST /hitl/command - Submit approval/rejection decision (with {"checkpoint_id": "...", "type": "approve|reject"})
  • POST /hitl/resume-sync/{id} - Resume execution after approval (JSON response)
  • POST /hitl/resume/{id} - Resume execution after approval (SSE stream)

See HUMAN_IN_THE_LOOP_USER_GUIDE.md for detailed usage and examples.


Async Task Configuration​

Configure asynchronous task processing for long-running operations. The async task system enables the HTTP 202 + Polling pattern for operations that may take minutes to complete.

The async task system uses these core framework types (no additional env vars required):

  • core.Task - Task data structure with status, progress, result
  • core.TaskQueue - Redis-backed task queue interface
  • core.TaskStore - Redis-backed task state storage
  • core.TaskWorkerPool - Worker pool implementation
  • orchestration.TaskAPIHandler - HTTP API handler for task endpoints

See Async Orchestration Guide for detailed usage.

Default Redis orchestration preset limits​

redisprovider.NewDefaultBackends loads these variables automatically for the selected backend roles. Lower-layer callers use redisprovider.LoadOptionsFromEnvironment explicitly, then redisprovider.ConfigureOptions when code configuration must win. Present empty, malformed, non-positive, or overflowing durations are rejected before backends are returned; later code options do not suppress that validation.

VariableDefaultStatusDescriptionSource
TRUVAG3_EXECUTION_DEBUG_TTL72h (3 days)ImplementedSuccessful execution retention applied to the actual Redis execution store by the presetorchestration/redisprovider/options.go
TRUVAG3_EXECUTION_DEBUG_ERROR_TTL72h (3 days)ImplementedFailed/cancelled execution retention applied by the Redis preset; WithExecutionStoreConfig overrides valid environment valuesorchestration/redisprovider/options.go
TRUVAG3_LLM_DEBUG_TTL72h (3 days)ImplementedSuccessful LLM-debug retention applied by the Redis presetorchestration/redisprovider/options.go
TRUVAG3_LLM_DEBUG_ERROR_TTL72h (3 days)ImplementedFailed LLM-debug retention applied by the Redis presetorchestration/redisprovider/options.go
TRUVAG3_HITL_CHECKPOINT_TTL24hImplementedCheckpoint retention applied by the Redis presetorchestration/redisprovider/options.go
TRUVAG3_WORKFLOW_STATE_TTL24hImplementedRetention for workflow execution state composed by the default Redis backend presetorchestration/redisprovider/options.go
TRUVAG3_TASK_QUEUE_RETRY_ATTEMPTS3ImplementedPositive number of Redis task-queue operation attemptsorchestration/redisprovider/options.go
TRUVAG3_TASK_QUEUE_RETRY_DELAY100msImplementedPositive delay between Redis task-queue operation attemptsorchestration/redisprovider/options.go
TRUVAG3_TASK_INDEX_RECONCILE_INTERVAL1mImplementedPositive interval for the framework-owned task-index repair runnableorchestration/redisprovider/options.go
TRUVAG3_TASK_INDEX_RECONCILE_MAX_IDS1000ImplementedPositive maximum IDs examined by one bounded task-index repair passorchestration/redisprovider/options.go
TRUVAG3_SCHEDULER_MAX_SCHEDULES10000ImplementedPositive per-deployment schedule capacity enforced before inserting a new scheduleorchestration/redisprovider/options.go

Scheduled Execution Configuration​

Configure the scheduled-execution subsystem: delayed and recurring task execution across agents. The system has two components (scheduler-tool produces schedules, scheduled-executor consumes and dispatches them). Code-level configuration via ExecutorDeps fields takes priority over environment variables.

Scheduler-Tool (Producer)​

VariableDefaultStatusDescriptionSource
TRUVAG3_SCHEDULER_TICK_INTERVAL5sImplementedHow often the Scheduler polls for due schedules (Go duration)orchestration/scheduler.go
TRUVAG3_SCHEDULER_LOCK_TTL30sImplementedDistributed lock TTL for leader election; must be > tick interval (Go duration)orchestration/scheduler.go
TRUVAG3_SCHEDULER_MAX_SCHEDULES10000ImplementedMaximum schedules retained in one deployment's explicit all/due indexesorchestration/redis_schedule_store.go

Scheduled-Executor (Consumer)​

VariableDefaultStatusDescriptionSource
TRUVAG3_EXECUTOR_WORKER_COUNT5ImplementedNumber of concurrent dispatch goroutinesexamples/scheduled-executor/worker.go
TRUVAG3_EXECUTOR_MAX_RETRIES3ImplementedMax retry attempts per task before dead-letteringexamples/scheduled-executor/worker.go
TRUVAG3_EXECUTOR_RETRY_BASE_DELAY5sImplementedBase delay for exponential backoff (Go duration)examples/scheduled-executor/worker.go
TRUVAG3_EXECUTOR_RETRY_MAX_DELAY60sImplementedMaximum backoff cap (Go duration)examples/scheduled-executor/worker.go
TRUVAG3_EXECUTOR_DISPATCH_TIMEOUT15mImplementedPer-request HTTP timeout for POST to the target agent. Size it for that agent's entire synchronous request, including planning, phases, retries, synthesis and any blocking HITL wait. Matching only the target's per-call TRUVAG3_ORCHESTRATION_TIMEOUT is insufficient.examples/scheduled-executor/worker.go

Both components require REDIS_URL for the task queue and service registry. The scheduled-executor also requires TRUVAG3_K8S_SERVICE_NAME and standard framework variables for service registration.

Example: Tuning for High-Volume Scheduling​

# Scheduler-tool: faster polling for time-sensitive schedules
export TRUVAG3_SCHEDULER_TICK_INTERVAL=2s
export TRUVAG3_SCHEDULER_LOCK_TTL=10s

# Scheduled-executor: more workers, more retries, tighter backoff
export TRUVAG3_EXECUTOR_WORKER_COUNT=10
export TRUVAG3_EXECUTOR_MAX_RETRIES=5
export TRUVAG3_EXECUTOR_RETRY_BASE_DELAY=2s
export TRUVAG3_EXECUTOR_RETRY_MAX_DELAY=30s
# Dispatch timeout defaults to 15m — only lower this if your agents
# complete the entire synchronous request faster, including all phases.

Code-Level Override​

Environment variables are the deployment-time tuning layer. For stable compile-time defaults, set fields directly on ExecutorDeps:

worker, _ := NewWorker(ExecutorDeps{
WorkerCount: 10, // overrides TRUVAG3_EXECUTOR_WORKER_COUNT
MaxRetries: 5, // overrides TRUVAG3_EXECUTOR_MAX_RETRIES
DispatchTimeout: 30 * time.Second, // overrides TRUVAG3_EXECUTOR_DISPATCH_TIMEOUT
// other fields...
})

See Scheduled Tasks Guide for the full architecture and operational guide.


Prompt Configuration​

Configure LLM prompt customization for orchestration.

VariableDefaultStatusDescriptionSource
TRUVAG3_PROMPT_TEMPLATE_FILE(none)ImplementedPath to custom prompt template fileorchestration/prompt_config_env.go
TRUVAG3_PROMPT_DOMAIN(none)ImplementedDomain context (healthcare, finance, legal, retail)orchestration/prompt_config_env.go
TRUVAG3_PROMPT_TYPE_RULES(none)ImplementedJSON array of additional type rulesorchestration/prompt_config_env.go
TRUVAG3_PROMPT_CUSTOM_INSTRUCTIONS(none)ImplementedJSON array of custom instructionsorchestration/prompt_config_env.go

Example​

export TRUVAG3_PROMPT_DOMAIN="healthcare"
export TRUVAG3_PROMPT_TYPE_RULES='[{"type_names":["uuid"],"json_type":"JSON strings","example":"\"abc-123\""}]'
export TRUVAG3_PROMPT_CUSTOM_INSTRUCTIONS='["Prefer local tools", "Minimize API calls"]'

Agent Skills Configuration​

Skills are disabled by default. These variables are read only by the explicit orchestration environment-resolution path (ResolveOrchestratorConfig with an environment mode or CreateOrchestratorFromEnvironment). Empty or malformed skill values that participate in effective resolution fail both compatible and strict modes without echoing their contents; EnvironmentDisabled performs no environment reads. A non-authoritative tuning value shadowed by an explicit code value is not consulted.

Skill environment precedence is intentionally asymmetric. When present, TRUVAG3_SKILLS_ENABLED and TRUVAG3_SKILL_BINDINGS_JSON are authoritative deployment settings applied after code options; the binding value replaces the complete developer-owned list and never appends or merges. Other skill variables fill only fields that code left unset. Model and guidance-file variables are read only after skills are effectively enabled with at least one binding. This keeps every pod replica on the same eligibility policy while preserving explicit code overrides for tuning values.

For a concept-to-operations walkthrough with authoring, binding, Kubernetes, and Registry Viewer examples, see the Agent Skills Guide.

Runtime and binding variables​

VariableDefaultStatusDescription
TRUVAG3_SKILLS_ENABLEDfalseImplementedEnable skill runtime. A non-empty binding list and injected SkillRegistry are also required.
TRUVAG3_SKILL_BINDINGS_JSON[]ImplementedComplete JSON array of {namespace,name,version,activation,required} bindings. version defaults to published; activation is always, auto, or explicit.
TRUVAG3_SKILL_DOMAIN_COMPATIBILITY_MODEwarnImplementedoff, warn, or enforce comparison between an agent prompt domain and authored skill domains. Domain never changes skill identity.
TRUVAG3_SKILL_CACHE_MODElocalImplementedlocal for verified immutable-body LRU caching or disabled. Aliases and catalog reads are never cached.
TRUVAG3_SKILL_CACHE_MAX_BYTES16777216ImplementedPositive byte capacity of the process-local immutable-content cache.
TRUVAG3_SKILL_REGISTRY_READ_TIMEOUT5sImplementedPositive timeout for each runtime registry operation.
TRUVAG3_SKILL_RESOURCE_SELECTION_ATTEMPT_TIMEOUT0sImplementedNonnegative duration for each built-in resource AI attempt; zero inherits parent. Resource v2 retries timeout within two total attempts.
TRUVAG3_SKILL_ACTIVATION_MODELagent/client modelImplementedModel intent for the bounded activation selector.
TRUVAG3_SKILL_RESOURCE_MODELagent/client modelImplementedModel intent for the bounded resource selector.
TRUVAG3_SKILL_ACTIVATION_GUIDANCE_FILEnoneImplementedMounted UTF-8 file containing bounded additive activation-selector guidance.
TRUVAG3_SKILL_RESOURCE_GUIDANCE_FILEnoneImplementedMounted UTF-8 file containing bounded additive resource-selector guidance.

Example complete binding replacement:

export TRUVAG3_SKILLS_ENABLED=true
export TRUVAG3_SKILL_BINDINGS_JSON='[
{"namespace":"travel","name":"weather-assessment","version":"published","activation":"auto","required":false},
{"namespace":"travel","name":"safety-policy","version":"3","activation":"always","required":true}
]'

Binding behavior is precise:

Field/valueRuntime behavior
version: "published"Resolve the mutable publication pointer once at request start, then pin its exact immutable revision and hashes for the execution.
version: "N"Resolve that positive immutable revision; later publications do not affect it.
activation: "always"Activate deterministically whenever candidate resolution admits the binding.
activation: "auto"Let the bounded selector activate it at initial planning or a later continuation boundary.
activation: "explicit"Activate only through the trusted host carrier; user text and ordinary request metadata cannot request it.
required: trueTreat candidate/content availability failures as fatal when applicable. This does not force activation. A required binding is invalid while skills are disabled.

SkillConfig.RuntimePolicyID is deliberately code-only and limited to 128 bytes. It identifies custom activation, resource-resolution, or token-counting behavior for response-cache eligibility; it is not a deployment environment switch.

Selector guidance is capped at 4,096 bytes and 512 estimated tokens. Selector temperature (0.01), deliberately unset provider-native response format, strict JSON parsing, retry count, fixed prompts, and output ceilings are framework contracts and are not environment switches. The unset response format avoids provider-specific wire values; the fixed prompt/parser/retry path still enforces structured JSON output.

Resource selector v2 accepts a complete outer JSON/unlabelled fence before strict body validation. Its retry eligibility includes child-attempt timeout, within the unchanged two-attempt ceiling; activation is unchanged. The attempt-duration setting is tunable: code zero is unset, nonzero code wins over env, and explicit env 0s inherits the parent deadline. Invalid consulted values fail in both compatible and strict modes; disabled-env mode ignores them. Optional omission is diagnosed, while parent cancellation remains terminal.

Runtime limits​

VariableDefaultStatusDescription
TRUVAG3_SKILL_MAX_BINDINGS32ImplementedMaximum explicit bindings.
TRUVAG3_SKILL_MAX_AUTO_CANDIDATES16ImplementedMaximum candidates presented to activation selection.
TRUVAG3_SKILL_CATALOG_TOKEN_BUDGET2000ImplementedBody-free activation catalog budget.
TRUVAG3_SKILL_MAX_RESOURCE_CANDIDATES32ImplementedMaximum resource-index candidates at one boundary.
TRUVAG3_SKILL_RESOURCE_CATALOG_TOKEN_BUDGET2000ImplementedBody-free resource catalog budget.
TRUVAG3_SKILL_MAX_ACTIVE_SKILLS6ImplementedMaximum admitted active skills in one execution.
TRUVAG3_SKILL_TOTAL_TOKEN_BUDGET8192ImplementedOverall skill projection budget.
TRUVAG3_SKILL_MAIN_TOKEN_BUDGET6144ImplementedMain instruction budget.
TRUVAG3_SKILL_RESOURCE_TOKEN_BUDGET4096ImplementedResource-content budget.
TRUVAG3_SKILL_MAX_RESOURCES_PER_PHASE2ImplementedResource bodies admitted at one boundary.
TRUVAG3_SKILL_MAX_RESOURCES_PER_EXECUTION8ImplementedDistinct resource bodies admitted across an execution.
TRUVAG3_SKILL_RESOLUTION_MAX_TOKENS512ImplementedFixed upper output budget used by selectors.
TRUVAG3_SKILL_SYNTHESIS_TOKEN_BUDGET6000ImplementedSkill contribution budget at synthesis.
TRUVAG3_SKILL_EFFECTIVE_INPUT_TOKEN_BUDGET0ImplementedOptional model-context allowance. When positive, the effective total skill budget is min(total_token_budget, floor(effective_input_token_budget/10)); 0 disables this additional 10% cap.

Response-cache short-circuits are eligible only when the behavior projection is stable: either SkillConfig.RuntimePolicyID is set, or no custom skill runtime component is installed and both selector models are explicitly pinned. Normal execution, immutable content caching, and skill correctness do not depend on this eligibility bit; an ineligible configuration simply bypasses cached answers.

Included Redis and Registry Viewer host​

VariableDefaultStatusDescription
TRUVAG3_SKILL_AUTHORING_MAX_NAME_CHARS64Example OnlyRegistry Viewer skill-management host override.
TRUVAG3_SKILL_AUTHORING_MAX_DESCRIPTION_CHARS1024Example OnlyRegistry Viewer host override.
TRUVAG3_SKILL_AUTHORING_MAX_MANIFEST_TOKENS5000Example OnlyRegistry Viewer host override.
TRUVAG3_SKILL_AUTHORING_MAX_MANIFEST_BYTES24576Example OnlyRegistry Viewer host override.
TRUVAG3_SKILL_AUTHORING_MAX_RESOURCE_TOKENS8000Example OnlyPer-resource host override.
TRUVAG3_SKILL_AUTHORING_MAX_RESOURCE_BYTES32768Example OnlyPer-resource host override.
TRUVAG3_SKILL_AUTHORING_MAX_RESOURCES32Example OnlyResources per package host override.
TRUVAG3_SKILL_AUTHORING_MAX_PACKAGE_BYTES1048576Example OnlyHTTP package body host override.
TRUVAG3_SKILL_ADMIN_MAX_DELETE_VERSIONS100Example OnlyMaximum inclusive deletion range accepted by the host.
TRUVAG3_SKILL_AUTHORING_ADVICE_MAX_OUTPUT_TOKENS1024Example OnlyOptional authoring-advisor output ceiling; the bundled host does not configure an advisor in V1.
JAEGER_UI_URLhttp://jaeger.localhostExample OnlyBrowser-facing Jaeger base URL used by the Registry Viewer trace redirect.

These Registry Viewer variables belong to the example host, not framework-global configuration. Other skills hosts pass SkillAuthoringLimits and SkillAdministrationLimits directly to NewSkillAdminHandler. The Registry Viewer binary reads these values from its process environment; its bundled setup.sh does not automatically forward authoring/admin overrides from the invoking shell into Kubernetes. It forwards JAEGER_UI_URL into the deployment ConfigMap as an optional browser-navigation target. Registry Viewer does not query Jaeger.


Quick Reference Table​

Essential Variables for Production (All Implemented)​

# Core
export TRUVAG3_AGENT_NAME="my-agent"
export TRUVAG3_PORT=8080
export TRUVAG3_NAMESPACE="production"

# Discovery
export REDIS_URL="redis://redis:6379"

# AI (one of these)
export OPENAI_API_KEY="sk-..."
# or: GROQ_API_KEY, ANTHROPIC_API_KEY, etc.

# Telemetry
export OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4318"
export OTEL_SERVICE_NAME="my-agent"

# Orchestration (for long-running AI workflows)
export TRUVAG3_ORCHESTRATION_TIMEOUT=5m
export TRUVAG3_HTTP_WRITE_TIMEOUT=5m
export TRUVAG3_HTTP_READ_TIMEOUT=5m

Essential Variables for Development (All Implemented)​

export TRUVAG3_DEV_MODE=true
export TRUVAG3_MOCK_DISCOVERY=true
export TRUVAG3_DEBUG=true

Iterative Planning Variables (for Multi-Phase DAG)​

# Enable multi-phase planning (default: true)
export TRUVAG3_ITERATIVE_PLANNING_ENABLED=true
export TRUVAG3_ITERATIVE_MAX_PHASES=20 # Max planning phases per request
export TRUVAG3_ITERATIVE_MAX_TOTAL_STEPS=200 # Max total steps across all phases
export TRUVAG3_ITERATIVE_PHASE_TIMEOUT=25m # Configured phase budget; delegation may enlarge it

Step Retry Backoff Variables (for Retry Tuning)​

# Exponential backoff for step retries (defaults shown)
export TRUVAG3_STEP_RETRY_INITIAL_DELAY=500ms # Base delay, doubles per attempt
export TRUVAG3_STEP_RETRY_MAX_DELAY=10s # Delay cap regardless of attempt count

Result Data Management Variables (for Large Responses)​

# Result trimming (enabled by default — prevents token overflow)
export TRUVAG3_RESULT_TRIM_ENABLED=true
export TRUVAG3_RESULT_TRIM_MAX_BYTES=65536 # 64 KiB per result (~16K tokens)
export TRUVAG3_RESULT_TRIM_MAX_TOTAL_BYTES=196608 # 192 KiB total (~48K tokens)
export TRUVAG3_RESULT_TRIM_MAX_MICRO_BYTES=65536 # 64 KB for micro-resolution prompts
export TRUVAG3_RESULT_TRIM_MAX_AGENT_INPUT_BYTES=0 # 0 = no cap (fidelity-first); set > 0 to enable the guard
export TRUVAG3_RESULT_TRIM_SCHEMA_MAPPING_THRESHOLD=16384 # 16 KB — schema mapping above this

# Result distillation (on by default — adds LLM call per large result)
export TRUVAG3_RESULT_DISTILL_ENABLED=true
export TRUVAG3_RESULT_DISTILL_THRESHOLD=16384 # Min bytes to trigger
export TRUVAG3_RESULT_DISTILL_PREFILTER=131072 # Pre-filter budget (128 KB)
export TRUVAG3_RESULT_DISTILL_TARGET=4096 # LLM output target
export TRUVAG3_RESULT_DISTILL_MODEL=fast # Catalog-backed providers; Bedrock needs a programmatic empty override
export TRUVAG3_RESULT_DISTILL_CACHE_TTL=5m # Distillation cache TTL
export TRUVAG3_RESULT_DISTILL_DEADLINE=45s # Hot-path compaction bound (positive durations only)
export TRUVAG3_RESULT_DISTILL_CONTEXT_TOKENS=150000 # Above this, chunk → map-reduce
export TRUVAG3_RESULT_DISTILL_MAP_CONCURRENCY=8 # Concurrent chunk distillations
export TRUVAG3_RESULT_DISTILL_MAPREDUCE_THRESHOLD=0 # Byte threshold → map-reduce (0 = disabled)

Shared Memory Variables (for Cross-Agent Coordination)​

# Domain scoping — agents in the same domain share memory
export TRUVAG3_AGENT_DOMAIN="infrastructure"

# Activity compaction — LLM-powered event digests
export TRUVAG3_SHARED_MEMORY_SUMMARIZER_MODEL=fast # Model for summarization/compaction
export TRUVAG3_SHARED_MEMORY_ENRICHMENT_SUMMARY_MAX_TOKENS=500 # Digest target; built-in generation allowance is 5x
export TRUVAG3_SHARED_MEMORY_COMPACTION_RAW_LIMIT=200 # Max events sent to compactor
export TRUVAG3_SHARED_MEMORY_COMPACTION_RECENT_DETAIL=15 # Raw events after digest

# Digest caching — reduces redundant LLM calls
export TRUVAG3_SHARED_MEMORY_DIGEST_CACHE_TTL=5m # Cache expiry
export TRUVAG3_SHARED_MEMORY_DIGEST_INCREMENTAL_THRESHOLD=20 # Above this → full recompact

# Activity coordination — real-time agent signals
export TRUVAG3_ACTIVITY_SIGNAL_TTL=5m # Signal expiry
export TRUVAG3_ACTIVITY_SIGNAL_MAX_IN_PROMPT=10 # Max signals in prompt

LLM Debug Variables (for Troubleshooting)​

# Enable debug payload storage (disabled by default)
export TRUVAG3_LLM_DEBUG_ENABLED=true
export TRUVAG3_LLM_DEBUG_TTL=72h # Success record retention (3 days)
export TRUVAG3_LLM_DEBUG_ERROR_TTL=72h # Error record retention (3 days)
export TRUVAG3_REDIS_NAMESPACE=production # Shared DB-0 deployment namespace

Kubernetes ConfigMap Example​

apiVersion: v1
kind: ConfigMap
metadata:
name: truvag3-config
data:
TRUVAG3_AGENT_NAME: "research-agent"
TRUVAG3_NAMESPACE: "production"
TRUVAG3_LOG_LEVEL: "info"
TRUVAG3_LOG_FORMAT: "json"
TRUVAG3_DISCOVERY_CACHE: "true"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector.observability:4318"

Kubernetes Secret Example​

apiVersion: v1
kind: Secret
metadata:
name: truvag3-secrets
type: Opaque
stringData:
OPENAI_API_KEY: "sk-..."
REDIS_URL: "redis://:password@redis:6379"

Configuration Priority​

Configuration is resolved in three layers, applied sequentially (last write wins):

StepSourceExamplePriority
1DefaultConfig()AllowedHeaders: ["Content-Type", "Authorization"]Lowest
2LoadFromEnv()TRUVAG3_CORS_HEADERS=Content-Type,Authorization,X-User-IDMedium
3Functional optionsWithCORS([]string{"*"}, true)Highest

Each step merges into the configuration struct. A later step only overwrites fields it explicitly sets — unset fields retain their value from earlier steps. For example, WithCORS sets Enabled, AllowedOrigins, and AllowCredentials but does not touch AllowedHeaders, so an env var override for headers survives.

This follows the standard Go / 12-factor convention (same as Viper, Cobra, Kong):

  • Defaults provide safe baselines
  • Environment variables allow deployment-time tuning without code changes (ideal for K8s ConfigMaps)
  • Functional options express explicit developer intent and take precedence

See also: NewConfig() in core/config.go documents this sequence in its godoc.

For environment variables with multiple valid names, standard names take precedence over framework-specific aliases. This rule does not make contradictory forms mergeable: Redis connection sources are selected exactly once, and REDIS_URL combined with either structured topology fields or the removed TRUVAG3_REDIS_URL alias fails validation.


Variables Marked as "Struct Tag Only"​

These variables are defined in Go struct tags with env:"..." annotations but are not currently loaded in the LoadFromEnv() function. They may work if you're using a reflection-based configuration loader, but the default LoadFromEnv() does not process them.

To use these variables, you would need to either:

  1. Use programmatic configuration via functional options
  2. Implement reflection-based struct tag parsing
  3. Submit a PR to add explicit loading for these variables

See Also​