All files / src chat.ts

54.16% Statements 13/24
33.33% Branches 3/9
33.33% Functions 1/3
56.52% Lines 13/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69  2x     2x           3x   3x   3x                       3x 3x 1x                       3x   3x   3x 3x                                     3x        
import { SeraphConfig } from './config';
import { createLLMProvider } from './llm';
import { AgentTool } from './mcp-manager';
 
export async function chat(
  message: string,
  config: SeraphConfig,
  tools: AgentTool[],
  logs?: string[],
): Promise<string> {
  const provider = createLLMProvider(config);
 
  let systemPrompt = `You are a helpful AI assistant. You have access to a set of tools to help you answer the user's question.`
 
  Iif (tools.length > 0) {
    systemPrompt += `
 
Available tools:
${tools.map((tool) => `- ${tool.name}: ${tool.description}`).join('\n')}
 
You can call a tool by responding with a JSON object with two fields: "tool" and "args".
The "tool" field should be the name of the tool to call.
The "args" field should be an object with the arguments to pass to the tool.
`;
  }
 
  let prompt = message;
  if (logs && logs.length > 0) {
    prompt = `
      Based on the following recent logs, answer the user's question.
 
      Logs:
      ${logs.join('\n')}
 
      Question:
      ${message}
      `;
  }
 
  // Add the system prompt to the beginning of the prompt
  prompt = `${systemPrompt}\n\n${prompt}`;
 
  const response = await provider.generate(prompt);
 
  try {
    const responseObject = JSON.parse(response);
    Iif (responseObject.tool && responseObject.args) {
      const tool = tools.find((t) => t.name === responseObject.tool);
      if (tool) {
        console.log(`Calling tool: ${tool.name}`);
        const toolResult = await tool.execute(responseObject.args);
        // We can recursively call chat to process the tool's output
        return chat(
          `The tool ${tool.name} returned the following result: ${toolResult}`,
          config,
          tools,
          logs,
        );
      } else {
        return `Unknown tool: ${responseObject.tool}`;
      }
    }
  } catch (error) {
    // If the response is not a valid JSON object, it's a regular message
    return response;
  }
 
  return response;
}