























@@ -1,10 +1,9 @@
1+import { readFileSync } from "node:fs";
12import { stat } from "node:fs/promises";
3+import { createRequire } from "node:module";
24import path from "node:path";
35import { Readable, Writable } from "node:stream";
4-import {
5-resumeToolRequest as embeddedResumeToolRequest,
6-runToolRequest as embeddedRunToolRequest,
7-} from "@clawdbot/lobster/core";
6+import { pathToFileURL } from "node:url";
8798export type LobsterEnvelope =
109| {
@@ -97,6 +96,45 @@ type EmbeddedToolRuntime = {
97969897type LoadEmbeddedToolRuntime = () => Promise<EmbeddedToolRuntime>;
999899+type LoadEmbeddedToolRuntimeFromPackageOptions = {
100+importModule?: (specifier: string) => Promise<Partial<EmbeddedToolRuntime>>;
101+resolvePackageEntry?: (specifier: string) => string;
102+};
103+104+const lobsterRequire = createRequire(import.meta.url);
105+106+function toEmbeddedToolRuntime(
107+moduleExports: Partial<EmbeddedToolRuntime>,
108+source: string,
109+): EmbeddedToolRuntime {
110+const { runToolRequest, resumeToolRequest } = moduleExports;
111+if (typeof runToolRequest === "function" && typeof resumeToolRequest === "function") {
112+return { runToolRequest, resumeToolRequest };
113+}
114+throw new Error(`${source} does not export Lobster embedded runtime functions`);
115+}
116+117+function findLobsterPackageRoot(resolvedEntryPath: string): string {
118+let dir = path.dirname(resolvedEntryPath);
119+while (true) {
120+const packageJsonPath = path.join(dir, "package.json");
121+try {
122+const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { name?: string };
123+if (parsed.name === "@clawdbot/lobster") {
124+return dir;
125+}
126+} catch {
127+// Keep walking until the installed package root is found.
128+}
129+130+const parent = path.dirname(dir);
131+if (parent === dir) {
132+throw new Error(`Could not locate @clawdbot/lobster package root from ${resolvedEntryPath}`);
133+}
134+dir = parent;
135+}
136+}
137+100138function normalizeForCwdSandbox(p: string): string {
101139const normalized = path.normalize(p);
102140return process.platform === "win32" ? normalized.toLowerCase() : normalized;
@@ -255,11 +293,39 @@ async function withTimeout<T>(
255293});
256294}
257295258-async function loadEmbeddedToolRuntimeFromPackage(): Promise<EmbeddedToolRuntime> {
259-return {
260-runToolRequest: embeddedRunToolRequest,
261-resumeToolRequest: embeddedResumeToolRequest,
262-};
296+export async function loadEmbeddedToolRuntimeFromPackage(
297+options: LoadEmbeddedToolRuntimeFromPackageOptions = {},
298+): Promise<EmbeddedToolRuntime> {
299+const importModule =
300+options.importModule ??
301+(async (specifier: string) => (await import(specifier)) as Partial<EmbeddedToolRuntime>);
302+const resolvePackageEntry =
303+options.resolvePackageEntry ?? ((specifier: string) => lobsterRequire.resolve(specifier));
304+305+let coreLoadError: unknown;
306+try {
307+const coreSpecifier = ["@clawdbot", "lobster", "core"].join("/");
308+return toEmbeddedToolRuntime(await importModule(coreSpecifier), "@clawdbot/lobster/core");
309+} catch (error) {
310+coreLoadError = error;
311+}
312+313+let fallbackLoadError: unknown;
314+try {
315+const packageEntryPath = resolvePackageEntry("@clawdbot/lobster");
316+const packageRoot = findLobsterPackageRoot(packageEntryPath);
317+const coreRuntimeUrl = pathToFileURL(path.join(packageRoot, "dist/src/core/index.js")).href;
318+return toEmbeddedToolRuntime(await importModule(coreRuntimeUrl), coreRuntimeUrl);
319+} catch (error) {
320+fallbackLoadError = error;
321+}
322+323+throw new Error("Failed to load the Lobster embedded runtime", {
324+cause: new AggregateError(
325+[coreLoadError, fallbackLoadError],
326+"Both Lobster embedded runtime load paths failed",
327+),
328+});
263329}
264330265331export function createEmbeddedLobsterRunner(options?: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。