Feat (cli): test run and teardown
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,3 +19,4 @@ chat_exports/*.json
|
|||||||
ragimport
|
ragimport
|
||||||
.env
|
.env
|
||||||
onnx/
|
onnx/
|
||||||
|
*.log
|
||||||
|
|||||||
91
cli-tests/sort-text/check.sh
Executable file
91
cli-tests/sort-text/check.sh
Executable file
@@ -0,0 +1,91 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
LOG_FILE="$SCRIPT_DIR/run.log"
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
log_pass() {
|
||||||
|
echo "[PASS] $1"
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_fail() {
|
||||||
|
echo "[FAIL] $1"
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "=== Checking results ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check animals directory exists
|
||||||
|
if [ -d "/tmp/sort-text/animals" ]; then
|
||||||
|
log_pass "animals directory exists"
|
||||||
|
else
|
||||||
|
log_fail "animals directory missing"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check colors directory exists
|
||||||
|
if [ -d "/tmp/sort-text/colors" ]; then
|
||||||
|
log_pass "colors directory exists"
|
||||||
|
else
|
||||||
|
log_fail "colors directory missing"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check animals contain cat/dog
|
||||||
|
ANIMALS_FILES=$(ls -1 /tmp/sort-text/animals 2>/dev/null | tr '\n' ' ')
|
||||||
|
if echo "$ANIMALS_FILES" | grep -q "file1.txt" && echo "$ANIMALS_FILES" | grep -q "file3.txt"; then
|
||||||
|
log_pass "animals contains animal files"
|
||||||
|
else
|
||||||
|
log_fail "animals missing animal files (got: $ANIMALS_FILES)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check colors contain red/blue
|
||||||
|
COLORS_FILES=$(ls -1 /tmp/sort-text/colors 2>/dev/null | tr '\n' ' ')
|
||||||
|
if echo "$COLORS_FILES" | grep -q "file2.txt" && echo "$COLORS_FILES" | grep -q "file4.txt"; then
|
||||||
|
log_pass "colors contains color files"
|
||||||
|
else
|
||||||
|
log_fail "colors missing color files (got: $COLORS_FILES)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify content
|
||||||
|
if grep -q "cat" /tmp/sort-text/animals/file1.txt 2>/dev/null; then
|
||||||
|
log_pass "file1.txt contains 'cat'"
|
||||||
|
else
|
||||||
|
log_fail "file1.txt missing 'cat'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "dog" /tmp/sort-text/animals/file3.txt 2>/dev/null; then
|
||||||
|
log_pass "file3.txt contains 'dog'"
|
||||||
|
else
|
||||||
|
log_fail "file3.txt missing 'dog'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "red" /tmp/sort-text/colors/file2.txt 2>/dev/null; then
|
||||||
|
log_pass "file2.txt contains 'red'"
|
||||||
|
else
|
||||||
|
log_fail "file2.txt missing 'red'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q "blue" /tmp/sort-text/colors/file4.txt 2>/dev/null; then
|
||||||
|
log_pass "file4.txt contains 'blue'"
|
||||||
|
else
|
||||||
|
log_fail "file4.txt missing 'blue'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Summary ==="
|
||||||
|
echo "PASSED: $PASS"
|
||||||
|
echo "FAILED: $FAIL"
|
||||||
|
|
||||||
|
if [ $FAIL -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Log file: $LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "All tests passed!"
|
||||||
|
exit 0
|
||||||
25
cli-tests/sort-text/run.sh
Executable file
25
cli-tests/sort-text/run.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
LOG_FILE="$SCRIPT_DIR/${TIMESTAMP}_run.log"
|
||||||
|
|
||||||
|
exec > "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
|
echo "=== Running teardown ==="
|
||||||
|
"$SCRIPT_DIR/teardown.sh"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Running setup ==="
|
||||||
|
"$SCRIPT_DIR/setup.sh"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Running task ==="
|
||||||
|
TASK=$(cat "$SCRIPT_DIR/task.txt")
|
||||||
|
cd /home/grail/projects/plays/goplays/gf-lt
|
||||||
|
go run . -cli -msg "$TASK"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Done ==="
|
||||||
|
echo "Log file: $LOG_FILE"
|
||||||
4
cli-tests/sort-text/teardown.sh
Executable file
4
cli-tests/sort-text/teardown.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
rm -rf /tmp/sort-text
|
||||||
131
tools/chain.go
131
tools/chain.go
@@ -150,7 +150,7 @@ func execSingle(command, stdin string) (string, error) {
|
|||||||
name := parts[0]
|
name := parts[0]
|
||||||
args := parts[1:]
|
args := parts[1:]
|
||||||
// Check if it's a built-in Go command
|
// Check if it's a built-in Go command
|
||||||
if result := execBuiltin(name, args, stdin); result != "" {
|
if result, isBuiltin := execBuiltin(name, args, stdin); isBuiltin {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
// Otherwise execute as system command
|
// Otherwise execute as system command
|
||||||
@@ -201,21 +201,23 @@ func tokenize(input string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// execBuiltin executes a built-in command if it exists.
|
// execBuiltin executes a built-in command if it exists.
|
||||||
func execBuiltin(name string, args []string, stdin string) string {
|
// Returns (result, true) if it was a built-in (even if result is empty).
|
||||||
|
// Returns ("", false) if it's not a built-in command.
|
||||||
|
func execBuiltin(name string, args []string, stdin string) (string, bool) {
|
||||||
switch name {
|
switch name {
|
||||||
case "echo":
|
case "echo":
|
||||||
if stdin != "" {
|
if stdin != "" {
|
||||||
return stdin
|
return stdin, true
|
||||||
}
|
}
|
||||||
return strings.Join(args, " ")
|
return strings.Join(args, " "), true
|
||||||
case "time":
|
case "time":
|
||||||
return "2006-01-02 15:04:05 MST"
|
return "2006-01-02 15:04:05 MST", true
|
||||||
case "cat":
|
case "cat":
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
if stdin != "" {
|
if stdin != "" {
|
||||||
return stdin
|
return stdin, true
|
||||||
}
|
}
|
||||||
return ""
|
return "", true
|
||||||
}
|
}
|
||||||
path := args[0]
|
path := args[0]
|
||||||
abs := path
|
abs := path
|
||||||
@@ -224,14 +226,14 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
}
|
}
|
||||||
data, err := os.ReadFile(abs)
|
data, err := os.ReadFile(abs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprintf("[error] cat: %v", err)
|
return fmt.Sprintf("[error] cat: %v", err), true
|
||||||
}
|
}
|
||||||
return string(data)
|
return string(data), true
|
||||||
case "pwd":
|
case "pwd":
|
||||||
return cfg.FilePickerDir
|
return cfg.FilePickerDir, true
|
||||||
case "cd":
|
case "cd":
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "[error] usage: cd <dir>"
|
return "[error] usage: cd <dir>", true
|
||||||
}
|
}
|
||||||
dir := args[0]
|
dir := args[0]
|
||||||
// Resolve relative to cfg.FilePickerDir
|
// Resolve relative to cfg.FilePickerDir
|
||||||
@@ -242,16 +244,16 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
abs = filepath.Clean(abs)
|
abs = filepath.Clean(abs)
|
||||||
info, err := os.Stat(abs)
|
info, err := os.Stat(abs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprintf("[error] cd: %v", err)
|
return fmt.Sprintf("[error] cd: %v", err), true
|
||||||
}
|
}
|
||||||
if !info.IsDir() {
|
if !info.IsDir() {
|
||||||
return "[error] cd: not a directory: " + dir
|
return "[error] cd: not a directory: " + dir, true
|
||||||
}
|
}
|
||||||
cfg.FilePickerDir = abs
|
cfg.FilePickerDir = abs
|
||||||
return "Changed directory to: " + cfg.FilePickerDir
|
return "Changed directory to: " + cfg.FilePickerDir, true
|
||||||
case "mkdir":
|
case "mkdir":
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "[error] usage: mkdir [-p] <dir>"
|
return "[error] usage: mkdir [-p] <dir>", true
|
||||||
}
|
}
|
||||||
createParents := false
|
createParents := false
|
||||||
var dirPath string
|
var dirPath string
|
||||||
@@ -263,7 +265,7 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dirPath == "" {
|
if dirPath == "" {
|
||||||
return "[error] usage: mkdir [-p] <dir>"
|
return "[error] usage: mkdir [-p] <dir>", true
|
||||||
}
|
}
|
||||||
abs := dirPath
|
abs := dirPath
|
||||||
if !filepath.IsAbs(dirPath) {
|
if !filepath.IsAbs(dirPath) {
|
||||||
@@ -277,12 +279,12 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
mkdirFunc = os.Mkdir
|
mkdirFunc = os.Mkdir
|
||||||
}
|
}
|
||||||
if err := mkdirFunc(abs, 0o755); err != nil {
|
if err := mkdirFunc(abs, 0o755); err != nil {
|
||||||
return fmt.Sprintf("[error] mkdir: %v", err)
|
return fmt.Sprintf("[error] mkdir: %v", err), true
|
||||||
}
|
}
|
||||||
if createParents {
|
if createParents {
|
||||||
return "Created " + dirPath + " (with parents)"
|
return "Created " + dirPath + " (with parents)", true
|
||||||
}
|
}
|
||||||
return "Created " + dirPath
|
return "Created " + dirPath, true
|
||||||
case "ls":
|
case "ls":
|
||||||
dir := "."
|
dir := "."
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
@@ -297,7 +299,7 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
}
|
}
|
||||||
entries, err := os.ReadDir(abs)
|
entries, err := os.ReadDir(abs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprintf("[error] ls: %v", err)
|
return fmt.Sprintf("[error] ls: %v", err), true
|
||||||
}
|
}
|
||||||
var out strings.Builder
|
var out strings.Builder
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
@@ -317,21 +319,98 @@ func execBuiltin(name string, args []string, stdin string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if out.Len() == 0 {
|
if out.Len() == 0 {
|
||||||
return "(empty directory)"
|
return "(empty directory)", true
|
||||||
}
|
}
|
||||||
return strings.TrimRight(out.String(), "\n")
|
return strings.TrimRight(out.String(), "\n"), true
|
||||||
case "go":
|
case "go":
|
||||||
// Allow all go subcommands
|
// Allow all go subcommands
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return "[error] usage: go <subcommand> [options]"
|
return "[error] usage: go <subcommand> [options]", true
|
||||||
}
|
}
|
||||||
cmd := exec.Command("go", args...)
|
cmd := exec.Command("go", args...)
|
||||||
cmd.Dir = cfg.FilePickerDir
|
cmd.Dir = cfg.FilePickerDir
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprintf("[error] go %s: %v\n%s", args[0], err, string(output))
|
return fmt.Sprintf("[error] go %s: %v\n%s", args[0], err, string(output)), true
|
||||||
}
|
}
|
||||||
return string(output)
|
return string(output), true
|
||||||
|
case "cp":
|
||||||
|
if len(args) < 2 {
|
||||||
|
return "[error] usage: cp <source> <dest>", true
|
||||||
|
}
|
||||||
|
src := args[0]
|
||||||
|
dst := args[1]
|
||||||
|
if !filepath.IsAbs(src) {
|
||||||
|
src = filepath.Join(cfg.FilePickerDir, src)
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(dst) {
|
||||||
|
dst = filepath.Join(cfg.FilePickerDir, dst)
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(src)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] cp: %v", err), true
|
||||||
|
}
|
||||||
|
err = os.WriteFile(dst, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] cp: %v", err), true
|
||||||
|
}
|
||||||
|
return "Copied " + src + " to " + dst, true
|
||||||
|
case "mv":
|
||||||
|
if len(args) < 2 {
|
||||||
|
return "[error] usage: mv <source> <dest>", true
|
||||||
|
}
|
||||||
|
src := args[0]
|
||||||
|
dst := args[1]
|
||||||
|
if !filepath.IsAbs(src) {
|
||||||
|
src = filepath.Join(cfg.FilePickerDir, src)
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(dst) {
|
||||||
|
dst = filepath.Join(cfg.FilePickerDir, dst)
|
||||||
|
}
|
||||||
|
err := os.Rename(src, dst)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] mv: %v", err), true
|
||||||
|
}
|
||||||
|
return "Moved " + src + " to " + dst, true
|
||||||
|
case "rm":
|
||||||
|
if len(args) == 0 {
|
||||||
|
return "[error] usage: rm [-r] <file>", true
|
||||||
|
}
|
||||||
|
recursive := false
|
||||||
|
var target string
|
||||||
|
for _, a := range args {
|
||||||
|
if a == "-r" || a == "-rf" || a == "-fr" || a == "-recursive" {
|
||||||
|
recursive = true
|
||||||
|
} else if target == "" {
|
||||||
|
target = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if target == "" {
|
||||||
|
return "[error] usage: rm [-r] <file>", true
|
||||||
|
}
|
||||||
|
abs := target
|
||||||
|
if !filepath.IsAbs(target) {
|
||||||
|
abs = filepath.Join(cfg.FilePickerDir, target)
|
||||||
|
}
|
||||||
|
info, err := os.Stat(abs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] rm: %v", err), true
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
if recursive {
|
||||||
|
err = os.RemoveAll(abs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] rm: %v", err), true
|
||||||
|
}
|
||||||
|
return "Removed " + abs, true
|
||||||
|
}
|
||||||
|
return "[error] rm: is a directory (use -r)", true
|
||||||
|
}
|
||||||
|
err = os.Remove(abs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("[error] rm: %v", err), true
|
||||||
|
}
|
||||||
|
return "Removed " + abs, true
|
||||||
}
|
}
|
||||||
return ""
|
return "", false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,10 +134,10 @@ func (t *Tools) initAgentsB() {
|
|||||||
agent.RegisterB("summarize_chat", agent.NewWebAgentB(t.webAgentClient, summarySysPrompt))
|
agent.RegisterB("summarize_chat", agent.NewWebAgentB(t.webAgentClient, summarySysPrompt))
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitTools(cfg *config.Config, logger *slog.Logger, store storage.FullRepo) *Tools {
|
func InitTools(initCfg *config.Config, logger *slog.Logger, store storage.FullRepo) *Tools {
|
||||||
_ = logger
|
logger = logger
|
||||||
_ = cfg
|
cfg = initCfg
|
||||||
if cfg.PlaywrightEnabled {
|
if initCfg.PlaywrightEnabled {
|
||||||
if err := CheckPlaywright(); err != nil {
|
if err := CheckPlaywright(); err != nil {
|
||||||
// slow, need a faster check if playwright install
|
// slow, need a faster check if playwright install
|
||||||
if err := InstallPW(); err != nil {
|
if err := InstallPW(); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user