docs(llm): record that non-reasoning catalog models lose the lone off level
The adapter omits the seam's reasoning field whenever a model carries no reasoning metadata, which is the model's own property and says nothing about where the model came from. Both the JSDoc and the Agent Note read as though only hand-declared models were meant, so a reader would infer that the 251 installed-catalog models pi-ai marks as non-reasoning still offer their single off level. They do not, and that is the point: a picker holding only off misrepresents a provider that thinks by default, because off dispatches the same bytes as naming no effort at all. Behavior is unchanged; only the prose that describes it was narrower than the contract. adapter.spec.ts already pins the catalog case through openai/gpt-4.1 and catalog.spec.ts pins the hand-declared one.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/architecture/2026-08-03-pi-ai-declared-provider-catalog.md
|
||||
2026-08-03-pi-ai-declared-provider-catalog.md: 343b54c5a09be17c0e4c31c219c01b0f1119847a
|
||||
2026-08-03-pi-ai-declared-provider-catalog.zh.md: 8bc1fceb165cf6477be973944f0091db9bbe75f3
|
||||
2026-08-03-pi-ai-declared-provider-catalog.md: 3e926756dcf7d98eea7eb327b6722ff242fe245a
|
||||
2026-08-03-pi-ai-declared-provider-catalog.zh.md: 5385f0f309146b75ab17b0926d700b8fe66a11f8
|
||||
|
||||
@@ -31,6 +31,12 @@ Resolution fails loud and names the route and model at fault: a model the catalo
|
||||
|
||||
The configurable-provider directory is now the installed catalog **joined with** every route the current profiles declare, re-registered when that set changes. Without the join a hand-declared route would have no settings address and no configuration surface could show or edit it.
|
||||
|
||||
### A capability whose only level does nothing is reported unavailable
|
||||
|
||||
pi-ai reports a model with no reasoning metadata as supporting the single level `off`, and the adapter used to pass that straight through. It reaches the seam as a one-item effort list, which every surface renders as a picker holding one selectable control — and that control is a lie: `off` becomes an *omitted* reasoning option at dispatch, byte-for-byte the request that naming no effort already produces. A provider whose own default is to think keeps thinking while the surface shows `off` selected.
|
||||
|
||||
`reasoningInfo` therefore omits the seam's `reasoning` field whenever `model.reasoning` is falsy. The condition is the model's own metadata, not where the model came from, so this covers every hand-declared model **and** the 251 installed-catalog models pi-ai marks as non-reasoning. Those previously offered the lone `off`; they now offer nothing, and the surface shows the provider default alone. Models that do carry reasoning metadata are untouched — their level list still crosses the seam unfiltered, `off` included, because there it selects between real alternatives.
|
||||
|
||||
### Credentials stay outside pi-ai
|
||||
|
||||
pi-ai's `Models` carries its own credential concept — a `CredentialStore` keyed by provider id, with `envApiKeyAuth` resolving `credential.key ?? env(VAR)`. Adopting it would have created a second credential source of truth beside `ctx.credentials` and, worse, reintroduced the ambient fallback the harness deliberately forbids: a named-but-missing `apiKeyEnv` must fail with `MISSING_CREDENTIAL` rather than authenticate with whatever unrelated key the environment holds.
|
||||
|
||||
@@ -31,6 +31,12 @@ Status: implemented
|
||||
|
||||
可配置提供方目录现在是已安装 catalog **与**当前 profile 声明的每条路由的并集,并在该集合变化时重新登记。没有这个并集,手工声明的路由就没有 settings 地址,任何配置界面都无法展示或编辑它。
|
||||
|
||||
### 唯一档位什么也做不到的能力,报告为不可用
|
||||
|
||||
pi-ai 把没有推理元数据的模型报告为只支持 `off` 一档,而适配器此前原样透传。它抵达 seam 时是一个单元素的 effort 列表,任何界面都会把它渲染成一个只有一项可选控件的选择器——而这个控件在撒谎:`off` 在派发时变成被*省略*的 reasoning 选项,与「不点名任何档位」产出的请求逐字节相同。自身默认就在思考的提供方会继续思考,界面却显示 `off` 已选中。
|
||||
|
||||
因此只要 `model.reasoning` 为假,`reasoningInfo` 就省略 seam 的 `reasoning` 字段。判据是模型自身的元数据,而非模型的来源,所以它覆盖每一个手工声明的模型**以及** pi-ai 标记为不具备推理能力的那 251 个已安装 catalog 模型。它们此前提供那个孤零零的 `off`,现在什么也不提供,界面只剩提供方默认。携带推理元数据的模型不受影响——其档位列表仍不经筛选地穿过 seam、`off` 也在内,因为在那里它是在真实备选之间做选择。
|
||||
|
||||
### 凭据留在 pi-ai 之外
|
||||
|
||||
pi-ai 的 `Models` 自带一套凭据概念——按提供方 id 索引的 `CredentialStore`,配合 `envApiKeyAuth` 解析 `credential.key ?? env(VAR)`。采用它会在 `ctx.credentials` 之外制造第二个凭据事实源,更糟的是会把 harness 明确禁止的环境回落重新引进来:点名了却取不到的 `apiKeyEnv` 必须以 `MISSING_CREDENTIAL` 失败,而不是用环境里恰好持有的某个无关密钥完成认证。
|
||||
|
||||
@@ -110,14 +110,15 @@ function resolveReasoningLevel(
|
||||
/**
|
||||
* Selectable reasoning efforts for one model, or nothing at all.
|
||||
*
|
||||
* A model the installed catalog does not describe carries no reasoning
|
||||
* metadata, and pi-ai reports that as the single level `off`. Passing that
|
||||
* through would offer a control that cannot do what it says: `off` is
|
||||
* translated to *omitting* the reasoning option, which for such a model is
|
||||
* byte-for-byte the same request as naming no effort — so a provider whose own
|
||||
* default is to think would keep thinking with `off` selected. Omitting
|
||||
* `reasoning` entirely is the seam's way of saying the capability is
|
||||
* unavailable, which leaves the surface offering only the provider's default.
|
||||
* A model that carries no reasoning metadata — every hand-declared one, and
|
||||
* every catalog model pi-ai marks as non-reasoning — is reported by pi-ai as
|
||||
* supporting the single level `off`. Passing that through would offer a control
|
||||
* that cannot do what it says: `off` is translated to *omitting* the reasoning
|
||||
* option, which for such a model is byte-for-byte the same request as naming no
|
||||
* effort — so a provider whose own default is to think would keep thinking with
|
||||
* `off` selected. Omitting `reasoning` entirely is the seam's way of saying the
|
||||
* capability is unavailable, which leaves the surface offering only the
|
||||
* provider's default.
|
||||
* @param model - the resolved model descriptor.
|
||||
* @param defaultLevel - the profile's configured effort, already validated.
|
||||
* @returns the `reasoning` field, or an empty object when none can be offered.
|
||||
|
||||
Reference in New Issue
Block a user