

























@@ -1101,7 +1101,7 @@ describe("createFeishuReplyDispatcher streaming behavior", () => {
11011101);
11021102});
110311031104-it("shows transient tool status on streaming cards but omits it from the final close", async () => {
1104+it("shows shared transient tool status on streaming cards but omits it from the final close", async () => {
11051105resolveFeishuAccountMock.mockReturnValue({
11061106accountId: "main",
11071107appId: "app_id",
@@ -1124,12 +1124,70 @@ describe("createFeishuReplyDispatcher streaming behavior", () => {
11241124const updateTexts = streamingInstances[0].update.mock.calls.map((call: unknown[]) =>
11251125typeof call[0] === "string" ? call[0] : "",
11261126);
1127-expect(updateTexts.some((text) => text.includes("Using: web_search"))).toBe(true);
1127+expect(updateTexts.some((text) => text.includes("🔎 Web Search"))).toBe(true);
11281128expect(streamingInstances[0].close).toHaveBeenCalledWith("final answer", {
11291129note: "Agent: agent",
11301130});
11311131});
113211321133+it("shows raw command detail in streaming card tool status", async () => {
1134+resolveFeishuAccountMock.mockReturnValue({
1135+accountId: "main",
1136+appId: "app_id",
1137+appSecret: "app_secret",
1138+domain: "feishu",
1139+config: {
1140+renderMode: "card",
1141+streaming: true,
1142+},
1143+});
1144+1145+const { result, options } = createDispatcherHarness({
1146+runtime: createRuntimeLogger(),
1147+});
1148+await options.onReplyStart?.();
1149+result.replyOptions.onToolStart?.({
1150+name: "exec",
1151+args: { command: "pnpm test -- --watch=false" },
1152+detailMode: "raw",
1153+});
1154+result.replyOptions.onPartialReply?.({ text: "final answer" });
1155+await options.onIdle?.();
1156+1157+const updateTexts = streamingInstances[0].update.mock.calls.map((call: unknown[]) =>
1158+typeof call[0] === "string" ? call[0] : "",
1159+);
1160+expect(
1161+updateTexts.some((text) => text.includes("🛠️ Exec: run tests, `pnpm test -- --watch=false`")),
1162+).toBe(true);
1163+});
1164+1165+it("omits message-like tools from streaming card status", async () => {
1166+resolveFeishuAccountMock.mockReturnValue({
1167+accountId: "main",
1168+appId: "app_id",
1169+appSecret: "app_secret",
1170+domain: "feishu",
1171+config: {
1172+renderMode: "card",
1173+streaming: true,
1174+},
1175+});
1176+1177+const { result, options } = createDispatcherHarness({
1178+runtime: createRuntimeLogger(),
1179+});
1180+await options.onReplyStart?.();
1181+result.replyOptions.onToolStart?.({ name: "message" });
1182+result.replyOptions.onPartialReply?.({ text: "final answer" });
1183+await options.onIdle?.();
1184+1185+const updateTexts = streamingInstances[0].update.mock.calls.map((call: unknown[]) =>
1186+typeof call[0] === "string" ? call[0] : "",
1187+);
1188+expect(updateTexts.some((text) => text.includes("Message"))).toBe(false);
1189+});
1190+11331191it("does not suppress a later final after error closeout", async () => {
11341192resolveFeishuAccountMock.mockReturnValue({
11351193accountId: "main",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。