Ensure llm-cost-based-ratelimit precedes llm-cost in generated YAML#1402
Ensure llm-cost-based-ratelimit precedes llm-cost in generated YAML#1402
Conversation
WalkthroughGenerateLLM YAML now adds two new policy-name constants, emits empty Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
platform-api/src/internal/service/llm_deployment.go (1)
1440-1447: Edge case: multiple policies with the same name.The loop records only the last index for each policy name. If duplicate
llm-costpolicies exist (e.g., added via directappend()calls at lines 620, 646, 684, 711), only the last occurrence is considered for swapping.Example scenario:
- Input:
[llm-cost, llm-cost-based-ratelimit, llm-cost]costIdx = 2,rateLimitIdx = 1- Condition
costIdx < rateLimitIdxis false → no swap- Result: first
llm-costremains at index 0, beforellm-cost-based-ratelimitThis is likely rare since
addOrAppendPolicyPathprevents duplicates, but consider tracking the first occurrence ofllm-costinstead:♻️ Optional: track first llm-cost occurrence
func orderLLMPolicies(policies []api.LLMPolicy) []api.LLMPolicy { costIdx := -1 rateLimitIdx := -1 for i, p := range policies { switch p.Name { case llmCostPolicyName: - costIdx = i + if costIdx == -1 { + costIdx = i + } case llmCostBasedRateLimitPolicyName: rateLimitIdx = i } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-api/src/internal/service/llm_deployment.go` around lines 1440 - 1447, The loop over policies only records the last index for llm-cost and llm-cost-based-ratelimit, causing duplicate llm-cost entries to be misordered; update the scan that sets costIdx and rateLimitIdx in the block iterating over policies so it records the first occurrence (e.g., initialize costIdx/rateLimitIdx to -1 and only set costIdx = i or rateLimitIdx = i when the current value is still -1) for names llmCostPolicyName and llmCostBasedRateLimitPolicyName; this preserves the intended swap logic and complements existing deduplication in addOrAppendPolicyPath.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@platform-api/src/internal/service/llm_deployment.go`:
- Around line 1440-1447: The loop over policies only records the last index for
llm-cost and llm-cost-based-ratelimit, causing duplicate llm-cost entries to be
misordered; update the scan that sets costIdx and rateLimitIdx in the block
iterating over policies so it records the first occurrence (e.g., initialize
costIdx/rateLimitIdx to -1 and only set costIdx = i or rateLimitIdx = i when the
current value is still -1) for names llmCostPolicyName and
llmCostBasedRateLimitPolicyName; this preserves the intended swap logic and
complements existing deduplication in addOrAppendPolicyPath.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 54cd0631-e741-40b8-a9ac-4f68671e9f2e
📒 Files selected for processing (1)
platform-api/src/internal/service/llm_deployment.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
platform-api/src/internal/service/llm_test.go (1)
432-432: Add explicit regression tests forllm-cost-based-ratelimitordering.Line 432 and related assertions verify policy lookup/version, but this PR’s core guarantee is relative order (
llm-cost-based-ratelimitbeforellm-cost). Please add direct tests fororderLLMPolicies(or end-to-end provider/proxy policy slices) covering wrong order, correct order, only one present, and neither present.🧪 Suggested test addition
+func TestOrderLLMPolicies(t *testing.T) { + tests := []struct { + name string + input []api.LLMPolicy + expected []string + }{ + { + name: "swaps when llm-cost appears before llm-cost-based-ratelimit", + input: []api.LLMPolicy{ + {Name: "foo", Version: ""}, + {Name: "llm-cost", Version: ""}, + {Name: "llm-cost-based-ratelimit", Version: ""}, + {Name: "bar", Version: ""}, + }, + expected: []string{"foo", "llm-cost-based-ratelimit", "llm-cost", "bar"}, + }, + { + name: "keeps order when already correct", + input: []api.LLMPolicy{ + {Name: "llm-cost-based-ratelimit", Version: ""}, + {Name: "llm-cost", Version: ""}, + }, + expected: []string{"llm-cost-based-ratelimit", "llm-cost"}, + }, + { + name: "no change when only one exists", + input: []api.LLMPolicy{ + {Name: "llm-cost", Version: ""}, + }, + expected: []string{"llm-cost"}, + }, + { + name: "no change when neither exists", + input: []api.LLMPolicy{ + {Name: "advanced-ratelimit", Version: ""}, + }, + expected: []string{"advanced-ratelimit"}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got := orderLLMPolicies(tc.input) + if len(got) != len(tc.expected) { + t.Fatalf("expected %d policies, got %d", len(tc.expected), len(got)) + } + for i, name := range tc.expected { + if got[i].Name != name { + t.Fatalf("expected policy[%d]=%s, got=%s", i, name, got[i].Name) + } + } + }) + } +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-api/src/internal/service/llm_test.go` at line 432, Add explicit regression tests that verify the relative ordering guarantee that orderLLMPolicies enforces: write unit tests that call orderLLMPolicies (or build the provider/proxy policy slices and assert their final order) for four scenarios—input where "llm-cost" appears before "llm-cost-based-ratelimit" (wrong order) and assert the output reorders them, input already in the correct order and assert it remains unchanged, input containing only "llm-cost" and assert the single policy is preserved, and input containing neither policy and assert the slice is unchanged; use the existing helper findPolicy to assert presence/positions and reference the orderLLMPolicies function (and the policy names "llm-cost-based-ratelimit" and "llm-cost") when locating the code to modify.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@platform-api/src/internal/service/llm_test.go`:
- Line 432: Add explicit regression tests that verify the relative ordering
guarantee that orderLLMPolicies enforces: write unit tests that call
orderLLMPolicies (or build the provider/proxy policy slices and assert their
final order) for four scenarios—input where "llm-cost" appears before
"llm-cost-based-ratelimit" (wrong order) and assert the output reorders them,
input already in the correct order and assert it remains unchanged, input
containing only "llm-cost" and assert the single policy is preserved, and input
containing neither policy and assert the slice is unchanged; use the existing
helper findPolicy to assert presence/positions and reference the
orderLLMPolicies function (and the policy names "llm-cost-based-ratelimit" and
"llm-cost") when locating the code to modify.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e1632609-456f-472c-822f-75807d5677f8
📒 Files selected for processing (1)
platform-api/src/internal/service/llm_test.go
Purpose
Ensures correct policy execution ordering in generated deployment YAML for LLM providers and proxies. When both
llm-costandllm-cost-based-ratelimitpolicies are present,llm-costmust execute afterllm-cost-based-ratelimit— since cost tracking depends on rate limiting being evaluated first.Goals
Guarantee that
llm-cost-based-ratelimitalways appears beforellm-costin the generated deployment YAML, regardless of the order in which they were stored or submitted.Approach
Added an
orderLLMPolicieshelper inllm_deployment.gothat scans the assembled policy slice and swapsllm-costandllm-cost-based-ratelimitif they are out of order. The helper is called in bothgenerateLLMProviderDeploymentYAMLandgenerateLLMProxyDeploymentYAMLafter all policies are assembled, before marshalling to YAML. All other policies retain their relative positions.User stories
As an API developer, when I attach both
llm-costandllm-cost-based-ratelimitpolicies to an LLM provider or proxy, I want the gateway to enforce rate limiting before cost tracking so that cost is only recorded for requests that pass the rate limit.Documentation
N/A — internal policy ordering enforced at the platform layer; no user-facing behaviour change.
Automation tests
Security checks
Samples
N/A
Related PRs
N/A
Summary by CodeRabbit
New Features
Improvements