Settings polishing, logout button
frdel committed
Feb 5, 2026 at 22:02 UTC
181135f58a4850d6fbb07aa5d5841bb021f1e1e2
34 files changed
+256
-154
python/api/logout.py
new
+15
@@ -0,0 +1,15 @@
1
+from python.helpers.api import ApiHandler, Request, session
2
+
3
+
4
+class ApiLogout(ApiHandler):
5
+ @classmethod
6
+ def requires_auth(cls) -> bool:
7
+ return False
8
+
9
+ async def process(self, input: dict, request: Request) -> dict:
10
+ try:
11
+ session.clear()
12
+ except Exception:
13
+ session.pop("authentication", None)
14
+ session.pop("csrf_token", None)
15
+ return {"ok": True}
run_ui.py
+1
@@ -218,6 +218,7 @@ async def serve_index():
218
version_time=gitinfo["commit_time"],
219
runtime_id=runtime.get_runtime_id(),
220
runtime_is_development=("true" if runtime.is_development() else "false"),
221
+ logged_in=("true" if login.get_credentials_hash() else "false"),
222
)
223
return index
224
tests/test_settings_developer_sections.py
+1
-1
@@ -20,7 +20,7 @@ def test_websocket_harness_entrypoint_is_present_in_developer_settings_template(
20
content = dev_template_path.read_text(encoding="utf-8")
21
assert "websocket-tester.html" in content
22
assert "websocket-event-console.html" in content
23
- assert "!$store.settingsStore.additional?.is_dockerized" in content
23
+ assert "!$store.settings.additional?.is_dockerized" in content
24
25
26
def test_websocket_harness_template_is_gated_by_runtime():
webui/components/settings/a2a/a2a-connection.html
+2
-2
@@ -11,7 +11,7 @@
11
12
<!-- API Token Information -->
13
<div x-data>
14
- <template x-if="$store.settingsStore.settings">
14
+ <template x-if="$store.settings.settings">
15
<div style="background-color: var(--color-bg-secondary); border: 1px solid var(--color-border); border-radius: 6px; padding: 12px; margin: 16px 0;">
16
<h4 style="margin: 0 0 8px 0; color: var(--color-text-primary);">API Token Information</h4>
17
<p style="margin: 0 0 8px 0; color: var(--color-text-secondary); font-size: 14px;">
@@ -21,7 +21,7 @@
21
</p>
22
<div style="margin-top: 8px;">
23
<label style="display: block; margin-bottom: 4px; color: var(--color-text-secondary); font-size: 12px; font-weight: 600;">Token:</label>
24
- <input type="text" readonly x-model="$store.settingsStore.settings.mcp_server_token" style="width: 100%; padding: 6px 8px; background-color: var(--color-bg-primary); color: var(--color-text-primary); border: 1px solid var(--color-border); border-radius: 4px; font-family: monospace; font-size: 13px;" />
24
+ <input type="text" readonly x-model="$store.settings.settings.mcp_server_token" style="width: 100%; padding: 6px 8px; background-color: var(--color-bg-primary); color: var(--color-text-primary); border: 1px solid var(--color-border); border-radius: 4px; font-family: monospace; font-size: 13px;" />
25
</div>
26
</div>
27
</template>
webui/components/settings/a2a/a2a-server.html
+1
-1
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">A0 A2A Server</div>
webui/components/settings/agent/agent-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/settings/agent/agent.html
+7
-7
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Agent Config</div>
11
<div class="section-description">
@@ -20,9 +20,9 @@
20
</div>
21
</div>
22
<div class="field-control">
23
- <select x-model="$store.settingsStore.settings.agent_profile">
24
- <template x-for="option in $store.settingsStore.additional?.agent_subdirs" :key="option.value">
25
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.agent_profile" x-text="option.label"></option>
23
+ <select x-model="$store.settings.settings.agent_profile">
24
+ <template x-for="option in $store.settings.additional?.agent_subdirs" :key="option.value">
25
+ <option :value="option.value" :selected="option.value === $store.settings.settings.agent_profile" x-text="option.label"></option>
26
</template>
27
</select>
28
</div>
@@ -36,9 +36,9 @@
36
</div>
37
</div>
38
<div class="field-control">
39
- <select x-model="$store.settingsStore.settings.agent_knowledge_subdir">
40
- <template x-for="option in $store.settingsStore.additional?.knowledge_subdirs" :key="option.value">
41
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.agent_knowledge_subdir" x-text="option.label"></option>
39
+ <select x-model="$store.settings.settings.agent_knowledge_subdir">
40
+ <template x-for="option in $store.settings.additional?.knowledge_subdirs" :key="option.value">
41
+ <option :value="option.value" :selected="option.value === $store.settings.settings.agent_knowledge_subdir" x-text="option.label"></option>
42
</template>
43
</select>
44
</div>
webui/components/settings/agent/browser_model.html
+26
-12
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Web Browser Model</div>
11
<div class="section-description">
@@ -18,9 +18,9 @@
18
<div class="field-description">Select provider for web browser model used by Agent Zero</div>
19
</div>
20
<div class="field-control">
21
- <select x-model="$store.settingsStore.settings.browser_model_provider">
22
- <template x-for="option in $store.settingsStore.additional?.chat_providers" :key="option.value">
23
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.browser_model_provider" x-text="option.label"></option>
21
+ <select x-model="$store.settings.settings.browser_model_provider">
22
+ <template x-for="option in $store.settings.additional?.chat_providers" :key="option.value">
23
+ <option :value="option.value" :selected="option.value === $store.settings.settings.browser_model_provider" x-text="option.label"></option>
24
</template>
25
</select>
26
</div>
@@ -32,7 +32,21 @@
32
<div class="field-description">Exact name of model from selected provider</div>
33
</div>
34
<div class="field-control">
35
- <input type="text" x-model="$store.settingsStore.settings.browser_model_name" />
35
+ <input type="text" x-model="$store.settings.settings.browser_model_name" />
36
+ </div>
37
+ </div>
38
+
39
+ <div class="field">
40
+ <div class="field-label">
41
+ <div class="field-title">API key</div>
42
+ <div class="field-description">API key for the selected web browser model provider</div>
43
+ </div>
44
+ <div class="field-control">
45
+ <input
46
+ type="text"
47
+ x-model="$store.settings.settings.api_keys[$store.settings.settings.browser_model_provider]"
48
+ autocomplete="off"
49
+ />
50
</div>
51
</div>
52
@@ -44,7 +58,7 @@
58
</div>
59
</div>
60
<div class="field-control">
47
- <input type="text" x-model="$store.settingsStore.settings.browser_model_api_base" />
61
+ <input type="text" x-model="$store.settings.settings.browser_model_api_base" />
62
</div>
63
</div>
64
@@ -57,7 +71,7 @@
71
</div>
72
<div class="field-control">
73
<label class="toggle">
60
- <input type="checkbox" x-model="$store.settingsStore.settings.browser_model_vision" />
74
+ <input type="checkbox" x-model="$store.settings.settings.browser_model_vision" />
75
<span class="toggler"></span>
76
</label>
77
</div>
@@ -71,7 +85,7 @@
85
</div>
86
</div>
87
<div class="field-control">
74
- <input type="number" x-model.number="$store.settingsStore.settings.browser_model_rl_requests" />
88
+ <input type="number" x-model.number="$store.settings.settings.browser_model_rl_requests" />
89
</div>
90
</div>
91
@@ -83,7 +97,7 @@
97
</div>
98
</div>
99
<div class="field-control">
86
- <input type="number" x-model.number="$store.settingsStore.settings.browser_model_rl_input" />
100
+ <input type="number" x-model.number="$store.settings.settings.browser_model_rl_input" />
101
</div>
102
</div>
103
@@ -95,7 +109,7 @@
109
</div>
110
</div>
111
<div class="field-control">
98
- <input type="number" x-model.number="$store.settingsStore.settings.browser_model_rl_output" />
112
+ <input type="number" x-model.number="$store.settings.settings.browser_model_rl_output" />
113
</div>
114
</div>
115
@@ -107,7 +121,7 @@
121
</div>
122
</div>
123
<div class="field-control">
110
- <textarea x-model="$store.settingsStore.settings.browser_model_kwargs"></textarea>
124
+ <textarea x-model="$store.settings.settings.browser_model_kwargs"></textarea>
125
</div>
126
</div>
127
@@ -119,7 +133,7 @@
133
</div>
134
</div>
135
<div class="field-control">
122
- <textarea x-model="$store.settingsStore.settings.browser_http_headers"></textarea>
136
+ <textarea x-model="$store.settings.settings.browser_http_headers"></textarea>
137
</div>
138
</div>
139
</div>
webui/components/settings/agent/chat_model.html
+28
-14
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Chat Model</div>
11
<div class="section-description">
@@ -18,9 +18,9 @@
18
<div class="field-description">Select provider for main chat model used by Agent Zero</div>
19
</div>
20
<div class="field-control">
21
- <select x-model="$store.settingsStore.settings.chat_model_provider">
22
- <template x-for="option in $store.settingsStore.additional?.chat_providers" :key="option.value">
23
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.chat_model_provider" x-text="option.label"></option>
21
+ <select x-model="$store.settings.settings.chat_model_provider">
22
+ <template x-for="option in $store.settings.additional?.chat_providers" :key="option.value">
23
+ <option :value="option.value" :selected="option.value === $store.settings.settings.chat_model_provider" x-text="option.label"></option>
24
</template>
25
</select>
26
</div>
@@ -32,7 +32,21 @@
32
<div class="field-description">Exact name of model from selected provider</div>
33
</div>
34
<div class="field-control">
35
- <input type="text" x-model="$store.settingsStore.settings.chat_model_name" />
35
+ <input type="text" x-model="$store.settings.settings.chat_model_name" />
36
+ </div>
37
+ </div>
38
+
39
+ <div class="field">
40
+ <div class="field-label">
41
+ <div class="field-title">API key</div>
42
+ <div class="field-description">API key for the selected chat model provider</div>
43
+ </div>
44
+ <div class="field-control">
45
+ <input
46
+ type="text"
47
+ x-model="$store.settings.settings.api_keys[$store.settings.settings.chat_model_provider]"
48
+ autocomplete="off"
49
+ />
50
</div>
51
</div>
52
@@ -44,7 +58,7 @@
58
</div>
59
</div>
60
<div class="field-control">
47
- <input type="text" x-model="$store.settingsStore.settings.chat_model_api_base" />
61
+ <input type="text" x-model="$store.settings.settings.chat_model_api_base" />
62
</div>
63
</div>
64
@@ -56,7 +70,7 @@
70
</div>
71
</div>
72
<div class="field-control">
59
- <input type="number" x-model.number="$store.settingsStore.settings.chat_model_ctx_length" />
73
+ <input type="number" x-model.number="$store.settings.settings.chat_model_ctx_length" />
74
</div>
75
</div>
76
@@ -73,9 +87,9 @@
87
min="0.01"
88
max="1"
89
step="0.01"
76
- x-model.number="$store.settingsStore.settings.chat_model_ctx_history"
90
+ x-model.number="$store.settings.settings.chat_model_ctx_history"
91
/>
78
- <span class="range-value" x-text="$store.settingsStore.settings.chat_model_ctx_history"></span>
92
+ <span class="range-value" x-text="$store.settings.settings.chat_model_ctx_history"></span>
93
</div>
94
</div>
95
@@ -88,7 +102,7 @@
102
</div>
103
<div class="field-control">
104
<label class="toggle">
91
- <input type="checkbox" x-model="$store.settingsStore.settings.chat_model_vision" />
105
+ <input type="checkbox" x-model="$store.settings.settings.chat_model_vision" />
106
<span class="toggler"></span>
107
</label>
108
</div>
@@ -102,7 +116,7 @@
116
</div>
117
</div>
118
<div class="field-control">
105
- <input type="number" x-model.number="$store.settingsStore.settings.chat_model_rl_requests" />
119
+ <input type="number" x-model.number="$store.settings.settings.chat_model_rl_requests" />
120
</div>
121
</div>
122
@@ -114,7 +128,7 @@
128
</div>
129
</div>
130
<div class="field-control">
117
- <input type="number" x-model.number="$store.settingsStore.settings.chat_model_rl_input" />
131
+ <input type="number" x-model.number="$store.settings.settings.chat_model_rl_input" />
132
</div>
133
</div>
134
@@ -126,7 +140,7 @@
140
</div>
141
</div>
142
<div class="field-control">
129
- <input type="number" x-model.number="$store.settingsStore.settings.chat_model_rl_output" />
143
+ <input type="number" x-model.number="$store.settings.settings.chat_model_rl_output" />
144
</div>
145
</div>
146
@@ -138,7 +152,7 @@
152
</div>
153
</div>
154
<div class="field-control">
141
- <textarea x-model="$store.settingsStore.settings.chat_model_kwargs"></textarea>
155
+ <textarea x-model="$store.settings.settings.chat_model_kwargs"></textarea>
156
</div>
157
</div>
158
</div>
webui/components/settings/agent/embed_model.html
+23
-9
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Embedding Model</div>
11
<div class="section-description">
@@ -18,9 +18,9 @@
18
<div class="field-description">Select provider for embedding model used by the framework</div>
19
</div>
20
<div class="field-control">
21
- <select x-model="$store.settingsStore.settings.embed_model_provider">
22
- <template x-for="option in $store.settingsStore.additional?.embedding_providers" :key="option.value">
23
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.embed_model_provider" x-text="option.label"></option>
21
+ <select x-model="$store.settings.settings.embed_model_provider">
22
+ <template x-for="option in $store.settings.additional?.embedding_providers" :key="option.value">
23
+ <option :value="option.value" :selected="option.value === $store.settings.settings.embed_model_provider" x-text="option.label"></option>
24
</template>
25
</select>
26
</div>
@@ -32,7 +32,21 @@
32
<div class="field-description">Exact name of model from selected provider</div>
33
</div>
34
<div class="field-control">
35
- <input type="text" x-model="$store.settingsStore.settings.embed_model_name" />
35
+ <input type="text" x-model="$store.settings.settings.embed_model_name" />
36
+ </div>
37
+ </div>
38
+
39
+ <div class="field">
40
+ <div class="field-label">
41
+ <div class="field-title">API key</div>
42
+ <div class="field-description">API key for the selected embedding model provider</div>
43
+ </div>
44
+ <div class="field-control">
45
+ <input
46
+ type="text"
47
+ x-model="$store.settings.settings.api_keys[$store.settings.settings.embed_model_provider]"
48
+ autocomplete="off"
49
+ />
50
</div>
51
</div>
52
@@ -44,7 +58,7 @@
58
</div>
59
</div>
60
<div class="field-control">
47
- <input type="text" x-model="$store.settingsStore.settings.embed_model_api_base" />
61
+ <input type="text" x-model="$store.settings.settings.embed_model_api_base" />
62
</div>
63
</div>
64
@@ -56,7 +70,7 @@
70
</div>
71
</div>
72
<div class="field-control">
59
- <input type="number" x-model.number="$store.settingsStore.settings.embed_model_rl_requests" />
73
+ <input type="number" x-model.number="$store.settings.settings.embed_model_rl_requests" />
74
</div>
75
</div>
76
@@ -68,7 +82,7 @@
82
</div>
83
</div>
84
<div class="field-control">
71
- <input type="number" x-model.number="$store.settingsStore.settings.embed_model_rl_input" />
85
+ <input type="number" x-model.number="$store.settings.settings.embed_model_rl_input" />
86
</div>
87
</div>
88
@@ -80,7 +94,7 @@
94
</div>
95
</div>
96
<div class="field-control">
83
- <textarea x-model="$store.settingsStore.settings.embed_model_kwargs"></textarea>
97
+ <textarea x-model="$store.settings.settings.embed_model_kwargs"></textarea>
98
</div>
99
</div>
100
</div>
webui/components/settings/agent/memory.html
+19
-19
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Memory</div>
11
<div class="section-description">
@@ -20,7 +20,7 @@
20
</div>
21
</div>
22
<div class="field-control">
23
- <input type="text" x-model="$store.settingsStore.settings.agent_memory_subdir" />
23
+ <input type="text" x-model="$store.settings.settings.agent_memory_subdir" />
24
</div>
25
</div>
26
@@ -48,7 +48,7 @@
48
</div>
49
<div class="field-control">
50
<label class="toggle">
51
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_recall_enabled" />
51
+ <input type="checkbox" x-model="$store.settings.settings.memory_recall_enabled" />
52
<span class="toggler"></span>
53
</label>
54
</div>
@@ -63,7 +63,7 @@
63
</div>
64
<div class="field-control">
65
<label class="toggle">
66
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_recall_delayed" />
66
+ <input type="checkbox" x-model="$store.settings.settings.memory_recall_delayed" />
67
<span class="toggler"></span>
68
</label>
69
</div>
@@ -78,7 +78,7 @@
78
</div>
79
<div class="field-control">
80
<label class="toggle">
81
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_recall_query_prep" />
81
+ <input type="checkbox" x-model="$store.settings.settings.memory_recall_query_prep" />
82
<span class="toggler"></span>
83
</label>
84
</div>
@@ -93,7 +93,7 @@
93
</div>
94
<div class="field-control">
95
<label class="toggle">
96
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_recall_post_filter" />
96
+ <input type="checkbox" x-model="$store.settings.settings.memory_recall_post_filter" />
97
<span class="toggler"></span>
98
</label>
99
</div>
@@ -107,8 +107,8 @@
107
</div>
108
</div>
109
<div class="field-control">
110
- <input type="range" min="1" max="10" step="1" x-model.number="$store.settingsStore.settings.memory_recall_interval" />
111
- <span class="range-value" x-text="$store.settingsStore.settings.memory_recall_interval"></span>
110
+ <input type="range" min="1" max="10" step="1" x-model.number="$store.settings.settings.memory_recall_interval" />
111
+ <span class="range-value" x-text="$store.settings.settings.memory_recall_interval"></span>
112
</div>
113
</div>
114
@@ -120,7 +120,7 @@
120
</div>
121
</div>
122
<div class="field-control">
123
- <input type="number" x-model.number="$store.settingsStore.settings.memory_recall_history_len" />
123
+ <input type="number" x-model.number="$store.settings.settings.memory_recall_history_len" />
124
</div>
125
</div>
126
@@ -132,8 +132,8 @@
132
</div>
133
</div>
134
<div class="field-control">
135
- <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settingsStore.settings.memory_recall_similarity_threshold" />
136
- <span class="range-value" x-text="$store.settingsStore.settings.memory_recall_similarity_threshold"></span>
135
+ <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settings.settings.memory_recall_similarity_threshold" />
136
+ <span class="range-value" x-text="$store.settings.settings.memory_recall_similarity_threshold"></span>
137
</div>
138
</div>
139
@@ -145,7 +145,7 @@
145
</div>
146
</div>
147
<div class="field-control">
148
- <input type="number" x-model.number="$store.settingsStore.settings.memory_recall_memories_max_search" />
148
+ <input type="number" x-model.number="$store.settings.settings.memory_recall_memories_max_search" />
149
</div>
150
</div>
151
@@ -157,7 +157,7 @@
157
</div>
158
</div>
159
<div class="field-control">
160
- <input type="number" x-model.number="$store.settingsStore.settings.memory_recall_memories_max_result" />
160
+ <input type="number" x-model.number="$store.settings.settings.memory_recall_memories_max_result" />
161
</div>
162
</div>
163
@@ -169,7 +169,7 @@
169
</div>
170
</div>
171
<div class="field-control">
172
- <input type="number" x-model.number="$store.settingsStore.settings.memory_recall_solutions_max_search" />
172
+ <input type="number" x-model.number="$store.settings.settings.memory_recall_solutions_max_search" />
173
</div>
174
</div>
175
@@ -181,7 +181,7 @@
181
</div>
182
</div>
183
<div class="field-control">
184
- <input type="number" x-model.number="$store.settingsStore.settings.memory_recall_solutions_max_result" />
184
+ <input type="number" x-model.number="$store.settings.settings.memory_recall_solutions_max_result" />
185
</div>
186
</div>
187
@@ -194,7 +194,7 @@
194
</div>
195
<div class="field-control">
196
<label class="toggle">
197
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_memorize_enabled" />
197
+ <input type="checkbox" x-model="$store.settings.settings.memory_memorize_enabled" />
198
<span class="toggler"></span>
199
</label>
200
</div>
@@ -209,7 +209,7 @@
209
</div>
210
<div class="field-control">
211
<label class="toggle">
212
- <input type="checkbox" x-model="$store.settingsStore.settings.memory_memorize_consolidation" />
212
+ <input type="checkbox" x-model="$store.settings.settings.memory_memorize_consolidation" />
213
<span class="toggler"></span>
214
</label>
215
</div>
@@ -223,8 +223,8 @@
223
</div>
224
</div>
225
<div class="field-control">
226
- <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settingsStore.settings.memory_memorize_replace_threshold" />
227
- <span class="range-value" x-text="$store.settingsStore.settings.memory_memorize_replace_threshold"></span>
226
+ <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settings.settings.memory_memorize_replace_threshold" />
227
+ <span class="range-value" x-text="$store.settings.settings.memory_memorize_replace_threshold"></span>
228
</div>
229
</div>
230
</div>
webui/components/settings/agent/speech.html
+10
-10
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Speech</div>
11
<div class="section-description">
@@ -28,9 +28,9 @@
28
<div class="field-description">Select the speech-to-text model size</div>
29
</div>
30
<div class="field-control">
31
- <select x-model="$store.settingsStore.settings.stt_model_size">
32
- <template x-for="option in $store.settingsStore.additional?.stt_models" :key="option.value">
33
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.stt_model_size" x-text="option.label"></option>
31
+ <select x-model="$store.settings.settings.stt_model_size">
32
+ <template x-for="option in $store.settings.additional?.stt_models" :key="option.value">
33
+ <option :value="option.value" :selected="option.value === $store.settings.settings.stt_model_size" x-text="option.label"></option>
34
</template>
35
</select>
36
</div>
@@ -42,7 +42,7 @@
42
<div class="field-description">Language code (e.g. en, fr, it)</div>
43
</div>
44
<div class="field-control">
45
- <input type="text" x-model="$store.settingsStore.settings.stt_language" />
45
+ <input type="text" x-model="$store.settings.settings.stt_language" />
46
</div>
47
</div>
48
@@ -52,8 +52,8 @@
52
<div class="field-description">Silence detection threshold. Lower values are more sensitive to noise.</div>
53
</div>
54
<div class="field-control">
55
- <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settingsStore.settings.stt_silence_threshold" />
56
- <span class="range-value" x-text="$store.settingsStore.settings.stt_silence_threshold"></span>
55
+ <input type="range" min="0" max="1" step="0.01" x-model.number="$store.settings.settings.stt_silence_threshold" />
56
+ <span class="range-value" x-text="$store.settings.settings.stt_silence_threshold"></span>
57
</div>
58
</div>
59
@@ -63,7 +63,7 @@
63
<div class="field-description">Duration of silence before the system considers speaking to have ended.</div>
64
</div>
65
<div class="field-control">
66
- <input type="number" x-model.number="$store.settingsStore.settings.stt_silence_duration" />
66
+ <input type="number" x-model.number="$store.settings.settings.stt_silence_duration" />
67
</div>
68
</div>
69
@@ -73,7 +73,7 @@
73
<div class="field-description">Duration of silence before the system closes the microphone.</div>
74
</div>
75
<div class="field-control">
76
- <input type="number" x-model.number="$store.settingsStore.settings.stt_waiting_timeout" />
76
+ <input type="number" x-model.number="$store.settings.settings.stt_waiting_timeout" />
77
</div>
78
</div>
79
@@ -86,7 +86,7 @@
86
</div>
87
<div class="field-control">
88
<label class="toggle">
89
- <input type="checkbox" x-model="$store.settingsStore.settings.tts_kokoro" />
89
+ <input type="checkbox" x-model="$store.settings.settings.tts_kokoro" />
90
<span class="toggler"></span>
91
</label>
92
</div>
webui/components/settings/agent/util_model.html
+24
-10
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Utility model</div>
11
<div class="section-description">
@@ -18,9 +18,9 @@
18
<div class="field-description">Select provider for utility model used by the framework</div>
19
</div>
20
<div class="field-control">
21
- <select x-model="$store.settingsStore.settings.util_model_provider">
22
- <template x-for="option in $store.settingsStore.additional?.chat_providers" :key="option.value">
23
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.util_model_provider" x-text="option.label"></option>
21
+ <select x-model="$store.settings.settings.util_model_provider">
22
+ <template x-for="option in $store.settings.additional?.chat_providers" :key="option.value">
23
+ <option :value="option.value" :selected="option.value === $store.settings.settings.util_model_provider" x-text="option.label"></option>
24
</template>
25
</select>
26
</div>
@@ -32,7 +32,21 @@
32
<div class="field-description">Exact name of model from selected provider</div>
33
</div>
34
<div class="field-control">
35
- <input type="text" x-model="$store.settingsStore.settings.util_model_name" />
35
+ <input type="text" x-model="$store.settings.settings.util_model_name" />
36
+ </div>
37
+ </div>
38
+
39
+ <div class="field">
40
+ <div class="field-label">
41
+ <div class="field-title">API key</div>
42
+ <div class="field-description">API key for the selected utility model provider</div>
43
+ </div>
44
+ <div class="field-control">
45
+ <input
46
+ type="text"
47
+ x-model="$store.settings.settings.api_keys[$store.settings.settings.util_model_provider]"
48
+ autocomplete="off"
49
+ />
50
</div>
51
</div>
52
@@ -44,7 +58,7 @@
58
</div>
59
</div>
60
<div class="field-control">
47
- <input type="text" x-model="$store.settingsStore.settings.util_model_api_base" />
61
+ <input type="text" x-model="$store.settings.settings.util_model_api_base" />
62
</div>
63
</div>
64
@@ -56,7 +70,7 @@
70
</div>
71
</div>
72
<div class="field-control">
59
- <input type="number" x-model.number="$store.settingsStore.settings.util_model_rl_requests" />
73
+ <input type="number" x-model.number="$store.settings.settings.util_model_rl_requests" />
74
</div>
75
</div>
76
@@ -68,7 +82,7 @@
82
</div>
83
</div>
84
<div class="field-control">
71
- <input type="number" x-model.number="$store.settingsStore.settings.util_model_rl_input" />
85
+ <input type="number" x-model.number="$store.settings.settings.util_model_rl_input" />
86
</div>
87
</div>
88
@@ -80,7 +94,7 @@
94
</div>
95
</div>
96
<div class="field-control">
83
- <input type="number" x-model.number="$store.settingsStore.settings.util_model_rl_output" />
97
+ <input type="number" x-model.number="$store.settings.settings.util_model_rl_output" />
98
</div>
99
</div>
100
@@ -92,7 +106,7 @@
106
</div>
107
</div>
108
<div class="field-control">
95
- <textarea x-model="$store.settingsStore.settings.util_model_kwargs"></textarea>
109
+ <textarea x-model="$store.settings.settings.util_model_kwargs"></textarea>
110
</div>
111
</div>
112
</div>
webui/components/settings/backup/backup-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/settings/backup/backup_restore.html
+2
-2
@@ -21,7 +21,7 @@
21
<div class="field-control">
22
<button
23
class="btn btn-field"
24
- @click="$store.settingsStore.handleFieldButton({ id: 'backup_create' })"
24
+ @click="$store.settings.handleFieldButton({ id: 'backup_create' })"
25
>
26
Create Backup
27
</button>
@@ -38,7 +38,7 @@
38
<div class="field-control">
39
<button
40
class="btn btn-field"
41
- @click="$store.settingsStore.handleFieldButton({ id: 'backup_restore' })"
41
+ @click="$store.settings.handleFieldButton({ id: 'backup_restore' })"
42
>
43
Restore Backup
44
</button>
webui/components/settings/developer/dev.html
+16
-16
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">Development</div>
11
<div class="section-description">
@@ -20,15 +20,15 @@
20
</div>
21
</div>
22
<div class="field-control">
23
- <select x-model="$store.settingsStore.settings.shell_interface">
24
- <template x-for="option in $store.settingsStore.additional?.shell_interfaces" :key="option.value">
25
- <option :value="option.value" :selected="option.value === $store.settingsStore.settings.shell_interface" x-text="option.label"></option>
23
+ <select x-model="$store.settings.settings.shell_interface">
24
+ <template x-for="option in $store.settings.additional?.shell_interfaces" :key="option.value">
25
+ <option :value="option.value" :selected="option.value === $store.settings.settings.shell_interface" x-text="option.label"></option>
26
</template>
27
</select>
28
</div>
29
</div>
30
31
- <template x-if="!$store.settingsStore.additional?.is_dockerized">
31
+ <template x-if="!$store.settings.additional?.is_dockerized">
32
<div>
33
<div class="field">
34
<div class="field-label">
@@ -38,7 +38,7 @@
38
</div>
39
</div>
40
<div class="field-control">
41
- <input type="text" x-model="$store.settingsStore.settings.rfc_url" />
41
+ <input type="text" x-model="$store.settings.settings.rfc_url" />
42
</div>
43
</div>
44
</div>
@@ -52,11 +52,11 @@
52
</div>
53
</div>
54
<div class="field-control">
55
- <input type="password" autocomplete="off" x-model="$store.settingsStore.settings.rfc_password" />
55
+ <input type="password" autocomplete="off" x-model="$store.settings.settings.rfc_password" />
56
</div>
57
</div>
58
59
- <template x-if="!$store.settingsStore.additional?.is_dockerized">
59
+ <template x-if="!$store.settings.additional?.is_dockerized">
60
<div>
61
<div class="field">
62
<div class="field-label">
@@ -64,7 +64,7 @@
64
<div class="field-description">HTTP port for dockerized instance of A0.</div>
65
</div>
66
<div class="field-control">
67
- <input type="number" x-model.number="$store.settingsStore.settings.rfc_port_http" />
67
+ <input type="number" x-model.number="$store.settings.settings.rfc_port_http" />
68
</div>
69
</div>
70
@@ -74,7 +74,7 @@
74
<div class="field-description">SSH port for dockerized instance of A0.</div>
75
</div>
76
<div class="field-control">
77
- <input type="number" x-model.number="$store.settingsStore.settings.rfc_port_ssh" />
77
+ <input type="number" x-model.number="$store.settings.settings.rfc_port_ssh" />
78
</div>
79
</div>
80
</div>
@@ -89,7 +89,7 @@
89
</div>
90
<div class="field-control">
91
<label class="toggle">
92
- <input type="checkbox" x-model="$store.settingsStore.settings.websocket_server_restart_enabled" />
92
+ <input type="checkbox" x-model="$store.settings.settings.websocket_server_restart_enabled" />
93
<span class="toggler"></span>
94
</label>
95
</div>
@@ -102,9 +102,9 @@
102
Temporarily enable uvicorn access logs for debugging WebSocket transport issues (default off).
103
</div>
104
<template
105
- x-if="$store.settingsStore.additional?.runtime_settings &&
106
- $store.settingsStore.settings?.uvicorn_access_logs_enabled !==
107
- $store.settingsStore.additional.runtime_settings.uvicorn_access_logs_enabled"
105
+ x-if="$store.settings.additional?.runtime_settings &&
106
+ $store.settings.settings?.uvicorn_access_logs_enabled !==
107
+ $store.settings.additional.runtime_settings.uvicorn_access_logs_enabled"
108
>
109
<div class="field-description">
110
Applies after backend restart.
@@ -113,13 +113,13 @@
113
</div>
114
<div class="field-control">
115
<label class="toggle">
116
- <input type="checkbox" x-model="$store.settingsStore.settings.uvicorn_access_logs_enabled" />
116
+ <input type="checkbox" x-model="$store.settings.settings.uvicorn_access_logs_enabled" />
117
<span class="toggler"></span>
118
</label>
119
</div>
120
</div>
121
122
- <template x-if="!$store.settingsStore.additional?.is_dockerized">
122
+ <template x-if="!$store.settings.additional?.is_dockerized">
123
<div>
124
<div class="section-title">Testing</div>
125
<div class="section-description">
webui/components/settings/developer/developer-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/settings/external/api_keys.html
+3
-3
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore.settings">
8
+ <template x-if="$store.settings.settings">
9
<div>
10
<div class="section-title">API Keys</div>
11
<div class="section-description">
@@ -13,7 +13,7 @@
13
For more information about Agent Zero Venice provider, see <a href="http://agent-zero.ai/?community/api-dashboard/about" target="_blank">Agent Zero Venice</a>.
14
</div>
15
16
- <template x-for="provider in $store.settingsStore.apiKeyProviders" :key="provider.value">
16
+ <template x-for="provider in $store.settings.apiKeyProviders" :key="provider.value">
17
<div class="field">
18
<div class="field-label">
19
<div class="field-title" x-text="provider.label"></div>
@@ -21,7 +21,7 @@
21
<div class="field-control">
22
<input
23
type="text"
24
- x-model="$store.settingsStore.settings.api_keys[provider.value]"
24
+ x-model="$store.settings.settings.api_keys[provider.value]"
25
autocomplete="off"
26
/>
27
</div>
webui/components/settings/external/auth.html
+2
-2
@@ -6,8 +6,8 @@
6
<body>
7
<div
8
x-data="{
9
- get settings() { return $store.settingsStore.settings },
10
- get additional() { return $store.settingsStore.additional || {} }
9
+ get settings() { return $store.settings.settings },
10
+ get additional() { return $store.settings.additional || {} }
11
}"
12
>
13
<template x-if="settings">
webui/components/settings/external/external-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/settings/external/external_api.html
+1
-1
@@ -21,7 +21,7 @@
21
<div class="field-control">
22
<button
23
class="btn btn-field"
24
- @click="$store.settingsStore.handleFieldButton({ id: 'external_api_examples' })"
24
+ @click="$store.settings.handleFieldButton({ id: 'external_api_examples' })"
25
>
26
Show API Examples
27
</button>
webui/components/settings/external/litellm.html
+1
-1
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">LiteLLM Global Settings</div>
webui/components/settings/external/secrets.html
+1
-1
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">Secrets Management</div>
webui/components/settings/external/update_checker.html
+1
-1
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">Update Checker</div>
webui/components/settings/mcp/mcp-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/settings/mcp/mcp_client.html
+2
-2
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">External MCP Servers</div>
@@ -20,7 +20,7 @@
20
<div class="field-control">
21
<button
22
class="btn btn-field"
23
- @click="$store.settingsStore.handleFieldButton({ id: 'mcp_servers_config' })"
23
+ @click="$store.settings.handleFieldButton({ id: 'mcp_servers_config' })"
24
>
25
Open
26
</button>
webui/components/settings/mcp/mcp_server.html
+1
-1
@@ -4,7 +4,7 @@
4
</head>
5
6
<body>
7
- <div x-data="{ get settings() { return $store.settingsStore.settings } }">
7
+ <div x-data="{ get settings() { return $store.settings.settings } }">
8
<template x-if="settings">
9
<div>
10
<div class="section-title">A0 MCP Server</div>
webui/components/settings/mcp/server/example.html
+2
-2
@@ -12,7 +12,7 @@
12
13
<!-- API Token Information -->
14
<div x-data>
15
- <template x-if="$store.settingsStore.settings">
15
+ <template x-if="$store.settings.settings">
16
<div style="background-color: var(--color-bg-secondary); border: 1px solid var(--color-border); border-radius: 6px; padding: 12px; margin: 16px 0;">
17
<h4 style="margin: 0 0 8px 0; color: var(--color-text-primary);">API Token Information</h4>
18
<p style="margin: 0 0 8px 0; color: var(--color-text-secondary); font-size: 14px;">
@@ -21,7 +21,7 @@
21
</p>
22
<div style="margin-top: 8px;">
23
<label style="display: block; margin-bottom: 4px; color: var(--color-text-secondary); font-size: 12px; font-weight: 600;">Token:</label>
24
- <input type="text" readonly x-model="$store.settingsStore.settings.mcp_server_token" style="width: 100%; padding: 6px 8px; background-color: var(--color-bg-primary); color: var(--color-text-primary); border: 1px solid var(--color-border); border-radius: 4px; font-family: monospace; font-size: 13px;" />
24
+ <input type="text" readonly x-model="$store.settings.settings.mcp_server_token" style="width: 100%; padding: 6px 8px; background-color: var(--color-bg-primary); color: var(--color-text-primary); border: 1px solid var(--color-border); border-radius: 4px; font-family: monospace; font-size: 13px;" />
25
</div>
26
</div>
27
</template>
webui/components/settings/settings-store.js
+1
-1
@@ -168,7 +168,7 @@ const model = {
168
},
169
};
170
171
-const store = createStore("settingsStore", model);
171
+const store = createStore("settings", model);
172
173
export { store };
174
webui/components/settings/settings.html
+29
-29
@@ -9,86 +9,86 @@
9
</script>
10
11
<div x-data>
12
- <template x-if="$store.settingsStore">
13
- <div x-init="$store.settingsStore.onOpen()" x-destroy="$store.settingsStore.cleanup()">
12
+ <template x-if="$store.settings">
13
+ <div x-init="$store.settings.onOpen()" x-destroy="$store.settings.cleanup()">
14
15
<!-- Loading state -->
16
- <div x-show="$store.settingsStore.isLoading && !$store.settingsStore.settings" class="settings-loading">
16
+ <div x-show="$store.settings.isLoading && !$store.settings.settings" class="settings-loading">
17
<span class="material-symbols-outlined spinning">progress_activity</span>
18
<span>Loading settings...</span>
19
</div>
20
21
<!-- Error state -->
22
- <div x-show="$store.settingsStore.error && !$store.settingsStore.settings" class="settings-error">
22
+ <div x-show="$store.settings.error && !$store.settings.settings" class="settings-error">
23
<span class="material-symbols-outlined">error</span>
24
- <span x-text="$store.settingsStore.error"></span>
25
- <button class="btn btn-retry" @click="$store.settingsStore.onOpen()">Retry</button>
24
+ <span x-text="$store.settings.error"></span>
25
+ <button class="btn btn-retry" @click="$store.settings.onOpen()">Retry</button>
26
</div>
27
28
<!-- Settings content -->
29
- <div x-show="$store.settingsStore.settings" class="settings-content">
29
+ <div x-show="$store.settings.settings" class="settings-content">
30
<!-- Tab Navigation -->
31
<div class="settings-tabs-container">
32
<div class="settings-tabs no-scrollbar">
33
<div class="settings-tab"
34
- :class="{'active': $store.settingsStore.activeTab === 'agent'}"
35
- @click="$store.settingsStore.switchTab('agent')"
34
+ :class="{'active': $store.settings.activeTab === 'agent'}"
35
+ @click="$store.settings.switchTab('agent')"
36
title="Agent Settings">Agent Settings</div>
37
<div class="settings-tab"
38
- :class="{'active': $store.settingsStore.activeTab === 'skills'}"
39
- @click="$store.settingsStore.switchTab('skills')"
38
+ :class="{'active': $store.settings.activeTab === 'skills'}"
39
+ @click="$store.settings.switchTab('skills')"
40
title="Skills">Skills</div>
41
<div class="settings-tab"
42
- :class="{'active': $store.settingsStore.activeTab === 'external'}"
43
- @click="$store.settingsStore.switchTab('external')"
42
+ :class="{'active': $store.settings.activeTab === 'external'}"
43
+ @click="$store.settings.switchTab('external')"
44
title="External Services">External Services</div>
45
<div class="settings-tab"
46
- :class="{'active': $store.settingsStore.activeTab === 'mcp'}"
47
- @click="$store.settingsStore.switchTab('mcp')"
46
+ :class="{'active': $store.settings.activeTab === 'mcp'}"
47
+ @click="$store.settings.switchTab('mcp')"
48
title="MCP">MCP/A2A</div>
49
<div class="settings-tab"
50
- :class="{'active': $store.settingsStore.activeTab === 'developer'}"
51
- @click="$store.settingsStore.switchTab('developer')"
50
+ :class="{'active': $store.settings.activeTab === 'developer'}"
51
+ @click="$store.settings.switchTab('developer')"
52
title="Developer">Developer</div>
53
<div class="settings-tab"
54
- :class="{'active': $store.settingsStore.activeTab === 'backup'}"
55
- @click="$store.settingsStore.switchTab('backup')"
54
+ :class="{'active': $store.settings.activeTab === 'backup'}"
55
+ @click="$store.settings.switchTab('backup')"
56
title="Backup & Restore">Backup & Restore</div>
57
</div>
58
</div>
59
60
<!-- Settings sections for agent, external, developer, mcp, backup tabs -->
61
<div id="settings-sections">
62
- <div x-show="$store.settingsStore.activeTab === 'agent'">
62
+ <div x-show="$store.settings.activeTab === 'agent'">
63
<x-component path="settings/agent/agent-settings.html"></x-component>
64
</div>
65
- <div x-show="$store.settingsStore.activeTab === 'external'">
65
+ <div x-show="$store.settings.activeTab === 'external'">
66
<x-component path="settings/external/external-settings.html"></x-component>
67
</div>
68
- <div x-show="$store.settingsStore.activeTab === 'mcp'">
68
+ <div x-show="$store.settings.activeTab === 'mcp'">
69
<x-component path="settings/mcp/mcp-settings.html"></x-component>
70
</div>
71
- <div x-show="$store.settingsStore.activeTab === 'developer'">
71
+ <div x-show="$store.settings.activeTab === 'developer'">
72
<x-component path="settings/developer/developer-settings.html"></x-component>
73
</div>
74
- <div x-show="$store.settingsStore.activeTab === 'backup'">
74
+ <div x-show="$store.settings.activeTab === 'backup'">
75
<x-component path="settings/backup/backup-settings.html"></x-component>
76
</div>
77
- <div x-show="$store.settingsStore.activeTab === 'skills'">
77
+ <div x-show="$store.settings.activeTab === 'skills'">
78
<x-component path="settings/skills/skills-settings.html"></x-component>
79
</div>
80
</div>
81
</div>
82
83
<!-- Footer -->
84
- <div class="modal-footer" data-modal-footer x-show="$store.settingsStore.settings">
84
+ <div class="modal-footer" data-modal-footer x-show="$store.settings.settings">
85
<button class="btn btn-ok"
86
- @click="$store.settingsStore.saveAndClose()"
87
- :disabled="$store.settingsStore?.isLoading">
86
+ @click="$store.settings.saveAndClose()"
87
+ :disabled="$store.settings?.isLoading">
88
Save
89
</button>
90
<button class="btn btn-cancel"
91
- @click="$store.settingsStore.closeSettings()">
91
+ @click="$store.settings.closeSettings()">
92
Cancel
93
</button>
94
</div>
webui/components/settings/skills/skills-settings.html
+1
-1
@@ -5,7 +5,7 @@
5
6
<body>
7
<div x-data>
8
- <template x-if="$store.settingsStore">
8
+ <template x-if="$store.settings">
9
<div>
10
<nav>
11
<ul>
webui/components/sidebar/chats/chats-store.js
+24
@@ -1,4 +1,5 @@
1
import { createStore } from "/js/AlpineStore.js";
2
+import { callJsonApi } from "/js/api.js";
3
import {
4
sendJsonData,
5
getContext,
@@ -16,6 +17,7 @@ const model = {
17
contexts: [],
18
selected: "",
19
selectedContext: null,
20
+ loggedIn: false,
21
22
// for convenience
23
getSelectedChatId() {
@@ -27,6 +29,7 @@ const model = {
29
},
30
31
init() {
32
+ this.loggedIn = Boolean(window.runtimeInfo && window.runtimeInfo.loggedIn);
33
// Initialize from sessionStorage
34
const lastSelectedChat = sessionStorage.getItem("lastSelectedChat");
35
if (lastSelectedChat) {
@@ -336,6 +339,27 @@ const model = {
339
} catch (_e) {
340
// ignore
341
}
342
+ },
343
+
344
+ async logout() {
345
+ try {
346
+ await callJsonApi("/logout", {});
347
+ } catch (_e) {
348
+ // ignore
349
+ }
350
+
351
+ try {
352
+ sessionStorage.removeItem("lastSelectedChat");
353
+ sessionStorage.removeItem("lastSelectedTask");
354
+ } catch (_e) {
355
+ // ignore
356
+ }
357
+
358
+ try {
359
+ window.location.reload();
360
+ } catch (_e) {
361
+ // ignore
362
+ }
363
}
364
};
365
webui/components/sidebar/top-section/quick-actions.html
+5
@@ -94,6 +94,11 @@
94
95
<div class="dropdown-separator"></div>
96
97
+ <button class="dropdown-item" @click="$confirmClick($event, () => { $store.chats.logout(); dropdownOpen = false })" :disabled="!$store.chats.loggedIn">
98
+ <span class="material-symbols-outlined">logout</span>
99
+ <span>Logout</span>
100
+ </button>
101
+
102
<button class="dropdown-item" @click="$confirmClick($event, () => { $store.chats.restart(); dropdownOpen = false })">
103
<span class="material-symbols-outlined">restart_alt</span>
104
<span>Restart A0</span>
webui/index.html
+2
-1
@@ -67,7 +67,8 @@
67
globalThis.runtimeInfo = {
68
...(globalThis.runtimeInfo || {}),
69
id: "{{runtime_id}}",
70
- isDevelopment: {{runtime_is_development}},
70
+ isDevelopment: "{{runtime_is_development}}" === "true",
71
+ loggedIn: "{{logged_in}}" === "true",
72
};
73
</script>
74
</head>