Skip to content

Refactoring#49

Merged
Sang-it merged 4 commits into
mainfrom
refactoring
Apr 5, 2026
Merged

Refactoring#49
Sang-it merged 4 commits into
mainfrom
refactoring

Conversation

@Sang-it

@Sang-it Sang-it commented Apr 5, 2026

Copy link
Copy Markdown
Member

No description provided.

Sang-it added 4 commits April 4, 2026 20:30
Add a new @enfinyte/services package that re-exports all shared Live
service layers (Resolver, Vault, Ledger) from a single canonical import
path. Update backend and api_platform to import from @enfinyte/services
instead of directly from resolver, vault, and ledger packages.
- Fix bugs: getCostForModel return type mismatch, unsafe LLM output
  assertion, typo in model_cost.ts
- Add logging helper (log.ts) to reduce boilerplate across all modules
- Clean up service entry: extract withRedis helper, move logging into
  resolveImpl, simplify getCostForModel to one-liner
- Split resolve_auto.ts (261 lines) into extract_text.ts, classify.ts,
  and slimmed resolve_auto.ts
- Split parse_model_id.ts (968 lines) into per-family parser directory
  with types, constants, helpers, strip, and 6 family parsers
- Reorganize data_manager/fetch.ts: remove unsafe generic cast, split
  modelsDevAction into focused functions, reduce logging noise
models.dev reports costs in USD per million tokens (e.g. input=15 means
$15/1M tokens), but buildTransaction was multiplying raw token counts
directly by this rate, producing costs 1,000,000x too high.
@greptile-apps

greptile-apps Bot commented Apr 5, 2026

Copy link
Copy Markdown

Greptile Summary

This PR is a structural refactoring that introduces a new @enfinyte/services package to consolidate imports from resolver, vault, and ledger into a single public API surface, splits the monolithic parse_model_id.ts (967 lines) into a well-structured directory of focused modules, and simplifies the Effect-based logging pattern across the resolver with a new log.ts helper factory. It also contains a critical billing bug fix — token costs were previously computed without dividing by 1_000_000, inflating USD cost records by a factor of one million.

Key changes:

  • New @enfinyte/services package (packages/services/) centralises re-exports of ResolverService, VaultService, LedgerService, and their types — all consuming packages updated to use this new import path
  • parse_model_id refactor: the 967-line monolith split into constants.ts, helpers.ts, types.ts, strip.ts, index.ts, and per-family parsers (claude.ts, gemini.ts, gpt.ts, llama.ts, o_series.ts, generic.ts)
  • Logging DRY-up: new log.ts introduces resolverLog/dataManagerLog factories, replacing dozens of verbose Effect.logInfo(...).pipe(Effect.annotateLogs({...})) call sites with clean one-liners
  • Billing bug fix: buildTransaction cost USD fields now correctly divide by 1_000_000 to normalise from per-million-token pricing stored in Redis
  • getCostForModel fix: Redis layer now returns null (not []) when no cost is found, removing the Array.isArray workaround in the service layer
  • classify.ts / extract_text.ts extraction: LLM classification and text extraction logic moved out of resolve_auto.ts into dedicated modules

Issues found:

  • parseProviderModelImpl in packages/backend/src/services/apikey.ts still imports via resolver/src/parser internal path rather than the new @enfinyte/services API — inconsistent with the PR's refactoring goal
  • tapError error logging was removed from HTTP fetch failures in data_manager/fetch.ts, reducing operational visibility when the data cache population fails
  • detectFamily in parse_model_id/index.ts declares a | null return type but never returns null, making the null guard in parseBareId dead code
  • Hardcoded year ceiling > 2030 in helpers.ts will silently misparse model dates after 2030"

Confidence Score: 4/5

Safe to merge; primarily structural refactoring with a critical billing bug fix and no breaking API changes

