How Agent Configuration Overrides Are Applied to OpenMAIC's Initial State
OpenMAIC merges server-side defaults, environment variables, and request-level configOverrides in lib/agent/runtime/build-agent.ts to construct the agent's initial state, with later sources taking precedence over earlier ones.
In the OpenMAIC framework, the initial state serves as the immutable seed for every agent session. Understanding how agent configuration overrides flow into this state is critical for customizing behavior across deployments without modifying core source code.
The Three-Layer Configuration Merge
OpenMAIC employs a cascading merge strategy inside lib/agent/runtime/build-agent.ts. Three distinct sources contribute to the final configuration object that becomes part of the canvas initial state.
Server-Side Defaults
The foundation consists of immutable defaults loaded from the repository's configuration directory and persisted workspace settings. The function getAgentBaseConfig() retrieves these values, establishing the baseline agent capabilities and provider settings.
Environment-Derived Overrides
The runtime reads deployment-specific values from environment variables (e.g., AGENT_TEMPERATURE, LLM_PROVIDER) through resolveEnvOverrides(). These settings overwrite server defaults but remain subordinate to request-level inputs, allowing operators to tune systems without code changes.
Request-Level Overrides
Client applications send per-session customizations via the configOverrides payload in the HTTP request body. These values always win during the merge, enabling dynamic UI controls like temperature sliders to instantly affect agent behavior.
Implementation in build-agent.ts
The core merging logic resides in lib/agent/runtime/build-agent.ts. The buildAgent function executes a shallow merge where subsequent sources overwrite previous ones:
export function buildAgent(request: AgentRequest) {
// 1️⃣ Load immutable server-side defaults
const baseConfig = getAgentBaseConfig();
// 2️⃣ Apply environment-derived overrides
const envConfig = resolveEnvOverrides();
// 3️⃣ Extract request-level overrides
const requestConfig = request.configOverrides ?? {};
// 4️⃣ Merge with precedence: request > env > base
const mergedConfig = {
...baseConfig,
...envConfig,
...requestConfig,
};
// 5️⃣ Package into the canvas initial state
const initialState = {
...defaultCanvasState,
config: mergedConfig,
};
return initialState;
}
This function returns the fully composed initial state that downstream orchestration consumes.
Propagation to the Canvas Store
The merged configuration is injected into the static initialState object defined in lib/store/canvas.ts at line 219. This object serves as the single source of truth for the agent's starting configuration, including UI layout and skill lists.
// lib/store/canvas.ts (line 219)
const initialState = {
...defaultCanvasState,
config: mergedConfig, // Injected from build-agent.ts
};
Orchestration and State Initialization
When a new session begins, lib/orchestration/stateless-generate.ts consumes this initial state to seed the execution graph. The streaming pipeline initializes with these configuration values locked in, ensuring consistent behavior throughout the session lifecycle.
Validation Through Testing
The precedence rules are enforced by comprehensive test suites:
tests/agent-runtime/tool-call-integrity.test.tsverifies that request-levelconfigOverridescorrectly modify tool call parameters in the initial state.tests/server/provider-config.test.tsvalidates that environment variables override server-side YAML configurations while remaining subordinate to request payloads.
Practical Implementation Examples
Supplying a temperature override from the client:
await fetch('/api/agent/sessions', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'gpt-4',
configOverrides: { temperature: 0.9 },
}),
});
Setting global provider defaults via environment:
# .env file
AGENT_PROVIDER=openai
AGENT_TEMPERATURE=0.7
Inspecting the merged configuration at runtime:
import { useCanvasStore } from '@/lib/store/canvas';
const { config } = useCanvasStore.getState();
console.log(config); // Final merged configuration
Summary
- Three sources feed the initial state: server-side defaults, environment variables, and request-level overrides.
- Precedence is strict: request overrides beat environment variables, which beat server defaults.
- Implementation lives in
lib/agent/runtime/build-agent.ts, wherebuildAgent()performs a shallow merge. - The canvas store (
lib/store/canvas.ts, line 219) receives the final configuration object. - Orchestration begins with
lib/orchestration/stateless-generate.tsusing this seed state. - Tests in
tests/agent-runtime/tool-call-integrity.test.tsandtests/server/provider-config.test.tsguarantee correct precedence.
Frequently Asked Questions
What happens if the same key exists in both environment variables and request overrides?
The request override wins. The merge logic in buildAgent applies requestConfig last, ensuring client-specified values always take precedence over deployment environment settings.
Does OpenMAIC support deep merging of nested configuration objects?
No. The merge performed in lib/agent/runtime/build-agent.ts is shallow. Top-level keys are replaced wholesale rather than recursively merged, simplifying the precedence model and preventing unintended partial overrides.
How can I verify which configuration values are active in a running session?
Import the canvas store from lib/store/canvas.ts and inspect the config property. This object reflects the fully merged state after all three layers have been applied during the initial buildAgent call.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →