Fixed message history and response
Publish Library / Build NPM Project (push) Successful in 59s
Publish Library / Tag Version (push) Successful in 22s

This commit is contained in:
2026-08-03 19:30:39 -04:00
parent afc6653364
commit 89619e211e
5 changed files with 44 additions and 34 deletions
+20 -13
View File
@@ -20,15 +20,17 @@ export class OpenAi extends LLMProvider {
for(let i = 0; i < history.length; i++) {
const h = history[i];
if(h.role === 'assistant' && h.tool_calls) {
const tools = h.tool_calls.map((tc: any) => ({
const items: any[] = [];
if(h.content) items.push({role: 'assistant', content: h.content, timestamp: h.timestamp});
items.push(...h.tool_calls.map((tc: any) => ({
role: 'tool',
id: tc.id,
name: tc.function.name,
args: JSONAttemptParse(tc.function.arguments, {}),
timestamp: h.timestamp
}));
history.splice(i, 1, ...tools);
i += tools.length - 1;
})));
history.splice(i, 1, ...items);
i += items.length - 1;
} else if(h.role === 'tool') {
const record = history.find(h2 => h.tool_call_id == h2.id);
if(record) {
@@ -108,7 +110,7 @@ export class OpenAi extends LLMProvider {
};
}
let resp: any, hasStreamedText = false, terminal = false;
let resp: any, terminal = false;
do {
requestParams.messages = history.map(({timestamp, ...m}) => m);
resp = await this.client.chat.completions.create(requestParams).catch(err => {
@@ -117,14 +119,12 @@ export class OpenAi extends LLMProvider {
});
if(options.stream) {
if(hasStreamedText) options.stream({text: '\n\n'});
resp.choices = [{message: {role: 'assistant', content: '', tool_calls: [], timestamp: Date.now()}}];
for await (const chunk of resp) {
if(controller.signal.aborted) break;
if(chunk.choices[0].delta.content) {
const text = chunk.choices[0].delta.content;
resp.choices[0].message.content += text;
if(text) { hasStreamedText = true; options.stream({text}); }
resp.choices[0].message.content += chunk.choices[0].delta.content;
options.stream({text: chunk.choices[0].delta.content});
}
if(chunk.choices[0].delta.tool_calls) {
for(const deltaTC of chunk.choices[0].delta.tool_calls) {
@@ -168,7 +168,7 @@ export class OpenAi extends LLMProvider {
if(chunk.done) { terminal = true; return; }
options.stream!(chunk);
});
const result = await tool.fn(args, toolStream, this.ai);
const result = await tool.fn(args, toolStream, this.ai, toolCall.id);
return {role: 'tool', tool_call_id: toolCall.id, content: typeof result == 'object' ? JSONSanitize(result) : result, timestamp: Date.now()};
} catch (err: any) {
return {role: 'tool', tool_call_id: toolCall.id, content: JSONSanitize({error: err?.message || err?.toString() || 'Unknown'}), timestamp: Date.now()};
@@ -180,13 +180,20 @@ export class OpenAi extends LLMProvider {
} while (!terminal && !controller.signal.aborted && resp.choices?.[0]?.message?.tool_calls?.length);
if(!terminal) {
const textContent = resp.choices[0].message.content?.trim() || '';
history.push({role: 'assistant', content: textContent, timestamp: Date.now()});
const textContent = resp.choices[0].message.content || '';
history.push({role: 'assistant', content: textContent.trim(), timestamp: Date.now()});
}
history = this.toStandard(history);
if(options.history) options.history.splice(0, options.history.length, ...history.filter(h => h.role !== 'system'));
if(options.stream) options.stream({done: true});
const finalContent = history.at(-1)?.content;
const turnStart = history.map(h => h.role).lastIndexOf('user');
const finalContent = history.slice(turnStart + 1).reduce((str, h) => {
if(h.role === 'assistant') return str + (h.content || '');
if(h.role === 'tool') return str + `<tool>${h.name}</tool>\n\n`;
return str;
}, '').trim();
res(options.schema ? JSONAttemptParse(finalContent, finalContent) : finalContent);
}), {abort: () => controller.abort()});
}