The changes are well-scoped: the new @enfinyte/services package is a clean consolidation, the parse_model_id split is a faithful extraction with no logic changes, and the billing fix is correct. Score is 4 rather than 5 due to the removed error logging for network failures (operational regression), one internal-path import that violates the PR's own package-boundary goal, and a dead null return type that could mislead future contributors.

packages/backend/src/services/apikey.ts (internal path import), packages/resolver/src/data_manager/fetch.ts (removed error logging), packages/resolver/src/parser/parse_model_id/index.ts (dead null return type)

Important Files Changed

Filename Overview
packages/services/src/index.ts New @enfinyte/services package consolidating re-exports from resolver, vault, and ledger into a single public API surface
packages/resolver/src/log.ts New shared logging helper factory (resolverLog/dataManagerLog) that eliminates boilerplate Effect.annotateLogs call sites across the resolver
packages/resolver/src/index.ts Simplified ResolverServiceLive with withRedis helper; getCostForModel now correctly returns null instead of [] removing the Array.isArray workaround
packages/api_platform/src/services/ai/index.ts Critical billing bug fix: cost calculations now divide by 1,000,000 to normalise per-million-token pricing; imports consolidated to @enfinyte/services
packages/backend/src/services/apikey.ts Type import updated to @enfinyte/services but parseProviderModelImpl still imported via internal resolver/src/parser path, bypassing the new package boundary
packages/resolver/src/data_manager/fetch.ts Refactored to separate model and cost processing; tapError error logging for network and parse failures removed, reducing operational observability
packages/resolver/src/parser/parse_model_id/index.ts New entry-point for the refactored model-ID parser; detectFamily declares
packages/resolver/src/parser/parse_model_id/helpers.ts Date extraction helpers with hardcoded year ceiling > 2030 that will silently fail to parse model dates released after 2030
packages/resolver/src/redis/model_cost.ts getCostForModel now returns null (not []) when no cost is found; typo fixed in canonicalProvdierModelName variable name
packages/resolver/src/resolver/classify.ts LLM classification logic extracted from resolve_auto.ts into its own module with improved structured error logging via resolverLog helper
packages/resolver/src/resolver/extract_text.ts Text extraction utilities extracted from resolve_auto.ts into a standalone pure module with no logic changes

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["@enfinyte/services\n(new package)"] -->|re-exports| B["resolver"]
    A -->|re-exports| C["vault"]
    A -->|re-exports| D["ledger"]
    E["api_platform"] -->|imports from| A
    F["backend"] -->|imports from| A
    F -->|"direct internal import ⚠️"| B
    B --> G["resolver/index.ts\n(ResolverServiceLive)"] 
    G --> H["resolver/classify.ts (new)"]
    G --> I["resolver/extract_text.ts (new)"]
    G --> J["resolver/resolve_auto.ts"]
    G --> K["resolver/resolve_intent.ts"]
    B --> M["parser/parse_model_id/ (new dir)"]
    M --> N["index.ts"]
    M --> O["families/claude.ts"]
    M --> P["families/gpt.ts"]
    M --> Q["families/gemini.ts + llama.ts + o_series.ts + generic.ts"]
    B --> U["log.ts (new)"]
    U -->|resolverLog| G
    U -->|dataManagerLog| V["data_manager/fetch.ts"]
Loading

Reviews (1): Last reviewed commit: "fix: divide token costs by 1M to match m..." | Re-trigger Greptile

Comment thread packages/resolver/src/parser/parse_model_id/index.ts
Comment thread packages/backend/src/services/apikey.ts
Comment thread packages/resolver/src/data_manager/fetch.ts
Comment thread packages/resolver/src/parser/parse_model_id/helpers.ts
Comment thread packages/api_platform/src/services/ai/index.ts
@Sang-it Sang-it merged commit 8d72bb4 into main Apr 5, 2026
2 checks passed
@Sang-it Sang-it deleted the refactoring branch April 5, 2026 02:39
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