Replay reconstructs an AI request from the ledger and re-executes it.
(ctx context.Context, cfg *config.Config, store requests.Store, requestID string, mode Mode, deps Dependencies)
| 39 | |
| 40 | // Replay reconstructs an AI request from the ledger and re-executes it. |
| 41 | func Replay(ctx context.Context, cfg *config.Config, store requests.Store, requestID string, mode Mode, deps Dependencies) (types.AIResponse, error) { |
| 42 | if store == nil { |
| 43 | return types.AIResponse{}, errors.New("ledger store is nil") |
| 44 | } |
| 45 | row, err := store.GetRequest(ctx, requestID) |
| 46 | if err != nil { |
| 47 | return types.AIResponse{}, err |
| 48 | } |
| 49 | var req types.AIRequest |
| 50 | if len(row.AIRequestJSON) > 0 { |
| 51 | if err := json.Unmarshal(row.AIRequestJSON, &req); err != nil { |
| 52 | return types.AIResponse{}, fmt.Errorf("decode ai_request_json: %w", err) |
| 53 | } |
| 54 | } else { |
| 55 | if err := json.Unmarshal(row.InputJSON, &req.Input); err != nil { |
| 56 | return types.AIResponse{}, fmt.Errorf("decode input: %w", err) |
| 57 | } |
| 58 | if err := json.Unmarshal(row.ContextJSON, &req.Context); err != nil { |
| 59 | return types.AIResponse{}, fmt.Errorf("decode context: %w", err) |
| 60 | } |
| 61 | } |
| 62 | req.RequestID = row.RequestID |
| 63 | req.TenantID = row.TenantID |
| 64 | req.TaskType = row.TaskType |
| 65 | req.Priority = row.Priority |
| 66 | req.RequestType = row.RequestType |
| 67 | req.PipelineRef = row.PipelineRef |
| 68 | req = types.NormalizeAIRequest(req) |
| 69 | |
| 70 | switch mode { |
| 71 | case ModeExact: |
| 72 | return replayExact(ctx, cfg, req, row, deps) |
| 73 | case ModeCurrent: |
| 74 | return replayCurrent(ctx, cfg, req, deps) |
| 75 | default: |
| 76 | return types.AIResponse{}, fmt.Errorf("unknown replay mode %q", mode) |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | func replayExact(ctx context.Context, cfg *config.Config, req types.AIRequest, row requests.RequestRow, deps Dependencies) (types.AIResponse, error) { |
| 81 | var snap types.PolicySnapshot |