mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Rename the tool-presentation transport from code-mode to ptc everywhere that is not written into session logs: the mode config value becomes 'ptc', the preset directory/id becomes ptc, the demo becomes demo:ptc, the dispatch waterfall becomes tools/ptc-dispatch-log (types PtcDispatch*), the prompt rule becomes tools:ptc-only, source/test files become ptc.ts etc., and prose says PTC mode / PTC 模式. The session-persistent vocabulary (durable events tool/code-dispatch*, logged plugin name tools-code-mode, sub-call id segment :code:) intentionally stays and moves in the stacked persistence PR, which is blocked until the SESSION_FORMAT_VERSION v0→v1 migration lands with it. run_code, its code parameter, CodeSdkLanguage, CodeRunFailedError, the dsh-code-runtime family, third-party codex names, and frozen archived notes keep their names.
3.4 KiB
3.4 KiB
Agent Note: 基于既有 seam 的最小 read_image 工具
Status: implemented
English | 中文
问题
多模态附件工作为用户上传建立了完整的持久路径,但模型无法查看磁盘图片。read 按约定拒绝二进制内容,因此被问到截图或渲染图表的 agent 要么失败,要么使用有损的变通方法。PR #598 的独立尝试把工具与循环级路由作用域、按路由控制 schema 可见性和新的会话日志概念放在一起。这些能力不是发布一条带图片且已记录的工具结果所必需的。
决定
两个图片读取操作都放在 dsh-tool-fs,通过现有扩展点发布普通的持久工具结果。
read_image读取文件系统路径。 扩展名选择声明的 PNG/JPEG/WebP/GIF 媒体类型,附件存储的魔数与像素校验保持权威。字节沿ctx.fs.stat→ 有界ctx.fs.readBytes→ctx.attachments.saveImage→fs/observed流动。工具结果包含元数据和一个ImageBlock。FileSystem.readBytes(target, signal, maxBytes)是新的必备提供方原语:字节上限放在 seam 上,任何后端都无法无界缓冲文件;stat 大小先短路,随后的流最多多读一个字节以防 stat 之后的增长(FS_TOO_LARGE)。- 注册随组合条件挂载,执行按路由门禁。 工具只在
ctx.inject(['attachments'], …)作用域内注册。执行时在 I/O 之前通过ctx.llm.resolveModelInfo解析调用路由,并要求inputModalities包含image;能力未知即拒绝。纯文本路由仍可使用此前的持久图片,因为共享 LLM 运行时会在请求组装时把图片投影为占位符。 - PTC mode 以带外方式转发图像:嵌套分派返回规范值(仅限本次执行,不含图像块),并延迟提交一条携带信封和图像的
user角色上下文消息,图片仍会到达下一次请求。 - llm-replay 模型可以声明
inputModalities,因此 keyless ACP 快照可以覆盖支持图片的结果和纯文本拒绝。
考虑过的替代方案
- PR #598 的路由作用域设计使用 request-ready 扩展点、按路由控制 schema 可见性、可逆投影和三个持久概念。共享 LLM 请求投影现在可以处理纯文本路由,无需把工具注册或会话格式放进 agent-loop。
- 用
agent.inject()代替带图像的工具结果——把图像绕过工具结果,作为单独注入的用户消息。拒绝:图像就是工具的结果;拆开只会多一条无收益的日志消息,而工具结果路径本就端到端可用。 - 用魔数嗅探代替扩展名声明——嗅探重复了附件存储已拥有的检测(基于 sharp,权威)。扩展名只是声明;不匹配时按改名修复提示失败关闭,而不是被静默接受,这也让模型对文件名与内容的对应保持诚实。
- 无条件注册、缺存储时执行报错——拒绝;没有附件存储的部署永远无法满足该工具,其 schema 会是常态谎言。相反,路由门禁是逐调用状态,正确的位置就是执行边界。
后果
- 工具在纯文本路由上拒绝执行,而会话历史中已经存在的图片会由请求期占位符表示。
- 重复的图片结果会累积请求成本,直到请求投影或压缩将其移除;内容寻址只去重持久字节。
- 工具结果卡片渲染持久引用而非像素;内嵌预览延后到 UI 包处理。