u
This commit is contained in:
76
src/tools/ask-expert.js
Normal file
76
src/tools/ask-expert.js
Normal file
@@ -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 ?? '')));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user