Commit Graph
23 Commits
Author SHA1 Message Date
root 6d00225cc4 feat(tg): 思考块改为可折叠引用块(与工具调用区分)
TG 不支持按消息自定义引用块颜色(竖线颜色跟随客户端主题),按用户
选择采用官方可折叠引用块:默认收起为「💭 思考过程 ▾」,点击展开,
与工具调用的普通蓝色竖线引用块在交互上明确区分。

- rich 模式:Telegram 原生 markdown 可折叠引用语法(**> 开头 + 行尾 ||)
- HTML 模式:markdownToHtml 转换为 <blockquote expandable>
- 思考文本内的 || 全角化,避免被解析成 spoiler 实体
2026-09-17 11:36:15 +08:00
root 0b946ffaa4 Merge remote-tracking branch 'gitea/master'
# Conflicts:
#	lib/bridge.js
#	src/bridge.ts
2026-09-17 11:24:47 +08:00
root 2c50a35795 feat(ask): 键盘常态提供 ✏️ 输入自定义答案 按钮
- 每个带选项的提问键盘固定追加第三行 ✏️ 输入自定义答案
- 点击后该题进入待文本状态(textWanted),丢弃该题已点选的按钮项
- 下一条文本消息自动填充最先待文本的题;带 1:/2: 前缀的作答同样可清除待文本状态
- 已实测:✏️ → 发送 111 → custom 答案正确回流
2026-09-17 11:21:30 +08:00
rootandShirobana Agent Bot <tg-bridge> da06485d64 fix(ask): prototype 拦截器替代 waterfall hook + TG 原生按钮作答
根因:dsh 0.1.5-rc.1 把 'user-questions/request' waterfall 分发到
per-fiber events 注册表,其他 fiber 的 ctx.on 监听(含本插件)永远收不到
分发(实测 root/global/agent 作用域监听全部落空)。

修复:包装 UserQuestionService.prototype.ask(类跨实例共享),无论哪个
fiber/实例发起的 ask 都能拦截到 agent+questions;TG 答案与原 ask 竞速,
保留 dual-path 语义;stop 时恢复原型,热重载不叠加。

功能(应用户要求):
- 提问前显式发送预告文本消息
- 选项改用 TG 原生 inline keyboard 按钮(单选即点即答,多选带提交键)
- 文本作答保留并与按钮作答合并,逐题累计、齐题自动提交
- 附带修复:Telegram API 调用加 15s 客户端超时(代理挂死会卡死通知队列)

Co-authored-by: Shirobana Agent Bot <tg-bridge>
2026-09-17 11:15:16 +08:00
dsh-agent 4039dec03c feat(config): 渲染默认 rich(用户要求 2026-09-14)
Config.rendering 默认 'html'→'rich';显式 'html'/'compat' 仍可强制兼容模式。
profile cordis.patch.yml 的 rendering 同步改为 rich(patch 会覆盖插件默认值,
两处都改才生效)。旧客户端显示'不支持'时用 /rich off 按聊天切回。
2026-09-16 10:42:45 +08:00
owo e748132541 fix: make optional services non-blocking 2026-09-15 21:37:16 +08:00
dsh-agent 5fa2827ed6 feat(tg): 去掉 '> Thinking…' 思考提示流水
用户要求:不再发送思考指示(assistant/chunk 的 reasoning 分支整段移除,
连带 thinkingSessions 状态与相关清理)。tool/call、tool/result、todo/write、
turn/end 的流水保持不变。
2026-09-14 19:16:28 +08:00
dsh-agent 9f03c6c748 fix(ask_user): dsh 0.1.5 走 user-questions/request waterfall
0.1.5 移除了 userQuestions.provider,改为 waterfall 事件注册(与 approval/request 同形);
同时把 2026-09-12 只在编译产物上做过的修复回植到 src,避免源码/产物漂移。
2026-09-14 19:03:08 +08:00
RRRosmontis f3f6a3ebaf feat: admit photos and image documents into the bound session
Telegram 图片消息此前一律回复「暂只支持文本消息」。本改动:

