Skip to content

Commit e28e7b7

Browse files
Print status of subcalls
1 parent a136e12 commit e28e7b7

File tree

6 files changed

+127
-37
lines changed

6 files changed

+127
-37
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ require (
2929
github.com/go-logr/logr v1.4.1 // indirect
3030
github.com/google/go-cmp v0.6.0 // indirect
3131
github.com/google/go-containerregistry v0.16.1 // indirect
32+
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect
3233
github.com/gorilla/websocket v1.5.0 // indirect
3334
github.com/hexops/gotextdiff v1.0.3 // indirect
3435
github.com/hexops/valast v1.4.3 // indirect

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
3232
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3333
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
3434
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
35-
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
36-
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
35+
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
36+
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
3737
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
3838
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
3939
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=

pkg/cli/gptscript.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ type GPTScript struct {
3232
runner.Options
3333
DisplayOptions
3434
Debug bool `usage:"Enable debug logging"`
35-
Quiet bool `usage:"No output logging" short:"q"`
35+
Quiet *bool `usage:"No output logging" short:"q"`
3636
Output string `usage:"Save output to a file, or - for stdout" short:"o"`
3737
Input string `usage:"Read input from a file (\"-\" for stdin)" short:"f"`
3838
SubTool string `usage:"Use tool of this name, not the first tool in file"`
@@ -80,19 +80,19 @@ func (r *GPTScript) listModels(ctx context.Context) error {
8080
}
8181

8282
func (r *GPTScript) Pre(cmd *cobra.Command, args []string) error {
83-
if r.Quiet {
83+
if r.Quiet == nil {
8484
if term.IsTerminal(int(os.Stdout.Fd())) {
85-
r.Quiet = false
85+
r.Quiet = new(bool)
8686
} else {
87-
r.Quiet = true
87+
r.Quiet = &[]bool{true}[0]
8888
}
8989
}
9090

9191
if r.Debug {
9292
mvl.SetDebug()
9393
} else {
9494
mvl.SetSimpleFormat()
95-
if r.Quiet {
95+
if *r.Quiet {
9696
mvl.SetError()
9797
}
9898
}
@@ -165,7 +165,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
165165
CacheOptions: r.CacheOptions,
166166
OpenAIOptions: r.OpenAIOptions,
167167
MonitorFactory: monitor.NewConsole(monitor.Options(r.DisplayOptions), monitor.Options{
168-
DisplayProgress: !r.Quiet,
168+
DisplayProgress: !*r.Quiet,
169169
}),
170170
})
171171
if err != nil {
@@ -188,7 +188,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) error {
188188
return err
189189
}
190190
} else {
191-
if !r.Quiet {
191+
if !*r.Quiet {
192192
if toolInput != "" {
193193
_, _ = fmt.Fprint(os.Stderr, "\nINPUT:\n\n")
194194
_, _ = fmt.Fprintln(os.Stderr, toolInput)

pkg/monitor/display.go

+98-10
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ type display struct {
5959
}
6060

6161
type livePrinter struct {
62-
lastLines map[string]string
63-
needsNewline bool
62+
lastContent map[string]string
63+
callIDMap map[string]string
64+
activePrinters []string
65+
toPrint []string
66+
needsNewline bool
6467
}
6568

6669
func (l *livePrinter) end() {
@@ -71,21 +74,100 @@ func (l *livePrinter) end() {
7174
_, _ = fmt.Fprintln(os.Stderr)
7275
}
7376
l.needsNewline = false
77+
if len(l.activePrinters) > 0 {
78+
delete(l.lastContent, l.activePrinters[0])
79+
}
7480
}
7581

76-
func (l *livePrinter) print(event runner.Event, c call) {
82+
func (l *livePrinter) progressStart(event runner.Event, c call) {
83+
if l == nil {
84+
return
85+
}
86+
if !slices.Contains(l.activePrinters, c.ID) {
87+
l.activePrinters = append(l.activePrinters, c.ID)
88+
}
89+
l.toPrint = slices.DeleteFunc(l.toPrint, func(s string) bool {
90+
return s == c.ID
91+
})
92+
}
93+
94+
func (l *livePrinter) progressEnd(event runner.Event, c call) {
7795
if l == nil {
7896
return
7997
}
80-
if c.ParentID != "" {
98+
var result []string
99+
for i, id := range l.activePrinters {
100+
if id != c.ID {
101+
result = append(result, id)
102+
continue
103+
}
104+
105+
if i != 0 {
106+
if !slices.Contains(l.toPrint, id) {
107+
l.toPrint = append(l.toPrint, id)
108+
}
109+
continue
110+
}
111+
112+
for _, toPrintID := range l.toPrint {
113+
content := l.lastContent[toPrintID]
114+
delete(l.lastContent, toPrintID)
115+
if content != "" {
116+
_, _ = fmt.Fprint(os.Stderr, content)
117+
if !strings.HasSuffix(content, "\n") {
118+
_, _ = fmt.Fprintln(os.Stderr)
119+
}
120+
}
121+
}
122+
123+
l.toPrint = nil
124+
result = l.activePrinters[1:]
125+
if len(result) > 0 {
126+
content := l.lastContent[result[0]]
127+
if content != "" {
128+
_, _ = fmt.Fprint(os.Stderr, content)
129+
l.needsNewline = !strings.HasSuffix(content, "\n")
130+
}
131+
}
132+
break
133+
}
134+
l.activePrinters = result
135+
}
136+
137+
func (l *livePrinter) formatContent(event runner.Event, c call) string {
138+
if event.Content == "" {
139+
return event.Content
140+
}
141+
prefix := fmt.Sprintf(" content [%s] content | ", l.callIDMap[c.ID])
142+
var lines []string
143+
for _, line := range strings.Split(event.Content, "\n") {
144+
if len(line) > 100 {
145+
line = line[:100] + " ..."
146+
}
147+
lines = append(lines, prefix+line)
148+
}
149+
return strings.Join(lines, "\n")
150+
}
151+
152+
func (l *livePrinter) print(event runner.Event, c call) {
153+
if l == nil {
81154
return
82155
}
83156

84-
last := l.lastLines[c.ID]
85-
line := strings.TrimPrefix(event.Content, last)
86-
_, _ = fmt.Fprint(os.Stderr, line)
87-
l.needsNewline = !strings.HasSuffix(line, "\n")
88-
l.lastLines[c.ID] = event.Content
157+
content := l.formatContent(event, c)
158+
last := l.lastContent[c.ID]
159+
l.lastContent[c.ID] = content
160+
161+
if len(l.activePrinters) > 0 && l.activePrinters[0] == c.ID && content != "" {
162+
line, ok := strings.CutPrefix(content, last)
163+
if !ok && last != "" {
164+
_, _ = fmt.Fprintln(os.Stderr)
165+
}
166+
if line != "" {
167+
_, _ = fmt.Fprint(os.Stderr, line)
168+
l.needsNewline = !strings.HasSuffix(line, "\n")
169+
}
170+
}
89171
}
90172

91173
func (d *display) Event(event runner.Event) {
@@ -135,13 +217,17 @@ func (d *display) Event(event runner.Event) {
135217

136218
switch event.Type {
137219
case runner.EventTypeCallStart:
220+
d.livePrinter.progressStart(event, currentCall)
138221
d.livePrinter.end()
139222
currentCall.Start = event.Time
140223
currentCall.Input = event.Content
141224
log.Fields("input", event.Content).Infof("started [%s]", callName)
225+
case runner.EventTypeCallSubCalls:
226+
d.livePrinter.progressEnd(event, currentCall)
142227
case runner.EventTypeCallProgress:
143228
d.livePrinter.print(event, currentCall)
144229
case runner.EventTypeCallContinue:
230+
d.livePrinter.progressStart(event, currentCall)
145231
d.livePrinter.end()
146232
log.Fields("toolResults", event.ToolResults).Infof("continue [%s]", callName)
147233
case runner.EventTypeChat:
@@ -167,6 +253,7 @@ func (d *display) Event(event runner.Event) {
167253
Cached: event.ChatResponseCached,
168254
})
169255
case runner.EventTypeCallFinish:
256+
d.livePrinter.progressEnd(event, currentCall)
170257
d.livePrinter.end()
171258
currentCall.End = event.Time
172259
currentCall.Output = event.Content
@@ -204,7 +291,8 @@ func newDisplay(dumpState string, progress bool) *display {
204291
}
205292
if progress {
206293
display.livePrinter = &livePrinter{
207-
lastLines: map[string]string{},
294+
lastContent: map[string]string{},
295+
callIDMap: display.callIDMap,
208296
}
209297
}
210298
return display

pkg/openai/client.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -407,19 +407,11 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest,
407407
cacheKey := c.cacheKey(request)
408408
request.Stream = true
409409

410-
msg := ""
411-
if len(request.Messages) > 0 {
412-
msg = request.Messages[len(request.Messages)-1].Content
413-
if msg != "" {
414-
msg = "Sent content:\n\n" + msg + "\n"
415-
}
416-
}
417-
418410
partial <- Status{
419411
CompletionID: transactionID,
420412
PartialResponse: &types.CompletionMessage{
421413
Role: types.CompletionMessageRoleTypeAssistant,
422-
Content: types.Text(msg + "Waiting for model response...\n"),
414+
Content: types.Text("Waiting for model response..."),
423415
},
424416
}
425417

pkg/runner/runner.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,24 @@ func (r *Runner) Run(ctx context.Context, prg types.Program, env []string, input
8383
}
8484

8585
type Event struct {
86-
Time time.Time `json:"time,omitempty"`
87-
CallContext *engine.Context `json:"callContext,omitempty"`
88-
ToolResults int `json:"toolResults,omitempty"`
89-
Type EventType `json:"type,omitempty"`
90-
ChatCompletionID string `json:"chatCompletionId,omitempty"`
91-
ChatRequest any `json:"chatRequest,omitempty"`
92-
ChatResponse any `json:"chatResponse,omitempty"`
93-
ChatResponseCached bool `json:"chatResponseCached,omitempty"`
94-
Content string `json:"content,omitempty"`
86+
Time time.Time `json:"time,omitempty"`
87+
CallContext *engine.Context `json:"callContext,omitempty"`
88+
ToolSubCalls map[string]engine.Call `json:"toolSubCalls,omitempty"`
89+
ToolResults int `json:"toolResults,omitempty"`
90+
Type EventType `json:"type,omitempty"`
91+
ChatCompletionID string `json:"chatCompletionId,omitempty"`
92+
ChatRequest any `json:"chatRequest,omitempty"`
93+
ChatResponse any `json:"chatResponse,omitempty"`
94+
ChatResponseCached bool `json:"chatResponseCached,omitempty"`
95+
Content string `json:"content,omitempty"`
9596
}
9697

9798
type EventType string
9899

99100
var (
100101
EventTypeCallStart = EventType("callStart")
101102
EventTypeCallContinue = EventType("callContinue")
103+
EventTypeCallSubCalls = EventType("callSubCalls")
102104
EventTypeCallProgress = EventType("callProgress")
103105
EventTypeChat = EventType("callChat")
104106
EventTypeCallFinish = EventType("callFinish")
@@ -138,6 +140,13 @@ func (r *Runner) call(callCtx engine.Context, monitor Monitor, env []string, inp
138140
return *result.Result, nil
139141
}
140142

143+
monitor.Event(Event{
144+
Time: time.Now(),
145+
CallContext: &callCtx,
146+
Type: EventTypeCallSubCalls,
147+
ToolSubCalls: result.Calls,
148+
})
149+
141150
callResults, err := r.subCalls(callCtx, monitor, env, result)
142151
if err != nil {
143152
return "", err

0 commit comments

Comments
 (0)