@chrysb/alphaclaw 0.5.6 → 0.5.7-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/alphaclaw.js +6 -1
- package/lib/public/css/agents.css +92 -0
- package/lib/public/css/explorer.css +101 -0
- package/lib/public/css/shell.css +15 -4
- package/lib/public/js/app.js +69 -3
- package/lib/public/js/components/action-button.js +5 -0
- package/lib/public/js/components/agents-tab/agent-bindings-section/helpers.js +76 -0
- package/lib/public/js/components/agents-tab/agent-bindings-section/index.js +490 -0
- package/lib/public/js/components/agents-tab/agent-bindings-section/use-agent-bindings.js +256 -0
- package/lib/public/js/components/agents-tab/agent-detail-panel.js +74 -0
- package/lib/public/js/components/agents-tab/agent-identity-section.js +175 -0
- package/lib/public/js/components/agents-tab/agent-overview/index.js +53 -0
- package/lib/public/js/components/agents-tab/agent-overview/manage-card.js +44 -0
- package/lib/public/js/components/agents-tab/agent-overview/model-card.js +158 -0
- package/lib/public/js/components/agents-tab/agent-overview/use-model-card.js +169 -0
- package/lib/public/js/components/agents-tab/agent-overview/use-workspace-card.js +45 -0
- package/lib/public/js/components/agents-tab/agent-overview/workspace-card.js +47 -0
- package/lib/public/js/components/agents-tab/agent-pairing-section.js +265 -0
- package/lib/public/js/components/agents-tab/create-agent-modal.js +189 -0
- package/lib/public/js/components/agents-tab/create-channel-modal.js +323 -0
- package/lib/public/js/components/agents-tab/delete-agent-dialog.js +50 -0
- package/lib/public/js/components/agents-tab/edit-agent-modal.js +109 -0
- package/lib/public/js/components/agents-tab/index.js +148 -0
- package/lib/public/js/components/agents-tab/use-agents.js +89 -0
- package/lib/public/js/components/channel-account-status-badge.js +35 -0
- package/lib/public/js/components/channel-operations-panel.js +33 -0
- package/lib/public/js/components/channels.js +545 -60
- package/lib/public/js/components/envars.js +25 -4
- package/lib/public/js/components/general/index.js +21 -11
- package/lib/public/js/components/general/use-general-tab.js +78 -16
- package/lib/public/js/components/google/gmail-setup-wizard.js +1 -3
- package/lib/public/js/components/google/index.js +28 -30
- package/lib/public/js/components/icons.js +37 -0
- package/lib/public/js/components/models-tab/index.js +58 -224
- package/lib/public/js/components/models-tab/model-picker.js +212 -0
- package/lib/public/js/components/models-tab/use-models.js +17 -14
- package/lib/public/js/components/onboarding/use-welcome-pairing.js +4 -4
- package/lib/public/js/components/onboarding/welcome-pairing-step.js +2 -2
- package/lib/public/js/components/overflow-menu.js +122 -0
- package/lib/public/js/components/pairings.js +36 -8
- package/lib/public/js/components/routes/agents-route.js +27 -0
- package/lib/public/js/components/routes/general-route.js +2 -0
- package/lib/public/js/components/routes/index.js +1 -0
- package/lib/public/js/components/routes/telegram-route.js +2 -2
- package/lib/public/js/components/secret-input.js +8 -1
- package/lib/public/js/components/sidebar.js +64 -26
- package/lib/public/js/components/telegram-workspace/index.js +175 -74
- package/lib/public/js/components/telegram-workspace/manage.js +83 -10
- package/lib/public/js/components/telegram-workspace/onboarding.js +9 -8
- package/lib/public/js/components/webhooks.js +43 -18
- package/lib/public/js/hooks/use-app-shell-controller.js +7 -0
- package/lib/public/js/hooks/use-browse-navigation.js +8 -5
- package/lib/public/js/hooks/use-destination-session-selection.js +8 -1
- package/lib/public/js/lib/api.js +163 -9
- package/lib/public/js/lib/app-navigation.js +2 -1
- package/lib/public/js/lib/channel-create-operation.js +102 -0
- package/lib/public/js/lib/format.js +14 -0
- package/lib/public/js/lib/sse.js +51 -0
- package/lib/public/js/lib/telegram-api.js +38 -18
- package/lib/public/setup.html +1 -0
- package/lib/public/shared/browse-file-policies.json +0 -1
- package/lib/server/agents/service.js +1478 -0
- package/lib/server/constants.js +2 -2
- package/lib/server/env.js +3 -1
- package/lib/server/gateway.js +104 -20
- package/lib/server/gmail-watch.js +29 -2
- package/lib/server/onboarding/import/import-applier.js +0 -1
- package/lib/server/onboarding/index.js +0 -6
- package/lib/server/onboarding/workspace.js +73 -38
- package/lib/server/openclaw-config.js +23 -0
- package/lib/server/operation-events.js +141 -0
- package/lib/server/routes/agents.js +266 -0
- package/lib/server/routes/pairings.js +135 -25
- package/lib/server/routes/system.js +90 -10
- package/lib/server/routes/telegram.js +247 -51
- package/lib/server/telegram-workspace.js +61 -10
- package/lib/server/topic-registry.js +66 -7
- package/lib/server/watchdog.js +39 -1
- package/lib/server/webhooks.js +60 -12
- package/lib/server.js +21 -7
- package/lib/setup/core-prompts/AGENTS.md +6 -5
- package/lib/setup/core-prompts/TOOLS.md +1 -8
- package/package.json +1 -1
- package/lib/setup/skills/control-ui/SKILL.md +0 -62
package/bin/alphaclaw.js
CHANGED
|
@@ -105,6 +105,7 @@ telegram topic add options:
|
|
|
105
105
|
--thread <id> Telegram thread ID
|
|
106
106
|
--name <text> Topic name
|
|
107
107
|
--system <text> Optional system instructions
|
|
108
|
+
--agent <id> Optional agent ID for per-topic routing
|
|
108
109
|
--group <id> Optional group ID override (auto-resolves when one group exists)
|
|
109
110
|
|
|
110
111
|
Examples:
|
|
@@ -112,6 +113,7 @@ Examples:
|
|
|
112
113
|
alphaclaw git-sync --message "update config" --file "workspace/app/config.json"
|
|
113
114
|
alphaclaw telegram topic add --thread 12 --name "Testing"
|
|
114
115
|
alphaclaw telegram topic add --thread 12 --name "Testing" --system "Handle QA requests"
|
|
116
|
+
alphaclaw telegram topic add --thread 12 --name "Ops" --agent ops
|
|
115
117
|
`);
|
|
116
118
|
process.exit(0);
|
|
117
119
|
}
|
|
@@ -375,6 +377,7 @@ const runTelegramTopicAdd = () => {
|
|
|
375
377
|
const systemInstructions = String(
|
|
376
378
|
flagValue(commandArgs, "--system") || "",
|
|
377
379
|
).trim();
|
|
380
|
+
const agentId = String(flagValue(commandArgs, "--agent") || "").trim();
|
|
378
381
|
const requestedGroupId = String(
|
|
379
382
|
flagValue(commandArgs, "--group") || "",
|
|
380
383
|
).trim();
|
|
@@ -423,6 +426,7 @@ const runTelegramTopicAdd = () => {
|
|
|
423
426
|
topicRegistry.updateTopic(groupId, threadId, {
|
|
424
427
|
name: topicName,
|
|
425
428
|
...(systemInstructions ? { systemInstructions } : {}),
|
|
429
|
+
...(agentId ? { agentId } : {}),
|
|
426
430
|
});
|
|
427
431
|
|
|
428
432
|
const requireMention =
|
|
@@ -440,8 +444,9 @@ const runTelegramTopicAdd = () => {
|
|
|
440
444
|
workspaceDir: path.join(openclawDir, "workspace"),
|
|
441
445
|
});
|
|
442
446
|
|
|
447
|
+
const agentSuffix = agentId ? ` agent=${agentId}` : "";
|
|
443
448
|
console.log(
|
|
444
|
-
`[alphaclaw] Topic mapped: group=${groupId} thread=${threadId} name=${topicName}`,
|
|
449
|
+
`[alphaclaw] Topic mapped: group=${groupId} thread=${threadId} name=${topicName}${agentSuffix}`,
|
|
445
450
|
);
|
|
446
451
|
console.log(
|
|
447
452
|
`[alphaclaw] Concurrency updated: agent=${syncResult.maxConcurrent} subagents=${syncResult.subagentMaxConcurrent} topics=${syncResult.totalTopics}`,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* ── Agents detail layout ────────────────────── */
|
|
2
|
+
|
|
3
|
+
.app-content-pane.agents-pane {
|
|
4
|
+
padding: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/* ── Detail panel ────────────────────────────── */
|
|
8
|
+
|
|
9
|
+
.agents-detail-panel {
|
|
10
|
+
height: 100%;
|
|
11
|
+
overflow-y: auto;
|
|
12
|
+
padding: 0 32px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.agents-detail-inner {
|
|
16
|
+
max-width: 42rem;
|
|
17
|
+
width: 100%;
|
|
18
|
+
margin: 0 auto;
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
min-height: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.agents-detail-header {
|
|
25
|
+
padding-top: 16px;
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: flex-start;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
gap: 12px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.agents-detail-header-title {
|
|
33
|
+
font-size: 16px;
|
|
34
|
+
font-weight: 600;
|
|
35
|
+
color: var(--text);
|
|
36
|
+
min-width: 0;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
text-overflow: ellipsis;
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── Sub-tabs ────────────────────────────────── */
|
|
43
|
+
|
|
44
|
+
.agents-sub-tabs {
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
gap: 2px;
|
|
48
|
+
padding-top: 12px;
|
|
49
|
+
border-bottom: 1px solid var(--border);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.agents-sub-tab {
|
|
53
|
+
padding: 8px 14px;
|
|
54
|
+
font-size: 13px;
|
|
55
|
+
font-weight: 500;
|
|
56
|
+
color: var(--text-muted);
|
|
57
|
+
background: transparent;
|
|
58
|
+
border: none;
|
|
59
|
+
border-bottom: 2px solid transparent;
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
transition: color 0.12s, border-color 0.12s;
|
|
62
|
+
font-family: inherit;
|
|
63
|
+
margin-bottom: -1px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.agents-sub-tab:hover {
|
|
67
|
+
color: var(--text);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.agents-sub-tab.active {
|
|
71
|
+
color: var(--accent);
|
|
72
|
+
border-bottom-color: var(--accent);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.agents-detail-content {
|
|
76
|
+
flex: 1;
|
|
77
|
+
padding: 24px 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* ── Empty state ─────────────────────────────── */
|
|
81
|
+
|
|
82
|
+
.agents-empty-state {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-direction: column;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
height: 100%;
|
|
88
|
+
color: var(--text-dim);
|
|
89
|
+
gap: 12px;
|
|
90
|
+
padding: 32px;
|
|
91
|
+
text-align: center;
|
|
92
|
+
}
|
|
@@ -95,6 +95,107 @@
|
|
|
95
95
|
overflow: hidden;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/* ── Sidebar agents list ─────────────────────── */
|
|
99
|
+
|
|
100
|
+
.sidebar-agents-header {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
justify-content: space-between;
|
|
104
|
+
gap: 8px;
|
|
105
|
+
padding: 12px 16px 4px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.sidebar-agents-label {
|
|
109
|
+
padding: 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.sidebar-agents-add-button {
|
|
113
|
+
border: none;
|
|
114
|
+
background: transparent;
|
|
115
|
+
color: var(--text-muted);
|
|
116
|
+
font: inherit;
|
|
117
|
+
display: inline-flex;
|
|
118
|
+
align-items: center;
|
|
119
|
+
justify-content: center;
|
|
120
|
+
line-height: 1;
|
|
121
|
+
padding: 6px;
|
|
122
|
+
margin: -6px;
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
opacity: 0.9;
|
|
125
|
+
transition: color 0.1s, opacity 0.1s;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.sidebar-agents-add-icon {
|
|
129
|
+
width: 16px;
|
|
130
|
+
height: 16px;
|
|
131
|
+
display: block;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sidebar-agents-add-button:hover {
|
|
135
|
+
color: var(--text);
|
|
136
|
+
opacity: 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.sidebar-agents-list {
|
|
140
|
+
flex: 0 0 auto;
|
|
141
|
+
overflow: visible;
|
|
142
|
+
padding: 2px 0 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.sidebar-agent-item {
|
|
146
|
+
display: flex;
|
|
147
|
+
align-items: center;
|
|
148
|
+
gap: 6px;
|
|
149
|
+
padding: 6px 16px 6px 24px;
|
|
150
|
+
color: var(--text-muted);
|
|
151
|
+
font-size: 13px;
|
|
152
|
+
line-height: 1.4;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
transition: background 0.1s, color 0.1s;
|
|
155
|
+
position: relative;
|
|
156
|
+
user-select: none;
|
|
157
|
+
border: none;
|
|
158
|
+
background: transparent;
|
|
159
|
+
width: 100%;
|
|
160
|
+
text-align: left;
|
|
161
|
+
font: inherit;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.sidebar-agent-item:hover {
|
|
165
|
+
background: var(--bg-hover);
|
|
166
|
+
color: var(--text);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.sidebar-agent-item.active {
|
|
170
|
+
background: var(--bg-active);
|
|
171
|
+
color: var(--accent);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.sidebar-agent-item.active::before {
|
|
175
|
+
content: "";
|
|
176
|
+
position: absolute;
|
|
177
|
+
left: 0;
|
|
178
|
+
top: 0;
|
|
179
|
+
bottom: 0;
|
|
180
|
+
width: 2px;
|
|
181
|
+
background: var(--accent);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.sidebar-agent-name {
|
|
185
|
+
flex: 1;
|
|
186
|
+
min-width: 0;
|
|
187
|
+
overflow: hidden;
|
|
188
|
+
text-overflow: ellipsis;
|
|
189
|
+
white-space: nowrap;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.sidebar-agents-add {
|
|
193
|
+
margin: 0;
|
|
194
|
+
padding: 16px 14px 8px 20px;
|
|
195
|
+
border-top: 1px solid var(--border);
|
|
196
|
+
margin-top: 8px;
|
|
197
|
+
}
|
|
198
|
+
|
|
98
199
|
.file-tree-wrap {
|
|
99
200
|
width: 100%;
|
|
100
201
|
display: flex;
|
package/lib/public/css/shell.css
CHANGED
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
.sidebar-footer:empty { display: none; }
|
|
175
175
|
|
|
176
176
|
.sidebar-footer:not(:empty) {
|
|
177
|
-
padding:
|
|
177
|
+
padding: 12px 16px;
|
|
178
178
|
border-top: 1px solid var(--border);
|
|
179
179
|
}
|
|
180
180
|
|
|
@@ -222,7 +222,9 @@
|
|
|
222
222
|
position: absolute;
|
|
223
223
|
top: calc(100% + 4px);
|
|
224
224
|
right: 0;
|
|
225
|
-
min-width:
|
|
225
|
+
min-width: max-content;
|
|
226
|
+
width: max-content;
|
|
227
|
+
max-width: min(280px, calc(100vw - 24px));
|
|
226
228
|
background: var(--bg-sidebar);
|
|
227
229
|
border: 1px solid var(--border-strong);
|
|
228
230
|
border-radius: 8px;
|
|
@@ -231,16 +233,25 @@
|
|
|
231
233
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
.brand-dropdown a
|
|
236
|
+
.brand-dropdown a,
|
|
237
|
+
.brand-dropdown-item {
|
|
235
238
|
display: block;
|
|
239
|
+
width: 100%;
|
|
236
240
|
padding: 6px 10px;
|
|
241
|
+
font: inherit;
|
|
237
242
|
font-size: 12px;
|
|
238
243
|
color: var(--text-muted);
|
|
239
244
|
text-decoration: none;
|
|
240
245
|
border-radius: 5px;
|
|
241
246
|
transition: background 0.1s, color 0.1s;
|
|
247
|
+
background: transparent;
|
|
248
|
+
border: none;
|
|
249
|
+
text-align: left;
|
|
250
|
+
white-space: nowrap;
|
|
251
|
+
cursor: pointer;
|
|
242
252
|
}
|
|
243
|
-
.brand-dropdown a:hover
|
|
253
|
+
.brand-dropdown a:hover,
|
|
254
|
+
.brand-dropdown-item:hover { background: var(--bg-hover); color: var(--text); }
|
|
244
255
|
|
|
245
256
|
/* ── Statusbar ─────────────────────────────────── */
|
|
246
257
|
|
package/lib/public/js/app.js
CHANGED
|
@@ -14,6 +14,7 @@ import { GlobalRestartBanner } from "./components/global-restart-banner.js";
|
|
|
14
14
|
import { LoadingSpinner } from "./components/loading-spinner.js";
|
|
15
15
|
import { AppSidebar } from "./components/sidebar.js";
|
|
16
16
|
import {
|
|
17
|
+
AgentsRoute,
|
|
17
18
|
BrowseRoute,
|
|
18
19
|
DoctorRoute,
|
|
19
20
|
EnvarsRoute,
|
|
@@ -25,6 +26,7 @@ import {
|
|
|
25
26
|
WatchdogRoute,
|
|
26
27
|
WebhooksRoute,
|
|
27
28
|
} from "./components/routes/index.js";
|
|
29
|
+
import { useAgents } from "./components/agents-tab/use-agents.js";
|
|
28
30
|
import { useAppShellController } from "./hooks/use-app-shell-controller.js";
|
|
29
31
|
import { useAppShellUi } from "./hooks/use-app-shell-ui.js";
|
|
30
32
|
import { useBrowseNavigation } from "./hooks/use-browse-navigation.js";
|
|
@@ -38,6 +40,7 @@ const html = htm.bind(h);
|
|
|
38
40
|
const kDoctorWarningDismissedUntilUiSettingKey =
|
|
39
41
|
"doctorWarningDismissedUntilMs";
|
|
40
42
|
const kOneWeekMs = 7 * 24 * 60 * 60 * 1000;
|
|
43
|
+
const kPendingCreateAgentWindowFlag = "__alphaclawPendingCreateAgent";
|
|
41
44
|
|
|
42
45
|
const App = () => {
|
|
43
46
|
const [location, setLocation] = useLocation();
|
|
@@ -66,6 +69,34 @@ const App = () => {
|
|
|
66
69
|
onCloseMobileSidebar: shellActions.closeMobileSidebar,
|
|
67
70
|
});
|
|
68
71
|
|
|
72
|
+
const {
|
|
73
|
+
state: agentsState,
|
|
74
|
+
actions: agentsActions,
|
|
75
|
+
} = useAgents();
|
|
76
|
+
|
|
77
|
+
const isAgentsRoute = location.startsWith("/agents");
|
|
78
|
+
const selectedAgentId = (() => {
|
|
79
|
+
const match = location.match(/^\/agents\/([^/]+)/);
|
|
80
|
+
return match ? decodeURIComponent(match[1]) : "";
|
|
81
|
+
})();
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!isAgentsRoute) return;
|
|
85
|
+
if (window[kPendingCreateAgentWindowFlag]) return;
|
|
86
|
+
if (selectedAgentId) return;
|
|
87
|
+
if (agentsState.loading || agentsState.agents.length === 0) return;
|
|
88
|
+
setLocation(`/agents/${encodeURIComponent(agentsState.agents[0].id)}`);
|
|
89
|
+
}, [isAgentsRoute, selectedAgentId, agentsState.loading, agentsState.agents, setLocation]);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!isAgentsRoute) return;
|
|
93
|
+
if (!window[kPendingCreateAgentWindowFlag]) return;
|
|
94
|
+
window[kPendingCreateAgentWindowFlag] = false;
|
|
95
|
+
window.setTimeout(() => {
|
|
96
|
+
window.dispatchEvent(new Event("alphaclaw:create-agent"));
|
|
97
|
+
}, 0);
|
|
98
|
+
}, [isAgentsRoute]);
|
|
99
|
+
|
|
69
100
|
useEffect(() => {
|
|
70
101
|
const settings = readUiSettings();
|
|
71
102
|
settings[kDoctorWarningDismissedUntilUiSettingKey] =
|
|
@@ -143,6 +174,17 @@ const App = () => {
|
|
|
143
174
|
acLatest=${controllerState.acLatest}
|
|
144
175
|
acUpdating=${controllerState.acUpdating}
|
|
145
176
|
onAcUpdate=${controllerActions.handleAcUpdate}
|
|
177
|
+
agents=${agentsState.agents}
|
|
178
|
+
selectedAgentId=${selectedAgentId}
|
|
179
|
+
onSelectAgent=${(agentId) => setLocation(`/agents/${encodeURIComponent(agentId)}`)}
|
|
180
|
+
onAddAgent=${() => {
|
|
181
|
+
if (isAgentsRoute) {
|
|
182
|
+
window.dispatchEvent(new Event("alphaclaw:create-agent"));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
window[kPendingCreateAgentWindowFlag] = true;
|
|
186
|
+
setLocation("/agents");
|
|
187
|
+
}}
|
|
146
188
|
/>
|
|
147
189
|
<div
|
|
148
190
|
class=${`sidebar-resizer ${shellState.isResizingSidebar ? "is-resizing" : ""}`}
|
|
@@ -181,10 +223,25 @@ const App = () => {
|
|
|
181
223
|
}}
|
|
182
224
|
/>
|
|
183
225
|
</div>
|
|
226
|
+
<div
|
|
227
|
+
class="app-content-pane agents-pane"
|
|
228
|
+
style=${{ display: isAgentsRoute ? "block" : "none" }}
|
|
229
|
+
>
|
|
230
|
+
<${AgentsRoute}
|
|
231
|
+
agents=${agentsState.agents}
|
|
232
|
+
loading=${agentsState.loading}
|
|
233
|
+
saving=${agentsState.saving}
|
|
234
|
+
agentsActions=${agentsActions}
|
|
235
|
+
selectedAgentId=${selectedAgentId}
|
|
236
|
+
onSelectAgent=${(agentId) => setLocation(`/agents/${encodeURIComponent(agentId)}`)}
|
|
237
|
+
onNavigateToBrowseFile=${browseActions.navigateToBrowseFile}
|
|
238
|
+
onSetLocation=${setLocation}
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
184
241
|
<div
|
|
185
242
|
class="app-content-pane"
|
|
186
243
|
onscroll=${shellActions.handlePaneScroll}
|
|
187
|
-
style=${{ display: browseState.isBrowseRoute ? "none" : "block" }}
|
|
244
|
+
style=${{ display: browseState.isBrowseRoute || isAgentsRoute ? "none" : "block" }}
|
|
188
245
|
>
|
|
189
246
|
<div
|
|
190
247
|
class=${`mobile-topbar ${shellState.mobileTopbarScrolled ? "is-scrolled" : ""}`}
|
|
@@ -212,7 +269,7 @@ const App = () => {
|
|
|
212
269
|
</span>
|
|
213
270
|
</div>
|
|
214
271
|
<div class="max-w-2xl w-full mx-auto">
|
|
215
|
-
${!browseState.isBrowseRoute
|
|
272
|
+
${!browseState.isBrowseRoute && !isAgentsRoute
|
|
216
273
|
? html`
|
|
217
274
|
<${Switch}>
|
|
218
275
|
<${Route} path="/general">
|
|
@@ -220,6 +277,7 @@ const App = () => {
|
|
|
220
277
|
statusData=${controllerState.sharedStatus}
|
|
221
278
|
watchdogData=${controllerState.sharedWatchdogStatus}
|
|
222
279
|
doctorStatusData=${controllerState.sharedDoctorStatus}
|
|
280
|
+
agents=${agentsState.agents}
|
|
223
281
|
doctorWarningDismissedUntilMs=${doctorWarningDismissedUntilMs}
|
|
224
282
|
onRefreshStatuses=${controllerActions.refreshSharedStatuses}
|
|
225
283
|
onSetLocation=${setLocation}
|
|
@@ -240,8 +298,16 @@ const App = () => {
|
|
|
240
298
|
<${Route} path="/doctor">
|
|
241
299
|
<${DoctorRoute} onNavigateToBrowseFile=${browseActions.navigateToBrowseFile} />
|
|
242
300
|
</${Route}>
|
|
301
|
+
<${Route} path="/telegram/:accountId">
|
|
302
|
+
${(params) => html`
|
|
303
|
+
<${TelegramRoute}
|
|
304
|
+
accountId=${decodeURIComponent(params.accountId || "default")}
|
|
305
|
+
onBack=${browseActions.exitSubScreen}
|
|
306
|
+
/>
|
|
307
|
+
`}
|
|
308
|
+
</${Route}>
|
|
243
309
|
<${Route} path="/telegram">
|
|
244
|
-
<${
|
|
310
|
+
<${RouteRedirect} to="/telegram/default" />
|
|
245
311
|
</${Route}>
|
|
246
312
|
<${Route} path="/models">
|
|
247
313
|
<${ModelsRoute} onRestartRequired=${controllerActions.setRestartRequired} />
|
|
@@ -13,6 +13,11 @@ const kStaticToneClassByTone = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const getToneClass = (tone, isInteractive) => {
|
|
16
|
+
if (tone === "subtle") {
|
|
17
|
+
return isInteractive
|
|
18
|
+
? "border border-border text-gray-500 hover:text-gray-300 hover:border-gray-500"
|
|
19
|
+
: "border border-border text-gray-500";
|
|
20
|
+
}
|
|
16
21
|
if (tone === "neutral") {
|
|
17
22
|
return isInteractive
|
|
18
23
|
? "border border-border text-gray-500 hover:text-gray-300 hover:border-gray-500"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export const announceBindingsChanged = (agentId) => {
|
|
2
|
+
window.dispatchEvent(
|
|
3
|
+
new CustomEvent("alphaclaw:agent-bindings-changed", {
|
|
4
|
+
detail: { agentId: String(agentId || "").trim() },
|
|
5
|
+
}),
|
|
6
|
+
);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const resolveChannelAccountLabel = ({ channelId, account = {} }) => {
|
|
10
|
+
const providerLabel = channelId
|
|
11
|
+
? channelId.charAt(0).toUpperCase() + channelId.slice(1)
|
|
12
|
+
: "Channel";
|
|
13
|
+
const configuredName = String(account?.name || "").trim();
|
|
14
|
+
if (configuredName) return configuredName;
|
|
15
|
+
const accountId = String(account?.id || "").trim();
|
|
16
|
+
if (!accountId || accountId === "default") return providerLabel;
|
|
17
|
+
return `${providerLabel} ${accountId}`;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getChannelItemSortRank = (item = {}) => {
|
|
21
|
+
if (item.isAwaitingPairing) return 99;
|
|
22
|
+
if (item.isOwned) return 0;
|
|
23
|
+
if (item.isUnconfigured) return 3;
|
|
24
|
+
if (item.isAvailable) return 1;
|
|
25
|
+
return 2;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const getAccountStatusInfo = ({ statusInfo, accountId }) => {
|
|
29
|
+
const normalizedAccountId = String(accountId || "").trim() || "default";
|
|
30
|
+
const accountStatuses =
|
|
31
|
+
statusInfo?.accounts && typeof statusInfo.accounts === "object"
|
|
32
|
+
? statusInfo.accounts
|
|
33
|
+
: null;
|
|
34
|
+
if (accountStatuses?.[normalizedAccountId]) {
|
|
35
|
+
return accountStatuses[normalizedAccountId];
|
|
36
|
+
}
|
|
37
|
+
if (normalizedAccountId === "default" && statusInfo) {
|
|
38
|
+
return statusInfo;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const getResolvedAccountStatusInfo = ({
|
|
44
|
+
account,
|
|
45
|
+
statusInfo,
|
|
46
|
+
accountId,
|
|
47
|
+
}) => {
|
|
48
|
+
const accountStatus = String(account?.status || "").trim();
|
|
49
|
+
if (accountStatus) {
|
|
50
|
+
return {
|
|
51
|
+
status: accountStatus,
|
|
52
|
+
paired: Number(account?.paired || 0),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return getAccountStatusInfo({ statusInfo, accountId });
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const isImplicitDefaultAccount = ({ accountId, boundAgentId }) =>
|
|
59
|
+
String(accountId || "").trim() === "default" &&
|
|
60
|
+
!String(boundAgentId || "").trim();
|
|
61
|
+
|
|
62
|
+
export const canAgentBindAccount = ({
|
|
63
|
+
accountId,
|
|
64
|
+
boundAgentId,
|
|
65
|
+
agentId,
|
|
66
|
+
isDefaultAgent,
|
|
67
|
+
}) => {
|
|
68
|
+
const normalizedBoundAgentId = String(boundAgentId || "").trim();
|
|
69
|
+
if (normalizedBoundAgentId) {
|
|
70
|
+
return normalizedBoundAgentId === String(agentId || "").trim();
|
|
71
|
+
}
|
|
72
|
+
if (isImplicitDefaultAccount({ accountId, boundAgentId })) {
|
|
73
|
+
return !!isDefaultAgent;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
};
|