@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
|
@@ -28,9 +28,15 @@ import {
|
|
|
28
28
|
kTelegramWorkspaceCacheKey,
|
|
29
29
|
} from "../../lib/storage-keys.js";
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const resolveStorageKey = (baseKey, accountId) => {
|
|
32
|
+
const suffix = String(accountId || "").trim();
|
|
33
|
+
if (!suffix || suffix === "default") return baseKey;
|
|
34
|
+
return `${baseKey}.${suffix}`;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const loadTelegramWorkspaceState = (accountId) => {
|
|
32
38
|
try {
|
|
33
|
-
const raw = window.localStorage.getItem(kTelegramWorkspaceStorageKey);
|
|
39
|
+
const raw = window.localStorage.getItem(resolveStorageKey(kTelegramWorkspaceStorageKey, accountId));
|
|
34
40
|
if (!raw) return {};
|
|
35
41
|
const parsed = JSON.parse(raw);
|
|
36
42
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
@@ -38,9 +44,22 @@ const loadTelegramWorkspaceState = () => {
|
|
|
38
44
|
return {};
|
|
39
45
|
}
|
|
40
46
|
};
|
|
41
|
-
const
|
|
47
|
+
const saveTelegramWorkspaceState = (accountId, state) => {
|
|
48
|
+
try {
|
|
49
|
+
window.localStorage.setItem(
|
|
50
|
+
resolveStorageKey(kTelegramWorkspaceStorageKey, accountId),
|
|
51
|
+
JSON.stringify(state),
|
|
52
|
+
);
|
|
53
|
+
} catch {}
|
|
54
|
+
};
|
|
55
|
+
const removeTelegramWorkspaceState = (accountId) => {
|
|
56
|
+
try {
|
|
57
|
+
window.localStorage.removeItem(resolveStorageKey(kTelegramWorkspaceStorageKey, accountId));
|
|
58
|
+
} catch {}
|
|
59
|
+
};
|
|
60
|
+
const loadTelegramWorkspaceCache = (accountId) => {
|
|
42
61
|
try {
|
|
43
|
-
const raw = window.localStorage.getItem(kTelegramWorkspaceCacheKey);
|
|
62
|
+
const raw = window.localStorage.getItem(resolveStorageKey(kTelegramWorkspaceCacheKey, accountId));
|
|
44
63
|
if (!raw) return null;
|
|
45
64
|
const parsed = JSON.parse(raw);
|
|
46
65
|
const data = parsed?.data;
|
|
@@ -50,14 +69,19 @@ const loadTelegramWorkspaceCache = () => {
|
|
|
50
69
|
return null;
|
|
51
70
|
}
|
|
52
71
|
};
|
|
53
|
-
const saveTelegramWorkspaceCache = (data) => {
|
|
72
|
+
const saveTelegramWorkspaceCache = (accountId, data) => {
|
|
54
73
|
try {
|
|
55
74
|
window.localStorage.setItem(
|
|
56
|
-
kTelegramWorkspaceCacheKey,
|
|
75
|
+
resolveStorageKey(kTelegramWorkspaceCacheKey, accountId),
|
|
57
76
|
JSON.stringify({ cachedAt: Date.now(), data }),
|
|
58
77
|
);
|
|
59
78
|
} catch {}
|
|
60
79
|
};
|
|
80
|
+
const removeTelegramWorkspaceCache = (accountId) => {
|
|
81
|
+
try {
|
|
82
|
+
window.localStorage.removeItem(resolveStorageKey(kTelegramWorkspaceCacheKey, accountId));
|
|
83
|
+
} catch {}
|
|
84
|
+
};
|
|
61
85
|
|
|
62
86
|
const BackButton = ({ onBack }) => html`
|
|
63
87
|
<button
|
|
@@ -73,15 +97,84 @@ const BackButton = ({ onBack }) => html`
|
|
|
73
97
|
</button>
|
|
74
98
|
`;
|
|
75
99
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
const MultiGroupView = ({
|
|
101
|
+
accountId,
|
|
102
|
+
groups,
|
|
103
|
+
concurrency,
|
|
104
|
+
debugEnabled,
|
|
105
|
+
onResetOnboarding,
|
|
106
|
+
}) => {
|
|
107
|
+
const [expandedGroupId, setExpandedGroupId] = useState(
|
|
108
|
+
() => groups[0]?.groupId || "",
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const toggle = (gId) =>
|
|
112
|
+
setExpandedGroupId((current) => (current === gId ? "" : gId));
|
|
113
|
+
|
|
114
|
+
return html`
|
|
115
|
+
<div class="space-y-3">
|
|
116
|
+
${groups.map(
|
|
117
|
+
(g) => html`
|
|
118
|
+
<div
|
|
119
|
+
key=${g.groupId}
|
|
120
|
+
class="border border-border rounded-lg overflow-hidden"
|
|
121
|
+
>
|
|
122
|
+
<button
|
|
123
|
+
onclick=${() => toggle(g.groupId)}
|
|
124
|
+
class="w-full flex items-center justify-between px-3 py-2.5 bg-black/20 hover:bg-black/30 transition-colors text-left"
|
|
125
|
+
>
|
|
126
|
+
<div>
|
|
127
|
+
<p class="text-sm text-gray-300 font-medium">
|
|
128
|
+
${g.groupName || g.groupId}
|
|
129
|
+
</p>
|
|
130
|
+
<p class="text-[11px] text-gray-500 font-mono">${g.groupId}</p>
|
|
131
|
+
</div>
|
|
132
|
+
<svg
|
|
133
|
+
width="16"
|
|
134
|
+
height="16"
|
|
135
|
+
viewBox="0 0 16 16"
|
|
136
|
+
fill="currentColor"
|
|
137
|
+
class="text-gray-500 transition-transform ${expandedGroupId ===
|
|
138
|
+
g.groupId
|
|
139
|
+
? "rotate-180"
|
|
140
|
+
: ""}"
|
|
141
|
+
>
|
|
142
|
+
<path
|
|
143
|
+
d="M4.354 5.646a.5.5 0 00-.708.708l4 4a.5.5 0 00.708 0l4-4a.5.5 0 00-.708-.708L8 9.293 4.354 5.646z"
|
|
144
|
+
/>
|
|
145
|
+
</svg>
|
|
146
|
+
</button>
|
|
147
|
+
${expandedGroupId === g.groupId &&
|
|
148
|
+
html`
|
|
149
|
+
<div class="p-3 border-t border-border">
|
|
150
|
+
<${ManageTelegramWorkspace}
|
|
151
|
+
accountId=${accountId}
|
|
152
|
+
groupId=${g.groupId}
|
|
153
|
+
groupName=${g.groupName}
|
|
154
|
+
initialTopics=${g.topics}
|
|
155
|
+
configAgentMaxConcurrent=${concurrency?.agentMaxConcurrent}
|
|
156
|
+
configSubagentMaxConcurrent=${concurrency?.subagentMaxConcurrent}
|
|
157
|
+
debugEnabled=${debugEnabled}
|
|
158
|
+
onResetOnboarding=${onResetOnboarding}
|
|
159
|
+
/>
|
|
160
|
+
</div>
|
|
161
|
+
`}
|
|
162
|
+
</div>
|
|
163
|
+
`,
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
`;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const TelegramWorkspace = ({ accountId = "default", onBack }) => {
|
|
170
|
+
const initialState = loadTelegramWorkspaceState(accountId);
|
|
171
|
+
const cachedWorkspace = loadTelegramWorkspaceCache(accountId);
|
|
79
172
|
const [step, setStep] = useState(() => {
|
|
80
173
|
const value = Number.parseInt(String(initialState.step ?? 0), 10);
|
|
81
174
|
if (!Number.isFinite(value)) return 0;
|
|
82
175
|
return Math.min(Math.max(value, 0), kSteps.length - 1);
|
|
83
176
|
});
|
|
84
|
-
const [botInfo, setBotInfo] = useState(
|
|
177
|
+
const [botInfo, setBotInfo] = useState(null);
|
|
85
178
|
const [groupId, setGroupId] = useState(initialState.groupId || "");
|
|
86
179
|
const [groupInfo, setGroupInfo] = useState(initialState.groupInfo || null);
|
|
87
180
|
const [verifyGroupError, setVerifyGroupError] = useState(
|
|
@@ -94,6 +187,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
94
187
|
const [workspaceConfig, setWorkspaceConfig] = useState(() => ({
|
|
95
188
|
ready: !!cachedWorkspace,
|
|
96
189
|
configured: !!cachedWorkspace?.configured,
|
|
190
|
+
groups: cachedWorkspace?.groups || [],
|
|
97
191
|
groupId: cachedWorkspace?.groupId || "",
|
|
98
192
|
groupName: cachedWorkspace?.groupName || "",
|
|
99
193
|
topics: cachedWorkspace?.topics || {},
|
|
@@ -108,12 +202,10 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
108
202
|
const goBack = () => setStep((s) => Math.max(0, s - 1));
|
|
109
203
|
const resetOnboarding = async () => {
|
|
110
204
|
try {
|
|
111
|
-
const data = await api.resetWorkspace();
|
|
205
|
+
const data = await api.resetWorkspace({ accountId });
|
|
112
206
|
if (!data.ok) throw new Error(data.error || "Failed to reset onboarding");
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
window.localStorage.removeItem(kTelegramWorkspaceCacheKey);
|
|
116
|
-
} catch {}
|
|
207
|
+
removeTelegramWorkspaceState(accountId);
|
|
208
|
+
removeTelegramWorkspaceCache(accountId);
|
|
117
209
|
setStep(0);
|
|
118
210
|
setBotInfo(null);
|
|
119
211
|
setGroupId("");
|
|
@@ -124,6 +216,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
124
216
|
setWorkspaceConfig({
|
|
125
217
|
ready: true,
|
|
126
218
|
configured: false,
|
|
219
|
+
groups: [],
|
|
127
220
|
groupId: "",
|
|
128
221
|
groupName: "",
|
|
129
222
|
topics: {},
|
|
@@ -136,48 +229,36 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
136
229
|
}
|
|
137
230
|
};
|
|
138
231
|
const handleDone = () => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
subagentMaxConcurrent: null,
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
}),
|
|
158
|
-
);
|
|
159
|
-
} catch {}
|
|
232
|
+
removeTelegramWorkspaceState(accountId);
|
|
233
|
+
const doneGroupName = groupInfo?.chat?.title || groupId;
|
|
234
|
+
saveTelegramWorkspaceCache(accountId, {
|
|
235
|
+
ready: true,
|
|
236
|
+
configured: true,
|
|
237
|
+
groups: [{ groupId, groupName: doneGroupName, topics: topics || {} }],
|
|
238
|
+
groupId,
|
|
239
|
+
groupName: doneGroupName,
|
|
240
|
+
topics: topics || {},
|
|
241
|
+
debugEnabled: !!workspaceConfig?.debugEnabled,
|
|
242
|
+
concurrency: workspaceConfig?.concurrency || {
|
|
243
|
+
agentMaxConcurrent: null,
|
|
244
|
+
subagentMaxConcurrent: null,
|
|
245
|
+
},
|
|
246
|
+
});
|
|
160
247
|
window.location.reload();
|
|
161
248
|
};
|
|
162
249
|
|
|
163
250
|
useEffect(() => {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
verifyGroupError,
|
|
173
|
-
allowUserId,
|
|
174
|
-
topics,
|
|
175
|
-
}),
|
|
176
|
-
);
|
|
177
|
-
} catch {}
|
|
251
|
+
saveTelegramWorkspaceState(accountId, {
|
|
252
|
+
step,
|
|
253
|
+
groupId,
|
|
254
|
+
groupInfo,
|
|
255
|
+
verifyGroupError,
|
|
256
|
+
allowUserId,
|
|
257
|
+
topics,
|
|
258
|
+
});
|
|
178
259
|
}, [
|
|
260
|
+
accountId,
|
|
179
261
|
step,
|
|
180
|
-
botInfo,
|
|
181
262
|
groupId,
|
|
182
263
|
groupInfo,
|
|
183
264
|
verifyGroupError,
|
|
@@ -189,12 +270,14 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
189
270
|
let active = true;
|
|
190
271
|
const bootstrapWorkspace = async () => {
|
|
191
272
|
try {
|
|
192
|
-
const data = await api.workspace();
|
|
273
|
+
const data = await api.workspace({ accountId });
|
|
193
274
|
if (!active || !data?.ok) return;
|
|
194
|
-
|
|
275
|
+
const groups = Array.isArray(data.groups) ? data.groups : [];
|
|
276
|
+
if (!data.configured || groups.length === 0) {
|
|
195
277
|
const nextConfig = {
|
|
196
278
|
ready: true,
|
|
197
279
|
configured: false,
|
|
280
|
+
groups: [],
|
|
198
281
|
groupId: "",
|
|
199
282
|
groupName: "",
|
|
200
283
|
topics: {},
|
|
@@ -205,15 +288,17 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
205
288
|
},
|
|
206
289
|
};
|
|
207
290
|
setWorkspaceConfig(nextConfig);
|
|
208
|
-
saveTelegramWorkspaceCache(nextConfig);
|
|
291
|
+
saveTelegramWorkspaceCache(accountId, nextConfig);
|
|
209
292
|
return;
|
|
210
293
|
}
|
|
294
|
+
const first = groups[0];
|
|
211
295
|
const nextConfig = {
|
|
212
296
|
ready: true,
|
|
213
297
|
configured: true,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
298
|
+
groups,
|
|
299
|
+
groupId: first.groupId,
|
|
300
|
+
groupName: first.groupName || first.groupId,
|
|
301
|
+
topics: first.topics || {},
|
|
217
302
|
debugEnabled: !!data.debugEnabled,
|
|
218
303
|
concurrency: data.concurrency || {
|
|
219
304
|
agentMaxConcurrent: null,
|
|
@@ -221,13 +306,13 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
221
306
|
},
|
|
222
307
|
};
|
|
223
308
|
setWorkspaceConfig(nextConfig);
|
|
224
|
-
saveTelegramWorkspaceCache(nextConfig);
|
|
225
|
-
setGroupId(
|
|
226
|
-
setTopics(
|
|
309
|
+
saveTelegramWorkspaceCache(accountId, nextConfig);
|
|
310
|
+
setGroupId(first.groupId);
|
|
311
|
+
setTopics(first.topics || {});
|
|
227
312
|
setGroupInfo({
|
|
228
313
|
chat: {
|
|
229
|
-
id:
|
|
230
|
-
title:
|
|
314
|
+
id: first.groupId,
|
|
315
|
+
title: first.groupName || first.groupId,
|
|
231
316
|
isForum: true,
|
|
232
317
|
},
|
|
233
318
|
bot: {
|
|
@@ -245,7 +330,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
245
330
|
return () => {
|
|
246
331
|
active = false;
|
|
247
332
|
};
|
|
248
|
-
}, []);
|
|
333
|
+
}, [accountId]);
|
|
249
334
|
|
|
250
335
|
return html`
|
|
251
336
|
<div class="space-y-4">
|
|
@@ -271,17 +356,30 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
271
356
|
</h2>
|
|
272
357
|
</div>
|
|
273
358
|
</div>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
359
|
+
${(workspaceConfig.groups || []).length <= 1
|
|
360
|
+
? html`
|
|
361
|
+
<${ManageTelegramWorkspace}
|
|
362
|
+
accountId=${accountId}
|
|
363
|
+
groupId=${workspaceConfig.groupId}
|
|
364
|
+
groupName=${workspaceConfig.groupName}
|
|
365
|
+
initialTopics=${workspaceConfig.topics}
|
|
366
|
+
configAgentMaxConcurrent=${workspaceConfig.concurrency
|
|
367
|
+
?.agentMaxConcurrent}
|
|
368
|
+
configSubagentMaxConcurrent=${workspaceConfig.concurrency
|
|
369
|
+
?.subagentMaxConcurrent}
|
|
370
|
+
debugEnabled=${workspaceConfig.debugEnabled}
|
|
371
|
+
onResetOnboarding=${resetOnboarding}
|
|
372
|
+
/>
|
|
373
|
+
`
|
|
374
|
+
: html`
|
|
375
|
+
<${MultiGroupView}
|
|
376
|
+
accountId=${accountId}
|
|
377
|
+
groups=${workspaceConfig.groups}
|
|
378
|
+
concurrency=${workspaceConfig.concurrency}
|
|
379
|
+
debugEnabled=${workspaceConfig.debugEnabled}
|
|
380
|
+
onResetOnboarding=${resetOnboarding}
|
|
381
|
+
/>
|
|
382
|
+
`}
|
|
285
383
|
`
|
|
286
384
|
: html`
|
|
287
385
|
<div class="flex items-center justify-between mb-4">
|
|
@@ -305,6 +403,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
305
403
|
${step === 0 &&
|
|
306
404
|
html`
|
|
307
405
|
<${VerifyBotStep}
|
|
406
|
+
accountId=${accountId}
|
|
308
407
|
botInfo=${botInfo}
|
|
309
408
|
setBotInfo=${setBotInfo}
|
|
310
409
|
onNext=${goNext}
|
|
@@ -317,6 +416,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
317
416
|
${step === 2 &&
|
|
318
417
|
html`
|
|
319
418
|
<${AddBotStep}
|
|
419
|
+
accountId=${accountId}
|
|
320
420
|
groupId=${groupId}
|
|
321
421
|
setGroupId=${setGroupId}
|
|
322
422
|
groupInfo=${groupInfo}
|
|
@@ -332,6 +432,7 @@ export const TelegramWorkspace = ({ onBack }) => {
|
|
|
332
432
|
${step === 3 &&
|
|
333
433
|
html`
|
|
334
434
|
<${TopicsStep}
|
|
435
|
+
accountId=${accountId}
|
|
335
436
|
groupId=${groupId}
|
|
336
437
|
topics=${topics}
|
|
337
438
|
setTopics=${setTopics}
|
|
@@ -5,10 +5,25 @@ import { showToast } from "../toast.js";
|
|
|
5
5
|
import { ActionButton } from "../action-button.js";
|
|
6
6
|
import { ConfirmDialog } from "../confirm-dialog.js";
|
|
7
7
|
import * as api from "../../lib/telegram-api.js";
|
|
8
|
+
import { fetchAgents } from "../../lib/api.js";
|
|
8
9
|
|
|
9
10
|
const html = htm.bind(h);
|
|
10
11
|
|
|
12
|
+
const AgentSelect = ({ value, agents, onChange, className = "" }) => html`
|
|
13
|
+
<select
|
|
14
|
+
value=${value}
|
|
15
|
+
onChange=${(e) => onChange(e.target.value)}
|
|
16
|
+
class="bg-black/30 border border-border rounded-lg px-2 py-1.5 text-xs text-gray-200 focus:outline-none focus:border-gray-500 ${className}"
|
|
17
|
+
>
|
|
18
|
+
<option value="">Default</option>
|
|
19
|
+
${agents.map(
|
|
20
|
+
(a) => html`<option value=${a.id}>${a.name || a.id}</option>`,
|
|
21
|
+
)}
|
|
22
|
+
</select>
|
|
23
|
+
`;
|
|
24
|
+
|
|
11
25
|
export const ManageTelegramWorkspace = ({
|
|
26
|
+
accountId,
|
|
12
27
|
groupId,
|
|
13
28
|
groupName,
|
|
14
29
|
initialTopics,
|
|
@@ -20,18 +35,21 @@ export const ManageTelegramWorkspace = ({
|
|
|
20
35
|
const [topics, setTopics] = useState(initialTopics || {});
|
|
21
36
|
const [newTopicName, setNewTopicName] = useState("");
|
|
22
37
|
const [newTopicInstructions, setNewTopicInstructions] = useState("");
|
|
38
|
+
const [newTopicAgentId, setNewTopicAgentId] = useState("");
|
|
23
39
|
const [showCreateTopic, setShowCreateTopic] = useState(false);
|
|
24
40
|
const [creating, setCreating] = useState(false);
|
|
25
41
|
const [deleting, setDeleting] = useState(null);
|
|
26
42
|
const [editingTopicId, setEditingTopicId] = useState("");
|
|
27
43
|
const [editingTopicName, setEditingTopicName] = useState("");
|
|
28
44
|
const [editingTopicInstructions, setEditingTopicInstructions] = useState("");
|
|
45
|
+
const [editingTopicAgentId, setEditingTopicAgentId] = useState("");
|
|
29
46
|
const [renamingTopicId, setRenamingTopicId] = useState("");
|
|
30
47
|
const [error, setError] = useState(null);
|
|
31
48
|
const [deleteTopicConfirm, setDeleteTopicConfirm] = useState(null);
|
|
49
|
+
const [agents, setAgents] = useState([]);
|
|
32
50
|
|
|
33
51
|
const loadTopics = async () => {
|
|
34
|
-
const data = await api.listTopics(groupId);
|
|
52
|
+
const data = await api.listTopics(groupId, { accountId });
|
|
35
53
|
if (data.ok) setTopics(data.topics || {});
|
|
36
54
|
};
|
|
37
55
|
|
|
@@ -44,22 +62,34 @@ export const ManageTelegramWorkspace = ({
|
|
|
44
62
|
}
|
|
45
63
|
}, [initialTopics]);
|
|
46
64
|
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
fetchAgents()
|
|
67
|
+
.then((data) => setAgents(Array.isArray(data?.agents) ? data.agents : []))
|
|
68
|
+
.catch(() => {});
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
47
71
|
const createSingle = async () => {
|
|
48
72
|
const name = newTopicName.trim();
|
|
49
73
|
const systemInstructions = newTopicInstructions.trim();
|
|
74
|
+
const agentId = newTopicAgentId.trim();
|
|
50
75
|
if (!name) return;
|
|
51
76
|
setCreating(true);
|
|
52
77
|
setError(null);
|
|
53
78
|
try {
|
|
54
79
|
const data = await api.createTopicsBulk(groupId, [
|
|
55
|
-
{
|
|
56
|
-
|
|
80
|
+
{
|
|
81
|
+
name,
|
|
82
|
+
...(systemInstructions ? { systemInstructions } : {}),
|
|
83
|
+
...(agentId ? { agentId } : {}),
|
|
84
|
+
},
|
|
85
|
+
], { accountId });
|
|
57
86
|
if (!data.ok)
|
|
58
87
|
throw new Error(data.results?.[0]?.error || "Failed to create topic");
|
|
59
88
|
const failed = data.results.filter((r) => !r.ok);
|
|
60
89
|
if (failed.length > 0) throw new Error(failed[0].error);
|
|
61
90
|
setNewTopicName("");
|
|
62
91
|
setNewTopicInstructions("");
|
|
92
|
+
setNewTopicAgentId("");
|
|
63
93
|
setShowCreateTopic(false);
|
|
64
94
|
await loadTopics();
|
|
65
95
|
showToast(`Created topic: ${name}`, "success");
|
|
@@ -72,7 +102,7 @@ export const ManageTelegramWorkspace = ({
|
|
|
72
102
|
const handleDelete = async (topicId, topicName) => {
|
|
73
103
|
setDeleting(topicId);
|
|
74
104
|
try {
|
|
75
|
-
const data = await api.deleteTopic(groupId, topicId);
|
|
105
|
+
const data = await api.deleteTopic(groupId, topicId, { accountId });
|
|
76
106
|
if (!data.ok) throw new Error(data.error);
|
|
77
107
|
await loadTopics();
|
|
78
108
|
if (data.removedFromRegistryOnly) {
|
|
@@ -86,21 +116,24 @@ export const ManageTelegramWorkspace = ({
|
|
|
86
116
|
setDeleting(null);
|
|
87
117
|
};
|
|
88
118
|
|
|
89
|
-
const startRename = (topicId, topicName, topicInstructions = "") => {
|
|
119
|
+
const startRename = (topicId, topicName, topicInstructions = "", topicAgentId = "") => {
|
|
90
120
|
setEditingTopicId(String(topicId));
|
|
91
121
|
setEditingTopicName(String(topicName || ""));
|
|
92
122
|
setEditingTopicInstructions(String(topicInstructions || ""));
|
|
123
|
+
setEditingTopicAgentId(String(topicAgentId || ""));
|
|
93
124
|
};
|
|
94
125
|
|
|
95
126
|
const cancelRename = () => {
|
|
96
127
|
setEditingTopicId("");
|
|
97
128
|
setEditingTopicName("");
|
|
98
129
|
setEditingTopicInstructions("");
|
|
130
|
+
setEditingTopicAgentId("");
|
|
99
131
|
};
|
|
100
132
|
|
|
101
133
|
const saveRename = async (topicId) => {
|
|
102
134
|
const nextName = editingTopicName.trim();
|
|
103
135
|
const nextSystemInstructions = editingTopicInstructions.trim();
|
|
136
|
+
const nextAgentId = editingTopicAgentId.trim();
|
|
104
137
|
if (!nextName) {
|
|
105
138
|
setError("Topic name is required");
|
|
106
139
|
return;
|
|
@@ -111,10 +144,11 @@ export const ManageTelegramWorkspace = ({
|
|
|
111
144
|
const data = await api.updateTopic(groupId, topicId, {
|
|
112
145
|
name: nextName,
|
|
113
146
|
systemInstructions: nextSystemInstructions,
|
|
114
|
-
|
|
115
|
-
|
|
147
|
+
agentId: nextAgentId,
|
|
148
|
+
}, { accountId });
|
|
149
|
+
if (!data.ok) throw new Error(data.error || "Failed to update topic");
|
|
116
150
|
await loadTopics();
|
|
117
|
-
showToast(`
|
|
151
|
+
showToast(`Updated topic: ${nextName}`, "success");
|
|
118
152
|
cancelRename();
|
|
119
153
|
} catch (e) {
|
|
120
154
|
setError(e.message);
|
|
@@ -169,6 +203,14 @@ export const ManageTelegramWorkspace = ({
|
|
|
169
203
|
>
|
|
170
204
|
Thread ID
|
|
171
205
|
</th>
|
|
206
|
+
${agents.length > 0 &&
|
|
207
|
+
html`
|
|
208
|
+
<th
|
|
209
|
+
class="text-left px-3 py-2 text-gray-500 font-medium w-32"
|
|
210
|
+
>
|
|
211
|
+
Agent
|
|
212
|
+
</th>
|
|
213
|
+
`}
|
|
172
214
|
<th class="px-3 py-2 w-28" />
|
|
173
215
|
</tr>
|
|
174
216
|
</thead>
|
|
@@ -180,7 +222,7 @@ export const ManageTelegramWorkspace = ({
|
|
|
180
222
|
<tr
|
|
181
223
|
class="border-b border-border last:border-0 align-top"
|
|
182
224
|
>
|
|
183
|
-
<td class="px-3 py-2" colspan
|
|
225
|
+
<td class="px-3 py-2" colspan=${agents.length > 0 ? 4 : 3}>
|
|
184
226
|
<div class="space-y-2">
|
|
185
227
|
<input
|
|
186
228
|
type="text"
|
|
@@ -203,6 +245,17 @@ export const ManageTelegramWorkspace = ({
|
|
|
203
245
|
rows="6"
|
|
204
246
|
class="w-full bg-black/30 border border-border rounded-lg px-2 py-1.5 text-xs text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-500 resize-y"
|
|
205
247
|
/>
|
|
248
|
+
${agents.length > 0 &&
|
|
249
|
+
html`
|
|
250
|
+
<div class="flex items-center gap-2">
|
|
251
|
+
<label class="text-xs text-gray-500">Agent:</label>
|
|
252
|
+
<${AgentSelect}
|
|
253
|
+
value=${editingTopicAgentId}
|
|
254
|
+
agents=${agents}
|
|
255
|
+
onChange=${setEditingTopicAgentId}
|
|
256
|
+
/>
|
|
257
|
+
</div>
|
|
258
|
+
`}
|
|
206
259
|
<div class="flex items-center gap-2">
|
|
207
260
|
<button
|
|
208
261
|
onclick=${() => saveRename(id)}
|
|
@@ -239,10 +292,11 @@ export const ManageTelegramWorkspace = ({
|
|
|
239
292
|
id,
|
|
240
293
|
topic.name,
|
|
241
294
|
topic.systemInstructions,
|
|
295
|
+
topic.agentId,
|
|
242
296
|
)}
|
|
243
297
|
class="inline-flex items-center justify-center text-white/80 hover:text-white transition-colors"
|
|
244
298
|
title="Edit topic"
|
|
245
|
-
aria-label="
|
|
299
|
+
aria-label="Edit topic"
|
|
246
300
|
>
|
|
247
301
|
<svg
|
|
248
302
|
width="14"
|
|
@@ -271,6 +325,14 @@ export const ManageTelegramWorkspace = ({
|
|
|
271
325
|
>
|
|
272
326
|
${id}
|
|
273
327
|
</td>
|
|
328
|
+
${agents.length > 0 &&
|
|
329
|
+
html`
|
|
330
|
+
<td class="px-3 py-2 text-gray-400 w-32">
|
|
331
|
+
${topic.agentId
|
|
332
|
+
? html`<span class="text-gray-300">${agents.find((a) => a.id === topic.agentId)?.name || topic.agentId}</span>`
|
|
333
|
+
: html`<span class="text-gray-600">default</span>`}
|
|
334
|
+
</td>
|
|
335
|
+
`}
|
|
274
336
|
<td class="px-3 py-2">
|
|
275
337
|
<div
|
|
276
338
|
class="flex items-center gap-2 justify-end"
|
|
@@ -325,6 +387,17 @@ export const ManageTelegramWorkspace = ({
|
|
|
325
387
|
rows="5"
|
|
326
388
|
class="w-full bg-black/30 border border-border rounded-lg px-3 py-2 text-sm text-gray-200 placeholder-gray-600 focus:outline-none focus:border-gray-500 resize-y"
|
|
327
389
|
/>
|
|
390
|
+
${agents.length > 0 &&
|
|
391
|
+
html`
|
|
392
|
+
<div class="flex items-center gap-2">
|
|
393
|
+
<label class="text-xs text-gray-500">Agent:</label>
|
|
394
|
+
<${AgentSelect}
|
|
395
|
+
value=${newTopicAgentId}
|
|
396
|
+
agents=${agents}
|
|
397
|
+
onChange=${setNewTopicAgentId}
|
|
398
|
+
/>
|
|
399
|
+
</div>
|
|
400
|
+
`}
|
|
328
401
|
<div class="flex justify-end">
|
|
329
402
|
<${ActionButton}
|
|
330
403
|
onClick=${createSingle}
|
|
@@ -25,7 +25,7 @@ export const StepIndicator = ({ currentStep, steps }) => html`
|
|
|
25
25
|
`;
|
|
26
26
|
|
|
27
27
|
// Step 1: Verify Bot
|
|
28
|
-
export const VerifyBotStep = ({ botInfo, setBotInfo, onNext }) => {
|
|
28
|
+
export const VerifyBotStep = ({ accountId, botInfo, setBotInfo, onNext }) => {
|
|
29
29
|
const [loading, setLoading] = useState(false);
|
|
30
30
|
const [error, setError] = useState(null);
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ export const VerifyBotStep = ({ botInfo, setBotInfo, onNext }) => {
|
|
|
33
33
|
setLoading(true);
|
|
34
34
|
setError(null);
|
|
35
35
|
try {
|
|
36
|
-
const data = await api.verifyBot();
|
|
36
|
+
const data = await api.verifyBot({ accountId });
|
|
37
37
|
if (!data.ok) throw new Error(data.error);
|
|
38
38
|
setBotInfo(data.bot);
|
|
39
39
|
} catch (e) {
|
|
@@ -180,6 +180,7 @@ export const CreateGroupStep = ({ onNext, onBack }) => html`
|
|
|
180
180
|
|
|
181
181
|
// Step 3: Add Bot to Group / Verify Group
|
|
182
182
|
export const AddBotStep = ({
|
|
183
|
+
accountId,
|
|
183
184
|
groupId,
|
|
184
185
|
setGroupId,
|
|
185
186
|
groupInfo,
|
|
@@ -216,7 +217,7 @@ export const AddBotStep = ({
|
|
|
216
217
|
setLoading(true);
|
|
217
218
|
setVerifyGroupError(null);
|
|
218
219
|
try {
|
|
219
|
-
const data = await api.verifyGroup(id);
|
|
220
|
+
const data = await api.verifyGroup(id, { accountId });
|
|
220
221
|
if (!data.ok) throw new Error(data.error);
|
|
221
222
|
setGroupId(id);
|
|
222
223
|
setGroupInfo(data);
|
|
@@ -245,7 +246,7 @@ export const AddBotStep = ({
|
|
|
245
246
|
...(userIdValue ? { userId: userIdValue } : {}),
|
|
246
247
|
groupName: groupInfo?.chat?.title || groupId,
|
|
247
248
|
requireMention: false,
|
|
248
|
-
});
|
|
249
|
+
}, { accountId });
|
|
249
250
|
if (!data?.ok)
|
|
250
251
|
throw new Error(data?.error || "Failed to configure Telegram group");
|
|
251
252
|
if (data.userId) setUserId(String(data.userId));
|
|
@@ -370,7 +371,7 @@ export const AddBotStep = ({
|
|
|
370
371
|
};
|
|
371
372
|
|
|
372
373
|
// Step 4: Create Topics
|
|
373
|
-
export const TopicsStep = ({ groupId, topics, setTopics, onNext, onBack }) => {
|
|
374
|
+
export const TopicsStep = ({ accountId, groupId, topics, setTopics, onNext, onBack }) => {
|
|
374
375
|
const [newTopicName, setNewTopicName] = useState("");
|
|
375
376
|
const [newTopicInstructions, setNewTopicInstructions] = useState("");
|
|
376
377
|
const [creating, setCreating] = useState(false);
|
|
@@ -379,7 +380,7 @@ export const TopicsStep = ({ groupId, topics, setTopics, onNext, onBack }) => {
|
|
|
379
380
|
const [deleteTopicConfirm, setDeleteTopicConfirm] = useState(null);
|
|
380
381
|
|
|
381
382
|
const loadTopics = async () => {
|
|
382
|
-
const data = await api.listTopics(groupId);
|
|
383
|
+
const data = await api.listTopics(groupId, { accountId });
|
|
383
384
|
if (data.ok) setTopics(data.topics);
|
|
384
385
|
};
|
|
385
386
|
|
|
@@ -396,7 +397,7 @@ export const TopicsStep = ({ groupId, topics, setTopics, onNext, onBack }) => {
|
|
|
396
397
|
try {
|
|
397
398
|
const data = await api.createTopicsBulk(groupId, [
|
|
398
399
|
{ name, ...(systemInstructions ? { systemInstructions } : {}) },
|
|
399
|
-
]);
|
|
400
|
+
], { accountId });
|
|
400
401
|
if (!data.ok)
|
|
401
402
|
throw new Error(data.results?.[0]?.error || "Failed to create topic");
|
|
402
403
|
const failed = data.results.filter((r) => !r.ok);
|
|
@@ -414,7 +415,7 @@ export const TopicsStep = ({ groupId, topics, setTopics, onNext, onBack }) => {
|
|
|
414
415
|
const handleDelete = async (topicId, topicName) => {
|
|
415
416
|
setDeleting(topicId);
|
|
416
417
|
try {
|
|
417
|
-
const data = await api.deleteTopic(groupId, topicId);
|
|
418
|
+
const data = await api.deleteTopic(groupId, topicId, { accountId });
|
|
418
419
|
if (!data.ok) throw new Error(data.error);
|
|
419
420
|
await loadTopics();
|
|
420
421
|
if (data.removedFromRegistryOnly) {
|