larkcc 0.3.0 → 0.5.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +177 -23
  3. package/dist/agent.js +138 -32
  4. package/dist/agent.js.map +1 -1
  5. package/dist/app.js.map +1 -1
  6. package/dist/cardkit.d.ts +92 -0
  7. package/dist/cardkit.js +407 -0
  8. package/dist/cardkit.js.map +1 -0
  9. package/dist/config.d.ts +28 -2
  10. package/dist/config.js +49 -45
  11. package/dist/config.js.map +1 -1
  12. package/dist/feishu.d.ts +36 -5
  13. package/dist/feishu.js +343 -41
  14. package/dist/feishu.js.map +1 -1
  15. package/dist/format/builder.d.ts +126 -37
  16. package/dist/format/builder.js +276 -116
  17. package/dist/format/builder.js.map +1 -1
  18. package/dist/format/card-optimize.d.ts +42 -0
  19. package/dist/format/card-optimize.js +74 -0
  20. package/dist/format/card-optimize.js.map +1 -0
  21. package/dist/format/constants.d.ts +87 -14
  22. package/dist/format/constants.js +147 -58
  23. package/dist/format/constants.js.map +1 -1
  24. package/dist/format/document.d.ts +4 -2
  25. package/dist/format/document.js +57 -35
  26. package/dist/format/document.js.map +1 -1
  27. package/dist/format/guide.d.ts +19 -0
  28. package/dist/format/guide.js +201 -0
  29. package/dist/format/guide.js.map +1 -0
  30. package/dist/format/image-resolver.d.ts +31 -0
  31. package/dist/format/image-resolver.js +202 -0
  32. package/dist/format/image-resolver.js.map +1 -0
  33. package/dist/format/index.d.ts +8 -3
  34. package/dist/format/index.js +8 -2
  35. package/dist/format/index.js.map +1 -1
  36. package/dist/format/parser.d.ts +22 -0
  37. package/dist/format/parser.js +55 -12
  38. package/dist/format/parser.js.map +1 -1
  39. package/dist/format/sanitize.d.ts +3 -0
  40. package/dist/format/sanitize.js +16 -7
  41. package/dist/format/sanitize.js.map +1 -1
  42. package/dist/format/thinking.d.ts +29 -0
  43. package/dist/format/thinking.js +50 -0
  44. package/dist/format/thinking.js.map +1 -0
  45. package/dist/resources/format-guide.md +109 -0
  46. package/dist/streaming.d.ts +77 -0
  47. package/dist/streaming.js +293 -0
  48. package/dist/streaming.js.map +1 -0
  49. package/dist/version.d.ts +1 -1
  50. package/dist/version.js +1 -1
  51. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.5.0] - 2026-03-27
11
+
12
+ ### Added
13
+
14
+ - Streaming output support with two modes: CardKit (default) and Update
15
+ - **CardKit mode**: single-card architecture with state machine (idle → creating → streaming → completed), aligned with official openclaw-lark approach
16
+ - **Update mode**: message patch API with auto-fallback chain (cardkit → update → none)
17
+ - Image resolver for external images (download and re-upload to Feishu CDN)
18
+ - Internal CDN domain skip list (feishucdn.com, larksuitecdn.com, etc.)
19
+ - Configurable `card_title` for all streaming modes (default: "Claude")
20
+ - Collapsible thinking section in CardKit complete output
21
+ - Per-tool status words for tool cards (replaces random thinking words)
22
+ - `prepublishOnly` script to package.json for safe npm publishing
23
+ - Card footer metadata (model, tokens, duration) in streaming cards
24
+
25
+ ### Changed
26
+
27
+ - Default streaming mode changed from `update` to `cardkit`
28
+ - CardKit mode no longer sends separate tool call cards (single-card design)
29
+
30
+ ### Removed
31
+
32
+ - `thinking_words` config option (replaced by per-tool status words)
33
+
34
+ ### Fixed
35
+
36
+ - Correct CardKit API format (card_json type, IM message reply, sequence counter)
37
+ - CardKit lazy card creation on first `append()` call
38
+ - Image resolver CDN download failures with internal domain blacklist
39
+ - ESM-compatible `__dirname` polyfill in guide.ts
40
+ - Align all docx block structures with Feishu SDK types to resolve 1770024 error
41
+
8
42
  ## [0.3.0] - 2026-03-26
9
43
 
10
44
  ### Added
package/README.md CHANGED
@@ -313,9 +313,15 @@ setup 不需要填 open_id,发第一条消息自动保存。
313
313
  - 👌 处理中打 reaction,完成换 DONE
314
314
  - 💬 回复引用原消息
315
315
  - ⚡ 工具调用实时展示
316
- - 📋 Markdown 卡片渲染
316
+ - 🌊 流式输出(互斥守卫 + 自适应节流 + 长间隔批处理)
317
+ - 📋 Markdown 卡片渲染(自动标题降级适配)
317
318
  - 📄 超长消息支持分段发送或写入云文档
319
+ - 🛡️ 文档写入容错(单表/批次失败不影响整篇文档)
320
+ - 🎯 格式指导注入(从源头优化输出质量)
318
321
  - 🖼 图片理解(支持富文本多图)
322
+ - 🧠 思考过程分离(可折叠显示 Claude 的推理过程)
323
+ - ⏱ 响应元数据(耗时、token 数实时显示)
324
+ - 🖼 外部图片自动上传(下载 → 飞书 → 渲染,支持卡片和文档)
319
325
  - ⌨️ Slash 命令
320
326
  - ⏹ `/stop` 中断任务
321
327
  - 👥 群聊 @ 触发
@@ -368,6 +374,93 @@ setup 不需要填 open_id,发第一条消息自动保存。
368
374
  \<u\> 显示为 <u>