- photo 取最大尺寸(TG 压成 jpeg),document 仅接受 image/png|jpeg|webp|gif
- caption 作为伴随文本块进入同一条消息(不解析为命令)
- 相册(同一 media_group_id)去抖 1.2s 合并为一条多图消息,避免 N 连回合
- 派发走宿主 sessions.prompt RPC(Web 端同通道):模型图像能力校验 +
  附件服务持久化 + mode queue 排队,与纯文本路径的 agent.followup 语义一致
- 错误映射:MODEL_DOES_NOT_SUPPORT_IMAGES → 提示换多模态模型;其余回退
  图片发送失败 + [code] 详情;下载失败即时提示
- 客户端新增 getFile/downloadFile(GET file 端点,复用代理感知 fetch)

tests +7(58/58):photo+caption、png document、pdf 拒绝、相册合并、
模型不支持、下载失败、未绑定。无 emoji 文案。
2026-09-05 17:51:21 +08:00
RRRosmontis 8600835436 fix: /compact 改走宿主命令通道(commands.execute),绕开隔离作用域
根因:compaction-basic 挂载在隔离作用域,插件 ctx 的 ctx.get('compaction')
解析不到(实测 undefined;agent.ctx 亦不可达)。但宿主命令运行时的按 agent
作用层已注册 /compact(command-compact,Web 端同款通道),
commands.find(agent,'compact') 可命中。

因此 /compact 改为 ctx.commands.execute(agent,'/compact',[],signal) 派发:
- 与 Web 端 /compact 完全同语义(busy/错误映射、command/run 生命周期日志)
- 结果文本按 command-compact 固定文案翻译为中文回复;无法识别时回退原文详情
- 忙会话提前提示(busySessions/phase 预检);异步执行不阻塞轮询;同会话去重
- 测试改 mock commands.find/execute(51 全绿)
2026-09-05 17:34:37 +08:00
RRRosmontis d712fb3494 feat: /status 通用状态显示 + /compact 手动压缩;HTML 兼容渲染默认化
- /status:绑定会话/会话 ID/工作区/当前模型/思考强度/上下文长度/
  首 token 平均/输出速率/输入输出 tokens —— 与 Web 底部统计条同源
  同算法(sessionProjections: sessionStats/tokenUsage/contextPressure),
  投影插件缺失时逐组优雅降级;冷会话不强制 resume
- /compact:复用 ctx.compaction.compactNow 手动压缩绑定会话历史,
  异步执行不阻塞轮询,完成/失败均中文通知,同会话去重,
  桥停止/热重载自动中止进行中的压缩
- 全部用户可见文案不使用 emoji
- rendering 默认改 html(兼容优先)+ userQuestions/approval 双通道等
  既有修改一并合入(此前已上线确认)
- tests:+6 覆盖 /status 全字段与 /compact 各分支(51 全绿)
2026-09-05 17:24:41 +08:00
RRRosmontis 20898d5d21 fix: guard markdownToHtml in the HTML fallback path
A throw from the converter used to escape the try/catch and drop the
message; degrade to plain text for that chunk instead.
2026-09-02 16:10:48 +08:00
RRRosmontis cecb655a4b fix: register /cancel as a proper command
Previously /cancel was intercepted inside the 'unknown' branch, and the
comparison used the command WITHOUT the leading slash while parseCommand
returns it WITH one ('/cancel') — the check never matched, so /cancel
always fell through to the unknown-command reply, even with a pending
ask/approval.

Now a first-class command (menu included): closes the TG-side
answer/approval channel when one is pending, otherwise reports that
nothing is awaiting a reply.
2026-09-02 16:07:53 +08:00
RRRosmontis cde6979f2d feat: resilient delivery, live progress visibility, TG-side answering, /stop /mission /new
Delivery & visibility:
- per-chunk retry with capped backoff on rich/HTML sends; rich failure now
  falls back to HTML instead of dropping the reply
