| 60 | } |
| 61 | |
| 62 | func (r *Runner) Run(ctx context.Context, id string, logs io.Writer) error { |
| 63 | ctx, span := tracing.StartSpan(ctx) |
| 64 | defer span.End() |
| 65 | |
| 66 | logs = loadtestutil.NewSyncWriter(logs) |
| 67 | logger := slog.Make(sloghuman.Sink(logs)).Leveled(slog.LevelDebug).Named(id) |
| 68 | r.client.SetLogger(logger) |
| 69 | r.client.SetLogBodies(true) |
| 70 | |
| 71 | span.SetAttributes( |
| 72 | attribute.String("chat.runner_id", id), |
| 73 | attribute.String("chat.workspace_id", r.cfg.WorkspaceID.String()), |
| 74 | attribute.Int("chat.turns_requested", r.cfg.Turns), |
| 75 | attribute.Int64("chat.turn_start_delay_ms", r.cfg.TurnStartDelay.Milliseconds()), |
| 76 | ) |
| 77 | span.SetAttributes(attribute.String("chat.model_config_id", r.cfg.ModelConfigID.String())) |
| 78 | |
| 79 | markTurnStartReady := func() {} |
| 80 | if r.cfg.TurnStartReadyWaitGroup != nil { |
| 81 | markTurnStartReady = sync.OnceFunc(r.cfg.TurnStartReadyWaitGroup.Done) |
| 82 | } |
| 83 | r.markTurnStartReady = markTurnStartReady |
| 84 | defer r.markTurnStartReady() |
| 85 | |
| 86 | defer func() { |
| 87 | if !r.conversationStart.IsZero() { |
| 88 | r.result.totalDuration = time.Since(r.conversationStart) |
| 89 | r.cfg.Metrics.ChatConversationDurationSeconds.Observe(r.result.totalDuration.Seconds()) |
| 90 | } |
| 91 | span.SetAttributes( |
| 92 | attribute.String("chat.final_status", r.result.finalStatus), |
| 93 | attribute.String("chat.failure_stage", r.result.failureStage), |
| 94 | attribute.Int("chat.retry_count", r.result.retryCount), |
| 95 | attribute.Int("chat.turns_completed", r.result.turnsCompleted), |
| 96 | attribute.Bool("chat.saw_first_output", r.result.sawFirstOutput), |
| 97 | ) |
| 98 | if r.result.totalDuration > 0 { |
| 99 | span.SetAttributes(attribute.Float64("chat.total_duration_seconds", r.result.totalDuration.Seconds())) |
| 100 | } |
| 101 | }() |
| 102 | |
| 103 | workspaceID := r.cfg.WorkspaceID |
| 104 | modelConfigID := r.cfg.ModelConfigID |
| 105 | logger = logger.With(slog.F("workspace_id", workspaceID)) |
| 106 | logger.Info(ctx, "starting chat runner") |
| 107 | |
| 108 | r.resetConversation(time.Now(), markTurnStartReady) |
| 109 | |
| 110 | createStartedAt := time.Now() |
| 111 | chat, err := r.client.CreateChat(ctx, codersdk.CreateChatRequest{ |
| 112 | OrganizationID: r.cfg.OrganizationID, |
| 113 | WorkspaceID: &workspaceID, |
| 114 | ModelConfigID: &modelConfigID, |
| 115 | Content: []codersdk.ChatInputPart{{ |
| 116 | Type: codersdk.ChatInputPartTypeText, |
| 117 | Text: r.cfg.Prompt, |
| 118 | }}, |
| 119 | }) |