369
375
  ```
370
376
 
377
+ ## 流式输出
378
+
379
+ 回复内容会以打字机效果逐字显示,无需等待完整输出。
380
+
381
+ 内部使用 FlushController:
382
+ - **互斥守卫** — 防止并发刷新冲突
383
+ - **自适应节流** — 根据上次刷新时间动态调整间隔
384
+ - **长间隔批处理** — 2 秒无新内容自动 flush 剩余缓冲
385
+
386
+ ### 配置
387
+
388
+ ```yaml
389
+ streaming:
390
+ enabled: true # 是否启用流式(默认 true)
391
+ mode: cardkit # update(message.patch)| cardkit | none
392
+ flush_interval_ms: 300 # 最小刷新间隔(毫秒)
393
+ thinking_enabled: false # 是否显示 Claude 思考过程
394
+ fallback_on_error: true # 失败时降级为一次性发送
395
+
396
+ # 卡片标题(所有模式生效)
397
+ card_title: Claude # 留空则不显示 header
398
+
399
+ # 图片自动解析(下载外部图片上传到飞书)
400
+ image_resolver:
401
+ enabled: true # 是否启用(默认 true)
402
+ ```
403
+
404
+ ### 模式说明
405
+
406
+ | 模式 | 说明 | 额外权限 |
407
+ |------|------|---------|
408
+ | `update` | 使用消息 patch API 模拟流式 | 无(默认即可用) |
409
+ | `cardkit` | 使用飞书 CardKit API(真正打字机效果) | `cardkit:card:write` |
410
+ | `none` | 禁用流式,等待完整输出后一次性发送 | 无 |
411
+
412
+ - `cardkit` 模式为默认模式,采用单卡片架构(对齐飞书官方 OpenClaw 方案),全程只有一个消息
413
+ - `cardkit` 模式下工具调用不可见(不打工具卡片),失败时自动降级为 `update`
414
+ - `update` 模式使用消息 patch API 模拟流式,会发送独立的工具调用卡片
415
+ - 流式过程中如果内容超长,最终会自动写入云文档并回复链接
416
+
417
+ ### 中断
418
+
419
+ 流式输出过程中可以使用 `/stop` 中断,卡片会立即显示中断消息。
420
+
421
+ ### 思考过程
422
+
423
+ 开启 `streaming.thinking_enabled: true` 后,Claude 的扩展思考过程会以可折叠面板显示在回复上方:
424
+
425
+ - 流式期间显示 "💭 思考中..." 提示
426
+ - 完成后思考内容收起在折叠面板中,点击可展开查看
427
+ - 关闭时完全过滤 `<thinking>` 标签,用户无感
428
+
429
+ ### 响应元数据
430
+
431
+ 每条回复底部自动显示耗时和 token 用量:
432
+
433
+ ```
434
+ ⏱ 8.2s · 1,234 tokens
435
+ ```
436
+
437
+ 仅显示在卡片消息中,云文档不追加。
438
+
439
+ ## 格式优化
440
+
441
+ ### 卡片自动优化
442
+
443
+ 发送到飞书卡片的 Markdown 会自动经过优化管线处理:
444
+
445
+ 1. **标题降级** — H1→H4, H2-H6→H5(飞书卡片只支持 H4/H5)
446
+ 2. **代码块保护** — 代码块内容不会被其他处理逻辑误解析
447
+ 3. **外部图片上传** — 自动下载外部图片并上传到飞书,替换为 `img_xxx` 格式(卡片和文档均支持)
448
+
449
+ ### 格式指导(System Prompt)
450
+
451
+ 默认启用,通过 Claude Code SDK 的 system prompt 注入飞书格式规范,从源头提升输出质量。整个会话只需注入一次,不重复消耗 token。
452
+
453
+ ```yaml
454
+ format_guide:
455
+ enabled: true # 是否启用(默认 true)
456
+ ```
457
+
458
+ **自定义格式指导:**
459
+
460
+ 编辑 `~/.larkcc/format-guide.md` 即可覆盖默认内容。格式指导内容是纯 Markdown,你可以根据实际需求增减规则。
461
+
462
+ 查看默认格式指导:`resources/format-guide.md`(随项目发布)。
463
+
371
464
  ## 消息类型支持
372
465
 
373
466
  | 类型 | 单聊 | 群聊 |
@@ -408,6 +501,25 @@ overflow:
408
501
  threshold: 2800 # 写文档阈值
409
502
  title_template: "{cwd} - {session_id} - {datetime}"
410
503
 
504
+ # 格式指导(从源头优化 Claude 输出质量)
505
+ format_guide:
506
+ enabled: true # 是否注入飞书格式要求到 prompt
507
+
508
+ # 卡片标题
509
+ card_title: Claude # 留空则不显示 header
510
+
511
+ # 流式输出配置
512
+ streaming:
513
+ enabled: true # 是否启用流式(默认 true)
514
+ mode: cardkit # update | cardkit | none
515
+ flush_interval_ms: 300 # 最小刷新间隔(毫秒)
516
+ thinking_enabled: false # 是否显示思考过程
517
+ fallback_on_error: true # 失败时降级
518
+
519
+ # 图片自动解析(下载外部图片上传到飞书)
520
+ image_resolver:
521
+ enabled: true # 是否启用(默认 true)
522
+
411
523
  commands:
412
524
  deploy: "部署到测试环境"
413
525
 
@@ -429,12 +541,8 @@ reaction:
429
541
  done: DONE # 完成
430
542
  error: OnIt # 出错
431
543
 
432
- # 思考状态词(随机显示)
433
- thinking_words:
434
- - "💭 思考中..."
435
- - "🔍 分析中..."
436
- - "💻 编码中..."
437
- # ... 更多状态词
544
+ # 卡片标题
545
+ card_title: Claude
438
546
 
439
547
  profiles:
440
548
  mybot:
@@ -489,9 +597,13 @@ profiles:
489
597
 
490
598
  - 支持 Markdown 格式(标题、代码块、列表等)
491
599
 
492
- **无效图片过滤:**
600
+ **图片处理:**
493
601
 
494
- 当内容包含 `blob:` 格式的无效图片 URL(如 websearch 返回的临时图片)时,系统会自动过滤并在消息末尾提示。
602
+ - `blob:` 格式的无效图片 URL 自动过滤
603
+ - 外部图片(`https://`)自动下载并上传到飞书,替换为内部 `img_xxx` 格式
604
+ - 上传失败的图片降级为链接,不影响整体流程
605
+ - 图片大小限制 10MB,下载超时 10 秒
606
+ - 卡片和云文档均支持图片渲染
495
607
 
