上下文管理:Compaction / Spill / Token-meter + 后台任务

Compaction(上下文压缩)

capability seam:Definition dsh-compaction(ctx.compaction)+ Provider dsh-compaction-basic + Consumer dsh-command-compact。

三个 declaration-merge 的 log-only 事件:

  • compaction/start { turn }:获取 log 记录的锁(数字=自动 turn、null=手动)。锁最后释放——崩溃变成可检测的孤儿锁而非假的”已完成”。
  • compaction/summary { summary, shadowedRange, shadowedSeqs, shadowedTokenCount, provider, model, usage? }
  • compaction/end { turn, error? }

摘要本身不进 surface;唯一的 surface 变更是一条 user/message + surfaceOp:{op:'replace', start, end}(见 session-model)。

CompactionEngine API:

  • compactIfNeeded(agent, trigger: 'pressure'|'context-overflow', signal)(自动)
  • compactNow(agent, signal)(idle 手动,作为 agent maintenance,无有用范围返回 null 不落盘)
  • compactRegion(start, end, agent, signal)(显式区间,边界须 tool call/result 配对平衡)

挂点:pressure 检查在 serial agent/pre-step(请求派生前);overflow 恢复在 agent/request-error,只有 surface replacement generation 推进才返回 retry。流程:先调可选 ctx.toolResultPruner(确定性 head/middle/tail 修剪,每次替换前 append compaction/prune 影子计价事件)→ 经 ctx.tokenMeter 重测 → 可不产生摘要直接推进 surface。手动失败码:busy|cancelled|changed|summary|commit|persistence。

Token-meter(压力计价)

ctx.tokenMeter:请求压力与 surface 计价的 replay 快照服务。

  • measure(session, requestHeader?) → { logRevision, baseline, surfaceDeltaTokens, totalTokens(请求+响应压力), surfaceTokens, nodes }。
  • baseline.kind: 'usage'(最近一次成功 provider 调用的规范请求包络相同 → 复用真实 usage)或 'estimated'(全启发式)。快照 detached 深冻结,不随后续 fold 增长。
  • compaction 的阈值判断与 prune 计价都消费它。

Spill(大结果溢出落盘)

capability seam:dsh-spill(ctx.spillStore,单方法 saveText)+ dsh-spill-local + dsh-spill-policy。

  • saveText({ owner, source:{toolName, callId}, suggestedName, content }) → SpillRef { locator, bytes, retrievalHint }。SpillLocator 是 branded 不透明模型可见句柄(本地=文件路径),消费者只渲染 retrievalHint 不解析。
  • 本地后端写 <root>/session-<sha256>/…,0700 根、'wx' 0600 独占创建防符号链接(见 engineering 防御模式)。fork 的 session 继承已有 locator,不复制不重新归属。
  • 策略端(tools/post-execute):超过 maxInlineBytes 的纯文本结果替换为 head/tail 预览 + spill 引用;best-effort(存储失败保留原 inline)。seam 只管存储:无保留策略、无检索 API。

Jobs(后台任务运行时)

通用长时运行工具运行时:ctx.jobs(抽象 seam)+ dsh-jobs-local(进程内)+ dsh-tool-jobs(模型面)。内置 JobKindMap { bash, subagent }(可扩展);JobId branded 形如 <kind>-N;访问控制靠 owner 授权而非 id 保密。

  • Producer 契约:JobStart { kind, label, owner?, run(): JobHooks }——runtime 先 preflight 再 run(),之后注册原子化不可失败。JobHooks { cancel, done, readOutput? };done 在资源释放后才 resolve。
  • 状态机:running|stopping|completed|killed|failed;结算 first-wins;completion 最后宣布(reporter 可能同步开模型 turn);reported 标志抑制冗余通知。
  • API:start/list/get/read/kill/wait(id, timeoutMs)/onJobDone/onJobsChanged/attachController。owner disposal 取消并 await 其 job;默认每 owner maxConcurrentJobsPerOwner = 10。

Schedule(session-local 提醒)

durable 提醒,回到原活 session 成为普通后续 turn;ScheduleDeliveryMode 固定 'session-local'(无外部通道、无冷会话调度器)。

  • 三种规则:after(正延迟)、at(绝对时刻,带 offset RFC 3339 或显式时区;DST gap 拒绝、overlap 取较早 instant)、every(固定间隔 ≥300s,锚定创建时刻)。
  • 持久权威是 schedule/change session 事件:create / delete / dispatch。fork 只 fold seedLength 之后的事件,故不继承父 session 的活跃提醒。
  • catch-up:session 冷/忙跨多个目标时,每个 Every 记录只贡献最近一次到期;多条逾期合成一个 follow-up 批次。
  • 活投递:进程内 owner 从 durable fold 导出最早 timer,bounded wait 后重读墙钟;到期工作等 agent 完全 idle、认领 maintenance 相位、排一条 followup()。从不 steer()、从不打断当前 turn。窄崩溃区间 ⇒ best-effort at-least-once。
  • 工具:schedule_create/list/delete;管理调用与到期工作在 Agent 级队列串行化。

与 Jobs 的区别:Jobs 是”现在在后台跑、可随时读/杀”的执行运行时;Schedule 是”未来某刻回到会话”的 durable 提醒(事件溯源、可 fork/replay 恢复)。

相关页面