Skip to content

feat: connect ledger / refactor#48

Merged
Sang-it merged 5 commits into
mainfrom
feat/qol-changes
Apr 4, 2026
Merged

feat: connect ledger / refactor#48
Sang-it merged 5 commits into
mainfrom
feat/qol-changes

Conversation

@Sang-it
Copy link
Copy Markdown
Member

@Sang-it Sang-it commented Mar 23, 2026

No description provided.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Mar 23, 2026

Greptile Summary

This PR adds per-model pricing data to the Redis cache. When modelsDevAction runs, it now decodes the models.dev JSON a second time through the new ProviderModelToCostSchema, extracts {input, output} costs keyed as provider/model, and persists them via the new bulkSetProviderModelCost helper in model_cost.ts. A corresponding getCostForModel getter is also introduced for downstream lookup.

Key changes:

  • New packages/resolver/src/redis/model_cost.ts — Redis helpers for cost get/set/delete with JSON serialisation via Effect Schema.parseJson.
  • ProviderSchema in modelsdev.ts now types the model value to expose the optional cost struct, enabling two separate schema transforms from the same raw payload.
  • fetch.ts decodes cost data alongside the existing model-list decode and writes it to Redis in the same modelsDevAction call.

Issues found:

  • getCostForModel returns [] (an empty array) for a cache miss instead of null/Option, producing a Cost | never[] union that makes safe consumption error-prone.
  • Models with no upstream cost data are stored as {input: 0, output: 0}, making it impossible to distinguish a genuinely free model from one with missing data.
  • The .ts extension is included in the re-export in index.ts, inconsistent with every other export in that file.
  • Minor typo: canonicalProvdierModelName in bulkSetProviderModelCost.

Confidence Score: 3/5

  • The feature is mostly correct but getCostForModel returns a wrong type on cache miss, which will surface as a runtime bug in any caller that treats the result as a Cost object.
  • The bulk-write path is sound and won't break existing functionality, but the read path (getCostForModel) returns [] instead of null for a missing key. Any consumer that destructures the returned value as { input, output } will get undefined for both fields, which is a latent runtime bug as soon as this getter is used. The @ts-expect-error workaround and the 0-default for unknown costs are also worth addressing before the feature is considered production-ready.
  • packages/resolver/src/redis/model_cost.ts — the cache-miss return value needs to be fixed before the getter is wired up to any endpoint.

Important Files Changed

Filename Overview
packages/resolver/src/redis/model_cost.ts New file providing CRUD helpers for model cost data in Redis; getCostForModel has a logic bug returning [] instead of null for a cache miss, and a typo in bulkSetProviderModelCost's callback variable name.
packages/resolver/src/data_manager/fetch.ts Extends modelsDevAction to decode cost data from the same JSON payload and bulk-write it to Redis; uses a @ts-expect-error workaround with a FIXME for typing the accumulator, but the core logic is sound.
packages/resolver/src/data_manager/schema/modelsdev.ts Extends ProviderSchema to include typed cost fields and adds ProviderModelToCostSchema; silently defaults absent cost values to 0, making free vs. unknown costs indistinguishable.
packages/resolver/src/redis/index.ts Re-exports the new model_cost module but includes the .ts extension, inconsistent with all other re-exports in the file.
packages/resolver/src/redis/fetch_point.ts Whitespace-only change adding a blank line after the import; no functional impact.

Sequence Diagram

sequenceDiagram
    participant DM as DataManager (fetch.ts)
    participant API as models.dev API
    participant S as Schema (modelsdev.ts)
    participant R as Redis (model_cost.ts)

    DM->>API: GET /api.json
    API-->>DM: JSON payload
    DM->>S: decodeUnknown(ProviderModelMapSchema)(json)
    S-->>DM: provider → string[] map
    DM->>R: bulkSetModelsForProvider(supported)
    DM->>S: decodeUnknown(ProviderModelToCostSchema)(json)
    S-->>DM: provider → [{model, input, output}][]
    DM->>DM: reduce to {provider/model → {input, output}}
    DM->>R: bulkSetProviderModelCost(supportedCost)
    R->>R: setCostForModel × N (concurrency=5)
    Note over R: PREFIX = "enfinyte:model_to_cost:"
Loading

Reviews (1): Last reviewed commit: "feat: add model cost to redis" | Re-trigger Greptile

Comment thread packages/resolver/src/redis/model_cost.ts
Comment thread packages/resolver/src/redis/model_cost.ts
Comment thread packages/resolver/src/redis/index.ts Outdated
Comment thread packages/resolver/src/data_manager/schema/modelsdev.ts
Sang-it added 2 commits March 23, 2026 10:44
Record every LLM request as a ledger transaction with resolution latency,
category, token usage, cost, timing (ttft + total latency), and error info.
Extends resolver return type to thread category through all resolution paths
and exposes getCostForModel on ResolverService for cost lookups from Redis.
@Sang-it Sang-it force-pushed the feat/qol-changes branch from a2da0fb to 08c82bf Compare April 3, 2026 13:39
Sang-it added 2 commits April 3, 2026 22:55
…uced duplication

- Rename 7 absurdly long filenames in api_platform/services/ai (e.g.,
  responseFieldsToAISDKGenerateTextCallSettingsAdapters.ts → adapters.ts)
- Extract RequestParams type to replace 5-param function signatures
- Extract prepareCallOptions, tryProviders, resolveProviders shared helpers
- Extract buildBaseResponse to eliminate 3x duplicated ResponseResource defaults
- Create provider-registry.ts to unify duplicated provider switches
- Move ProviderModelPair, IntentPair, Intent domain types to common package
- Extract VerifyApiKeyResult to common for cross-service contract
- Extract classifyWithLLM generic helper from near-identical getCategory/getPolicy
- Extract assembleUserContext from backend apikey verifyKey
- Centralize Redis key prefixes in resolver/redis/consts.ts
- Simplify resolver dispatch from Match pattern to simple tag check
- Remove verbose logging from parsers (error types carry the context)
- Remove dead code: classification-cache.ts, MOCK_* constants, console.logs,
  void outputFormat, duplicate validation, commented-out service, stale TODO
- Fix @ts-expect-error in data_manager/fetch.ts with proper typing
- Fix .ts import extension in match_models.ts
- Fix misleading error messages in AI service fallback paths

Net result: -460 lines, 0 type errors, 0 test regressions (156 pass, 7 pre-existing fail)
@Sang-it Sang-it changed the title feat: add model cost to redis feat: connect ledger / refactor Apr 4, 2026
@Sang-it Sang-it merged commit 2bbd87a into main Apr 4, 2026
2 checks passed
@Sang-it Sang-it deleted the feat/qol-changes branch April 4, 2026 23:04
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