From b80e4dd7de0e7c68ea50121ab9d69c4d6dc7f618 Mon Sep 17 00:00:00 2001 From: seb Date: Wed, 23 Sep 2026 01:26:47 +0200 Subject: [PATCH] u --- src/tools/ask-expert.js | 76 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/tools/ask-expert.js diff --git a/src/tools/ask-expert.js b/src/tools/ask-expert.js new file mode 100644 index 0000000..84b4370 --- /dev/null +++ b/src/tools/ask-expert.js @@ -0,0 +1,76 @@ +'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: + 'Ask a human expert a question. Use this ONLY as a last resort, but you ' + + 'MUST use it every time something is confusing, unclear, or progress ' + + 'seems difficult—do not keep guessing or spinning. The question is ' + + 'presented to the user as a copy-pasteable block that they can hand to an ' + + 'expert, and their reply (the expert\'s answer) is returned to you. ' + + 'Provide a self-contained `question`; put any supporting detail the ' + + 'expert will need (error messages, code, what you already tried) in the ' + + 'optional `context`.', + parameters: { + type: 'object', + additionalProperties: false, + required: ['question'], + properties: { + question: { + type: 'string', + description: 'The question to put to the expert. Keep it concise and specific.', + }, + context: { + type: 'string', + description: + 'Optional supporting detail the expert needs to answer well ' + + '(error messages, relevant code, what you already tried, etc.).', + }, + }, + }, + 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 ?? ''))); +}