dsh-bots 0.2.12 → 0.2.13
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/lib/client.js +144 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -323,6 +323,7 @@
|
|
|
323
323
|
.dbs-fileChip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;background:var(--dsw-alias-interactive-bg-hover);font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;max-width:100%;user-select:none}
|
|
324
324
|
.dbs-fileChip:hover{color:var(--dsw-alias-label-primary)}
|
|
325
325
|
.dbs-fileChipName{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
326
|
+
.dbs-setLabel{font-size:12px;line-height:16px;color:var(--dsw-alias-label-tertiary);margin:8px 0 4px}
|
|
326
327
|
.dbs-chatbar{flex:none;display:flex;align-items:center;gap:8px;height:44px;padding:0 12px;border-bottom:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.08))}
|
|
327
328
|
.dbs-chatbarName{font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
|
|
328
329
|
.dbs-scrollBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden auto}
|
|
@@ -458,6 +459,16 @@
|
|
|
458
459
|
'chat.stop.noop': '当前没有进行中的生成',
|
|
459
460
|
'media.openFailed': '打开失败,文件可能已移动或被删除',
|
|
460
461
|
'chat.members.manage': '管理成员',
|
|
462
|
+
'chat.settings': '设置',
|
|
463
|
+
'chat.settings.title': '会话设置',
|
|
464
|
+
'chat.settings.name': '名称',
|
|
465
|
+
'chat.settings.desc': '简介',
|
|
466
|
+
'chat.settings.workspace': '工作区隔离',
|
|
467
|
+
'chat.settings.root': '工作区根目录',
|
|
468
|
+
'chat.settings.rootPh': '留空 = 不启用',
|
|
469
|
+
'chat.settings.paths': '额外可写路径(逗号分隔)',
|
|
470
|
+
'chat.settings.pathsPh': '/tmp/xxx, /Users/you/shared',
|
|
471
|
+
'chat.settings.hint': '写入被沙盒限制在工作区(含额外路径)内,读取不受限;同 slug 的 Bot 共享同一目录。',
|
|
461
472
|
'modal.members.title': '管理群成员',
|
|
462
473
|
'modal.members.hint': '勾选的 Bot 为群成员;保存后立即生效(可随时再改)。',
|
|
463
474
|
'action.delete': '删除',
|
|
@@ -560,6 +571,16 @@
|
|
|
560
571
|
'chat.stop.noop': 'No generation in progress',
|
|
561
572
|
'media.openFailed': 'Open failed — the file may have moved or been deleted',
|
|
562
573
|
'chat.members.manage': 'Manage members',
|
|
574
|
+
'chat.settings': 'Settings',
|
|
575
|
+
'chat.settings.title': 'Session settings',
|
|
576
|
+
'chat.settings.name': 'Name',
|
|
577
|
+
'chat.settings.desc': 'Description',
|
|
578
|
+
'chat.settings.workspace': 'Workspace jail',
|
|
579
|
+
'chat.settings.root': 'Workspace root',
|
|
580
|
+
'chat.settings.rootPh': 'Empty = disabled',
|
|
581
|
+
'chat.settings.paths': 'Extra writable paths (comma-separated)',
|
|
582
|
+
'chat.settings.pathsPh': '/tmp/xxx, /Users/you/shared',
|
|
583
|
+
'chat.settings.hint': 'Writes are sandboxed to the workspace (plus extra paths); reads stay unrestricted. Bots sharing a slug share one directory.',
|
|
563
584
|
'modal.members.title': 'Manage group members',
|
|
564
585
|
'modal.members.hint': 'Checked bots are members; changes apply immediately on save (editable again anytime).',
|
|
565
586
|
'action.delete': 'Delete',
|
|
@@ -762,6 +783,7 @@
|
|
|
762
783
|
confirmDelete: null,
|
|
763
784
|
/** Manage-members dialog: group agentId | null (system modal). */
|
|
764
785
|
manageMembers: null,
|
|
786
|
+
settingsAgentId: null,
|
|
765
787
|
/** Bumped on a language switch so module-scope `t` output re-renders. */
|
|
766
788
|
localeRev: 0,
|
|
767
789
|
};
|
|
@@ -1380,6 +1402,13 @@
|
|
|
1380
1402
|
return null;
|
|
1381
1403
|
return e('div', { className: 'dbs-mediaRefs' }, imgs.map((r) => e(MediaImage, { key: r, path: r })), files.map((r) => e(FileChip, { key: r, path: r })));
|
|
1382
1404
|
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Settings glyph — three sliders, drawn inline (the primitives package
|
|
1407
|
+
* exposes no verified gear export; same policy as SendUpIcon).
|
|
1408
|
+
*/
|
|
1409
|
+
function SettingsGlyph() {
|
|
1410
|
+
return e('svg', { viewBox: '0 0 16 16', width: '16', height: '16', 'aria-hidden': true }, e('g', { stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round' }, e('line', { x1: 2, y1: 4, x2: 14, y2: 4 }), e('line', { x1: 2, y1: 8, x2: 14, y2: 8 }), e('line', { x1: 2, y1: 12, x2: 14, y2: 12 })), e('g', { fill: 'currentColor' }, e('circle', { cx: 10, cy: 4, r: 2 }), e('circle', { cx: 5.5, cy: 8, r: 2 }), e('circle', { cx: 11.5, cy: 12, r: 2 })));
|
|
1411
|
+
}
|
|
1383
1412
|
function ToolCard(p) {
|
|
1384
1413
|
const [open, setOpen] = React.useState(false);
|
|
1385
1414
|
const en = p.entry;
|
|
@@ -1695,12 +1724,16 @@
|
|
|
1695
1724
|
variant: 'ghost', size: 'sm', title: t('action.close'), 'aria-label': t('action.close'),
|
|
1696
1725
|
icon: Ico('IconCloseOutline16', { size: 16 }),
|
|
1697
1726
|
onClick: () => patch({ chatAgentId: null }),
|
|
1698
|
-
}), agent !== null ? e(Avatar, { agent, size: 24 }) : null, e('span', { className: 'dbs-chatbarName' }, agent?.name ?? t('chat.loading')), e('span', { className: 'dbs-meta' }, isGroup ? t('chat.group', { n: memberNames.length }) : t('chat.single')), isGroup
|
|
1727
|
+
}), agent !== null ? e(Avatar, { agent, size: 24 }) : null, e('span', { className: 'dbs-chatbarName' }, agent?.name ?? t('chat.loading')), e('span', { className: 'dbs-meta' }, isGroup ? t('chat.group', { n: memberNames.length }) : t('chat.single')), e('span', { style: { flex: 1 } }), isGroup
|
|
1699
1728
|
? e(Button, {
|
|
1700
1729
|
variant: 'ghost', size: 'sm', title: t('chat.members.manage'), 'aria-label': t('chat.members.manage'),
|
|
1701
1730
|
onClick: () => patch({ manageMembers: p.agentId }),
|
|
1702
1731
|
}, t('chat.members.manage'))
|
|
1703
|
-
: null, e('
|
|
1732
|
+
: null, e('button', {
|
|
1733
|
+
className: 'dbs-railBtn', type: 'button',
|
|
1734
|
+
title: t('chat.settings'), 'aria-label': t('chat.settings'),
|
|
1735
|
+
onClick: () => patch({ settingsAgentId: p.agentId }),
|
|
1736
|
+
}, e(SettingsGlyph, null))), error !== null
|
|
1704
1737
|
? e('div', { className: 'dbs-error', onClick: () => setError(null) }, error)
|
|
1705
1738
|
: null, e('div', { className: 'dbs-scrollArea' }, e('div', { className: 'dbs-scrollBody', ref: scrollRef, onScroll: onScrollBody }, e('div', { className: 'dbs-scroll' }, e('div', { className: 'dbs-column' }, entries === null
|
|
1706
1739
|
? e('div', { className: 'dbs-skeleton' }, e('div', { className: 'dbs-skelRow', style: { width: '42%' } }), e('div', { className: 'dbs-skelRow', style: { width: '76%' } }), e('div', { className: 'dbs-skelRow', style: { width: '58%' } }))
|
|
@@ -2161,6 +2194,113 @@
|
|
|
2161
2194
|
onClick: () => void submit(),
|
|
2162
2195
|
}, working ? t('action.saving') : t('action.save')))));
|
|
2163
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Per-session settings: name (+ description) for every chat; singles
|
|
2199
|
+
* additionally get the §14 workspace-jail editor (root + extra writable
|
|
2200
|
+
* paths). updateAgent merges only the name/description/title/avatar
|
|
2201
|
+
* fields engine-side, so saving cannot clobber the rest of a profile;
|
|
2202
|
+
* an empty root removes the jail (workspaceRoot: null).
|
|
2203
|
+
*/
|
|
2204
|
+
function AgentSettingsModal() {
|
|
2205
|
+
const s = useStore();
|
|
2206
|
+
const agent = agentById(s.settingsAgentId);
|
|
2207
|
+
const isGroup = agent?.isGroup === true;
|
|
2208
|
+
const [name, setName] = React.useState('');
|
|
2209
|
+
const [desc, setDesc] = React.useState('');
|
|
2210
|
+
const [root, setRoot] = React.useState('');
|
|
2211
|
+
const [paths, setPaths] = React.useState('');
|
|
2212
|
+
const [wsLoaded, setWsLoaded] = React.useState(false);
|
|
2213
|
+
const [working, setWorking] = React.useState(false);
|
|
2214
|
+
const [err, setErr] = React.useState(null);
|
|
2215
|
+
React.useEffect(() => {
|
|
2216
|
+
if (agent === null || agent === undefined)
|
|
2217
|
+
return;
|
|
2218
|
+
setName(String(agent.name ?? ''));
|
|
2219
|
+
setDesc(String(agent.description ?? ''));
|
|
2220
|
+
if (agent.isGroup === true) {
|
|
2221
|
+
setWsLoaded(true);
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
let alive = true;
|
|
2225
|
+
botsCall('workspaceGet', { agentId: agent.id })
|
|
2226
|
+
.then((c) => {
|
|
2227
|
+
if (alive === false)
|
|
2228
|
+
return;
|
|
2229
|
+
setRoot(c.workspaceRoot ?? '');
|
|
2230
|
+
setPaths((c.allowPaths ?? []).join(', '));
|
|
2231
|
+
setWsLoaded(true);
|
|
2232
|
+
})
|
|
2233
|
+
.catch(() => { if (alive)
|
|
2234
|
+
setWsLoaded(true); });
|
|
2235
|
+
return () => { alive = false; };
|
|
2236
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2237
|
+
}, [s.settingsAgentId]);
|
|
2238
|
+
if (agent === null || agent === undefined)
|
|
2239
|
+
return null;
|
|
2240
|
+
const valid = name.trim() !== '';
|
|
2241
|
+
async function save() {
|
|
2242
|
+
if (working || valid === false)
|
|
2243
|
+
return;
|
|
2244
|
+
setWorking(true);
|
|
2245
|
+
setErr(null);
|
|
2246
|
+
try {
|
|
2247
|
+
await botsCall('update', { id: agent.id, profile: { name: name.trim(), description: desc.trim() } });
|
|
2248
|
+
if (agent.isGroup !== true && wsLoaded === true) {
|
|
2249
|
+
const list = paths.split(/[,,]/).map((x) => x.trim()).filter((x) => x !== '');
|
|
2250
|
+
await botsCall('workspaceSet', {
|
|
2251
|
+
agentId: agent.id,
|
|
2252
|
+
workspaceRoot: root.trim() === '' ? null : root.trim(),
|
|
2253
|
+
allowPaths: list,
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
patch({ settingsAgentId: null });
|
|
2257
|
+
await refreshAgents();
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
catch (e2) {
|
|
2261
|
+
setErr(String(e2?.message ?? e2));
|
|
2262
|
+
}
|
|
2263
|
+
setWorking(false);
|
|
2264
|
+
}
|
|
2265
|
+
return e('div', {
|
|
2266
|
+
className: 'dbs-modalBackdrop',
|
|
2267
|
+
onClick: () => { if (working === false)
|
|
2268
|
+
patch({ settingsAgentId: null }); },
|
|
2269
|
+
}, e('div', {
|
|
2270
|
+
className: 'dbs-modalCard', role: 'dialog', 'aria-modal': true,
|
|
2271
|
+
'aria-label': t('chat.settings.title'),
|
|
2272
|
+
onClick: (ev) => { ev.stopPropagation(); },
|
|
2273
|
+
}, e('div', { className: 'dbs-modalTitleRow' }, e('span', { className: 'dbs-modalTitle' }, t('chat.settings.title')), e(Button, {
|
|
2274
|
+
variant: 'ghost', size: 'sm', title: t('action.close'), 'aria-label': t('action.close'),
|
|
2275
|
+
disabled: working,
|
|
2276
|
+
icon: Ico('IconCloseOutline16', { size: 16 }),
|
|
2277
|
+
onClick: () => patch({ settingsAgentId: null }),
|
|
2278
|
+
})), e('div', { className: 'dbs-modalBody' }, e('div', { className: 'dbs-setLabel' }, t('chat.settings.name')), e(Input, {
|
|
2279
|
+
value: name, autoFocus: true, disabled: working,
|
|
2280
|
+
onChange: (ev) => setName(ev.target.value),
|
|
2281
|
+
}), isGroup === false
|
|
2282
|
+
? e('div', null, e('div', { className: 'dbs-setLabel' }, t('chat.settings.desc')), e(Input, {
|
|
2283
|
+
value: desc, disabled: working,
|
|
2284
|
+
onChange: (ev) => setDesc(ev.target.value),
|
|
2285
|
+
}), e('div', { className: 'dbs-setLabel', style: { marginTop: 12, fontWeight: 600 } }, t('chat.settings.workspace')), e('div', { className: 'dbs-setLabel' }, t('chat.settings.root')), e(Input, {
|
|
2286
|
+
value: root, disabled: working || wsLoaded === false,
|
|
2287
|
+
placeholder: t('chat.settings.rootPh'),
|
|
2288
|
+
onChange: (ev) => setRoot(ev.target.value),
|
|
2289
|
+
}), e('div', { className: 'dbs-setLabel' }, t('chat.settings.paths')), e(Input, {
|
|
2290
|
+
value: paths, disabled: working || wsLoaded === false,
|
|
2291
|
+
placeholder: t('chat.settings.pathsPh'),
|
|
2292
|
+
onChange: (ev) => setPaths(ev.target.value),
|
|
2293
|
+
}), e('div', { className: 'dbs-meta', style: { marginTop: 8 } }, t('chat.settings.hint')))
|
|
2294
|
+
: null, err !== null
|
|
2295
|
+
? e('div', { className: 'dbs-error', onClick: () => { setErr(null); } }, err)
|
|
2296
|
+
: null), e('div', { className: 'dbs-modalFooter' }, e(Button, {
|
|
2297
|
+
variant: 'ghost', size: 'sm', disabled: working,
|
|
2298
|
+
onClick: () => patch({ settingsAgentId: null }),
|
|
2299
|
+
}, t('action.cancel')), e(Button, {
|
|
2300
|
+
variant: 'primary', size: 'sm', disabled: valid === false || working,
|
|
2301
|
+
onClick: () => void save(),
|
|
2302
|
+
}, working === true ? t('action.saving') : t('action.save')))));
|
|
2303
|
+
}
|
|
2164
2304
|
/** Delete confirmation modal: same system-dialog chrome as CreateModal. */
|
|
2165
2305
|
function ConfirmDeleteModal() {
|
|
2166
2306
|
const s = useStore();
|
|
@@ -2239,6 +2379,8 @@
|
|
|
2239
2379
|
layers.push(e(CreateModal, { key: 'create' }));
|
|
2240
2380
|
if (s.manageMembers !== null)
|
|
2241
2381
|
layers.push(e(ManageMembersModal, { key: 'manage-members' }));
|
|
2382
|
+
if (s.settingsAgentId !== null)
|
|
2383
|
+
layers.push(e(AgentSettingsModal, { key: 'agent-settings' }));
|
|
2242
2384
|
if (s.confirmDelete !== null)
|
|
2243
2385
|
layers.push(e(ConfirmDeleteModal, { key: 'confirm-delete' }));
|
|
2244
2386
|
return layers.length === 0 ? null : e('div', null, layers);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bots",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "Multi-bot workbench for DeepSeek Harness: bridges the sdk-bots orchestration gateway (group chats, single bots) into the dsh web shell with official-styled UI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|