mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-08-22 16:24:01 +00:00
- Consolidated PG migration 054: agent_hooks rename + junction table + deprecated column drop - Updated SQLite schema v19 with final consolidated migration - Removed obsolete schema rebuild files (v21, v23) - Updated Go store layer (pg/hooks.go, sqlitestore/hooks.go) - Updated integration tests to use new table names (hooks, hook_agents) - Updated TypeScript protocol, UI components, and i18n strings - Updated gateway methods to reflect schema changes Tables: agent_hooks → hooks, agent_hook_agents → hook_agents
164 lines
5.1 KiB
Go
164 lines
5.1 KiB
Go
package methods
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/agent"
|
|
"github.com/nextlevelbuilder/goclaw/internal/config"
|
|
"github.com/nextlevelbuilder/goclaw/internal/gateway"
|
|
"github.com/nextlevelbuilder/goclaw/internal/tools"
|
|
"github.com/nextlevelbuilder/goclaw/pkg/protocol"
|
|
)
|
|
|
|
// Response shape matches TS AgentConfig (ui/web/src/types/agent.ts).
|
|
// Nested keys (softTrim.*, hardClear.*) stay aligned with ContextPruningConfig.
|
|
type configDefaultsResponse struct {
|
|
Agents configDefaultsAgents `json:"agents"`
|
|
}
|
|
|
|
type configDefaultsAgents struct {
|
|
ContextPruning pruningDefaultsJSON `json:"contextPruning"`
|
|
Subagents subagentDefaultsJSON `json:"subagents"`
|
|
}
|
|
|
|
type pruningDefaultsJSON struct {
|
|
KeepLastAssistants int `json:"keepLastAssistants"`
|
|
SoftTrimRatio float64 `json:"softTrimRatio"`
|
|
HardClearRatio float64 `json:"hardClearRatio"`
|
|
MinPrunableToolChars int `json:"minPrunableToolChars"`
|
|
TTL string `json:"ttl"`
|
|
SoftTrim pruningSoftTrimJSON `json:"softTrim"`
|
|
HardClear pruningHardClearJSON `json:"hardClear"`
|
|
}
|
|
|
|
type pruningSoftTrimJSON struct {
|
|
MaxChars int `json:"maxChars"`
|
|
HeadChars int `json:"headChars"`
|
|
TailChars int `json:"tailChars"`
|
|
}
|
|
|
|
type pruningHardClearJSON struct {
|
|
Enabled bool `json:"enabled"`
|
|
Placeholder string `json:"placeholder"`
|
|
}
|
|
|
|
type subagentDefaultsJSON struct {
|
|
MaxConcurrent int `json:"maxConcurrent"`
|
|
MaxSpawnDepth int `json:"maxSpawnDepth"`
|
|
MaxChildrenPerAgent int `json:"maxChildrenPerAgent"`
|
|
ArchiveAfterMinutes int `json:"archiveAfterMinutes"`
|
|
MaxRetries int `json:"maxRetries"`
|
|
}
|
|
|
|
// handleDefaults returns nested defaults for UI placeholder consumption.
|
|
// Read-only — no mutation; the response is pure SSoT + user overlay snapshot.
|
|
func (m *ConfigMethods) handleDefaults(_ context.Context, client *gateway.Client, req *protocol.RequestFrame) {
|
|
client.SendResponse(protocol.NewOKResponse(req.ID, buildConfigDefaults(m.cfg)))
|
|
}
|
|
|
|
// buildConfigDefaults seeds from Go consts (SSoT) then overlays any non-zero
|
|
// fields the operator set in cfg.Agents.Defaults. Overlay mirrors the resolver
|
|
// semantics in resolvePruningSettings so UI placeholders match runtime behaviour.
|
|
func buildConfigDefaults(cfg *config.Config) configDefaultsResponse {
|
|
p := agent.DefaultPruningValues()
|
|
s := tools.DefaultSubagentConfig()
|
|
|
|
resp := configDefaultsResponse{
|
|
Agents: configDefaultsAgents{
|
|
ContextPruning: pruningDefaultsJSON{
|
|
KeepLastAssistants: p.KeepLastAssistants,
|
|
SoftTrimRatio: p.SoftTrimRatio,
|
|
HardClearRatio: p.HardClearRatio,
|
|
MinPrunableToolChars: p.MinPrunableToolChars,
|
|
TTL: p.TTL,
|
|
SoftTrim: pruningSoftTrimJSON{
|
|
MaxChars: p.SoftTrimMaxChars,
|
|
HeadChars: p.SoftTrimHeadChars,
|
|
TailChars: p.SoftTrimTailChars,
|
|
},
|
|
HardClear: pruningHardClearJSON{
|
|
Enabled: p.HardClearEnabled,
|
|
Placeholder: p.HardClearPlaceholder,
|
|
},
|
|
},
|
|
Subagents: subagentDefaultsJSON{
|
|
MaxConcurrent: s.MaxConcurrent,
|
|
MaxSpawnDepth: s.MaxSpawnDepth,
|
|
MaxChildrenPerAgent: s.MaxChildrenPerAgent,
|
|
ArchiveAfterMinutes: s.ArchiveAfterMinutes,
|
|
MaxRetries: s.MaxRetries,
|
|
},
|
|
},
|
|
}
|
|
|
|
if cfg == nil {
|
|
return resp
|
|
}
|
|
overlayPruning(&resp.Agents.ContextPruning, cfg.Agents.Defaults.ContextPruning)
|
|
overlaySubagents(&resp.Agents.Subagents, cfg.Agents.Defaults.Subagents)
|
|
return resp
|
|
}
|
|
|
|
func overlayPruning(dst *pruningDefaultsJSON, src *config.ContextPruningConfig) {
|
|
if src == nil {
|
|
return
|
|
}
|
|
if src.KeepLastAssistants > 0 {
|
|
dst.KeepLastAssistants = src.KeepLastAssistants
|
|
}
|
|
if src.SoftTrimRatio > 0 && src.SoftTrimRatio <= 1 {
|
|
dst.SoftTrimRatio = src.SoftTrimRatio
|
|
}
|
|
if src.HardClearRatio > 0 && src.HardClearRatio <= 1 {
|
|
dst.HardClearRatio = src.HardClearRatio
|
|
}
|
|
if src.MinPrunableToolChars > 0 {
|
|
dst.MinPrunableToolChars = src.MinPrunableToolChars
|
|
}
|
|
if src.TTL != "" {
|
|
dst.TTL = src.TTL
|
|
}
|
|
if src.SoftTrim != nil {
|
|
if src.SoftTrim.MaxChars > 0 {
|
|
dst.SoftTrim.MaxChars = src.SoftTrim.MaxChars
|
|
}
|
|
if src.SoftTrim.HeadChars > 0 {
|
|
dst.SoftTrim.HeadChars = src.SoftTrim.HeadChars
|
|
}
|
|
if src.SoftTrim.TailChars > 0 {
|
|
dst.SoftTrim.TailChars = src.SoftTrim.TailChars
|
|
}
|
|
}
|
|
if src.HardClear != nil {
|
|
if src.HardClear.Enabled != nil {
|
|
dst.HardClear.Enabled = *src.HardClear.Enabled
|
|
}
|
|
if src.HardClear.Placeholder != "" {
|
|
dst.HardClear.Placeholder = src.HardClear.Placeholder
|
|
}
|
|
}
|
|
}
|
|
|
|
func overlaySubagents(dst *subagentDefaultsJSON, src *config.SubagentsConfig) {
|
|
if src == nil {
|
|
return
|
|
}
|
|
if src.MaxConcurrent > 0 {
|
|
dst.MaxConcurrent = src.MaxConcurrent
|
|
}
|
|
// Mirror runtime clamps in cmd/gateway_agents.go so UI placeholders reflect
|
|
// the effective value (not operator's raw over-limit config.json).
|
|
if src.MaxSpawnDepth > 0 {
|
|
dst.MaxSpawnDepth = min(src.MaxSpawnDepth, 5)
|
|
}
|
|
if src.MaxChildrenPerAgent > 0 {
|
|
dst.MaxChildrenPerAgent = min(src.MaxChildrenPerAgent, 20)
|
|
}
|
|
if src.ArchiveAfterMinutes > 0 {
|
|
dst.ArchiveAfterMinutes = src.ArchiveAfterMinutes
|
|
}
|
|
if src.MaxRetries > 0 {
|
|
dst.MaxRetries = src.MaxRetries
|
|
}
|
|
}
|