X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/723f6e18adc6482ed913e1618c8a76e981720c2b..c781f79f3c8cb9a7577ee1574d196988da2719b3:/agent.go diff --git a/agent.go b/agent.go index dbcabd2..8226a43 100644 --- a/agent.go +++ b/agent.go @@ -25,6 +25,28 @@ const ( agentIDBytes = 16 ) +// Agent is one agent and its directory. The directory holds config.json, the +// user's instructions in instructions.md, the chat, and the usage file. +type Agent struct { + dir string + config AgentConfig +} + +// AgentConfig holds the settings of the config.json of an agent. ID is random, +// made once when the file is made, and never changes. The cache key comes from +// the ID, so a rename keeps the prompt cache and two agents with one name do +// not share a key. Workdir is the directory where the commands of the agent +// run. Responsibility and Parent are set together for a child agent. +type AgentConfig struct { + Name string `json:"name"` + ID string `json:"id"` + Model string `json:"model"` + Effort string `json:"effort"` + Workdir string `json:"workdir"` + Responsibility string `json:"responsibility,omitempty"` + Parent string `json:"parent,omitempty"` +} + // openAgent reads the config.json of the agent in dir. When the file does not // exist, it makes the directory and writes the file with the defaults and a new // ID. A missing field of an existing file takes the default, but the ID must be @@ -73,11 +95,24 @@ func openAgent(dir string) (*Agent, error) { }, nil } -// Agent is one agent and its directory. The directory holds config.json, the -// user's instructions in instructions.md, the chat, and the usage file. -type Agent struct { - dir string - config AgentConfig +// Images returns the shared data-directory image store, also for a child. +func (a *Agent) Images() *ImageStore { + root := a.dir + if a.config.Parent != "" { + root = filepath.Dir(filepath.Dir(root)) + } + + return &ImageStore{dir: filepath.Join(filepath.Dir(root), imageDirName)} +} + +// Voices returns the shared data-directory audio store, also for a child. +func (a *Agent) Voices() *VoiceStore { + root := a.dir + if a.config.Parent != "" { + root = filepath.Dir(filepath.Dir(root)) + } + + return &VoiceStore{dir: filepath.Join(filepath.Dir(root), voiceDirName)} } // CacheKey returns the prompt cache key of every model call of the agent. @@ -107,12 +142,12 @@ func (a *Agent) Prompt() (string, error) { } // Tools returns the tools shared by the turns and compactions of this agent. A -// child has no WhatsApp, child creation, or route tools. +// child has no image output, WhatsApp, child creation, or route tools. func (a *Agent) Tools() []ModelTool { tools := promptTools() if a.config.Parent != "" { tools = slices.DeleteFunc(tools, func(tool ModelTool) bool { - return strings.HasPrefix(tool.Name, "whatsapp_") || tool.Name == "agent_create" || tool.Name == "route" || tool.Name == "unroute" || tool.Name == "routes" + return strings.HasPrefix(tool.Name, "whatsapp_") || tool.Name == "image_show" || tool.Name == "agent_create" || tool.Name == "route" || tool.Name == "unroute" || tool.Name == "routes" }) } @@ -275,21 +310,6 @@ func (a *Agent) instructions() (string, error) { return string(data), nil } -// AgentConfig holds the settings of the config.json of an agent. ID is random, -// made once when the file is made, and never changes. The cache key comes from -// the ID, so a rename keeps the prompt cache and two agents with one name do -// not share a key. Workdir is the directory where the commands of the agent -// run. Responsibility and Parent are set together for a child agent. -type AgentConfig struct { - Name string `json:"name"` - ID string `json:"id"` - Model string `json:"model"` - Effort string `json:"effort"` - Workdir string `json:"workdir"` - Responsibility string `json:"responsibility,omitempty"` - Parent string `json:"parent,omitempty"` -} - // validate makes sure that each setting has a valid value. func (c AgentConfig) validate() error { if c.Name == "" || strings.ContainsAny(c.Name, "\r\n") {