fix(release): classify packaged runtime deps roots

This commit is contained in:
Peter Steinberger
2026-05-02 02:17:00 +01:00
parent 3f6b67fd4e
commit 1844c1fb38
4 changed files with 53 additions and 6 deletions

View File

@@ -29,10 +29,20 @@ describeLive("xai x_search live", () => {
});
expect(tool).toBeTruthy();
const result = await tool!.execute("x-search:live", {
query: "OpenClaw from:steipete",
to_date: "2026-03-28",
});
let result: Awaited<ReturnType<NonNullable<typeof tool>["execute"]>>;
try {
result = await tool!.execute("x-search:live", {
query: "OpenClaw from:steipete",
to_date: "2026-03-28",
});
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (isBillingErrorMessage(message)) {
console.warn(`[xai:x-search:live] skip: billing drift: ${message}`);
return;
}
throw error;
}
const details = (result.details ?? {}) as {
provider?: string;

View File

@@ -85,6 +85,10 @@ async function runXaiLiveCase(label: string, run: () => Promise<void>): Promise<
}
}
function isRealtimeOpenBillingDrift(error: Error): boolean {
return isBillingErrorMessage(error.message) || error.message.includes("server response: 429");
}
describeLive("xai plugin live", () => {
it("synthesizes TTS through the registered speech provider", async () => {
await runXaiLiveCase("tts", async () => {
@@ -189,7 +193,21 @@ describeLive("xai plugin live", () => {
});
try {
await session.connect();
try {
await session.connect();
} catch (error) {
const thrown = error instanceof Error ? error : new Error(String(error));
if (isRealtimeOpenBillingDrift(thrown)) {
console.warn(`[xai:live] skip realtime-open: billing drift: ${thrown.message}`);
return;
}
throw error;
}
const billingError = errors.find(isRealtimeOpenBillingDrift);
if (billingError) {
console.warn(`[xai:live] skip realtime-open: billing drift: ${billingError.message}`);
return;
}
expect(errors).toEqual([]);
expect(session.isConnected()).toBe(true);
} finally {

View File

@@ -705,9 +705,10 @@ export async function runPluginRegistryPostinstallMigration(params = {}) {
export function isSourceCheckoutRoot(params) {
const pathExists = params.existsSync ?? existsSync;
const hasPostinstallInventory = pathExists(join(params.packageRoot, DIST_INVENTORY_PATH));
return (
(pathExists(join(params.packageRoot, ".git")) ||
pathExists(join(params.packageRoot, "pnpm-workspace.yaml"))) &&
(pathExists(join(params.packageRoot, "pnpm-workspace.yaml")) && !hasPostinstallInventory)) &&
pathExists(join(params.packageRoot, "src")) &&
pathExists(join(params.packageRoot, "extensions"))
);

View File

@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
import path from "node:path";
import { describe, expect, it, vi } from "vitest";
import {
isSourceCheckoutRoot,
isDirectPostinstallInvocation,
pruneOpenClawCompileCache,
pruneInstalledPackageDist,
@@ -136,6 +137,23 @@ describe("bundled plugin postinstall", () => {
);
});
it("does not classify published packages with source files as source checkouts", () => {
const packageRoot = "/pkg";
const existingPaths = new Set([
path.join(packageRoot, "pnpm-workspace.yaml"),
path.join(packageRoot, "src"),
path.join(packageRoot, "extensions"),
path.join(packageRoot, "dist", "postinstall-inventory.json"),
]);
expect(
isSourceCheckoutRoot({
packageRoot,
existsSync: (value: string) => existingPaths.has(value),
}),
).toBe(false);
});
it("prunes source-checkout bundled plugin node_modules", async () => {
const packageRoot = await createTempDirAsync("openclaw-source-checkout-");
const extensionsDir = path.join(packageRoot, "extensions");