fix: OpenRouter header format, pipx install, code exec output truncation, and model config UI improvements
- Change X-OpenRouter-Categories from YAML list to comma-separated string - Add pipx to base Python installation - Truncate long lines in code execution output to 500 chars (250 from each end) before prompt detection - Reorder model config UI sections and simplify plugin config button handler - Remove border/padding from model summary grid and adjust mobile responsive styles
frdel committed
Mar 19, 2026 at 16:28 UTC
a7bfc7798bf1788ed74bb35b800778ea46b9c94d
4 files changed
+65
-57
conf/model_providers.yaml
+1
-3
@@ -124,9 +124,7 @@ chat:
124
extra_headers:
125
"HTTP-Referer": "https://agent-zero.ai/"
126
"X-Title": "Agent Zero"
127
- "X-OpenRouter-Categories":
128
- - personal-agent
129
- - cloud-agent
127
+ "X-OpenRouter-Categories": "personal-agent,cloud-agent"
128
sambanova:
129
name: Sambanova
130
litellm_provider: sambanova
docker/base/fs/ins/install_python.sh
+1
-1
@@ -55,7 +55,7 @@ pyenv install 3.12.4
55
source /opt/venv-a0/bin/activate
56
57
# upgrade pip and install static packages
58
-pip install --no-cache-dir --upgrade pip
58
+pip install --no-cache-dir --upgrade pip pipx
59
60
# Install some packages in specific variants
61
pip install --no-cache-dir \
plugins/_code_execution/tools/code_execution_tool.py
+3
-1
@@ -265,8 +265,10 @@ class CodeExecution(Tool):
265
)
266
last_lines.reverse()
267
for idx, line in enumerate(last_lines):
268
+ line = line.strip()
269
+ line = line if len(line) <= 500 else line[:250] + line[-250:]
270
for pat in prompt_patterns:
269
- if pat.search(line.strip()):
271
+ if pat.search(line):
272
PrintStyle.info(
273
"Detected shell prompt, returning output early."
274
)
plugins/_model_config/webui/models-summary.html
+60
-52
@@ -1,4 +1,5 @@
1
<html>
2
+
3
<head>
4
<title>Model Configuration</title>
5
</head>
@@ -9,79 +10,77 @@
10
</script>
11
12
<div x-data>
12
- <template x-if="$store.modelConfig">
13
- <div>
14
- <div class="section-title">Model Configuration</div>
15
- <div class="section-description">
16
- Model settings are managed through the Model Configuration plugin, supporting per-project and per-agent overrides.
17
- </div>
18
-
19
- <div style="display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px;">
20
- <button class="btn btn-field" @click="(async () => {
21
- const pluginMeta = { name: '_model_config', always_enabled: true, per_project_config: true, per_agent_config: true, has_config_screen: true };
22
- if ($store.pluginToggle?.open) await $store.pluginToggle.open(pluginMeta);
23
- await $store.pluginSettingsPrototype.open('_model_config', { perProjectConfig: true, perAgentConfig: true });
24
- openModal('components/plugins/plugin-settings.html');
25
- })()">
26
- Configure Models
27
- </button>
28
- <button class="btn btn-field" @click="openModal('/plugins/_model_config/webui/api-keys.html')">
29
- Manage API Keys
30
- </button>
31
- </div>
32
-
33
- <!-- Read-only model config summary -->
34
- <div x-data="{ loading: true, models: [] }"
35
- x-init="
13
+ <template x-if="$store.modelConfig">
14
+ <div>
15
+ <div class="section-title">Model Configuration</div>
16
+ <div class="section-description">
17
+ AI models can be configured globally, per project, per agent and using quick-switch presets as well.
18
+ </div>
19
+
20
+ <!-- Read-only model config summary -->
21
+ <div x-data="{ loading: true, models: [] }" x-init="
22
models = await $store.modelConfig.loadModelsSummary().catch(() => []);
23
loading = false;
38
- "
39
- class="model-summary">
40
- <div class="model-summary-header">
41
- <div class="field-title">Current Models</div>
42
- <div class="field-description">Active model configuration resolved from global, project, and agent profile scopes.</div>
43
- </div>
44
- <div x-show="loading" style="text-align:center; padding:12px;">
45
- <span class="material-symbols-outlined spinning" style="font-size:18px;">progress_activity</span>
46
- </div>
47
- <template x-if="!loading && models.length">
48
- <div class="model-summary-grid">
49
- <template x-for="m in models" :key="m.title">
50
- <div class="model-summary-row">
51
- <span class="material-symbols-outlined model-summary-icon" x-text="m.icon"></span>
52
- <span class="model-summary-label" x-text="m.title"></span>
53
- <span class="model-summary-value">
54
- <span x-text="m.provider" style="opacity:0.6;"></span>
55
- <span style="opacity:0.3; margin:0 4px;">/</span>
56
- <span x-text="m.name"></span>
57
- </span>
24
+ " class="model-summary">
25
+ <div class="model-summary-header">
26
+ <div class="field-title">Current Models</div>
27
+ <div class="field-description">Active model configuration resolved from global, project, and agent profile
28
+ scopes.</div>
29
+ </div>
30
+ <div x-show="loading" style="text-align:center; padding:12px;">
31
+ <span class="material-symbols-outlined spinning" style="font-size:18px;">progress_activity</span>
32
+ </div>
33
+ <template x-if="!loading && models.length">
34
+ <div class="model-summary-grid">
35
+ <template x-for="m in models" :key="m.title">
36
+ <div class="model-summary-row">
37
+ <span class="material-symbols-outlined model-summary-icon" x-text="m.icon"></span>
38
+ <span class="model-summary-label" x-text="m.title"></span>
39
+ <span class="model-summary-value">
40
+ <span x-text="m.provider" style="opacity:0.6;"></span>
41
+ <span style="opacity:0.3; margin:0 4px;">/</span>
42
+ <span x-text="m.name"></span>
43
+ </span>
44
+ </div>
45
+ </template>
46
</div>
47
</template>
48
</div>
61
- </template>
62
- </div>
63
- </div>
64
- </template>
49
+
50
+ <div style="display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px;">
51
+ <button class="btn btn-field" @click="$store.pluginListStore.openPluginConfig('_model_config')">
52
+ Configure Models
53
+ </button>
54
+ <button class="btn btn-field" @click="openModal('/plugins/_model_config/webui/api-keys.html')">
55
+ Manage API Keys
56
+ </button>
57
+ </div>
58
+
59
+ </div>
60
+ </template>
61
</div>
62
63
<style>
64
.model-summary {
65
margin-top: 14px;
66
}
67
+
68
.model-summary-header {
69
margin-bottom: 8px;
70
}
71
+
72
.model-summary-grid {
73
display: flex;
74
flex-direction: column;
75
background: var(--color-input);
78
- border: 1px solid var(--color-border);
79
- border-radius: 8px;
80
- padding: 0.75em 1em;
76
+ /* border: 1px solid var(--color-border);
77
+ border-radius: 8px; */
78
+ /* padding: 0.75em 1em; */
79
max-width: 100%;
80
overflow: hidden;
81
box-sizing: border-box;
82
}
83
+
84
.model-summary-row {
85
display: flex;
86
align-items: center;
@@ -90,20 +89,24 @@
89
font-size: 0.82rem;
90
min-width: 0;
91
}
92
+
93
.model-summary-row:not(:last-child) {
94
border-bottom: 1px solid var(--color-border);
95
}
96
+
97
.model-summary-icon {
98
font-size: 16px;
99
opacity: 0.45;
100
flex-shrink: 0;
101
}
102
+
103
.model-summary-label {
104
width: 80px;
105
flex-shrink: 0;
106
font-weight: 500;
107
opacity: 0.7;
108
}
109
+
110
.model-summary-value {
111
flex: 1;
112
min-width: 0;
@@ -111,18 +114,22 @@
114
text-overflow: ellipsis;
115
white-space: nowrap;
116
}
117
+
118
@media (max-width: 600px) {
119
.model-summary-grid {
120
padding: 0.5em 0.5em;
121
}
122
+
123
.model-summary-row {
124
flex-wrap: wrap;
125
padding: 8px 8px;
126
gap: 4px;
127
}
128
+
129
.model-summary-label {
130
width: auto;
131
}
132
+
133
.model-summary-value {
134
width: 100%;
135
flex-basis: 100%;
@@ -134,4 +141,5 @@
141
}
142
</style>
143
</body>
137
-</html>
144
+
145
+</html>
\ No newline at end of file