496
608
  **自动清理:**
497
609
 
@@ -536,19 +648,45 @@ overflow:
536
648
 
537
649
  ### 权限
538
650
 
651
+ 权限按功能分组,建议全部开通:
652
+
653
+ #### 基础消息(必开)
654
+
539
655
  | 权限 | 用途 |
540
656
  |------|------|
541
- | `im:message` | 基础消息(含下载消息中的文件) |
542
- | `im:message:send_as_bot` | 发送消息 |
543
- | `im:message.p2p_msg:readonly` | 接收私聊 |
657
+ | `im:message` | 基础消息(含下载消息中的图片、文件) |
658
+ | `im:message:send_as_bot` | 以机器人身份发送消息、回复消息、更新消息(**流式输出也依赖此权限**) |
659
+ | `im:message.p2p_msg:readonly` | 接收私聊消息 |
544
660
  | `im:message.group_at_msg:readonly` | 接收群 @ 消息 |
545
- | `im:message.reactions:write_only` | 打 reaction |
546
- | `cardkit:card:write` | 发送卡片 |
547
- | `docx:document` | 创建/编辑云文档(超长消息写入) |
548
- | `drive:file` | 删除云空间文件(清理旧文档) |
661
+ | `im:message.reactions:write_only` | 打 reaction 表情(处理中/完成/出错状态) |
662
+
663
+ #### 卡片与富文本
664
+
665
+ | 权限 | 用途 |
666
+ |------|------|
667
+ | `cardkit:card:write` | 发送交互式卡片、CardKit 流式输出 |
549
668
 
550
669
  > 💡 `im:message` 权限已包含下载消息中资源文件(图片、文件)的能力
551
670
 
