Skip to content

Commit 8bf87bf

Browse files
Merge pull request #206 from ibuildthecloud/eval
feat: add gptscript eval sub command
2 parents cdd7016 + 4302136 commit 8bf87bf

File tree

7 files changed

+242
-112
lines changed

7 files changed

+242
-112
lines changed

pkg/cli/eval.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strconv"
7+
"strings"
8+
9+
"github.com/gptscript-ai/gptscript/pkg/gptscript"
10+
"github.com/gptscript-ai/gptscript/pkg/input"
11+
"github.com/gptscript-ai/gptscript/pkg/loader"
12+
"github.com/gptscript-ai/gptscript/pkg/types"
13+
"github.com/spf13/cobra"
14+
)
15+
16+
type Eval struct {
17+
Tools []string `usage:"Tools available to call"`
18+
MaxTokens int `usage:"Maximum number of tokens to output"`
19+
Model string `usage:"The model to use"`
20+
JSON bool `usage:"Output JSON"`
21+
Temperature string `usage:"Set the temperature, \"creativity\""`
22+
InternalPrompt *bool `Usage:"Set to false to disable the internal prompt"`
23+
24+
gptscript *GPTScript
25+
}
26+
27+
func (e *Eval) Run(cmd *cobra.Command, args []string) error {
28+
tool := types.Tool{
29+
Parameters: types.Parameters{
30+
Description: "inline script",
31+
Tools: e.Tools,
32+
MaxTokens: e.MaxTokens,
33+
ModelName: e.Model,
34+
JSONResponse: e.JSON,
35+
InternalPrompt: e.InternalPrompt,
36+
},
37+
Instructions: strings.Join(args, " "),
38+
}
39+
40+
if e.Temperature != "" {
41+
temp, err := strconv.ParseFloat(e.Temperature, 32)
42+
if err != nil {
43+
return fmt.Errorf("failed to parse %v: %v", e.Temperature, err)
44+
}
45+
temp32 := float32(temp)
46+
tool.Temperature = &temp32
47+
}
48+
49+
prg, err := loader.ProgramFromSource(cmd.Context(), tool.String(), "")
50+
if err != nil {
51+
return err
52+
}
53+
54+
opts := e.gptscript.NewGPTScriptOpts()
55+
runner, err := gptscript.New(&opts)
56+
if err != nil {
57+
return err
58+
}
59+
60+
toolInput, err := input.FromFile(e.gptscript.Input)
61+
if err != nil {
62+
return err
63+
}
64+
65+
toolOutput, err := runner.Run(e.gptscript.NewRunContext(cmd), prg, os.Environ(), toolInput)
66+
if err != nil {
67+
return err
68+
}
69+
70+
return e.gptscript.PrintOutput("", toolOutput)
71+
}

pkg/cli/gptscript.go

Lines changed: 110 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package cli
22

