dsh-lark-bot 0.19.3 → 0.19.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/dist/cli.js +122 -2
- package/dist/cli.js.map +1 -1
- package/dist/plugin.js +122 -2
- package/dist/plugin.js.map +1 -1
- package/dist/skill.d.ts +26 -0
- package/dist/skill.js +94 -0
- package/dist/skill.js.map +1 -0
- package/package.json +5 -1
package/dist/cli.js
CHANGED
|
@@ -2779,6 +2779,18 @@ function patchYamlFor(options) {
|
|
|
2779
2779
|
"",
|
|
2780
2780
|
"- id: hmr",
|
|
2781
2781
|
" disabled: true",
|
|
2782
|
+
"",
|
|
2783
|
+
// Model-invocable channel skill: expose the dsh-lark-bot operations guide
|
|
2784
|
+
// to THIS agent session's skill catalog — the one the `skill` tool reads.
|
|
2785
|
+
// The bridge engine registers the same skill on its own cordis context
|
|
2786
|
+
// (plugin.ts), but that context is never the one the model reads. This row
|
|
2787
|
+
// ensures the skill also lands on the agent runtime's context so that
|
|
2788
|
+
// `skill("dsh-lark-bot")` resolves in a live SDK session. It is kept
|
|
2789
|
+
// outside the bridgeTools gate because it needs no callback endpoint and
|
|
2790
|
+
// is also useful to the guardian's core-only safe profile.
|
|
2791
|
+
"- insert:",
|
|
2792
|
+
" - id: lark-skill",
|
|
2793
|
+
` name: '${own.name}/skill'`,
|
|
2782
2794
|
""
|
|
2783
2795
|
];
|
|
2784
2796
|
if (bridgeTools) {
|
|
@@ -7314,7 +7326,11 @@ function processElements(state, locale, maxTools) {
|
|
|
7314
7326
|
function thinkingPanel(state, locale, maxTools) {
|
|
7315
7327
|
return {
|
|
7316
7328
|
tag: "collapsible_panel",
|
|
7317
|
-
|
|
7329
|
+
// Default to collapsed: the top-level compatibility snapshot already shows
|
|
7330
|
+
// the latest status and current tools, so keep the detailed per-tool list
|
|
7331
|
+
// collapsed to avoid two overlapping expanded surfaces. (Both sections are
|
|
7332
|
+
// retained for now.)
|
|
7333
|
+
expanded: false,
|
|
7318
7334
|
header: {
|
|
7319
7335
|
title: { tag: "plain_text", content: `\u2699\uFE0F ${locale === "zh_cn" ? "\u6267\u884C\u8FC7\u7A0B" : "Execution"} \xB7 ${summaryText(state, locale)}` },
|
|
7320
7336
|
icon: { tag: "standard_icon", token: "down-small-ccm_outlined" },
|
|
@@ -8000,6 +8016,15 @@ async function runAttempt(input, cwd, workspaceCwd, sessionId, resuming, replyOp
|
|
|
8000
8016
|
log.warn("run-flow", "card-update-failed", { scope: input.scope, error });
|
|
8001
8017
|
}
|
|
8002
8018
|
};
|
|
8019
|
+
const unregisterReanchor = input.runCardAnchors?.register(input.chatId, async () => {
|
|
8020
|
+
if (state.terminal !== "running") return;
|
|
8021
|
+
try {
|
|
8022
|
+
await controller.update(renderer(state, density, Date.now()));
|
|
8023
|
+
if (typeof controller.reanchor === "function") await controller.reanchor();
|
|
8024
|
+
} catch (error) {
|
|
8025
|
+
log.warn("run-flow", "card-reanchor-failed", { scope: input.scope, error });
|
|
8026
|
+
}
|
|
8027
|
+
});
|
|
8003
8028
|
const showResumeRecovery = async (error) => {
|
|
8004
8029
|
if (classifySessionError(errorMessage(error)) === void 0) throw error;
|
|
8005
8030
|
resumeFailure = errorMessage(error);
|
|
@@ -8173,6 +8198,7 @@ async function runAttempt(input, cwd, workspaceCwd, sessionId, resuming, replyOp
|
|
|
8173
8198
|
unsubscribeQuestion?.();
|
|
8174
8199
|
unsubscribePlan?.();
|
|
8175
8200
|
unsubscribeApproval?.();
|
|
8201
|
+
unregisterReanchor?.();
|
|
8176
8202
|
}
|
|
8177
8203
|
};
|
|
8178
8204
|
let producerStarted = false;
|
|
@@ -11904,6 +11930,41 @@ var ResilientCardStreamController = class {
|
|
|
11904
11930
|
});
|
|
11905
11931
|
}
|
|
11906
11932
|
}
|
|
11933
|
+
/**
|
|
11934
|
+
* Recall the current card and re-create it as the newest top-level message in
|
|
11935
|
+
* the chat, rebinding the controller to the fresh message id. Because Feishu
|
|
11936
|
+
* cannot reorder an existing message, this is the only way to keep an
|
|
11937
|
+
* in-progress process card visible at the tail while interim agent bubbles are
|
|
11938
|
+
* appended below. Best-effort: if the recall fails the card is left where it
|
|
11939
|
+
* is (no duplicate is created); if the controller is closed or failed the id
|
|
11940
|
+
* is left unchanged.
|
|
11941
|
+
*/
|
|
11942
|
+
async reanchor() {
|
|
11943
|
+
if (this.closed || this.failed) return this.messageId;
|
|
11944
|
+
if (this.inFlight !== void 0) await this.inFlight;
|
|
11945
|
+
if (this.timer !== void 0) {
|
|
11946
|
+
clearTimeout(this.timer);
|
|
11947
|
+
this.timer = void 0;
|
|
11948
|
+
}
|
|
11949
|
+
const card = this.latest;
|
|
11950
|
+
if (card === void 0) return this.messageId;
|
|
11951
|
+
try {
|
|
11952
|
+
await this.channel.recallMessage(this.messageId);
|
|
11953
|
+
} catch (error) {
|
|
11954
|
+
log.warn("lark-card-stream", "reanchor-recall-failed", {
|
|
11955
|
+
messageId: this.messageId,
|
|
11956
|
+
error: error instanceof Error ? error.message : String(error)
|
|
11957
|
+
});
|
|
11958
|
+
return this.messageId;
|
|
11959
|
+
}
|
|
11960
|
+
const sent = await this.channel.send(this.chatId, { card }, {});
|
|
11961
|
+
if (!sent.messageId) throw new Error("Feishu card re-anchor returned no message_id");
|
|
11962
|
+
this.messageId = sent.messageId;
|
|
11963
|
+
this.latest = card;
|
|
11964
|
+
this.dirty = false;
|
|
11965
|
+
this.failed = false;
|
|
11966
|
+
return this.messageId;
|
|
11967
|
+
}
|
|
11907
11968
|
};
|
|
11908
11969
|
function adaptLarkChannel(channel) {
|
|
11909
11970
|
const base = {
|
|
@@ -14147,6 +14208,63 @@ function wizardContextFor(event, deps, channel, scope) {
|
|
|
14147
14208
|
};
|
|
14148
14209
|
}
|
|
14149
14210
|
|
|
14211
|
+
// src/bridge/run-card-anchors.ts
|
|
14212
|
+
var RunCardAnchors = class {
|
|
14213
|
+
byChatId = /* @__PURE__ */ new Map();
|
|
14214
|
+
/**
|
|
14215
|
+
* Register a re-anchor callback for a chat. Returns a disposer; safe to call
|
|
14216
|
+
* more than once (idempotent).
|
|
14217
|
+
*/
|
|
14218
|
+
register(chatId, reanchor) {
|
|
14219
|
+
const set = this.byChatId.get(chatId) ?? /* @__PURE__ */ new Set();
|
|
14220
|
+
set.add(reanchor);
|
|
14221
|
+
this.byChatId.set(chatId, set);
|
|
14222
|
+
let active = true;
|
|
14223
|
+
return () => {
|
|
14224
|
+
if (!active) return;
|
|
14225
|
+
active = false;
|
|
14226
|
+
set.delete(reanchor);
|
|
14227
|
+
if (set.size === 0) this.byChatId.delete(chatId);
|
|
14228
|
+
};
|
|
14229
|
+
}
|
|
14230
|
+
/** Notify that a new bubble was delivered to the chat. */
|
|
14231
|
+
async bubbleSent(chatId) {
|
|
14232
|
+
const set = this.byChatId.get(chatId);
|
|
14233
|
+
if (!set || set.size === 0) return;
|
|
14234
|
+
await Promise.allSettled([...set].map((reanchor) => reanchor()));
|
|
14235
|
+
}
|
|
14236
|
+
};
|
|
14237
|
+
function attachRunCardAnchors(channel, anchors) {
|
|
14238
|
+
const notify = (chatId) => {
|
|
14239
|
+
void anchors.bubbleSent(chatId).catch((error) => {
|
|
14240
|
+
log.warn("run-card-anchors", "bubble-sent-failed", {
|
|
14241
|
+
chatId,
|
|
14242
|
+
error: error instanceof Error ? error.message : String(error)
|
|
14243
|
+
});
|
|
14244
|
+
});
|
|
14245
|
+
};
|
|
14246
|
+
return {
|
|
14247
|
+
...channel,
|
|
14248
|
+
async sendMarkdown(chatId, markdown2, options) {
|
|
14249
|
+
const result = await channel.sendMarkdown(chatId, markdown2, options);
|
|
14250
|
+
notify(chatId);
|
|
14251
|
+
return result;
|
|
14252
|
+
},
|
|
14253
|
+
async sendCard(chatId, card, options) {
|
|
14254
|
+
if (typeof channel.sendCard !== "function") return void 0;
|
|
14255
|
+
const result = await channel.sendCard(chatId, card, options);
|
|
14256
|
+
notify(chatId);
|
|
14257
|
+
return result;
|
|
14258
|
+
},
|
|
14259
|
+
async sendFile(chatId, fileName, content, options) {
|
|
14260
|
+
if (typeof channel.sendFile !== "function") return void 0;
|
|
14261
|
+
const result = await channel.sendFile(chatId, fileName, content, options);
|
|
14262
|
+
notify(chatId);
|
|
14263
|
+
return result;
|
|
14264
|
+
}
|
|
14265
|
+
};
|
|
14266
|
+
}
|
|
14267
|
+
|
|
14150
14268
|
// src/notify/server.ts
|
|
14151
14269
|
import { createServer } from "http";
|
|
14152
14270
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
@@ -17662,6 +17780,7 @@ async function startBridgeEngine(options) {
|
|
|
17662
17780
|
const questions = new QuestionRegistry();
|
|
17663
17781
|
const plans = new PlanApprovalRegistry();
|
|
17664
17782
|
const densityStore = new DensityStore();
|
|
17783
|
+
const runCardAnchors = new RunCardAnchors();
|
|
17665
17784
|
const models = new ModelStore();
|
|
17666
17785
|
const wizardStore = new WizardStore();
|
|
17667
17786
|
const dshConfig = new DshProviderManager({ env: process.env });
|
|
@@ -17892,6 +18011,7 @@ async function startBridgeEngine(options) {
|
|
|
17892
18011
|
plans,
|
|
17893
18012
|
densityStore,
|
|
17894
18013
|
channel: streaming,
|
|
18014
|
+
runCardAnchors,
|
|
17895
18015
|
defaultWorkspace,
|
|
17896
18016
|
replyTo: first.messageId,
|
|
17897
18017
|
deliverFinalReply: (replyScope, chatId, markdown2, options2) => replyDispatcher.deliver(replyScope, chatId, markdown2, options2),
|
|
@@ -18094,7 +18214,7 @@ async function startBridgeEngine(options) {
|
|
|
18094
18214
|
error: "channel does not expose getBotIdentity"
|
|
18095
18215
|
});
|
|
18096
18216
|
}
|
|
18097
|
-
streaming = adaptLarkChannel(bridge.channel);
|
|
18217
|
+
streaming = attachRunCardAnchors(adaptLarkChannel(bridge.channel), runCardAnchors);
|
|
18098
18218
|
larkChannel = bridge.channel;
|
|
18099
18219
|
const deliverUpdateResult = async () => {
|
|
18100
18220
|
await updateHandoff.deliverResult(async (state) => {
|