dsh-advisor-group 0.1.2 → 0.1.4
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.en.md +203 -0
- package/README.md +154 -79
- package/lib/client.js +183 -1
- package/lib/index.d.mts +45 -0
- package/lib/index.mjs +2737 -211
- package/package.json +14 -14
- package/README.zh.md +0 -135
package/lib/client.js
CHANGED
|
@@ -1497,7 +1497,189 @@ function AdvisorGroupSettingsTab() {
|
|
|
1497
1497
|
}))), (0, react.createElement)("div", { style: settingsSectionStyle }, dailyGuard ? (0, react.createElement)("div", { style: {
|
|
1498
1498
|
fontSize: 12,
|
|
1499
1499
|
color: !dailyGuard.enabled || dailyGuard.remaining > 0 ? "var(--dsh-color-muted, #8b90a0)" : "#e11d48"
|
|
1500
|
-
} }, dailyGuard.enabled ? dailyGuard.remaining > 0 ? `今日剩余咨询次数:${dailyGuard.remaining} / ${dailyGuard.limit}(UTC 日切)` : `今日咨询次数已用尽(${dailyGuard.used} / ${dailyGuard.limit}),将于 UTC 日切后恢复。` : `今日已咨询 ${dailyGuard.used} 次(每日上限已关闭)。`) : null), (0, react.createElement)("div", { style: settingsSectionStyle }, (0, react.createElement)("div", { style: {
|
|
1500
|
+
} }, dailyGuard.enabled ? dailyGuard.remaining > 0 ? `今日剩余咨询次数:${dailyGuard.remaining} / ${dailyGuard.limit}(UTC 日切)` : `今日咨询次数已用尽(${dailyGuard.used} / ${dailyGuard.limit}),将于 UTC 日切后恢复。` : `今日已咨询 ${dailyGuard.used} 次(每日上限已关闭)。`) : null), (0, react.createElement)("div", { style: settingsSectionStyle }, (0, react.createElement)("strong", null, "全局蜂群"), (0, react.createElement)("div", { style: {
|
|
1501
|
+
fontSize: 12,
|
|
1502
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1503
|
+
margin: "4px 0 8px"
|
|
1504
|
+
} }, "跨会话提问的开关与默认应答方式。"), (0, react.createElement)("div", { style: {
|
|
1505
|
+
display: "flex",
|
|
1506
|
+
alignItems: "center",
|
|
1507
|
+
gap: 8
|
|
1508
|
+
} }, (0, react.createElement)("input", {
|
|
1509
|
+
type: "checkbox",
|
|
1510
|
+
checked: config.swarm.enabled,
|
|
1511
|
+
onChange: (e) => setConfig({
|
|
1512
|
+
...config,
|
|
1513
|
+
swarm: {
|
|
1514
|
+
...config.swarm,
|
|
1515
|
+
enabled: e.target.checked
|
|
1516
|
+
}
|
|
1517
|
+
})
|
|
1518
|
+
}), label("总开关")), (0, react.createElement)("div", { style: {
|
|
1519
|
+
fontSize: 12,
|
|
1520
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1521
|
+
margin: "2px 0 8px"
|
|
1522
|
+
} }, "关闭后本插件不再跨会话提问,三个工具会明确拒绝"), (0, react.createElement)("div", { style: {
|
|
1523
|
+
display: "grid",
|
|
1524
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
|
|
1525
|
+
gap: 8
|
|
1526
|
+
} }, (0, react.createElement)("div", null, label("默认应答方式"), (0, react.createElement)("select", {
|
|
1527
|
+
value: config.swarm.defaultMode,
|
|
1528
|
+
onChange: (e) => setConfig({
|
|
1529
|
+
...config,
|
|
1530
|
+
swarm: {
|
|
1531
|
+
...config.swarm,
|
|
1532
|
+
defaultMode: e.target.value === "detach" ? "detach" : "wait"
|
|
1533
|
+
}
|
|
1534
|
+
}),
|
|
1535
|
+
style: settingsInputStyle
|
|
1536
|
+
}, (0, react.createElement)("option", { value: "wait" }, "同步等待"), (0, react.createElement)("option", { value: "detach" }, "异步投递"))), (0, react.createElement)("div", null, label("默认等待上限(分钟)"), (0, react.createElement)("input", {
|
|
1537
|
+
type: "number",
|
|
1538
|
+
min: 1,
|
|
1539
|
+
max: 10,
|
|
1540
|
+
value: String(Math.round(config.swarm.defaultWaitMs / 6e4)),
|
|
1541
|
+
onChange: (e) => setConfig({
|
|
1542
|
+
...config,
|
|
1543
|
+
swarm: {
|
|
1544
|
+
...config.swarm,
|
|
1545
|
+
defaultWaitMs: Math.min(10, Math.max(1, Number(e.target.value) || 1)) * 6e4
|
|
1546
|
+
}
|
|
1547
|
+
}),
|
|
1548
|
+
style: settingsInputStyle
|
|
1549
|
+
}), (0, react.createElement)("div", { style: {
|
|
1550
|
+
fontSize: 12,
|
|
1551
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1552
|
+
marginTop: 4
|
|
1553
|
+
} }, "可填 1–10 分钟")), (0, react.createElement)("div", null, label("异步结果保留(小时)"), (0, react.createElement)("input", {
|
|
1554
|
+
type: "number",
|
|
1555
|
+
min: 1,
|
|
1556
|
+
max: 720,
|
|
1557
|
+
value: String(config.swarm.resultTtlHours),
|
|
1558
|
+
onChange: (e) => setConfig({
|
|
1559
|
+
...config,
|
|
1560
|
+
swarm: {
|
|
1561
|
+
...config.swarm,
|
|
1562
|
+
resultTtlHours: Math.min(720, Math.max(1, Number(e.target.value) || 1))
|
|
1563
|
+
}
|
|
1564
|
+
}),
|
|
1565
|
+
style: settingsInputStyle
|
|
1566
|
+
}))), (0, react.createElement)("div", { style: {
|
|
1567
|
+
display: "flex",
|
|
1568
|
+
alignItems: "center",
|
|
1569
|
+
gap: 8,
|
|
1570
|
+
marginTop: 8
|
|
1571
|
+
} }, (0, react.createElement)("input", {
|
|
1572
|
+
type: "checkbox",
|
|
1573
|
+
checked: config.swarm.rosterIncludeSubagents,
|
|
1574
|
+
onChange: (e) => setConfig({
|
|
1575
|
+
...config,
|
|
1576
|
+
swarm: {
|
|
1577
|
+
...config.swarm,
|
|
1578
|
+
rosterIncludeSubagents: e.target.checked
|
|
1579
|
+
}
|
|
1580
|
+
})
|
|
1581
|
+
}), label("名录列出子代理会话")), (0, react.createElement)("div", { style: {
|
|
1582
|
+
display: "flex",
|
|
1583
|
+
alignItems: "center",
|
|
1584
|
+
gap: 8,
|
|
1585
|
+
marginTop: 8
|
|
1586
|
+
} }, (0, react.createElement)("input", {
|
|
1587
|
+
type: "checkbox",
|
|
1588
|
+
checked: config.swarm.routingEnabled !== false,
|
|
1589
|
+
onChange: (e) => setConfig({
|
|
1590
|
+
...config,
|
|
1591
|
+
swarm: {
|
|
1592
|
+
...config.swarm,
|
|
1593
|
+
routingEnabled: e.target.checked
|
|
1594
|
+
}
|
|
1595
|
+
})
|
|
1596
|
+
}), label("按问题找会话")), (0, react.createElement)("div", { style: {
|
|
1597
|
+
fontSize: 12,
|
|
1598
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1599
|
+
margin: "2px 0 8px"
|
|
1600
|
+
} }, "没有点名会话时,先按问题关键词列出候选,交给用户挑一个,不自动投递"), (0, react.createElement)("div", { style: {
|
|
1601
|
+
display: "flex",
|
|
1602
|
+
alignItems: "center",
|
|
1603
|
+
gap: 8
|
|
1604
|
+
} }, label("候选数"), (0, react.createElement)("input", {
|
|
1605
|
+
type: "number",
|
|
1606
|
+
min: 1,
|
|
1607
|
+
max: 8,
|
|
1608
|
+
value: String(config.swarm.routingTopN ?? 3),
|
|
1609
|
+
disabled: config.swarm.routingEnabled === false,
|
|
1610
|
+
onChange: (e) => setConfig({
|
|
1611
|
+
...config,
|
|
1612
|
+
swarm: {
|
|
1613
|
+
...config.swarm,
|
|
1614
|
+
routingTopN: Math.min(8, Math.max(1, Number(e.target.value) || 3))
|
|
1615
|
+
}
|
|
1616
|
+
}),
|
|
1617
|
+
style: {
|
|
1618
|
+
...settingsInputStyle,
|
|
1619
|
+
width: 120
|
|
1620
|
+
}
|
|
1621
|
+
})), (0, react.createElement)("div", { style: {
|
|
1622
|
+
display: "flex",
|
|
1623
|
+
alignItems: "center",
|
|
1624
|
+
gap: 8,
|
|
1625
|
+
marginTop: 8
|
|
1626
|
+
} }, label("路由方式"), (0, react.createElement)("select", {
|
|
1627
|
+
value: config.swarm.routingEngine === "jev" ? "jev" : "local",
|
|
1628
|
+
disabled: config.swarm.routingEnabled === false,
|
|
1629
|
+
onChange: (e) => setConfig({
|
|
1630
|
+
...config,
|
|
1631
|
+
swarm: {
|
|
1632
|
+
...config.swarm,
|
|
1633
|
+
routingEngine: e.target.value === "jev" ? "jev" : "local"
|
|
1634
|
+
}
|
|
1635
|
+
}),
|
|
1636
|
+
style: settingsInputStyle
|
|
1637
|
+
}, (0, react.createElement)("option", { value: "local" }, "本地计算"), (0, react.createElement)("option", { value: "jev" }, "Jev 判断"))), (0, react.createElement)("div", { style: {
|
|
1638
|
+
fontSize: 12,
|
|
1639
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1640
|
+
margin: "2px 0 8px"
|
|
1641
|
+
} }, "Jev 判断需要单独配置在「触发判定」里的 Jev 凭据;任何失败都会静默回退到本地排序"), (0, react.createElement)("div", { style: {
|
|
1642
|
+
display: "flex",
|
|
1643
|
+
alignItems: "center",
|
|
1644
|
+
gap: 8,
|
|
1645
|
+
marginTop: 8
|
|
1646
|
+
} }, label("是否该问别的会话"), (0, react.createElement)("select", {
|
|
1647
|
+
value: config.swarm.routingAsk === "off" ? "off" : config.swarm.routingAsk === "always" ? "always" : "gated",
|
|
1648
|
+
onChange: (e) => setConfig({
|
|
1649
|
+
...config,
|
|
1650
|
+
swarm: {
|
|
1651
|
+
...config.swarm,
|
|
1652
|
+
routingAsk: e.target.value === "off" ? "off" : e.target.value === "always" ? "always" : "gated"
|
|
1653
|
+
}
|
|
1654
|
+
}),
|
|
1655
|
+
style: settingsInputStyle
|
|
1656
|
+
}, (0, react.createElement)("option", { value: "off" }, "关"), (0, react.createElement)("option", { value: "gated" }, "本地预过滤 + Jev(默认)"), (0, react.createElement)("option", { value: "always" }, "每轮都问"))), (0, react.createElement)("div", { style: {
|
|
1657
|
+
fontSize: 12,
|
|
1658
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1659
|
+
margin: "2px 0 8px"
|
|
1660
|
+
} }, "中间档只在消息看起来涉及别的会话时才问 Jev,几乎不花钱;最后一档每轮都会多一次 Jev 调用"), (0, react.createElement)("div", { style: { marginTop: 8 } }, label("不参与路由的会话"), (0, react.createElement)("textarea", {
|
|
1661
|
+
"aria-label": "routingExclude",
|
|
1662
|
+
placeholder: "每行一个:会话标题关键词或完整 sessionId",
|
|
1663
|
+
rows: 3,
|
|
1664
|
+
value: (config.swarm.routingExclude ?? []).join("\n"),
|
|
1665
|
+
onChange: (e) => setConfig({
|
|
1666
|
+
...config,
|
|
1667
|
+
swarm: {
|
|
1668
|
+
...config.swarm,
|
|
1669
|
+
routingExclude: e.target.value.split("\n").map((line) => line.trim()).filter((line) => line.length > 0)
|
|
1670
|
+
}
|
|
1671
|
+
}),
|
|
1672
|
+
style: {
|
|
1673
|
+
...settingsInputStyle,
|
|
1674
|
+
marginTop: 4,
|
|
1675
|
+
resize: "vertical",
|
|
1676
|
+
width: "100%"
|
|
1677
|
+
}
|
|
1678
|
+
}), (0, react.createElement)("div", { style: {
|
|
1679
|
+
fontSize: 12,
|
|
1680
|
+
color: "var(--dsh-color-muted, #8b90a0)",
|
|
1681
|
+
marginTop: 4
|
|
1682
|
+
} }, "填会话标题里的关键词或完整 sessionId;这些会话不会出现在路由候选和会话名录里,被点名时也会拒绝投递"))), (0, react.createElement)("div", { style: settingsSectionStyle }, (0, react.createElement)("div", { style: {
|
|
1501
1683
|
display: "grid",
|
|
1502
1684
|
gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
|
|
1503
1685
|
gap: 8
|
package/lib/index.d.mts
CHANGED
|
@@ -144,12 +144,57 @@ interface QuotaConfig {
|
|
|
144
144
|
/** Max new consultations per UTC day when enabled (1–100000), default 50. */
|
|
145
145
|
maxPerDay: number;
|
|
146
146
|
}
|
|
147
|
+
interface SwarmConfig {
|
|
148
|
+
/** Master switch for the cross-session tools (ask_session / list_sessions / ask_result). */
|
|
149
|
+
enabled: boolean;
|
|
150
|
+
/** Default response mode when the caller omits both `waitMs` and `detach`. */
|
|
151
|
+
defaultMode: 'wait' | 'detach';
|
|
152
|
+
/** Default wait ceiling in milliseconds when the caller omits `waitMs` (1–10 min). */
|
|
153
|
+
defaultWaitMs: number;
|
|
154
|
+
/** How long detached ask results are kept on disk, in hours (clamped to 1–720). */
|
|
155
|
+
resultTtlHours: number;
|
|
156
|
+
/** Whether the session roster lists subagent sessions. */
|
|
157
|
+
rosterIncludeSubagents: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Route an unnamed question to candidate sessions instead of guessing or
|
|
160
|
+
* sending it blind (pure keyword layer, no model call). Schema default is on.
|
|
161
|
+
*/
|
|
162
|
+
routingEnabled?: boolean;
|
|
163
|
+
/** How many routing candidates to return (1–8, default 3). */
|
|
164
|
+
routingTopN?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Which engine orders the routing candidates (2026-10-19): 'local' (default)
|
|
167
|
+
* uses the keyword scorer alone; 'jev' still recalls with the local scorer —
|
|
168
|
+
* it is the recall step and the safety net — and lets Jev re-rank that closed
|
|
169
|
+
* list. Jev reuses the `trigger.jev` credentials/endpoint config; when it is
|
|
170
|
+
* not configured, or on any failure, the local order is returned unchanged.
|
|
171
|
+
*/
|
|
172
|
+
routingEngine?: 'local' | 'jev';
|
|
173
|
+
/**
|
|
174
|
+
* Whether a user turn should ask the cross-session engine for a suggestion
|
|
175
|
+
* (2026-10-19). 'off' never calls Jev; 'gated' (default) asks only when the
|
|
176
|
+
* pure prefilter thinks the turn points at another session/task; 'always'
|
|
177
|
+
* asks on every turn (one batched Jev call per turn). Any answer is a hint
|
|
178
|
+
* only: nothing is delivered and the model decides.
|
|
179
|
+
*/
|
|
180
|
+
routingAsk?: 'off' | 'gated' | 'always';
|
|
181
|
+
/**
|
|
182
|
+
* Sessions excluded from the whole swarm (2026-10-19): an entry matches a
|
|
183
|
+
* session when it equals its session id (case-insensitive) or is a
|
|
184
|
+
* case-insensitive substring of its title / fallback display name. Excluded
|
|
185
|
+
* sessions never appear in the roster or routing candidates, routing aliases
|
|
186
|
+
* pointing at them are dropped, and an explicit ask_session target that
|
|
187
|
+
* resolves to one is refused with `swarm-excluded`.
|
|
188
|
+
*/
|
|
189
|
+
routingExclude?: string[];
|
|
190
|
+
}
|
|
147
191
|
interface Config {
|
|
148
192
|
enabled: boolean;
|
|
149
193
|
discussion: DiscussionConfig;
|
|
150
194
|
trigger: TriggerConfig;
|
|
151
195
|
ui: UiConfig;
|
|
152
196
|
quota: QuotaConfig;
|
|
197
|
+
swarm: SwarmConfig;
|
|
153
198
|
advisors: AdvisorConfig[];
|
|
154
199
|
}
|
|
155
200
|
declare const Config: Schema<Config>;
|