Skip to content

feat: Make Sonnet 4.6 free for one week in review mode#295

Open
kiloconnect[bot] wants to merge 1 commit intomainfrom
feat/sonnet-46-free-review-promo
Open

feat: Make Sonnet 4.6 free for one week in review mode#295
kiloconnect[bot] wants to merge 1 commit intomainfrom
feat/sonnet-46-free-review-promo

Conversation

@kiloconnect
Copy link
Contributor

@kiloconnect kiloconnect bot commented Feb 17, 2026

Summary

Make Claude Sonnet 4.6 (claude-sonnet-4-6-20250514) free for one week in Code Reviewer (review mode).

Promotion window: 2026-02-18 00:00 UTC → 2026-02-25 00:00 UTC (7 days)

Changes

Free model promotion (following PR #27 patterns)

  • Add sonnet_46_free_review_model in src/lib/providers/anthropic.ts with review_only: true flag
  • Extend KiloFreeModel type with review_only, promotion_start, and promotion_end fields
  • Register the model in kiloFreeModels array in src/lib/models.ts
  • Hide review-only models from the public model list (same pattern as slackbot_only)
  • Block access to review-only models outside of internal API (Code Reviewer) and outside the promotion window

Promotion-aware model selection

  • Add getDefaultCodeReviewModel() function that returns the promotional model during the active window
  • Update prepare-review-payload.ts to use the promotion-aware model selection
  • When no custom model is configured, code reviews automatically use Sonnet 4.6 during the promotion

Tracking & Reporting

  • Structured logging: Log when the promotional model is selected for a code review (includes reviewId, owner, promotion dates)
  • Admin endpoint: New getReviewPromotionStats tRPC query in the admin code reviews router that reports:
    • Total/completed/failed reviews using the promo model
    • Unique users and organizations
    • Daily breakdown with per-day user counts
    • Promotion active status
  • Helper functions: isReviewOnlyModel(), isReviewPromotionActive(), getActiveReviewPromotionModel()

Access control

  • Review-only models return "model does not exist" when accessed outside of Code Reviewer (internalApiUse)
  • Promotion automatically expires — after promotion_end, the model returns "does not exist"
  • No changes needed to billing: code reviews already use skipBalanceCheck: true

Files changed

  • src/lib/providers/kilo-free-model.ts — Extended type with review_only, promotion_start, promotion_end
  • src/lib/providers/anthropic.ts — Added sonnet_46_free_review_model definition
  • src/lib/models.ts — Registered model + added helper functions
  • src/lib/providers/openrouter/index.ts — Filter review-only models from public list
  • src/app/api/openrouter/[...path]/route.ts — Access control for review-only models
  • src/lib/code-reviews/core/constants.ts — Promotion-aware getDefaultCodeReviewModel()
  • src/lib/code-reviews/triggers/prepare-review-payload.ts — Use promotion model + tracking logs
  • src/routers/admin-code-reviews-router.tsgetReviewPromotionStats admin endpoint

Testing

  • TypeScript type checking passes
  • No snapshot changes (review-only models are hidden from public model list)

Built for alex.alecu by Kilo for Slack

- Add claude-sonnet-4-6-20250514 as a free promotional model for Code Reviewer
- Promotion window: 2026-02-18 to 2026-02-25 (7 days)
- Model is hidden from public model list (review_only flag)
- Only accessible through internal API (Code Reviewer) during promotion
- Add promotion tracking admin endpoint (getReviewPromotionStats)
- Add structured logging for promotion model usage
*/
export function getDefaultCodeReviewModel(): string {
const promoModel = getActiveReviewPromotionModel();
return promoModel?.internal_id ?? BASE_CODE_REVIEW_MODEL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: getDefaultCodeReviewModel() returns internal_id instead of public_id, which means the promotional model will not be recognized as free by the API route.

The API route at src/app/api/openrouter/[...path]/route.ts uses the model ID to check isFreeModel(), isReviewOnlyModel(), and isRateLimitedModel() — all of which match against public_id. The applyProviderSpecificLogic() function in src/lib/providers/index.ts:243 then rewrites requestToMutate.model from public_idinternal_id before sending to OpenRouter.

By returning internal_id here, the model bypasses the review-only access gate and isn't recognized as free, so users will be charged credits for what's supposed to be a free promotional model.

For reference, the Slack integration correctly uses public_id (opus_46_free_slackbot_model.public_id) in src/lib/integrations/slack-service.ts:20.

Suggested change
return promoModel?.internal_id ?? BASE_CODE_REVIEW_MODEL;
return promoModel?.public_id ?? BASE_CODE_REVIEW_MODEL;

and(
gte(cloud_agent_code_reviews.created_at, promoStart),
lt(cloud_agent_code_reviews.created_at, promoEnd),
eq(cliSessions.last_model, promoModelId)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: This query matches last_model against promoModel.internal_id. If the critical bug in getDefaultCodeReviewModel() is fixed to return public_id instead of internal_id, then last_model in the DB will store the public_id (e.g. anthropic/claude-sonnet-4-6-20250514:review), and this query will need to match on public_id as well.

Consider using promoModel.public_id here to stay consistent with the fix, or add a comment clarifying which ID format last_model stores.

@kiloconnect
Copy link
Contributor Author

kiloconnect bot commented Feb 17, 2026

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
src/lib/code-reviews/core/constants.ts 25 getDefaultCodeReviewModel() returns internal_id instead of public_id — the promotional model won't be recognized as free by the API route, causing users to be charged credits

WARNING

File Line Issue
src/routers/admin-code-reviews-router.ts 399 Admin stats query matches last_model against internal_id; if the CRITICAL fix switches to public_id, this query will also need updating
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
src/lib/models.ts 56 isRateLimitedModel() excludes slackbot_only but not review_only models — the review-only promo model will be subject to the standard free-model IP rate limiter, which may not be desired since it's accessed via internalApiUse (code reviewer)
Files Reviewed (7 files)
  • src/app/api/openrouter/[...path]/route.ts - 0 issues
  • src/lib/code-reviews/core/constants.ts - 1 issue
  • src/lib/code-reviews/triggers/prepare-review-payload.ts - 0 issues
  • src/lib/models.ts - 0 issues
  • src/lib/providers/anthropic.ts - 0 issues
  • src/lib/providers/kilo-free-model.ts - 0 issues
  • src/lib/providers/openrouter/index.ts - 0 issues
  • src/routers/admin-code-reviews-router.ts - 1 issue

Fix these issues in Kilo Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants