Vendored
+44
-6
@@ -9,6 +9,7 @@ const catalog = require('./catalog.js');
|
||||
const device = require('./device.js');
|
||||
const events = require('./events.js');
|
||||
const paths = require('./paths.js');
|
||||
const completeWatch = require('./complete-watch.js');
|
||||
|
||||
let sdk = null;
|
||||
let initError = null;
|
||||
@@ -377,11 +378,29 @@ async function complete(opts, onEvent) {
|
||||
let text = '';
|
||||
let thinking = '';
|
||||
const toolCalls = [];
|
||||
try {
|
||||
const abortRun = () => {
|
||||
try {
|
||||
if (run && typeof run.abort === 'function') run.abort();
|
||||
else if (sdk && typeof sdk.abortCompletion === 'function' && requestId) sdk.abortCompletion({ requestId });
|
||||
} catch (_) {}
|
||||
};
|
||||
let settleTimeout;
|
||||
const timedOutGate = new Promise((resolve) => {
|
||||
settleTimeout = () => resolve('timeout');
|
||||
});
|
||||
const watch = completeWatch.attachCompleteWatch({
|
||||
timeoutMs: opts && opts.timeoutMs,
|
||||
idleMs: opts && opts.idleMs,
|
||||
abort: abortRun,
|
||||
onTimeout: settleTimeout,
|
||||
});
|
||||
const consume = (async () => {
|
||||
if (run.events && typeof run.events[Symbol.asyncIterator] === 'function') {
|
||||
for await (const ev of run.events) {
|
||||
if (watch.timedOut()) return;
|
||||
const n = events.normalizeCompletionEvent(ev);
|
||||
if (!n) continue;
|
||||
watch.bump();
|
||||
if (n.type === 'contentDelta') {
|
||||
text += n.delta;
|
||||
if (onEvent) onEvent(n);
|
||||
@@ -397,18 +416,22 @@ async function complete(opts, onEvent) {
|
||||
}
|
||||
} else if (run.tokenStream) {
|
||||
for await (const token of run.tokenStream) {
|
||||
if (watch.timedOut()) return;
|
||||
watch.bump();
|
||||
text += token;
|
||||
if (onEvent) onEvent({ type: 'contentDelta', delta: token });
|
||||
}
|
||||
if (run.toolCallStream) {
|
||||
for await (const evt of run.toolCallStream) {
|
||||
if (watch.timedOut()) return;
|
||||
watch.bump();
|
||||
const call = evt.call || evt;
|
||||
toolCalls.push(call);
|
||||
if (onEvent) onEvent({ type: 'toolCall', call });
|
||||
}
|
||||
}
|
||||
}
|
||||
let stats = null;
|
||||
if (watch.timedOut()) return;
|
||||
try {
|
||||
if (run.final) {
|
||||
const fin = await run.final;
|
||||
@@ -419,14 +442,29 @@ async function complete(opts, onEvent) {
|
||||
toolCalls.length = 0;
|
||||
for (const c of fin.toolCalls) toolCalls.push(c);
|
||||
}
|
||||
stats = fin.stats || null;
|
||||
}
|
||||
} else if (run.stats) {
|
||||
stats = await run.stats;
|
||||
}
|
||||
} catch (_) {}
|
||||
return { text, thinking, toolCalls, stats, requestId, stopReason: 'stop' };
|
||||
})();
|
||||
consume.catch(() => {});
|
||||
try {
|
||||
await Promise.race([consume, timedOutGate]);
|
||||
let stats = null;
|
||||
if (!watch.timedOut()) {
|
||||
try {
|
||||
if (run.stats) stats = await run.stats;
|
||||
} catch (_) {}
|
||||
}
|
||||
return {
|
||||
text,
|
||||
thinking,
|
||||
toolCalls,
|
||||
stats,
|
||||
requestId,
|
||||
stopReason: watch.timedOut() ? 'timeout' : 'stop',
|
||||
};
|
||||
} finally {
|
||||
watch.clear();
|
||||
if (requestId) activeRequests.delete(requestId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user