Skip to content

fix(block_cost_config): audit + correct stale LLM/block rates + migrate generic ReplicateModelBlock to COST_USD - #12912

Merged
majdyz merged 8 commits into
devfrom
fix/gpt5-sync-rate
Apr 24, 2026
Merged

fix(block_cost_config): audit + correct stale LLM/block rates + migrate generic ReplicateModelBlock to COST_USD#12912
majdyz merged 8 commits into
devfrom
fix/gpt5-sync-rate

Conversation

@majdyz

@majdyz majdyz commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Why

PR #12909's pricing refresh was sourced from aggregators (pricepertoken, blog mirrors) instead of provider pricing pages. Follow-up audit against official provider docs caught 22 stale entries — 9 LLM token rates + 12 non-LLM block rates + 1 block that needed a code refactor to bill dynamically. Also flagged by Sentry: Mistral models were sitting on the wrong provider's rate table.

Cross-verified JS-rendered pages (docs.x.ai, DeepSeek, Kimi) via agent-browser.

Corrections applied

LLM TOKEN_COST (9 entries)

Model Old New Reason
GPT5 94/750 188/1500 Was OpenAI Batch API rate; Standard is $1.25/$10
DEEPSEEK_CHAT 42/63 21/42 Unified to deepseek-v4-flash at $0.14/$0.28 (Sept 2025)
DEEPSEEK_R1_0528 82/329 21/42 Same v4-flash routing
MISTRAL_LARGE_3 300/900 300/900 (restored after brief 75/225 detour) Routes via OpenRouter ($2/$6), not Mistral direct
MISTRAL_NEMO 3/6 → 23/23 5/5 Routes via OpenRouter ($0.035/$0.035); Mistral-direct $0.15 doesn't apply
KIMI_K2_0905 82/330 90/375 Matches K2 family $0.60/$2.50
KIMI_K2_5 90/450 66/300 OpenRouter pass-through $0.44/$2
KIMI_K2_6 143/600 112/698 OpenRouter pass-through $0.7448/$4.655
META_LLAMA_4_MAVERICK 30/90 75/116 Groq $0.50/$0.77 (deprecated 2026-02-20)

Non-LLM BLOCK_COSTS — rate corrections (11 entries)

Under-billing fixes:

  • AIVideoGeneratorBlock (FAL) SECOND 3 → 15 cr/s
  • CreateTalkingAvatarVideoBlock (D-ID) RUN 15 → 100 cr
  • Nano Banana Pro/2 across 3 blocks: RUN 14 → 21 cr
  • UnrealTextToSpeechBlock RUN 5 → COST_USD 150 cr/$ (block now emits chars × $0.000016)

Over-billing fixes:

  • IdeogramModelBlock default 16 → 12, V_3 18 → 14
  • AIImageEditorBlock FLUX_KONTEXT_MAX 20 → 12
  • ValidateEmailsBlock 250 → 150 cr/$
  • SearchTheWebBlock 100 → 150 cr/$
  • GetLinkedinProfilePictureBlock 3 → 1 cr