33
import (
4+
"context"
45
"fmt"
56
"io"
67
"os"
8+
"sort"
79
"strings"
810

911
"github.com/acorn-io/cmd"
@@ -41,17 +43,38 @@ type GPTScript struct {
4143
Quiet *bool `usage:"No output logging (set --quiet=false to force on even when there is no TTY)" short:"q"`
4244
Output string `usage:"Save output to a file, or - for stdout" short:"o"`
4345
Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"`
44-
SubTool string `usage:"Use tool of this name, not the first tool in file"`
45-
Assemble bool `usage:"Assemble tool to a single artifact, saved to --output" hidden:"true"`
46-
ListModels bool `usage:"List the models available and exit"`
47-
ListTools bool `usage:"List built-in tools and exit"`
48-
Server bool `usage:"Start server"`
49-
ListenAddress string `usage:"Server listen address" default:"127.0.0.1:9090"`
46+
SubTool string `usage:"Use tool of this name, not the first tool in file" local:"true"`
47+
Assemble bool `usage:"Assemble tool to a single artifact, saved to --output" hidden:"true" local:"true"`
48+
ListModels bool `usage:"List the models available and exit" local:"true"`
49+
ListTools bool `usage:"List built-in tools and exit" local:"true"`
50+
Server bool `usage:"Start server" local:"true"`
51+
ListenAddress string `usage:"Server listen address" default:"127.0.0.1:9090" local:"true"`
5052
Chdir string `usage:"Change current working directory" short:"C"`
5153
}
5254

5355
func New() *cobra.Command {
54-
return cmd.Command(&GPTScript{})
56+
root := &GPTScript{}
57+
return cmd.Command(root, &Eval{
58+
gptscript: root,
59+
})
60+
}
61+
62+
func (r *GPTScript) NewRunContext(cmd *cobra.Command) context.Context {
63+
ctx := cmd.Context()
64+
if r.Confirm {
65+
ctx = confirm.WithConfirm(ctx, confirm.TextPrompt{})
66+
}
67+
return ctx
68+
}
69+
70+
func (r *GPTScript) NewGPTScriptOpts() gptscript.Options {
71+
return gptscript.Options{
72+
Cache: cache.Options(r.CacheOptions),
73+
OpenAI: openai.Options(r.OpenAIOptions),
74+
Monitor: monitor.Options(r.DisplayOptions),
75+
Quiet: r.Quiet,
76+
Env: os.Environ(),
77+
}
5578
}
5679

5780
func (r *GPTScript) Customize(cmd *cobra.Command) {
@@ -74,16 +97,27 @@ func (r *GPTScript) Customize(cmd *cobra.Command) {
7497
}
7598
}
7699

77-
func (r *GPTScript) listTools() error {
100+
func (r *GPTScript) listTools(ctx context.Context, gptScript *gptscript.GPTScript, prg types.Program) error {
101+
tools := gptScript.ListTools(ctx, prg)
102+
sort.Slice(tools, func(i, j int) bool {
103+
return tools[i].Name < tools[j].Name
104+
})
78105
var lines []string
79-
for _, tool := range builtin.ListTools() {
106+
for _, tool := range tools {
107+
if tool.Name == "" {
108+
tool.Name = prg.Name
109+
}
110+
111+
// Don't print instructions
112+
tool.Instructions = ""
113+
80114
lines = append(lines, tool.String())
81115
}
82116
fmt.Println(strings.Join(lines, "\n---\n"))
83117
return nil
84118
}
85119

86-
func (r *GPTScript) Pre(*cobra.Command, []string) error {
120+
func (r *GPTScript) PersistentPre(*cobra.Command, []string) error {
87121
// chdir as soon as possible
88122
if r.Chdir != "" {
89123
if err := os.Chdir(r.Chdir); err != nil {
@@ -111,10 +145,7 @@ func (r *GPTScript) Pre(*cobra.Command, []string) error {
111145
mvl.SetError()
112146
}
113147
}
114-
return nil
115-
}
116148

117-
func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
118149
if r.Color != nil {
119150
color.NoColor = !*r.Color
120151
}
@@ -123,14 +154,64 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
123154
log.Infof("WARNING: Changing the default model can have unknown behavior for existing tools. Use the model field per tool instead.")
124155
}
125156

126-
gptOpt := gptscript.Options{
127-
Cache: cache.Options(r.CacheOptions),
128-
OpenAI: openai.Options(r.OpenAIOptions),
129-
Monitor: monitor.Options(r.DisplayOptions),
130-
Quiet: r.Quiet,
131-
Env: os.Environ(),
157+
return nil
158+
}
159+
160+
func (r *GPTScript) listModels(ctx context.Context, gptScript *gptscript.GPTScript, args []string) error {
161+
models, err := gptScript.ListModels(ctx, args...)
162+
if err != nil {
163+
return err
164+
}
165+
fmt.Println(strings.Join(models, "\n"))
166+
return nil
167+
}
168+
169+
func (r *GPTScript) readProgram(ctx context.Context, args []string) (prg types.Program, err error) {
170+
if len(args) == 0 {
171+
return
132172
}
133173

174+
if args[0] == "-" {
175+
data, err := io.ReadAll(os.Stdin)
176+
if err != nil {
177+
return prg, err
178+
}
179+
prg, err = loader.ProgramFromSource(ctx, string(data), r.SubTool)
180+
if err != nil {
181+
return prg, err
182+
}
183+
}
184+
185+
return loader.Program(ctx, args[0], r.SubTool)
186+
}
187+
188+
func (r *GPTScript) PrintOutput(toolInput, toolOutput string) (err error) {
189+
if r.Output != "" {
190+
err = os.WriteFile(r.Output, []byte(toolOutput), 0644)
191+
if err != nil {
192+
return err
193+
}
194+
} else {
195+
if !*r.Quiet {
196+
if toolInput != "" {
197+
_, _ = fmt.Fprint(os.Stderr, "\nINPUT:\n\n")
198+
_, _ = fmt.Fprintln(os.Stderr, toolInput)
199+
}
200+
_, _ = fmt.Fprint(os.Stderr, "\nOUTPUT:\n\n")
201+
}
202+
fmt.Print(toolOutput)
203+
if !strings.HasSuffix(toolOutput, "\n") {
204+
fmt.Println()
205+
}
206+
}
207+
208+
return
209+
}
210+
211+
func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
212+
gptOpt := r.NewGPTScriptOpts()
213+
ctx := cmd.Context()
214+
134215
if r.Server {
135216
s, err := server.New(&server.Options{
136217
ListenAddress: r.ListenAddress,
@@ -140,7 +221,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
140221
return err
141222
}
142223
defer s.Close()
143-
return s.Start(cmd.Context())
224+
return s.Start(ctx)
144225
}
145226

146227
gptScript, err := gptscript.New(&gptOpt)
@@ -150,42 +231,22 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
150231
defer gptScript.Close()
151232

152233
if r.ListModels {
153-
models, err := gptScript.ListModels(cmd.Context(), args...)
154-
if err != nil {
155-
return err
156-
}
157-
fmt.Println(strings.Join(models, "\n"))
158-
return nil
234+
return r.listModels(ctx, gptScript, args)
235+
}
236+
237+
prg, err := r.readProgram(ctx, args)
238+
if err != nil {
239+
return err
159240
}
160241

161242
if r.ListTools {
162-
return r.listTools()
243+
return r.listTools(ctx, gptScript, prg)
163244
}
164245

165246
if len(args) == 0 {
166247
return cmd.Help()
167248
}
168249

169-
var (
170-
prg types.Program
171-
)
172-
173-
if args[0] == "-" {
174-
data, err := io.ReadAll(os.Stdin)
175-
if err != nil {
176-
return err
177-
}
178-
prg, err = loader.ProgramFromSource(cmd.Context(), string(data), r.SubTool)
179-
if err != nil {
180-
return err
181-
}
182-
} else {
183-
prg, err = loader.Program(cmd.Context(), args[0], r.SubTool)
184-
if err != nil {
185-
return err
186-
}
187-
}
188-
189250
if r.Assemble {
190251
var out io.Writer = os.Stdout
191252
if r.Output != "" && r.Output != "-" {
@@ -205,33 +266,10 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
205266
return err
206267
}
207268

208-
ctx := cmd.Context()
209-
if r.Confirm {
210-
ctx = confirm.WithConfirm(ctx, confirm.TextPrompt{})
211-
}
212-
s, err := gptScript.Run(ctx, prg, os.Environ(), toolInput)
269+
s, err := gptScript.Run(r.NewRunContext(cmd), prg, os.Environ(), toolInput)
213270
if err != nil {
214271
return err
215272
}
216273

217-
if r.Output != "" {
218-
err = os.WriteFile(r.Output, []byte(s), 0644)
219-
if err != nil {
220-
return err
221-
}
222-
} else {
223-
if !*r.Quiet {
224-
if toolInput != "" {
225-
_, _ = fmt.Fprint(os.Stderr, "\nINPUT:\n\n")
226-
_, _ = fmt.Fprintln(os.Stderr, toolInput)
227-
}
228-
_, _ = fmt.Fprint(os.Stderr, "\nOUTPUT:\n\n")
229-
}
230-
fmt.Print(s)
231-
if !strings.HasSuffix(s, "\n") {
232-
fmt.Println()
233-
}
234-
}
235-
236-
return nil
274+
return r.PrintOutput(toolInput, s)
237275
}

0 commit comments

Comments
 (0)