agent: eliminate Dispatcher, use tools.Server directly
Runtime.Dispatcher → Runtime.ExecServer (tools.Server). The Dispatcher
abstraction routed to exactly one server ('execute') — unnecessary
indirection. BuildRuntime now takes tools.Server directly.
Agent.newDispatcher → Agent.newToolServer. AgentCfg/Config updated.
All GetServer('execute') calls replaced with direct ExecServer access.
exec closure simplified: direct CallTool, no tool-name lookup.
This commit is contained in:
parent
0524f38db0
commit
d6bc89d3e2
|
|
@ -29,7 +29,7 @@ type Agent struct {
|
||||||
agentsDir string
|
agentsDir string
|
||||||
baseLayers []string // system prompt layers for /agent reloads
|
baseLayers []string // system prompt layers for /agent reloads
|
||||||
promptEnvExtra []string // PRIME_* vars for prompt resolution
|
promptEnvExtra []string // PRIME_* vars for prompt resolution
|
||||||
newDispatcher func() tools.Dispatcher
|
newToolServer func() tools.Server
|
||||||
newBackend func(string) (backend.Backend, error)
|
newBackend func(string) (backend.Backend, error)
|
||||||
currentAction atomic.Pointer[actionHandle]
|
currentAction atomic.Pointer[actionHandle]
|
||||||
warnedContext bool
|
warnedContext bool
|
||||||
|
|
@ -258,10 +258,10 @@ func (ag *Agent) ToolCallCount() int64 {
|
||||||
|
|
||||||
// SetSessionEnv injects session env vars into the execute server.
|
// SetSessionEnv injects session env vars into the execute server.
|
||||||
func (ag *Agent) SetSessionEnv(sessionID string) {
|
func (ag *Agent) SetSessionEnv(sessionID string) {
|
||||||
if ag.runtime.Dispatcher == nil {
|
if ag.runtime.ExecServer == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if srv, ok := ag.runtime.Dispatcher.GetServer("execute"); ok {
|
if srv := ag.runtime.ExecServer; srv != nil {
|
||||||
if es, ok := srv.(tools.EnvSetter); ok {
|
if es, ok := srv.(tools.EnvSetter); ok {
|
||||||
es.SetEnv("OLLIE_SESSION_ID", sessionID)
|
es.SetEnv("OLLIE_SESSION_ID", sessionID)
|
||||||
if ag.id != "" {
|
if ag.id != "" {
|
||||||
|
|
@ -273,10 +273,10 @@ func (ag *Agent) SetSessionEnv(sessionID string) {
|
||||||
|
|
||||||
// SetEnv stores an environment variable on the execute server.
|
// SetEnv stores an environment variable on the execute server.
|
||||||
func (ag *Agent) SetEnv(key, value string) {
|
func (ag *Agent) SetEnv(key, value string) {
|
||||||
if ag.runtime.Dispatcher == nil {
|
if ag.runtime.ExecServer == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if srv, ok := ag.runtime.Dispatcher.GetServer("execute"); ok {
|
if srv := ag.runtime.ExecServer; srv != nil {
|
||||||
if es, ok := srv.(tools.EnvSetter); ok {
|
if es, ok := srv.(tools.EnvSetter); ok {
|
||||||
es.SetEnv(key, value)
|
es.SetEnv(key, value)
|
||||||
}
|
}
|
||||||
|
|
@ -285,10 +285,10 @@ func (ag *Agent) SetEnv(key, value string) {
|
||||||
|
|
||||||
// Close releases agent resources (dispatcher, execute server).
|
// Close releases agent resources (dispatcher, execute server).
|
||||||
func (ag *Agent) Close() {
|
func (ag *Agent) Close() {
|
||||||
if ag.runtime.Dispatcher == nil {
|
if ag.runtime.ExecServer == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if srv, ok := ag.runtime.Dispatcher.GetServer("execute"); ok {
|
if srv := ag.runtime.ExecServer; srv != nil {
|
||||||
if c, ok := srv.(interface{ Close() }); ok {
|
if c, ok := srv.(interface{ Close() }); ok {
|
||||||
c.Close()
|
c.Close()
|
||||||
}
|
}
|
||||||
|
|
@ -302,8 +302,8 @@ func (ag *Agent) SetCWD(dir string) {
|
||||||
if oldCwd != "" && dir != "" && oldCwd != dir {
|
if oldCwd != "" && dir != "" && oldCwd != dir {
|
||||||
ag.runtime.Preamble = strings.ReplaceAll(ag.runtime.Preamble, oldCwd, dir)
|
ag.runtime.Preamble = strings.ReplaceAll(ag.runtime.Preamble, oldCwd, dir)
|
||||||
}
|
}
|
||||||
if ag.runtime != nil && ag.runtime.Dispatcher != nil {
|
if ag.runtime.ExecServer != nil {
|
||||||
if srv, ok := ag.runtime.Dispatcher.GetServer("execute"); ok {
|
if srv := ag.runtime.ExecServer; srv != nil {
|
||||||
if ws, ok := srv.(tools.CWDSetter); ok {
|
if ws, ok := srv.(tools.CWDSetter); ok {
|
||||||
ws.SetCWD(dir)
|
ws.SetCWD(dir)
|
||||||
}
|
}
|
||||||
|
|
@ -472,13 +472,9 @@ func (ag *Agent) React(responseID, emoji string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// execServer returns the execute server interface, or nil if unavailable.
|
// execServer returns the execute server, or nil if unavailable.
|
||||||
func (ag *Agent) execServer() interface{} {
|
func (ag *Agent) execServer() tools.Server {
|
||||||
if ag.runtime.Dispatcher == nil {
|
return ag.runtime.ExecServer
|
||||||
return nil
|
|
||||||
}
|
|
||||||
srv, _ := ag.runtime.Dispatcher.GetServer("execute")
|
|
||||||
return srv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue pushes a prompt onto the agent's FIFO.
|
// Queue pushes a prompt onto the agent's FIFO.
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import (
|
||||||
// env provides additional environment variables injected into prompt resolution
|
// env provides additional environment variables injected into prompt resolution
|
||||||
// subprocesses (e.g. OLLIE_SESSION_ID=xxx).
|
// subprocesses (e.g. OLLIE_SESSION_ID=xxx).
|
||||||
// The caller is responsible for registering all servers on d before calling this.
|
// The caller is responsible for registering all servers on d before calling this.
|
||||||
func BuildRuntime(cfg *AgentConfig, d tools.Dispatcher, cwd string, env []string, baseLayers ...string) *Runtime {
|
func BuildRuntime(cfg *AgentConfig, srv tools.Server, cwd string, env []string, baseLayers ...string) *Runtime {
|
||||||
var messages []string
|
var messages []string
|
||||||
|
|
||||||
var allToolInfos []tools.ToolInfo
|
var allToolInfos []tools.ToolInfo
|
||||||
|
|
@ -25,7 +25,7 @@ func BuildRuntime(cfg *AgentConfig, d tools.Dispatcher, cwd string, env []string
|
||||||
|
|
||||||
if cfg == nil || cfg.ToolsEnabled() {
|
if cfg == nil || cfg.ToolsEnabled() {
|
||||||
var listErr error
|
var listErr error
|
||||||
allToolInfos, listErr = d.ListTools()
|
allToolInfos, listErr = srv.ListTools()
|
||||||
if listErr != nil {
|
if listErr != nil {
|
||||||
messages = append(messages, fmt.Sprintf("list tools: %v", listErr))
|
messages = append(messages, fmt.Sprintf("list tools: %v", listErr))
|
||||||
}
|
}
|
||||||
|
|
@ -69,30 +69,14 @@ func BuildRuntime(cfg *AgentConfig, d tools.Dispatcher, cwd string, env []string
|
||||||
}
|
}
|
||||||
maxSteps = cfg.MaxSteps
|
maxSteps = cfg.MaxSteps
|
||||||
if len(cfg.AllowTools) > 0 {
|
if len(cfg.AllowTools) > 0 {
|
||||||
if srv, ok := d.GetServer("execute"); ok {
|
if rs, ok := srv.(tools.ToolRestrictionSetter); ok {
|
||||||
if rs, ok := srv.(tools.ToolRestrictionSetter); ok {
|
rs.SetAllowTools(cfg.AllowTools)
|
||||||
rs.SetAllowTools(cfg.AllowTools)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exec := func(ctx context.Context, name string, args json.RawMessage) (string, []backend.ContentBlock, error) {
|
exec := func(ctx context.Context, name string, args json.RawMessage) (string, []backend.ContentBlock, error) {
|
||||||
infos, listErr := d.ListTools()
|
raw, err := srv.CallTool(ctx, name, args)
|
||||||
if listErr != nil {
|
|
||||||
return "", nil, listErr
|
|
||||||
}
|
|
||||||
server := ""
|
|
||||||
for _, t := range infos {
|
|
||||||
if t.Name == name {
|
|
||||||
server = t.Server
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if server == "" {
|
|
||||||
return "", nil, fmt.Errorf("unknown tool: %s", name)
|
|
||||||
}
|
|
||||||
raw, err := d.Dispatch(ctx, server, name, args)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -104,24 +88,20 @@ func BuildRuntime(cfg *AgentConfig, d tools.Dispatcher, cwd string, env []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var classify toolClassifier
|
var classify toolClassifier
|
||||||
if srv, ok := d.GetServer("execute"); ok {
|
if pc, ok := srv.(tools.ParallelClassifier); ok {
|
||||||
if pc, ok := srv.(tools.ParallelClassifier); ok {
|
classify = pc.IsParallelRead
|
||||||
classify = pc.IsParallelRead
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tierFn func(string, json.RawMessage) ResultTier
|
var tierFn func(string, json.RawMessage) ResultTier
|
||||||
if srv, ok := d.GetServer("execute"); ok {
|
if tc, ok := srv.(tools.TierClassifier); ok {
|
||||||
if tc, ok := srv.(tools.TierClassifier); ok {
|
tierFn = func(name string, args json.RawMessage) ResultTier {
|
||||||
tierFn = func(name string, args json.RawMessage) ResultTier {
|
switch tc.ResultTierArgs(name, args) {
|
||||||
switch tc.ResultTierArgs(name, args) {
|
case "cold":
|
||||||
case "cold":
|
return TierCold
|
||||||
return TierCold
|
case "warm":
|
||||||
case "warm":
|
return TierWarm
|
||||||
return TierWarm
|
default:
|
||||||
default:
|
return TierHot
|
||||||
return TierHot
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +140,7 @@ func BuildRuntime(cfg *AgentConfig, d tools.Dispatcher, cwd string, env []string
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Runtime{
|
return &Runtime{
|
||||||
Dispatcher: d,
|
ExecServer: srv,
|
||||||
Tools: allTools,
|
Tools: allTools,
|
||||||
Exec: exec,
|
Exec: exec,
|
||||||
ClassifyTool: classify,
|
ClassifyTool: classify,
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ func (ag *Agent) cmdAgent(_ context.Context, args []string) {
|
||||||
ag.emit(infoEvent(fmt.Sprintf("error: agent %q: %v", name, err)))
|
ag.emit(infoEvent(fmt.Sprintf("error: agent %q: %v", name, err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
disp := ag.newDispatcher()
|
disp := ag.newToolServer()
|
||||||
env := []string{"OLLIE_SESSION_ID=" + ag.sessionID, "OLLIE_UNAME=" + ag.id}
|
env := []string{"OLLIE_SESSION_ID=" + ag.sessionID, "OLLIE_UNAME=" + ag.id}
|
||||||
env = append(env, ag.promptEnvExtra...)
|
env = append(env, ag.promptEnvExtra...)
|
||||||
rt := BuildRuntime(cfg, disp, ag.cwd, env, ag.baseLayers...)
|
rt := BuildRuntime(cfg, disp, ag.cwd, env, ag.baseLayers...)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type AgentCfg struct {
|
||||||
CWD string // working directory for tool execution
|
CWD string // working directory for tool execution
|
||||||
BaseLayers []string
|
BaseLayers []string
|
||||||
PromptEnvExtra []string
|
PromptEnvExtra []string
|
||||||
NewDispatcher func() tools.Dispatcher
|
NewToolServer func() tools.Server
|
||||||
NewBackend func(string) (backend.Backend, error)
|
NewBackend func(string) (backend.Backend, error)
|
||||||
Bus *pubsub.Bus
|
Bus *pubsub.Bus
|
||||||
Log *olog.Logger
|
Log *olog.Logger
|
||||||
|
|
@ -42,7 +42,7 @@ func NewAgent(cfg AgentCfg) *Agent {
|
||||||
cwd: cfg.CWD,
|
cwd: cfg.CWD,
|
||||||
baseLayers: cfg.BaseLayers,
|
baseLayers: cfg.BaseLayers,
|
||||||
promptEnvExtra: cfg.PromptEnvExtra,
|
promptEnvExtra: cfg.PromptEnvExtra,
|
||||||
newDispatcher: cfg.NewDispatcher,
|
newToolServer: cfg.NewToolServer,
|
||||||
newBackend: cfg.NewBackend,
|
newBackend: cfg.NewBackend,
|
||||||
bus: cfg.Bus,
|
bus: cfg.Bus,
|
||||||
log: cfg.Log,
|
log: cfg.Log,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
// agents replaces it atomically.
|
// agents replaces it atomically.
|
||||||
type Runtime struct {
|
type Runtime struct {
|
||||||
Backend backend.Backend
|
Backend backend.Backend
|
||||||
Dispatcher tools.Dispatcher
|
ExecServer tools.Server // the execute server (tool runtime, env, cwd)
|
||||||
Hooks Hooks
|
Hooks Hooks
|
||||||
Preamble string // compiled system prompt
|
Preamble string // compiled system prompt
|
||||||
Tools []backend.Tool
|
Tools []backend.Tool
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ type Config struct {
|
||||||
CWD string
|
CWD string
|
||||||
History *agent.History
|
History *agent.History
|
||||||
Runtime *agent.Runtime
|
Runtime *agent.Runtime
|
||||||
NewDispatcher func() tools.Dispatcher
|
NewToolServer func() tools.Server
|
||||||
NewBackend func(string) (backend.Backend, error)
|
NewBackend func(string) (backend.Backend, error)
|
||||||
Log *olog.Logger
|
Log *olog.Logger
|
||||||
MaxSteps int
|
MaxSteps int
|
||||||
|
|
@ -150,7 +150,7 @@ func New(cfg Config) *Session {
|
||||||
CWD: paths.ExpandHome(cfg.CWD),
|
CWD: paths.ExpandHome(cfg.CWD),
|
||||||
BaseLayers: cfg.BaseLayers,
|
BaseLayers: cfg.BaseLayers,
|
||||||
PromptEnvExtra: cfg.PromptEnvExtra,
|
PromptEnvExtra: cfg.PromptEnvExtra,
|
||||||
NewDispatcher: cfg.NewDispatcher,
|
NewToolServer: cfg.NewToolServer,
|
||||||
NewBackend: cfg.NewBackend,
|
NewBackend: cfg.NewBackend,
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
Log: log,
|
Log: log,
|
||||||
|
|
|
||||||
Reference in New Issue