feat(websearch): add managed mcp runtime and provider cooldowns

- switch ccs-websearch MCP to stdio-first framing and keep legacy compatibility

- add cooldown persistence and bounded retries for provider failures

- surface cooldown status in readiness output and regression tests
This commit is contained in:
Tam Nhu Tran committed 2026-03-31 14:22:11 -04:00
1 parent cae5b710b8
commit 7f83e041b7
10 files changed
+1115 -63

No files matched your search

+38 -20
View File
@@ -61,9 +61,7 @@ function getTools() {
}
function writeMessage(message) {
const body = Buffer.from(JSON.stringify(message), 'utf8');
process.stdout.write(`Content-Length: ${body.length}\r\n\r\n`);
process.stdout.write(body);
process.stdout.write(`${JSON.stringify(message)}\n`);
}
function writeResponse(id, result) {
@@ -262,26 +260,46 @@ function writeSessionSummary(exitCodeOrSignal) {
function parseMessages() {
while (true) {
const headerEnd = inputBuffer.indexOf('\r\n\r\n');
if (headerEnd === -1) {
return;
}
let body;
const startsWithLegacyHeaders = inputBuffer
.slice(0, Math.min(inputBuffer.length, 32))
.toString('utf8')
.toLowerCase()
.startsWith('content-length:');
const headerText = inputBuffer.slice(0, headerEnd).toString('utf8');
const contentLengthMatch = headerText.match(/content-length:\s*(\d+)/i);
if (!contentLengthMatch) {
inputBuffer = Buffer.alloc(0);
return;
}
if (startsWithLegacyHeaders) {
const headerEnd = inputBuffer.indexOf('\r\n\r\n');
if (headerEnd === -1) {
return;
}
const contentLength = Number.parseInt(contentLengthMatch[1], 10);
const messageEnd = headerEnd + 4 + contentLength;
if (inputBuffer.length < messageEnd) {
return;
}
const headerText = inputBuffer.slice(0, headerEnd).toString('utf8');
const contentLengthMatch = headerText.match(/content-length:\s*(\d+)/i);
if (!contentLengthMatch) {
inputBuffer = Buffer.alloc(0);
return;
}
const body = inputBuffer.slice(headerEnd + 4, messageEnd).toString('utf8');
inputBuffer = inputBuffer.slice(messageEnd);
const contentLength = Number.parseInt(contentLengthMatch[1], 10);
const messageEnd = headerEnd + 4 + contentLength;
if (inputBuffer.length < messageEnd) {
return;
}
body = inputBuffer.slice(headerEnd + 4, messageEnd).toString('utf8');
inputBuffer = inputBuffer.slice(messageEnd);
} else {
const newlineIndex = inputBuffer.indexOf('\n');
if (newlineIndex === -1) {
return;
}
body = inputBuffer.slice(0, newlineIndex).toString('utf8').replace(/\r$/, '').trim();
inputBuffer = inputBuffer.slice(newlineIndex + 1);
if (!body) {
continue;
}
}
let message;
try {