feat(model): 按 provider 形状独立适配推理开关 + per-persona 提供商链真接线(裁决 03.4.2/08.4.1/03.4.1 余项)
- 新增 reasoning_shape.go:**每个 provider 形状一个 resolver,只发自己形状的字段**
· deepseek:thinking{type} + reasoning_effort(依据 DevDocs/reference/deepseek 官方本地副本)
· vllm:chat_template_kwargs.enable_thinking · dashscope:顶层 enable_thinking(**只允许显式声明**)
· openai:仅 reasoning_effort · anthropic:自己的 thinking{budget_tokens}(未改)
· 未知 kind → WARN 且一个字段都不发(不许静默失效)
- 形状载体:models.json 组级 `reasoning.kind`(可热更新,未声明则不写该键)+ env `LLM_REASONING_KIND`
- 红线:`effort:none` 在只有布尔开关的形状上翻成**显式关思考**,绝不降成任何强度档
- 03.4.1 余项:`Request.PersonaID` + `RuntimeLLM.ForPersona(pid)` 视图;
每 persona 协议一条链并消费 `RouteProviderForPersona`;`agent/request.go` 非流式路径同一钩子
- **生产装配(主会话补)**:默认 agent 与 personaAgentPool 都改用 `ForPersona(pid)` 视图——
否则角色级模型/提供商路由在生产里永不被选中(形同虚设)
- 复核:build/vet 绿 + model/agent/config/cmd 包测试绿;5 条变异反证先红后还原
(其中一条「红但没钉住」已改用例:通道读取加 2s 超时,避免整包 panic 掩盖信号)
- 未落:DashScope 的 auto 推断(缺官方依据,只允许显式声明);Qwen `/think` 前导消息
(design/01 §2.1 与 design/11 §3 口径冲突,停手报告)
This commit is contained in:
1 parent
71fefe5fc3
commit
8890c30bb5
17 files changed
+1496
-134
No files matched your search
@@ -40,6 +40,11 @@ type OpenAIChatAdapter struct {
|
||||
model string
|
||||
client *http.Client
|
||||
recorder Recorder
|
||||
// reasoningKind is this endpoint's configured reasoning-switch shape
|
||||
// (models.json group reasoning.kind / LLM_REASONING_KIND, 裁决 03.4.2/08.4.1).
|
||||
// Empty means "auto": infer the vendor from the model name/base URL and send
|
||||
// nothing when the shape is ambiguous.
|
||||
reasoningKind string
|
||||
// log reports reasoning_effort validation and ignored thinking directives. It
|
||||
// is never nil: a discard logger tagged with this adapter's source is
|
||||
// installed when the caller supplies none, so a decision is always traceable.
|
||||
@@ -77,13 +82,18 @@ func WithOpenAILogger(l *slog.Logger) OpenAIOption {
|
||||
}
|
||||
|
||||
// NewOpenAIChat builds an adapter from a supplier config. baseURL is trimmed of
|
||||
// any trailing slash before the /chat/completions path is appended.
|
||||
// any trailing slash before the /chat/completions path is appended. The
|
||||
// endpoint's configured reasoning shape (cfg.ReasoningKind) travels with the
|
||||
// adapter so every chain built from the same config — the group's chain, its
|
||||
// per-persona chain and the local rung — resolves its reasoning switches the
|
||||
// same way.
|
||||
func NewOpenAIChat(cfg config.LLMConfig, opts ...OpenAIOption) *OpenAIChatAdapter {
|
||||
a := &OpenAIChatAdapter{
|
||||
name: "openai",
|
||||
baseURL: strings.TrimRight(cfg.BaseURL, "/"),
|
||||
apiKey: cfg.APIKey,
|
||||
model: cfg.Model,
|
||||
name: "openai",
|
||||
baseURL: strings.TrimRight(cfg.BaseURL, "/"),
|
||||
apiKey: cfg.APIKey,
|
||||
model: cfg.Model,
|
||||
reasoningKind: strings.TrimSpace(cfg.ReasoningKind),
|
||||
client: &http.Client{
|
||||
Transport: http.DefaultTransport,
|
||||
Timeout: defaultHTTPTimeout,
|
||||
|
||||
Reference in new issue
Block a user