- typing heartbeat: refresh sendChatAction every 4s for the whole turn
  (a single action expires in ~5s, long turns looked dead)
- turn/end error / abort / crash-recovery notices reach Telegram
  (API failures were previously invisible)
- tool/call progress summaries, tool/result failure notices, todo progress
- thinking indicator (one notice per reasoning phase, status only)
- notices prefixed '> ' render as Telegram blockquotes; plain-text fallback
- non-text messages get a hint instead of being silently dropped
- busy feedback: a followup queued mid-turn gets an explicit ack

TG-side answering (dual-path race; UI path untouched, first answer wins):
- ask_user_question questions render with letter options on TG; reply A /
  [A] / A,B (multi) / free text / '1: A' per-line for multi-question
- approval requests (approval/request waterfall) answerable from TG:
  [A] allow once / [B] reject; /cancel closes only the TG side

Commands: /stop (cancel current turn), /mission (todo snapshot + busy state),
/new (create a session in the current workspace and attach)

Persistence: chat→session bindings stored at $DSH_HOME/
telegram-channel-bindings.json (override: DSH_TELEGRAM_BINDINGS_FILE) and
restored on start — hot reloads and restarts no longer drop attachments.

Host seams without public surface yet are reached with documented structural
casts (userQuestions provider wrap, approval/request waterfall).

Tests: 41/41 pass. Two pre-existing environment failures in bridge.test.ts
(/last history mirror, assistant mirror) now pass: the former was fixed by
the rich→HTML fallback, the latter needed an event-loop flush after the
(void) listener call since resilient delivery lengthens the chain.
2026-09-01 16:06:00 +08:00
93f3bec975 feat: use Telegram native Rich Message for assistant replies
Co-authored-by: MuziIsabel <MuziIsabel@users.noreply.github.com>
2026-08-18 18:27:32 +08:00
owoandCursor 819010de1c fix: stabilize /model reasoning-effort selection (v0.3.5)
Keep pending model outside the picker map, omit undefined reasoningEffort in selectModel payload, auto-apply single-effort models, and surface RPC errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 22:41:43 +08:00
owoandCursor fb5a334edb feat: /last and bind button for previous Q/A context (v0.3.4)
After attaching a session, show a button and /last command that load the latest human/assistant turn via session.history so phone users can continue with context.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 20:25:07 +08:00
owoandCursor 3566df945b fix: warn when /sessions falls back to live-only list (v0.3.3)
Phone showed 2 sessions because apiProxy catalog failed (pre-0.3.2 inject bug) and live-agent fallback hid cold Web sessions. Surface that mode explicitly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 20:22:20 +08:00
owoandCursor 5dbe833205 fix: resolve apiProxy via ctx.get for /model (v0.3.2)
Cordis throws on ctx.apiProxy without inject; use ctx.get and declare apiProxy inject so catalog and model APIs work under dsh web.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 20:20:55 +08:00
owoandCursor ef0e7f34e3 feat: workspace→session picker and /model switch (v0.3.0)
Align Telegram session list with Web via apiProxy (exclude archived), resume cold sessions on bind, and allow model selection from the phone.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 18:46:56 +08:00
owoandCursor c6125807f7 fix: show session title and workspace in /sessions picker
Read cwd from session.header (not only meta) and title from sessionTitle service or session/title events; list details in the message body and richer inline buttons.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 18:10:43 +08:00
owoandCursor a83af2f33c Simplify install with one-click scripts; honor HTTP(S)_PROXY for Telegram.
Add install.ps1/install.sh, shrink README to script-first flow, register bot commands, and route API calls through undici EnvHttpProxyAgent when a proxy is set (v0.2.2).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 17:46:01 +08:00
owoandCursor 8ef1622822 fix: ship prebuilt lib and drop prepare for one-click git install
Avoids pnpm allowBuilds block on dsh plugin add; README install steps expanded for first-time users.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 17:16:25 +08:00