MCPcopy Index your code
hub / github.com/coder/coder / beginStep

Function beginStep

coderd/x/chatd/chatdebug/recorder.go:208–288  ·  view source on GitHub ↗

beginStep validates preconditions, creates a debug step, and returns a handle plus an enriched context carrying StepContext and attemptSink. Returns (nil, original ctx) when debug recording should be skipped.

(
	ctx context.Context,
	svc *Service,
	opts RecorderOptions,
	op Operation,
	normalizedReq any,
)

Source from the content-addressed store, hash-verified

206// handle plus an enriched context carrying StepContext and attemptSink.
207// Returns (nil, original ctx) when debug recording should be skipped.
208func beginStep(
209 ctx context.Context,
210 svc *Service,
211 opts RecorderOptions,
212 op Operation,
213 normalizedReq any,
214) (*stepHandle, context.Context) {
215 if svc == nil {
216 return nil, ctx
217 }
218
219 rc, ok := RunFromContext(ctx)
220 if !ok || rc.RunID == uuid.Nil {
221 return nil, ctx
222 }
223
224 chatID := opts.ChatID
225 if chatID == uuid.Nil {
226 chatID = rc.ChatID
227 }
228 if !svc.IsEnabled(ctx, chatID, opts.OwnerID) {
229 return nil, ctx
230 }
231
232 holder, reuseStep := reuseHolderFromContext(ctx)
233 if reuseStep {
234 holder.mu.Lock()
235 defer holder.mu.Unlock()
236 // Only reuse the cached handle if it belongs to the same run.
237 // A different RunContext means a new logical run, so we must
238 // create a fresh step to avoid cross-run attribution.
239 if holder.handle != nil && holder.handle.stepCtx.RunID == rc.RunID {
240 enriched := ContextWithStep(ctx, holder.handle.stepCtx)
241 enriched = withAttemptSink(enriched, holder.handle.sink)
242 return holder.handle, enriched
243 }
244 }
245
246 stepNum := nextStepNumber(rc.RunID)
247 step, err := svc.CreateStep(ctx, CreateStepParams{
248 RunID: rc.RunID,
249 ChatID: chatID,
250 StepNumber: stepNum,
251 Operation: op,
252 Status: StatusInProgress,
253 HistoryTipMessageID: rc.HistoryTipMessageID,
254 NormalizedRequest: normalizedReq,
255 })
256 if err != nil {
257 svc.log.Warn(ctx, "failed to create chat debug step",
258 slog.Error(err),
259 slog.F("chat_id", chatID),
260 slog.F("run_id", rc.RunID),
261 slog.F("operation", op),
262 )
263 return nil, ctx
264 }
265

Callers 8

TestBeginStep_NilServiceFunction · 0.85
GenerateMethod · 0.85
StreamMethod · 0.85
GenerateObjectMethod · 0.85
StreamObjectMethod · 0.85
TestBeginStepReuseStepFunction · 0.85

Calls 11

RunFromContextFunction · 0.85
reuseHolderFromContextFunction · 0.85
ContextWithStepFunction · 0.85
withAttemptSinkFunction · 0.85
nextStepNumberFunction · 0.85
syncStepCounterFunction · 0.85
IsEnabledMethod · 0.80
CreateStepMethod · 0.80
LockMethod · 0.45
UnlockMethod · 0.45
ErrorMethod · 0.45

Tested by 4

TestBeginStep_NilServiceFunction · 0.68
TestBeginStepReuseStepFunction · 0.68