feat: enhance Conversations component with detailed logging and tool call execution

- Updated the inference request structure to improve type safety and added comprehensive logging for both requests and responses.
- Modified tool call execution to handle only the latest tool call while sending placeholders for previous calls.
- Implemented error handling for tool results, ensuring proper logging and formatting of error messages.
- Introduced a timeout parameter for network requests in the ops_net module to enhance request reliability.
This commit is contained in:
M3gA-Mind
2026-03-10 05:24:16 +05:30
parent 9436fdef1c
commit 65baaaced5
2 changed files with 54 additions and 7 deletions
@@ -20,6 +20,10 @@ pub fn register<'js>(ctx: &Ctx<'js>, ops: &Object<'js>, ws_state: Arc<RwLock<Web
let method = opts["method"].as_str().unwrap_or("GET");
let headers_obj = opts["headers"].as_object();
let body = opts["body"].as_str();
let timeout_secs = opts["timeout"]
.as_u64()
.or_else(|| opts["timeout"].as_f64().map(|f| f as u64))
.unwrap_or(30);
let client = reqwest::Client::builder()
.use_rustls_tls()
@@ -29,10 +33,13 @@ pub fn register<'js>(ctx: &Ctx<'js>, ops: &Object<'js>, ws_state: Arc<RwLock<Web
"GET" => client.get(&url),
"POST" => client.post(&url),
"PUT" => client.put(&url),
"PATCH" => client.patch(&url),
"DELETE" => client.delete(&url),
_ => client.get(&url),
};
req = req.timeout(std::time::Duration::from_secs(timeout_secs));
if let Some(h) = headers_obj {
for (k, v) in h {
if let Some(val_str) = v.as_str() {
+47 -7
View File
@@ -381,12 +381,27 @@ const Conversations = () => {
const MAX_TOOL_ROUNDS = 5;
for (let round = 0; round < MAX_TOOL_ROUNDS; round++) {
const response = await inferenceApi.createChatCompletion({
const request: Parameters<typeof inferenceApi.createChatCompletion>[0] = {
model: selectedModel,
messages: loopMessages,
...(allSkillTools.length > 0 ? { tools: allSkillTools, tool_choice: 'auto' } : {}),
...(allSkillTools.length > 0
? { tools: allSkillTools, tool_choice: 'auto' as const }
: {}),
};
console.log('[Conversations] inference request:', {
round: round + 1,
model: request.model,
messageCount: request.messages.length,
tools: request.tools?.length ?? 0,
payload: request,
});
const response = await inferenceApi.createChatCompletion(request);
console.log('[Conversations] inference response:', {
round: round + 1,
choices: response.choices?.length ?? 0,
usage: response.usage,
payload: response,
});
console.log('🚀 ~ handleSendMessage ~ response:', response);
const choice = response.choices[0];
if (!choice) break;
@@ -401,8 +416,19 @@ const Conversations = () => {
tool_calls: message.tool_calls,
});
// Execute each tool and collect results
for (const tc of message.tool_calls) {
const latestIndex = message.tool_calls.length - 1;
// API requires a tool message for every tool_call_id; we execute only the latest and send placeholders for the rest
for (let i = 0; i < message.tool_calls.length; i++) {
const tc = message.tool_calls[i];
if (i !== latestIndex) {
loopMessages.push({
role: 'tool',
tool_call_id: tc.id,
content: '',
});
continue;
}
const dunderIdx = tc.function.name.indexOf('__');
const skillId = dunderIdx !== -1 ? tc.function.name.substring(0, dunderIdx) : '';
const toolName =
@@ -426,12 +452,26 @@ const Conversations = () => {
);
const result = await skillManager.callTool(skillId, toolName, toolArgs);
toolResultContent = result.content.map(c => c.text).join('\n');
if (result.isError) {
let toolReturnedError = result.isError;
if (!toolReturnedError && toolResultContent) {
try {
const parsed = JSON.parse(toolResultContent) as Record<string, unknown>;
if (parsed && typeof parsed.error === 'string') {
toolReturnedError = true;
toolResultContent = `Error: ${parsed.error}`;
}
} catch {
// not JSON or no error key — keep content as-is
}
}
if (toolReturnedError) {
console.warn(
`[Conversations] tool "${toolName}" returned an error:`,
toolResultContent
);
toolResultContent = `Error: ${toolResultContent}`;
if (!toolResultContent.startsWith('Error: ')) {
toolResultContent = `Error: ${toolResultContent}`;
}
} else {
console.log(
`[Conversations] tool "${toolName}" succeeded:`,