feat(agent): 支持为每个 agent 绑定 LLM 配置(agent 级默认模型)
按优先级 Agent 绑定 > 任务/会话指定 > 全局激活 解析每个 agent 运行的模型, 使 planner/worker/goals/mainagent/自定义 agent 可各自走不同 profile(如 plan 用 强模型、work 用弱模型)。未绑定时行为与原先完全一致。 - db: Agent 增 llm_profile_id + SetAgentLLMProfile;schema 幂等兜底 ALTER - server: 新增 effectiveProfileForAgent/providerForProfile/providerForAgent; buildPlannerWorker 让 planner/worker 各自解析 provider;provider 按 profile id 缓存以共享限速器;goals/会话链同步走绑定;绑定变更热重载 - api: agent 配置接口收 llm_profile_id(三态) + 返回可选 profile 列表 - web: agent 编辑器「配置与提示词」页新增「默认模型」下拉
This commit is contained in:
1 parent
289cf6a24f
commit
c84bba477f
10 files changed
+238
-55
No files matched your search
+16
-2
@@ -123,6 +123,7 @@ type Agent struct {
|
||||
Role string `json:"role"`
|
||||
Builtin bool `json:"builtin"`
|
||||
Enabled bool `json:"enabled"`
|
||||
LLMProfileID *int64 `json:"llm_profile_id"` // 绑定的 LLM 配置;nil=跟随任务/会话 pin,再回退全局激活
|
||||
MaxTurns int `json:"max_turns"` // 单次运行最大轮次;0=不限制
|
||||
RunSecs int `json:"run_seconds"` // worker 单次运行墙钟上限(秒);0=不限制
|
||||
WebSearch bool `json:"web_search"` // 是否启用网络搜索(受系统全局开关门控)
|
||||
@@ -141,11 +142,16 @@ type Agent struct {
|
||||
TriggerMaxParallel int `json:"trigger_max_parallel"`
|
||||
}
|
||||
|
||||
const agentCols = `id,key,name,COALESCE(description,''),role,builtin,enabled,COALESCE(max_turns,0),COALESCE(run_seconds,600),COALESCE(web_search,false),COALESCE(interactive_shell,false),COALESCE(wrapup_prompt,''),COALESCE(wrapup_max_turns,0),COALESCE(task_timeout_wrapup_prompt,''),COALESCE(task_timeout_wrapup_max_turns,0),COALESCE(trigger_run_mode,'serial'),COALESCE(trigger_merge_mode,'by_task'),COALESCE(trigger_max_parallel,5)`
|
||||
const agentCols = `id,key,name,COALESCE(description,''),role,builtin,enabled,COALESCE(max_turns,0),COALESCE(run_seconds,600),COALESCE(web_search,false),COALESCE(interactive_shell,false),COALESCE(wrapup_prompt,''),COALESCE(wrapup_max_turns,0),COALESCE(task_timeout_wrapup_prompt,''),COALESCE(task_timeout_wrapup_max_turns,0),COALESCE(trigger_run_mode,'serial'),COALESCE(trigger_merge_mode,'by_task'),COALESCE(trigger_max_parallel,5),llm_profile_id`
|
||||
|
||||
func scanAgent(sc interface{ Scan(...any) error }) (*Agent, error) {
|
||||
var a Agent
|
||||
err := sc.Scan(&a.ID, &a.Key, &a.Name, &a.Description, &a.Role, &a.Builtin, &a.Enabled, &a.MaxTurns, &a.RunSecs, &a.WebSearch, &a.InteractiveShell, &a.WrapupPrompt, &a.WrapupMaxTurns, &a.TaskTimeoutWrapupPrompt, &a.TaskTimeoutWrapupMaxTurns, &a.TriggerRunMode, &a.TriggerMergeMode, &a.TriggerMaxParallel)
|
||||
var prof sql.NullInt64 // llm_profile_id 可空:未绑定时为 NULL
|
||||
err := sc.Scan(&a.ID, &a.Key, &a.Name, &a.Description, &a.Role, &a.Builtin, &a.Enabled, &a.MaxTurns, &a.RunSecs, &a.WebSearch, &a.InteractiveShell, &a.WrapupPrompt, &a.WrapupMaxTurns, &a.TaskTimeoutWrapupPrompt, &a.TaskTimeoutWrapupMaxTurns, &a.TriggerRunMode, &a.TriggerMergeMode, &a.TriggerMaxParallel, &prof)
|
||||
if err == nil && prof.Valid {
|
||||
v := prof.Int64
|
||||
a.LLMProfileID = &v
|
||||
}
|
||||
return &a, err
|
||||
}
|
||||
|
||||
@@ -262,6 +268,14 @@ func (d *DB) SetAgentMaxTurns(key string, maxTurns int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// SetAgentLLMProfile binds an agent to a specific LLM profile (id != nil), or clears
|
||||
// the binding (id == nil) so the agent follows the task/conversation pin, else the
|
||||
// global active profile. Precedence at runtime: agent binding → task/conv pin → active.
|
||||
func (d *DB) SetAgentLLMProfile(key string, id *int64) error {
|
||||
_, err := d.Exec(`UPDATE agents SET llm_profile_id=$1 WHERE key=$2`, id, key)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetAgentWebSearch toggles whether an agent uses network search (still gated by
|
||||
// the global web-search master switch + backend/key config).
|
||||
func (d *DB) SetAgentWebSearch(key string, on bool) error {
|
||||
|
||||
Reference in new issue
Block a user