@kbediako/codex-orchestrator 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -826,11 +826,47 @@ async function runJsonRpcServer(handler, options = {}) {
|
|
|
826
826
|
const body = buffer.slice(0, expectedLength);
|
|
827
827
|
buffer = buffer.slice(expectedLength);
|
|
828
828
|
expectedLength = null;
|
|
829
|
-
await handleMessage(body.toString('utf8'));
|
|
829
|
+
await handleMessage(body.toString('utf8'), 'framed');
|
|
830
830
|
continue;
|
|
831
831
|
}
|
|
832
832
|
const headerEnd = buffer.indexOf('\r\n\r\n');
|
|
833
833
|
if (headerEnd === -1) {
|
|
834
|
+
const newlineIndex = buffer.indexOf('\n');
|
|
835
|
+
if (newlineIndex !== -1) {
|
|
836
|
+
const lineBuffer = buffer.slice(0, newlineIndex);
|
|
837
|
+
const line = lineBuffer.toString('utf8').trim();
|
|
838
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
839
|
+
if (!line) {
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
const normalizedLine = line.trimStart();
|
|
843
|
+
const looksLikeHeaderLine = /^[A-Za-z0-9-]+:/.test(normalizedLine);
|
|
844
|
+
const looksLikeJson = normalizedLine.startsWith('{') || normalizedLine.startsWith('[');
|
|
845
|
+
const isContentLength = normalizedLine.toLowerCase().startsWith('content-length:');
|
|
846
|
+
let restoredHeader = false;
|
|
847
|
+
if (!looksLikeJson && looksLikeHeaderLine) {
|
|
848
|
+
// Fall through to header-size checks for partial Content-Length frames (and other header lines).
|
|
849
|
+
buffer = Buffer.concat([Buffer.from(lineBuffer), Buffer.from('\n'), buffer]);
|
|
850
|
+
restoredHeader = true;
|
|
851
|
+
}
|
|
852
|
+
else if (!isContentLength) {
|
|
853
|
+
const lineBytes = Buffer.byteLength(line, 'utf8');
|
|
854
|
+
if (lineBytes > MAX_MCP_MESSAGE_BYTES) {
|
|
855
|
+
handleProtocolViolation(`Rejecting MCP payload (${lineBytes} bytes) larger than ${MAX_MCP_MESSAGE_BYTES}`);
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
await handleMessage(line, 'jsonl');
|
|
859
|
+
continue;
|
|
860
|
+
}
|
|
861
|
+
if (!restoredHeader && isContentLength) {
|
|
862
|
+
// Fall through to header-size checks for partial Content-Length frames.
|
|
863
|
+
buffer = Buffer.concat([Buffer.from(lineBuffer), Buffer.from('\n'), buffer]);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
else if (buffer.length > MAX_MCP_MESSAGE_BYTES) {
|
|
867
|
+
handleProtocolViolation(`Rejecting MCP payload (${buffer.length} bytes) larger than ${MAX_MCP_MESSAGE_BYTES}`);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
834
870
|
if (buffer.length > MAX_MCP_HEADER_BYTES) {
|
|
835
871
|
const overflow = buffer.slice(MAX_MCP_HEADER_BYTES);
|
|
836
872
|
const allowedPrefix = MCP_HEADER_DELIMITER_BUFFER.subarray(0, overflow.length);
|
|
@@ -851,6 +887,19 @@ async function runJsonRpcServer(handler, options = {}) {
|
|
|
851
887
|
return;
|
|
852
888
|
}
|
|
853
889
|
if (parsed.length === null) {
|
|
890
|
+
const lines = header.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
891
|
+
if (lines.length === 0) {
|
|
892
|
+
buffer = buffer.slice(headerEnd + 4);
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
const allJsonLike = lines.every((line) => line.startsWith('{') || line.startsWith('['));
|
|
896
|
+
if (allJsonLike) {
|
|
897
|
+
buffer = buffer.slice(headerEnd + 4);
|
|
898
|
+
for (const line of lines) {
|
|
899
|
+
await handleMessage(line, 'jsonl');
|
|
900
|
+
}
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
854
903
|
handleProtocolViolation('Missing Content-Length header in MCP message');
|
|
855
904
|
return;
|
|
856
905
|
}
|
|
@@ -867,7 +916,7 @@ async function runJsonRpcServer(handler, options = {}) {
|
|
|
867
916
|
buffer = buffer.slice(headerEnd + 4);
|
|
868
917
|
}
|
|
869
918
|
}
|
|
870
|
-
async function handleMessage(raw) {
|
|
919
|
+
async function handleMessage(raw, format) {
|
|
871
920
|
let request;
|
|
872
921
|
try {
|
|
873
922
|
request = JSON.parse(raw);
|
|
@@ -883,7 +932,7 @@ async function runJsonRpcServer(handler, options = {}) {
|
|
|
883
932
|
try {
|
|
884
933
|
const result = await handler(request);
|
|
885
934
|
if (id !== null && typeof id !== 'undefined') {
|
|
886
|
-
sendResponse({ jsonrpc: '2.0', id, result }, output);
|
|
935
|
+
sendResponse({ jsonrpc: '2.0', id, result }, output, format);
|
|
887
936
|
}
|
|
888
937
|
}
|
|
889
938
|
catch (error) {
|
|
@@ -892,7 +941,7 @@ async function runJsonRpcServer(handler, options = {}) {
|
|
|
892
941
|
jsonrpc: '2.0',
|
|
893
942
|
id,
|
|
894
943
|
error: { code: -32603, message: error?.message ?? String(error) }
|
|
895
|
-
}, output);
|
|
944
|
+
}, output, format);
|
|
896
945
|
}
|
|
897
946
|
}
|
|
898
947
|
}
|
|
@@ -920,10 +969,15 @@ function parseContentLengthHeader(header) {
|
|
|
920
969
|
}
|
|
921
970
|
return { length: contentLength };
|
|
922
971
|
}
|
|
923
|
-
function sendResponse(response, output = process.stdout) {
|
|
924
|
-
const payload =
|
|
925
|
-
|
|
926
|
-
|
|
972
|
+
function sendResponse(response, output = process.stdout, format = 'framed') {
|
|
973
|
+
const payload = JSON.stringify(response);
|
|
974
|
+
if (format === 'jsonl') {
|
|
975
|
+
output.write(`${payload}\n`);
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const buffer = Buffer.from(payload, 'utf8');
|
|
979
|
+
const header = Buffer.from(`Content-Length: ${buffer.length}\r\n\r\n`, 'utf8');
|
|
980
|
+
output.write(Buffer.concat([header, buffer]));
|
|
927
981
|
}
|
|
928
982
|
function safeJsonParse(text) {
|
|
929
983
|
try {
|