Non-LLM BLOCK_COSTS — block refactored for dynamic billing (1 entry)

  • ReplicateModelBlock (the generic "run any Replicate model" wrapper) migrated from flat RUN 10 cr → COST_USD 150 cr/$. Block now uses client.predictions.async_create + async_wait instead of async_run(wait=False) so it can read prediction.metrics.predict_time and bill predict_time × $0.0014/s (Nvidia L40S mid-tier, where most popular public models run).

    Additionally (addressing CodeRabbit's critical review on this refactor): async_wait() returns normally regardless of terminal status — it doesn't raise on failed/canceled like the old async_run did. The block now explicitly checks prediction.status after async_wait() and raises RuntimeError on failed (with prediction.error as context) or canceled before merge_stats, so failed runs are never billed for partial compute time.

    Why this matters: flat 10 cr was 10–500× under-billing long video/LLM runs (users could wire in a $50/hr A100 Llama inference and pay us $0.10). It was also 20× over-billing trivial SDXL runs. Now scales with real compute time AND no longer bills failed predictions.

Documentation-only

  • Grok legacy models (grok-3, grok-4-0709, grok-4-fast, grok-code-fast-1): dropped from docs.x.ai's public pricing page but still callable via the API. Added inline comment noting this; rates kept at their verified launch pricing.
  • Mistral routing: added comment explaining why TOKEN_COST for MISTRAL_* is the OpenRouter safety floor (not Mistral-direct) since ModelMetadata.provider = "open_router" for all Mistral entries.

How

  • For each entry, opened the official provider pricing page directly and computed our_cr = round(1.5 × provider_usd × 100).
  • For JS-rendered pages (docs.x.ai, api-docs.deepseek.com), used agent-browser headless to render + extract rates from the DOM.
  • Migrated 2 blocks (UnrealTextToSpeechBlock, ReplicateModelBlock) from flat RUN to COST_USD — the Replicate migration touched the block's SDK interaction.
  • Updated 2 FAL-video unit tests that asserted the old 3 cr/s rate.
  • Updated 3 stale test assertions: 2 for Unreal TTS (still on characters cost_type) + 1 for ZeroBounce (old 250 cr).

Known remaining risk (explicitly out of scope)

  • ReplicateFluxAdvancedModelBlock not migrated — bounded to Flux models ($0.04–$0.08), flat 10 cr stays within 1.25–2.5× margin. Separate PR if desired.
  • AgentMail on free tier (1 RUN). When paid pricing publishes, revisit.
  • Live Replicate API verification: mitigated via 9 unit tests covering the refactored path (async_create version-vs-model branching, metrics-based billing emission, failed/canceled raises, zero/missing-metrics no-emission, async_wait ordering), and SDK signature confirmed via inspect.signature — but no real API call executed. A smoke test on a cheap model before merge is still recommended.

Test plan

  • poetry run pytest backend/data/block_cost_config_test.py backend/executor/block_usage_cost_test.py backend/blocks/claude_code_cost_test.py backend/blocks/cost_leak_fixes_test.py backend/blocks/block_cost_tracking_test.py backend/copilot/tools/helpers_test.py backend/blocks/replicate/replicate_block_cost_test.py -q — all passing (80+ tests).
  • Sources: openai.com/api/pricing, claude.com/pricing, api-docs.deepseek.com, mistral.ai/pricing, platform.kimi.ai/docs/pricing, docs.x.ai, groq.com/pricing, replicate.com, fal.ai, d-id.com, ideogram.ai, zerobounce.net, jina.ai, unrealspeech.com, enrichlayer.com.
  • Live Replicate API call to verify predictions.async_create + async_wait + metrics.predict_time path.

PR #12909 refresh set GPT-5 to 94/1500 cr/1M which corresponds to a
$0.625/$5 provider rate — that's OpenAI's Batch API tier (50% off
Sync). Most block calls go through the Sync API; the correct Standard
rate is $1.25/$10 per 1M, which at our 1.5x margin = 188/1500 cr/1M.

This was under-billing every GPT-5 call by 2x on input.

Source: https://openai.com/api/pricing — GPT-5 Standard pricing.
@majdyz
majdyz requested a review from a team as a code owner April 24, 2026 15:36
@majdyz
majdyz requested review from 0ubbe and Pwuts and removed request for a team April 24, 2026 15:36
@github-project-automation github-project-automation Bot moved this to 🆕 Needs initial review in AutoGPT development kanban Apr 24, 2026
@github-actions github-actions Bot added the platform/backend AutoGPT Platform - Back end label Apr 24, 2026
@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Recalibrated token and block credit rates across multiple LLM providers and blocks; expanded provider-specific LLM BlockCost mappings; switched several blocks from flat-run credits to USD-based billing and updated tests to match new per-second/per-unit rates. Replicate execution now uses predictions.async_create/async_wait and emits USD provider costs.

Changes

Cohort / File(s) Summary
Token & LLM cost config
autogpt_platform/backend/backend/data/block_cost_config.py
Updated TOKEN_COST per‑1M token rates for several LlmModel entries and expanded LLM_COST to include provider-specific BlockCost mappings (OpenAI, Groq, OpenRouter via COST_USD with cost_amount=150, plus llama_api, v0, aiml_api).
Block credit adjustments
autogpt_platform/backend/backend/data/block_cost_config.py
Adjusted BLOCK_COSTS: many blocks had credit changes and/or switched cost_type to COST_USD (examples: D‑ID talking avatar 15→100, SearchTheWeb 100→150, Ideogram image costs decreased, ReplicateModelBlock and UnrealTextToSpeech moved to COST_USD with larger amounts, LinkedIn pic 3→1, Nano Banana ↑, ZeroBounce ↓, FAL AIVideoGenerator per‑second 3→15).
Replicate execution & billing
autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
Switched from client.async_run(..., wait=False) to creating a prediction via client.predictions.async_create and awaiting with prediction.async_wait; selects version= vs model= based on model_ref; reads prediction.metrics["predict_time"] when present and emits NodeExecutionStats with provider_cost in cost_usd computed via _REPLICATE_USD_PER_SEC.
TTS provider cost emission
autogpt_platform/backend/backend/blocks/text_to_speech_block.py
Replaced character-count flat provider-cost emission with USD-per-character provider_cost and provider_cost_type="cost_usd" for UnrealTextToSpeech; added inline pricing comments.
Tests updated for billing changes
autogpt_platform/backend/backend/data/block_cost_config_test.py, autogpt_platform/backend/backend/executor/block_usage_cost_test.py
Updated assertions and docstrings to reflect new FAL AIVideoGenerator billing (15 credits/s) and updated computed totals; pre‑flight unknown‑walltime behavior unchanged.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

size/m

Suggested reviewers

  • Pwuts
  • kcze

Poem

🐰 I hop through lines of cost and code,

Tokens tally as I patrol the road,
Seconds and cents in a careful trot,
I nibble changes—billing's carrot plot,
A cheerful rabbit nods: the ledgers show.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the main change: auditing and correcting stale LLM/block pricing rates, plus migrating ReplicateModelBlock to COST_USD billing. It is concise and specific.
Description check ✅ Passed The PR description comprehensively documents stale pricing entries audited against official provider docs, specific rate corrections with before/after values and reasons, block refactoring details (ReplicateModelBlock migration), and test verification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/gpt5-sync-rate

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Overlap Detection

This check compares your PR against all other open PRs targeting the same branch to detect potential merge conflicts early.

🔴 Merge Conflicts Detected

The following PRs have been tested and will have merge conflicts if merged after this PR. Consider coordinating with the authors.

🟢 Low Risk — File Overlap Only

These PRs touch the same files but different sections (click to expand)

Summary: 5 conflict(s), 0 medium risk, 2 low risk (out of 7 PRs with file overlap)


Auto-generated on push. Ignores: openapi.json, lock files.

@codecov

codecov Bot commented Apr 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.36066% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.24%. Comparing base (408b205) to head (221ec68).
⚠️ Report is 2 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #12912      +/-   ##
==========================================
+ Coverage   68.21%   68.24%   +0.03%     
==========================================
  Files        1959     1960       +1     
  Lines      149934   150048     +114     
  Branches    15606    15612       +6     
==========================================
+ Hits       102273   102403     +130     
+ Misses      44627    44610      -17     
- Partials     3034     3035       +1     
Flag Coverage Δ
platform-backend 77.85% <98.36%> (+0.02%) ⬆️
platform-frontend-e2e 30.29% <ø> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Platform Backend 77.85% <98.36%> (+0.02%) ⬆️
Platform Frontend 32.83% <ø> (+0.03%) ⬆️
AutoGPT Libs ∅ <ø> (∅)
Classic AutoGPT 28.43% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Beyond the GPT-5 Standard-vs-Batch fix, verified all TOKEN_COST entries
against each provider's current pricing page. Additional corrections:

- DEEPSEEK_CHAT: 42/63 -> 21/42 (provider unified deepseek-chat +
  deepseek-reasoner to deepseek-v4-flash $0.14/$0.28 in Sept 2025)
- DEEPSEEK_R1_0528: 82/329 -> 21/42 (same v4-flash routing)
- MISTRAL_LARGE_3: 300/900 -> 75/225 (Mistral dropped to $0.50/$1.50)
- MISTRAL_NEMO: 3/6 -> 23/23 (was severely under-billing; provider is
  $0.15 flat for both input and output)
- KIMI_K2_0905: 82/330 -> 90/375 (matches current K2-0905 $0.60/$2.50)
- META_LLAMA_4_MAVERICK: 30/90 -> 75/116 (Groq prices $0.50/$0.77;
  note Groq deprecated this 2026-02-20 — consider retiring enum)

Provider sources: openai.com/api/pricing, api-docs.deepseek.com,
mistral.ai/pricing, platform.kimi.ai/docs/pricing, groq.com/pricing.
Cross-verified via agent-browser for JS-rendered docs.x.ai + DeepSeek.

All 40 cost-pipeline unit tests pass.
@github-actions github-actions Bot added size/m and removed size/s labels Apr 24, 2026
Comment thread autogpt_platform/backend/backend/data/block_cost_config.py Outdated
Full audit against provider pricing pages uncovered 10 more stale
entries beyond the LLM token rates:

Under-billing (was losing money):
- AIVideoGeneratorBlock (FAL): SECOND 3 -> 15 cr/s
  (provider is $0.05-$0.30/s depending on tier; 3 cr only covered
  $0.02/s models)
- CreateTalkingAvatarVideoBlock (D-ID): RUN 15 -> 100 cr
  (D-ID charges $5.90/min; 15 cr was ~10x under for a median 10-sec
  clip at $0.98 real cost)
- Nano Banana Pro / Nano Banana 2 (3 blocks each): RUN 14 -> 21 cr
  (provider $0.14/image, 14 cr was under cost-of-goods)

Over-billing (normalizing margin to 1.5x baseline):
- IdeogramModelBlock default: RUN 16 -> 12 cr
- IdeogramModelBlock V_3: RUN 18 -> 14 cr
- AIImageEditorBlock FLUX_KONTEXT_MAX: RUN 20 -> 12 cr
- ValidateEmailsBlock (ZeroBounce): COST_USD 250 -> 150 cr/$
- SearchTheWebBlock (Jina): COST_USD 100 -> 150 cr/$
- GetLinkedinProfilePictureBlock: RUN 3 -> 1 cr

Tests updated to match new FAL 15 cr/s rate (was 3 cr/s in 2 tests).

Sources: replicate.com, fal.ai, d-id.com, ideogram.ai, zerobounce.net,
jina.ai. Cross-verified via agent-browser for JS-rendered docs.x.ai
(Grok prices already correct at 300/900 for Grok 4.20 @ $2/$6).
@majdyz majdyz changed the title fix(block_cost_config): correct GPT-5 rate to Standard API, not Batch fix(block_cost_config): audit + correct stale LLM + block rates against provider pricing Apr 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
autogpt_platform/backend/backend/data/block_cost_config.py (1)

1227-1243: ⚠️ Potential issue | 🟡 Minor

FAL per-second rate bump from 3 → 15 cr/s is a 5× user-facing price increase — confirm it's intentional.

Per prior learnings, AIVideoGeneratorBlock is walltime-billed (FAL SDK doesn't surface provider_cost / output duration), so the credit cost scales linearly with whatever wall-clock time the block spends. The comment's justification (Lite tier $0.10/s @ 1.5×) is reasonable for the slow tiers, but fast Lite-tier calls that previously charged ~3 cr will now charge ~15 cr even when the actual provider cost is well under that. That's a significant live-customer price change that deserves a release note / changelog entry separate from the GPT-5 fix.

Code-wise, the change and both test updates (75 cr @ 5s, 120 cr @ 8s) are internally consistent — no bug. Just flagging the pricing impact for sign-off.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/data/block_cost_config.py` around lines 1227
- 1243, AIVideoGeneratorBlock's per-second cost was increased from 3→15
(BlockCost(cost_amount=15, cost_type=BlockCostType.SECOND) with fal_credentials
filter), which is a 5× user-facing price change — confirm this is intentional
with product/finance and either revert to previous value or get sign-off; after
sign-off, add a clear release-note/changelog entry describing the pricing change
and rationale, and add an in-code comment next to AIVideoGeneratorBlock
referencing the changelog entry and the fal_credentials-based walltime billing
behavior so reviewers see this is deliberate; if reverting, update the tests
that expect 75cr@5s and 120cr@8s accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@autogpt_platform/backend/backend/data/block_cost_config.py`:
- Around line 1227-1243: AIVideoGeneratorBlock's per-second cost was increased
from 3→15 (BlockCost(cost_amount=15, cost_type=BlockCostType.SECOND) with
fal_credentials filter), which is a 5× user-facing price change — confirm this
is intentional with product/finance and either revert to previous value or get
sign-off; after sign-off, add a clear release-note/changelog entry describing
the pricing change and rationale, and add an in-code comment next to
AIVideoGeneratorBlock referencing the changelog entry and the
fal_credentials-based walltime billing behavior so reviewers see this is
deliberate; if reverting, update the tests that expect 75cr@5s and 120cr@8s
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d8d5ce75-26c2-4c95-82ce-f3d3db924e52

📥 Commits

Reviewing files that changed from the base of the PR and between ec895d7 and e1e1692.

📒 Files selected for processing (3)
  • autogpt_platform/backend/backend/data/block_cost_config.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: check API types
  • GitHub Check: end-to-end tests
  • GitHub Check: test (3.13)
  • GitHub Check: type-check (3.12)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.11)
  • GitHub Check: Seer Code Review
  • GitHub Check: Analyze (typescript)
  • GitHub Check: Analyze (python)
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (5)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

autogpt_platform/backend/**/*.py: Use poetry run ... command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl
Use absolute imports with from backend.module import ... for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoid hasattr/getattr/isinstance for type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no # type: ignore, # noqa, # pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use %s for deferred interpolation in debug log statements for efficiency; use f-strings elsewhere for readability (e.g., logger.debug("Processing %s items", count) vs logger.info(f"Processing {count} items"))
Sanitize error paths by using os.path.basename() in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Use transaction=True for Redis pipelines to ensure atomicity on multi-step operations
Use max(0, value) guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...

Files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/backend/**/*_test.py

📄 CodeRabbit inference engine (autogpt_platform/backend/AGENTS.md)

autogpt_platform/backend/**/*_test.py: Use pytest with snapshot testing for API responses
Colocate test files with source files using *_test.py naming convention
Mock at boundaries — mock where the symbol is used, not where it's defined; after refactoring, update mock targets to match new module paths
Use AsyncMock from unittest.mock for async functions in tests
When writing tests, use Test-Driven Development (TDD): write failing tests marked with @pytest.mark.xfail before implementation, then remove the marker once the implementation is complete
When creating snapshots in tests, use poetry run pytest path/to/test.py --snapshot-update; always review snapshot changes with git diff before committing

Files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
autogpt_platform/backend/backend/data/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All data access in backend requires user ID checks; verify this for any 'data/*.py' changes

Files:

  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/**/data/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

For changes touching data/*.py, validate user ID checks or explain why not needed

Files:

  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
🧠 Learnings (18)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.
📚 Learning: 2026-04-23T13:55:24.409Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T13:53:29.246Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T04:01:32.723Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T13:53:40.315Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-15T15:30:09.706Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/executor/block_usage_cost_test.py
  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-21T04:35:34.710Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12865
File: autogpt_platform/backend/backend/data/credit.py:1584-1584
Timestamp: 2026-04-21T04:35:34.710Z
Learning: When reviewing this codebase, don’t flag snake_case attribute names (e.g., `subscription_tier`, `stripe_customer_id`, `top_up_config`) on the app-layer Pydantic `User` model as “wrong” field names. These are correct for the app-layer model and are expected to be mapped from the Prisma-layer camelCase fields (e.g., `subscriptionTier`, `stripeCustomerId`) inside methods like `User.from_db()`. Only Prisma-returned/raw objects would use camelCase, but functions like `get_user_by_id(user_id: str)` are expected to return the Pydantic app-layer model.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config_test.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T00:07:27.117Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-09T10:50:43.907Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-09T10:50:43.907Z
Learning: Repo: Significant-Gravitas/AutoGPT — File: autogpt_platform/backend/backend/blocks/llm.py
For xAI Grok models accessed via OpenRouter, the API returns `null` for `max_completion_tokens`. The convention in this codebase is to use the model's context window size as the `max_output_tokens` value in ModelMetadata. For example, Grok 3 uses 131072 (128k) and Grok 4 uses 262144 (256k). Do not flag these as incorrect max output token values.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-08T17:27:07.646Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: classic/forge/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:27:07.646Z
Learning: Applies to classic/forge/**/forge/llm/providers/**/*.py : Supported model names include OpenAI (GPT3, GPT3_16k, GPT4, GPT4_32k, GPT4_TURBO, GPT4_O), Anthropic (CLAUDE3_OPUS, CLAUDE3_SONNET, CLAUDE3_HAIKU, CLAUDE3_5_SONNET, CLAUDE3_5_SONNET_v2, CLAUDE3_5_HAIKU, CLAUDE4_SONNET, CLAUDE4_OPUS, CLAUDE4_5_OPUS), and Groq (LLAMA3_8B, LLAMA3_70B, MIXTRAL_8X7B)

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
🔇 Additional comments (5)
autogpt_platform/backend/backend/data/block_cost_config.py (3)

278-283: GPT-5 rate correction looks right.

input=188, output=1500 matches OpenAI Standard (Sync) API pricing of $1.25 / $10 per 1M at the file's documented 150 cr/$ = 1.5× margin convention (line 241-245), and is now consistent with GPT5_1 above. The previous 94/… implied Batch input pricing, which under-billed Sync-mode calls (the only path used by these blocks).


570-584: No action requiredSearchTheWebBlock correctly emits provider_cost=0.01 with provider_cost_type="cost_usd" (lines 76–78 of search.py), confirming the COST_USD billing path will function as designed. The 150 cr/$ multiplier matches the documented 1.5x margin baseline.


310-340: Collateral TOKEN_COST re-prices confirmed accurate against provider sources.

Spot-checked the TOKEN_COST rows:

  • GPT-5 188/1500: $1.25/$10.00 per 1M (Sync API, April 2026) — matches. ✓
  • DeepSeek 21/42: $0.14/$0.28 per 1M (deepseek-v4-flash, Sept 2025 unified pricing) — matches. ✓
  • Mistral Large 3 75/225: $0.50/$1.50 per 1M (confirmed via OpenRouter) — matches. ✓
  • Mistral Nemo, Kimi K2_0905, Meta Llama 4 Maverick, Perplexity Sonar tiers: consistent with surrounding family entries and the documented 1.5× margin over published rates.

The TOKEN_COST entries apply a uniform 1.5× margin over provider pricing, with de-marginization via 1 credit ≈ $0.01 (lines 244–245). All spot-checked values are correct.

Note: The PR description advertises a "one-line change" but the diff actually touches multiple TOKEN_COST rows (GPT-5, DeepSeek, Mistral, Cohere, Kimi, Perplexity, Meta Llama) and other BLOCK_COSTS entries — worth clarifying in the merge-log description for transparency, but the numerical values are correct.

autogpt_platform/backend/backend/data/block_cost_config_test.py (1)

143-161: Test update matches the new 15 cr/s rate.

Math checks out: 5s × 15 cr/s = 75 credits post-flight; pre-flight remains 0. Docstring correctly reflects cost_amount=15.

autogpt_platform/backend/backend/executor/block_usage_cost_test.py (1)

200-214: Test update is consistent with the FAL rate change.

8s × 15 cr/s = 120 credits; pre-flight remains 0. Function name and comment correctly reflect the new rate. No other assertions in this file depend on FAL pricing.

…k legacy doc

- KIMI_K2_5: 90/450 -> 66/300 (OpenRouter pass-through $0.44/$2)
- KIMI_K2_6: 143/600 -> 112/698 (OpenRouter pass-through $0.7448/$4.655)
- UnrealTextToSpeechBlock: RUN 5 cr -> COST_USD 150 cr/$. Block now
  computes USD from len(text) * $0.000016 (Unreal Speech $16/1M chars)
  and emits cost_usd via merge_stats. Long narrations no longer under-bill.
- Grok legacy (grok-3, grok-4-0709, grok-4-fast, grok-code-fast-1):
  rates were already correct at their launch pricing; added inline
  comment noting the docs.x.ai page no longer lists them publicly but
  the API + historical rates remain valid.
Comment thread autogpt_platform/backend/backend/data/block_cost_config.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
autogpt_platform/backend/backend/data/block_cost_config.py (1)

712-733: ⚠️ Potential issue | 🟡 Minor

Inconsistent Nano Banana pricing across blocks — AIImageEditorBlock still charges 14 cr while AIImageGeneratorBlock / AIImageCustomizerBlock were raised to 21 cr.

The audit raised Nano Banana Pro / Nano Banana 2 from 14 → 21 in AIImageGeneratorBlock (lines 928, 939) and AIImageCustomizerBlock (lines 963, 974) with the justification $0.14/image at 2K @ 1.5x margin. The same underlying Replicate models are wired here at cost_amount=14 — roughly the old 1.0× rate, so they're under-billed by ~33% relative to the rest of the PR's 1.5× baseline.

🛠 Suggested alignment
         BlockCost(
-            cost_amount=14,  # Nano Banana Pro
+            cost_amount=21,  # Nano Banana Pro: $0.14/image @ 1.5x margin
             cost_filter={
                 "model": FluxKontextModelName.NANO_BANANA_PRO,
                 ...
             },
         ),
         BlockCost(
-            cost_amount=14,  # Nano Banana 2
+            cost_amount=21,  # Nano Banana 2: same pricing tier as Pro
             cost_filter={
                 "model": FluxKontextModelName.NANO_BANANA_2,
                 ...
             },
         ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/data/block_cost_config.py` around lines 712
- 733, The BlockCost entries for Nano Banana models are underpriced at
cost_amount=14; update the BlockCost instances that use
FluxKontextModelName.NANO_BANANA_PRO and FluxKontextModelName.NANO_BANANA_2 (the
ones referencing replicate_credentials.id/provider/type) to cost_amount=21 so
the AIImageEditorBlock pricing aligns with the AIImageGeneratorBlock and
AIImageCustomizerBlock changes; keep the same cost_filter structure and
replicate_credentials references unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@autogpt_platform/backend/backend/data/block_cost_config.py`:
- Around line 712-733: The BlockCost entries for Nano Banana models are
underpriced at cost_amount=14; update the BlockCost instances that use
FluxKontextModelName.NANO_BANANA_PRO and FluxKontextModelName.NANO_BANANA_2 (the
ones referencing replicate_credentials.id/provider/type) to cost_amount=21 so
the AIImageEditorBlock pricing aligns with the AIImageGeneratorBlock and
AIImageCustomizerBlock changes; keep the same cost_filter structure and
replicate_credentials references unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2758ec89-9e16-4690-a629-5341769a155a

📥 Commits

Reviewing files that changed from the base of the PR and between e1e1692 and c3448f5.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: check API types
  • GitHub Check: Seer Code Review
  • GitHub Check: test (3.13)
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: end-to-end tests
  • GitHub Check: Check PR Status
🧰 Additional context used
📓 Path-based instructions (5)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

autogpt_platform/backend/**/*.py: Use poetry run ... command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl
Use absolute imports with from backend.module import ... for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoid hasattr/getattr/isinstance for type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no # type: ignore, # noqa, # pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use %s for deferred interpolation in debug log statements for efficiency; use f-strings elsewhere for readability (e.g., logger.debug("Processing %s items", count) vs logger.info(f"Processing {count} items"))
Sanitize error paths by using os.path.basename() in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Use transaction=True for Redis pipelines to ensure atomicity on multi-step operations
Use max(0, value) guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...

Files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/backend/backend/blocks/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/backend/blocks/**/*.py: Inherit from 'Block' base class with input/output schemas when adding new blocks in backend
Implement 'run' method with proper error handling in backend blocks
Generate block UUID using 'uuid.uuid4()' when creating new blocks in backend
Write tests alongside block implementation when adding new blocks in backend

autogpt_platform/backend/backend/blocks/**/*.py: For blocks handling files, use store_media_file() with return_format="for_local_processing" when processing with local tools (ffmpeg, MoviePy, PIL)
For blocks handling files, use store_media_file() with return_format="for_external_api" when sending content to external APIs (Replicate, OpenAI)
For blocks returning files, use store_media_file() with return_format="for_block_output" to enable auto-adaptation to execution context (workspace:// in CoPilot, data URI in graphs)
When creating new blocks, inherit from Block base class, define input/output schemas using BlockSchema, implement async run method, and generate unique block ID using uuid.uuid4()

Files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/backend/backend/data/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All data access in backend requires user ID checks; verify this for any 'data/*.py' changes

Files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/**/data/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

For changes touching data/*.py, validate user ID checks or explain why not needed

Files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
🧠 Learnings (24)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12566
File: autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts:968-974
Timestamp: 2026-03-26T00:32:06.673Z
Learning: In Significant-Gravitas/AutoGPT, the admin-facing methods in `autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts` (e.g., `addUserCredits`, `getUsersHistory`, `getUserRateLimit`, `resetUserRateLimit`) intentionally follow the legacy `BackendAPI` pattern with manually defined types in `autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts`. Migrating these admin endpoints to the generated OpenAPI hooks (`@/app/api/__generated__/endpoints/`) is a planned separate effort covering all admin endpoints together, not done piecemeal per PR. Do not flag individual admin type additions in `types.ts` as blocking issues.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12536
File: autogpt_platform/frontend/src/app/api/openapi.json:5770-5790
Timestamp: 2026-03-24T21:25:15.983Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12536`
File: autogpt_platform/frontend/src/app/api/openapi.json
Learning: The OpenAPI spec file is auto-generated; per established convention, endpoints generally declare only 200/201, 401, and 422 responses. Do not suggest adding explicit 403/404 response entries for single operations unless planning a repo-wide spec update. Prefer clarifying such behaviors in endpoint descriptions/docstrings instead of altering response maps.
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:18.476Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.
📚 Learning: 2026-04-23T13:53:29.246Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T04:01:32.723Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T13:55:24.409Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: Cost billing via the cost(*costs) decorator is applied at input-evaluation time (before a block’s run() executes). Therefore, mutating input_data inside run() will not change billing. When a block’s billing depends on a field plus URL/sniff-derived signals, treat the explicitly declared billing field (e.g., is_video) as the only billing source—set it correctly before run() (or in the code path that occurs before the decorator evaluates input_data). This should be checked for all blocks under autogpt_platform/backend/backend/blocks/ so billing signals are not mistakenly assumed to update during run().

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-04-23T13:53:40.315Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-02-05T04:11:00.596Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 11796
File: autogpt_platform/backend/backend/blocks/video/concat.py:3-4
Timestamp: 2026-02-05T04:11:00.596Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, when creating a new block, generate a UUID once with uuid.uuid4() and hard-code the resulting string as the block's id parameter. Do not call uuid.uuid4() at runtime; IDs must be constant across all imports and runs to ensure stability.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-03-16T16:32:21.686Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:32:21.686Z
Learning: In autogpt_platform/backend/backend/blocks/, the Block base class execute() already wraps run() in a try/except to convert uncaught exceptions into BlockExecutionError/BlockUnknownError. Do not add per-block try/except in individual block run() methods, as this is not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Only use explicit try/except within blocks that need to distinguish between success and error yield paths inside a generator (e.g., attachment blocks). This guidance applies to all Python files under autogpt_platform/backend/backend/blocks/ and similar block implementations; avoid duplicating error handling in run() unless a block requires generator-based branching.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: In autogpt_platform/backend/backend/blocks/ (and related blocks under autogpt_platform/backend/backend/blocks/), do not add try/except blocks around a block's run() method for standard error propagation. The block executor framework (backend/executor/manager.py) catches uncaught exceptions from run() and emits them on the 'error' output. Only add explicit try/except blocks when you need to control partial outputs in failure cases (e.g., certain outputs must not be yielded on error, as in attachment blocks). This is the standard pattern across the codebase; apply it broadly to blocks' run() implementations.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-03-16T16:30:23.196Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:30:23.196Z
Learning: In any Python file under autogpt_platform/backend/backend/blocks, do not add a try/except around run() solely for standard error handling. The block framework’s _execute() in _base.py already catches unhandled exceptions and re-raises as BlockExecutionError or BlockUnknownError. If you yield ("error", message), _execute() raises BlockExecutionError immediately, so the error port will not propagate downstream. Reserve explicit try/except for scenarios where you must control partial output (e.g., attachment blocks that must skip yielding content_base64 on failure).

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: Do not wrap synchronous AgentMail SDK calls with asyncio.to_thread() in blocks under autogpt_platform/backend/backend/blocks (and across the codebase). The block executor runs node execution in dedicated threads via asyncio.run_coroutine_threadsafe (see manager.py around lines ~745-752 and ~1079). The existing pattern avoids using asyncio.to_thread for SDK calls inside async run() methods, so maintain that approach and do not add to_thread usage in these code paths.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/blocks/text_to_speech_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-09T10:50:43.907Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-09T10:50:43.907Z
Learning: Repo: Significant-Gravitas/AutoGPT — File: autogpt_platform/backend/backend/blocks/llm.py
For xAI Grok models accessed via OpenRouter, the API returns `null` for `max_completion_tokens`. The convention in this codebase is to use the model's context window size as the `max_output_tokens` value in ModelMetadata. For example, Grok 3 uses 131072 (128k) and Grok 4 uses 262144 (256k). Do not flag these as incorrect max output token values.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T00:07:27.117Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-08T17:27:07.646Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: classic/forge/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:27:07.646Z
Learning: Applies to classic/forge/**/forge/llm/providers/**/*.py : Supported model names include OpenAI (GPT3, GPT3_16k, GPT4, GPT4_32k, GPT4_TURBO, GPT4_O), Anthropic (CLAUDE3_OPUS, CLAUDE3_SONNET, CLAUDE3_HAIKU, CLAUDE3_5_SONNET, CLAUDE3_5_SONNET_v2, CLAUDE3_5_HAIKU, CLAUDE4_SONNET, CLAUDE4_OPUS, CLAUDE4_5_OPUS), and Groq (LLAMA3_8B, LLAMA3_70B, MIXTRAL_8X7B)

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-15T15:30:09.706Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-21T04:35:34.710Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12865
File: autogpt_platform/backend/backend/data/credit.py:1584-1584
Timestamp: 2026-04-21T04:35:34.710Z
Learning: When reviewing this codebase, don’t flag snake_case attribute names (e.g., `subscription_tier`, `stripe_customer_id`, `top_up_config`) on the app-layer Pydantic `User` model as “wrong” field names. These are correct for the app-layer model and are expected to be mapped from the Prisma-layer camelCase fields (e.g., `subscriptionTier`, `stripeCustomerId`) inside methods like `User.from_db()`. Only Prisma-returned/raw objects would use camelCase, but functions like `get_user_by_id(user_id: str)` are expected to return the Pydantic app-layer model.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
🔇 Additional comments (4)
autogpt_platform/backend/backend/data/block_cost_config.py (3)

303-314: Nice explicit documentation of legacy Grok SKUs.

Inlining that these rates are historical and that docs.x.ai no longer lists them prevents future reviewers from flagging the entries as stale without context. Good call retaining them since the models are still API-callable.


1239-1255: Walltime rate bump + honest caveat LGTM.

15 cr/s (~$0.15/s) cleanly covers the FAL Lite tier at 1.5×, and the inline comment explicitly documents that Veo/Seedance tiers still slightly under-bill pending per-call provider_cost from the SDK. Matches the intent already established for this block (walltime is the best available signal until the SDK exposes spend).


763-775: Migration confirmed: provider_cost_type="cost_usd" convention is established and correctly resolved.

The COST_USD handler in executor/utils.py:219 properly checks for this sentinel (if stats.provider_cost_type != "cost_usd" returns 0.0). Multiple blocks already emit this pattern in production (VideoNarration, ClaudeCode, Perplexity, Codex, Firecrawl, etc.), and the billing path is tested in block_usage_cost_test.py:112-114 and billing_reconciliation_test.py:133. UnrealTextToSpeechBlock follows the established convention and mirrors the paired provider_cost_type emission from text_to_speech_block.py:114.

autogpt_platform/backend/backend/blocks/text_to_speech_block.py (1)

108-116: Clean swap to proportional USD-based billing.

len(input_data.text) * 0.000016 matches Unreal Speech's published $16 / 1M char rate, and Python's len() on str returns code points (which is what Unreal meters), so multi-byte UTF-8 characters won't be double-counted. The merge_stats call is still post-call_unreal_speech_api, so failed API calls don't charge the wallet.

The only thing load-bearing across both files is the "cost_usd" string literal matching whatever the COST_USD resolver expects — I've left a verification script on the paired block_cost_config.py change rather than duplicating it here.

…enRouter floor

ReplicateModelBlock takes ANY model ref as input. Flat 10 cr/run
was 10-500x under-billing long video/LLM runs ($1-$50+) and 20x
over-billing tiny SDXL. Block now uses predictions.async_create +
async_wait to read prediction.metrics.predict_time after completion,
emits (predict_time * $0.0014/s) as provider_cost, billed at
COST_USD 150 cr/$. $0.0014/s is the Nvidia L40S mid-tier rate where
most popular public models run.

Also: MISTRAL_LARGE_3 and MISTRAL_NEMO in TOKEN_COST are the safety
floor for OpenRouter-routed calls (ModelMetadata.provider =
'open_router'). Rates now match OpenRouter's pass-through pricing
instead of Mistral-direct's /v1/chat rates, which we never call.
Addresses Sentry bug prediction on MISTRAL_NEMO being 'higher than
actual cost from OpenRouter'.

- ReplicateModelBlock: RUN 10 -> COST_USD 150 cr/$ (dynamic billing)
- ReplicateFluxAdvancedModelBlock: unchanged (bounded to Flux models
  $0.04-$0.08, flat 10 cr stays within 1.25-2.5x margin)
- MISTRAL_LARGE_3: 75/225 -> 300/900 (OpenRouter $2/$6)
- MISTRAL_NEMO: 23/23 -> 5/5 (OpenRouter $0.035/$0.035)

@majdyz majdyz left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@coderabbitai Re: FAL AIVideoGeneratorBlock 3→15 cr/s sign-off — this is intentional. The prior 3 cr/s rate was set based on Lite-tier FAL models at $0.02/s, but in practice most users run Veo/Seedance at $0.25-$0.30/s. At 3 cr/s we were under-billing the common Veo case by ~10x and losing money per render. 15 cr/s ($0.15/s billed at $0.01/credit) covers the Lite tier with 1.5x margin (matches the platform-wide baseline) while still being ~50% under-bill for Veo — acceptable until the block migrates to COST_USD (blocked on FAL SDK not exposing per-call provider_cost). Flagged in the PR description's follow-up section.

@majdyz majdyz changed the title fix(block_cost_config): audit + correct stale LLM + block rates against provider pricing fix(block_cost_config): audit + correct stale LLM/block rates + migrate generic ReplicateModelBlock to COST_USD Apr 24, 2026
…ling path

Adds 7 unit tests for the refactored run_model:
- Uses version= keyword when model_ref has ':' (pinned version)
- Uses model= keyword otherwise (unpinned 'owner/name')
- Emits provider_cost = predict_time * $0.0014/s via merge_stats
- async_wait is awaited before reading metrics
- Skips merge_stats when metrics missing OR predict_time is 0
  (avoids silent wallet-free leak if SDK quirks return empty metrics)
- Sanity-checks _REPLICATE_USD_PER_SEC is in the Replicate hardware
  tier range ($0.0005-$0.002/s)

SDK surface confirmed against installed replicate==* package:
- Predictions.async_create(model=, version=, input=) — matches
- Prediction.metrics is Optional[Dict] — matches
- Prediction.async_wait exists — matches

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
autogpt_platform/backend/backend/data/block_cost_config.py (2)

447-466: ⚠️ Potential issue | 🟡 Minor

OpenRouter COST_USD path relies on provider_cost being emitted — no fallback if x-total-cost is missing.

With cost_amount=150 and cost_type=COST_USD, a pre-flight charge is 0 and the real charge is provider_cost × 150. If OpenRouter ever omits x-total-cost (documented as rare but possible — e.g., some free/promotional models, errors mid-stream) the block will be billed as 0 credits.

For existing COST_USD blocks (Perplexity, ClaudeCode, VideoNarration) you've accepted this tradeoff, and the PR comment explicitly says "provider pricing drift is handled upstream." Just flagging that unlike the prior per-model TOKEN_COST rates, there is no floor here. Consider whether to add a non-zero cost_amount minimum (e.g., via a second TOKENS BlockCost entry that acts as a floor) or keep a lightweight rate-card fallback in the LLM path when x-total-cost is null — the openrouter-cost-reconcile Langfuse event already tracks this via cost_source=="fallback" per your prior learnings.

Not blocking; just make sure the monitoring for resolved_generation_id_count==0 / cost_source=="fallback" stays actionable so a drop in x-total-cost coverage surfaces before it becomes a wallet-drain incident.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/data/block_cost_config.py` around lines 447
- 466, The OpenRouter COST_USD BlockCost (created in the list comprehension that
builds BlockCost(cost_type=BlockCostType.COST_USD, cost_amount=150,
cost_filter={...} for models where MODEL_METADATA[model].provider ==
"open_router")) has no fallback when the x-total-cost header is missing, causing
zero billing; add a lightweight fallback floor by either (A) adding a second
BlockCost entry for the same models with cost_type=BlockCostType.TOKEN_COST (or
a small non-zero COST_USD) that will act as a minimum pre-flight charge, or (B)
reduce reliance on cost_amount=150 by ensuring the LLM billing path uses a
fallback rate-card when x-total-cost is null and emits the
openrouter-cost-reconcile event with cost_source=="fallback" and
resolved_generation_id_count==0; update the BlockCost list creation around
BlockCost and MODEL_METADATA/ MODEL_COST references and ensure
open_router_credentials is used consistently.

417-466: ⚠️ Potential issue | 🔴 Critical

Add ollama provider check to LLM_COST BlockCost list to prevent zero-credit charge fallthrough.

The new provider-grouping split inadvertently omits ollama. Five ollama models are defined in MODEL_METADATA with provider="ollama" and assigned costs in MODEL_COST (lines 141-145: 1 credit each), and are tested as billable (block_usage_cost_test.py line 168). Without an explicit check for MODEL_METADATA[model].provider == "ollama", ollama models will fail all cost_filter matches and silently charge 0 credits—violating the documented invariant at lines 524-525 ("A missing entry here makes the block run for free...even when the upstream provider charges real USD").

Add:

# Ollama Models
+ [
    BlockCost(
        cost_type=BlockCostType.TOKENS,
        cost_filter={
            "model": model,
            "credentials": {
                "id": ollama_credentials.id,
            },
        },
        cost_amount=cost,
    )
    for model, cost in MODEL_COST.items()
    if MODEL_METADATA[model].provider == "ollama"
]

after the groq block (around line 446) and ensure ollama_credentials is initialized above the LLM_COST list (similar to openai_credentials, etc.).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/data/block_cost_config.py` around lines 417
- 466, The LLM_COST construction omitted models with provider "ollama", causing
those models to fall through to zero-cost; add an explicit Ollama Models list
comprehension (same shape as the Groq/OpenAI blocks) that creates
BlockCost(cost_type=BlockCostType.TOKENS, cost_filter={"model": model,
"credentials": {"id": ollama_credentials.id}}, cost_amount=cost) for models
where MODEL_METADATA[model].provider == "ollama", and insert it after the Groq
block; also ensure ollama_credentials is created/initialized above the LLM_COST
list (analogous to openai_credentials, groq_credentials,
open_router_credentials) so the reference exists.
🧹 Nitpick comments (1)
autogpt_platform/backend/backend/blocks/replicate/replicate_block.py (1)

94-99: Test mock bypasses the new billing + status paths.

The test_mock replaces run_model wholesale with a string-returning lambda, so neither merge_stats(provider_cost=...) nor the terminal-status handling is exercised in tests. Given the PR migrates this block from flat RUN to COST_USD billing via prediction.metrics.predict_time, it would be worth adding a dedicated test (or expanding test_mock) that:

  1. Returns a fake Prediction-shaped object with populated metrics.predict_time and asserts merge_stats fires with the expected provider_cost.
  2. Covers a status="failed" fixture (once the fix from the previous comment lands) to lock in the new error behavior.

Not blocking, but the refactor introduces two new invariants (billing path + failure path) that aren't currently test-covered.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@autogpt_platform/backend/backend/blocks/replicate/replicate_block.py` around
lines 94 - 99, The test mock currently replaces run_model with a simple
string-returning lambda and bypasses the new billing and failure handling;
update the test_mock used in tests for replicate_block to return a fake
Prediction-shaped object (include prediction.metrics.predict_time populated) so
that replicate_block.merge_stats is exercised and assert the expected
provider_cost is merged, and add a second test fixture where the fake Prediction
has status="failed" to validate the terminal-status/error handling paths in the
run_model -> replicate block flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@autogpt_platform/backend/backend/blocks/replicate/replicate_block.py`:
- Around line 180-193: After awaiting prediction.async_wait(), check
prediction.status and if it equals "failed" or "canceled" raise an exception
(including prediction.error or prediction.output for context) before doing any
billing or calling extract_result; this ensures failures don't silently proceed
and bill. Update the status reporting code that currently hardcodes "succeeded"
to use prediction.status so the real state is surfaced. Keep billing in
merge_stats(NodeExecutionStats(...)) only after confirming prediction.status
indicates success, and reference prediction.metrics["predict_time"] and
_REPLICATE_USD_PER_SEC as before when computing provider_cost.

---

Outside diff comments:
In `@autogpt_platform/backend/backend/data/block_cost_config.py`:
- Around line 447-466: The OpenRouter COST_USD BlockCost (created in the list
comprehension that builds BlockCost(cost_type=BlockCostType.COST_USD,
cost_amount=150, cost_filter={...} for models where
MODEL_METADATA[model].provider == "open_router")) has no fallback when the
x-total-cost header is missing, causing zero billing; add a lightweight fallback
floor by either (A) adding a second BlockCost entry for the same models with
cost_type=BlockCostType.TOKEN_COST (or a small non-zero COST_USD) that will act
as a minimum pre-flight charge, or (B) reduce reliance on cost_amount=150 by
ensuring the LLM billing path uses a fallback rate-card when x-total-cost is
null and emits the openrouter-cost-reconcile event with cost_source=="fallback"
and resolved_generation_id_count==0; update the BlockCost list creation around
BlockCost and MODEL_METADATA/ MODEL_COST references and ensure
open_router_credentials is used consistently.
- Around line 417-466: The LLM_COST construction omitted models with provider
"ollama", causing those models to fall through to zero-cost; add an explicit
Ollama Models list comprehension (same shape as the Groq/OpenAI blocks) that
creates BlockCost(cost_type=BlockCostType.TOKENS, cost_filter={"model": model,
"credentials": {"id": ollama_credentials.id}}, cost_amount=cost) for models
where MODEL_METADATA[model].provider == "ollama", and insert it after the Groq
block; also ensure ollama_credentials is created/initialized above the LLM_COST
list (analogous to openai_credentials, groq_credentials,
open_router_credentials) so the reference exists.

---

Nitpick comments:
In `@autogpt_platform/backend/backend/blocks/replicate/replicate_block.py`:
- Around line 94-99: The test mock currently replaces run_model with a simple
string-returning lambda and bypasses the new billing and failure handling;
update the test_mock used in tests for replicate_block to return a fake
Prediction-shaped object (include prediction.metrics.predict_time populated) so
that replicate_block.merge_stats is exercised and assert the expected
provider_cost is merged, and add a second test fixture where the fake Prediction
has status="failed" to validate the terminal-status/error handling paths in the
run_model -> replicate block flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8db81f37-3bcf-424f-bc7b-cdc3960183b7

📥 Commits

Reviewing files that changed from the base of the PR and between c3448f5 and 41005d5.

📒 Files selected for processing (2)
  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: check API types
  • GitHub Check: test (3.12)
  • GitHub Check: type-check (3.12)
  • GitHub Check: type-check (3.13)
  • GitHub Check: type-check (3.11)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.13)
  • GitHub Check: lint
  • GitHub Check: Seer Code Review
  • GitHub Check: end-to-end tests
  • GitHub Check: Analyze (python)
  • GitHub Check: Check PR Status
  • GitHub Check: Analyze (typescript)
🧰 Additional context used
📓 Path-based instructions (5)
autogpt_platform/backend/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/**/*.py: Use Python 3.11 (required; managed by Poetry via pyproject.toml) for backend development
Always run 'poetry run format' (Black + isort) before linting in backend development
Always run 'poetry run lint' (ruff) after formatting in backend development

autogpt_platform/backend/**/*.py: Use poetry run ... command for executing Python package dependencies
Use top-level imports only — avoid local/inner imports except for lazy imports of heavy optional dependencies like openpyxl
Use absolute imports with from backend.module import ... for cross-package imports; single-dot relative imports are acceptable for sibling modules within the same package; avoid double-dot relative imports
Do not use duck typing — avoid hasattr/getattr/isinstance for type dispatch; use typed interfaces/unions/protocols instead
Use Pydantic models over dataclass/namedtuple/dict for structured data
Do not use linter suppressors — no # type: ignore, # noqa, # pyright: ignore; fix the type/code instead
Prefer list comprehensions over manual loop-and-append patterns
Use early return with guard clauses first to avoid deep nesting
Use %s for deferred interpolation in debug log statements for efficiency; use f-strings elsewhere for readability (e.g., logger.debug("Processing %s items", count) vs logger.info(f"Processing {count} items"))
Sanitize error paths by using os.path.basename() in error messages to avoid leaking directory structure
Be aware of TOCTOU (Time-Of-Check-Time-Of-Use) issues — avoid check-then-act patterns for file access and credit charging
Use transaction=True for Redis pipelines to ensure atomicity on multi-step operations
Use max(0, value) guards for computed values that should never be negative
Keep files under ~300 lines; if a file grows beyond this, split by responsibility (extract helpers, models, or a sub-module into a new file)
Keep functions under ~40 lines; extract named helpers when a function grows longer
...

Files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/backend/backend/blocks/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

autogpt_platform/backend/backend/blocks/**/*.py: Inherit from 'Block' base class with input/output schemas when adding new blocks in backend
Implement 'run' method with proper error handling in backend blocks
Generate block UUID using 'uuid.uuid4()' when creating new blocks in backend
Write tests alongside block implementation when adding new blocks in backend

autogpt_platform/backend/backend/blocks/**/*.py: For blocks handling files, use store_media_file() with return_format="for_local_processing" when processing with local tools (ffmpeg, MoviePy, PIL)
For blocks handling files, use store_media_file() with return_format="for_external_api" when sending content to external APIs (Replicate, OpenAI)
For blocks returning files, use store_media_file() with return_format="for_block_output" to enable auto-adaptation to execution context (workspace:// in CoPilot, data URI in graphs)
When creating new blocks, inherit from Block base class, define input/output schemas using BlockSchema, implement async run method, and generate unique block ID using uuid.uuid4()

Files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
autogpt_platform/{backend,autogpt_libs}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Format Python code with poetry run format

Files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/backend/backend/data/**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All data access in backend requires user ID checks; verify this for any 'data/*.py' changes

Files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
autogpt_platform/**/data/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

For changes touching data/*.py, validate user ID checks or explain why not needed

Files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
🧠 Learnings (25)
📓 Common learnings
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12566
File: autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts:968-974
Timestamp: 2026-03-26T00:32:06.673Z
Learning: In Significant-Gravitas/AutoGPT, the admin-facing methods in `autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts` (e.g., `addUserCredits`, `getUsersHistory`, `getUserRateLimit`, `resetUserRateLimit`) intentionally follow the legacy `BackendAPI` pattern with manually defined types in `autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts`. Migrating these admin endpoints to the generated OpenAPI hooks (`@/app/api/__generated__/endpoints/`) is a planned separate effort covering all admin endpoints together, not done piecemeal per PR. Do not flag individual admin type additions in `types.ts` as blocking issues.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12284
File: autogpt_platform/frontend/src/app/api/openapi.json:11897-11900
Timestamp: 2026-03-04T23:58:18.476Z
Learning: Repo: Significant-Gravitas/AutoGPT — PR `#12284`
Backend/frontend OpenAPI codegen convention: In backend/api/features/store/model.py, the StoreSubmission and StoreSubmissionAdminView models define submitted_at: datetime | None, changes_summary: str | None, and instructions: str | None with no default. This is intentional to produce “required but nullable” fields in OpenAPI (properties appear in required[] and use anyOf [type, null]). This matches Prisma’s submittedAt DateTime? and changesSummary String?. Do not flag this as a required/nullable mismatch.
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/service.py`, background tasks that persist cost or emit Langfuse backfill (e.g. the cost-reconcile task) must be anchored to `_background_tasks` using `_background_tasks.add(task)` and `task.add_done_callback(_background_tasks.discard)`, mirroring the existing pattern at lines 3063 / 4232 / 4256. This prevents the asyncio task from being garbage-collected before persistence or Langfuse emission completes. Do NOT flag the absence of this anchoring as acceptable in this file. Established in PR `#12889` commit 5ce3d0388.
📚 Learning: 2026-04-23T13:53:29.246Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1064-1111
Timestamp: 2026-04-23T13:53:29.246Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, the E2B sandbox blocks (`ExecuteCodeBlock`, `InstantiateCodeSandboxBlock`, `ExecuteCodeStepBlock`) are intentionally billed per-node-execution walltime (`BlockCostType.SECOND`, `cost_divisor=10`, 1 credit per 10s) using `stats.walltime` from the `async_time_measured` decorator in `manager.py::_on_node_execution`. Idle time between steps is deliberately absorbed by the platform — this makes per-step charges predictable and user-visible. Do NOT flag the absence of sandbox-lifetime billing as a bug. Future migration to raw sandbox uptime billing would require plumbing `provider_cost_type="sandbox_seconds"` from the E2B SDK into `NodeExecutionStats` and switching to `COST_USD`/`SECOND` against that field; until then, walltime-per-execution is the correct and intentional model. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T04:01:32.723Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12876
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:0-0
Timestamp: 2026-04-22T04:01:32.723Z
Learning: In `autogpt_platform/backend/backend/copilot/tools/helpers.py`, the `run_block` copilot path charges ONLY the user credit wallet (via `spend_credits` / `_charge_block_credits`). The microdollar rate-limit counter (`record_cost_usage`) is NOT incremented for `run_block` block executions — the `_record_block_microdollar_cost` helper was explicitly reverted (commit 16ae0f7b5, PR `#12876`) to avoid double-accounting. Do NOT flag missing microdollar recording in `execute_block` as a bug; the credit wallet is the sole billing mechanism for copilot `run_block` calls.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T13:55:24.409Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:1112-1119
Timestamp: 2026-04-23T13:55:24.409Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `AIVideoGeneratorBlock` is intentionally billed by walltime seconds (`BlockCostType.SECOND`, `cost_amount=3`, no `cost_divisor`) using `fal_credentials`. The FAL SDK does not currently expose per-request `provider_cost` or output duration in the response path used; walltime is the best available billing signal. Do NOT flag the absence of `COST_USD` or output-duration billing as a bug. Migration to `BlockCostType.COST_USD` against FAL-reported spend would require an SDK upgrade or a new stats-scraping path and is deferred until the FAL SDK exposes that signal. Established in PR `#12894`.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-02-05T04:11:00.596Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 11796
File: autogpt_platform/backend/backend/blocks/video/concat.py:3-4
Timestamp: 2026-02-05T04:11:00.596Z
Learning: In autogpt_platform/backend/backend/blocks/**/*.py, when creating a new block, generate a UUID once with uuid.uuid4() and hard-code the resulting string as the block's id parameter. Do not call uuid.uuid4() at runtime; IDs must be constant across all imports and runs to ensure stability.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-03-16T16:32:21.686Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:32:21.686Z
Learning: In autogpt_platform/backend/backend/blocks/, the Block base class execute() already wraps run() in a try/except to convert uncaught exceptions into BlockExecutionError/BlockUnknownError. Do not add per-block try/except in individual block run() methods, as this is not the established pattern (e.g., Gmail, Slack, Todoist blocks omit it). Only use explicit try/except within blocks that need to distinguish between success and error yield paths inside a generator (e.g., attachment blocks). This guidance applies to all Python files under autogpt_platform/backend/backend/blocks/ and similar block implementations; avoid duplicating error handling in run() unless a block requires generator-based branching.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: Cost billing via the cost(*costs) decorator is applied at input-evaluation time (before a block’s run() executes). Therefore, mutating input_data inside run() will not change billing. When a block’s billing depends on a field plus URL/sniff-derived signals, treat the explicitly declared billing field (e.g., is_video) as the only billing source—set it correctly before run() (or in the code path that occurs before the decorator evaluates input_data). This should be checked for all blocks under autogpt_platform/backend/backend/blocks/ so billing signals are not mistakenly assumed to update during run().

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-02-26T17:02:22.448Z
Learnt from: Pwuts
Repo: Significant-Gravitas/AutoGPT PR: 12211
File: .pre-commit-config.yaml:160-179
Timestamp: 2026-02-26T17:02:22.448Z
Learning: Keep the pre-commit hook pattern broad for autogpt_platform/backend to ensure OpenAPI schema changes are captured. Do not narrow to backend/api/ alone, since the generated schema depends on Pydantic models across multiple directories (backend/data/, backend/blocks/, backend/copilot/, backend/integrations/, backend/util/). Narrowing could miss schema changes and cause frontend type desynchronization.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-05T15:42:08.207Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12297
File: .claude/skills/backend-check/SKILL.md:14-16
Timestamp: 2026-03-05T15:42:08.207Z
Learning: In Python files under autogpt_platform/backend (recursively), rely on poetry run format to perform formatting (Black + isort) and linting (ruff). Do not run poetry run lint as a separate step after poetry run format, since format already includes linting checks.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: In autogpt_platform/backend/backend/blocks/ (and related blocks under autogpt_platform/backend/backend/blocks/), do not add try/except blocks around a block's run() method for standard error propagation. The block executor framework (backend/executor/manager.py) catches uncaught exceptions from run() and emits them on the 'error' output. Only add explicit try/except blocks when you need to control partial outputs in failure cases (e.g., certain outputs must not be yielded on error, as in attachment blocks). This is the standard pattern across the codebase; apply it broadly to blocks' run() implementations.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-03-16T16:30:23.196Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/pods.py:62-74
Timestamp: 2026-03-16T16:30:23.196Z
Learning: In any Python file under autogpt_platform/backend/backend/blocks, do not add a try/except around run() solely for standard error handling. The block framework’s _execute() in _base.py already catches unhandled exceptions and re-raises as BlockExecutionError or BlockUnknownError. If you yield ("error", message), _execute() raises BlockExecutionError immediately, so the error port will not propagate downstream. Reserve explicit try/except for scenarios where you must control partial output (e.g., attachment blocks that must skip yielding content_base64 on failure).

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-03-16T16:30:11.452Z
Learnt from: Abhi1992002
Repo: Significant-Gravitas/AutoGPT PR: 12417
File: autogpt_platform/backend/backend/blocks/agent_mail/threads.py:80-102
Timestamp: 2026-03-16T16:30:11.452Z
Learning: Do not wrap synchronous AgentMail SDK calls with asyncio.to_thread() in blocks under autogpt_platform/backend/backend/blocks (and across the codebase). The block executor runs node execution in dedicated threads via asyncio.run_coroutine_threadsafe (see manager.py around lines ~745-752 and ~1079). The existing pattern avoids using asyncio.to_thread for SDK calls inside async run() methods, so maintain that approach and do not add to_thread usage in these code paths.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
📚 Learning: 2026-03-16T16:35:40.236Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12440
File: autogpt_platform/backend/backend/api/features/workflow_import.py:54-63
Timestamp: 2026-03-16T16:35:40.236Z
Learning: Avoid using the word 'competitor' in public-facing identifiers and text. Use neutral naming for API paths, model names, function names, and UI text. Examples: rename 'CompetitorFormat' to 'SourcePlatform', 'convert_competitor_workflow' to 'convert_workflow', '/competitor-workflow' to '/workflow'. Apply this guideline to files under autogpt_platform/backend and autogpt_platform/frontend.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-31T15:37:38.626Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12623
File: autogpt_platform/backend/backend/copilot/tools/agent_generator/fixer.py:37-47
Timestamp: 2026-03-31T15:37:38.626Z
Learning: When validating/constructing Anthropic API model IDs in Significant-Gravitas/AutoGPT, allow the hyphen-separated Claude Opus 4.6 model ID `claude-opus-4-6` (it corresponds to `LlmModel.CLAUDE_4_6_OPUS` in `autogpt_platform/backend/backend/blocks/llm.py`). Do NOT require the dot-separated form in Anthropic contexts. Only OpenRouter routing variants should use the dot separator (e.g., `anthropic/claude-opus-4.6`); `claude-opus-4-6` should be treated as correct when passed to Anthropic, and flagged only if it’s used in the OpenRouter path where the dot form is expected.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-15T02:43:36.890Z
Learnt from: ntindle
Repo: Significant-Gravitas/AutoGPT PR: 12780
File: autogpt_platform/backend/backend/copilot/tools/workspace_files.py:0-0
Timestamp: 2026-04-15T02:43:36.890Z
Learning: When reviewing Python exception handlers, do not flag `isinstance(e, X)` checks as dead/unreachable if the caught exception `X` is a subclass of the exception type being handled. For example, if `X` (e.g., `VirusScanError`) inherits from `ValueError` (directly or via an intermediate class) and it can be raised within an `except ValueError:` block, then `isinstance(e, X)` inside that handler is reachable and should not be treated as dead code.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:04.431Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/config.py:0-0
Timestamp: 2026-04-22T11:46:04.431Z
Learning: Do not flag the Claude Sonnet 4.6 model ID as incorrect when it uses the project’s established hyphenated convention: `anthropic/claude-sonnet-4-6`. This hyphen form is the intentional, production convention and should be treated as valid (including in files like llm.py, blocks tests, reasoning.py, `_is_anthropic_model` tests, and config defaults). Note that OpenRouter also accepts the dot variant `anthropic/claude-sonnet-4.6`, so either form may be tolerated, but `anthropic/claude-sonnet-4-6` should be considered the standard to match project usage.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-22T11:46:12.892Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12881
File: autogpt_platform/backend/backend/copilot/baseline/service.py:322-332
Timestamp: 2026-04-22T11:46:12.892Z
Learning: In this codebase (Significant-Gravitas/AutoGPT), OpenRouter-routed Anthropic model IDs should use the hyphen-separated convention (e.g., `anthropic/claude-sonnet-4-6`, `anthropic/claude-opus-4-6`). Although OpenRouter may accept both hyphen and dot variants, treat the hyphen-separated form as the intended, correct codebase-wide convention and do not flag it as an error. Only flag the dot-separated variant (e.g., `anthropic/claude-sonnet-4.6`) as incorrect when reviewing/validating model ID strings for OpenRouter-routed Anthropic models.

Applied to files:

  • autogpt_platform/backend/backend/blocks/replicate/replicate_block.py
  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T13:53:40.315Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12894
File: autogpt_platform/backend/backend/data/block_cost_config.py:271-277
Timestamp: 2026-04-23T13:53:40.315Z
Learning: In `autogpt_platform/backend/backend/data/block_cost_config.py`, `compute_token_credits()` intentionally returns `MODEL_COST[model]` (the flat tier) on pre-flight (when `stats is None`) for the `TOKENS` billing path. Returning 0 pre-flight would allow a zero-balance user to bypass the credit gate and trigger an LLM call, with the insufficient-balance error only surfacing post-flight (a billing leak). The overcharge concern (actual token cost < MODEL_COST estimate) is handled by `_charge_reconciled_usage_sync` in `autogpt_platform/backend/backend/executor/billing.py`, which issues a negative-delta refund via `spend_credits(cost=negative)` when real usage falls below the pre-flight estimate. Do NOT flag the MODEL_COST pre-flight floor in this function as an overcharge bug; the refund path covers it.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T12:55:26.122Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12893
File: autogpt_platform/backend/backend/blocks/ayrshare/post_to_tiktok.py:24-24
Timestamp: 2026-04-23T12:55:26.122Z
Learning: In `Significant-Gravitas/AutoGPT`, the `cost(*costs)` decorator in `autogpt_platform/backend/backend/sdk/cost_integration.py` evaluates `input_data` **at input-evaluation time, before `run()` executes**. Mutating fields of `input_data` inside a block's `run()` method (e.g., `input_data.is_video = has_video`) has **no effect on billing** because the cost filter has already been applied. For blocks that derive a computed boolean from both an explicit field and URL-sniffing (like `has_video` in `PostToTikTokBlock`), the explicit field (e.g., `is_video`) is the sole billing signal; callers must set it correctly. This applies to all blocks under `autogpt_platform/backend/backend/blocks/`.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-23T00:07:27.117Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-04-23T00:07:27.117Z
Learning: In `autogpt_platform/backend/backend/copilot/sdk/openrouter_cost.py`, the `openrouter-cost-reconcile` Langfuse event carries `cost_source` ("openrouter" for authoritative OpenRouter-resolved cost, "fallback" for rate-card fallback) and `resolved_generation_id_count` alongside the reconciled cost and token/model/provider metadata. This lets operators distinguish authoritative reconciliations from fallbacks in Langfuse. Established in PR `#12889` commit 5ce3d0388.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-09T10:50:43.907Z
Learnt from: Bentlybro
Repo: Significant-Gravitas/AutoGPT PR: 0
File: :0-0
Timestamp: 2026-03-09T10:50:43.907Z
Learning: Repo: Significant-Gravitas/AutoGPT — File: autogpt_platform/backend/backend/blocks/llm.py
For xAI Grok models accessed via OpenRouter, the API returns `null` for `max_completion_tokens`. The convention in this codebase is to use the model's context window size as the `max_output_tokens` value in ModelMetadata. For example, Grok 3 uses 131072 (128k) and Grok 4 uses 262144 (256k). Do not flag these as incorrect max output token values.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-13T15:49:44.961Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/rate_limit.py:0-0
Timestamp: 2026-03-13T15:49:44.961Z
Learning: In `autogpt_platform/backend/backend/copilot/rate_limit.py`, the original per-session token window (with a TTL-based reset) was replaced with fixed daily and weekly windows. `resets_at` is now derived from `_daily_reset_time()` (midnight UTC) and `_weekly_reset_time()` (next Monday 00:00 UTC) — deterministic fixed-boundary calculations that require no Redis TTL introspection.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-03-15T15:30:09.706Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12385
File: autogpt_platform/backend/backend/copilot/tools/helpers.py:149-185
Timestamp: 2026-03-15T15:30:09.706Z
Learning: In autogpt_platform/backend/backend/copilot/tools/helpers.py, within execute_block, when InsufficientBalanceError occurs after post-execution credit charging (concurrent balance drain after pre-check passed), this is treated as a non-fatal billing leak: log at ERROR level with structured JSON fields `{"billing_leak": True, "user_id": ..., "cost": ...}` for monitoring/alerting, then return BlockOutputResponse normally. Discarding the output would worsen UX since the block already executed with potential side effects. Reuse the credit_model obtained during the pre-execution balance check (guarded by `if cost > 0 and credit_model:`) for the post-execution charge; do not perform a second get_user_credit_model call.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-08T17:27:07.646Z
Learnt from: CR
Repo: Significant-Gravitas/AutoGPT PR: 0
File: classic/forge/CLAUDE.md:0-0
Timestamp: 2026-04-08T17:27:07.646Z
Learning: Applies to classic/forge/**/forge/llm/providers/**/*.py : Supported model names include OpenAI (GPT3, GPT3_16k, GPT4, GPT4_32k, GPT4_TURBO, GPT4_O), Anthropic (CLAUDE3_OPUS, CLAUDE3_SONNET, CLAUDE3_HAIKU, CLAUDE3_5_SONNET, CLAUDE3_5_SONNET_v2, CLAUDE3_5_HAIKU, CLAUDE4_SONNET, CLAUDE4_OPUS, CLAUDE4_5_OPUS), and Groq (LLAMA3_8B, LLAMA3_70B, MIXTRAL_8X7B)

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
📚 Learning: 2026-04-21T04:35:34.710Z
Learnt from: majdyz
Repo: Significant-Gravitas/AutoGPT PR: 12865
File: autogpt_platform/backend/backend/data/credit.py:1584-1584
Timestamp: 2026-04-21T04:35:34.710Z
Learning: When reviewing this codebase, don’t flag snake_case attribute names (e.g., `subscription_tier`, `stripe_customer_id`, `top_up_config`) on the app-layer Pydantic `User` model as “wrong” field names. These are correct for the app-layer model and are expected to be mapped from the Prisma-layer camelCase fields (e.g., `subscriptionTier`, `stripeCustomerId`) inside methods like `User.from_db()`. Only Prisma-returned/raw objects would use camelCase, but functions like `get_user_by_id(user_id: str)` are expected to return the Pydantic app-layer model.

Applied to files:

  • autogpt_platform/backend/backend/data/block_cost_config.py
🔇 Additional comments (3)
autogpt_platform/backend/backend/data/block_cost_config.py (2)

280-354: Token rate recalibration checks out.

Spot-checked the updated entries against the inline provider rates:

  • GPT5 / GPT5_1 @ 188/1500 = $1.25/$10 × 150 cr/$ ✓
  • DEEPSEEK_CHAT / R1_0528 @ 21/42 = $0.14/$0.28 × 150 ✓
  • KIMI_K2_5 @ 66/300 = $0.44/$2.00 × 150 ✓
  • KIMI_K2_6 @ 112/698 = $0.7448/$4.655 × 150 ✓ (698.25 → 698 floors, not ceils — trivial)
  • META_LLAMA_4_MAVERICK @ 75/116 = $0.50/$0.77 × 150 ✓
  • MISTRAL_NEMO @ 5/5 ≈ $0.03/$0.03 × 150 ✓

Note: the comment at lines 320–324 claims TOKEN_COST is a safety floor "when OpenRouter fails to return x-total-cost" for Mistral models, but since the OpenRouter group in LLM_COST only emits COST_USD BlockCosts (not TOKENS), the Mistral TOKEN_COST entries aren't actually consulted at billing time for provider=="open_router" models. Harmless (the entries are dormant data), just inaccurate documentation.


681-701: ReplicateModelBlock pricing change is sound; see the follow-up on the block itself.

The $0.0014/s L40S mid-tier assumption with 1.5× margin is a reasonable interim; the follow-up ticket for generic Replicate migration noted in the PR description is the right resolution path. The actual billing correctness depends on prediction.metrics.predict_time being populated — see separate comment on replicate_block.py run_model regarding failed-prediction handling which affects this billing path.

autogpt_platform/backend/backend/blocks/replicate/replicate_block.py (1)

30-35: L40S rate under-bills cheap L4 models noticeably; leaving as-is per PR scope is fine.

Cheap L4 models run at ~$0.000275/s — the L40S rate of $0.001400/s over-bills those by ~5×, which the PR comment acknowledges. The inverse (A100 heavy models) under-bills marginally. Given the PR explicitly defers proper per-hardware resolution to the follow-up refactor ("separate PR"), this is an acceptable interim. Just noting the constant should be revisited alongside that refactor so it doesn't silently calcify.

…lling

async_wait() returns normally regardless of prediction terminal status
— only async_run raises ModelError on 'failed'. Without an explicit
status check we'd bill partial compute time on a failed run, yield
empty output via extract_result(None), and hardcode 'status: succeeded'
hiding the failure.

Check prediction.status after async_wait and raise before merge_stats
so failures surface as exceptions (caught by run() and re-raised as
BlockExecutionError). Also guard against output=None on succeeded
predictions (type-narrowing for extract_result).

Addresses CodeRabbit critical on #12912.
…ates

Three tests on CI were still asserting old values:
- UnrealTextToSpeech tests assumed provider_cost=len(text) with type
  'characters'. Updated to assert provider_cost=len(text)*$0.000016
  with type 'cost_usd' per the text_to_speech_block migration.
- ZeroBounce ValidateEmailsBlock cost_amount test assumed 250, now 150
  after the margin alignment in this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant