run_marker.go

 1package agent
 2
 3import (
 4	"context"
 5	"sync/atomic"
 6)
 7
 8// runCompleteMarkerKey is the unexported context key carrying a
 9// [runCompleteMarker] from the dispatch boundary (backend.runAgent)
10// down into the coordinator. It lets the dispatcher learn whether the
11// coordinator already published the authoritative terminal
12// notify.RunComplete for the run, so a fallback terminal event is only
13// emitted when one is actually missing (e.g. an error returned before
14// sessionAgent.Run ever executed). It avoids a breaking change to the
15// Coordinator interface.
16type runCompleteMarkerKey struct{}
17
18// runCompleteMarker records whether a terminal RunComplete has been
19// published for a run. It is shared by pointer through the context so
20// a publish deep in the call stack is observable by the dispatcher
21// after the call returns.
22type runCompleteMarker struct {
23	published atomic.Bool
24}
25
26// WithRunCompleteMarker returns ctx carrying a fresh marker the
27// coordinator can flag via [MarkRunCompletePublished] once it emits the
28// run's terminal RunComplete. Callers read the result with
29// [RunCompletePublished]. Attaching the marker is optional: code paths
30// without one simply skip the dedup signal.
31func WithRunCompleteMarker(ctx context.Context) context.Context {
32	return context.WithValue(ctx, runCompleteMarkerKey{}, &runCompleteMarker{})
33}
34
35// MarkRunCompletePublished records that the authoritative terminal
36// RunComplete has been published for the run carried by ctx. It is a
37// no-op when no marker is present (e.g. the in-process/local Run path,
38// which is not dispatched through backend.runAgent).
39func MarkRunCompletePublished(ctx context.Context) {
40	if m, ok := ctx.Value(runCompleteMarkerKey{}).(*runCompleteMarker); ok {
41		m.published.Store(true)
42	}
43}
44
45// RunCompletePublished reports whether [MarkRunCompletePublished] was
46// called on ctx's marker. It returns false when no marker is present.
47func RunCompletePublished(ctx context.Context) bool {
48	if m, ok := ctx.Value(runCompleteMarkerKey{}).(*runCompleteMarker); ok {
49		return m.published.Load()
50	}
51	return false
52}