From 765a54305e3a4aa52275b464e694e4f072777437 Mon Sep 17 00:00:00 2001 From: roboomp Date: Sun, 26 Jul 2026 11:18:31 +0000 Subject: [PATCH] fix(stt): preserved nearest sherpa runtime - Loaded the nearest wrapper first and limited ancestor fallback to missing-addon failures. - Covered nested version-conflict installs alongside the broken-hoist layout. --- .../coding-agent/src/stt/sherpa-runtime.ts | 40 +++++++++++++------ .../test/stt-sherpa-runtime.test.ts | 33 ++++++++++++++- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/packages/coding-agent/src/stt/sherpa-runtime.ts b/packages/coding-agent/src/stt/sherpa-runtime.ts index 1b92d9bf1..c2ce2fb5a 100644 --- a/packages/coding-agent/src/stt/sherpa-runtime.ts +++ b/packages/coding-agent/src/stt/sherpa-runtime.ts @@ -37,19 +37,35 @@ export interface SherpaRuntime { }; } -function getPlatformPackage(): string { - const platform = os.platform() === "win32" ? "win" : os.platform(); - return `sherpa-onnx-${platform}-${os.arch()}`; -} - -/** Loads the source-workspace sherpa wrapper colocated with its native platform package. */ +/** Loads the nearest working source-workspace sherpa wrapper, including hoisted fallbacks. */ export function loadSourceSherpaRuntime(sourceUrl: string): SherpaRuntime { const sourceRequire = createRequire(sourceUrl); - const platformPackage = getPlatformPackage(); - for (const nodeModules of sourceRequire.resolve.paths(SHERPA_PACKAGE) ?? []) { - if (!resolveRuntimeModule(nodeModules, platformPackage)) continue; - const entry = resolveRuntimeModule(nodeModules, SHERPA_PACKAGE); - if (entry) return createRequire(entry)(entry); + const nearestEntry = sourceRequire.resolve(SHERPA_PACKAGE); + try { + return createRequire(nearestEntry)(nearestEntry); + } catch (error) { + if (!(error instanceof Error && error.message.startsWith("Could not find sherpa-onnx-node. Tried"))) { + throw error; + } + const platform = os.platform(); + const platformPackage = `sherpa-onnx-${platform === "win32" ? "win" : platform}-${os.arch()}`; + for (const nodeModules of sourceRequire.resolve.paths(SHERPA_PACKAGE) ?? []) { + if (!resolveRuntimeModule(nodeModules, platformPackage)) continue; + const entry = resolveRuntimeModule(nodeModules, SHERPA_PACKAGE); + if (!entry || entry === nearestEntry) continue; + try { + return createRequire(entry)(entry); + } catch (candidateError) { + if ( + !( + candidateError instanceof Error && + candidateError.message.startsWith("Could not find sherpa-onnx-node. Tried") + ) + ) { + throw candidateError; + } + } + } + throw error; } - return sourceRequire(SHERPA_PACKAGE); } diff --git a/packages/coding-agent/test/stt-sherpa-runtime.test.ts b/packages/coding-agent/test/stt-sherpa-runtime.test.ts index 6c8198cad..830685b4f 100644 --- a/packages/coding-agent/test/stt-sherpa-runtime.test.ts +++ b/packages/coding-agent/test/stt-sherpa-runtime.test.ts @@ -30,11 +30,42 @@ describe("sherpa source runtime resolution", () => { "module.exports = { OfflineRecognizer: { createAsync() {} } };\n", ); await writePackage(rootNodeModules, PLATFORM_PACKAGE, "module.exports = {};\n"); - await writePackage(packageNodeModules, "sherpa-onnx-node", "throw new Error('loaded isolated wrapper');\n"); + await writePackage( + packageNodeModules, + "sherpa-onnx-node", + "throw new Error('Could not find sherpa-onnx-node. Tried');\n", + ); const sourceUrl = path.join(tmp, "packages", "coding-agent", "src", "stt", "asr-worker.ts"); const runtime = loadSourceSherpaRuntime(sourceUrl); expect(runtime.OfflineRecognizer.createAsync).toBeTypeOf("function"); }); + + it("prefers the nearest wrapper when its nested platform addon is loadable", async () => { + tmp = await fs.mkdtemp(path.join(os.tmpdir(), "omp-sherpa-source-")); + const rootNodeModules = path.join(tmp, "node_modules"); + const packageNodeModules = path.join(tmp, "packages", "coding-agent", "node_modules"); + await writePackage( + rootNodeModules, + "sherpa-onnx-node", + "module.exports = { OfflineRecognizer: { createAsync: function rootRuntime() {} } };\n", + ); + await writePackage(rootNodeModules, PLATFORM_PACKAGE, "module.exports = {};\n"); + await writePackage( + packageNodeModules, + "sherpa-onnx-node", + `require("./node_modules/${PLATFORM_PACKAGE}"); module.exports = { OfflineRecognizer: { createAsync: function nestedRuntime() {} } };\n`, + ); + await writePackage( + path.join(packageNodeModules, "sherpa-onnx-node", "node_modules"), + PLATFORM_PACKAGE, + "module.exports = {};\n", + ); + + const sourceUrl = path.join(tmp, "packages", "coding-agent", "src", "stt", "asr-worker.ts"); + const runtime = loadSourceSherpaRuntime(sourceUrl); + + expect(runtime.OfflineRecognizer.createAsync.name).toBe("nestedRuntime"); + }); });