DSH / Atlas
2026-07-04proposedsimplification

Prune dead public API and result fields

裁剪无用的公开与结果接口

Several package-root exports, result fields, and convenience methods have no production consumer. They survive because tests import internals through public entry points or because a type anticipated a caller that never arrived. Each item is small in isolation, but together they enlarge the SDK contract, generated catalogs, documentation, and regression matrix without enabling a shipped path. The production corpus is

English

Problem

Several package-root exports, result fields, and convenience methods have no production consumer. They survive because tests import internals through public entry points or because a type anticipated a caller that never arrived. Each item is small in isolation, but together they enlarge the SDK contract, generated catalogs, documentation, and regression matrix without enabling a shipped path.

The production corpus is packages/*/*/src, example sources/config, and runtime scripts. Tests, package READMEs, and Agent Note prose are evidence of publication but not fixed callers. cordis_inspect makes packages/extensions/tool-cordis/src/api-catalog.ts model-visible, and cordis_mount can invoke injected services through guarded real-service proxies, so catalogued service methods and returned shapes are a genuine dynamic product surface. The table therefore distinguishes absence of a fixed repository caller from unreachability: rows touching catalogued vocabulary intentionally contract what model-written mounts can discover and call, while package-root implementation helpers are not reached through that service façade. Exact-symbol searches produce the following inventory:

API elementProduction evidenceSimplification
SurfaceManager.invalidate()Only its unit test calls it; seeding completes before the lazily-created manager exists and the session never replaces its log reference.Delete it and its impossible wholesale-replacement contract.
ToolExecutionResult.callIdEvery hook already receives the immutable ToolExecution; the loop and ACP correlate through the call/session event. No consumer reads the duplicate result field.Remove the field, copy/mismatch guards, and tests that prove the duplicate cannot disagree.
ReactLoopAgent root exportOutside-package named imports are tests; production programs against Agent and creates/resumes through ctx.agents.Return/interface-type Agent and make the concrete loop class package-internal; keep the deliberate synchronous config-only AgentLoop.create() path.
workflow-worker-thread protocol/runtime/session re-exports and named WorkerThreadWorkflowEngineEvery package-name consumer uses the default engine; the workflow Agent Note already defines the worker wire protocol as private.Keep the default plugin class/config contract; drop the duplicate named class export and keep protocol modules source-private.
code-runtime-worker protocol/bootstrap re-exportsOutside-package production/e2e consumers use WorkerThreadCodeRuntime and config, not BootstrapPort, PatchableStream, or worker message/boot types.Keep the runtime class/config contract and make its wire/bootstrap vocabulary source-private.
ACP agentOptions root exportThe helper has only same-file and ACP-test consumers; the sole outside-package production consumer mounts the plugin namespace.Keep name, inject, Config, AcpConfig, and apply; make agentOptions source-private and test it through bridge behavior.
providerWording and completedTurnPrefix root exportsEach has one same-package production caller; only the balanced-prefix helper has a same-package white-box test.Make them source-private and test provider behavior.
depthOf, SubagentDepthError, waitForExit, and exitsWithin root exportsProduction subagent backends consume the in-process runner and subprocess construction/disposal helpers, not these enforcement/test internals. SENSITIVE_ENV_PATTERN is excluded because the SDK helper applies it to caller-supplied environments.Keep depth and exit behavior but make the remaining helpers and error source-private; test through spawn and disposal. Keep the shared credential pattern public.
PersistenceCoordinator.inits, backend inits accessors, seedCoversPrefix, and assertSerializableThe accessors exist for white-box tests; seedCoversPrefix has no outside production importer; assertSerializable has no production caller and duplicates the coordinator append boundary's lossless snapshot.Observe initialization through session/flush, make seedCoversPrefix source-private, and delete assertSerializable. Keep both backends, SessionHeader, and SQLite's version contract.
LlmError.status and replay statusAdapters/replay populate it, but production branches on stable error code/message and never reads raw status.Remove the unread field and replay plumbing while preserving error classification.
BlockAssembler.push() return valueBoth production callers ignore the returned completed block.Return void; keep the deliberately public blocks()/message() contract.
compactRegion's separate session argumentThe fixed caller passes the same object already present as agent.session; the model-visible mount API can also call the method, but accepting two identities permits a mounted plugin to provide an incoherent pair.Keep the manual-region API while deliberately narrowing it to agent.session as the one source of truth.
CompactionResult.startSeq, summarySeq, endSeq, and summaryThe production consumer reads only shadowed range/seq/token accounting; the durable log owns summary and event identity.Remove the four result echoes while keeping both shared transcript renderers.
BasicCompactionEngine estimation/summarization visibilityNo outside production caller invokes the five methods; the implemented Agent Note names only estimateContentTokens() and summarize() as subclass hooks.Make those two protected and the three orchestration-only estimators private.
CodeLogEntry.source/level and RunCodeMeta.dispatchesEvery production consumer maps logs to text; no presenter/model path reads the other fields or the persisted dispatch count.Make code-runtime logs strings (or text-only entries) and remove result-meta dispatch plumbing; keep the local counter that mints deterministic dispatch ids.
CodeRuntime.language and CodeRuntime.isolationThe worker backend supplies the only production values, while Code Mode and every other production caller invoke only run().Remove the unread descriptors while preserving the worker's language, isolation, budgets, cancellation, and disposal behavior.
ToolNotFoundError.toolName, SystemPrompt.config, and BashTask.commandEach stored public value has no production reader.Drop the unread field while retaining error messages, resolved configuration behavior, and task lifecycle.
Backend package-root implementation helpersThe exact inventory below is called only through relative same-package imports. Production namespace imports mount the retained plugin contract without reading these properties; named root consumers are tests.Retain each adapter/provider/service and its config/error contract; stop exporting the listed helper functions/constants at package roots.
Consumer package-root implementation helpersThe exact inventory below has only same-package production callers. Production namespace imports mount plugin contracts without reading helper properties; named root consumers are tests.Retain plugin contracts and stable error codes; move tests to package-local modules or public behavior and stop exporting the listed helpers at package roots.

