72 lines
2.6 KiB
JavaScript
72 lines
2.6 KiB
JavaScript
'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 ?? '')));
|
||
}
|