chore: script release tag push and trim daemon log noise
This commit is contained in:
@@ -52,7 +52,6 @@ import { createAgentMcpServer } from "./agent/mcp-server.js";
|
||||
import { createAllClients, shutdownProviders } from "./agent/provider-registry.js";
|
||||
import { createTerminalManager, type TerminalManager } from "../terminal/terminal-manager.js";
|
||||
import {
|
||||
buildOfferEndpoints,
|
||||
createConnectionOfferV2,
|
||||
encodeOfferToFragmentUrl,
|
||||
} from "./connection-offer.js";
|
||||
@@ -524,20 +523,6 @@ export async function createPaseoDaemon(
|
||||
const relayPublicEndpoint = config.relayPublicEndpoint ?? relayEndpoint;
|
||||
const appBaseUrl = config.appBaseUrl ?? "https://app.paseo.sh";
|
||||
|
||||
const directEndpoints = buildOfferEndpoints({
|
||||
listenHost: listenTarget.host,
|
||||
port: listenTarget.port,
|
||||
});
|
||||
|
||||
logger.info(
|
||||
{
|
||||
serverId,
|
||||
endpoints: directEndpoints,
|
||||
wsUrls: directEndpoints.map((endpoint) => `ws://${endpoint}/ws`),
|
||||
},
|
||||
"direct_connect"
|
||||
);
|
||||
|
||||
if (relayEnabled) {
|
||||
const offer = await createConnectionOfferV2({
|
||||
serverId,
|
||||
@@ -547,8 +532,6 @@ export async function createPaseoDaemon(
|
||||
|
||||
const url = encodeOfferToFragmentUrl({ offer, appBaseUrl });
|
||||
logger.info({ url }, "pairing_offer");
|
||||
} else {
|
||||
logger.info("relay_disabled");
|
||||
}
|
||||
|
||||
if (relayEnabled) {
|
||||
|
||||
@@ -197,10 +197,10 @@ describe("ConnectionOfferV2 (daemon E2E)", () => {
|
||||
});
|
||||
|
||||
try {
|
||||
const directConnect = await new Promise<{ endpoints: string[] }>((resolve, reject) => {
|
||||
const sawListeningLog = await new Promise<boolean>((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
proc.kill();
|
||||
reject(new Error("timed out waiting for direct_connect log"));
|
||||
reject(new Error("timed out waiting for server listening log"));
|
||||
}, 15000);
|
||||
|
||||
const onData = (data: Buffer) => {
|
||||
@@ -213,16 +213,12 @@ describe("ConnectionOfferV2 (daemon E2E)", () => {
|
||||
reject(new Error("unexpected pairing_offer log when --no-relay is set"));
|
||||
return;
|
||||
}
|
||||
if (!line.includes("direct_connect")) continue;
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(line) as { msg?: string; endpoints?: unknown };
|
||||
if (parsed.msg !== "direct_connect") continue;
|
||||
const endpoints = Array.isArray(parsed.endpoints)
|
||||
? parsed.endpoints.filter((v) => typeof v === "string")
|
||||
: [];
|
||||
if (endpoints.length === 0) continue;
|
||||
const parsed = JSON.parse(line) as { msg?: string };
|
||||
if (parsed.msg !== `Server listening on http://0.0.0.0:${port}`) continue;
|
||||
clearTimeout(timeout);
|
||||
resolve({ endpoints });
|
||||
resolve(true);
|
||||
return;
|
||||
} catch {
|
||||
// ignore
|
||||
@@ -243,8 +239,7 @@ describe("ConnectionOfferV2 (daemon E2E)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(directConnect.endpoints).toContain(`localhost:${port}`);
|
||||
expect(directConnect.endpoints).toContain(`192.168.1.12:${port}`);
|
||||
expect(sawListeningLog).toBe(true);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`failed; stdout so far:\\n${stdoutLines.join("")}\\n\\n${String(err)}`
|
||||
|
||||
@@ -54,15 +54,15 @@ describe("sherpa model downloader", () => {
|
||||
).rejects.toThrow(/auto-download/i);
|
||||
});
|
||||
|
||||
test("ensureSherpaOnnxModel logs artifact download progress", async () => {
|
||||
test("ensureSherpaOnnxModel logs lifecycle events without progress spam", async () => {
|
||||
const modelsDir = makeTmpDir();
|
||||
const progressLogs: Array<Record<string, unknown>> = [];
|
||||
const infoMessages: string[] = [];
|
||||
|
||||
const loggerWithSpy = {
|
||||
child: () => loggerWithSpy,
|
||||
info: (obj?: unknown, msg?: string) => {
|
||||
if (msg === "Downloading model artifact" && obj && typeof obj === "object") {
|
||||
progressLogs.push(obj as Record<string, unknown>);
|
||||
info: (_obj?: unknown, msg?: string) => {
|
||||
if (typeof msg === "string") {
|
||||
infoMessages.push(msg);
|
||||
}
|
||||
},
|
||||
error: () => undefined,
|
||||
@@ -90,9 +90,8 @@ describe("sherpa model downloader", () => {
|
||||
}
|
||||
|
||||
expect(fetchMock).toHaveBeenCalled();
|
||||
expect(progressLogs.length).toBeGreaterThan(0);
|
||||
const final = progressLogs.at(-1);
|
||||
expect(final?.modelId).toBe("pocket-tts-onnx-int8");
|
||||
expect(final?.pct).toBe(100);
|
||||
expect(infoMessages).toContain("Starting model download");
|
||||
expect(infoMessages).toContain("Model download completed");
|
||||
expect(infoMessages).not.toContain("Downloading model artifact");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createWriteStream } from "node:fs";
|
||||
import { mkdir, rename, rm, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { Readable, Transform } from "node:stream";
|
||||
import { Readable } from "node:stream";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { spawn } from "node:child_process";
|
||||
import type pino from "pino";
|
||||
@@ -39,31 +39,13 @@ async function hasRequiredFiles(modelDir: string, requiredFiles: string[]): Prom
|
||||
return true;
|
||||
}
|
||||
|
||||
const UNKNOWN_SIZE_PROGRESS_BYTES_STEP = 5 * 1024 * 1024;
|
||||
const UNKNOWN_SIZE_PROGRESS_MS_STEP = 1000;
|
||||
|
||||
type DownloadToFileOptions = {
|
||||
url: string;
|
||||
outputPath: string;
|
||||
logger: pino.Logger;
|
||||
modelId: SherpaOnnxModelId;
|
||||
artifact: string;
|
||||
};
|
||||
|
||||
function parseContentLength(res: Response): number | null {
|
||||
const raw = res.headers.get("content-length");
|
||||
if (!raw) {
|
||||
return null;
|
||||
}
|
||||
const parsed = Number.parseInt(raw, 10);
|
||||
if (!Number.isFinite(parsed) || parsed <= 0) {
|
||||
return null;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
async function downloadToFile(options: DownloadToFileOptions): Promise<void> {
|
||||
const { url, outputPath, logger, modelId, artifact } = options;
|
||||
const { url, outputPath } = options;
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to download ${url}: ${res.status} ${res.statusText}`);
|
||||
@@ -76,62 +58,9 @@ async function downloadToFile(options: DownloadToFileOptions): Promise<void> {
|
||||
await mkdir(path.dirname(outputPath), { recursive: true });
|
||||
|
||||
const nodeStream = Readable.fromWeb(res.body as any);
|
||||
const totalBytes = parseContentLength(res);
|
||||
|
||||
let downloadedBytes = 0;
|
||||
let lastLoggedPct = -1;
|
||||
let lastLoggedBytes = 0;
|
||||
let lastLoggedAt = 0;
|
||||
|
||||
const logProgress = (force: boolean): void => {
|
||||
const pct =
|
||||
totalBytes && totalBytes > 0
|
||||
? Math.min(100, Math.floor((downloadedBytes * 100) / totalBytes))
|
||||
: null;
|
||||
|
||||
if (!force) {
|
||||
if (pct !== null) {
|
||||
if (pct <= lastLoggedPct) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const now = Date.now();
|
||||
const advancedBytes = downloadedBytes - lastLoggedBytes;
|
||||
if (advancedBytes < UNKNOWN_SIZE_PROGRESS_BYTES_STEP && now - lastLoggedAt < UNKNOWN_SIZE_PROGRESS_MS_STEP) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(
|
||||
{
|
||||
modelId,
|
||||
artifact,
|
||||
url,
|
||||
downloadedBytes,
|
||||
totalBytes,
|
||||
pct,
|
||||
},
|
||||
"Downloading model artifact"
|
||||
);
|
||||
lastLoggedPct = pct ?? -1;
|
||||
lastLoggedBytes = downloadedBytes;
|
||||
lastLoggedAt = Date.now();
|
||||
};
|
||||
|
||||
logProgress(false);
|
||||
|
||||
const progressStream = new Transform({
|
||||
transform(chunk: Buffer, _encoding, callback) {
|
||||
downloadedBytes += chunk.length;
|
||||
logProgress(false);
|
||||
callback(null, chunk);
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
await pipeline(nodeStream, progressStream, createWriteStream(tmpPath));
|
||||
logProgress(true);
|
||||
await pipeline(nodeStream, createWriteStream(tmpPath));
|
||||
await rename(tmpPath, outputPath);
|
||||
} catch (error) {
|
||||
await rm(tmpPath, { force: true }).catch(() => undefined);
|
||||
@@ -194,9 +123,6 @@ export async function ensureSherpaOnnxModel(options: EnsureSherpaOnnxModelOption
|
||||
await downloadToFile({
|
||||
url: spec.archiveUrl,
|
||||
outputPath: archivePath,
|
||||
logger,
|
||||
modelId: options.modelId,
|
||||
artifact: archiveFilename,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,9 +177,6 @@ export async function ensureSherpaOnnxModel(options: EnsureSherpaOnnxModelOption
|
||||
await downloadToFile({
|
||||
url: file.url,
|
||||
outputPath: dst,
|
||||
logger,
|
||||
modelId: options.modelId,
|
||||
artifact: file.relPath,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user