Grouped helper-export inventory

  • dsh-llm-deepseek: httpErrorCode, serializeMessages, serializeRequest, DONE, parseSse, mapFinishReason, mapUsage, and translate; dsh-llm-pi-ai: buildModel, mapStopReason, mapUsage, toPiContext, and toStreamChunks.
  • dsh-bash-local: DEFAULT_GRACE_MS, ENV_OVERRIDES, killGroup, OutputCollector, and runBash; dsh-bash-sandbox: shellQuote, classifyDenial, and classifyRunnerFailure; dsh-sandbox-local: bwrapProfileArgs, landlockProfileArgs, and seatbeltProfileArgs. The public mutable test-injection fields and their types are outside this proposal.
  • dsh-fs-local: applyLiteralEdit, listDirectory, probe, readForEdit, readTextForDiff, readWholeText, resolveLocalTarget, restoreLineEndings, streamWholeText, and writeFileAtomic.
  • dsh-web-fetch-http: classifyContentType, decoderForCharset, isSameOrigin, parseCharset, and validateFetchUrl; dsh-web-search-exa: mapExaResponse and mapExaResult; dsh-web-search-deepseek: citationSnippets and mapAnthropicResponse; dsh-web-search-perplexity: mapPerplexityResponse and mapPerplexityResult.
  • dsh-tool-fs: READ_LIMIT, STREAM_MIN_SIZE, READ_MAX_BYTES, READ_MAX_LINE_LENGTH, DIFF_CONTEXT, applyReadTool, parseReadArgs, applyWriteTool, formatWriteOutput, parseWriteArgs, applyEditTool, formatEditOutput, parseEditArgs, buildWindow, formatReadOutput, computeHunkDiffs, and diffsFromMeta.
  • dsh-tool-web: WEB_SEARCH_MAX_RESULTS, applyWebSearchTool, formatSearchOutput, parseSearchArgs, presentSearchCall, applyWebFetchTool, formatFetchOutput, parseFetchArgs, presentFetchCall, renderBody, and htmlToMarkdown; dsh-tool-call-timeout-policy: toolTimeoutResult; dsh-compaction-basic: resolveConfig; dsh-tool-bash: renderResult.

Proposal

Remove or demote every row as one bounded coordinated public-surface cleanup. Update package READMEs, JSDoc, generated API/event catalogs, type-equivalence records, exports maps where needed, and tests so they exercise the owning public contract instead of preserving test-only entry points. Do not collapse any capability seam, LLM adapter, persistence backend, or lifecycle quiescence contract.

Alternatives considered

Keep test conveniences and self-contained results public. Public helpers can make white-box tests convenient, self-contained result fields can look ergonomic, and future embedders might want the concrete loop or enumeration methods. Those benefits are hypothetical; today they make every implementation and document explain states that no shipped caller can observe. A real consumer can introduce the smallest contract it needs, with its ownership and failure semantics known.

Keep every catalogued member for model-written mounts. The self-referential toolset is a real generic consumer route, not generated-doc noise. Its value comes from an accurate, composable service API, however, not from preserving duplicate fields or incoherent argument pairs indefinitely; each catalogued contraction above removes a fact available elsewhere on the same execution, agent, or result and updates the API reference in the same change.

Acceptance criteria

  • Exact-symbol searches show no removed API outside this Agent Note and any implemented-Agent Note amendments.
  • Every API element listed in this Agent Note is absent or demoted as specified; deliberately retained extension/test contracts outside the inventory are unchanged.
  • Tool execution, compaction, both LLM adapters, both persistence backends, workflow isolation, and agent creation/resume retain their shipped behavior.
  • Typecheck, coverage, snapshots, doc-sync, module-graph verification, build, and hygiene pass.

Risks

Most removals are compile-visible but runtime-neutral. The compaction argument cleanup deliberately forbids a session/context mismatch while retaining the manual-region API. External pre-release embedders and existing model-written mounts may import fewer helpers, pass fewer arguments, or receive narrower result shapes; this is an intentional product-surface contraction, not merely generated-catalog cleanup. The repository is unreleased, so carrying unsupported surface is the larger foundation cost.

中文

问题

若干包根导出、结果字段和便利方法没有生产消费方。它们之所以存活,要么是因为测试通过公开入口导入了内部实现,要么是因为某个类型预期了一个从未出现的调用者。每一项单独看都很小,但合在一起,它们扩大了 SDK 约定、生成的 catalog、文档和回归矩阵,却没有支撑任何已交付的路径。

生产语料库是 packages/*/*/src、示例源码/配置和运行时脚本。测试、包 README 和 Agent Note 行文是发布的证据,但不是固定调用者。cordis_inspect 使 packages/extensions/tool-cordis/src/api-catalog.ts 对模型可见,cordis_mount 可以通过受保护的真实服务代理调用注入的服务,因此 catalog 中的服务方法和返回形状是真正的动态产品接口。下表因此区分「没有固定的仓库调用者」与「不可达」:涉及 catalog 词汇的行有意收缩模型编写的 mount 能发现和调用的内容,而包根实现辅助函数并不通过该服务门面可达。精确符号搜索得出以下清单:

