Conversation
- Align check-types-split with packages/db, packages/lib, and UI components; exclude Storybook stories from the UI chunk. - Add check-types:tests to CI; add root scripts for UI, agent-server, and gateway typechecks. - packages/ui: path aliases for @/lib, @/db, @/app, @/packages/ui; styled-jsx attrs for <style jsx>. - packages/lib: JWKS uses jose KeyLike; runtime-factory imports plugin-sql default with typed adapter factory. - gateway-discord: explicit discord.js handler types, connectBot characterId, sendTyping guard, listener map cast. - services/agent-server: requireInternalAuth accepts Elysia string/number status. - Tests: mocks, RequestInit/fetch preconnect, UUID casts, toMatchObject, financial addCredits, Playwright APIRequestContext, and related fixes. - New anthropic-thinking provider helper and unit test. Note: services/operator (Pepr) is not part of the main workspace typecheck. Made-with: Cursor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR adds Anthropic “extended thinking” (CoT) budget support with per-agent settings and env fallbacks/caps, provider-options merge helpers, widespread integration of those helpers into AI request calls, TypeScript typing and test infrastructure improvements, Milady test rework, a rate-limit preset change, and documentation updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Route as MCP/A2A Route
participant Resolver as CharacterResolver
participant Anthropic as AnthropicThinking
participant LLM as LLMProvider
Client->>Route: POST /api/agents/{id}/mcp (chat)
Route->>Resolver: resolve character
Resolver-->>Route: character (includes settings)
Route->>Anthropic: parseThinkingBudgetFromCharacterSettings(settings)
Anthropic-->>Route: agentThinkingBudget?
Route->>Anthropic: mergeAnthropicCotProviderOptions(model, env, budget)
Anthropic-->>Route: providerOptions fragment
Route->>LLM: streamText({ model, prompt, ...providerOptions })
LLM-->>Route: stream response
Route-->>Client: stream completion
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
🚥 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 docstrings
🧪 Generate unit tests (beta)
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 |
|
Code Review This PR adds Anthropic extended thinking (ANTHROPIC_COT_BUDGET) support across all AI routes, fixes TypeScript type errors in tests/packages, adds a check-types:tests CI step, and hardens the Discord gateway with explicit handler types. The implementation is generally solid with good test coverage for the new helper. Issues:
app-promotion-assets.ts, app-promotion.ts, twitter-automation/app-automation.ts, and seo.ts pass explicit temperature alongside mergeProviderOptions. When ANTHROPIC_COT_BUDGET is set, @ai-sdk/anthropic silently strips temperature/topP/topK (noted in the v1/chat completions comment). Callers relying on temperature 0.7/0.8 will silently get default sampling - an invisible behavior change. Consider logging a warning at startup when both are configured.
The function deep-merges only gateway, anthropic, and google. Any other provider key present in both a and b (e.g. openai, azure) is overwritten by the shallow spread without merging. Worth a comment flagging this limitation.
Removing the isDevelopment override drops STANDARD from 10,000 to 60 req/min in local dev. Developers running hot-reload tests or UI workflows will now hit production limits backed only by in-memory storage. Consider keeping separate dev limits or documenting the change prominently.
The default import is immediately cast to a manually-written signature. If the upstream @elizaos/plugin-sql signature changes, this cast will silently pass wrong types. Worth a comment explaining the workaround and a TODO to remove it when upstream fixes the type export.
In x402-topup.test.ts, afterAll accesses referralsServiceForTest etc. with definite-assignment assertions and no null guards. If beforeAll throws before all three are assigned, afterAll will also throw and may swallow the original failure. The previous null-guard pattern was safer. Positives:
|
Rename milady billing route test to z-milady-billing-route for script ordering, use queue-backed db mocks re-registered in beforeEach, and add mockMiladyPricingMinimumDepositForRouteTests so route tests do not replace MILADY_PRICING with only MINIMUM_DEPOSIT (which broke billing thresholds in-process). Update package.json bulk/special unit paths accordingly. Made-with: Cursor
Extend anthropic-thinking handling, add cloud-provider-options, update provider types and index exports, and thread safe model params through v1 chat, completions, messages, responses, generate-image, MCP/A2A, and internal services. Expand anthropic-thinking unit tests. Made-with: Cursor
Add engineering docs (unit-testing-milady-mocks, anthropic-cot-budget), root CHANGELOG.md, README links and accurate test script table, ROADMAP and site changelog entries. Expand JSDoc and .env.example with rationale for ANTHROPIC_COT_BUDGET and partial MILADY_PRICING mock pitfalls. Made-with: Cursor
|
Code Review - PR 417 This PR is a broad type-fix/quality pass with one new functional feature (Anthropic extended thinking via ANTHROPIC_COT_BUDGET). The changes are generally clean. A few things worth discussing: ISSUES
File: packages/lib/middleware/rate-limit.ts Removing the isDevelopment branch means local dev now hits the same strict limits as production (60/min STANDARD, 10/min STRICT, 5 per 5-min CRITICAL) backed only by in-memory storage. Developers iterating locally will now hit 429s immediately. The old 10000 req/window dev ceiling existed precisely to avoid this. The log message change says "same numeric limits as production" explicitly. Was this intentional? If so, it should be called out in the PR description. If not, the isDevelopment guard should be restored.
File: packages/tests/integration/x402-topup.test.ts Using ! on the three service vars silences TS but means if beforeAll throws partway through, afterAll will crash accessing properties on uninitialized vars. The original null-guards were load-bearing. Consider keeping them or initializing with no-op stubs.
File: packages/lib/providers/anthropic-thinking.ts The merge is one level deep for anthropic/google/gateway. For the thinking key specifically: if base has { thinking: { type: "disabled" } } and COT helper adds { thinking: { type: "enabled", budgetTokens: N } }, the second replaces the first entirely. This is the desired behavior, but a short comment would prevent future contributors from trying to fix it.
File: app/api/v1/generate-image/route.ts The else branch in isOpenAIModel ? mergeAnthropicCot : mergeGoogleImage covers everything that is not OpenAI. Future Anthropic image models would fall into the Google path and pick up responseModalities unnecessarily. Low risk now, worth noting when new providers are added.
File: packages/lib/eliza/runtime-factory.ts Casting the default import manually bypasses TS module resolution. A comment explaining the upstream typing gap would help future audits. POSITIVES
Overall this is a solid type cleanup pass. The rate-limit change is the most impactful behavioral difference and should be confirmed as intentional before merge. |
|
PR Review: fix(types): test project, split check-types, UI package, gateways Overall this is well-structured work with clear documentation of design decisions. A few items worth addressing before merge. Bugs / Correctness x402-topup.test.ts: afterAll null safety regression - The refactor replaced null-guarded service patches with definite assignment (!) but the afterAll cleanup now runs unconditionally. If beforeAll throws before the service variables are assigned, afterAll will throw on property access, masking the root failure and potentially breaking test teardown for other suites. Restore optional chaining or null guards in afterAll even if the variable declarations no longer need the union type. Behaviour Change Worth Calling Out Rate limit presets: dev-mode unlimited -> production limits for local development - packages/lib/middleware/rate-limit.ts removes the isDevelopment pattern and always uses production-level limits (STANDARD: 60/min, STRICT: 10/min, etc.). The only difference now is in-memory vs Redis backing. This will hit local developers on standard routes once they exceed 60 req/min. If intentional, worth a note in dev setup docs. Minor Issues
What is Good
Summary: The null-safety regression in x402-topup.test.ts afterAll is the only real bug. The rate-limit behaviour change is worth explicit acknowledgement. Everything else is minor or informational. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Spread order lets
optionsoverride deploy-wide thinking config- Swapped the spread order so mergeAnthropicCotProviderOptions comes after options, ensuring deploy-wide ANTHROPIC_COT_BUDGET cannot be overridden by caller-supplied options.
Or push these changes by commenting:
@cursor push 99924fb2eb
Preview (99924fb2eb)
diff --git a/packages/lib/api/a2a/skills.ts b/packages/lib/api/a2a/skills.ts
--- a/packages/lib/api/a2a/skills.ts
+++ b/packages/lib/api/a2a/skills.ts
@@ -91,8 +91,8 @@
role: m.role as "user" | "assistant" | "system",
content: m.content,
})),
+ ...options,
...mergeAnthropicCotProviderOptions(model),
- ...options,
});
let fullText = "";This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.
Read user_characters.settings.anthropicThinkingBudgetTokens for agent chat; add ANTHROPIC_COT_BUDGET_MAX cap and resolution helpers. Wire MCP and A2A routes; extend tests, env-validator, and .env.example. Update CHANGELOG, site changelog, README, ROADMAP, anthropic-cot-budget doc, and route/module comments with WHYs (owner-controlled settings vs untrusted request params). Made-with: Cursor
…ridden Move mergeAnthropicCotProviderOptions spread after options spread in executeSkillChatCompletion to ensure the deploy-wide ANTHROPIC_COT_BUDGET configuration takes precedence over caller-supplied options. This aligns with all other call sites in the codebase which consistently place mergeAnthropicCotProviderOptions last to enforce operator-controlled thinking budgets.
…ridden Move mergeAnthropicCotProviderOptions spread after options spread in executeSkillChatCompletion to ensure the deploy-wide ANTHROPIC_COT_BUDGET configuration takes precedence over caller-supplied options. This aligns with all other call sites in the codebase which consistently place mergeAnthropicCotProviderOptions last to enforce operator-controlled thinking budgets. Applied via @cursor push command
There was a problem hiding this comment.
Pull request overview
Aligns repo typechecking and test typings across the workspace, introduces deploy-scoped Anthropic extended-thinking configuration helpers, and tightens/clarifies several gateway + test mocks/casts to reduce order-dependent failures.
Changes:
- Split/expand typecheck coverage (tests project typecheck in CI, new per-package typecheck scripts, updated tsconfigs/paths).
- Add Anthropic COT budget env + providerOptions merge helpers and thread them through gateway-backed routes/services.
- Stabilize/retarget numerous unit/integration tests (mocks, env handling, casting, and fixture shapes), including Milady pricing mock helper + renamed cron test.
Reviewed changes
Copilot reviewed 100 out of 101 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.test.json | Adds UI package path aliases and refines include/exclude for test typecheck. |
| services/agent-server/src/routes.ts | Broadens set.status typing for Elysia compatibility. |
| services/agent-server/package.json | Adds typecheck script. |
| packages/ui/tsconfig.json | Adds cross-workspace path aliases and excludes Storybook stories from UI typecheck. |
| packages/ui/src/styled-jsx.d.ts | Augments React style attributes for styled-jsx. |
| packages/tests/unit/z-milady-billing-route.test.ts | Reworks Milady billing cron test mocking to be order-stable across the suite. |
| packages/tests/unit/x402/facilitator-service.test.ts | Adjusts casts for stricter typing. |
| packages/tests/unit/wallet-auth.test.ts | Fixes mock typing/resolved values. |
| packages/tests/unit/waifu-bridge.test.ts | Uses a typed mutable env view for NODE_ENV writes. |
| packages/tests/unit/v1-milaidy-provision-route.test.ts | Uses shared Milady pricing mock helper. |
| packages/tests/unit/token-agent-linkage.test.ts | Refactors validation test into scenario loop with strict checks. |
| packages/tests/unit/security-validations.test.ts | Avoids {} prototype typing issues in pollution assertions. |
| packages/tests/unit/referrals-service.test.ts | Uses toMatchObject to reduce brittle equality. |
| packages/tests/unit/provisioning-jobs.test.ts | Fixes Vitest mock restore typing and fetch assignment typing. |
| packages/tests/unit/provisioning-jobs-followups.test.ts | Uses toMatchObject for partial comparisons. |
| packages/tests/unit/privy-sync.test.ts | Uses toMatchObject for hydrated user comparisons. |
| packages/tests/unit/pr385-round5-fixes.test.ts | Aligns fake service signature with optional id param. |
| packages/tests/unit/performance-optimizations.test.ts | Adds typed helpers to avoid repeated unsafe access to provider snapshots. |
| packages/tests/unit/oauth/token-cache.test.ts | Rewrites date normalization branch for clearer typing. |
| packages/tests/unit/oauth/provider-registry.test.ts | Adjusts optional chaining/non-null assertions in provider routes. |
| packages/tests/unit/oauth/oauth-service.test.ts | Tightens typings for provider routes/platform loops/status handling. |
| packages/tests/unit/oauth/errors.test.ts | Stabilizes enum value typing for expectations. |
| packages/tests/unit/milaidy-sandbox-bridge-security.test.ts | Fixes fetch typing and backup fixture shape updates. |
| packages/tests/unit/milaidy-pairing-token-route.test.ts | Stabilizes env setup/teardown for base domain; removes module mock. |
| packages/tests/unit/milaidy-agent-routes-followups.test.ts | Uses shared Milady pricing mock helper. |
| packages/tests/unit/milady-sandbox-service.test.ts | Introduces typed sandbox provider helper and updates sandbox fixture fields. |
| packages/tests/unit/milady-create-routes.test.ts | Uses shared Milady pricing mock helper. |
| packages/tests/unit/mcp-twitter-tools.test.ts | Adds typed OAuth fixtures + handler result typing; normalizes token result shape. |
| packages/tests/unit/mcp-proxy-affiliate-pricing.test.ts | Fixes fetch typing cast. |
| packages/tests/unit/mcp-lib.test.ts | Tightens auth context typing and assertions. |
| packages/tests/unit/mcp-hubspot-tools.test.ts | Adds typed OAuth fixtures/token helper and fixes fetch typing casts. |
| packages/tests/unit/mcp-google-tools.test.ts | Adds typed OAuth fixtures/handler result typing; fixes fetch typing casts. |
| packages/tests/unit/internal-jwt-auth.test.ts | Uses typed env writes for NODE_ENV. |
| packages/tests/unit/field-encryption.test.ts | Adds typed rows and mock signatures to match repository interfaces. |
| packages/tests/unit/evm-rpc-proxy-route.test.ts | Fixes fetch typing casts. |
| packages/tests/unit/engagement-metrics/compute-metrics-cron.test.ts | Aligns mock signatures with implementation params. |
| packages/tests/unit/engagement-metrics/admin-metrics-api.test.ts | Aligns mock signature with implementation params. |
| packages/tests/unit/eliza-app/whatsapp-auth.test.ts | Casts string literals for stricter typing compatibility. |
| packages/tests/unit/eliza-app/telegram-ux-helpers.test.ts | Fixes fetch typing cast. |
| packages/tests/unit/docker-ssh-cloud-deploy.test.ts | Adjusts logger redact import strategy. |
| packages/tests/unit/database-url.test.ts | Uses typed env record for safe env mutation + asserts. |
| packages/tests/unit/compat-envelope.test.ts | Updates Milady sandbox fixture with new billing fields. |
| packages/tests/unit/api/route-test-helpers.ts | Improves routeParams typing and fixes File BlobPart typing. |
| packages/tests/unit/api/openapi-catalog.test.ts | Refactors test structure and simplifies OPTIONS invocation. |
| packages/tests/unit/anthropic-thinking.test.ts | Adds unit tests for new Anthropic thinking env + merge helpers. |
| packages/tests/unit/admin-service-pricing-route.test.ts | Tightens auth mock typing and request construction. |
| packages/tests/runtime/performance.test.ts | Fixes UUID typing casts for agentId. |
| packages/tests/runtime/mcp-assistant-trending.test.ts | Updates debug rendering mode and failure handling structure. |
| packages/tests/runtime/integration/runtime-factory/oauth-cache-invalidation.test.ts | Removes any for MCP settings lookup with typed cast. |
| packages/tests/runtime/integration/performance/runtime-creation.test.ts | Fixes UUID typing casts for agentId. |
| packages/tests/runtime/integration/message-handler/mcp-tools.test.ts | Updates debug rendering mode and failure handling structure. |
| packages/tests/playwright/fixtures/auth.fixture.ts | Uses APIRequestContext instead of inferred request type and removes any call. |
| packages/tests/load-env.ts | Uses typed env write for NODE_ENV. |
| packages/tests/integration/x402-topup.test.ts | Refactors service patch typing and restores methods after suite. |
| packages/tests/integration/webhooks-e2e.test.ts | Wraps fetch to auto-sign webhooks and preserves fetch.preconnect. |
| packages/tests/integration/unified-oauth-api.test.ts | Tightens it wrapper signature. |
| packages/tests/integration/services/users.service.test.ts | Adds fixture guard and tightens nullable handling. |
| packages/tests/integration/services/users-join-regression.test.ts | Adds runtime guard for relation shape. |
| packages/tests/integration/services/organizations.service.test.ts | Simplifies membership assertion. |
| packages/tests/integration/server-wallets.test.ts | Updates mocked returning rows and loosens assertion to toMatchObject. |
| packages/tests/integration/mcp-registry.test.ts | Tightens test wrapper signature. |
| packages/tests/integration/financial/credits-budget-flow.test.ts | Removes source field from addCredits call in test. |
| packages/tests/integration/financial/concurrent-operations.test.ts | Removes source field from addCredits call in test. |
| packages/tests/helpers/mock-milady-pricing-for-route-tests.ts | Adds helper to safely override Milady MINIMUM_DEPOSIT without clobbering constants. |
| packages/tests/helpers/index.ts | Re-exports the new Milady pricing mock helper. |
| packages/tests/fixtures/mcp-test-character.ts | Updates simpleTestCharacter id to UUID-like value. |
| packages/tests/e2e/setup-server.ts | Wraps fetch to ensure server availability and preserves fetch.preconnect. |
| packages/services/gateway-discord/src/gateway-manager.ts | Tightens discord.js handler typing, adds characterId routing, guards sendTyping, and listener map casts. |
| packages/scripts/check-types-split.ts | Updates typecheck chunk selection and excludes stories from temp configs. |
| packages/lib/services/twitter-automation/app-automation.ts | Threads new Anthropic COT merge helper into gateway generateText calls. |
| packages/lib/services/seo.ts | Threads new Anthropic COT merge helper into SEO Claude calls. |
| packages/lib/services/app-promotion.ts | Threads new Anthropic COT merge helper into promo copy generation. |
| packages/lib/services/app-promotion-assets.ts | Uses merge helpers for google image modalities + Anthropic COT for copy generation. |
| packages/lib/services/app-builder-ai-sdk.ts | Threads new Anthropic COT merge helper into streamText calls. |
| packages/lib/providers/types.ts | Broadens providerOptions typing to shared JSON-serializable merged options. |
| packages/lib/providers/index.ts | Exports new anthropic-thinking helpers. |
| packages/lib/providers/cloud-provider-options.ts | Adds shared merged providerOptions type alias. |
| packages/lib/providers/anthropic-thinking.ts | Adds env parsing + merge helpers for Anthropic extended thinking. |
| packages/lib/middleware/rate-limit.ts | Makes preset numeric limits consistent across dev/prod; clarifies logging/docs. |
| packages/lib/eliza/runtime-factory.ts | Changes plugin-sql adapter import to default + casted factory signature. |
| packages/lib/config/env-validator.ts | Adds validation rule for ANTHROPIC_COT_BUDGET. |
| packages/lib/auth/jwks.ts | Updates jose KeyLike typings for cached keys. |
| packages/lib/api/a2a/skills.ts | Threads merge helpers into skill chat + image generation paths. |
| packages/content/changelog.mdx | Adds Mar 27, 2026 entry for Anthropic COT + Milady testing fixes. |
| package.json | Adds per-package typecheck scripts and updates unit test split scripts for renamed file. |
| docs/unit-testing-milady-mocks.md | Documents Bun mock.module pitfalls and Milady pricing mock strategy. |
| docs/anthropic-cot-budget.md | Documents ANTHROPIC_COT_BUDGET behavior and providerOptions merge rationale. |
| docs/ROADMAP.md | Records completed items for COT budget + Milady test stabilization. |
| app/api/v1/responses/route.ts | Uses gateway+Anthropic merge helper for providerOptions injection. |
| app/api/v1/messages/route.ts | Threads merge helper into non-stream and stream AI SDK calls. |
| app/api/v1/generate-image/route.ts | Uses merge helpers for google image modalities and optional Anthropic COT. |
| app/api/v1/chat/route.ts | Threads merge helper into chat streaming call. |
| app/api/v1/chat/completions/route.ts | Threads merge helper into streaming and non-streaming calls. |
| app/api/v1/admin/service-pricing/tests/route.integration.test.ts | Standardizes NextRequest construction via URL base. |
| app/api/mcp/tools/generation.ts | Threads merge helpers into MCP generation (text + image) tools. |
| app/api/agents/[id]/mcp/route.ts | Threads merge helper into tool-call streaming. |
| app/api/agents/[id]/a2a/route.ts | Threads merge helper into A2A streaming. |
| README.md | Adds links to new “WHY” engineering docs and clarifies bun run test staging. |
| CHANGELOG.md | Adds Keep-a-Changelog style engineering changelog entries for these changes. |
| .github/workflows/tests.yml | Adds check-types:tests to CI. |
| .env.example | Documents optional ANTHROPIC_COT_BUDGET env var. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const createDatabaseAdapter = createDatabaseAdapterDefault as ( | ||
| config: { postgresUrl: string }, | ||
| agentId: UUID, | ||
| ) => IDatabaseAdapter; |
There was a problem hiding this comment.
@elizaos/plugin-sql/node is being imported as a default export and then cast to a callable adapter factory. This bypasses type safety and can hide a runtime mismatch if the default export isn’t actually callable (or if its signature changes). Consider updating the local declare module "@elizaos/plugin-sql/node" typings to correctly model the default export (e.g., a callable function with any attached properties like schema) and then import it with the accurate type, rather than casting unknown here.
| const createDatabaseAdapter = createDatabaseAdapterDefault as ( | |
| config: { postgresUrl: string }, | |
| agentId: UUID, | |
| ) => IDatabaseAdapter; | |
| type CreateDatabaseAdapterFn = ( | |
| config: { postgresUrl: string }, | |
| agentId: UUID, | |
| ) => IDatabaseAdapter; | |
| function ensureCreateDatabaseAdapter(fn: unknown): CreateDatabaseAdapterFn { | |
| if (typeof fn !== "function") { | |
| throw new TypeError( | |
| 'Default export from "@elizaos/plugin-sql/node" is not a callable database adapter factory', | |
| ); | |
| } | |
| return fn as CreateDatabaseAdapterFn; | |
| } | |
| const createDatabaseAdapter = ensureCreateDatabaseAdapter( | |
| createDatabaseAdapterDefault, | |
| ); |
There was a problem hiding this comment.
Dismissed: Comment targets line 21 but identifier schema not found in file — code may have been removed or renamed
There was a problem hiding this comment.
Fixed in 6455e14.
| ANTHROPIC_COT_BUDGET: { | ||
| required: false, | ||
| description: | ||
| "Default Anthropic extended-thinking token budget when a character omits settings.anthropicThinkingBudgetTokens. Unset or 0 disables unless the character sets a positive budget", | ||
| validate: (value: string) => { | ||
| const trimmed = value.trim(); | ||
| if (trimmed === "") { | ||
| return false; | ||
| } | ||
| if (!/^\d+$/.test(trimmed)) { | ||
| return false; | ||
| } | ||
| const n = Number.parseInt(trimmed, 10); | ||
| return n >= 0 && n <= Number.MAX_SAFE_INTEGER; | ||
| }, | ||
| errorMessage: | ||
| "Must be a non-negative integer string (0 = off; when enabling, Anthropic often expects at least ~1024)", | ||
| }, |
There was a problem hiding this comment.
ANTHROPIC_COT_BUDGET parsing in anthropic-thinking.ts throws on invalid non-empty values, but the env validator treats invalid optional values as warnings (startup continues). That means a mis-set budget can turn into request-time exceptions across any route that spreads mergeAnthropicCotProviderOptions(...). Either make invalid values for this variable a hard validation error (fail fast at startup), or change the parsing/merge path to degrade safely (e.g., log once and treat as "off").
There was a problem hiding this comment.
Fixed in fe10e6b.
There was a problem hiding this comment.
Fixed in 18bfb11.
| // Importing via the file-system path with a cache-buster query param | ||
| // guarantees we always get the real implementation regardless of mocks. | ||
| import { redact } from "../../lib/utils/logger.ts?_real"; | ||
| import { redact } from "../../lib/utils/logger"; |
There was a problem hiding this comment.
The comment above says this import uses a cache-buster query param to avoid mock.module("@/lib/utils/logger") poisoning, but the import no longer includes any cache-buster. If other unit files mock the logger module earlier in the same Bun process, this test may again receive the mocked module and lose the real redact export. Either restore the cache-buster (or another unmocked import strategy) or update the comment and ensure redact is always available in the mocked logger module(s).
There was a problem hiding this comment.
Fixed in fe10e6b.
There was a problem hiding this comment.
Dismissed: Line 16 still includes the cache-buster query param ?v=docker-ssh-test as required
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Iteration 1 prr-fix:prrc_kwdop6btdm6yyjtn
Iteration 1 prr-fix:prrc_kwdop6btdm6yyjt7
Changes: - rate-limit.ts: PR Review: fix(types): test project, split check-types, UI package, gateways ...
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Code Review — PR #417: Anthropic CoT ControlsOverall the approach is sound: centralizing thinking-budget resolution in a single helper, keeping budgets off request bodies, and wiring env defaults through a type-safe merge layer. A few issues worth addressing before merge. 🐛 Potential Bugs1. Temperature conflict in Anthropic's API rejects requests with // seo.ts
const { text } = await generateText({
model: gateway.languageModel(modelId),
temperature: 0.3, // ← will cause API error when ANTHROPIC_COT_BUDGET is set
...mergeAnthropicCotProviderOptions(modelId),
...// app-promotion.ts
await generateText({
model: gateway.languageModel(promoModel),
temperature: 0.7, // ← same risk
...mergeAnthropicCotProviderOptions(promoModel),If the AI SDK Gateway path does not strip 2. In const cotOpts = isOpenAIModel
? mergeAnthropicCotProviderOptions(imageModel) // returns {} for OpenAI — no-op
: mergeGoogleImageModalitiesWithAnthropicCot(imageModel); // applies google.responseModalities to ANY non-OpenAI modelBefore this PR,
|
app/api/agents/[id]/a2a/route.ts
Outdated
| process.env, | ||
| agentThinkingBudget ?? undefined, | ||
| ); | ||
| const baseCost = await estimateRequestCost(model, fullMessages, effectiveThinkingBudget); |
There was a problem hiding this comment.
A2A route cost estimation inconsistent with MCP route
Medium Severity
The A2A route passes effectiveThinkingBudget (type number | null) directly to estimateRequestCost as maxOutputTokens. When the thinking budget is e.g. 5000, estimateRequestCost uses 5000 as the total output token estimate, replacing the default 500 base output tokens. The MCP route correctly adds the thinking budget on top of base output tokens (500 + effectiveThinkingBudget). This means the A2A route underestimates credit reservation when thinking is enabled. Additionally, when resolveAnthropicThinkingBudgetTokens returns null, it's passed as null to a parameter typed number | undefined.
Additional Locations (1)
There was a problem hiding this comment.
Fixed in 67138cc.
app/api/agents/[id]/a2a/route.ts
Outdated
| // Note: estimateRequestCost adds thinking tokens to output estimate when budget is provided | ||
| // Calculate estimated costs, including potential thinking budget | ||
| // Use resolveAnthropicThinkingBudgetTokens to get effective budget (same as MCP route) | ||
| // This ensures credit reservation accounts for thinking tokens |
There was a problem hiding this comment.
Duplicate comment block in A2A route handler
Low Severity
Lines 297-301 contain a duplicated comment — // Calculate estimated costs, including potential thinking budget appears twice in succession (once at line 297 with a // Note: continuation, and again at line 299 with different continuation text). This looks like an accidental merge artifact from editing the same block twice.
There was a problem hiding this comment.
Fixed in 67138cc.
Iteration 7 prr-fix:prrc_kwdop6btdm6y8iwm prr-fix:prrc_kwdop6btdm6y8iwq
PR Review: feat: Anthropic CoT controlsOverall this is well-structured work — the security rationale (budget lives on the character record, not request bodies) is sound, the deep-merge helpers are properly designed, and env validation with Bugs / Correctness1. Duplicate comment block in There are two nearly-identical comment blocks left by accident around the cost estimation section: // Calculate estimated costs, including potential thinking budget
// Note: estimateRequestCost adds thinking tokens to output estimate when budget is provided
// Calculate estimated costs, including potential thinking budget ← duplicate
// Use resolveAnthropicThinkingBudgetTokens to get effective budget (same as MCP route)One should be removed. 2. Inconsistent output-token estimation between MCP and A2A routes
These do different things. If 3. const estimatedOutputTokens = model.includes("claude") && effectiveThinkingBudget > 0Every other check in this file uses 4.
5. No minimum budget enforcement in Anthropic requires Design / Quality6. Root-level The routes import from 7. The change removes 8.
Missing Test Coverage9. The root Minor
|
Iteration 1 prr-fix:ic-4143706884-3 prr-fix:ic-4144015244-5
Iteration 1 prr-fix:ic-4144023511-5
Iteration 1 prr-fix:ic-4143990242-4
Code Review — PR #417: Anthropic CoT ControlsOverall the architecture is sound: character settings > env default > disabled, with proper security rationale (untrusted clients cannot set thinking budgets). The merge helpers are a good abstraction. A few issues worth addressing before merge: Bugs / Correctness1. Root-level
The root-level test ( 2. In const parsed = Number.parseInt(multiplier, 10);But if (!/^\d+(\.\d+)?$/.test(trimmed)) {Setting 3. Both route handlers add: settings: Record<string, unknown>;to their local character type. If any existing settings: Record<string, unknown> | null;4. Thinking budget cost estimate inconsistency between MCP and A2A routes MCP route: const effectiveThinkingBudget = resolveAnthropicThinkingBudgetTokens(...) ?? 0;
const estimatedOutputTokens = model.includes("claude") && effectiveThinkingBudget > 0
? baseOutputTokens + effectiveThinkingBudget
: baseOutputTokens;A2A route: const maxOutputTokens = effectiveThinkingBudget != null ? 500 + effectiveThinkingBudget : undefined;
const baseCost = await estimateRequestCost(model, fullMessages, maxOutputTokens);The logic is different: MCP checks Design / Clarity5. The validator accepts 6. The JSDoc notes that non- 7. The A2A skills route applies Minor8. 9. Test file naming — What's Good
The main blocking items are #1 (root-level duplicate with wrong model list), #2 (parseInt/float mismatch), and #3 (nullable settings type). |
Iteration 4 prr-fix:ic-4144080947-4
Eliza Cloud V2Stack
Commandsbun install # Install dependencies
bun run dev # Start dev server
bun run build # Production build
bun run db:migrate # Apply database migrations
bun run db:generate # Generate migration from schema
bun run db:studio # Open Drizzle StudioDatabase MigrationsNever use Schema Change Workflow
Custom Migrationsnpx drizzle-kit generate --custom --name=descriptive_nameRules
Type Checking
bun run check-types 2>&1 | grep -E "(your-file\.ts|your-other-file\.ts)"If the grep returns empty, your changes are clean. Project Structure |
Eliza CloudA comprehensive AI agent development platform built with Next.js 15, featuring multi-model AI generation (text, image, video), full elizaOS runtime integration, enterprise authentication, credit-based billing, and production-ready cloud infrastructure. 📋 Table of Contents
🎯 OverviewEliza Cloud V2 is a full-stack AI-as-a-Service platform that combines:
✨ Key Features🤖 AI Generation Studio
🧠 elizaOS Runtime Integration
💳 SaaS Platform Features
📊 Management & Analytics
🔐 Security & Infrastructure
🏗 ArchitectureDirectory StructureRequest Flowgraph TD
A[Client Request] --> B[Next.js Middleware]
B --> C{Auth Required?}
C -->|Yes| D[Privy Auth]
C -->|No| E[Route Handler]
D -->|Authenticated| E
D -->|Unauthenticated| F[Redirect to Login]
E --> G{Request Type}
G -->|AI Chat| H[AI SDK Gateway]
G -->|Image/Video| I[Gemini/Fal.ai]
G -->|Data| J[Drizzle ORM]
G -->|Container| K[AWS ECS/ECR]
G -->|elizaOS| L[AgentRuntime]
H --> M[Response]
I --> M
J --> N[PostgreSQL]
K --> M
L --> N
N --> M
Database ArchitectureThe platform uses a single database with integrated schemas:
🛠 Tech StackCore Framework
Database & ORM
Authentication & Billing
AI & Machine Learning
Storage & Infrastructure
Styling & UI
Development Tools
📦 PrerequisitesRequired Software
Required Services
Optional Services
🚀 Quick Start1. Clone and Installcd cloud
bun install2. Environment SetupCopy the example environment file: cp .env.example .env.localEdit For local caching, the repo expects the Docker Redis container on REDIS_URL=redis://localhost:6379
KV_URL=redis://localhost:6379Leave Minimum required variables: # Database
DATABASE_URL=postgresql://user:password@host:5432/database?sslmode=require
# Privy Authentication
NEXT_PUBLIC_PRIVY_APP_ID=your_privy_app_id_here
PRIVY_APP_SECRET=your_privy_app_secret_here
PRIVY_WEBHOOK_SECRET=replace_with_strong_random_secret
# AI (at least one)
OPENAI_API_KEY=sk-your_openai_key
# OR
AI_GATEWAY_API_KEY=your_gateway_key
# Optional for Groq-native models (groq/compound, groq/compound-mini)
GROQ_API_KEY=your_groq_keyEliza App variables (for Telegram, iMessage, Discord, and WhatsApp integrations): # JWT secret for Eliza App user sessions (required)
ELIZA_APP_JWT_SECRET= # Generate: openssl rand -hex 32
# Telegram (optional)
ELIZA_APP_TELEGRAM_BOT_TOKEN= # From @BotFather
# iMessage / Blooio (optional)
ELIZA_APP_BLOOIO_API_KEY= # From Blooio dashboard
# Discord (optional)
ELIZA_APP_DISCORD_BOT_TOKEN= # Developer Portal → Bot
ELIZA_APP_DISCORD_APPLICATION_ID= # Developer Portal → General Information (also the OAuth2 Client ID)
ELIZA_APP_DISCORD_CLIENT_SECRET= # Developer Portal → OAuth2 → Client Secret
# WhatsApp Business Cloud API (optional — for the public Eliza App bot)
ELIZA_APP_WHATSAPP_ACCESS_TOKEN= # Meta Business Settings → System Users → Generate Token
ELIZA_APP_WHATSAPP_PHONE_NUMBER_ID= # Meta App Dashboard → WhatsApp → API Setup
ELIZA_APP_WHATSAPP_APP_SECRET= # Meta App Dashboard → Settings → Basic → App Secret
ELIZA_APP_WHATSAPP_VERIFY_TOKEN= # Generate: openssl rand -hex 32
ELIZA_APP_WHATSAPP_PHONE_NUMBER= # Display phone number in E.164 format (e.g. +14245074963)Organization-level WhatsApp (Dashboard > Settings > Connections):
See .env.example for the full list of Eliza App environment variables. Generate secure passwords: # Generate PRIVY_WEBHOOK_SECRET (min 32 chars)
openssl rand -base64 32
# Generate CRON_SECRET / ELIZA_APP_JWT_SECRET
openssl rand -hex 323. Database SetupIf you want the full local infrastructure stack, start Postgres and Redis first: bun run db:local:startRun migrations to create all tables: npm run db:migrate4. Seed Credit Packs (Optional)If using Stripe billing: npm run seed:credit-packsThis creates credit pack products in Stripe. 5. Start Development Servernpm run devVisit http://localhost:3000. 6. First Login
💻 DevelopmentAvailable Scripts# Development
npm run dev # Start dev server with Turbopack
npm run build # Production build with Turbopack
npm start # Start production server
# Database
npm run db:generate # Generate migrations from schema changes
npm run db:migrate # Run pending migrations
npm run db:studio # Open Drizzle Studio
# Code Quality
npm run lint # Run ESLint
npm run lint:fix # Auto-fix ESLint issues
npm run format # Format with Prettier
npm run format:check # Check formatting
npm run check-types # TypeScript type checking
# Utilities
npm run seed:credit-packs # Seed Stripe credit packs
npm run bootstrapper:build # Build container bootstrapperTesting (unit vs integration vs runtime)Tests are split by kind; use the right script for what you want to run:
Env is loaded from Engineering docs (WHYs)
Development Workflow
Project Structure Guidelines
🔐 Production SecuritySecurity Features Implemented✅ Content Security Policy (CSP): Comprehensive CSP configured in
✅ Security Headers: Multiple layers of protection:
Pre-Production ChecklistBefore deploying to production, complete these critical steps: 1. Configure Privy DashboardVisit https://dashboard.privy.io and configure:
2. Set Environment VariablesNEXT_PUBLIC_PRIVY_APP_ID=your_production_app_id
NEXT_PUBLIC_PRIVY_CLIENT_ID=your_production_client_id
PRIVY_APP_SECRET=your_production_app_secret
PRIVY_WEBHOOK_SECRET=strong_random_secret_here3. Test Security Configuration# Build and run in production mode
npm run build
npm run start
# Test security headers (in another terminal)
npm run test:security-headers
# Test all authentication flows
# - Login with all methods
# - Wallet connections
# - Transactions
# - Check browser console for CSP violationsDocumentationComplete security documentation is available:
Testing Your Security SetupRun the automated security headers test: npm run test:security-headersThis will verify:
Common Security IssuesIssue: "Domain not allowed"
Issue: Privy iframe not loading
Issue: CSP violations
See docs/CSP_TESTING_GUIDE.md for detailed troubleshooting. 🔧 Platform Features1. AI Text GenerationLocation: Features:
Usage: import { useChat } from "@ai-sdk/react";
const { messages, input, handleSubmit, isLoading } = useChat({
api: "/api/v1/chat",
body: { model: "gpt-4o" },
});Cost: Token-based pricing from Anthropic Messages API (Claude Code): For tools that expect the Anthropic Messages API (e.g. Claude Code), use POST /api/v1/messages with the same request/response shape. Set Public cloud agents (MCP / A2A) — Anthropic extended thinking: For 2. AI Image GenerationLocation: Features:
API: POST /api/v1/generate-image
Content-Type: application/json
Authorization: Bearer eliza_your_api_key
{
"prompt": "A serene landscape with mountains and lake at sunset"
}Cost: $0.01 per image 3. AI Video GenerationLocation: Features:
API: POST /api/v1/generate-video
Content-Type: application/json
Authorization: Bearer eliza_your_api_key
{
"prompt": "A cinematic shot of a spaceship flying through stars",
"model": "fal-ai/veo3"
}Cost: $0.05 per video ($0.025 for fallback) 4. Gallery & Media StorageLocation: Features:
Vercel Blob Benefits:
Setup: # 1. Create Blob store in Vercel Dashboard
# 2. Copy BLOB_READ_WRITE_TOKEN to .env.local
BLOB_READ_WRITE_TOKEN=vercel_blob_rw_your_token5. Container DeploymentsLocation: Features:
How It Works:
Multi-Project Example: # Deploy first project
cd ~/chatbot
elizaos deploy --project-name chatbot --api-key eliza_xxx
# URL: https://fc51b251-chatbot.containers.elizacloud.ai
# Deploy second project (same user, different project)
cd ~/assistant
elizaos deploy --project-name assistant --api-key eliza_xxx
# URL: https://fc51b251-assistant.containers.elizacloud.ai
# Update chatbot
cd ~/chatbot
# ... make changes ...
elizaos deploy --project-name chatbot # Auto-detected as update
# URL unchanged: https://fc51b251-chatbot.containers.elizacloud.aiHuman-Readable URLs:
Instance Specs (Auto-Selected): ARM64 (t4g.small - Recommended):
x86_64 (t3.small - Universal):
Platform is automatically detected from your system. ARM64 provides better cost efficiency ($2.92/month savings) while x86_64 ensures universal compatibility. Container Management: # List all containers (with project names)
elizaos containers list --api-key eliza_xxx
# View logs (auto-detects from current directory)
cd ~/chatbot
elizaos containers logs # Finds chatbot project automatically
# Delete container (auto-detects from current directory)
cd ~/chatbot
elizaos containers delete # Finds and deletes chatbot projectDeployment Architecture: Docker Image Requirements:
API: POST /api/v1/containers
Content-Type: application/json
Authorization: Bearer eliza_your_api_key
{
"name": "my-agent",
"port": 3000,
"max_instances": 1,
"environment_vars": {
"NODE_ENV": "production"
},
"ecr_image_uri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/elizaos/my-project:latest"
}Requirements:
6. elizaOS Agent IntegrationLocation: Features:
Database Schema:
API: # Create room
POST /api/eliza/rooms
{
"agentId": "uuid",
"name": "Chat Room"
}
# Send message
POST /api/eliza/rooms/{roomId}/messages
{
"content": "Hello, agent!",
"authorId": "user-uuid"
}7. Character CreatorLocation: Features:
Workflow:
Example: {
"name": "Alex",
"bio": ["A friendly AI assistant", "Specializes in technical support"],
"adjectives": ["helpful", "knowledgeable", "patient"],
"system": "You are a helpful technical support agent...",
"style": {
"chat": ["Be concise", "Use bullet points"],
"post": ["Be professional", "Include examples"]
},
"plugins": ["@elizaos/plugin-sql", "@elizaos/plugin-openai"]
}8. Developer API & Programmatic AccessLocation: Documented management endpoints that explicitly note API key support API key authentication is available for the specific endpoints documented in this README (for example:
Session-based auth only (no API key support yet): Why API Keys for Management Endpoints? Traditional SaaS platforms only expose limited APIs. We've enabled API key authentication across these management endpoints because:
Generic Voice API: Voice endpoints use provider-agnostic paths ( Billing Management: Agents and developers can configure auto-top-up settings programmatically, ensuring autonomous agents never stop working due to insufficient credits. 9. API Key ManagementLocation: Features:
Key Format: API: # Create API key
POST /api/v1/api-keys
{
"name": "Production API Key",
"description": "Main production key",
"rate_limit": 10000
}
# Regenerate key
POST /api/v1/api-keys/{id}/regenerate
# Delete key
DELETE /api/v1/api-keys/{id}Using API Keys: curl https://your-app.com/api/v1/chat \
-H "Authorization: Bearer eliza_your_key_here" \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Hello"}]}'9. Credit System & BillingLocation: Features:
Pricing:
Stripe Integration:
Credit Packs (example): [
{ name: "Starter", credits: 10000, price: 9.99 },
{ name: "Pro", credits: 50000, price: 39.99 },
{ name: "Enterprise", credits: 200000, price: 129.99 },
];Setup: See Referrals & Affiliates
See docs/referrals.md for flow, API, and revenue math; docs/affiliate-referral-comparison.md for comparison with the other cloud repo. Signup codes
Wallet API (SIWE + wallet header auth)
10. Analytics & MonitoringLocation: Features:
Metrics Tracked:
Provider Health:
11. MCP (Model Context Protocol) APILocation: Features:
Available MCP Tools:
Using MCP Inspector: npm run mcp:inspectorUsing with Claude Desktop: Add to your Claude Desktop config: {
"mcpServers": {
"eliza-cloud": {
"url": "http://localhost:3000/api/mcp",
"transport": {
"type": "streamableHttp"
},
"headers": {
"Authorization": "Bearer eliza_your_api_key_here"
}
}
}
}🗄 Database ArchitectureSaaS Schema (
|
Iteration 1 prr-fix:ic-4144102325-5
Iteration 2 prr-fix:ic-4143785130-8
Iteration 2 prr-fix:ic-4140973365-1 prr-fix:ic-4143807945-15
Iteration 2 prr-fix:ic-4144061538-2
packages/lib/api/a2a/skills.ts
Outdated
| * The calling agent's character is not available here — skills are invoked via | ||
| * the A2A protocol which only provides user/org context, not agent personality. | ||
| */ | ||
| </search> |
There was a problem hiding this comment.
Cursor search/replace artifact left in production code
High Severity
A stray </search> tag from a Cursor search/replace operation was accidentally committed on line 12 of packages/lib/api/a2a/skills.ts. This is not valid TypeScript and will cause a syntax error, breaking the A2A skills module at parse time.
There was a problem hiding this comment.
Fixed in 67138cc.
| supportsExtendedThinking, | ||
| type ThinkingConfig, | ||
| type CharacterThinkingSettings, | ||
| } from "./anthropic-thinking"; |
There was a problem hiding this comment.
Root test imports from nonexistent module path
Medium Severity
The root-level anthropic-thinking.test.ts imports validateBudgetTokens, getThinkingConfig, buildThinkingParam, and CharacterThinkingSettings from ./anthropic-thinking, but no such file exists at the repository root. The actual implementation lives at packages/lib/providers/anthropic-thinking.ts and exports completely different functions. This test will fail at import time.
There was a problem hiding this comment.
Dismissed: Comment targets line 9 but identifier validateBudgetTokens not found in file — code may have been removed or renamed
| const multiplier = process.env.RATE_LIMIT_MULTIPLIER; | ||
| if (!multiplier) return 1; | ||
| const parsed = Number.parseInt(multiplier, 10); | ||
| return Number.isNaN(parsed) || parsed < 1 ? 1 : parsed; |
There was a problem hiding this comment.
Validator accepts floats but consumer uses parseInt
Low Severity
getRateLimitMultiplier parses RATE_LIMIT_MULTIPLIER with Number.parseInt, silently truncating decimal values (e.g., "1.5" → 1). However, the env validator in env-validator.ts explicitly accepts floats via parseFloat and regex /^\d+(\.\d+)?$/. An operator who sets a fractional multiplier would pass validation but get unexpected truncation.
Additional Locations (1)
There was a problem hiding this comment.
Could not auto-fix (wrong file or repeated failures); manual review recommended.
Code ReviewOverall: The core design is solid — thinking budgets are server-side controlled, the resolution hierarchy (character > env default, capped by env max) is clean, and the security rationale (untrusted MCP/A2A callers must not raise token budgets) is sound. The new Bug: Root-level
|
|
test connection |
PR Review: feat: Anthropic CoT controlsGood overall direction — gating thinking budgets on server-side character settings (not untrusted request bodies) is the right security model. The per-agent override + env default + env cap hierarchy is clean. A few issues to address before merge: Bug: Root-level test file imports non-existent module
import {
validateBudgetTokens,
getThinkingConfig,
buildThinkingParam,
supportsExtendedThinking,
} from "./anthropic-thinking";No Bug: Fragile model detection in MCP credit reservationIn const estimatedOutputTokens = model.includes("claude") && effectiveThinkingBudget > 0
? baseOutputTokens + effectiveThinkingBudget
: baseOutputTokens;
// Prefer:
const estimatedOutputTokens = supportsExtendedThinking(model) && effectiveThinkingBudget > 0
? baseOutputTokens + effectiveThinkingBudget
: baseOutputTokens;Credit underestimation on generic v1 routesMCP and A2A routes correctly add the thinking budget to Consider either: (a) adjusting the estimate the same way MCP/A2A do, or (b) documenting why the asymmetry is intentional. Silent temperature stripping on shared endpointsWhen Minor: Redundant null-coalescing in A2A routeIn Positive callouts
|
Iteration 1 prr-fix:ic-4143706884-3 prr-fix:ic-4144015244-5
Iteration 1 prr-fix:ic-4144023511-5
Iteration 1 prr-fix:ic-4143990242-4
Iteration 1 prr-fix:prrc_kwdop6btdm6y8tp_
Code Review: feat: Anthropic CoT controlsOverall this is a well-structured feature. The separation of concerns (character settings → env default → env cap) is sound, and the rationale for not allowing CoT budget in request bodies is clearly documented. A few issues need attention before merge. Critical1. Root-level test file imports a nonexistent module
Additionally, even if the import path were fixed, Either move the test to Medium2. The env-validator for const parsed = Number.parseInt(multiplier, 10); // 1.5 → 1A value of 3. Removing Minor / Observations4. No unit tests for the actual exported API The key functions in 5. Credit over-reservation for thinking budget is undocumented Both MCP and A2A routes compute 6. If a future call site passes both What looks good
|
Explains reasoning for dismissed issues inline in code
Code ReviewOverall this is a well-designed feature with good security thinking — keeping the thinking budget server-controlled (character settings + env) rather than client-controlled is the right call. The layered env default + per-agent override + hard cap model is solid. A few issues worth addressing before merge: Bugs1. The test imports import {
validateBudgetTokens,
getThinkingConfig,
buildThinkingParam,
supportsExtendedThinking,
type ThinkingConfig,
type CharacterThinkingSettings,
} from "./anthropic-thinking";None of these names exist in
The unit tests for the production module should be colocated under 2. -} as const;
+};This changes Performance / Correctness3. Credit reservation estimates the thinking budget twice for MCP vs A2A routes MCP route ( const effectiveThinkingBudget = resolveAnthropicThinkingBudgetTokens(...) ?? 0;
const estimatedOutputTokens = model.includes("claude") && effectiveThinkingBudget > 0
? baseOutputTokens + effectiveThinkingBudget
: baseOutputTokens;A2A route ( const maxOutputTokens = effectiveThinkingBudget != null ? 500 + effectiveThinkingBudget : undefined;
const baseCost = await estimateRequestCost(model, fullMessages, maxOutputTokens);The MCP route uses Breaking Change for Developers4. Rate limits now default to production values in dev — requires action to restore old behavior The change removes the The PR description notes this ("Rate-limit behavior in development also changes to production-level defaults") but the 5. Minor: In const parsed = Number.parseInt(multiplier, 10);In if (!/^\d+(\.\d+)?$/.test(trimmed)) return false;
const n = Number.parseFloat(trimmed);
return n > 0 && Number.isFinite(n);The validator accepts What's Good
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| if (!multiplier) return 1; | ||
| const parsed = Number.parseInt(multiplier, 10); | ||
| return Number.isNaN(parsed) || parsed < 1 ? 1 : parsed; | ||
| } |
There was a problem hiding this comment.
Rate limit multiplier applies in production without guard
Medium Severity
RATE_LIMIT_MULTIPLIER is read and applied unconditionally in all environments, including production. Previously, production always used strict numeric limits (60, 10, 200, 5, 10, 100) while only development got relaxed limits (10000). Now, if RATE_LIMIT_MULTIPLIER is accidentally set in a production deployment (e.g., left over from staging), all rate limits are multiplied — RATE_LIMIT_MULTIPLIER=100 would allow 6000 requests/minute on STANDARD endpoints. getRateLimitMultiplier has no NODE_ENV === "production" guard to force the multiplier to 1.
Additional Locations (1)
| const n = Number.parseFloat(trimmed); | ||
| return n > 0 && Number.isFinite(n); | ||
| }, | ||
| errorMessage: "Must be a positive number (e.g., 1, 10, 100)", |
There was a problem hiding this comment.
Rate limit multiplier validator accepts floats, parser truncates
Low Severity
The RATE_LIMIT_MULTIPLIER env validator accepts float strings (regex ^\d+(\.\d+)?$ and Number.parseFloat), but getRateLimitMultiplier uses Number.parseInt(multiplier, 10) which silently truncates decimals. Setting RATE_LIMIT_MULTIPLIER=1.5 passes validation but is treated as 1 at runtime. The validator and the consumer disagree on the accepted format.
Additional Locations (1)
Code Review: feat: Anthropic CoT controlsOverall the design is solid — locking the thinking budget to character settings rather than request bodies is the right security call, and the deep-merge helpers prevent accidental provider-key clobbering. A few issues need fixing before merge. Critical — will break at runtime/test time1. The test file at the repo root imports This test file appears to have been generated against a stale or different API surface and will fail to compile. Either update it to test the actual exported symbols with correct import paths, or move it to the proper test directory with matching function names. 2. The pattern Behavioral Change — developer experience regression3. Rate-limit preset change silently breaks local dev Removing the Logic / Correctness4. Dead code in A2A route:
5. Inconsistent model-check heuristic for credit estimation
6. The env-validator accepts Minor / Nits7. Only 8. Credit reservation underestimates for thinking-heavy responses
What is well done
|



Note: services/operator (Pepr) is not part of the main workspace typecheck.
Made-with: Cursor
Note
Medium Risk
Medium risk: changes LLM
providerOptionsand credit reservation estimates across multiple production API routes, which can impact billing and model behavior; also modifies rate limiting presets via a new env multiplier.Overview
Introduces per-agent Anthropic extended thinking controls by adding
packages/lib/providers/anthropic-thinking.tsto resolve thinking budgets fromuser_characters.settings.anthropicThinkingBudgetTokenswith deploy-level defaults (ANTHROPIC_COT_BUDGET) and an optional global cap (ANTHROPIC_COT_BUDGET_MAX), plus helpers to deep-mergeproviderOptionswithout clobbering existinggateway/googlesettings.Wires these options into MCP/A2A agent chat (including credit reservation estimates that account for thinking tokens) and applies env-based thinking merges to several other text routes, while explicitly disabling CoT for background/promo/SEO and image-generation flows to preserve temperature control. Adds env validation for the new variables, updates rate limiting to use production-level limits in dev with a
RATE_LIMIT_MULTIPLIER, expands CI/typecheck coverage, and hardens/adjusts unit+integration tests (including Milady pricing mock isolation) with new docs and changelog entries.Written by Cursor Bugbot for commit 3b0b079. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
New Features
Documentation
Bug Fixes
Chores