feat: add self-correcting OpenAI sampling-param handling#101
Conversation
OpenAI split Chat Completions into two parameter generations: legacy models use `temperature` + `max_tokens`, while newer reasoning models (o1/o3/o4/gpt-5+) use `max_completion_tokens` and reject `temperature` overrides. Pick the best-guess parameter set per model family via a short legacy allowlist, then auto-correct on rejection: `post_openai_chat` inspects OpenAI's error (preferring the structured `error.param` field over the message text) and adjusts the offending field in place, retrying up to MAX_OPENAI_PARAM_ADJUSTMENTS times. The constant counts corrections rather than requests, and every attempt flows through a single loop path so the true request count (adjustments + 1) is clear. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6ccdb5b to
7144215
Compare
|
Thanks for the focused fix. The overall direction looks right: centralizing OpenAI sampling-parameter handling and using structured OpenAI error details is a good approach, and I don’t see a security issue in the bounded retry loop. I’d like to request two small changes before merge:
I verified locally that |
Address review feedback: - Route the Proxy provider (OpenAI-compatible, defaults to api.openai.com with a GPT-5 model) through apply_openai_sampling_params + post_openai_chat, so it gets the same param selection and self-correcting retry as OpenAI instead of always sending temperature + max_tokens. - Make adjust_openai_request swap the token-limit field in both directions: max_tokens -> max_completion_tokens (reasoning models) and max_completion_tokens -> max_tokens (proxies that only accept the legacy field), so the retry loop recovers regardless of which the endpoint rejects. - Add unit tests for apply_openai_sampling_params (legacy vs reasoning models, unset token limit, case-insensitive detection) and adjust_openai_request (remove rejected temperature, convert max_tokens both ways, message-only fallback, no-op when field absent, combined adjustments). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Cảm ơn phản hồi chi tiết! Mình đã xử lý cả hai điểm trong commit mới: 1. Proxy provider dùng chung retry path OpenAI-compatible
Ngoài ra mình mở rộng
Nhờ vậy vòng retry tự phục hồi dù endpoint từ chối trường nào. 2. Unit tests cho logic mới Đã thêm test cho:
Đã xác nhận local: |
OpenAI and proxy summary requests now choose legacy max_tokens or reasoning max_completion_tokens based on the selected model, then retry when the API rejects temperature or token-limit fields. Constraint: Port only upstream PR vanloctech#101 runtime handling and tests; do not pull broader long-video AI Summary flow or unrelated provider changes. Rejected: Apply the new sampling map to every OpenAI-compatible provider | DeepSeek, Qwen, and LM Studio currently use their existing stable request shape and were outside PR vanloctech#101. Rejected: Add a new user setting for parameter mode | automatic correction covers the observed API mismatch with less UI surface. Confidence: high Scope-risk: narrow Directive: Keep OpenAI request compatibility in the provider layer so Summary callers do not branch on model families. Tested: bun run biome check --write . Tested: bun run tsc -b Tested: cargo check Tested: cargo test services::ai::providers::tests --lib Tested: cargo test --lib
Vấn đề
OpenAI đã tách Chat Completions thành hai thế hệ tham số sampling khác nhau:
temperature+max_tokens.max_completion_tokensvà không cho phép overridetemperature.Nếu gửi sai bộ tham số cho model, OpenAI sẽ trả về lỗi 400 và request thất bại. Việc cố gắng duy trì một danh sách đầy đủ tất cả model để biết dùng tham số nào là bất khả thi và dễ lỗi thời.
Giải pháp
PR này thêm cơ chế tự đoán rồi tự sửa để tính năng tóm tắt hoạt động ổn định trên cả hai thế hệ model, mà không cần bảo trì danh sách model dài dòng:
apply_openai_sampling_paramschọn bộ tham số "đoán tốt nhất" dựa trên một allowlist ngắn các dòng model cũ.post_openai_chatsẽ phân tích lỗi trả về — ưu tiên dùng trường có cấu trúcerror.paramthay vì đọc message dạng text — rồi sửa đúng trường bị lỗi ngay tại chỗ và thử lại.MAX_OPENAI_PARAM_ADJUSTMENTS. Hằng số này đếm số lần điều chỉnh (không phải số request); trường hợp xấu nhất làsố lần điều chỉnh + 1request. Mọi lần gửi đều đi qua cùng một nhánh trong vòng lặp để tổng số request luôn rõ ràng.Lý do thiết kế
Cách kiểm thử
cargo checkchạy sạch🤖 Được tạo với sự hỗ trợ của Claude Code