接口生产证据简化方式
SurfaceManager.invalidate()只有其单元测试调用它;seeding 在惰性创建的 manager 存在之前就已完成,且会话从不替换其日志引用。删除它及其不可能触发的整体替换约定。
ToolExecutionResult.callId每个钩子已经接收不可变的 ToolExecution;循环和 ACP(Agent Client Protocol)通过调用/会话事件关联。没有消费方读取这个重复的结果字段。移除该字段、复制/不匹配守卫,以及证明该重复不可能不一致的测试。
ReactLoopAgent 根导出包外的命名导入都是测试;生产代码面向 Agent 编程,通过 ctx.agents 创建/恢复。将返回类型和接口类型设为 Agent,将具体循环类改为包内部;保留有意设计的同步、仅配置的 AgentLoop.create() 路径。
workflow-worker-thread 的 protocol/runtime/session 再导出与命名的 WorkerThreadWorkflowEngine所有通过包名导入的消费方都使用默认引擎;工作流 Agent Note 已将 worker 协议格式(wire format)定义为私有。保留默认插件类/配置约定;移除重复的命名类导出,将协议模块保持为源码私有。
code-runtime-worker 的 protocol/bootstrap 再导出包外的生产/e2e 消费方使用 WorkerThreadCodeRuntime 和配置,而非 BootstrapPortPatchableStream 或 worker 消息/启动类型。保留运行时类/配置约定,将其协议格式/bootstrap 词汇改为源码私有。
ACP 的 agentOptions 根导出该辅助函数只有同文件和 ACP 测试消费方;唯一的包外生产消费方挂载的是插件命名空间。保留 nameinjectConfigAcpConfigapply;将 agentOptions 改为源码私有,通过桥接层行为测试。
providerWordingcompletedTurnPrefix 根导出各有一个同包生产调用者;只有 balanced-prefix 辅助函数有一个同包白盒测试。改为源码私有,测试提供方行为。
depthOfSubagentDepthErrorwaitForExitexitsWithin 根导出生产 subagent 后端消费的是进程内 runner 和子进程构造/dispose(资源释放)辅助函数,而非这些强制机制和测试内部实现。SENSITIVE_ENV_PATTERN 不在其中,因为 SDK helper 会将它应用于调用方传入的环境。保留深度与退出行为,但将剩余辅助函数和 error 改为源码私有;通过 spawn 和 dispose 测试。保持共享凭据正则公开。
PersistenceCoordinator.inits、后端 inits 访问器、seedCoversPrefixassertSerializable访问器为白盒测试而存在;seedCoversPrefix 没有包外生产导入者;assertSerializable 没有生产调用者,且与 coordinator append 边界的无损快照重复。通过 session/flush 观察初始化,将 seedCoversPrefix 改为源码私有,删除 assertSerializable。保留两个后端、SessionHeader 和 SQLite 的版本约定。
LlmError.status 与回放 status适配器/回放填充它,但生产分支基于稳定的错误码/消息判断,从不读取原始 status。移除未读字段和回放管道,保留错误分类。
BlockAssembler.push() 返回值两个生产调用者都忽略返回的已完成块。返回 void;保留有意公开的 blocks()/message() 约定。
compactRegion 的独立 session 参数固定调用方传入的对象就是 agent.session 中已有的对象;模型可见的 mount API 也可以调用该方法,但同时接受两个独立对象,会让挂载的插件传入不一致的组合。保留手动 region API,同时有意将其收窄为以 agent.session 为唯一真源。
CompactionResult.startSeqsummarySeqendSeqsummary生产消费方只读取 shadowed range/seq/token 统计;持久日志拥有 summary 和事件标识。移除四个结果回显,保留两个共享的 transcript(文本记录)渲染器。
BasicCompactionEngine 的估算/摘要方法可见性没有包外生产调用者调用这五个方法;已实现的 Agent Note 只将 estimateContentTokens()summarize() 命名为子类钩子。将这两个方法改为 protected,其余三个编排专用的估算器改为 private。
CodeLogEntry.source/levelRunCodeMeta.dispatches每个生产消费方都将日志映射为文本;没有 presenter/模型路径读取其他字段或持久化的 dispatch 计数。将 code-runtime 日志改为字符串(或纯文本条目),移除 result-meta 的 dispatch 管道;保留用于生成确定性 dispatch id 的本地计数器。
CodeRuntime.languageCodeRuntime.isolationworker 后端提供唯一的生产值,而 Code Mode 及其他所有生产调用方只调用 run()移除未读描述符,同时保留 worker 的语言、隔离、预算、取消与资源释放行为。
ToolNotFoundError.toolNameSystemPrompt.configBashTask.command每个存储的公开值都没有生产读取者。移除未读字段,保留错误消息、已解析的配置行为和任务生命周期。
后端包根实现辅助函数下方精确清单仅通过相对路径的同包导入调用。生产命名空间导入挂载的是保留的插件约定,不读取这些属性;包根命名导入的消费方都是测试。保留每个适配器/提供方/服务及其配置/错误约定;停止在包根导出所列辅助函数/常量。
消费方包根实现辅助函数下方精确清单只有同包生产调用者。生产命名空间导入挂载的是插件约定,不读取辅助属性;包根命名导入的消费方都是测试。保留插件约定和稳定的错误码;将测试迁移到包内模块或公开行为,停止在包根导出所列辅助函数。

