fix: address PR review feedback for subprocess cleanup and binary resolution
Wrap SDK query loop in try/finally so subprocess cleanup runs on error paths. Swap Chroma binary check order to try project-level .bin first (common case). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -115,14 +115,15 @@ export class ChromaServerManager {
|
|||||||
try {
|
try {
|
||||||
// chromadb package installs a 'chroma' bin entry
|
// chromadb package installs a 'chroma' bin entry
|
||||||
const chromaBinDir = path.dirname(require.resolve('chromadb/package.json'));
|
const chromaBinDir = path.dirname(require.resolve('chromadb/package.json'));
|
||||||
const chromaBin = path.join(chromaBinDir, 'node_modules', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
|
// Check project-level .bin first (most common npm/bun installation layout)
|
||||||
// Fallback: check project-level .bin
|
|
||||||
const projectBin = path.join(chromaBinDir, '..', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
|
const projectBin = path.join(chromaBinDir, '..', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
|
||||||
|
// Fallback: nested node_modules .bin (rare — pnpm or workspace hoisting)
|
||||||
|
const nestedBin = path.join(chromaBinDir, 'node_modules', '.bin', isWindows ? 'chroma.cmd' : 'chroma');
|
||||||
|
|
||||||
if (existsSync(chromaBin)) {
|
if (existsSync(projectBin)) {
|
||||||
command = chromaBin;
|
|
||||||
} else if (existsSync(projectBin)) {
|
|
||||||
command = projectBin;
|
command = projectBin;
|
||||||
|
} else if (existsSync(nestedBin)) {
|
||||||
|
command = nestedBin;
|
||||||
} else {
|
} else {
|
||||||
// Last resort: npx with explicit cwd
|
// Last resort: npx with explicit cwd
|
||||||
command = isWindows ? 'npx.cmd' : 'npx';
|
command = isWindows ? 'npx.cmd' : 'npx';
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ export class SDKAgent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Process SDK messages
|
// Process SDK messages — cleanup in finally ensures subprocess termination
|
||||||
|
// even if the loop throws (e.g., context overflow, invalid API key)
|
||||||
|
try {
|
||||||
for await (const message of queryResult) {
|
for await (const message of queryResult) {
|
||||||
// Capture or update memory session ID from SDK message
|
// Capture or update memory session ID from SDK message
|
||||||
// IMPORTANT: The SDK may return a DIFFERENT session_id on resume than what we sent!
|
// IMPORTANT: The SDK may return a DIFFERENT session_id on resume than what we sent!
|
||||||
@@ -271,12 +273,13 @@ export class SDKAgent {
|
|||||||
// Usage telemetry is captured at SDK level
|
// Usage telemetry is captured at SDK level
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
// Ensure subprocess is terminated after query completes
|
// Ensure subprocess is terminated after query completes (or on error)
|
||||||
const tracked = getProcessBySession(session.sessionDbId);
|
const tracked = getProcessBySession(session.sessionDbId);
|
||||||
if (tracked && !tracked.process.killed && tracked.process.exitCode === null) {
|
if (tracked && !tracked.process.killed && tracked.process.exitCode === null) {
|
||||||
await ensureProcessExit(tracked, 5000);
|
await ensureProcessExit(tracked, 5000);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mark session complete
|
// Mark session complete
|
||||||
const sessionDuration = Date.now() - session.startTime;
|
const sessionDuration = Date.now() - session.startTime;
|
||||||
|
|||||||
Reference in New Issue
Block a user