#81 - .env vars applied to settings
deci committed
Dec 9, 2025 at 16:47 UTC
2400dd5882007d250740286ac1e5d5257207df25
4 files changed
+164
-71
README.md
+1
@@ -81,6 +81,7 @@ Agent Zero now supports **Projects** – isolated workspaces with their own prom
81
- The framework does not guide or limit the agent in any way. There are no hard-coded rails that agents have to follow.
82
- Every prompt, every small message template sent to the agent in its communication loop can be found in the **prompts/** folder and changed.
83
- Every default tool can be found in the **python/tools/** folder and changed or copied to create new predefined tools.
84
+- **Automated configuration** via `A0_SET_` environment variables for deployment automation and easy setup.
85
86

87
docs/development.md
+14
@@ -149,6 +149,20 @@ You're now ready to contribute to Agent Zero, create custom extensions, or modif
149
- See [extensibility](extensibility.md) for instructions on how to create custom extensions.
150
- See [contribution](contribution.md) for instructions on how to contribute to the framework.
151
152
+## Configuration via Environment Variables
153
+
154
+For development and testing, you can override default settings using the `.env` file with `A0_SET_` prefixed variables:
155
+
156
+```env
157
+# Add to your .env file
158
+A0_SET_chat_model_provider=ollama
159
+A0_SET_chat_model_name=llama3.2
160
+A0_SET_chat_model_api_base=http://localhost:11434
161
+A0_SET_memory_recall_interval=5
162
+```
163
+
164
+These environment variables automatically override the hardcoded defaults in `get_default_settings()` without modifying code. Useful for testing different configurations or multi-environment setups.
165
+
166
## Want to build your docker image?
167
- You can use the `DockerfileLocal` to build your docker image.
168
- Navigate to your project root in the terminal and run `docker build -f DockerfileLocal -t agent-zero-local --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) .`
docs/installation.md
+47
-1
@@ -93,9 +93,55 @@ The following user guide provides instructions for installing and running Agent
93
- `/tmp/settings.json` - Your Agent Zero settings
94
95
> [!TIP]
96
-> Choose a location that's easy to access and backup. All your Agent Zero data
96
+> Choose a location that's easy to access and backup. All your Agent Zero data
97
> will be directly accessible in this directory.
98
99
+### Automated Configuration via Environment Variables
100
+
101
+Agent Zero settings can be automatically configured using environment variables with the `A0_SET_` prefix in your `.env` file. This enables automated deployments without manual configuration.
102
+
103
+**Usage:**
104
+Add variables to your `.env` file in the format:
105
+```
106
+A0_SET_{setting_name}={value}
107
+```
108
+
109
+**Examples:**
110
+```env
111
+# Model configuration
112
+A0_SET_chat_model_provider=anthropic
113
+A0_SET_chat_model_name=claude-3-5-sonnet-20241022
114
+A0_SET_chat_model_ctx_length=200000
115
+
116
+# Memory settings
117
+A0_SET_memory_recall_enabled=true
118
+A0_SET_memory_recall_interval=5
119
+
120
+# Agent configuration
121
+A0_SET_agent_profile=custom
122
+A0_SET_agent_memory_subdir=production
123
+```
124
+
125
+**Docker usage:**
126
+When running Docker, you can pass these as environment variables:
127
+```bash
128
+docker run -p 50080:80 \
129
+ -e A0_SET_chat_model_provider=anthropic \
130
+ -e A0_SET_chat_model_name=claude-3-5-sonnet-20241022 \
131
+ agent0ai/agent-zero
132
+```
133
+
134
+**Type conversion:**
135
+- Strings are used as-is
136
+- Numbers are automatically converted (e.g., "100000" becomes integer 100000)
137
+- Booleans accept: true/false, 1/0, yes/no, on/off (case-insensitive)
138
+- Dictionaries must be valid JSON (e.g., `{"temperature": "0"}`)
139
+
140
+**Notes:**
141
+- These override default values in settings.json
142
+- Sensitive settings (API keys, passwords) use their existing environment variables
143
+- Container/process restart required for changes to take effect
144
+
145
2.3. Run the container:
146
- In Docker Desktop, go back to the "Images" tab
147
- Click the `Run` button next to the `agent0ai/agent-zero` image
python/helpers/settings.py
+102
-70
@@ -4,7 +4,7 @@ import json
4
import os
5
import re
6
import subprocess
7
-from typing import Any, Literal, TypedDict, cast
7
+from typing import Any, Literal, TypedDict, cast, TypeVar
8
9
import models
10
from python.helpers import runtime, whisper, defer, git
@@ -15,6 +15,38 @@ from python.helpers.secrets import get_default_secrets_manager
15
from python.helpers import dirty_json
16
17
18
+T = TypeVar('T')
19
+
20
+def get_default_value(name: str, value: T) -> T:
21
+ """
22
+ Load setting value from .env with A0_SET_ prefix, falling back to default.
23
+
24
+ Args:
25
+ name: Setting name (will be prefixed with A0_SET_)
26
+ value: Default value to use if env var not set
27
+
28
+ Returns:
29
+ Environment variable value (type-normalized) or default value
30
+ """
31
+ env_value = dotenv.get_dotenv_value(f"A0_SET_{name}")
32
+
33
+ if env_value is None:
34
+ return value
35
+
36
+ # Normalize type to match value param type
37
+ try:
38
+ if isinstance(value, bool):
39
+ return env_value.lower() in ('true', '1', 'yes', 'on') # type: ignore
40
+ elif isinstance(value, dict):
41
+ return json.loads(env_value) # type: ignore
42
+ elif isinstance(value, str):
43
+ return str(env_value).strip() # type: ignore
44
+ else:
45
+ return type(value)(env_value) # type: ignore
46
+ except (ValueError, TypeError, json.JSONDecodeError):
47
+ return value
48
+
49
+
50
class Settings(TypedDict):
51
version: str
52
@@ -1456,83 +1488,83 @@ def _write_sensitive_settings(settings: Settings):
1488
def get_default_settings() -> Settings:
1489
return Settings(
1490
version=_get_version(),
1459
- chat_model_provider="openrouter",
1460
- chat_model_name="openai/gpt-4.1",
1461
- chat_model_api_base="",
1462
- chat_model_kwargs={"temperature": "0"},
1463
- chat_model_ctx_length=100000,
1464
- chat_model_ctx_history=0.7,
1465
- chat_model_vision=True,
1466
- chat_model_rl_requests=0,
1467
- chat_model_rl_input=0,
1468
- chat_model_rl_output=0,
1469
- util_model_provider="openrouter",
1470
- util_model_name="openai/gpt-4.1-mini",
1471
- util_model_api_base="",
1472
- util_model_ctx_length=100000,
1473
- util_model_ctx_input=0.7,
1474
- util_model_kwargs={"temperature": "0"},
1475
- util_model_rl_requests=0,
1476
- util_model_rl_input=0,
1477
- util_model_rl_output=0,
1478
- embed_model_provider="huggingface",
1479
- embed_model_name="sentence-transformers/all-MiniLM-L6-v2",
1480
- embed_model_api_base="",
1481
- embed_model_kwargs={},
1482
- embed_model_rl_requests=0,
1483
- embed_model_rl_input=0,
1484
- browser_model_provider="openrouter",
1485
- browser_model_name="openai/gpt-4.1",
1486
- browser_model_api_base="",
1487
- browser_model_vision=True,
1488
- browser_model_rl_requests=0,
1489
- browser_model_rl_input=0,
1490
- browser_model_rl_output=0,
1491
- browser_model_kwargs={"temperature": "0"},
1492
- browser_http_headers={},
1493
- memory_recall_enabled=True,
1494
- memory_recall_delayed=False,
1495
- memory_recall_interval=3,
1496
- memory_recall_history_len=10000,
1497
- memory_recall_memories_max_search=12,
1498
- memory_recall_solutions_max_search=8,
1499
- memory_recall_memories_max_result=5,
1500
- memory_recall_solutions_max_result=3,
1501
- memory_recall_similarity_threshold=0.7,
1502
- memory_recall_query_prep=True,
1503
- memory_recall_post_filter=True,
1504
- memory_memorize_enabled=True,
1505
- memory_memorize_consolidation=True,
1506
- memory_memorize_replace_threshold=0.9,
1491
+ chat_model_provider=get_default_value("chat_model_provider", "openrouter"),
1492
+ chat_model_name=get_default_value("chat_model_name", "openai/gpt-4.1"),
1493
+ chat_model_api_base=get_default_value("chat_model_api_base", ""),
1494
+ chat_model_kwargs=get_default_value("chat_model_kwargs", {"temperature": "0"}),
1495
+ chat_model_ctx_length=get_default_value("chat_model_ctx_length", 100000),
1496
+ chat_model_ctx_history=get_default_value("chat_model_ctx_history", 0.7),
1497
+ chat_model_vision=get_default_value("chat_model_vision", True),
1498
+ chat_model_rl_requests=get_default_value("chat_model_rl_requests", 0),
1499
+ chat_model_rl_input=get_default_value("chat_model_rl_input", 0),
1500
+ chat_model_rl_output=get_default_value("chat_model_rl_output", 0),
1501
+ util_model_provider=get_default_value("util_model_provider", "openrouter"),
1502
+ util_model_name=get_default_value("util_model_name", "openai/gpt-4.1-mini"),
1503
+ util_model_api_base=get_default_value("util_model_api_base", ""),
1504
+ util_model_ctx_length=get_default_value("util_model_ctx_length", 100000),
1505
+ util_model_ctx_input=get_default_value("util_model_ctx_input", 0.7),
1506
+ util_model_kwargs=get_default_value("util_model_kwargs", {"temperature": "0"}),
1507
+ util_model_rl_requests=get_default_value("util_model_rl_requests", 0),
1508
+ util_model_rl_input=get_default_value("util_model_rl_input", 0),
1509
+ util_model_rl_output=get_default_value("util_model_rl_output", 0),
1510
+ embed_model_provider=get_default_value("embed_model_provider", "huggingface"),
1511
+ embed_model_name=get_default_value("embed_model_name", "sentence-transformers/all-MiniLM-L6-v2"),
1512
+ embed_model_api_base=get_default_value("embed_model_api_base", ""),
1513
+ embed_model_kwargs=get_default_value("embed_model_kwargs", {}),
1514
+ embed_model_rl_requests=get_default_value("embed_model_rl_requests", 0),
1515
+ embed_model_rl_input=get_default_value("embed_model_rl_input", 0),
1516
+ browser_model_provider=get_default_value("browser_model_provider", "openrouter"),
1517
+ browser_model_name=get_default_value("browser_model_name", "openai/gpt-4.1"),
1518
+ browser_model_api_base=get_default_value("browser_model_api_base", ""),
1519
+ browser_model_vision=get_default_value("browser_model_vision", True),
1520
+ browser_model_rl_requests=get_default_value("browser_model_rl_requests", 0),
1521
+ browser_model_rl_input=get_default_value("browser_model_rl_input", 0),
1522
+ browser_model_rl_output=get_default_value("browser_model_rl_output", 0),
1523
+ browser_model_kwargs=get_default_value("browser_model_kwargs", {"temperature": "0"}),
1524
+ browser_http_headers=get_default_value("browser_http_headers", {}),
1525
+ memory_recall_enabled=get_default_value("memory_recall_enabled", True),
1526
+ memory_recall_delayed=get_default_value("memory_recall_delayed", False),
1527
+ memory_recall_interval=get_default_value("memory_recall_interval", 3),
1528
+ memory_recall_history_len=get_default_value("memory_recall_history_len", 10000),
1529
+ memory_recall_memories_max_search=get_default_value("memory_recall_memories_max_search", 12),
1530
+ memory_recall_solutions_max_search=get_default_value("memory_recall_solutions_max_search", 8),
1531
+ memory_recall_memories_max_result=get_default_value("memory_recall_memories_max_result", 5),
1532
+ memory_recall_solutions_max_result=get_default_value("memory_recall_solutions_max_result", 3),
1533
+ memory_recall_similarity_threshold=get_default_value("memory_recall_similarity_threshold", 0.7),
1534
+ memory_recall_query_prep=get_default_value("memory_recall_query_prep", True),
1535
+ memory_recall_post_filter=get_default_value("memory_recall_post_filter", True),
1536
+ memory_memorize_enabled=get_default_value("memory_memorize_enabled", True),
1537
+ memory_memorize_consolidation=get_default_value("memory_memorize_consolidation", True),
1538
+ memory_memorize_replace_threshold=get_default_value("memory_memorize_replace_threshold", 0.9),
1539
api_keys={},
1540
auth_login="",
1541
auth_password="",
1542
root_password="",
1511
- agent_profile="agent0",
1512
- agent_memory_subdir="default",
1513
- agent_knowledge_subdir="custom",
1514
- rfc_auto_docker=True,
1515
- rfc_url="localhost",
1543
+ agent_profile=get_default_value("agent_profile", "agent0"),
1544
+ agent_memory_subdir=get_default_value("agent_memory_subdir", "default"),
1545
+ agent_knowledge_subdir=get_default_value("agent_knowledge_subdir", "custom"),
1546
+ rfc_auto_docker=get_default_value("rfc_auto_docker", True),
1547
+ rfc_url=get_default_value("rfc_url", "localhost"),
1548
rfc_password="",
1517
- rfc_port_http=55080,
1518
- rfc_port_ssh=55022,
1519
- shell_interface="local" if runtime.is_dockerized() else "ssh",
1520
- stt_model_size="base",
1521
- stt_language="en",
1522
- stt_silence_threshold=0.3,
1523
- stt_silence_duration=1000,
1524
- stt_waiting_timeout=2000,
1525
- tts_kokoro=True,
1526
- mcp_servers='{\n "mcpServers": {}\n}',
1527
- mcp_client_init_timeout=10,
1528
- mcp_client_tool_timeout=120,
1529
- mcp_server_enabled=False,
1549
+ rfc_port_http=get_default_value("rfc_port_http", 55080),
1550
+ rfc_port_ssh=get_default_value("rfc_port_ssh", 55022),
1551
+ shell_interface=get_default_value("shell_interface", "local" if runtime.is_dockerized() else "ssh"),
1552
+ stt_model_size=get_default_value("stt_model_size", "base"),
1553
+ stt_language=get_default_value("stt_language", "en"),
1554
+ stt_silence_threshold=get_default_value("stt_silence_threshold", 0.3),
1555
+ stt_silence_duration=get_default_value("stt_silence_duration", 1000),
1556
+ stt_waiting_timeout=get_default_value("stt_waiting_timeout", 2000),
1557
+ tts_kokoro=get_default_value("tts_kokoro", True),
1558
+ mcp_servers=get_default_value("mcp_servers", '{\n "mcpServers": {}\n}'),
1559
+ mcp_client_init_timeout=get_default_value("mcp_client_init_timeout", 10),
1560
+ mcp_client_tool_timeout=get_default_value("mcp_client_tool_timeout", 120),
1561
+ mcp_server_enabled=get_default_value("mcp_server_enabled", False),
1562
mcp_server_token=create_auth_token(),
1531
- a2a_server_enabled=False,
1563
+ a2a_server_enabled=get_default_value("a2a_server_enabled", False),
1564
variables="",
1565
secrets="",
1534
- litellm_global_kwargs={},
1535
- update_check_enabled=True,
1566
+ litellm_global_kwargs=get_default_value("litellm_global_kwargs", {}),
1567
+ update_check_enabled=get_default_value("update_check_enabled", True),
1568
)
1569
1570