Switch to double quotes and reformat codebase with Biome
This commit is contained in:
@@ -107,7 +107,7 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
void main().catch((error) => {
|
||||
const message = error instanceof Error ? error.stack ?? error.message : String(error);
|
||||
const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
||||
process.stderr.write(`${message}\n`);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ const result = spawnSync(
|
||||
{
|
||||
stdio: "inherit",
|
||||
env: process.env,
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (result.error) {
|
||||
|
||||
@@ -19,22 +19,20 @@ async function main(): Promise<void> {
|
||||
|
||||
const defaultOutPath = path.resolve(repoRoot, "tmp", "dictation-baseline.transcript.txt");
|
||||
const audioPath =
|
||||
process.env.DICTATION_AUDIO_PATH ??
|
||||
(process.argv[2] ? path.resolve(process.argv[2]) : null);
|
||||
process.env.DICTATION_AUDIO_PATH ?? (process.argv[2] ? path.resolve(process.argv[2]) : null);
|
||||
const outPath = path.resolve(process.env.DICTATION_OUT_PATH ?? process.argv[3] ?? defaultOutPath);
|
||||
|
||||
if (!audioPath) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
"Usage: npx tsx packages/server/scripts/dictation-generate-baseline.ts <audioPath> [outPath]\n" +
|
||||
" Or set DICTATION_AUDIO_PATH / DICTATION_OUT_PATH.\n"
|
||||
" Or set DICTATION_AUDIO_PATH / DICTATION_OUT_PATH.\n",
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const apiKey = requireEnv("OPENAI_API_KEY");
|
||||
const transcriptionModel =
|
||||
process.env.OPENAI_REALTIME_TRANSCRIPTION_MODEL ?? "gpt-4o-transcribe";
|
||||
const transcriptionModel = process.env.OPENAI_REALTIME_TRANSCRIPTION_MODEL ?? "gpt-4o-transcribe";
|
||||
const prompt =
|
||||
process.env.OPENAI_REALTIME_DICTATION_TRANSCRIPTION_PROMPT ??
|
||||
"Transcribe only what the speaker says. Do not add words. Preserve punctuation and casing. If the audio is silence or non-speech noise, return an empty transcript.";
|
||||
|
||||
@@ -31,8 +31,10 @@ function parseArgs(argv: string[]): { modelsDir: string; modelIds: LocalSpeechMo
|
||||
}
|
||||
|
||||
if (modelIds.length === 0) {
|
||||
const stt = (process.env.PASEO_LOCAL_STT_MODEL || DEFAULT_LOCAL_STT_MODEL) as LocalSpeechModelId;
|
||||
const tts = (process.env.PASEO_LOCAL_TTS_MODEL || DEFAULT_LOCAL_TTS_MODEL) as LocalSpeechModelId;
|
||||
const stt = (process.env.PASEO_LOCAL_STT_MODEL ||
|
||||
DEFAULT_LOCAL_STT_MODEL) as LocalSpeechModelId;
|
||||
const tts = (process.env.PASEO_LOCAL_TTS_MODEL ||
|
||||
DEFAULT_LOCAL_TTS_MODEL) as LocalSpeechModelId;
|
||||
modelIds.push(stt, tts);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,7 @@ const __dirname = path.dirname(__filename);
|
||||
|
||||
function main() {
|
||||
const repoRoot = path.resolve(__dirname, "../../..");
|
||||
const outPath = path.join(
|
||||
repoRoot,
|
||||
"packages/website/public/schemas/paseo.config.v1.json"
|
||||
);
|
||||
const outPath = path.join(repoRoot, "packages/website/public/schemas/paseo.config.v1.json");
|
||||
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
||||
|
||||
const schema = zodToJsonSchema(PersistedConfigSchema, {
|
||||
|
||||
@@ -258,10 +258,10 @@ function toCsv(rows: GeneratedSample[]): string {
|
||||
lines.push(
|
||||
cells
|
||||
.map((cell) => {
|
||||
const escaped = cell.replace(/"/g, "\"\"");
|
||||
const escaped = cell.replace(/"/g, '""');
|
||||
return escaped.includes(",") ? `"${escaped}"` : escaped;
|
||||
})
|
||||
.join(",")
|
||||
.join(","),
|
||||
);
|
||||
}
|
||||
return `${lines.join("\n")}\n`;
|
||||
@@ -278,7 +278,7 @@ logger.info(
|
||||
speed: options.speed,
|
||||
text: options.text,
|
||||
},
|
||||
"Generating TTS matrix across all model/voice combinations"
|
||||
"Generating TTS matrix across all model/voice combinations",
|
||||
);
|
||||
|
||||
await ensureLocalSpeechModels({
|
||||
@@ -303,7 +303,7 @@ for (const modelId of options.modelIds) {
|
||||
precision: "int8",
|
||||
targetChunkMs: 50,
|
||||
},
|
||||
logger
|
||||
logger,
|
||||
);
|
||||
const result = await tts.synthesizeSpeech(options.text);
|
||||
const pcm16 = await readStreamToBuffer(result.stream);
|
||||
@@ -354,7 +354,9 @@ for (const modelId of options.modelIds) {
|
||||
logger.info({ modelId, numSpeakers }, "Discovered Sherpa speaker count");
|
||||
|
||||
for (let sid = 0; sid < numSpeakers; sid += 1) {
|
||||
const audio = (tts as { generate: (config: { text: string; sid: number; speed: number }) => unknown }).generate({
|
||||
const audio = (
|
||||
tts as { generate: (config: { text: string; sid: number; speed: number }) => unknown }
|
||||
).generate({
|
||||
text: options.text,
|
||||
sid,
|
||||
speed,
|
||||
@@ -402,7 +404,7 @@ const manifest = {
|
||||
|
||||
await writeFile(
|
||||
path.join(options.outputDir, "manifest.json"),
|
||||
`${JSON.stringify(manifest, null, 2)}\n`
|
||||
`${JSON.stringify(manifest, null, 2)}\n`,
|
||||
);
|
||||
await writeFile(path.join(options.outputDir, "samples.csv"), toCsv(generated));
|
||||
await writeFile(
|
||||
@@ -419,7 +421,7 @@ await writeFile(
|
||||
" voice-label = default for Pocket TTS",
|
||||
"",
|
||||
`Total files: ${generated.length}`,
|
||||
].join("\n")
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
logger.info(
|
||||
@@ -428,5 +430,5 @@ logger.info(
|
||||
generatedCount: generated.length,
|
||||
models: Array.from(new Set(generated.map((item) => item.modelId))),
|
||||
},
|
||||
"TTS matrix generation complete"
|
||||
"TTS matrix generation complete",
|
||||
);
|
||||
|
||||
@@ -4,13 +4,9 @@ import { z } from "zod";
|
||||
|
||||
const server = new McpServer({ name: "paseo-test-mcp", version: "1.0.0" });
|
||||
|
||||
server.tool(
|
||||
"paseo_roundtrip_text",
|
||||
{ text: z.string() },
|
||||
async ({ text }) => ({
|
||||
content: [{ type: "text", text: `ECHO:${text}` }],
|
||||
})
|
||||
);
|
||||
server.tool("paseo_roundtrip_text", { text: z.string() }, async ({ text }) => ({
|
||||
content: [{ type: "text", text: `ECHO:${text}` }],
|
||||
}));
|
||||
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
|
||||
@@ -4,17 +4,14 @@ import { standardizePrompt } from "ai/internal";
|
||||
|
||||
async function processConversation() {
|
||||
try {
|
||||
const conversationPath =
|
||||
".debug.conversations/ce44c79a-0689-4210-8e00-72c0a627406d-2.json";
|
||||
const conversationPath = ".debug.conversations/ce44c79a-0689-4210-8e00-72c0a627406d-2.json";
|
||||
|
||||
process.stdout.write(`Loading conversation from: ${conversationPath}\n`);
|
||||
|
||||
const conversationData: any = JSON.parse(
|
||||
readFileSync(conversationPath, "utf-8")
|
||||
);
|
||||
const conversationData: any = JSON.parse(readFileSync(conversationPath, "utf-8"));
|
||||
|
||||
process.stdout.write(
|
||||
`\nLoaded conversation ${conversationData.conversationId} with ${conversationData.messages.length} messages\n\n`
|
||||
`\nLoaded conversation ${conversationData.conversationId} with ${conversationData.messages.length} messages\n\n`,
|
||||
);
|
||||
|
||||
const result = await standardizePrompt({
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
describe('supervision parity', () => {
|
||||
test('has exactly one runtime callsite for runSupervisor', () => {
|
||||
const daemonRunner = readFileSync(new URL('./daemon-runner.ts', import.meta.url), 'utf8')
|
||||
const devRunner = readFileSync(new URL('./dev-runner.ts', import.meta.url), 'utf8')
|
||||
describe("supervision parity", () => {
|
||||
test("has exactly one runtime callsite for runSupervisor", () => {
|
||||
const daemonRunner = readFileSync(new URL("./daemon-runner.ts", import.meta.url), "utf8");
|
||||
const devRunner = readFileSync(new URL("./dev-runner.ts", import.meta.url), "utf8");
|
||||
|
||||
const daemonRunnerCalls = (daemonRunner.match(/\brunSupervisor\s*\(/g) ?? []).length
|
||||
const devRunnerCalls = (devRunner.match(/\brunSupervisor\s*\(/g) ?? []).length
|
||||
const daemonRunnerCalls = (daemonRunner.match(/\brunSupervisor\s*\(/g) ?? []).length;
|
||||
const devRunnerCalls = (devRunner.match(/\brunSupervisor\s*\(/g) ?? []).length;
|
||||
|
||||
expect(daemonRunnerCalls + devRunnerCalls).toBe(1)
|
||||
})
|
||||
})
|
||||
expect(daemonRunnerCalls + devRunnerCalls).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
describe('supervisor lifecycle intents', () => {
|
||||
test('uses explicit shutdown and restart IPC intents', () => {
|
||||
const source = readFileSync(new URL('./supervisor.ts', import.meta.url), 'utf8')
|
||||
const legacyShutdownReason = ['cli', 'shutdown'].join('_')
|
||||
describe("supervisor lifecycle intents", () => {
|
||||
test("uses explicit shutdown and restart IPC intents", () => {
|
||||
const source = readFileSync(new URL("./supervisor.ts", import.meta.url), "utf8");
|
||||
const legacyShutdownReason = ["cli", "shutdown"].join("_");
|
||||
|
||||
expect(source).toContain('"paseo:shutdown"')
|
||||
expect(source).toContain('"paseo:restart"')
|
||||
expect(source).not.toContain(legacyShutdownReason)
|
||||
})
|
||||
})
|
||||
expect(source).toContain('"paseo:shutdown"');
|
||||
expect(source).toContain('"paseo:restart"');
|
||||
expect(source).not.toContain(legacyShutdownReason);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,15 +11,17 @@ async function main() {
|
||||
|
||||
const client = new Client(
|
||||
{ name: "test-client", version: "1.0.0" },
|
||||
{ capabilities: { elicitation: {} } }
|
||||
{ capabilities: { elicitation: {} } },
|
||||
);
|
||||
|
||||
// Listen for events
|
||||
client.setNotificationHandler(
|
||||
z.object({
|
||||
method: z.literal("codex/event"),
|
||||
params: z.object({ msg: z.any() }),
|
||||
}).passthrough(),
|
||||
z
|
||||
.object({
|
||||
method: z.literal("codex/event"),
|
||||
params: z.object({ msg: z.any() }),
|
||||
})
|
||||
.passthrough(),
|
||||
(data) => {
|
||||
const event = (data.params as { msg: unknown }).msg as {
|
||||
type?: string;
|
||||
@@ -41,7 +43,7 @@ async function main() {
|
||||
} else {
|
||||
process.stdout.write("Event: " + event.type + "\n");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
await client.connect(transport);
|
||||
@@ -50,22 +52,26 @@ async function main() {
|
||||
process.stdout.write("\n=== Testing dynamic MCP server config ===\n\n");
|
||||
|
||||
try {
|
||||
const result = await client.callTool({
|
||||
name: "codex",
|
||||
arguments: {
|
||||
prompt: "List all the MCP tools you have available. Just list them, don't use any.",
|
||||
sandbox: "danger-full-access",
|
||||
"approval-policy": "never",
|
||||
config: {
|
||||
mcp_servers: {
|
||||
"test-server": {
|
||||
command: "npx",
|
||||
args: ["-y", "mcp-server-time"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, undefined, { timeout: 60000 });
|
||||
const result = await client.callTool(
|
||||
{
|
||||
name: "codex",
|
||||
arguments: {
|
||||
prompt: "List all the MCP tools you have available. Just list them, don't use any.",
|
||||
sandbox: "danger-full-access",
|
||||
"approval-policy": "never",
|
||||
config: {
|
||||
mcp_servers: {
|
||||
"test-server": {
|
||||
command: "npx",
|
||||
args: ["-y", "mcp-server-time"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
{ timeout: 60000 },
|
||||
);
|
||||
|
||||
process.stdout.write("\n=== RESULT ===\n");
|
||||
const content = (result as { content: { text?: string }[] }).content;
|
||||
|
||||
@@ -49,7 +49,9 @@ function parseArgs(argv: string[]): CliOptions {
|
||||
|
||||
const positional: string[] = [];
|
||||
let outPath: string | undefined;
|
||||
let model = LocalSttModelIdSchema.parse(process.env.PASEO_LOCAL_STT_MODEL ?? DEFAULT_LOCAL_STT_MODEL);
|
||||
let model = LocalSttModelIdSchema.parse(
|
||||
process.env.PASEO_LOCAL_STT_MODEL ?? DEFAULT_LOCAL_STT_MODEL,
|
||||
);
|
||||
let modelsDir = defaultModelsDir;
|
||||
|
||||
for (let i = 0; i < argv.length; i++) {
|
||||
@@ -146,13 +148,15 @@ async function main(): Promise<void> {
|
||||
throw new Error(
|
||||
"Local STT service is unavailable. Check model files or run `npm run speech:download -- --model " +
|
||||
options.model +
|
||||
"`."
|
||||
"`.",
|
||||
);
|
||||
}
|
||||
|
||||
const audio = await readFile(options.wavPath);
|
||||
const manager = new STTManager("dev-local-wav-transcribe", logger, runtime.sttService);
|
||||
const result = await manager.transcribe(audio, "audio/wav", { label: "dev-local-wav-transcribe" });
|
||||
const result = await manager.transcribe(audio, "audio/wav", {
|
||||
label: "dev-local-wav-transcribe",
|
||||
});
|
||||
|
||||
const transcript = result.text.trim();
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ async function synthesizeInput(text: string, logger: pino.Logger): Promise<Buffe
|
||||
responseFormat: "pcm",
|
||||
voice: "alloy",
|
||||
},
|
||||
logger
|
||||
logger,
|
||||
);
|
||||
|
||||
const generated = await tts.synthesizeSpeech(text);
|
||||
@@ -98,7 +98,7 @@ async function runVoiceRoundTrip(params: {
|
||||
await client.sendVoiceAudioChunk(
|
||||
chunk.toString("base64"),
|
||||
"audio/pcm;rate=24000;bits=16",
|
||||
isLast
|
||||
isLast,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,16 +141,14 @@ async function main(): Promise<void> {
|
||||
const newAgentResult = await runVoiceRoundTrip({
|
||||
daemonUrl,
|
||||
voiceAgentId,
|
||||
speechText:
|
||||
"Use the speak tool and say exactly: new voice agent round trip successful.",
|
||||
speechText: "Use the speak tool and say exactly: new voice agent round trip successful.",
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
const resumedResult = await runVoiceRoundTrip({
|
||||
daemonUrl,
|
||||
voiceAgentId: newAgentResult.voiceAgentId,
|
||||
speechText:
|
||||
"Use the speak tool and say exactly: resumed voice agent round trip successful.",
|
||||
speechText: "Use the speak tool and say exactly: resumed voice agent round trip successful.",
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
@@ -163,8 +161,8 @@ async function main(): Promise<void> {
|
||||
resumedResult,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
2,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ function parseArgs(argv: string[]): CliOptions {
|
||||
async function streamWithTimeout(
|
||||
iterator: AsyncGenerator<AgentStreamEvent>,
|
||||
timeoutMs: number,
|
||||
onEvent: (event: AgentStreamEvent) => Promise<void> | void
|
||||
onEvent: (event: AgentStreamEvent) => Promise<void> | void,
|
||||
): Promise<void> {
|
||||
const timeout = new Promise<never>((_, reject) => {
|
||||
setTimeout(() => reject(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs);
|
||||
@@ -171,7 +171,10 @@ async function main(): Promise<void> {
|
||||
}
|
||||
if (event.type === "timeline" && event.item.type === "tool_call") {
|
||||
logger.info({ name: event.item.name, callId: event.item.callId }, "Timeline tool call");
|
||||
if (typeof event.item.name === "string" && event.item.name.toLowerCase().includes("speak")) {
|
||||
if (
|
||||
typeof event.item.name === "string" &&
|
||||
event.item.name.toLowerCase().includes("speak")
|
||||
) {
|
||||
sawSpeakTimeline = true;
|
||||
}
|
||||
}
|
||||
@@ -189,8 +192,8 @@ async function main(): Promise<void> {
|
||||
failureError,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
2,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
await agentManager.closeAgent(agentId).catch(() => undefined);
|
||||
|
||||
@@ -75,7 +75,11 @@ async function main(): Promise<void> {
|
||||
|
||||
const offActivity = client.on("activity_log", (msg) => {
|
||||
if (msg.type !== "activity_log") return;
|
||||
if (msg.payload.type === "transcript" || msg.payload.type === "error" || msg.payload.type === "assistant") {
|
||||
if (
|
||||
msg.payload.type === "transcript" ||
|
||||
msg.payload.type === "error" ||
|
||||
msg.payload.type === "assistant"
|
||||
) {
|
||||
console.log("activity_log", {
|
||||
type: msg.payload.type,
|
||||
content: msg.payload.content,
|
||||
@@ -129,10 +133,10 @@ async function main(): Promise<void> {
|
||||
responseFormat: "pcm",
|
||||
voice: "alloy",
|
||||
},
|
||||
logger
|
||||
logger,
|
||||
);
|
||||
const generated = await tts.synthesizeSpeech(
|
||||
"Use the speak tool and say exactly round trip successful."
|
||||
"Use the speak tool and say exactly round trip successful.",
|
||||
);
|
||||
const pcm = await streamToBuffer(generated.stream as AsyncIterable<unknown>);
|
||||
|
||||
@@ -143,20 +147,20 @@ async function main(): Promise<void> {
|
||||
await client.sendVoiceAudioChunk(
|
||||
chunk.toString("base64"),
|
||||
"audio/pcm;rate=24000;bits=16",
|
||||
isLast
|
||||
isLast,
|
||||
);
|
||||
}
|
||||
|
||||
await Promise.race([
|
||||
firstAudio,
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error("Timed out waiting for first audio_output")), 120000)
|
||||
setTimeout(() => reject(new Error("Timed out waiting for first audio_output")), 120000),
|
||||
),
|
||||
]);
|
||||
await Promise.race([
|
||||
lastAudio,
|
||||
new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error("Timed out waiting for final audio_output")), 120000)
|
||||
setTimeout(() => reject(new Error("Timed out waiting for final audio_output")), 120000),
|
||||
),
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user