Introduce "agents"
An agent is currently a name given to a system prompt and a set of tools which the agent has access to. This resolves the previous issue of the set of configured tools being available in *all* contexts, which wasn't always desired. Tools are now only available when an agent is explicitly requested using the `-a/--agent` flag. Agents are expected to be expanded on: the concept of task-specilized agents (e.g. coding), the ability to define a set of files an agent should always have access to for RAG purposes, etc. Other changes: - Removes the "tools" top-level config structure (though this is expected to come back along with the abillity to define custom tools). - Renamed `pkg/agent` to `pkg/agents`
This commit is contained in:
114
pkg/agents/toolbox/file_insert_lines.go
Normal file
114
pkg/agents/toolbox/file_insert_lines.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package toolbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
toolutil "git.mlow.ca/mlow/lmcli/pkg/agents/toolbox/util"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/api"
|
||||
)
|
||||
|
||||
const FILE_INSERT_LINES_DESCRIPTION = `Insert lines into a file, must specify path.
|
||||
|
||||
Make sure your inserts match the flow and indentation of surrounding content.`
|
||||
|
||||
var FileInsertLinesTool = api.ToolSpec{
|
||||
Name: "file_insert_lines",
|
||||
Description: FILE_INSERT_LINES_DESCRIPTION,
|
||||
Parameters: []api.ToolParameter{
|
||||
{
|
||||
Name: "path",
|
||||
Type: "string",
|
||||
Description: "Path of the file to be modified, relative to the current working directory.",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "position",
|
||||
Type: "integer",
|
||||
Description: `Which line to insert content *before*.`,
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Name: "content",
|
||||
Type: "string",
|
||||
Description: `The content to insert.`,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
Impl: func(tool *api.ToolSpec, args map[string]interface{}) (string, error) {
|
||||
tmp, ok := args["path"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("path parameter to write_file was not included.")
|
||||
}
|
||||
path, ok := tmp.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Invalid path in function arguments: %v", tmp)
|
||||
}
|
||||
var position int
|
||||
tmp, ok = args["position"]
|
||||
if ok {
|
||||
tmp, ok := tmp.(float64)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Invalid position in function arguments: %v", tmp)
|
||||
}
|
||||
position = int(tmp)
|
||||
}
|
||||
var content string
|
||||
tmp, ok = args["content"]
|
||||
if ok {
|
||||
content, ok = tmp.(string)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("Invalid content in function arguments: %v", tmp)
|
||||
}
|
||||
}
|
||||
|
||||
result := fileInsertLines(path, position, content)
|
||||
ret, err := result.ToJson()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Could not serialize result: %v", err)
|
||||
}
|
||||
return ret, nil
|
||||
},
|
||||
}
|
||||
|
||||
func fileInsertLines(path string, position int, content string) api.CallResult {
|
||||
ok, reason := toolutil.IsPathWithinCWD(path)
|
||||
if !ok {
|
||||
return api.CallResult{Message: reason}
|
||||
}
|
||||
|
||||
// Read the existing file's content
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return api.CallResult{Message: fmt.Sprintf("Could not read path: %s", err.Error())}
|
||||
}
|
||||
_, err = os.Create(path)
|
||||
if err != nil {
|
||||
return api.CallResult{Message: fmt.Sprintf("Could not create new file: %s", err.Error())}
|
||||
}
|
||||
data = []byte{}
|
||||
}
|
||||
|
||||
if position < 1 {
|
||||
return api.CallResult{Message: "start_line cannot be less than 1"}
|
||||
}
|
||||
|
||||
lines := strings.Split(string(data), "\n")
|
||||
contentLines := strings.Split(strings.Trim(content, "\n"), "\n")
|
||||
|
||||
before := lines[:position-1]
|
||||
after := lines[position-1:]
|
||||
lines = append(before, append(contentLines, after...)...)
|
||||
|
||||
newContent := strings.Join(lines, "\n")
|
||||
|
||||
// Join the lines and write back to the file
|
||||
err = os.WriteFile(path, []byte(newContent), 0644)
|
||||
if err != nil {
|
||||
return api.CallResult{Message: fmt.Sprintf("Could not write to path: %s", err.Error())}
|
||||
}
|
||||
|
||||
return api.CallResult{Result: newContent}
|
||||
}
|
||||
Reference in New Issue
Block a user