bazilion 0.5.0 → 0.6.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/README.md +14 -9
- package/dist/cli.js +365 -140
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +4452 -16989
- package/dist/daemon.js.map +1 -1
- package/dist/web/client/assets/AgentAvatar-Cq7PVBE_.js +1 -0
- package/dist/web/client/assets/AgentTabs-M5K8emJ8.js +1 -0
- package/dist/web/client/assets/Button-BefUtjMZ.js +1 -0
- package/dist/web/client/assets/ChatPane-C8zQfpzH.js +74 -0
- package/dist/web/client/assets/ConfigTabs-DRqAymcN.js +1 -0
- package/dist/web/client/assets/FieldRow-BqWnxZiX.js +1 -0
- package/dist/web/client/assets/MembersEditor-B-47GLUb.js +1 -0
- package/dist/web/client/assets/SpawnTeamModal-DiiC7Nc0.js +1 -0
- package/dist/web/client/assets/TemplatesTabs-DB4KERTQ.js +1 -0
- package/dist/web/client/assets/_id-B7gv1aPQ.js +1 -0
- package/dist/web/client/assets/_id-C7d1AqS0.js +1 -0
- package/dist/web/client/assets/_id-DhiwjC8u.js +1 -0
- package/dist/web/client/assets/_id-p8lUuNFm.js +1 -0
- package/dist/web/client/assets/agents-v8G-wt0M.js +1 -0
- package/dist/web/client/assets/config-BdmYpS_y.js +3 -0
- package/dist/web/client/assets/groups-DiY_ExGM.js +1 -0
- package/dist/web/client/assets/inbox-DtfVx246.js +1 -0
- package/dist/web/client/assets/index-BQUL6oyH.js +12 -0
- package/dist/web/client/assets/login-CVS70W9g.js +1 -0
- package/dist/web/client/assets/mcp-BDLQq8OZ.js +1 -0
- package/dist/web/client/assets/memory-6GGuAXwx.js +1 -0
- package/dist/web/client/assets/profile-groups-BA8rwZMA.js +1 -0
- package/dist/web/client/assets/profiles-C0aAcPZg.js +1 -0
- package/dist/web/client/assets/routes-DgAhnKFw.js +1 -0
- package/dist/web/client/assets/services-BZ86QEah.js +1 -0
- package/dist/web/client/assets/skills-mv_NNNwo.js +1 -0
- package/dist/web/client/assets/styles-CmqUskDu.css +2 -0
- package/dist/web/client/assets/telegram-5f9WXs3x.js +1 -0
- package/dist/web/client/assets/tokens-DHiYsFUh.js +1 -0
- package/dist/web/client/assets/triggers-CjC8Ljrz.js +1 -0
- package/dist/web/client/assets/welcome-C-Cu-ziL.js +1 -0
- package/dist/web/client/assets/wire-constants-BkT5-597.js +1 -0
- package/dist/web/client/baziu.svg +8 -0
- package/dist/web/server/assets/AgentAvatar-8gTAy_tP.js +37 -0
- package/dist/web/server/assets/AgentTabs-BOjTN7QF.js +34 -0
- package/dist/web/server/assets/Button-Dsnw22OF.js +17 -0
- package/dist/web/server/assets/ChatPane-BvpswYvF.js +1084 -0
- package/dist/web/server/assets/ConfigTabs-CyuxzesF.js +41 -0
- package/dist/web/server/assets/FieldRow-DwyqycWI.js +94 -0
- package/dist/web/server/assets/MembersEditor-BWQztvrX.js +131 -0
- package/dist/web/server/assets/Sidebar-DmEiewRN.js +529 -0
- package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +107 -0
- package/dist/web/server/assets/TemplatesTabs---7h5GYa.js +30 -0
- package/dist/web/server/assets/_id-BZ-YCWSw.js +16 -0
- package/dist/web/server/assets/_id-Bm4-_AP-.js +367 -0
- package/dist/web/server/assets/_id-C78M9_j9.js +12 -0
- package/dist/web/server/assets/_id-CGZbudCl.js +28 -0
- package/dist/web/server/assets/_id-CHNm7EAd.js +161 -0
- package/dist/web/server/assets/_id-CrQbC5L8.js +16 -0
- package/dist/web/server/assets/_id-Crcw2HhT.js +38 -0
- package/dist/web/server/assets/_id-CvIGhq4U.js +16 -0
- package/dist/web/server/assets/_id-DF3pfi9M.js +27 -0
- package/dist/web/server/assets/_id-Dc8P9sy2.js +24 -0
- package/dist/web/server/assets/_id-GJk3EYTT.js +662 -0
- package/dist/web/server/assets/_id-pd4S7LTi.js +467 -0
- package/dist/web/server/assets/_tanstack-start-manifest_v-CPyKYMJg.js +174 -0
- package/dist/web/server/assets/agents-70EwQJR6.js +210 -0
- package/dist/web/server/assets/agents-Ds4lcREv.js +26 -0
- package/dist/web/server/assets/agents-K4Smhnq3.js +14 -0
- package/dist/web/server/assets/auth-DpAGLHpA.js +26 -0
- package/dist/web/server/assets/config-CMXUx_IF.js +19 -0
- package/dist/web/server/assets/config-DQbCsY_l.js +382 -0
- package/dist/web/server/assets/config-DxCGYgR9.js +12 -0
- package/dist/web/server/assets/createServerRpc-CBTntoKx.js +12 -0
- package/dist/web/server/assets/createSsrRpc-DHBVUN8O.js +16 -0
- package/dist/web/server/assets/daemon-client-2NRMzlTr.js +96 -0
- package/dist/web/server/assets/empty-plugin-adapters-Bos_V2s-.js +5 -0
- package/dist/web/server/assets/groups-CXVew7BP.js +150 -0
- package/dist/web/server/assets/groups-Cms8cvH5.js +12 -0
- package/dist/web/server/assets/groups-Dmcvw5ya.js +21 -0
- package/dist/web/server/assets/inbox-0QfwsrGo.js +27 -0
- package/dist/web/server/assets/inbox-8HybA2Ws.js +133 -0
- package/dist/web/server/assets/inbox-B7UWoICA.js +42 -0
- package/dist/web/server/assets/login-CNznncgA.js +58 -0
- package/dist/web/server/assets/login-CQybKk7Y.js +74 -0
- package/dist/web/server/assets/mcp-42BrkI1I.js +12 -0
- package/dist/web/server/assets/mcp-DIa0kIOf.js +268 -0
- package/dist/web/server/assets/mcp-DsTjY3uz.js +12 -0
- package/dist/web/server/assets/memory-BfrMp8iY.js +284 -0
- package/dist/web/server/assets/memory-Dr0lOM2y.js +28 -0
- package/dist/web/server/assets/memory-EEgLDfCj.js +16 -0
- package/dist/web/server/assets/profile-groups-BW5gU-fG.js +12 -0
- package/dist/web/server/assets/profile-groups-B_kIT6BU.js +208 -0
- package/dist/web/server/assets/profile-groups-C5isDI2t.js +28 -0
- package/dist/web/server/assets/profiles-BP1v-jna.js +453 -0
- package/dist/web/server/assets/profiles-BbPTpmyq.js +26 -0
- package/dist/web/server/assets/profiles-Cy5auEj8.js +12 -0
- package/dist/web/server/assets/router-CL100-Ly.js +460 -0
- package/dist/web/server/assets/routes-CzJLQxcS.js +14 -0
- package/dist/web/server/assets/routes-D2H1Hnoh.js +57 -0
- package/dist/web/server/assets/routes-Dzk8jvIo.js +33 -0
- package/dist/web/server/assets/services-Bgj6M2gC.js +12 -0
- package/dist/web/server/assets/services-DEgYsWJ4.js +17 -0
- package/dist/web/server/assets/services-DFenjiw0.js +94 -0
- package/dist/web/server/assets/skills-BASIP_rT.js +12 -0
- package/dist/web/server/assets/skills-C-JPRCHh.js +12 -0
- package/dist/web/server/assets/skills-DZXN680t.js +261 -0
- package/dist/web/server/assets/start-cOXH7eTI.js +4 -0
- package/dist/web/server/assets/telegram-BbvqVWxa.js +583 -0
- package/dist/web/server/assets/telegram-Bq49AtnP.js +12 -0
- package/dist/web/server/assets/telegram-sUckI94O.js +12 -0
- package/dist/web/server/assets/tokens-BERRE0wB.js +14 -0
- package/dist/web/server/assets/tokens-CImgxhDI.js +193 -0
- package/dist/web/server/assets/tokens-Dwn00iV7.js +12 -0
- package/dist/web/server/assets/triggers-DtexqbNH.js +16 -0
- package/dist/web/server/assets/triggers-TyIjwSYn.js +26 -0
- package/dist/web/server/assets/triggers-_iSeahif.js +191 -0
- package/dist/web/server/assets/welcome-BkQ9NC5K.js +81 -0
- package/dist/web/server/assets/wire-constants-Deb4NxBb.js +16 -0
- package/dist/web/server/server.js +5899 -0
- package/dist/web-server.js +42 -0
- package/dist/web-server.js.map +1 -0
- package/package.json +10 -4
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { t as createServerFn } from "../server.js";
|
|
2
|
+
import { t as createServerRpc } from "./createServerRpc-CBTntoKx.js";
|
|
3
|
+
import { n as daemonClient } from "./daemon-client-2NRMzlTr.js";
|
|
4
|
+
//#region src/routes/profile-groups/$id.tsx?tss-serverfn-split
|
|
5
|
+
var fetchDetail_createServerFn_handler = createServerRpc({
|
|
6
|
+
id: "86dad0c33c97a6f0913d1f38e9b01ac4144f7d0970b45fdb3470e9bc9a78e0e0",
|
|
7
|
+
name: "fetchDetail",
|
|
8
|
+
filename: "src/routes/profile-groups/$id.tsx"
|
|
9
|
+
}, (opts) => fetchDetail.__executeServer(opts));
|
|
10
|
+
var fetchDetail = createServerFn({ method: "POST" }).inputValidator((d) => d).handler(fetchDetail_createServerFn_handler, async ({ data }) => {
|
|
11
|
+
const c = daemonClient();
|
|
12
|
+
const [detail, profiles, models] = await Promise.all([
|
|
13
|
+
c.get(`/api/profile-groups/${encodeURIComponent(data.id)}`),
|
|
14
|
+
c.get("/api/profiles"),
|
|
15
|
+
c.get("/api/config/available-models")
|
|
16
|
+
]);
|
|
17
|
+
return {
|
|
18
|
+
detail,
|
|
19
|
+
profiles,
|
|
20
|
+
modelGroups: models.groups
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { fetchDetail_createServerFn_handler };
|
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
import { t as Route } from "./_id-CvIGhq4U.js";
|
|
2
|
+
import { t as AgentTabs } from "./AgentTabs-BOjTN7QF.js";
|
|
3
|
+
import { t as AgentAvatar } from "./AgentAvatar-8gTAy_tP.js";
|
|
4
|
+
import { t as ChatPane } from "./ChatPane-BvpswYvF.js";
|
|
5
|
+
import { r as REASONING_LEVELS } from "./wire-constants-Deb4NxBb.js";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { useRouter } from "@tanstack/react-router";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/CopyButton.tsx
|
|
10
|
+
function CopyButton({ value, className, ariaLabel = "Copy to clipboard", title = "Copy to clipboard" }) {
|
|
11
|
+
const [copied, setCopied] = useState(false);
|
|
12
|
+
async function copy() {
|
|
13
|
+
if (!value) return;
|
|
14
|
+
let ok = false;
|
|
15
|
+
try {
|
|
16
|
+
if (navigator.clipboard?.writeText) {
|
|
17
|
+
await navigator.clipboard.writeText(value);
|
|
18
|
+
ok = true;
|
|
19
|
+
}
|
|
20
|
+
} catch {}
|
|
21
|
+
if (!ok) {
|
|
22
|
+
const ta = document.createElement("textarea");
|
|
23
|
+
ta.value = value;
|
|
24
|
+
ta.setAttribute("readonly", "");
|
|
25
|
+
ta.style.position = "fixed";
|
|
26
|
+
ta.style.opacity = "0";
|
|
27
|
+
document.body.appendChild(ta);
|
|
28
|
+
ta.select();
|
|
29
|
+
try {
|
|
30
|
+
ok = document.execCommand("copy");
|
|
31
|
+
} catch {}
|
|
32
|
+
ta.remove();
|
|
33
|
+
}
|
|
34
|
+
if (ok) {
|
|
35
|
+
setCopied(true);
|
|
36
|
+
setTimeout(() => setCopied(false), 1e3);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ jsx("button", {
|
|
40
|
+
type: "button",
|
|
41
|
+
onClick: copy,
|
|
42
|
+
title,
|
|
43
|
+
"aria-label": ariaLabel,
|
|
44
|
+
className: `inline-flex h-[1.3rem] w-[1.6rem] items-center justify-center rounded-sm border border-transparent text-mocha-light transition-colors hover:border-frost hover:bg-snow hover:text-mocha ${copied ? "border-[#bcd9bc] bg-[#eef7ee] text-[#3b7a3b] hover:border-[#bcd9bc] hover:bg-[#eef7ee] hover:text-[#3b7a3b]" : ""} ${className ?? ""}`,
|
|
45
|
+
children: copied ? "✓" : "⧉"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/routes/agents/$id/index.tsx?tsr-split=component
|
|
50
|
+
function AgentDetailPage() {
|
|
51
|
+
const { resolved, initialMessages, sessionHead, groups, skills, modelGroups, telegramConfigured } = Route.useLoaderData();
|
|
52
|
+
const router = useRouter();
|
|
53
|
+
async function archive() {
|
|
54
|
+
if (!confirm(`archive "${resolved.agent.name}"? (reversible)`)) return;
|
|
55
|
+
await fetch(`/api/agents/${resolved.agent.id}/archive`, { method: "POST" });
|
|
56
|
+
await router.invalidate();
|
|
57
|
+
}
|
|
58
|
+
async function unarchive() {
|
|
59
|
+
await fetch(`/api/agents/${resolved.agent.id}/unarchive`, { method: "POST" });
|
|
60
|
+
await router.invalidate();
|
|
61
|
+
}
|
|
62
|
+
async function del() {
|
|
63
|
+
const msg = `Permanently delete agent "${resolved.agent.name}"?\n\nThis removes the DB rows (messages, triggers, skill attachments) AND the agent's on-disk directory (memory, templates, state, sessions). This cannot be undone.`;
|
|
64
|
+
if (!confirm(msg)) return;
|
|
65
|
+
const res = await fetch(`/api/agents/${resolved.agent.id}`, { method: "DELETE" });
|
|
66
|
+
if (res.ok || res.status === 204) window.location.assign("/agents");
|
|
67
|
+
else alert(`failed: ${res.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("header", {
|
|
71
|
+
className: "mb-8",
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsxs("div", {
|
|
74
|
+
className: "flex items-center gap-3",
|
|
75
|
+
children: [/* @__PURE__ */ jsx(AgentAvatar, {
|
|
76
|
+
identity: resolved.agent.identity,
|
|
77
|
+
size: 44
|
|
78
|
+
}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h1", {
|
|
79
|
+
className: "mb-0",
|
|
80
|
+
children: resolved.agent.name
|
|
81
|
+
}), (resolved.agent.identity?.creature || resolved.agent.identity?.vibe) && /* @__PURE__ */ jsx("p", {
|
|
82
|
+
className: "muted mt-0.5 text-sm",
|
|
83
|
+
children: [resolved.agent.identity?.creature, resolved.agent.identity?.vibe].filter(Boolean).join(" · ")
|
|
84
|
+
})] })]
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ jsxs("div", {
|
|
87
|
+
className: "mt-2 flex flex-wrap items-center gap-x-5 gap-y-2",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsxs(Tag, { children: [/* @__PURE__ */ jsx("span", {
|
|
90
|
+
className: "px-1.5 font-mono text-[0.95em] text-mocha select-all",
|
|
91
|
+
children: resolved.agent.id
|
|
92
|
+
}), /* @__PURE__ */ jsx(CopyButton, {
|
|
93
|
+
value: resolved.agent.id,
|
|
94
|
+
ariaLabel: "Copy agent UUID",
|
|
95
|
+
title: "Copy UUID to clipboard"
|
|
96
|
+
})] }),
|
|
97
|
+
/* @__PURE__ */ jsxs(Tag, { children: ["status: ", /* @__PURE__ */ jsx("span", {
|
|
98
|
+
className: "ml-1",
|
|
99
|
+
children: resolved.agent.status
|
|
100
|
+
})] }),
|
|
101
|
+
/* @__PURE__ */ jsxs(Tag, { children: ["profile: ", /* @__PURE__ */ jsx("code", {
|
|
102
|
+
className: "ml-1 bg-transparent px-0",
|
|
103
|
+
children: resolved.profile.id
|
|
104
|
+
})] }),
|
|
105
|
+
/* @__PURE__ */ jsxs(Tag, { children: [
|
|
106
|
+
"group:",
|
|
107
|
+
" ",
|
|
108
|
+
/* @__PURE__ */ jsx("a", {
|
|
109
|
+
href: `/groups/${encodeURIComponent(resolved.group.id)}`,
|
|
110
|
+
className: "ml-1 bg-transparent px-0 font-mono underline",
|
|
111
|
+
children: resolved.group.id
|
|
112
|
+
}),
|
|
113
|
+
" ",
|
|
114
|
+
"·",
|
|
115
|
+
" ",
|
|
116
|
+
/* @__PURE__ */ jsx("a", {
|
|
117
|
+
href: `/groups/${encodeURIComponent(resolved.group.id)}/memory`,
|
|
118
|
+
className: "ml-0.5 underline",
|
|
119
|
+
children: "shared memory →"
|
|
120
|
+
})
|
|
121
|
+
] }),
|
|
122
|
+
/* @__PURE__ */ jsxs(Tag, { children: ["model: ", /* @__PURE__ */ jsx("code", {
|
|
123
|
+
className: "ml-1 bg-transparent px-0",
|
|
124
|
+
children: resolved.model
|
|
125
|
+
})] }),
|
|
126
|
+
/* @__PURE__ */ jsxs(Tag, { children: [
|
|
127
|
+
"reasoning:",
|
|
128
|
+
" ",
|
|
129
|
+
/* @__PURE__ */ jsx("code", {
|
|
130
|
+
className: "ml-1 bg-transparent px-0",
|
|
131
|
+
children: resolved.reasoningLevel
|
|
132
|
+
})
|
|
133
|
+
] })
|
|
134
|
+
]
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ jsxs("div", {
|
|
137
|
+
className: "mt-3 flex flex-wrap gap-2",
|
|
138
|
+
children: [resolved.agent.status === "archived" ? /* @__PURE__ */ jsx("button", {
|
|
139
|
+
type: "button",
|
|
140
|
+
onClick: unarchive,
|
|
141
|
+
className: "ghost-btn",
|
|
142
|
+
children: "unarchive"
|
|
143
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
144
|
+
type: "button",
|
|
145
|
+
onClick: archive,
|
|
146
|
+
className: "ghost-btn",
|
|
147
|
+
children: "archive"
|
|
148
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
149
|
+
type: "button",
|
|
150
|
+
onClick: del,
|
|
151
|
+
className: "ghost-btn border-[rgba(196,135,138,0.4)] text-[#9B3D3D] hover:bg-[rgba(196,135,138,0.08)]",
|
|
152
|
+
children: "delete permanently"
|
|
153
|
+
})]
|
|
154
|
+
}),
|
|
155
|
+
/* @__PURE__ */ jsx(SettingsDetails, {
|
|
156
|
+
agentId: resolved.agent.id,
|
|
157
|
+
currentModelOverride: resolved.agent.modelOverride ?? null,
|
|
158
|
+
profileDefaultModel: resolved.profile.defaultModel,
|
|
159
|
+
currentReasoning: resolved.reasoningLevel,
|
|
160
|
+
modelGroups
|
|
161
|
+
})
|
|
162
|
+
]
|
|
163
|
+
}),
|
|
164
|
+
resolved.agent.status === "archived" && /* @__PURE__ */ jsxs("div", {
|
|
165
|
+
className: "mb-4 rounded-md border border-frost bg-fawn/35 px-4 py-2 text-[0.9em] text-chocolate",
|
|
166
|
+
children: [
|
|
167
|
+
/* @__PURE__ */ jsx("strong", {
|
|
168
|
+
className: "text-[#7a4e2a]",
|
|
169
|
+
children: "This agent is archived."
|
|
170
|
+
}),
|
|
171
|
+
" It's hidden from the default agent list; use ",
|
|
172
|
+
/* @__PURE__ */ jsx("em", { children: "unarchive" }),
|
|
173
|
+
" above to bring it back, or",
|
|
174
|
+
" ",
|
|
175
|
+
/* @__PURE__ */ jsx("em", { children: "delete permanently" }),
|
|
176
|
+
" to remove its data entirely."
|
|
177
|
+
]
|
|
178
|
+
}),
|
|
179
|
+
/* @__PURE__ */ jsx(AgentTabs, {
|
|
180
|
+
agentId: resolved.agent.id,
|
|
181
|
+
active: "chat",
|
|
182
|
+
archived: resolved.agent.status === "archived"
|
|
183
|
+
}),
|
|
184
|
+
/* @__PURE__ */ jsx(SectionTitle, { children: "Chat" }),
|
|
185
|
+
/* @__PURE__ */ jsx("div", {
|
|
186
|
+
className: "h-[70vh]",
|
|
187
|
+
children: /* @__PURE__ */ jsx(ChatPane, {
|
|
188
|
+
agentId: resolved.agent.id,
|
|
189
|
+
agentName: resolved.agent.name,
|
|
190
|
+
initialMessages,
|
|
191
|
+
initialSessionHead: sessionHead
|
|
192
|
+
})
|
|
193
|
+
}),
|
|
194
|
+
/* @__PURE__ */ jsx("p", {
|
|
195
|
+
className: "mt-2 text-[0.82em] text-mocha-light",
|
|
196
|
+
children: "chat history persists in bazilion across navigation and restarts."
|
|
197
|
+
}),
|
|
198
|
+
/* @__PURE__ */ jsxs("section", {
|
|
199
|
+
className: "mt-10",
|
|
200
|
+
children: [
|
|
201
|
+
/* @__PURE__ */ jsx(SectionTitle, { children: "Group" }),
|
|
202
|
+
/* @__PURE__ */ jsxs("p", {
|
|
203
|
+
className: "text-[0.9em] text-mocha-light",
|
|
204
|
+
children: [
|
|
205
|
+
"Current group: ",
|
|
206
|
+
/* @__PURE__ */ jsx("code", { children: resolved.group.id }),
|
|
207
|
+
" (",
|
|
208
|
+
resolved.group.name,
|
|
209
|
+
") —",
|
|
210
|
+
" ",
|
|
211
|
+
/* @__PURE__ */ jsx("code", { children: resolved.group.path }),
|
|
212
|
+
".",
|
|
213
|
+
" ",
|
|
214
|
+
/* @__PURE__ */ jsx("a", {
|
|
215
|
+
href: `/groups/${resolved.group.id}`,
|
|
216
|
+
children: "view / edit USER.md"
|
|
217
|
+
})
|
|
218
|
+
]
|
|
219
|
+
}),
|
|
220
|
+
/* @__PURE__ */ jsx(MoveGroupForm, {
|
|
221
|
+
agentId: resolved.agent.id,
|
|
222
|
+
currentGroupId: resolved.group.id,
|
|
223
|
+
groups
|
|
224
|
+
})
|
|
225
|
+
]
|
|
226
|
+
}),
|
|
227
|
+
/* @__PURE__ */ jsxs("section", {
|
|
228
|
+
className: "mt-10",
|
|
229
|
+
children: [/* @__PURE__ */ jsx(SectionTitle, { children: "Skills" }), /* @__PURE__ */ jsx(SkillsTable, {
|
|
230
|
+
agentId: resolved.agent.id,
|
|
231
|
+
attached: new Set(resolved.skills),
|
|
232
|
+
all: skills
|
|
233
|
+
})]
|
|
234
|
+
}),
|
|
235
|
+
telegramConfigured && /* @__PURE__ */ jsxs("section", {
|
|
236
|
+
className: "mt-10",
|
|
237
|
+
children: [/* @__PURE__ */ jsx(SectionTitle, { children: "Telegram" }), /* @__PURE__ */ jsx(TelegramSection, { agent: resolved.agent })]
|
|
238
|
+
})
|
|
239
|
+
] });
|
|
240
|
+
}
|
|
241
|
+
function SectionTitle({ children }) {
|
|
242
|
+
return /* @__PURE__ */ jsx("h3", {
|
|
243
|
+
className: "mb-3 font-body text-[0.85em] font-semibold uppercase tracking-wider text-mocha-light",
|
|
244
|
+
children
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function Tag({ children }) {
|
|
248
|
+
return /* @__PURE__ */ jsx("span", {
|
|
249
|
+
className: "inline-flex items-center gap-1 rounded-full border border-frost bg-ivory px-3 py-0.5 text-[0.84em] text-mocha-light",
|
|
250
|
+
children
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
function SettingsDetails({ agentId, currentModelOverride, profileDefaultModel, currentReasoning, modelGroups }) {
|
|
254
|
+
const router = useRouter();
|
|
255
|
+
const [modelOverride, setModelOverride] = useState(currentModelOverride ?? "");
|
|
256
|
+
const [reasoning, setReasoning] = useState(currentReasoning);
|
|
257
|
+
const [saving, setSaving] = useState(false);
|
|
258
|
+
const [savedFlash, setSavedFlash] = useState(false);
|
|
259
|
+
const [error, setError] = useState(null);
|
|
260
|
+
const currentInGroups = currentModelOverride !== null && modelGroups.some((g) => g.models.some((m) => `${g.provider}:${m}` === currentModelOverride));
|
|
261
|
+
async function save(e) {
|
|
262
|
+
e.preventDefault();
|
|
263
|
+
setSaving(true);
|
|
264
|
+
setError(null);
|
|
265
|
+
try {
|
|
266
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}`, {
|
|
267
|
+
method: "PATCH",
|
|
268
|
+
headers: { "content-type": "application/json" },
|
|
269
|
+
body: JSON.stringify({
|
|
270
|
+
modelOverride: modelOverride === "" ? null : modelOverride,
|
|
271
|
+
reasoningLevel: reasoning
|
|
272
|
+
})
|
|
273
|
+
});
|
|
274
|
+
if (!res.ok) {
|
|
275
|
+
const body = await res.json().catch(() => null);
|
|
276
|
+
throw new Error(body?.error ?? res.statusText);
|
|
277
|
+
}
|
|
278
|
+
setSavedFlash(true);
|
|
279
|
+
setTimeout(() => setSavedFlash(false), 1500);
|
|
280
|
+
await router.invalidate();
|
|
281
|
+
} catch (err) {
|
|
282
|
+
setError(err.message);
|
|
283
|
+
} finally {
|
|
284
|
+
setSaving(false);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return /* @__PURE__ */ jsxs("details", {
|
|
288
|
+
className: "mt-3 text-[0.9em]",
|
|
289
|
+
children: [/* @__PURE__ */ jsx("summary", {
|
|
290
|
+
className: "cursor-pointer text-mocha-light",
|
|
291
|
+
children: "settings"
|
|
292
|
+
}), /* @__PURE__ */ jsxs("form", {
|
|
293
|
+
onSubmit: save,
|
|
294
|
+
className: "mt-2 flex flex-wrap items-end gap-3 border-t border-dashed border-frost py-3",
|
|
295
|
+
children: [
|
|
296
|
+
/* @__PURE__ */ jsxs("label", {
|
|
297
|
+
className: "flex flex-col gap-1 text-[0.85em] text-mocha-light",
|
|
298
|
+
children: ["model override", /* @__PURE__ */ jsxs("select", {
|
|
299
|
+
name: "modelOverride",
|
|
300
|
+
value: modelOverride,
|
|
301
|
+
onChange: (e) => setModelOverride(e.target.value),
|
|
302
|
+
className: "min-w-[16rem] rounded-sm border border-frost bg-snow px-2 py-1.5",
|
|
303
|
+
children: [
|
|
304
|
+
/* @__PURE__ */ jsxs("option", {
|
|
305
|
+
value: "",
|
|
306
|
+
children: [
|
|
307
|
+
"inherit from profile (",
|
|
308
|
+
profileDefaultModel,
|
|
309
|
+
")"
|
|
310
|
+
]
|
|
311
|
+
}),
|
|
312
|
+
currentModelOverride !== null && !currentInGroups && /* @__PURE__ */ jsxs("option", {
|
|
313
|
+
value: currentModelOverride,
|
|
314
|
+
children: [currentModelOverride, " (not in curated list)"]
|
|
315
|
+
}),
|
|
316
|
+
modelGroups.map((g) => /* @__PURE__ */ jsx("optgroup", {
|
|
317
|
+
label: g.provider,
|
|
318
|
+
children: g.models.map((m) => {
|
|
319
|
+
const value = `${g.provider}:${m}`;
|
|
320
|
+
return /* @__PURE__ */ jsx("option", {
|
|
321
|
+
value,
|
|
322
|
+
children: value
|
|
323
|
+
}, value);
|
|
324
|
+
})
|
|
325
|
+
}, g.provider))
|
|
326
|
+
]
|
|
327
|
+
})]
|
|
328
|
+
}),
|
|
329
|
+
/* @__PURE__ */ jsxs("label", {
|
|
330
|
+
className: "flex flex-col gap-1 text-[0.85em] text-mocha-light",
|
|
331
|
+
children: ["reasoning level", /* @__PURE__ */ jsx("select", {
|
|
332
|
+
name: "reasoningLevel",
|
|
333
|
+
value: reasoning,
|
|
334
|
+
onChange: (e) => setReasoning(e.target.value),
|
|
335
|
+
className: "min-w-[16rem] rounded-sm border border-frost bg-snow px-2 py-1.5",
|
|
336
|
+
children: REASONING_LEVELS.map((lvl) => /* @__PURE__ */ jsx("option", {
|
|
337
|
+
value: lvl,
|
|
338
|
+
children: lvl
|
|
339
|
+
}, lvl))
|
|
340
|
+
})]
|
|
341
|
+
}),
|
|
342
|
+
/* @__PURE__ */ jsx("button", {
|
|
343
|
+
type: "submit",
|
|
344
|
+
disabled: saving,
|
|
345
|
+
children: saving ? "saving…" : "save"
|
|
346
|
+
}),
|
|
347
|
+
savedFlash && /* @__PURE__ */ jsx("span", {
|
|
348
|
+
className: "text-[0.85em] text-[#3b7a3b]",
|
|
349
|
+
children: "saved ✓"
|
|
350
|
+
}),
|
|
351
|
+
error && /* @__PURE__ */ jsx("span", {
|
|
352
|
+
className: "text-[0.85em] text-[#9B3D3D]",
|
|
353
|
+
children: error
|
|
354
|
+
})
|
|
355
|
+
]
|
|
356
|
+
})]
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
function MoveGroupForm({ agentId, currentGroupId, groups }) {
|
|
360
|
+
const router = useRouter();
|
|
361
|
+
const [groupId, setGroupId] = useState(currentGroupId);
|
|
362
|
+
const [moving, setMoving] = useState(false);
|
|
363
|
+
const [err, setErr] = useState(null);
|
|
364
|
+
async function move(e) {
|
|
365
|
+
e.preventDefault();
|
|
366
|
+
if (groupId === currentGroupId) return;
|
|
367
|
+
setMoving(true);
|
|
368
|
+
setErr(null);
|
|
369
|
+
try {
|
|
370
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}/group`, {
|
|
371
|
+
method: "PATCH",
|
|
372
|
+
headers: { "content-type": "application/json" },
|
|
373
|
+
body: JSON.stringify({ groupId })
|
|
374
|
+
});
|
|
375
|
+
if (!res.ok) {
|
|
376
|
+
const body = await res.json().catch(() => null);
|
|
377
|
+
throw new Error(body?.error ?? res.statusText);
|
|
378
|
+
}
|
|
379
|
+
await router.invalidate();
|
|
380
|
+
} catch (e2) {
|
|
381
|
+
setErr(e2.message);
|
|
382
|
+
} finally {
|
|
383
|
+
setMoving(false);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return /* @__PURE__ */ jsxs("form", {
|
|
387
|
+
onSubmit: move,
|
|
388
|
+
className: "mt-2 flex flex-wrap items-end gap-2",
|
|
389
|
+
children: [
|
|
390
|
+
/* @__PURE__ */ jsxs("label", {
|
|
391
|
+
className: "flex flex-col gap-1 text-[0.85em] text-mocha-light",
|
|
392
|
+
children: ["move to:", /* @__PURE__ */ jsx("select", {
|
|
393
|
+
value: groupId,
|
|
394
|
+
onChange: (e) => setGroupId(e.target.value),
|
|
395
|
+
className: "min-w-[18rem] rounded-sm border border-frost bg-snow px-2 py-1.5",
|
|
396
|
+
children: groups.map((g) => /* @__PURE__ */ jsxs("option", {
|
|
397
|
+
value: g.id,
|
|
398
|
+
children: [
|
|
399
|
+
g.id,
|
|
400
|
+
" — ",
|
|
401
|
+
g.path
|
|
402
|
+
]
|
|
403
|
+
}, g.id))
|
|
404
|
+
})]
|
|
405
|
+
}),
|
|
406
|
+
/* @__PURE__ */ jsx("button", {
|
|
407
|
+
type: "submit",
|
|
408
|
+
disabled: moving || groupId === currentGroupId,
|
|
409
|
+
children: moving ? "moving…" : "move"
|
|
410
|
+
}),
|
|
411
|
+
err && /* @__PURE__ */ jsx("span", {
|
|
412
|
+
className: "text-[0.85em] text-[#9B3D3D]",
|
|
413
|
+
children: err
|
|
414
|
+
})
|
|
415
|
+
]
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
function SkillsTable({ agentId, attached, all }) {
|
|
419
|
+
const router = useRouter();
|
|
420
|
+
const [pending, setPending] = useState(null);
|
|
421
|
+
const [err, setErr] = useState(null);
|
|
422
|
+
async function attach(name) {
|
|
423
|
+
setPending(name);
|
|
424
|
+
setErr(null);
|
|
425
|
+
try {
|
|
426
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}/skills`, {
|
|
427
|
+
method: "POST",
|
|
428
|
+
headers: { "content-type": "application/json" },
|
|
429
|
+
body: JSON.stringify({ skill: name })
|
|
430
|
+
});
|
|
431
|
+
if (!res.ok) {
|
|
432
|
+
const body = await res.json().catch(() => null);
|
|
433
|
+
throw new Error(body?.error ?? res.statusText);
|
|
434
|
+
}
|
|
435
|
+
await router.invalidate();
|
|
436
|
+
} catch (e) {
|
|
437
|
+
setErr(e.message);
|
|
438
|
+
} finally {
|
|
439
|
+
setPending(null);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async function detach(name) {
|
|
443
|
+
setPending(name);
|
|
444
|
+
setErr(null);
|
|
445
|
+
try {
|
|
446
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}/skills/${encodeURIComponent(name)}`, { method: "DELETE" });
|
|
447
|
+
if (!res.ok && res.status !== 204) {
|
|
448
|
+
const body = await res.json().catch(() => null);
|
|
449
|
+
throw new Error(body?.error ?? res.statusText);
|
|
450
|
+
}
|
|
451
|
+
await router.invalidate();
|
|
452
|
+
} catch (e) {
|
|
453
|
+
setErr(e.message);
|
|
454
|
+
} finally {
|
|
455
|
+
setPending(null);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (all.length === 0) return /* @__PURE__ */ jsx("p", {
|
|
459
|
+
className: "text-[0.9em] text-mocha-light",
|
|
460
|
+
children: "no skills installed"
|
|
461
|
+
});
|
|
462
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [err && /* @__PURE__ */ jsx("p", {
|
|
463
|
+
className: "mb-2 text-[0.85em] text-[#9B3D3D]",
|
|
464
|
+
children: err
|
|
465
|
+
}), /* @__PURE__ */ jsxs("table", { children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
466
|
+
/* @__PURE__ */ jsx("th", { children: "name" }),
|
|
467
|
+
/* @__PURE__ */ jsx("th", { children: "description" }),
|
|
468
|
+
/* @__PURE__ */ jsx("th", {})
|
|
469
|
+
] }) }), /* @__PURE__ */ jsx("tbody", { children: all.map((s) => {
|
|
470
|
+
const isAttached = attached.has(s.name);
|
|
471
|
+
const busy = pending === s.name;
|
|
472
|
+
return /* @__PURE__ */ jsxs("tr", { children: [
|
|
473
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("code", { children: s.name }) }),
|
|
474
|
+
/* @__PURE__ */ jsx("td", { children: s.description || /* @__PURE__ */ jsx("span", {
|
|
475
|
+
className: "text-mocha-light",
|
|
476
|
+
children: "—"
|
|
477
|
+
}) }),
|
|
478
|
+
/* @__PURE__ */ jsx("td", { children: isAttached ? /* @__PURE__ */ jsx("button", {
|
|
479
|
+
type: "button",
|
|
480
|
+
className: "ghost-btn",
|
|
481
|
+
disabled: busy,
|
|
482
|
+
onClick: () => detach(s.name),
|
|
483
|
+
children: busy ? "…" : "detach"
|
|
484
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
485
|
+
type: "button",
|
|
486
|
+
className: "ghost-btn",
|
|
487
|
+
disabled: busy,
|
|
488
|
+
onClick: () => attach(s.name),
|
|
489
|
+
children: busy ? "…" : "attach"
|
|
490
|
+
}) })
|
|
491
|
+
] }, s.name);
|
|
492
|
+
}) })] })] });
|
|
493
|
+
}
|
|
494
|
+
function TelegramSection({ agent }) {
|
|
495
|
+
const router = useRouter();
|
|
496
|
+
const [busy, setBusy] = useState(false);
|
|
497
|
+
const [error, setError] = useState(null);
|
|
498
|
+
const [mirrorMode, setMirrorMode] = useState(agent.telegramMirrorMode);
|
|
499
|
+
const [iconEmoji, setIconEmoji] = useState(agent.telegramIconEmoji ?? "");
|
|
500
|
+
const isBound = agent.telegramTopicId !== null;
|
|
501
|
+
async function bind() {
|
|
502
|
+
setBusy(true);
|
|
503
|
+
setError(null);
|
|
504
|
+
try {
|
|
505
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agent.id)}/telegram/bind`, { method: "POST" });
|
|
506
|
+
if (!res.ok) {
|
|
507
|
+
const body = await res.json().catch(() => null);
|
|
508
|
+
throw new Error(body?.error ?? res.statusText);
|
|
509
|
+
}
|
|
510
|
+
const result = await res.json();
|
|
511
|
+
window.open(result.deepLink, "_blank", "noopener");
|
|
512
|
+
await router.invalidate();
|
|
513
|
+
} catch (e) {
|
|
514
|
+
setError(e.message);
|
|
515
|
+
} finally {
|
|
516
|
+
setBusy(false);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
async function unbind() {
|
|
520
|
+
if (!confirm("Unbind this agent from its Telegram topic? The topic stays in Telegram as an orphan.")) return;
|
|
521
|
+
setBusy(true);
|
|
522
|
+
setError(null);
|
|
523
|
+
try {
|
|
524
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agent.id)}/telegram/binding`, { method: "DELETE" });
|
|
525
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
526
|
+
await router.invalidate();
|
|
527
|
+
} catch (e) {
|
|
528
|
+
setError(e.message);
|
|
529
|
+
} finally {
|
|
530
|
+
setBusy(false);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
async function saveMirrorMode(next) {
|
|
534
|
+
setMirrorMode(next);
|
|
535
|
+
try {
|
|
536
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agent.id)}`, {
|
|
537
|
+
method: "PATCH",
|
|
538
|
+
headers: { "content-type": "application/json" },
|
|
539
|
+
body: JSON.stringify({ telegramMirrorMode: next })
|
|
540
|
+
});
|
|
541
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
542
|
+
await router.invalidate();
|
|
543
|
+
} catch (e) {
|
|
544
|
+
setMirrorMode(agent.telegramMirrorMode);
|
|
545
|
+
setError(e.message);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
async function saveIcon() {
|
|
549
|
+
setError(null);
|
|
550
|
+
try {
|
|
551
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agent.id)}`, {
|
|
552
|
+
method: "PATCH",
|
|
553
|
+
headers: { "content-type": "application/json" },
|
|
554
|
+
body: JSON.stringify({ telegramIconEmoji: iconEmoji.trim() || null })
|
|
555
|
+
});
|
|
556
|
+
if (!res.ok) throw new Error(res.statusText);
|
|
557
|
+
await router.invalidate();
|
|
558
|
+
} catch (e) {
|
|
559
|
+
setError(e.message);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
563
|
+
className: "text-[0.9em]",
|
|
564
|
+
children: [
|
|
565
|
+
/* @__PURE__ */ jsx("div", {
|
|
566
|
+
className: "mb-3 flex items-center gap-3",
|
|
567
|
+
children: isBound ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
568
|
+
/* @__PURE__ */ jsx("span", {
|
|
569
|
+
className: "rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-semibold text-emerald-800",
|
|
570
|
+
children: "bound"
|
|
571
|
+
}),
|
|
572
|
+
/* @__PURE__ */ jsxs("span", {
|
|
573
|
+
className: "font-mono text-mocha",
|
|
574
|
+
children: ["topic #", agent.telegramTopicId]
|
|
575
|
+
}),
|
|
576
|
+
/* @__PURE__ */ jsx("button", {
|
|
577
|
+
type: "button",
|
|
578
|
+
onClick: bind,
|
|
579
|
+
disabled: busy,
|
|
580
|
+
className: "ghost-btn",
|
|
581
|
+
title: "Open the topic in Telegram (works on desktop/Android; iOS shows the topic list)",
|
|
582
|
+
children: "open in Telegram"
|
|
583
|
+
}),
|
|
584
|
+
/* @__PURE__ */ jsx("button", {
|
|
585
|
+
type: "button",
|
|
586
|
+
onClick: unbind,
|
|
587
|
+
disabled: busy,
|
|
588
|
+
className: "ghost-btn border-[rgba(196,135,138,0.4)] text-[#9B3D3D] hover:bg-[rgba(196,135,138,0.08)]",
|
|
589
|
+
children: "unbind"
|
|
590
|
+
})
|
|
591
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
592
|
+
className: "rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-800",
|
|
593
|
+
children: "unbound"
|
|
594
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
595
|
+
type: "button",
|
|
596
|
+
onClick: bind,
|
|
597
|
+
disabled: busy,
|
|
598
|
+
className: "ghost-btn",
|
|
599
|
+
title: "Create a Telegram topic for this agent",
|
|
600
|
+
children: busy ? "binding…" : "bind a topic"
|
|
601
|
+
})] })
|
|
602
|
+
}),
|
|
603
|
+
/* @__PURE__ */ jsxs("div", {
|
|
604
|
+
className: "flex items-center gap-2",
|
|
605
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
606
|
+
htmlFor: "mirror-mode",
|
|
607
|
+
className: "text-mocha-light",
|
|
608
|
+
children: "mirror mode:"
|
|
609
|
+
}), /* @__PURE__ */ jsxs("select", {
|
|
610
|
+
id: "mirror-mode",
|
|
611
|
+
value: mirrorMode,
|
|
612
|
+
onChange: (e) => void saveMirrorMode(e.target.value),
|
|
613
|
+
className: "rounded-md border bg-background px-2 py-1 font-mono text-sm",
|
|
614
|
+
disabled: busy,
|
|
615
|
+
children: [/* @__PURE__ */ jsx("option", {
|
|
616
|
+
value: "minimal",
|
|
617
|
+
children: "minimal — assistant messages only"
|
|
618
|
+
}), /* @__PURE__ */ jsx("option", {
|
|
619
|
+
value: "verbose",
|
|
620
|
+
children: "verbose — also tool calls"
|
|
621
|
+
})]
|
|
622
|
+
})]
|
|
623
|
+
}),
|
|
624
|
+
/* @__PURE__ */ jsxs("div", {
|
|
625
|
+
className: "mt-2 flex items-center gap-2",
|
|
626
|
+
children: [
|
|
627
|
+
/* @__PURE__ */ jsx("label", {
|
|
628
|
+
htmlFor: "topic-icon",
|
|
629
|
+
className: "text-mocha-light",
|
|
630
|
+
children: "topic icon:"
|
|
631
|
+
}),
|
|
632
|
+
/* @__PURE__ */ jsx("input", {
|
|
633
|
+
id: "topic-icon",
|
|
634
|
+
value: iconEmoji,
|
|
635
|
+
onChange: (e) => setIconEmoji(e.target.value),
|
|
636
|
+
placeholder: "(profile default)",
|
|
637
|
+
maxLength: 8,
|
|
638
|
+
className: "w-32 rounded-md border bg-background px-2 py-1 font-mono text-sm",
|
|
639
|
+
disabled: busy
|
|
640
|
+
}),
|
|
641
|
+
/* @__PURE__ */ jsx("button", {
|
|
642
|
+
type: "button",
|
|
643
|
+
onClick: () => void saveIcon(),
|
|
644
|
+
disabled: busy || iconEmoji === (agent.telegramIconEmoji ?? ""),
|
|
645
|
+
className: "ghost-btn",
|
|
646
|
+
children: "save icon"
|
|
647
|
+
})
|
|
648
|
+
]
|
|
649
|
+
}),
|
|
650
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
651
|
+
className: "mt-2 text-sm text-rose-700",
|
|
652
|
+
children: error
|
|
653
|
+
}),
|
|
654
|
+
/* @__PURE__ */ jsx("p", {
|
|
655
|
+
className: "mt-3 text-[0.85em] text-mocha-light",
|
|
656
|
+
children: "When bound, every assistant turn for this agent gets mirrored to the topic. Typing in the topic triggers a new turn. iOS Telegram clients have a known limitation that prevents inline link deep-links from opening directly into a topic — bound state is still functional; navigate via the topic list manually."
|
|
657
|
+
})
|
|
658
|
+
]
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
//#endregion
|
|
662
|
+
export { AgentDetailPage as component };
|