Changeset 0.27.2 (#169)
This commit is contained in:
110
server/taskutil/task_config.go
Normal file
110
server/taskutil/task_config.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package taskutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"git.gobha.me/xcaliber/chat-switchboard/models"
|
||||
"git.gobha.me/xcaliber/chat-switchboard/store"
|
||||
)
|
||||
|
||||
// TaskConfig holds the runtime task configuration read from global_settings.
|
||||
// Keys: tasks.enabled, tasks.allow_personal, tasks.max_concurrent,
|
||||
// tasks.default_max_tokens, tasks.default_max_tool_calls,
|
||||
// tasks.default_max_wall_clock
|
||||
type TaskConfig struct {
|
||||
Enabled bool
|
||||
AllowPersonal bool
|
||||
MaxConcurrent int
|
||||
DefaultMaxTokens int
|
||||
DefaultMaxToolCalls int
|
||||
DefaultMaxWallClock int // seconds
|
||||
}
|
||||
|
||||
// DefaultTaskConfig returns sensible defaults when no global config is set.
|
||||
func DefaultTaskConfig() TaskConfig {
|
||||
return TaskConfig{
|
||||
Enabled: true,
|
||||
AllowPersonal: true,
|
||||
MaxConcurrent: 5,
|
||||
DefaultMaxTokens: 4096,
|
||||
DefaultMaxToolCalls: 10,
|
||||
DefaultMaxWallClock: 300,
|
||||
}
|
||||
}
|
||||
|
||||
// LoadTaskConfig reads task configuration from global_settings.
|
||||
// Falls back to defaults for missing keys.
|
||||
func LoadTaskConfig(ctx context.Context, gc store.GlobalConfigStore) TaskConfig {
|
||||
cfg := DefaultTaskConfig()
|
||||
if gc == nil {
|
||||
return cfg
|
||||
}
|
||||
|
||||
raw, err := gc.Get(ctx, "tasks")
|
||||
if err != nil || raw == nil {
|
||||
return cfg
|
||||
}
|
||||
|
||||
if v, ok := boolVal(raw, "enabled"); ok {
|
||||
cfg.Enabled = v
|
||||
}
|
||||
if v, ok := boolVal(raw, "allow_personal"); ok {
|
||||
cfg.AllowPersonal = v
|
||||
}
|
||||
if v, ok := intVal(raw, "max_concurrent"); ok && v > 0 {
|
||||
cfg.MaxConcurrent = v
|
||||
}
|
||||
if v, ok := intVal(raw, "default_max_tokens"); ok && v > 0 {
|
||||
cfg.DefaultMaxTokens = v
|
||||
}
|
||||
if v, ok := intVal(raw, "default_max_tool_calls"); ok && v > 0 {
|
||||
cfg.DefaultMaxToolCalls = v
|
||||
}
|
||||
if v, ok := intVal(raw, "default_max_wall_clock"); ok && v > 0 {
|
||||
cfg.DefaultMaxWallClock = v
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// ApplyDefaults fills zero-value budget fields on a task with the global defaults.
|
||||
func (tc TaskConfig) ApplyDefaults(t *models.Task) {
|
||||
if t.MaxTokens == 0 {
|
||||
t.MaxTokens = tc.DefaultMaxTokens
|
||||
}
|
||||
if t.MaxToolCalls == 0 {
|
||||
t.MaxToolCalls = tc.DefaultMaxToolCalls
|
||||
}
|
||||
if t.MaxWallClock == 0 {
|
||||
t.MaxWallClock = tc.DefaultMaxWallClock
|
||||
}
|
||||
}
|
||||
|
||||
// ── helpers ────────────────────────────────────
|
||||
|
||||
func boolVal(m models.JSONMap, key string) (bool, bool) {
|
||||
v, ok := m[key]
|
||||
if !ok {
|
||||
return false, false
|
||||
}
|
||||
b, ok := v.(bool)
|
||||
return b, ok
|
||||
}
|
||||
|
||||
func intVal(m models.JSONMap, key string) (int, bool) {
|
||||
v, ok := m[key]
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
// JSON numbers are float64 after Unmarshal
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
return int(n), true
|
||||
case int:
|
||||
return n, true
|
||||
default:
|
||||
log.Printf("[task_config] unexpected type for %s: %T", key, v)
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user