'use strict'; import chalk from 'chalk'; import { input } from '@inquirer/prompts'; import { defineTool } from 'llmorbiter'; import { emitToolCall, clip } from './notify.js'; export const askExpertTool = defineTool({ name: 'ask_an_expert', description: 'Escalate to a human expert when you are genuinely stuck (a confusing or unclear problem, or ' + 'you have tried and are still spinning). Do not use it for things you can resolve yourself. ' + 'Question shown to user as copy-pasteable block for their expert; reply returned to you. ' + 'Self-contained `question`; put supporting detail (errors, code, what you tried) in optional `context`.', parameters: { type: 'object', additionalProperties: false, required: ['question'], properties: { question: { type: 'string', description: 'Question for the expert. Concise & specific.', }, context: { type: 'string', description: 'Opt supporting detail the expert needs (errors, code, what you tried).', }, }, }, invoke: async ({ question, context = '' }) => { const hasContext = context && context.trim().length > 0; // Present the question as a single, self-contained block the user can // select and copy straight into a chat with their expert. const lines = [hasContext ? `Question: ${question}` : question]; if (hasContext) { lines.push('', 'Context:', context.trim()); } const message = lines.join('\n'); console.log(''); console.log(chalk.blue.bold(' 🧑\u200d🔬 Ask an expert — copy & paste this to your expert:')); console.log(chalk.dim(' ┌' + '─'.repeat(60))); for (const line of message.split('\n')) { console.log(chalk.white(' │ ' + line)); } console.log(chalk.dim(' └' + '─'.repeat(60))); console.log(''); // Wait for the user to bring back the expert's answer. const answer = await input({ message: chalk.bold.blue("Expert's answer (paste it here)"), prefix: chalk.blue('›'), theme: { prefix: chalk.blue('›'), style: { answer: chalk.white, message: chalk.bold.blue }, }, }); console.log(''); return { answer }; }, }); /** * Call notification: the question being put to the expert. */ export function notifyCall(args = {}) { emitToolCall(askExpertTool.name, clip(JSON.stringify(args.question ?? ''))); }