8
8
"fmt"
9
9
"io"
10
10
"log/slog"
11
+ "maps"
11
12
"net/http"
12
13
"os/exec"
13
14
"strconv"
@@ -26,10 +27,13 @@ type Run struct {
26
27
wait func ()
27
28
basicCommand bool
28
29
29
- rawOutput map [string ]any
30
- output , errput string
31
- events chan Frame
32
- lock sync.Mutex
30
+ callsLock sync.RWMutex
31
+ calls map [string ]CallFrame
32
+ parentCallFrameID string
33
+ rawOutput map [string ]any
34
+ output , errput string
35
+ events chan Frame
36
+ lock sync.Mutex
33
37
}
34
38
35
39
// Text returns the text output of the gptscript. It blocks until the output is ready.
@@ -59,6 +63,25 @@ func (r *Run) Err() error {
59
63
return r .err
60
64
}
61
65
66
+ // Calls will return a flattened array of the calls for this run.
67
+ func (r * Run ) Calls () map [string ]CallFrame {
68
+ r .callsLock .RLock ()
69
+ defer r .callsLock .RUnlock ()
70
+ return maps .Clone (r .calls )
71
+ }
72
+
73
+ // ParentCallFrame returns the CallFrame for the top-level or "parent" call. The boolean indicates whether there is a parent CallFrame.
74
+ func (r * Run ) ParentCallFrame () (CallFrame , bool ) {
75
+ r .callsLock .RLock ()
76
+ defer r .callsLock .RUnlock ()
77
+
78
+ if r .parentCallFrameID == "" {
79
+ return CallFrame {}, false
80
+ }
81
+
82
+ return r .calls [r .parentCallFrameID ], true
83
+ }
84
+
62
85
// ErrorOutput returns the stderr output of the gptscript.
63
86
// Should only be called after Bytes or Text has returned an error.
64
87
func (r * Run ) ErrorOutput () string {
@@ -287,6 +310,15 @@ func (r *Run) request(ctx context.Context, payload any) (err error) {
287
310
return
288
311
}
289
312
313
+ if event .Call != nil {
314
+ r .callsLock .Lock ()
315
+ r .calls [event .Call .ID ] = * event .Call
316
+ if r .parentCallFrameID == "" && event .Call .ParentID == "" {
317
+ r .parentCallFrameID = event .Call .ID
318
+ }
319
+ r .callsLock .Unlock ()
320
+ }
321
+
290
322
if r .opts .IncludeEvents {
291
323
r .events <- event
292
324
}
0 commit comments