custom provider model field `max_tokens` is silently ignored
- 主要语言
- Rust
- 星标
- 54.2k
- 派生
- 6.2k
- 平均合并
- 3 天 4 小时
- 30 天内合并 PR
- 240
描述
## Summary
Declarative custom providers (`~/.config/goose/custom_providers/*.json`) define per-model entries that are parsed into `ModelInfo`. `ModelInfo` has no `max_tokens` field, and neither it nor `DeclarativeProviderConfig` uses `deny_unknown_fields` — so a user who writes `"max_tokens": 8192` in a model entry gets zero feedback and zero effect: serde's default "ignore unknown fields" behavior silently drops it.
## To Reproduce
1. Create `~/.config/goose/custom_providers/test.json`:
```json
{
"name": "test",
"engine": "openai",
"display_name": "Test",
"description": "test provider",
"api_key_env": "TEST_API_KEY",
"base_url": "http://localhost:8080/v1/chat/completions",
"models": [
{ "name": "my-model", "context_limit": 32768, "max_tokens": 8192 }
],
"requires_auth": false
}
```
2. Run a session against a self-hosted llama.cpp server via this custom OpenAI-compatible provider and inspect the outgoing request body.
3. The request contains no `max_tokens`/`max_completion_tokens` honoring the declared 8192, and goose never reports that the field was ignored.
## Expected vs actual
- **Expected:** the declared value is honored, or goose rejects/warns about the unsupported field at load time.
- **Actual:** the field is silently ignored. `ModelConfig.max_tokens` is only ever populated from `GOOSE_MAX_TOKENS` or the canonical model registry, so the per-model declaration has no effect.
## Code pointers (origin/main)
- `ModelInfo` — no `max_tokens` field, no `deny_unknown_fields`: `crates/goose-provider-types/src/base.rs:239`
- Declarative config parses `models: Vec`: `crates/goose-providers/src/declarative.rs:120`
- Request builder only emits the cap from `model_config.max_tokens`: `crates/goose-provider-types/src/formats/openai.rs:1710`
- The only sources for `ModelConfig.max_tokens`: `GOOSE_MAX_TOKENS` (`crates/goose/src/config/base.rs:1155`) and the canonical fill (`crates/goose-provider-types/src/model.rs:118`)
## Possible fixes (no preference)
- Support `max_tokens` in `ModelInfo` and map it into `ModelConfig`, or
- add `#[serde(deny_unknown_fields)]` to the declarative provider structs so typos/unsupported fields fail fast, or
- log a warning listing ignored unknown fields when loading custom provider files.
Observed on goose 1.45.0; verified still present on `main` (e20cb8787).
Related: #11049 — its repro also declares a per-model `"max_tokens": 4096` that is not applied, but that issue tracks `context_limit` precedence in the inventory path; the schema/unknown-field gap reported here is distinct and would remain after that fix.
贡献指南
调研方向
The issue is in the declarative provider parsing. Start by examining the ModelInfo struct in crates/goose-provider-types/src/base.rs and the parsing in crates/goose-providers/src/declarative.rs. Understand how the max_tokens field should be added to ModelInfo and then mapped into ModelConfig. Check the request builder in crates/goose-provider-types/src/formats/openai.rs to see where the cap is applied. Done looks like the field being respected in the outgoing request or a clear error/warning if it's unsupported.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- rust
- 领域
- ai-infra-agents, devtools
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 冷清
- 描述清晰度
- 描述清楚
- 新手友好度
- 65/100