Skip to content

fix: add OCR request pricing support#2864

Merged
akshaydeo merged 1 commit intomainfrom
04-20-fix_add_support_for_pricing_in_ocr_requests
Apr 20, 2026
Merged

fix: add OCR request pricing support#2864
akshaydeo merged 1 commit intomainfrom
04-20-fix_add_support_for_pricing_in_ocr_requests

Conversation

@Pratham-Mishra04
Copy link
Copy Markdown
Collaborator

Summary

Adds pricing support for OCR requests, enabling cost calculation based on the number of pages processed and whether document annotation is present.

Changes

  • Added ocr_cost_per_page and annotation_cost_per_page fields to the TableModelPricing table and PricingOptions struct
  • Added a database migration (add_ocr_pricing_columns) to introduce the two new pricing columns with rollback support
  • Implemented computeOCRCost which bills per page processed, adding annotation cost on top when a document annotation is present
  • Wired OCRRequest into the pricing lookup, cost extraction, and cost calculation pipeline
  • Mapped OCRRequest to the "ocr" normalized request type key for pricing catalog lookups
  • Propagated the new OCR pricing fields through the conversion helpers between PricingEntry and TableModelPricing

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

Send an OCR request through a model that has ocr_cost_per_page and/or annotation_cost_per_page configured. Verify that the resulting cost reflects the number of pages processed, and that annotation cost is included when DocumentAnnotation is non-empty.

go test ./...

Ensure the migration runs cleanly on a fresh and existing database, and that rollback drops the two columns without error.

Breaking changes

  • Yes
  • No

Related issues

Companion to the OCR request logging support added previously.

Security considerations

No new auth, secrets, or PII handling introduced. Pricing fields are internal configuration values.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 534760c4-31c9-44af-9c85-741a1b1163b1

📥 Commits

Reviewing files that changed from the base of the PR and between bd0b53b and ffae11d.

📒 Files selected for processing (11)
  • core/schemas/bifrost.go
  • framework/changelog.md
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • ui/lib/types/governance.ts
✅ Files skipped from review due to trivial changes (3)
  • framework/changelog.md
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • core/schemas/bifrost.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/configstore/migrations.go

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added OCR and annotation per‑page pricing to custom pricing and UI selectors; OCR appears as its own request type/category.
    • Pricing now includes OCR usage when calculating costs.
  • Bug Fixes

    • OCR responses now have their extra metadata populated correctly.
  • Chores

    • Database migration added to store OCR/annotation pricing columns; changelogs updated to note OCR pricing support.

Walkthrough

This change adds OCR request pricing support: new DB columns and migration, pricing model and calculation updates, response extra-field population for OCR, UI fields and types for OCR pricing overrides, and changelog entries across framework and transports.

Changes

Cohort / File(s) Summary
Database Schema
framework/configstore/migrations.go, framework/configstore/tables/modelpricing.go
Added migration add_ocr_pricing_columns to add/drop ocr_cost_per_page and annotation_cost_per_page. Added OCRCostPerPage and AnnotationCostPerPage fields to TableModelPricing.
Pricing Calculation & Model
framework/modelcatalog/pricing.go, framework/modelcatalog/pricing_overrides.go, framework/modelcatalog/utils.go
Added OCR fields to PricingOptions, extended normalization to map OCR requests, added computeOCRCost and integrated OCR usage into cost extraction and base cost calculation. patchPricing now applies OCR override fields.
Response Handling
core/schemas/bifrost.go
BifrostResponse.PopulateExtraFields now handles OCRResponse, populating ExtraFields (requestType, provider, originalModelRequested, resolvedModel).
Frontend UI
ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx, ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
Added "ocr" pricing group and request-type grouping; introduced ocr_cost_per_page and annotation_cost_per_page fields in pricing UI and request-type selection.
Frontend Types
ui/lib/types/governance.ts
Extended PricingOverridePatch to include optional ocr_cost_per_page and annotation_cost_per_page numeric fields.
Changelog
framework/changelog.md, transports/changelog.md
Added changelog entries noting support for OCR request pricing.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Client/UI
    participant API as Server/API
    participant Pricing as PricingService
    participant DB as Database
    UI->>API: create/update pricing override (ocr fields)
    API->>DB: persist pricing row (ocr_cost_per_page, annotation_cost_per_page)
    Note over DB: Migration may add columns if absent
    UI->>API: submit OCR request/result
    API->>Pricing: extract usage (pages, annotated)
    Pricing->>DB: read model pricing (including ocr columns)
    Pricing->>API: return computed cost
    API->>UI: return cost & populated OCR extra fields
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through code with eager paws,
Pages priced without a pause.
OCR counts and notes the rest,
Annotations get their best!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly and concisely summarizes the main change: adding OCR request pricing support to the codebase.
Description check ✅ Passed The pull request description provides a comprehensive overview covering summary, changes, type of change, affected areas, testing instructions, breaking changes, and security considerations, with all major template sections addressed.
Docstring Coverage ✅ Passed Docstring coverage is 91.67% which is sufficient. The required threshold is 80.00%.

✏️ 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 04-20-fix_add_support_for_pricing_in_ocr_requests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 20, 2026

Confidence Score: 5/5

Safe to merge — all changes follow established patterns, no data-integrity or security concerns.

Only a single P2 style finding (zero-page guard inconsistency that produces correct results). All other code is consistent with the existing pricing infrastructure, the migration is idempotent with proper rollback, and the UI types align with the backend.

No files require special attention.

Important Files Changed

Filename Overview
framework/modelcatalog/pricing.go Core OCR pricing logic: adds ocrProcessedPages/ocrIsAnnotated to costInput, OCR case in extractCostInput (with Pages-length fallback), early-exit guard updated, and new computeOCRCost function. Logic is correct and consistent with other request types.
framework/configstore/migrations.go Adds migrationAddOCRPricingColumns migration with idempotent HasColumn guards and rollback support. Follows the existing migration pattern exactly.
framework/configstore/tables/modelpricing.go Adds OCRCostPerPage and AnnotationCostPerPage nullable float64 fields with correct gorm tags and column names matching the migration.
framework/modelcatalog/utils.go Maps OCRRequest to "ocr" in normalizeRequestType and propagates OCR pricing fields in both conversion helpers (PricingEntry ↔ TableModelPricing).
framework/modelcatalog/pricing_overrides.go Adds OCRCostPerPage and AnnotationCostPerPage to the patchPricing field list. Follows the existing patch pattern.
ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx Adds OCR to REQUEST_TYPE_GROUPS and two new PRICING_FIELDS entries (ocr_cost_per_page, annotation_cost_per_page) correctly grouped under "ocr".
ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx Extends GroupKey union type with "ocr", adds OCR to PRICING_GROUPS, and maps "ocr" request type to "ocr" category in REQUEST_TYPE_TO_CATEGORY.
ui/lib/types/governance.ts Adds ocr_cost_per_page and annotation_cost_per_page optional fields to PricingOverridePatch interface, consistent with the Go backend struct.
core/schemas/bifrost.go Adds OCRRequest to the list of request types considered in the pricing entry lookup.

Reviews (7): Last reviewed commit: "fix: add support for pricing in OCR requ..." | Re-trigger Greptile

