Skip to content

feat: modelcatalog main composer added - #4192

Closed
Pratham-Mishra04 wants to merge 1 commit into
graphite-base/4192from
feat_modelcatalog_main_composer_added
Closed

feat: modelcatalog main composer added#4192
Pratham-Mishra04 wants to merge 1 commit into
graphite-base/4192from
feat_modelcatalog_main_composer_added

Conversation

@Pratham-Mishra04

Copy link
Copy Markdown
Collaborator

Summary

Briefly explain the purpose of this PR and the problem it solves.

Changes

  • What was changed and why
  • Any notable design decisions or trade-offs

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

Describe the steps to validate this change. Include commands and expected outcomes.

# Core/Transports
go version
go test ./...

# UI
cd ui
pnpm i || npm i
pnpm test || npm test
pnpm build || npm run build

If adding new configs or environment variables, document them here.

Screenshots/Recordings

If UI changes, add before/after screenshots or short clips.

Breaking changes

  • Yes
  • No

If yes, describe impact and migration instructions.

Related issues

Link related issues and discussions. Example: Closes #123

Security considerations

Note any security implications (auth, secrets, PII, sandboxing, etc.).

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

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@Pratham-Mishra04, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 59 minutes and 10 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: db64cf3d-88c6-43ab-9e19-302b0cafc990

📥 Commits

Reviewing files that changed from the base of the PR and between 022b5b1 and 0947354.

📒 Files selected for processing (20)
  • core/schemas/images.go
  • framework/modelcatalog/capabilities_test.go
  • framework/modelcatalog/config.go
  • framework/modelcatalog/datasheet/cost.go
  • framework/modelcatalog/datasheet/params.go
  • framework/modelcatalog/datasheet/store.go
  • framework/modelcatalog/datasheet/sync.go
  • framework/modelcatalog/datasheet/types.go
  • framework/modelcatalog/main.go
  • framework/modelcatalog/main_test.go
  • framework/modelcatalog/models.go
  • framework/modelcatalog/pool.go
  • framework/modelcatalog/pricing.go
  • framework/modelcatalog/pricing_overrides.go
  • framework/modelcatalog/pricing_overrides_test.go
  • framework/modelcatalog/pricing_test.go
  • framework/modelcatalog/refine_test.go
  • framework/modelcatalog/shims.go
  • framework/modelcatalog/sync.go
  • framework/modelcatalog/utils.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat_modelcatalog_main_composer_added

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

@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.

Pratham-Mishra04 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 3/5

Safe to merge after fixing the URL snapshot inconsistency in loadPricingFromURL — the rest of the refactor is structurally sound.

The URL snapshotting flaw in loadPricingFromURL is a concrete defect: the function validates rawURL but then hands s.URL() (a fresh live read) to the HTTP client. A concurrent UpdateSyncConfig call between those two lines would cause a request to go to an unvalidated URL. The companion loadModelParametersFromURL does this correctly, making the inconsistency easy to spot and fix. The Init goroutine-drain gap on error paths is real but bounded — the goroutines self-terminate via context cancellation and the window is only open when Init itself fails.

framework/modelcatalog/datasheet/sync.go (URL snapshot/request mismatch) and framework/modelcatalog/main.go (goroutine drain on error paths).

Important Files Changed

Filename Overview
framework/modelcatalog/main.go New composer wiring Init, sync ticker, distributed lock, and Cleanup. Background startup goroutines tracked by mc.wg are not waited on in error paths.
framework/modelcatalog/datasheet/sync.go URL→DB→memory sync logic. loadPricingFromURL validates rawURL but makes the HTTP request to s.URL() (re-read), bypassing the snapshot; loadModelParametersFromURL correctly uses rawURL.
framework/modelcatalog/datasheet/store.go Store struct with dual-mutex design (mu for pricing, syncCfgMu for URL/interval). Read paths take defensive copies; write paths hold write locks and call rebuildDatasheetViewUnsafe. Looks correct.
framework/modelcatalog/datasheet/cost.go Cost calculation with per-request-type dispatch, tiered pricing, and cache billing. DeepCopy used for ImageUsage mutation safety. Logic matches pricing types well.
framework/modelcatalog/datasheet/params.go Loads/syncs model parameters from DB or URL; applyModelParameters uses a full-swap under mu.Lock for atomic view transitions. URL snapshot correctly used for HTTP request here.
core/schemas/images.go Added DeepCopy to ImageUsage for safe cost calculation without mutating the caller's response. Correct nil-safe implementation.

Reviews (1): Last reviewed commit: "feat: modelcatalog main composer added" | Re-trigger Greptile

return nil, fmt.Errorf("pricing URL validation failed: %w", err)
}
client := &http.Client{Timeout: DefaultPricingTimeout}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, s.URL(), nil)

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.

P1 The HTTP request in loadPricingFromURL is built with s.URL() — a fresh lock-guarded read — instead of the already-snapshotted rawURL. The snapshot was taken precisely to avoid TOCTOU: rawURL is validated by bifrost.ValidateExternalURL, but if UpdateSyncConfig swaps the URL between that call and the http.NewRequestWithContext call, the request will go to the new, unvalidated URL. loadModelParametersFromURL handles this correctly by using rawURL for its request; this function should match.

Suggested change
req, err := http.NewRequestWithContext(ctx, http.MethodGet, s.URL(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)

Comment on lines 119 to 184
@@ -211,131 +183,122 @@ func Init(ctx context.Context, config *Config, configStore configstore.ConfigSto
return nil, paramsErr
}

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.

P2 Background goroutines not drained on Init failure

The two mc.wg.Add(1) background-startup goroutines (lines ~131–141 and ~159–169) are added to mc.wg before wg.Wait() returns. If Init returns an error after wg.Wait() (e.g., LoadOverridesFromStore fails at line 196), mc.syncCancel() is invoked by the deferred guard, causing the goroutines to self-terminate — but mc.wg.Wait() is never called. The caller receives nil, err and can never call Cleanup(), so there is no caller-visible wait for those goroutines to finish. The leak is bounded (they exit when the context is cancelled) but the process can shut down or the test harness can exit while they are still holding the distributed lock.

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.

2 participants