@xmanrui/dsh-im 4.13.0 → 4.14.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/lib/client.js +76 -1
- package/lib/index.js +247 -243
- package/package.json +1 -1
- package/plugin-src/client/channels/feishu/api.js +2 -0
- package/plugin-src/client/channels/feishu/index.js +57 -0
- package/plugin-src/client/i18n.js +5 -0
- package/plugin-src/host/channels/feishu/production.mjs +1 -0
- package/plugin-src/host/channels/feishu/rpc.mjs +16 -0
- package/src/channels/feishu/bridge.mjs +510 -3
- package/src/channels/feishu/feishu-runtime.mjs +9 -0
- package/src/channels/feishu/multi-bot-controller.mjs +16 -0
- package/src/channels/feishu/plugin-config-store.mjs +1 -0
- package/src/channels/shared/bot-workspace-store.mjs +14 -1
- package/src/channels/shared/harness-client.mjs +21 -2
- package/src/channels/shared/i18n-en/feishu.mjs +2 -0
- package/src/channels/shared/semantic/artifact.mjs +3 -1
|
@@ -161,7 +161,20 @@ function normalizeDeliveryTargets(value, { version } = {}) {
|
|
|
161
161
|
if (!targets || typeof targets !== 'object' || Array.isArray(targets)) return null;
|
|
162
162
|
const normalizedTargets = Object.create(null);
|
|
163
163
|
for (const [targetId, target] of Object.entries(targets)) {
|
|
164
|
-
|
|
164
|
+
// Backward compatibility: some released builds persisted the target id
|
|
165
|
+
// inside the stored object as well. Accept a redundant targetId that
|
|
166
|
+
// matches the map key when loading a stored document; a mismatch stays
|
|
167
|
+
// invalid so a corrupted file still fails closed.
|
|
168
|
+
let candidate = target;
|
|
169
|
+
if (target && typeof target === 'object' && !Array.isArray(target)
|
|
170
|
+
&& target.targetId !== undefined) {
|
|
171
|
+
if (target.targetId !== targetId) {
|
|
172
|
+
throw deliveryTargetError('invalid-target', 'Invalid target id');
|
|
173
|
+
}
|
|
174
|
+
const { targetId: _legacyTargetId, ...withoutLegacyId } = target;
|
|
175
|
+
candidate = withoutLegacyId;
|
|
176
|
+
}
|
|
177
|
+
const normalized = normalizeDeliveryTarget(candidate, {
|
|
165
178
|
targetId,
|
|
166
179
|
allowSessionSync: version >= CURRENT_DOCUMENT_VERSION,
|
|
167
180
|
});
|
|
@@ -590,6 +590,9 @@ export class HarnessReplyTracker {
|
|
|
590
590
|
const text = assistantMessageText(event);
|
|
591
591
|
const step = Number.isSafeInteger(event.data?.step) ? event.data.step : null;
|
|
592
592
|
this.#assistantText.setCanonical(step, text);
|
|
593
|
+
// canonical 定稿且非空时按 step 透出,供分步推送消费方使用;
|
|
594
|
+
// 先于 commitText 透出,保持 text 更新作为批次末尾的既有语义。
|
|
595
|
+
if (text) pushUpdate({ type: 'assistant-message', step, text });
|
|
593
596
|
this.#commitText(this.#assistantText.text, pushUpdate);
|
|
594
597
|
continue;
|
|
595
598
|
}
|
|
@@ -600,7 +603,19 @@ export class HarnessReplyTracker {
|
|
|
600
603
|
?? nonEmptyText(event.data?.subCallId);
|
|
601
604
|
if (callId) this.#toolNames.set(callId, name);
|
|
602
605
|
this.#lastToolName = name;
|
|
603
|
-
|
|
606
|
+
let argsText = null;
|
|
607
|
+
if (event.data?.arguments !== undefined && event.data?.arguments !== null) {
|
|
608
|
+
if (typeof event.data.arguments === 'string') {
|
|
609
|
+
argsText = event.data.arguments;
|
|
610
|
+
} else {
|
|
611
|
+
try {
|
|
612
|
+
argsText = JSON.stringify(event.data.arguments);
|
|
613
|
+
} catch {
|
|
614
|
+
argsText = undefined;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
pushUpdate({ type: 'tool', name, ...(argsText ? { arguments: argsText } : {}), ...(callId ? { callId } : {}) });
|
|
604
619
|
} else if (event.type === 'tool/result') {
|
|
605
620
|
const callId = nonEmptyText(event.data?.message?.source?.callId)
|
|
606
621
|
?? nonEmptyText(event.data?.callId)
|
|
@@ -1562,7 +1577,11 @@ export class HarnessClient {
|
|
|
1562
1577
|
lastPollSeq = tracker.lastSeq;
|
|
1563
1578
|
if (seqAdvanced) lastProgressAt = Date.now();
|
|
1564
1579
|
if (onUpdate) {
|
|
1565
|
-
|
|
1580
|
+
// latest 模式只投递一条最新进展;assistant-message 是分步推送专用更新,
|
|
1581
|
+
// 且 canonical 去重后可能成为批次唯一变化,绝不能冒充进度投给全部渠道。
|
|
1582
|
+
const visibleUpdates = progressMode === 'all'
|
|
1583
|
+
? updates
|
|
1584
|
+
: updates.filter((update) => update.type !== 'assistant-message').slice(-1);
|
|
1566
1585
|
for (const update of visibleUpdates) {
|
|
1567
1586
|
try {
|
|
1568
1587
|
await onUpdate(update);
|
|
@@ -373,4 +373,6 @@ export default {
|
|
|
373
373
|
'已请求停止后台任务。': 'Requested to stop the background task.',
|
|
374
374
|
'无法安全停止后台任务,请在 Harness 中查看并停止对应任务。': 'Unable to safely stop the background task. Please inspect and stop the matching task in Harness.',
|
|
375
375
|
'任务失败': 'Failed',
|
|
376
|
+
// feishu/bridge.mjs — step push context injection
|
|
377
|
+
'📎 已注入会话上下文': '📎 Context injected',
|
|
376
378
|
};
|
|
@@ -46,7 +46,9 @@ function artifactError(code, message) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function currentTurn(agent) {
|
|
49
|
-
const events = agent?.session?.
|
|
49
|
+
const events = typeof agent?.session?.snapshotEvents === 'function'
|
|
50
|
+
? agent.session.snapshotEvents()
|
|
51
|
+
: agent?.session?.events;
|
|
50
52
|
if (!Array.isArray(events)) return null;
|
|
51
53
|
let turn = null;
|
|
52
54
|
for (const event of events) {
|