• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kshard / thinker / 13442595752

20 Feb 2025 06:54PM UTC coverage: 71.538% (+3.8%) from 67.766%
13442595752

Pull #2

github

fogfish
update syntax
Pull Request #2: generalize reasoner for command workflow

105 of 128 new or added lines in 3 files covered. (82.03%)

10 existing lines in 2 files now uncovered.

279 of 390 relevant lines covered (71.54%)

0.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.62
/command/python.go
1
//
2
// Copyright (C) 2025 Dmitry Kolesnikov
3
//
4
// This file may be modified and distributed under the terms
5
// of the MIT license.  See the LICENSE file for details.
6
// https://github.com/kshard/thinker
7
//
8

9
package command
10

11
import (
12
        "bytes"
13
        "fmt"
14
        "log/slog"
15
        "os"
16
        "os/exec"
17
        "path/filepath"
18
        "strings"
19

20
        "github.com/kshard/chatter"
21
        "github.com/kshard/thinker"
22
)
23

24
// A unique name for bash (the shell)
25
const PYTHON = "python"
26

27
// Create new bash command, defining the os variant and working dir
28
func Python(dir string) thinker.Cmd {
1✔
29
        return thinker.Cmd{
1✔
30
                Cmd:    PYTHON,
1✔
31
                Short:  "Use Python REPL to execute scripts that help you complete your task (format python code with \\t, \\n). Declare dependencies to python modules.",
1✔
32
                Syntax: `python -c """source code"""`,
1✔
33
                Run:    python(dir),
1✔
34
        }
1✔
35
}
1✔
36

37
func pySetup(dir string) error {
1✔
38
        pyenv := filepath.Join(dir, ".venv")
1✔
39
        if _, err := os.Stat(pyenv); err != nil {
2✔
40
                slog.Info("Setup python")
1✔
41
                setup := exec.Command("python3", "-m", "venv", ".venv")
1✔
42
                setup.Dir = dir
1✔
43

1✔
44
                _, err := setup.Output()
1✔
45
                if err != nil {
1✔
NEW
46
                        return err
×
NEW
47
                }
×
48

49
                slog.Info("Setup pigar")
1✔
50
                pipreqs := exec.Command(filepath.Join(pyenv, "bin/python"), "-m", "pip", "install", "pigar")
1✔
51
                pipreqs.Dir = dir
1✔
52

1✔
53
                _, err = pipreqs.Output()
1✔
54
                if err != nil {
1✔
NEW
55
                        return err
×
NEW
56
                }
×
57
        }
58

59
        return nil
1✔
60
}
61

62
func pyDeps(dir, scode string) error {
1✔
63
        pyenv := filepath.Join(dir, ".venv")
1✔
64
        pysrc := filepath.Join(dir, "main.py")
1✔
65

1✔
66
        slog.Info("Write source code")
1✔
67
        if err := os.WriteFile(pysrc, []byte(scode), 0666); err != nil {
1✔
NEW
68
                return err
×
NEW
69
        }
×
70

71
        slog.Info("Generate deps")
1✔
72
        deps := exec.Command(filepath.Join(pyenv, "bin/pigar"), "generate", "--question-answer", "yes", "--auto-select")
1✔
73
        deps.Dir = dir
1✔
74

1✔
75
        _, err := deps.Output()
1✔
76
        if err != nil {
1✔
NEW
77
                return err
×
NEW
78
        }
×
79

80
        slog.Info("Install deps")
1✔
81
        pip := exec.Command(filepath.Join(pyenv, "bin/python"), "-m", "pip", "install", "-r", "requirements.txt")
1✔
82
        pip.Dir = dir
1✔
83

1✔
84
        _, err = pip.Output()
1✔
85
        if err != nil {
1✔
NEW
86
                return err
×
NEW
87
        }
×
88

89
        return nil
1✔
90
}
91

92
func python(dir string) func(chatter.Reply) (float64, thinker.CmdOut, error) {
1✔
93
        return func(command chatter.Reply) (float64, thinker.CmdOut, error) {
2✔
94
                if err := pySetup(dir); err != nil {
1✔
NEW
95
                        return 0.0, thinker.CmdOut{}, err
×
NEW
96
                }
×
97

98
                scode := strings.TrimSpace(command.Text)
1✔
99
                scode = strings.TrimPrefix(scode, `-c """`)
1✔
100
                scode = strings.TrimSuffix(scode, `"""`)
1✔
101

1✔
102
                if err := pyDeps(dir, scode); err != nil {
1✔
NEW
103
                        return 0.0, thinker.CmdOut{}, err
×
NEW
104
                }
×
105

106
                pyenv := filepath.Join(dir, ".venv")
1✔
107
                cmd := exec.Command(filepath.Join(pyenv, "bin/python"), "-c", scode)
1✔
108
                var stdout bytes.Buffer
1✔
109
                var stderr bytes.Buffer
1✔
110
                cmd.Dir = dir
1✔
111
                cmd.Stdout = &stdout
1✔
112
                cmd.Stderr = &stderr
1✔
113

1✔
114
                if err := cmd.Run(); err != nil {
1✔
NEW
115
                        err = thinker.Feedback(
×
NEW
116
                                fmt.Sprintf("The TOOL:%s has failed, improve the response based on feedback:", PYTHON),
×
NEW
117

×
NEW
118
                                `Strictly adhere python code formatting, use \t, \n where is needed`,
×
NEW
119
                                "Execution of python script is failed with the error: "+err.Error(),
×
NEW
120
                                "The error output is "+stderr.String(),
×
NEW
121
                        )
×
NEW
122
                        return 0.05, thinker.CmdOut{Cmd: PYTHON}, err
×
NEW
123
                }
×
124

125
                return 1.0, thinker.CmdOut{Cmd: PYTHON, Output: stdout.String()}, nil
1✔
126
        }
127
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc