prepareMessagesForRequest applies the prompt preparation pipeline used immediately before sending messages to a provider. It returns the possibly updated canonical messages and an independent provider-ready prompt. When preparation fails, the prompt result is nil and err is the terminal prompt-prepa
( ctx context.Context, opts RunOptions, messages []fantasy.Message, provider string, modelName string, step int, totalSteps int, )
| 738 | // prompt. When preparation fails, the prompt result is nil and err is the |
| 739 | // terminal prompt-preparation failure. |
| 740 | func prepareMessagesForRequest( |
| 741 | ctx context.Context, |
| 742 | opts RunOptions, |
| 743 | messages []fantasy.Message, |
| 744 | provider string, |
| 745 | modelName string, |
| 746 | step int, |
| 747 | totalSteps int, |
| 748 | ) (canonical []fantasy.Message, prompt []fantasy.Message, err error) { |
| 749 | canonical = messages |
| 750 | if opts.PrepareMessages != nil { |
| 751 | if updated := opts.PrepareMessages(canonical); updated != nil { |
| 752 | canonical = updated |
| 753 | } |
| 754 | } |
| 755 | // Copy messages so provider-specific caching mutations don't leak |
| 756 | // back to the canonical message slice. |
| 757 | prompt = slices.Clone(canonical) |
| 758 | prompt, sanitizeStats := chatsanitize.SanitizeAnthropicProviderToolHistory(provider, prompt) |
| 759 | chatsanitize.LogAnthropicProviderToolSanitization( |
| 760 | ctx, opts.Logger, "pre_request", provider, modelName, sanitizeStats, |
| 761 | slog.F("step_index", step), |
| 762 | slog.F("total_steps", totalSteps), |
| 763 | ) |
| 764 | prompt, err = chatsanitize.ApplyAnthropicProviderToolGuard( |
| 765 | ctx, opts.Logger, provider, modelName, prompt, |
| 766 | ) |
| 767 | if err != nil { |
| 768 | err = chaterror.WithClassification( |
| 769 | xerrors.Errorf("apply anthropic provider tool guard: %w", err), |
| 770 | chaterror.ClassifiedError{ |
| 771 | Message: "The chat continuation failed due to an internal state mismatch. This is not a configuration or billing issue. Start a new chat to continue.", |
| 772 | Detail: "Anthropic replay diagnostic: match=provider_tool_guard_postcondition_failed.", |
| 773 | Kind: codersdk.ChatErrorKindGeneric, |
| 774 | Provider: provider, |
| 775 | Retryable: false, |
| 776 | }, |
| 777 | ) |
| 778 | return canonical, nil, err |
| 779 | } |
| 780 | if shouldApplyAnthropicPromptCaching(opts.Model) { |
| 781 | addAnthropicPromptCaching(prompt) |
| 782 | } |
| 783 | return canonical, prompt, nil |
| 784 | } |
| 785 | |
| 786 | // guardedAttempt owns an attempt-scoped context and silence guard |
| 787 | // around a provider stream. release is idempotent and frees the |
no test coverage detected