分组辅助导出清单

  • dsh-llm-deepseekhttpErrorCodeserializeMessagesserializeRequestDONEparseSsemapFinishReasonmapUsagetranslatedsh-llm-pi-aibuildModelmapStopReasonmapUsagetoPiContexttoStreamChunks
  • dsh-bash-localDEFAULT_GRACE_MSENV_OVERRIDESkillGroupOutputCollectorrunBashdsh-bash-sandboxshellQuoteclassifyDenialclassifyRunnerFailuredsh-sandbox-localbwrapProfileArgslandlockProfileArgsseatbeltProfileArgs。公开的可变测试注入字段及其类型不在本提案范围内。
  • dsh-fs-localapplyLiteralEditlistDirectoryprobereadForEditreadTextForDiffreadWholeTextresolveLocalTargetrestoreLineEndingsstreamWholeTextwriteFileAtomic
  • dsh-web-fetch-httpclassifyContentTypedecoderForCharsetisSameOriginparseCharsetvalidateFetchUrldsh-web-search-examapExaResponsemapExaResultdsh-web-search-deepseekcitationSnippetsmapAnthropicResponsedsh-web-search-perplexitymapPerplexityResponsemapPerplexityResult
  • dsh-tool-fsREAD_LIMITSTREAM_MIN_SIZEREAD_MAX_BYTESREAD_MAX_LINE_LENGTHDIFF_CONTEXTapplyReadToolparseReadArgsapplyWriteToolformatWriteOutputparseWriteArgsapplyEditToolformatEditOutputparseEditArgsbuildWindowformatReadOutputcomputeHunkDiffsdiffsFromMeta
  • dsh-tool-webWEB_SEARCH_MAX_RESULTSapplyWebSearchToolformatSearchOutputparseSearchArgspresentSearchCallapplyWebFetchToolformatFetchOutputparseFetchArgspresentFetchCallrenderBodyhtmlToMarkdowndsh-tool-call-timeout-policytoolTimeoutResultdsh-compaction-basicresolveConfigdsh-tool-bashrenderResult

提案

以一次有界的、协调的公开接口清理,移除或降级上述每一行。同步更新包 README、JSDoc、生成的 API/事件 catalog、type-equiv 记录、必要的 exports map 以及测试,使测试通过所属的公开约定验证行为,而非保留仅为测试而存在的入口。不折叠任何能力 seam、LLM(大语言模型)适配器、持久化后端或生命周期完全停稳约定。

曾考虑的替代方案

保留测试便利函数和自包含的结果字段为公开。 公开辅助函数可以让白盒测试更方便,自包含的结果字段看起来更易用,未来的嵌入者可能需要具体循环类或枚举方法。这些好处是假设性的;当前它们让每处实现和文档都要解释没有已交付调用者能观察到的状态。真正的消费方可以引入它所需的最小约定,其所有权和失败语义明确。

保留所有 catalog 成员以供模型编写的 mount 使用。 自引用工具集是一条真实的通用消费路径,而非生成文档的噪音。然而,它的价值来自准确、可组合的服务接口,而非无限期保留重复字段或不一致的参数对;上述每一项 catalog 收缩都移除了在同一次执行、同一个 agent(智能体)或同一结果中其他位置已可获得的事实,并在同一变更中更新 API 参考。

验收标准

  • 精确符号搜索显示:在本 Agent Note 及任何对已实现 Agent Note 的修正之外,没有被移除的接口。
  • 本 Agent Note 列出的每个接口均按指定方式移除或降级;清单之外有意保留的扩展/测试约定不变。
  • 工具执行、上下文压缩(context compaction)、两个 LLM 适配器、两个持久化后端、工作流隔离以及 agent 创建/恢复保持其已交付行为。
  • 类型检查、覆盖率、快照、doc-sync(文档同步门禁)、module-graph 校验、构建和 hygiene 通过。

风险

大多数移除在编译时可见但对运行时无影响。上下文压缩参数清理有意禁止会话/上下文不匹配,同时保留手动 region API。外部预发布嵌入者和现有模型编写的 mount 可能导入更少的辅助函数、传递更少的参数或接收更窄的结果形状;这是有意的产品接口收缩,而非仅仅是生成 catalog 的清理。仓库尚未发布,因此承载不受支持的接口才是更大的基础成本。