fix(coding-agent): re-exported relocated catalog symbols from legacy pi-ai shim

`calculateCost`, `modelsAreEqual`, and `getBundledProviders` moved from the
`@oh-my-pi/pi-ai` barrel to `@oh-my-pi/pi-catalog/models` in the catalog
split (1b9d9d0851). The legacy-extension pi-ai root shim already bridged
`getBundledModel`/`getBundledModels` back under their old `getModel`/
`getModels` names but never re-exported the other relocated symbols, so any
legacy extension importing `calculateCost` from `@oh-my-pi/pi-ai` failed
plugin validation at install time with `Export named 'calculateCost' not
found in module '.../legacy-pi-ai-shim.ts'`.

Bridge all three symbols through the shim so pre-split legacy extensions
load again. Add regression tests that load fixtures importing
`calculateCost`, `modelsAreEqual`, and `getBundledProviders` from
`@oh-my-pi/pi-ai` and assert identity against the catalog implementations.

Fixes #4584
This commit is contained in:
roboomp
2026-07-05 02:03:35 +00:00
parent 38565c58cb
commit 5203fce696
3 changed files with 57 additions and 5 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Fixed legacy extension plugin validation failing with `Export named 'calculateCost' not found in module '.../legacy-pi-ai-shim.ts'` when the extension imports `calculateCost` (or `modelsAreEqual` / `getBundledProviders`) from `@oh-my-pi/pi-ai`. Those symbols were relocated to `@oh-my-pi/pi-catalog/models` during the catalog split but were never bridged back through the legacy `pi-ai` root shim; the shim now re-exports them alongside the existing `getModel` / `getModels` aliases so plugins written against pre-split pi-ai load again ([#4584](https://github.com/can1357/oh-my-pi/issues/4584)).
## [16.3.6] - 2026-07-04
### Changed
@@ -19,7 +19,13 @@
* `types.ts` via the `export *` below — pi-ai still exports both as types,
* only the runtime `Type` builder and `StringEnum()` helper were removed.
*/
import { getBundledModel, getBundledModels } from "@oh-my-pi/pi-catalog/models";
import {
calculateCost,
getBundledModel,
getBundledModels,
getBundledProviders,
modelsAreEqual,
} from "@oh-my-pi/pi-catalog/models";
import { type TSchema, Type } from "./typebox";
export interface StringEnumOptions<T extends string> {
@@ -66,8 +72,15 @@ export function StringEnum<T extends string | number>(
}
export * from "@oh-my-pi/pi-ai";
export { Type };
/** Compatibility aliases for renamed catalog functions */
/**
* Compatibility re-exports for catalog symbols that pi-ai historically exposed
* from its own barrel prior to the `refactor(catalog)!: split model catalog
* from pi-ai` change. Legacy extensions still import these from the pi-ai
* root, so the shim bridges them through to their new home in
* `@oh-my-pi/pi-catalog/models`. `getModel`/`getModels` are the historical
* pi-ai names for `getBundledModel`/`getBundledModels`; the remaining symbols
* kept their names across the move.
*/
export { calculateCost, getBundledProviders, modelsAreEqual, Type };
export const getModel = getBundledModel;
export const getModels = getBundledModels;
@@ -3,7 +3,13 @@ import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as url from "node:url";
import { getBundledModel, getBundledModels } from "@oh-my-pi/pi-catalog/models";
import {
calculateCost,
getBundledModel,
getBundledModels,
getBundledProviders,
modelsAreEqual,
} from "@oh-my-pi/pi-catalog/models";
import {
__resetLegacyPiResolutionCache,
installLegacyPiSpecifierShim,
@@ -124,6 +130,35 @@ describe("legacy-pi @(scope)/pi-ai root `Type` remap (issue #1437)", () => {
expect(loaded.testGetModels).toBe(getBundledModels);
});
it("re-exports calculateCost from @oh-my-pi/pi-catalog/models (issue #4584)", async () => {
// `calculateCost` was moved from the `@oh-my-pi/pi-ai` barrel to
// `@oh-my-pi/pi-catalog/models` in the catalog split. Legacy extensions
// still import it from the pi-ai root, so the shim must bridge it back
// to the catalog implementation. The historical regression was a plain
// `SyntaxError: Export named 'calculateCost' not found in module
// '.../legacy-pi-ai-shim.ts'` at extension-validation time.
const loaded = (await loadLegacyPiModule(
await writeFixtureExtension(
'import { calculateCost } from "@oh-my-pi/pi-ai"; export const probe = calculateCost;',
),
)) as { probe: unknown };
expect(loaded.probe).toBe(calculateCost);
});
it("re-exports modelsAreEqual and getBundledProviders from @oh-my-pi/pi-catalog/models", async () => {
const loaded = (await loadLegacyPiModule(
await writeFixtureExtension(
[
'import { modelsAreEqual, getBundledProviders } from "@oh-my-pi/pi-ai";',
"export const eq = modelsAreEqual;",
"export const providers = getBundledProviders;",
].join("\n"),
),
)) as { eq: unknown; providers: unknown };
expect(loaded.eq).toBe(modelsAreEqual);
expect(loaded.providers).toBe(getBundledProviders);
});
it("exports StringEnum as a schema builder with options support", async () => {
const loaded = (await loadLegacyPiModule(
await writeFixtureExtension(