Comment thread framework/modelcatalog/pricing.go Outdated
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_per_user_oauth_in_codemode_fixes branch from 21c2071 to 6f43215 Compare April 20, 2026 14:27
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from 0888812 to 1d7f479 Compare April 20, 2026 14:27
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@framework/modelcatalog/pricing.go`:
- Around line 403-404: The code currently sets isAnnotated using
result.OCRResponse.DocumentAnnotation != nil &&
*result.OCRResponse.DocumentAnnotation != "" which treats an empty-string
pointer as unannotated; change the check to only test pointer presence so any
non-nil DocumentAnnotation counts as annotated: set isAnnotated :=
result.OCRResponse.DocumentAnnotation != nil and keep assigning
input.ocrIsAnnotated = &isAnnotated (refer to
result.OCRResponse.DocumentAnnotation, isAnnotated, input.ocrIsAnnotated).
🪄 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: 1968951b-4e1a-425b-94f6-0043bd9731aa

📥 Commits

Reviewing files that changed from the base of the PR and between 6f43215 and 1d7f479.

📒 Files selected for processing (11)
  • core/schemas/bifrost.go
  • framework/changelog.md
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • ui/lib/types/governance.ts

Comment thread framework/modelcatalog/pricing.go
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_per_user_oauth_in_codemode_fixes branch from 6f43215 to 94b3fc9 Compare April 20, 2026 15:56
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from 1d7f479 to 6335f97 Compare April 20, 2026 15:56
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
framework/modelcatalog/pricing.go (1)

403-404: ⚠️ Potential issue | 🟠 Major

Bill annotation by presence, not by non-empty annotation text.

At Line 403, annotation billing is skipped when DocumentAnnotation is a non-nil pointer to "". That undercharges OCR requests where annotation is present but empty. Downstream effect: Line 811 won’t add annotation cost in those cases.

💡 Proposed fix
-		isAnnotated := result.OCRResponse.DocumentAnnotation != nil && *result.OCRResponse.DocumentAnnotation != ""
+		isAnnotated := result.OCRResponse.DocumentAnnotation != nil
 		input.ocrIsAnnotated = &isAnnotated
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/modelcatalog/pricing.go` around lines 403 - 404, The code
determines annotation presence by checking DocumentAnnotation != nil &&
*DocumentAnnotation != "", which treats a present-but-empty annotation as
absent; change the logic in the block that sets input.ocrIsAnnotated (where
result.OCRResponse.DocumentAnnotation is read) to mark annotation present
whenever DocumentAnnotation is non-nil (e.g., isAnnotated :=
result.OCRResponse.DocumentAnnotation != nil) so downstream billing (the logic
that adds annotation cost based on input.ocrIsAnnotated) correctly charges for
annotated documents even when the annotation text is empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@framework/modelcatalog/pricing.go`:
- Around line 403-404: The code determines annotation presence by checking
DocumentAnnotation != nil && *DocumentAnnotation != "", which treats a
present-but-empty annotation as absent; change the logic in the block that sets
input.ocrIsAnnotated (where result.OCRResponse.DocumentAnnotation is read) to
mark annotation present whenever DocumentAnnotation is non-nil (e.g.,
isAnnotated := result.OCRResponse.DocumentAnnotation != nil) so downstream
billing (the logic that adds annotation cost based on input.ocrIsAnnotated)
correctly charges for annotated documents even when the annotation text is
empty.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b8f765e3-94ec-4bde-91f3-3054f4da2149

📥 Commits

Reviewing files that changed from the base of the PR and between 1d7f479 and 6335f97.

📒 Files selected for processing (11)
  • core/schemas/bifrost.go
  • framework/changelog.md
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • ui/lib/types/governance.ts
✅ Files skipped from review due to trivial changes (3)
  • framework/changelog.md
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • framework/modelcatalog/pricing_overrides.go
  • ui/lib/types/governance.ts
  • framework/configstore/tables/modelpricing.go
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • framework/modelcatalog/utils.go
  • core/schemas/bifrost.go

@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from 6335f97 to b9107b1 Compare April 20, 2026 17:37
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_per_user_oauth_in_codemode_fixes branch from 94b3fc9 to 6c8788b Compare April 20, 2026 17:37
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/mcp/utils/utils.go`:
- Around line 66-70: BuildPerUserOAuthHeaders can panic when headers is nil
because headers.Clone() returns nil; add a nil-safety guard by checking if
headers == nil (or if cloned h == nil) and initialize h = make(http.Header)
before calling h.Set("Authorization", "Bearer "+accessToken"), then return h;
reference the BuildPerUserOAuthHeaders function and the headers.Clone()/h.Set
usage when making the change.
🪄 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: 8cdcfad1-44f1-4946-8f06-2e5746b08b22

📥 Commits

Reviewing files that changed from the base of the PR and between 6335f97 and b9107b1.

📒 Files selected for processing (14)
  • core/mcp/codemode/starlark/executecode.go
  • core/mcp/toolmanager.go
  • core/mcp/utils/utils.go
  • core/schemas/bifrost.go
  • framework/changelog.md
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • ui/lib/types/governance.ts
✅ Files skipped from review due to trivial changes (3)
  • framework/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • transports/changelog.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • framework/modelcatalog/utils.go
  • ui/lib/types/governance.ts
  • framework/modelcatalog/pricing.go
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go

Comment thread core/mcp/utils/utils.go
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from b9107b1 to 8f2c722 Compare April 20, 2026 17:43
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_per_user_oauth_in_codemode_fixes branch from 6c8788b to 7992fbe Compare April 20, 2026 17:43
coderabbitai[bot]
coderabbitai Bot previously approved these changes Apr 20, 2026
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_per_user_oauth_in_codemode_fixes branch from 7992fbe to cf03677 Compare April 20, 2026 18:11
@Pratham-Mishra04 Pratham-Mishra04 force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from 8f2c722 to bd0b53b Compare April 20, 2026 18:11
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
framework/modelcatalog/pricing.go (1)

397-404: ⚠️ Potential issue | 🟠 Major

Bill annotation by presence, not by non-empty string content.

At Line 403, requiring *DocumentAnnotation != "" can skip annotation charges when annotation is present but empty-string encoded, causing underbilling.

💡 Proposed fix
-		isAnnotated := result.OCRResponse.DocumentAnnotation != nil && *result.OCRResponse.DocumentAnnotation != ""
+		isAnnotated := result.OCRResponse.DocumentAnnotation != nil
 		input.ocrIsAnnotated = &isAnnotated
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@framework/modelcatalog/pricing.go` around lines 397 - 404, The code currently
sets isAnnotated by checking result.OCRResponse.DocumentAnnotation != nil &&
*result.OCRResponse.DocumentAnnotation != "" which can miss cases where an
annotation exists but is an empty string; change the check to only test presence
(e.g., result.OCRResponse.DocumentAnnotation != nil) and assign that boolean to
input.ocrIsAnnotated so annotation billing is based on the existence of
DocumentAnnotation rather than its non-empty content (referencing
result.OCRResponse.DocumentAnnotation and input.ocrIsAnnotated).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@framework/modelcatalog/pricing.go`:
- Around line 397-404: The code currently sets isAnnotated by checking
result.OCRResponse.DocumentAnnotation != nil &&
*result.OCRResponse.DocumentAnnotation != "" which can miss cases where an
annotation exists but is an empty string; change the check to only test presence
(e.g., result.OCRResponse.DocumentAnnotation != nil) and assign that boolean to
input.ocrIsAnnotated so annotation billing is based on the existence of
DocumentAnnotation rather than its non-empty content (referencing
result.OCRResponse.DocumentAnnotation and input.ocrIsAnnotated).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 724fb345-11a9-4874-824c-9bc5a84a3f23

📥 Commits

Reviewing files that changed from the base of the PR and between b9107b1 and bd0b53b.

📒 Files selected for processing (11)
  • core/schemas/bifrost.go
  • framework/changelog.md
  • framework/configstore/migrations.go
  • framework/configstore/tables/modelpricing.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • transports/changelog.md
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • ui/app/workspace/custom-pricing/overrides/pricingOverrideSheet.tsx
  • ui/lib/types/governance.ts
✅ Files skipped from review due to trivial changes (2)
  • framework/changelog.md
  • transports/changelog.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • ui/app/workspace/custom-pricing/overrides/pricingFieldSelector.tsx
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/utils.go
  • framework/configstore/migrations.go

Copy link
Copy Markdown
Contributor

akshaydeo commented Apr 20, 2026

Merge activity

  • Apr 20, 6:20 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 20, 6:27 PM UTC: Graphite rebased this pull request as part of a merge.
  • Apr 20, 6:28 PM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo akshaydeo changed the base branch from 04-20-fix_per_user_oauth_in_codemode_fixes to graphite-base/2864 April 20, 2026 18:25
@akshaydeo akshaydeo changed the base branch from graphite-base/2864 to main April 20, 2026 18:25
@akshaydeo akshaydeo dismissed coderabbitai[bot]’s stale review April 20, 2026 18:25

The base branch was changed.

@akshaydeo akshaydeo force-pushed the 04-20-fix_add_support_for_pricing_in_ocr_requests branch from bd0b53b to ffae11d Compare April 20, 2026 18:26
@akshaydeo akshaydeo merged commit e81439b into main Apr 20, 2026
11 of 17 checks passed
@akshaydeo akshaydeo deleted the 04-20-fix_add_support_for_pricing_in_ocr_requests branch April 20, 2026 18:28
dominictayloruk pushed a commit to dominictayloruk/bifrost that referenced this pull request Apr 21, 2026
## Summary

Adds pricing support for OCR requests, enabling cost calculation based on the number of pages processed and whether document annotation is present.

## Changes

- Added `ocr_cost_per_page` and `annotation_cost_per_page` fields to the `TableModelPricing` table and `PricingOptions` struct
- Added a database migration (`add_ocr_pricing_columns`) to introduce the two new pricing columns with rollback support
- Implemented `computeOCRCost` which bills per page processed, adding annotation cost on top when a document annotation is present
- Wired `OCRRequest` into the pricing lookup, cost extraction, and cost calculation pipeline
- Mapped `OCRRequest` to the `"ocr"` normalized request type key for pricing catalog lookups
- Propagated the new OCR pricing fields through the conversion helpers between `PricingEntry` and `TableModelPricing`

## Type of change

- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [x] Core (Go)
- [x] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [ ] UI (React)
- [ ] Docs

## How to test

Send an OCR request through a model that has `ocr_cost_per_page` and/or `annotation_cost_per_page` configured. Verify that the resulting cost reflects the number of pages processed, and that annotation cost is included when `DocumentAnnotation` is non-empty.

```sh
go test ./...
```

Ensure the migration runs cleanly on a fresh and existing database, and that rollback drops the two columns without error.

## Breaking changes

- [ ] Yes
- [x] No

## Related issues

Companion to the OCR request logging support added previously.

## Security considerations

No new auth, secrets, or PII handling introduced. Pricing fields are internal configuration values.

## Checklist

- [ ] I read `docs/contributing/README.md` and followed the guidelines
- [ ] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [ ] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants