feat: LLM 录制开关、模型列表第三方回退、命令页改为工具执行
在 review PR5 基础上的三处改进:
1. LLM 录制开关(默认关,settings.llm_record)
- 录制页数据大小下拉框旁加开关;关闭时 Recorder.Stream 直接透传,
不序列化、不累积、不写库,零开销。切换即时生效,无需重建 agent。
2. 模型列表拉取支持 Anthropic 兼容第三方
- pgListModels 改为按序尝试多个候选端点:anthropic 的 /v1/models 拿不到时,
剥掉 /anthropic 回退到 OpenAI 式 /models(自动切 Bearer 头)。
修复 DeepSeek(anthropic) 加载模型 404。
3. 命令页改为「工具执行」列表
- ListCommands 去掉 tool='Bash' 过滤,覆盖所有 tool_use;返回工具名列,
搜索匹配工具名或参数。前端加「工具」列、标题/侧边栏改为「工具执行」。
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
10f891a21d
commit
ad9f14f140
12 files changed
+225
-83
No files matched your search
+12
-3
@@ -336,7 +336,7 @@ func (s *Server) applyLLM(cfg agent.Config) error {
|
||||
s.cfgMu.Lock()
|
||||
profName := s.llmProf
|
||||
s.cfgMu.Unlock()
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, profName)
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, profName, s.m.LLMRecordEnabled)
|
||||
pl, wk := s.buildPlannerWorker(prov, cfg)
|
||||
s.engine.UseLLM(pl, wk)
|
||||
|
||||
@@ -400,7 +400,7 @@ func (s *Server) agentsForProfile(id int64) (*agent.Planner, *agent.Worker) {
|
||||
}
|
||||
// Wrap with recorder, tagged with this profile's name.
|
||||
if p, _ := s.m.pg.ProfileByID(id); p != nil {
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, p.Name)
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, p.Name, s.m.LLMRecordEnabled)
|
||||
}
|
||||
pl, wk := s.buildPlannerWorker(prov, cfg)
|
||||
s.profAgents[id] = &profBundle{pl: pl, wk: wk}
|
||||
@@ -427,7 +427,7 @@ func (s *Server) chatAgentForProfile(id int64) *agent.ChatAgent {
|
||||
}
|
||||
// Wrap with recorder, tagged with this profile's name.
|
||||
if p, _ := s.m.pg.ProfileByID(id); p != nil {
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, p.Name)
|
||||
prov = llmrec.Wrap(prov, s.m.PG(), cfg.Model, p.Name, s.m.LLMRecordEnabled)
|
||||
}
|
||||
tx := transcript.NewStore(filepath.Join(s.m.dir, "transcripts"))
|
||||
win := cfg.CompactionWindow()
|
||||
@@ -1458,6 +1458,7 @@ func (s *Server) settingsPayload() map[string]any {
|
||||
pyStored, _, _ := s.m.pg.GetSetting(settingPythonInterp)
|
||||
return map[string]any{
|
||||
"traffic_capture": s.m.TrafficEnabled(),
|
||||
"llm_record": s.m.LLMRecordEnabled(),
|
||||
"web_search_enabled": on,
|
||||
"web_search_backend": backend,
|
||||
"brave_key_set": strings.TrimSpace(braveKey) != "",
|
||||
@@ -1488,6 +1489,7 @@ func (s *Server) pgDetectPython(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *Server) putSettings(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct {
|
||||
TrafficCapture *bool `json:"traffic_capture"`
|
||||
LLMRecord *bool `json:"llm_record"` // LLM 录制开关(默认关);即时生效,无需重建 agent
|
||||
// Web search. WebSearchEnabled/Backend toggle the tool + backend; BraveKey/TavilyKey
|
||||
// are optional — omit (null) to leave a stored key untouched, send "" to clear.
|
||||
WebSearchEnabled *bool `json:"web_search_enabled"`
|
||||
@@ -1514,6 +1516,13 @@ func (s *Server) putSettings(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if req.LLMRecord != nil {
|
||||
// 录制器每次调用读取该标志,切换即时生效,无需 applyLLM 重建。
|
||||
if err := s.m.SetLLMRecordEnabled(*req.LLMRecord); err != nil {
|
||||
writeErr(w, 500, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
changed := false
|
||||
if req.TrafficCapture != nil {
|
||||
if err := s.m.SetTrafficEnabled(*req.TrafficCapture); err != nil {
|
||||
|
||||
Reference in new issue
Block a user