dsh-caduceus 0.7.0 → 0.10.5
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 +8 -2
- package/README.zh.md +8 -2
- package/cordis.patch.yml +2 -0
- package/dist/bridge/bridge.d.ts +7 -2
- package/dist/bridge/bridge.js +431 -20
- package/dist/bridge/types.d.ts +21 -1
- package/dist/commands/dispatch.d.ts +2 -2
- package/dist/commands/dispatch.js +3 -3
- package/dist/commands/parse.d.ts +15 -2
- package/dist/commands/parse.js +34 -3
- package/dist/config.d.ts +18 -4
- package/dist/config.js +9 -3
- package/dist/export.d.ts +44 -0
- package/dist/export.js +222 -0
- package/dist/home.d.ts +2 -0
- package/dist/home.js +4 -0
- package/dist/i18n.d.ts +42 -0
- package/dist/i18n.js +94 -0
- package/dist/index.js +48 -1
- package/dist/interactive/approval.js +1 -1
- package/dist/interactive/cards.d.ts +2 -1
- package/dist/interactive/cards.js +3 -1
- package/dist/interactive/runtime.d.ts +4 -0
- package/dist/interactive/runtime.js +15 -0
- package/dist/interactive/types.d.ts +2 -0
- package/dist/metrics.d.ts +28 -0
- package/dist/metrics.js +135 -0
- package/dist/render/cards.d.ts +4 -0
- package/dist/render/cards.js +17 -0
- package/dist/render/permission-card.d.ts +23 -0
- package/dist/render/permission-card.js +22 -0
- package/dist/status.d.ts +22 -0
- package/dist/status.js +95 -0
- package/dist/transport/feishu-response.d.ts +1 -0
- package/dist/transport/feishu-response.js +25 -0
- package/dist/transport/lark.js +5 -4
- package/dist/transport/normalize.js +3 -1
- package/dist/usage.d.ts +23 -0
- package/dist/usage.js +77 -0
- package/package.json +1 -1
|
@@ -88,7 +88,9 @@ export function normalizeMessageEvent(raw, botOpenId) {
|
|
|
88
88
|
if (senderType !== 'user')
|
|
89
89
|
return undefined;
|
|
90
90
|
const message = raw.message;
|
|
91
|
-
|
|
91
|
+
// Only a real thread_id makes a topic. In p2p, root_id can equal the
|
|
92
|
+
// message id; treating it as threadId produced bogus "topic replies".
|
|
93
|
+
const threadId = firstNonEmpty(message.thread_id);
|
|
92
94
|
const rootId = firstNonEmpty(message.root_id);
|
|
93
95
|
const mentions = (message.mentions ?? [])
|
|
94
96
|
.map((mention) => mention.id?.open_id)
|
package/dist/usage.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-usage aggregation from a session log (`sessionQuery.readSession`).
|
|
3
|
+
*
|
|
4
|
+
* The in-memory StatusTracker still feeds the process card, but `/usage` must
|
|
5
|
+
* work on a freshly restarted gateway, so it aggregates the durable event log
|
|
6
|
+
* instead.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-caduceus/usage
|
|
9
|
+
*/
|
|
10
|
+
import type { UsageTotals } from './status.js';
|
|
11
|
+
export interface UsageTurn {
|
|
12
|
+
readonly turn: number;
|
|
13
|
+
readonly usage: UsageTotals;
|
|
14
|
+
}
|
|
15
|
+
export interface UsageReport {
|
|
16
|
+
/** Per-turn totals, ordered by turn descending (newest first). */
|
|
17
|
+
readonly turns: readonly UsageTurn[];
|
|
18
|
+
readonly total: UsageTotals;
|
|
19
|
+
}
|
|
20
|
+
/** Aggregate every `assistant/message` usage event, grouped by `data.turn`. */
|
|
21
|
+
export declare function aggregateUsage(events: readonly unknown[]): UsageReport;
|
|
22
|
+
/** Render the three-line usage report; empty log is a distinct state. */
|
|
23
|
+
export declare function renderUsageReport(report: UsageReport): string;
|
package/dist/usage.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
function asRecord(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null
|
|
3
|
+
? value
|
|
4
|
+
: undefined;
|
|
5
|
+
}
|
|
6
|
+
function usageOf(value) {
|
|
7
|
+
const record = asRecord(value);
|
|
8
|
+
if (record === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
const num = (key) => typeof record[key] === 'number' ? record[key] : 0;
|
|
11
|
+
const input = num('inputTokens');
|
|
12
|
+
const output = num('outputTokens');
|
|
13
|
+
const cacheRead = num('cacheReadTokens');
|
|
14
|
+
const cacheWrite = num('cacheWriteTokens');
|
|
15
|
+
const providerTotal = typeof record['totalTokens'] === 'number' ? record['totalTokens'] : 0;
|
|
16
|
+
if (input === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0 && providerTotal === 0) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
const total = providerTotal > 0 ? providerTotal : input + output + cacheRead + cacheWrite;
|
|
20
|
+
return { input, output, cacheRead, cacheWrite, total };
|
|
21
|
+
}
|
|
22
|
+
function add(total, delta) {
|
|
23
|
+
return {
|
|
24
|
+
input: total.input + delta.input,
|
|
25
|
+
output: total.output + delta.output,
|
|
26
|
+
cacheRead: total.cacheRead + delta.cacheRead,
|
|
27
|
+
cacheWrite: total.cacheWrite + delta.cacheWrite,
|
|
28
|
+
total: total.total + delta.total,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const ZERO = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 };
|
|
32
|
+
/** Aggregate every `assistant/message` usage event, grouped by `data.turn`. */
|
|
33
|
+
export function aggregateUsage(events) {
|
|
34
|
+
const byTurn = new Map();
|
|
35
|
+
let total = ZERO;
|
|
36
|
+
for (const event of events) {
|
|
37
|
+
const row = asRecord(event);
|
|
38
|
+
if (row?.type !== 'assistant/message')
|
|
39
|
+
continue;
|
|
40
|
+
const data = asRecord(row.data);
|
|
41
|
+
if (data === undefined)
|
|
42
|
+
continue;
|
|
43
|
+
const usage = usageOf(data.usage);
|
|
44
|
+
if (usage === undefined)
|
|
45
|
+
continue;
|
|
46
|
+
const turn = typeof data.turn === 'number' ? data.turn : 0;
|
|
47
|
+
byTurn.set(turn, add(byTurn.get(turn) ?? ZERO, usage));
|
|
48
|
+
total = add(total, usage);
|
|
49
|
+
}
|
|
50
|
+
const turns = [...byTurn.entries()]
|
|
51
|
+
.sort((left, right) => right[0] - left[0])
|
|
52
|
+
.map(([turn, usage]) => ({ turn, usage }));
|
|
53
|
+
return { turns, total };
|
|
54
|
+
}
|
|
55
|
+
function line(label, usage) {
|
|
56
|
+
return (label +
|
|
57
|
+
':输入 ' +
|
|
58
|
+
usage.input +
|
|
59
|
+
' · 输出 ' +
|
|
60
|
+
usage.output +
|
|
61
|
+
' · 缓存命中 ' +
|
|
62
|
+
usage.cacheRead +
|
|
63
|
+
' · 合计 ' +
|
|
64
|
+
usage.total);
|
|
65
|
+
}
|
|
66
|
+
/** Render the three-line usage report; empty log is a distinct state. */
|
|
67
|
+
export function renderUsageReport(report) {
|
|
68
|
+
if (report.turns.length === 0)
|
|
69
|
+
return '会话里还没有用量记录';
|
|
70
|
+
const current = report.turns[0];
|
|
71
|
+
const previous = report.turns[1];
|
|
72
|
+
return [
|
|
73
|
+
line('本回合', current.usage),
|
|
74
|
+
previous === undefined ? '上回合:暂无' : line('上回合', previous.usage),
|
|
75
|
+
line('会话合计', report.total),
|
|
76
|
+
].join('\n');
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-caduceus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Feishu/Lark surface plugin for DeepSeek Harness (dsh): one topic per session, SOUL persona sync, streaming process cards, /status and /doctor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|