671
+ #### 云文档(超长消息写入)
672
+
673
+ | 权限 | 用途 |
674
+ |------|------|
675
+ | `docx:document` | 创建/编辑云文档(`overflow.mode: document` 时需要) |
676
+ | `drive:file` | 删除云空间文件(自动清理旧文档时需要) |
677
+
678
+ > 💡 不使用文档模式时,这两个权限可以不开
679
+
680
+ #### 开通步骤
681
+
682
+ 1. 进入 [飞书开发者后台](https://open.feishu.cn/) → 选择你的应用
683
+ 2. 左侧菜单 **权限管理** → 搜索并开通上述权限
684
+ 3. 点击 **权限管理** 页面上方的 **权限配置** → 批量开通
685
+ 4. 创建新版本 → 申请发布(企业自建应用管理员审批即可)
686
+ 5. 发布成功后权限生效
687
+
688
+ > ⚠️ 权限变更后需要重新发布应用版本,已运行的 larkcc 需要重启
689
+
552
690
  ### 事件订阅
553
691
 
554
692
  使用**长连接** → 订阅 `im.message.receive_v1`
@@ -748,7 +886,7 @@ You: [Error screenshot] How to fix this
748
886
  You: [Rich text with multiple images] Analyze these images
749
887
  ```
750
888
 
751
- > **Note:** Invalid image URLs (like `blob:` URLs from websearch) are automatically filtered.
889
+ > **Note:** Invalid image URLs (like `blob:` URLs from websearch) are automatically filtered. External images are automatically downloaded and uploaded to Feishu for proper rendering.
752
890
 
753
891
  ## File Support
754
892
 
@@ -821,21 +959,37 @@ larkcc -p mybot # Use specified bot
821
959
 
822
960
  ### Permissions
823
961
 
962
+ #### Basic Messaging (Required)
963
+
824
964
  | Permission | Purpose |
825
965
  |------------|---------|
826
- | `im:message` | Basic message (including file download) |
827
- | `im:message:send_as_bot` | Send messages |
966
+ | `im:message` | Basic message (including image/file download) |
967
+ | `im:message:send_as_bot` | Send/reply/update messages (**streaming also depends on this**) |
828
968
  | `im:message.p2p_msg:readonly` | Receive direct messages |
829
969
  | `im:message.group_at_msg:readonly` | Receive group @ messages |
830
- | `im:message.reactions:write_only` | Add reactions |
831
- | `cardkit:card:write` | Send cards |
832
- | `docx:document` | Create/edit cloud documents |
833
- | `drive:file` | Delete cloud files |
970
+ | `im:message.reactions:write_only` | Add reactions (processing/done/error status) |
971
+
972
+ #### Cards
973
+
974
+ | Permission | Purpose |
975
+ |------------|---------|
976
+ | `cardkit:card:write` | Send interactive cards, CardKit streaming |
977
+
978
+ #### Cloud Documents (for overflow mode)
979
+
980
+ | Permission | Purpose |
981
+ |------------|---------|
982
+ | `docx:document` | Create/edit cloud documents (when `overflow.mode: document`) |
983
+ | `drive:file` | Delete cloud files (auto-cleanup of old documents) |
834
984
 
835
985
  ### Event Subscription
836
986
 
837
987
  Use **Long Connection** → Subscribe to `im.message.receive_v1`
838
988
 
989
+ ## 致谢
990
+
991
+ CardKit 流式卡片实现参考了飞书官方 [openclaw-lark](https://github.com/larksuite/openclaw-lark) 项目的 API 用法与架构设计。
992
+
839
993
  ## Contributing
840
994
 
841
995
  See [CONTRIBUTING.md](CONTRIBUTING.md)
package/dist/agent.js CHANGED
@@ -1,9 +1,14 @@
1
1
  import { query } from "@anthropic-ai/claude-agent-sdk";
2
2
  import os from "os";
3
3
  import { execSync } from "child_process";
4
- import { replyFinalCard, sendToolCard, updateToolCard, } from "./feishu.js";
4
+ import { replyFinalCard, sendToolCard, updateToolCard, getTenantAccessToken, } from "./feishu.js";
5
5
  import { getSession, setSession } from "./session.js";
6
6
  import { logger } from "./logger.js";
7
+ import { getFormatGuideContent } from "./format/guide.js";
8
+ import { parseThinking, stripThinking } from "./format/thinking.js";
9
+ import { resolveImages } from "./format/image-resolver.js";
10
+ import { createStreamingCard } from "./streaming.js";
11
+ import { CardKitController } from "./cardkit.js";
7
12
  const TOOL_LABELS = {
8
13
  Read: "📂 读取文件",
9
14
  Write: "✏️ 写入文件",
@@ -32,12 +37,67 @@ function formatInput(name, input) {
32
37
  function truncate(str, len) {
33
38
  return str.length > len ? str.slice(0, len) + "..." : str;
34
39
  }
40
+ /**
41
+ * 构建 ReplyContext(多个地方复用)
42
+ */
43
+ function buildReplyContext(config, profile, cwd, chatId, rootMsgId) {
44
+ return {
45
+ profile: profile ?? "default",
46
+ cwd,
47
+ sessionId: getSession() ?? "",
48
+ overflow: config.overflow,
49
+ chatId,
50
+ rootMsgId,
51
+ appId: config.feishu.app_id,
52
+ appSecret: config.feishu.app_secret,
53
+ card_table: config.card_table,
54
+ };
55
+ }
56
+ /**
57
+ * 构建底部元数据字符串
58
+ * 格式:⏱ 8.2s · Claude Sonnet 4 · 1,234 tokens · ⚠️ 2 张图片上传失败
59
+ */
60
+ function buildFooterMetadata(elapsedSeconds, model, tokens, imageFailed) {
61
+ const parts = [`⏱ ${elapsedSeconds.toFixed(1)}s`];
62
+ if (model)
63
+ parts.push(model);
64
+ if (tokens)
65
+ parts.push(`${tokens.toLocaleString()} tokens`);
66
+ if (imageFailed && imageFailed > 0)
67
+ parts.push(`⚠️ ${imageFailed} 张图片上传失败`);
68
+ return parts.join(' · ');
69
+ }
35
70
  export async function runAgent(prompt, cwd, config, client, chatId, rootMsgId, images, abortSignal, // 可选中断信号
36
71
  profile // 机器人配置名
37
72
  ) {
38
73
  const sessionId = getSession();
74
+ const startTime = Date.now();
39
75
  let textBuffer = "";
40
76
  const toolMsgMap = new Map();
77
+ // 构建 ReplyContext
78
+ const replyContext = buildReplyContext(config, profile, cwd, chatId, rootMsgId);
79
+ // 创建流式控制器
80
+ // CardKit 模式:单卡片架构,不发工具卡片
81
+ // Update 模式:message.patch 模拟流式,保留工具卡片
82
+ const isCardkitMode = config.streaming?.mode === "cardkit";
83
+ let cardkitCtrl = null;
84
+ let streamingCard = createStreamingCard(config.streaming, client, rootMsgId, replyContext, config.card_title);
85
+ if (isCardkitMode && !streamingCard) {
86
+ cardkitCtrl = new CardKitController({
87
+ client,
88
+ appId: replyContext.appId,
89
+ appSecret: replyContext.appSecret,
90
+ rootMsgId,
91
+ cardTitle: config.card_title ?? "Claude",
92
+ thinkingEnabled: config.streaming?.thinking_enabled === true,
93
+ context: replyContext,
94
+ intervalMs: config.streaming?.flush_interval_ms || 300,
95
+ });
96
+ }
97
+ // 构建格式指导 system prompt(追加到 Claude Code 默认 system prompt 后面)
98
+ const systemPrompt = config.format_guide?.enabled !== false
99
+ ? getFormatGuideContent()
100
+ : undefined;
41
101
  // 构建 prompt content(支持图片)
42
102
  const promptContent = [];
43
103
  if (images && images.length > 0) {
@@ -73,21 +133,21 @@ profile // 机器人配置名
73
133
  permissionMode: config.claude.permission_mode,
74
134
  allowedTools: config.claude.allowed_tools,
75
135
  abortSignal,
136
+ ...(systemPrompt ? { systemPrompt: { type: 'preset', preset: 'claude_code', append: systemPrompt } } : {}),
76
137
  },
77
138
  })) {
78
139
  // 检查是否已中断
79
140
  if (abortSignal?.aborted) {
80
141
  logger.info("Agent aborted by user");
81
- await replyFinalCard(client, chatId, rootMsgId, "⏹ 任务已中断", {
82
- profile: profile ?? "default",
83
- cwd,
84
- sessionId: getSession() ?? "",
85
- overflow: config.overflow,
86
- chatId,
87
- rootMsgId,
88
- appId: config.feishu.app_id,
89
- appSecret: config.feishu.app_secret,
90
- });
142
+ if (cardkitCtrl) {
143
+ await cardkitCtrl.abort("⏹ 任务已中断");
144
+ }
145
+ else if (streamingCard) {
146
+ await streamingCard.abort("⏹ 任务已中断");
147
+ }
148
+ else {
149
+ await replyFinalCard(client, chatId, rootMsgId, "⏹ 任务已中断", replyContext, { cardTitle: config.card_title });
150
+ }
91
151
  break;
92
152
  }
93
153
  if (event.type === "assistant") {
@@ -95,8 +155,21 @@ profile // 机器人配置名
95
155
  for (const block of blocks) {
96
156
  if (block.type === "text" && block.text) {
97
157
  textBuffer += block.text;
158
+ // CardKit 模式:单卡片流式追加
159
+ if (cardkitCtrl)
160
+ await cardkitCtrl.append(block.text);
161
+ // Update 模式:流式追加
162
+ else if (streamingCard)
163
+ await streamingCard.append(block.text);
98
164
  }
99
165
  if (block.type === "tool_use" && block.id && block.name) {
166
+ // CardKit 模式:不发工具卡片(单卡片架构)
167
+ if (isCardkitMode) {
168
+ if (SILENT_TOOLS.has(block.name))
169
+ break;
170
+ logger.tool(block.name, formatInput(block.name, block.input ?? {}));
171
+ break;
172
+ }
100
173
  if (SILENT_TOOLS.has(block.name))
101
174
  break;
102
175
  const label = TOOL_LABELS[block.name] ?? `🔧 ${block.name}`;
@@ -104,21 +177,12 @@ profile // 机器人配置名
104
177
  const input = block.input;
105
178
  const questions = input.questions?.map(q => q.question).join("\n") ?? "";
106
179
  if (questions)
107
- await replyFinalCard(client, chatId, rootMsgId, questions, {
108
- profile: profile ?? "default",
109
- cwd,
110
- sessionId: getSession() ?? "",
111
- overflow: config.overflow,
112
- chatId,
113
- rootMsgId,
114
- appId: config.feishu.app_id,
115
- appSecret: config.feishu.app_secret,
116
- });
180
+ await replyFinalCard(client, chatId, rootMsgId, questions, replyContext, { cardTitle: config.card_title });
117
181
  break;
118
182
  }
119
183
  const detail = formatInput(block.name, block.input ?? {});
120
184
  logger.tool(block.name, detail);
121
- const msgId = await sendToolCard(client, chatId, rootMsgId, label, detail, "running", config.thinking_words);
185
+ const msgId = await sendToolCard(client, chatId, rootMsgId, label, detail, "running", block.name);
122
186
  toolMsgMap.set(block.id, { msgId, label, detail });
123
187
  }
124
188
  }
@@ -144,16 +208,58 @@ profile // 机器人配置名
144
208
  logger.dim(`session saved: ${resultEvent.session_id}`);
145
209
  }
146
210
  if (textBuffer) {
147
- await replyFinalCard(client, chatId, rootMsgId, textBuffer, {
148
- profile: profile ?? "default",
149
- cwd,
150
- sessionId: getSession() ?? "",
151
- overflow: config.overflow,
152
- chatId,
153
- rootMsgId,
154
- appId: config.feishu.app_id,
155
- appSecret: config.feishu.app_secret,
156
- });
211
+ // 计算耗时
212
+ const elapsedSeconds = (Date.now() - startTime) / 1000;
213
+ // 尝试从 SDK result 中提取 token 和 model 信息
214
+ const usage = resultEvent.result?.usage;
215
+ const tokens = usage
216
+ ? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0)
217
+ : undefined;
218
+ const model = resultEvent.result?.model;
219
+ // 解析 thinking
220
+ const thinkingEnabled = config.streaming?.thinking_enabled === true;
221
+ let finalContent;
222
+ let thinking;
223
+ if (thinkingEnabled) {
224
+ const parsed = parseThinking(textBuffer);
225
+ finalContent = parsed.content;
226
+ thinking = parsed.thinking || undefined;
227
+ }
228
+ else {
229
+ finalContent = stripThinking(textBuffer);
230
+ }
231
+ // 解析图片(下载外部图片上传到飞书)
232
+ let imageFailedCount = 0;
233
+ if (finalContent && config.image_resolver?.enabled !== false) {
234
+ try {
235
+ const token = await getTenantAccessToken(config.feishu.app_id, config.feishu.app_secret);
236
+ const imgResult = await resolveImages(finalContent, token);
237
+ finalContent = imgResult.content;
238
+ imageFailedCount = imgResult.failed;
239
+ }
240
+ catch (error) {
241
+ console.error("[IMAGE] Image resolution failed:", error);
242
+ // 继续发送,不阻断流程
243
+ }
244
+ }
245
+ // 构建元数据(一次性构建,避免可变拼接)
246
+ const metadata = buildFooterMetadata(elapsedSeconds, model, tokens, imageFailedCount);
247
+ const completeOptions = {
248
+ metadata,
249
+ thinking,
250
+ cardTitle: config.card_title,
251
+ };
252
+ if (cardkitCtrl) {
253
+ // CardKit 模式:单卡片完成
254
+ await cardkitCtrl.complete(finalContent, completeOptions);
255
+ }
256
+ else if (streamingCard) {
257
+ // Update 模式:最终更新卡片(内部处理 overflow)
258
+ await streamingCard.complete(finalContent, completeOptions);
259
+ }
260
+ else {
261
+ await replyFinalCard(client, chatId, rootMsgId, finalContent, replyContext, completeOptions);
262
+ }
157
263
  }
158
264
  logger.reply(chatId);
159
265
  }
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}