UNPKG

@nanocollective/nanocoder

Version:

A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter

66 lines 3.27 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { Box, Text } from 'ink'; import React from 'react'; import ToolMessage from '../components/tool-message.js'; import { ThemeContext } from '../hooks/useTheme.js'; import { jsonSchema, tool } from '../types/core.js'; import { signalQuestion } from '../utils/question-queue.js'; const executeAskQuestion = async (args) => { const { question, options, allowFreeform = true } = args; if (!options || options.length < 2 || options.length > 4) { return 'Error: ⚒ options must contain 2-4 items.'; } const answer = await signalQuestion({ question, options, allowFreeform, }); return answer; }; const askQuestionCoreTool = tool({ description: 'Ask the user a question with selectable options. Use when you need clarification, a decision between approaches, or user preference. The user sees the question with clickable options and can optionally type a custom answer. Returns the selected answer as a string. IMPORTANT: Never re-ask a question the user has already answered. Accept their response and proceed.', inputSchema: jsonSchema({ type: 'object', properties: { question: { type: 'string', description: 'The question to ask the user.', }, options: { type: 'array', items: { type: 'string' }, description: '2-4 selectable answer options for the user to choose from.', }, allowFreeform: { type: 'boolean', description: 'If true (default), adds a "Type custom answer..." option so the user can provide their own response.', }, }, required: ['question', 'options'], }), needsApproval: false, execute: async (args, _options) => { return await executeAskQuestion(args); }, }); const AskQuestionFormatter = React.memo(({ args, result }) => { const themeContext = React.useContext(ThemeContext); if (!themeContext) { throw new Error('ThemeContext not found'); } const { colors } = themeContext; const messageContent = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.tool, children: "\u2692 ask_user" }), _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: colors.secondary, children: "Question:" }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.text, children: args.question }) })] }), result && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.secondary, children: "Answer:" }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: colors.text, children: result }) })] }))] })); return _jsx(ToolMessage, { message: messageContent, hideBox: true }); }); const askQuestionFormatter = (args, result) => { if (result && result.startsWith('Error:')) { return _jsx(_Fragment, {}); } return _jsx(AskQuestionFormatter, { args: args, result: result }); }; export const askQuestionTool = { name: 'ask_user', tool: askQuestionCoreTool, formatter: askQuestionFormatter, }; //# sourceMappingURL=ask-question.js.map