62. 配置、模型运行时与基础设施¶
这个模块干什么¶
这一组文件把磁盘上的 settings、认证与缓存变成一次运行实际使用的 model/provider,并把项目资源的 trust、HTTP、包管理和平台入口放到可复用基础设施层。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/core/model-runtime.ts:94-593
settings 是全局与项目两层的合并结果;项目层是否参与取决于 projectTrusted,而启动迁移负责把旧格式搬到当前存储。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/migrations.ts:21-315
用户选到的模型并不直接等于网络 provider:resolver 先选 Model,runtime 再把 builtin、models.json、扩展、认证、headers 和远程 catalog 组合成可调用 provider。packages/coding-agent/src/core/model-resolver.ts:273-726 packages/coding-agent/src/core/model-runtime.ts:231-593 packages/coding-agent/src/core/provider-composer.ts:399-548
认证分为持久的 auth.json 和本进程的 API key override;后者不会写回凭据文件。packages/coding-agent/src/core/auth-storage.ts:28-271 packages/coding-agent/src/core/runtime-credentials.ts:3-48
其余文件提供明确但较薄的边界:路径/自更新、SDK 组装、代理 dispatcher、配置值展开、footer 数据、实验开关、包命令和 Bun 入口。packages/coding-agent/src/config.ts:315-566 packages/coding-agent/src/core/sdk.ts:38-398 packages/coding-agent/src/core/http-dispatcher.ts:4-106
核心文件速查¶
| 文件 | 一句话职责 | 必读优先级 |
|---|---|---|
packages/coding-agent/src/core/settings-manager.ts |
加载、迁移、合并全局/项目 settings,并提供运行时读取器与写入器。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/core/settings-manager.ts:660-1234 |
⭐⭐⭐ |
packages/coding-agent/src/migrations.ts |
启动时迁移旧 auth、session、tools/bin、keybindings 和 extension/commands 布局。packages/coding-agent/src/migrations.ts:21-315 |
⭐⭐⭐ |
packages/coding-agent/src/core/model-runtime.ts |
model、认证、provider 注册、刷新与 stream 的主运行时。packages/coding-agent/src/core/model-runtime.ts:94-593 |
⭐⭐⭐ |
packages/coding-agent/src/core/model-resolver.ts |
解析 CLI/模式匹配、scope 与初始模型选择优先级。packages/coding-agent/src/core/model-resolver.ts:14-53 packages/coding-agent/src/core/model-resolver.ts:273-726 |
⭐⭐⭐ |
packages/coding-agent/src/core/provider-composer.ts |
把 provider 的静态定义、模型覆盖、认证和 headers 组合成最终 provider。packages/coding-agent/src/core/provider-composer.ts:399-548 |
⭐⭐⭐ |
packages/coding-agent/src/core/auth-storage.ts、runtime-credentials.ts |
分别管理持久凭据与非持久的运行时 key 覆盖。packages/coding-agent/src/core/auth-storage.ts:28-271 packages/coding-agent/src/core/runtime-credentials.ts:3-48 |
⭐⭐⭐ |
packages/coding-agent/src/core/project-trust.ts、trust-manager.ts |
计算项目是否可信,并持久化 trust.json 及资源 gate 的判断。packages/coding-agent/src/core/project-trust.ts:14-96 packages/coding-agent/src/core/trust-manager.ts:8-244 |
⭐⭐⭐ |
packages/coding-agent/src/core/model-config.ts、models-store.ts、remote-catalog-provider.ts |
提供 models.json 快照、远程 catalog 的持久缓存和远程 overlay。packages/coding-agent/src/core/model-config.ts:231-293 packages/coding-agent/src/core/models-store.ts:8-57 packages/coding-agent/src/core/remote-catalog-provider.ts:5-123 |
⭐⭐ |
packages/coding-agent/src/core/model-registry.ts、provider-attribution.ts |
分别是扩展用的同步 facade 与 provider/host 的 attribution header 规则。packages/coding-agent/src/core/model-registry.ts:16-145 packages/coding-agent/src/core/provider-attribution.ts:11-97 |
⭐⭐ |
packages/coding-agent/src/config.ts、core/sdk.ts |
处理目录/安装方式/自更新,并把 settings、models、resources 组装给 SDK。packages/coding-agent/src/config.ts:315-566 packages/coding-agent/src/core/sdk.ts:38-398 |
⭐⭐ |
packages/coding-agent/src/core/package-manager.ts、package-manager-cli.ts、bun/ |
管理包/资源与 CLI 子命令,并给 Bun 二进制做最小启动补丁。packages/coding-agent/src/core/package-manager.ts:795-1238 packages/coding-agent/src/package-manager-cli.ts:55-887 packages/coding-agent/src/bun/cli.ts:1-15 |
⭐⭐ |
精读¶
1. config.ts:名称、目录与安装来源的唯一口径¶
config.ts 定义 package/app/config directory/version 等常量,并以这些常量派生 agent、bin、docs、package 等路径。packages/coding-agent/src/config.ts:315-346 packages/coding-agent/src/config.ts:367-444
因此其它模块不应自己拼 ~/.pi/agent 或包根目录;应经 getAgentDir()、getBinDir()、getDocsPath()、getPackageDir() 取路径。packages/coding-agent/src/config.ts:367-444
detectInstallMethod() 判断当前安装来源,getSelfUpdateCommand() 根据该结果给出可执行的自更新命令,getSelfUpdateUnavailableInstruction() 处理不能自动更新的情况。packages/coding-agent/src/config.ts:488-550 packages/coding-agent/src/config.ts:515-566
2. settings-manager.ts:schema 的加载、覆盖与 trust 边界¶
SettingsManager 通过 SettingsStorage 抽象读取配置,并提供 create()、fromStorage()、inMemory() 三种构造入口。packages/coding-agent/src/core/settings-manager.ts:274-378
它分别保留全局与项目 settings,再生成有效合并配置;项目设置只有在 project trusted 时才参与这一结果。packages/coding-agent/src/core/settings-manager.ts:274-510
loadFromStorage() 和 migrateSettings() 在读取阶段处理旧字段,使调用者读取 getters 时面对的是当前 schema。packages/coding-agent/src/core/settings-manager.ts:381-439
setProjectTrusted()、reload()、applyOverrides() 是运行中改变 trust、重新读盘或加临时覆盖的三个入口。packages/coding-agent/src/core/settings-manager.ts:442-510
常用 getter 集中在同一类中:默认 provider/model/thinking、transport、compaction、retry、HTTP timeout、provider retry、telemetry、packages 与资源路径都从这里读取。packages/coding-agent/src/core/settings-manager.ts:660-1234
getDefaultProjectTrust() 读取非交互模式没有已保存信任决定时使用的默认策略。packages/coding-agent/src/core/settings-manager.ts:899-907
“settings schema”在这里表现为类型化的 load/merge/getter/setter API,而非让所有调用点直接访问 JSON 对象。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/core/settings-manager.ts:660-1234
3. migrations.ts:在正常 runtime 前修旧数据¶
runMigrations(cwd) 在启动时依次执行 auth、session、tools/bin、keybindings 和 extension system 迁移。packages/coding-agent/src/migrations.ts:21-315
auth 迁移把旧 oauth.json 和 settings.json.apiKeys 合并进 auth.json,从而把凭据收敛到专门 storage。packages/coding-agent/src/migrations.ts:21-73
session 迁移修复旧的 agent-root 会话位置,tools 迁移把旧工具目录迁到 bin 约定。packages/coding-agent/src/migrations.ts:84-172
extension 迁移包括将旧 commands/ 目录转为 prompts/,并积累需要展示的弃用警告。packages/coding-agent/src/migrations.ts:257-315
showDeprecationWarnings() 与迁移结果分开,使 interactive 启动可以在 TUI 可用后再阻塞地展示提示。packages/coding-agent/src/migrations.ts:257-315 packages/coding-agent/src/main.ts:785-788
4. model-config.ts、models-store.ts、remote-catalog-provider.ts:静态快照和动态目录不混淆¶
ModelConfig.load() 解析、校验并冻结 models.json,得到 credential-blind 的不可变快照。packages/coding-agent/src/core/model-config.ts:231-293
它不直接读取 API key/OAuth,因此模型描述与“当前用户是否能调用”是两个阶段。packages/coding-agent/src/core/model-config.ts:231-293 packages/coding-agent/src/core/model-runtime.ts:231-593
FileModelsStore 持久化远程 catalog 缓存,InMemoryCodingAgentModelsStore 提供无文件/测试用后端。packages/coding-agent/src/core/models-store.ts:8-57
withRemoteCatalog() 在静态 builtin provider 上叠加 pi.dev catalog,并按 checkedAt、etag、last-modified 管理缓存与再验证。packages/coding-agent/src/core/remote-catalog-provider.ts:5-123
所以 catalog refresh 不必改写本地 models.json;它是 runtime 可更新的 overlay。packages/coding-agent/src/core/remote-catalog-provider.ts:5-123 packages/coding-agent/src/core/models-store.ts:8-57
5. model-resolver.ts:先确定“想用哪一个模型”¶
defaultModelPerProvider 保存各 provider 的首选模型 ID,供没有显式模型时的选择逻辑使用。packages/coding-agent/src/core/model-resolver.ts:14-53
resolveCliModel() 解析 --provider/--model 或 provider/model[:thinking],处理模式匹配、warning/error 与 fallback model id。packages/coding-agent/src/core/model-resolver.ts:385-556
resolveModelScope() 及其带 diagnostics 的变体把 settings/CLI 的模型 pattern 解析成可循环的 scoped models。packages/coding-agent/src/core/model-resolver.ts:273-360
findInitialModel() 的优先级是 CLI 指定、scoped models、已有认证的 settings 默认模型、任一可用模型(优先 provider 默认表)、最后 fallback。packages/coding-agent/src/core/model-resolver.ts:572-726
这一步只解决 Model 对象的选择;它尚未决定最终请求如何认证或加 header。packages/coding-agent/src/core/model-resolver.ts:385-726 packages/coding-agent/src/core/provider-composer.ts:399-548
6. model-runtime.ts 与 model-registry.ts:把选择变成可用运行时¶
ModelRuntime.create() 建立主运行时,refresh()、getAuth()、stream()、registerProvider()、registerNativeProvider()、unregisterProvider() 覆盖其核心生命周期。packages/coding-agent/src/core/model-runtime.ts:94-593
运行时把 builtin providers、远程 catalog、models.json 和 extension provider 组合成可查询、可认证、可 stream 的 Models。packages/coding-agent/src/core/model-runtime.ts:231-593
因此 extension 新注册 provider 后,不是单独维护另一个列表,而是进入同一个 runtime 的可用模型/认证路径。packages/coding-agent/src/core/model-runtime.ts:539-593
ModelRegistry 是给扩展使用的同步兼容 facade,内部仍委托 ModelRuntime,不应被理解为第二套模型数据库。packages/coding-agent/src/core/model-registry.ts:16-145
7. provider-composer.ts 与 provider-attribution.ts:最终 provider 的拼装点¶
composeModelProvider() 是最关键的组合函数:输入 builtin provider、models.json、extension config、OAuth/API key、headers 和 model overrides,输出新的 Provider。packages/coding-agent/src/core/provider-composer.ts:399-548
extension provider 先经 validateExtensionProvider() 做结构检查,再参与组合,避免任意对象直接进入请求路径。packages/coding-agent/src/core/provider-composer.ts:399-548
resolveConfiguredModelHeaders() 解析模型头,resolveCompatibilityRequestConfig() 处理兼容请求设置,configuredRequestAuthStatus() 推断配置后的认证状态。packages/coding-agent/src/core/provider-composer.ts:501-548
因此“同一个 model id”在不同 credentials、extension 覆盖或 headers 下可以得到不同的具体 provider 实例。packages/coding-agent/src/core/provider-composer.ts:399-548
provider-attribution.ts 在特定 provider/host 上加入 attribution/telemetry headers;OpenRouter、NVIDIA NIM、Cloudflare 与 opencode 都有独立分支。packages/coding-agent/src/core/provider-attribution.ts:11-97
这类 headers 在 composition 之后、网络请求之前参与,而不是写进模型选择器。packages/coding-agent/src/core/provider-attribution.ts:11-97 packages/coding-agent/src/core/provider-composer.ts:399-548
8. auth-storage.ts、runtime-credentials.ts 与 auth-guidance.ts:持久性分层¶
AuthStorage 是 auth.json 后端,提供 read、modify、delete、list;readStoredCredential() 是一次性的同步读取帮助函数。packages/coding-agent/src/core/auth-storage.ts:28-271
文件后端以 withLock() / withLockAsync() 串行化修改,并处理锁和 0600 权限。packages/coding-agent/src/core/auth-storage.ts:28-271
RuntimeCredentials 在持久 storage 上叠加进程内 API key override,适合 CLI --api-key,不会把覆盖持久化。packages/coding-agent/src/core/runtime-credentials.ts:3-48 packages/coding-agent/src/main.ts:705-715
认证不存在时的“去 /login”等用户提示集中在 auth-guidance.ts,不散落到 runtime/CLI 的每个错误分支。packages/coding-agent/src/core/auth-guidance.ts:6-25
9. project-trust.ts 与 trust-manager.ts:项目配置先过信任门¶
ProjectTrustStore 读写 trust.json,并提供项目/父目录的信任查找、更新和资源需求判断。packages/coding-agent/src/core/trust-manager.ts:8-244
hasTrustRequiringProjectResources() 把“是否存在需要 gate 的项目资源”变成共享判断,避免每个 loader 重新猜测。packages/coding-agent/src/core/trust-manager.ts:8-244
resolveProjectTrusted() 的顺序是显式 override、extension project_trust 事件、已保存 trust.json、默认策略或 interactive UI prompt。packages/coding-agent/src/core/project-trust.ts:14-96
这个顺序让 --approve/--no-approve 能一次性覆盖,同时仍允许扩展参与决策、用户保存决定、非交互使用默认策略。packages/coding-agent/src/core/project-trust.ts:14-96
资源 loader/package manager 在确定该布尔值后才允许项目 settings 和项目资源进入完整发现路径。packages/coding-agent/src/core/resource-loader.ts:333-493 packages/coding-agent/src/core/package-manager.ts:901-963
10. sdk.ts、defaults.ts 与辅助基础设施¶
createAgentSession() 是 SDK 启动器:组合 ModelRuntime、SettingsManager、SessionManager、DefaultResourceLoader 与 Agent,并串起 attribution、stream 与初始模型选择。packages/coding-agent/src/core/sdk.ts:38-398
SDK 路径和 CLI 路径因此共享 models/settings/resources 的基础对象,而不是 SDK 自己重做一个轻量 provider 栈。packages/coding-agent/src/core/sdk.ts:38-398 packages/coding-agent/src/core/model-runtime.ts:94-593
DEFAULT_THINKING_LEVEL 只有 "medium" 这一个默认常量,避免把默认值散在 resolver 和 settings getter 中。packages/coding-agent/src/core/defaults.ts:1-3
configureHttpDispatcher() 解析 idle timeout,并把 HTTP_PROXY/HTTPS_PROXY 注入 undici 全局 dispatcher。packages/coding-agent/src/core/http-dispatcher.ts:4-106
areExperimentalFeaturesEnabled() 只接受 PI_EXPERIMENTAL === "1",是极小且明确的功能 gate。packages/coding-agent/src/core/experimental.ts:1-3
SourceInfo helpers 把 package manager 的 PathMetadata 转为展示/诊断可携带的来源信息,也可创建 synthetic source。packages/coding-agent/src/core/source-info.ts:1-40
resolve-config-value.ts 支持 !command、$FOO/${FOO} 模板和字面值,并提供 headers 解析与缓存清理。packages/coding-agent/src/core/resolve-config-value.ts:1-287
这意味着 models/provider 配置中的敏感值可在需要时从环境或命令求值,而不必直接写死到 settings。packages/coding-agent/src/core/resolve-config-value.ts:1-287
FooterDataProvider 提供 git branch、extension status 和可用 provider 数,并监视 HEAD/reftable;WSL 挂载仓库可退回轮询。packages/coding-agent/src/core/footer-data-provider.ts:12-388
它是 UI 数据服务而非 model/session 状态的权威来源,因而可独立订阅和刷新。packages/coding-agent/src/core/footer-data-provider.ts:12-388
11. package-manager.ts、package-manager-cli.ts 与 bun/:分发面基础设施¶
DefaultPackageManager 负责解析资源、install、remove、update、listConfiguredPackages 和检查可用更新。packages/coding-agent/src/core/package-manager.ts:795-1238
它既服务扩展包安装,也服务资源解析,所以 package 的 manifest 与普通目录最终会进入同一条资源加载链。packages/coding-agent/src/core/package-manager.ts:795-1238 packages/coding-agent/src/core/resource-loader.ts:333-493
handleConfigCommand() 和 handlePackageCommand() 把 config/install/remove/update/list 接到 SettingsManager、ProjectTrustStore、DefaultPackageManager 与 ModelRuntime。packages/coding-agent/src/package-manager-cli.ts:55-887
普通 main() 在参数解析前调用这两个 handler,因此 package/config 子命令不会创建一般 agent runtime。packages/coding-agent/src/main.ts:492-507
bun/cli.ts 是 Bun 二进制入口:先恢复 sandbox 环境、注册 Bedrock shim,再进入主 CLI。packages/coding-agent/src/bun/cli.ts:1-15
restore-sandbox-env.ts 是 Bun sandbox 环境变量恢复补丁,register-bedrock.ts 只负责 provider module 注入,二者都刻意保持窄小。packages/coding-agent/src/bun/restore-sandbox-env.ts:1-36 packages/coding-agent/src/bun/register-bedrock.ts:1-4
数据流¶
下面追踪用户指定一个模型后,如何从配置走到可请求 provider。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/core/model-runtime.ts:94-593
settings.json / auth.json / models.json / extension providers
-> SettingsManager: 全局 + 已信任项目 + 临时覆盖
-> ModelRuntime.create(): 静态 models、catalog cache/remote overlay、auth stores
-> resolveCliModel() 或 findInitialModel(): 得到 Model
-> RuntimeCredentials: 可选 --api-key 覆盖持久 auth
-> composeModelProvider(): builtin + models.json + extension + auth + headers/overrides
-> provider attribution headers
-> ModelRuntime.stream(): 用具体 Provider 发出请求
settings 的合并与 trust gate 在 SettingsManager,auth 迁移在 runtime 建造之前执行。packages/coding-agent/src/core/settings-manager.ts:274-510 packages/coding-agent/src/migrations.ts:21-315
模型候选/初始选择由 resolver 完成,provider 的具体组合由 composer 和 runtime 完成。packages/coding-agent/src/core/model-resolver.ts:273-726 packages/coding-agent/src/core/provider-composer.ts:399-548 packages/coding-agent/src/core/model-runtime.ts:231-593
CLI --api-key 的覆盖点是 setRuntimeApiKey(),因此它在流程中位于模型已选中之后、可用列表刷新之前。packages/coding-agent/src/main.ts:705-715
自测¶
-
项目 settings 为什么不能只靠“文件存在”就参与最终配置?
packages/coding-agent/src/core/settings-manager.ts:274-510packages/coding-agent/src/core/project-trust.ts:14-96 -
findInitialModel()与composeModelProvider()分别解决什么问题,为什么不能合成一个函数?packages/coding-agent/src/core/model-resolver.ts:572-726packages/coding-agent/src/core/provider-composer.ts:399-548 -
--api-key和保存到auth.json的 credential 在生命周期上有何不同?packages/coding-agent/src/core/auth-storage.ts:28-271packages/coding-agent/src/core/runtime-credentials.ts:3-48packages/coding-agent/src/main.ts:705-715 -
为什么 remote catalog 需要
ModelsStore与 etag/last-modified,而不直接覆写 models.json?packages/coding-agent/src/core/models-store.ts:8-57packages/coding-agent/src/core/remote-catalog-provider.ts:5-123 -
为什么 package/config 子命令在一般
parseArgs()之前处理?packages/coding-agent/src/package-manager-cli.ts:55-887packages/coding-agent/src/main.ts:492-507