{"_id":"@acegalaxy/model-registry","_rev":"3-336a9eeb76da30db488df1691218a90b","name":"@acegalaxy/model-registry","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@acegalaxy/model-registry","version":"0.1.0","keywords":["ai","llm","model-registry","notion","claude","gpt","gemini","deepseek"],"author":{"name":"ACE Galaxy","email":"oss@acegalaxy.co"},"license":"MIT","_id":"@acegalaxy/model-registry@0.1.0","maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"homepage":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs#readme","bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs/issues"},"dist":{"shasum":"033beb2b2c598a8e308e6786d7cdf3b98dfedca6","tarball":"https://registry.npmjs.org/@acegalaxy/model-registry/-/model-registry-0.1.0.tgz","fileCount":14,"integrity":"sha512-/awKqgiXzQyuy1kam734nZ1q/dXbfnBWP+KJ9oaUVzQibt7p3bVzPrKSYlps8Psowr/hOG+VkUduKasqODRAVg==","signatures":[{"sig":"MEYCIQCg+ZgnyEIQPpqVly3BowpzySPSHSfocbtPeMA2igMDkAIhANQa2IzIY3nrmC3rIlEtc8/o5q+06I4EdjBTfhjsHwF+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37870},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./*":{"types":"./dist/*.d.ts","default":"./dist/*.js"}},"gitHead":"4215a322c47392855aa4a814655cf95b0b377715","private":false,"scripts":{"test":"node --test test/*.test.js","build":"tsc","clean":"rm -rf dist","pretest":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"kanelr","email":"lanhnk@acegalaxy.co"},"repository":{"url":"git+https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs.git","type":"git"},"_npmVersion":"11.12.1","description":"Notion-backed AI model registry — define model configs (provider, model, costs, capabilities) in a Notion table, sync to runtime via a single call. 3-layer fallback: Notion → cache → defaults.","directories":{},"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.7.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/model-registry_0.1.0_1778086018185_0.3233846577246231","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@acegalaxy/model-registry","version":"0.1.1","keywords":["ai","llm","model-registry","notion","claude","gpt","gemini","deepseek"],"author":{"name":"ACE Galaxy","email":"oss@acegalaxy.co"},"license":"MIT","_id":"@acegalaxy/model-registry@0.1.1","maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"homepage":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs#readme","bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs/issues"},"dist":{"shasum":"12e99e2e50d73ceda1c4ac66ebef1d0b9ab358c8","tarball":"https://registry.npmjs.org/@acegalaxy/model-registry/-/model-registry-0.1.1.tgz","fileCount":14,"integrity":"sha512-Rb70Q7+s5kILkjB/6OXKKUYaYf1muOJFpVgrHvra42iSZaYlV7Z5vqAsnFH5PxLcl3yr1R1KErBQgvmsK6WM4Q==","signatures":[{"sig":"MEUCIQCzyz1OykPELX+acd2AROHY/p0F4NP1a0OeCY822xrI6QIgKL4O8K5bjVHYOjT0HsW2APhJWzHR6urfhlQWYHbSzdU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37870},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./*":{"types":"./dist/*.d.ts","default":"./dist/*.js"}},"gitHead":"75db6e2531a3478cbad3383e94983ea08a6064c1","private":false,"scripts":{"test":"node --test test/*.test.js","build":"tsc","clean":"rm -rf dist","pretest":"npm run build","prepublishOnly":"npm run build"},"_npmUser":{"name":"kanelr","email":"lanhnk@acegalaxy.co"},"repository":{"url":"git+https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs.git","type":"git"},"_npmVersion":"11.12.1","description":"Notion-backed AI model registry — define model configs (provider, model, costs, capabilities) in a Notion table, sync to runtime via a single call. 3-layer fallback: Notion → cache → defaults.","directories":{},"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.7.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/model-registry_0.1.1_1778088188446_0.06593982178915136","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@acegalaxy/model-registry","version":"0.1.2","description":"Notion-backed AI model registry — define model configs (provider, model, costs, capabilities) in a Notion table, sync to runtime via a single call. 3-layer fallback: Notion → cache → defaults.","main":"dist/index.js","scripts":{"test":"node --test test/*.test.js","build":"tsc","prepublishOnly":"npm run build","clean":"rm -rf dist","pretest":"npm run build"},"keywords":["ai","llm","model-registry","notion","claude","gpt","gemini","deepseek"],"author":{"name":"ACE Galaxy","email":"oss@acegalaxy.co"},"license":"MIT","private":false,"engines":{"node":">=20"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs.git"},"bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs/issues"},"homepage":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs#readme","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./*":{"types":"./dist/*.d.ts","default":"./dist/*.js"},"./package.json":"./package.json"},"devDependencies":{"typescript":"^5.7.0","@types/node":"^20.0.0"},"gitHead":"75db6e2531a3478cbad3383e94983ea08a6064c1","_id":"@acegalaxy/model-registry@0.1.2","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-WbHtF1QcrNJ9FNBOxm2CQO4SWxlYRr5NLx6Ar8qaPb/Vn/y+xb8N6H65vanC5xtNZgxZ5W0vad9NPP80rNSPwQ==","shasum":"9f32a220e933caab7d32f9b85003fbb9439476e1","tarball":"https://registry.npmjs.org/@acegalaxy/model-registry/-/model-registry-0.1.2.tgz","fileCount":14,"unpackedSize":37910,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHriwVNGpCFrh79LJUt7FncLDIxZs/hDrxLUpbHW452WAiEAuVYutQBRMZrjbCahpuJmYitvDYr5QmytdBpJj4AqXuQ="}]},"_npmUser":{"name":"kanelr","email":"lanhnk@acegalaxy.co"},"directories":{},"maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/model-registry_0.1.2_1778088274648_0.1365494582207747"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-06T16:46:58.034Z","modified":"2026-05-06T17:24:34.930Z","0.1.0":"2026-05-06T16:46:58.331Z","0.1.1":"2026-05-06T17:23:08.596Z","0.1.2":"2026-05-06T17:24:34.808Z"},"bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs/issues"},"author":{"name":"ACE Galaxy","email":"oss@acegalaxy.co"},"license":"MIT","homepage":"https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs#readme","keywords":["ai","llm","model-registry","notion","claude","gpt","gemini","deepseek"],"repository":{"type":"git","url":"git+https://github.com/acegalaxy-co/ace_commons-model-registry-nodejs.git"},"description":"Notion-backed AI model registry — define model configs (provider, model, costs, capabilities) in a Notion table, sync to runtime via a single call. 3-layer fallback: Notion → cache → defaults.","maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"readme":"# @acegalaxy/model-registry\n\n[![npm version](https://img.shields.io/npm/v/@acegalaxy%2Fmodel-registry.svg)](https://www.npmjs.com/package/@acegalaxy/model-registry)\n[![npm downloads](https://img.shields.io/npm/dm/@acegalaxy%2Fmodel-registry.svg)](https://www.npmjs.com/package/@acegalaxy/model-registry)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node](https://img.shields.io/node/v/@acegalaxy%2Fmodel-registry.svg)](https://nodejs.org)\n\n\nNotion-backed AI model registry — define model configs (provider, model, costs, capabilities) in a Notion table, sync to runtime via a single call.\n\nManage Claude / GPT / Gemini / DeepSeek configs (pricing, context window, aliases, capabilities) in one Notion DB; consumers load them at startup with safe fallbacks.\n\n## Why\n\nLLM model lineups change weekly: new versions, new prices, deprecations. Hardcoding pricing tables in every service means stale costs and stale routing. This package lets ops own the model catalog in Notion while services read a normalized map at boot — with a 3-layer fallback so a Notion outage never knocks production offline.\n\n## Features\n\n- **3-layer load**: Notion DB → local cache file → hardcoded defaults\n- **Provider-agnostic**: Claude, GPT, Gemini, DeepSeek, Grok, etc.\n- **Cost metadata**: `pricePerMTokIn` / `pricePerMTokOut` per model\n- **Aliases**: resolve `gpt-4o-latest` / `claude-sonnet` → canonical key\n- **Cache atomic writes** (mode 0600, tmp + rename)\n- **5s Notion timeout** — never blocks boot\n- Zero runtime deps (you bring your own Notion fetcher)\n\n## Install\n\n```bash\nnpm install @acegalaxy/model-registry\n```\n\n## Quick start\n\n### 1. Define models in Notion\n\nCreate a Notion DB with rows like:\n\n| Key | Provider | Name | PricePerMTokIn | PricePerMTokOut | ContextWindow | Aliases |\n|---|---|---|---|---|---|---|\n| claude-opus-4 | anthropic | Claude Opus 4 | 15 | 75 | 200000 | opus, claude-opus |\n| gpt-4o | openai | GPT-4o | 2.5 | 10 | 128000 | gpt4o |\n| gemini-2.5-pro | google | Gemini 2.5 Pro | 1.25 | 10 | 1000000 | gemini-pro |\n\n### 2. Load registry at runtime\n\n```ts\nimport { loadModels } from \"@acegalaxy/model-registry\";\n\nconst DEFAULTS = {\n  \"claude-opus-4\": {\n    provider: \"anthropic\",\n    name: \"Claude Opus 4\",\n    pricePerMTokIn: 15,\n    pricePerMTokOut: 75,\n    contextWindow: 200_000,\n  },\n};\n\nconst { models, source, warnings } = await loadModels({\n  fetchRows: async () => myNotionAdapter.fetchModelsDB(),\n  cachePath: \"/var/cache/model-registry.json\",\n  defaults: DEFAULTS,\n});\n\nconsole.log(`loaded from ${source} (${Object.keys(models).length} models)`);\n// loaded from notion (12 models)\n```\n\n### 3. Query model by name / alias\n\n```ts\nfunction resolve(key: string) {\n  if (models[key]) return models[key];\n  for (const [canonical, entry] of Object.entries(models)) {\n    if (entry.aliases?.includes(key)) return models[canonical];\n  }\n  return models[\"gpt-4o\"]; // your default\n}\n\nconst m = resolve(\"opus\");\nconst cost = (inTok * m.pricePerMTokIn + outTok * m.pricePerMTokOut) / 1_000_000;\n```\n\n## Load source semantics\n\n| Source | When | Action |\n|---|---|---|\n| `notion` | `fetchRows()` returns non-empty within 5s | Cache written, return rows |\n| `cache` | Notion failed/empty AND cache file exists | Return cached rows |\n| `defaults` | Both above failed | Return hardcoded `defaults` |\n\n`defaults` is **required** and must be non-empty — guarantees the loader always returns a usable map.\n\n## API\n\n### `loadModels(opts): Promise<LoadModelsResult>`\n\n```ts\ninterface LoadModelsOpts {\n  fetchRows?: () => Promise<ModelMap | null>;\n  cachePath?: string;\n  defaults: ModelMap;     // required, non-empty\n  logger?: Logger;\n}\n\ninterface LoadModelsResult {\n  models: ModelMap;\n  source: \"notion\" | \"cache\" | \"defaults\";\n  warnings: string[];\n}\n```\n\n### `writeCache(path, models, logger?)`\n\nAtomic write helper if you manage cache externally.\n\n### `NOTION_TIMEOUT_MS`\n\nConstant: `5000`. Caller-imposed upper bound on `fetchRows()`.\n\n## Bring your own Notion fetcher\n\nThis package does **not** call the Notion API directly — pass your own adapter as `fetchRows`. This keeps the package transport-free and lets you reuse your existing Notion client / auth / rate-limiter.\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md). Security issues: see [SECURITY.md](./SECURITY.md).\n","readmeFilename":"README.md"}