agentk8 2.2.6 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export interface ConfirmationOption {
3
+ label: string;
4
+ value: string;
5
+ key?: string;
6
+ }
7
+ export interface ConfirmationProps {
8
+ message: string;
9
+ options: ConfirmationOption[];
10
+ onSelect: (value: string) => void;
11
+ onCancel: () => void;
12
+ }
13
+ export declare const Confirmation: React.FC<ConfirmationProps>;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ const theme = {
5
+ selected: '#4fd1c5', // teal-400
6
+ unselected: '#a0aec0', // gray-400
7
+ message: '#e2e8f0', // gray-200
8
+ key: '#718096', // gray-500
9
+ border: '#2d3748', // gray-800
10
+ };
11
+ export const Confirmation = ({ message, options, onSelect, onCancel, }) => {
12
+ const [selectedIndex, setSelectedIndex] = useState(0);
13
+ useInput((input, key) => {
14
+ if (key.upArrow) {
15
+ setSelectedIndex((prev) => (prev > 0 ? prev - 1 : options.length - 1));
16
+ }
17
+ else if (key.downArrow) {
18
+ setSelectedIndex((prev) => (prev < options.length - 1 ? prev + 1 : 0));
19
+ }
20
+ else if (key.return) {
21
+ onSelect(options[selectedIndex].value);
22
+ }
23
+ else if (key.escape) {
24
+ onCancel();
25
+ }
26
+ else {
27
+ // Handle number keys (1-9)
28
+ const num = parseInt(input, 10);
29
+ if (!isNaN(num) && num > 0 && num <= options.length) {
30
+ onSelect(options[num - 1].value);
31
+ }
32
+ }
33
+ });
34
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border, padding: 1, children: [_jsx(Text, { color: theme.message, bold: true, children: message }), _jsx(Box, { height: 1 }), options.map((option, index) => {
35
+ const isSelected = index === selectedIndex;
36
+ const prefix = isSelected ? '❯' : ' ';
37
+ return (_jsxs(Box, { marginLeft: 1, children: [_jsxs(Text, { color: isSelected ? theme.selected : theme.unselected, children: [prefix, " ", index + 1, ". ", option.label] }), option.key && (_jsx(Box, { marginLeft: 1, children: _jsxs(Text, { color: theme.key, children: ["(", option.key, ")"] }) }))] }, option.value));
38
+ }), _jsx(Box, { height: 1 }), _jsx(Text, { color: theme.key, dimColor: true, children: "Use \u2191/\u2193 to navigate, Enter to select, Esc to cancel" })] }));
39
+ };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ export interface QuestionOption {
3
+ label: string;
4
+ recommended?: boolean;
5
+ }
6
+ export interface Question {
7
+ header: string;
8
+ question: string;
9
+ options: QuestionOption[];
10
+ answer?: string;
11
+ }
12
+ export interface QuestionWizardProps {
13
+ questions: Question[];
14
+ onComplete: (answers: {
15
+ header: string;
16
+ answer: string;
17
+ }[]) => void;
18
+ onCancel: () => void;
19
+ }
20
+ export declare const QuestionWizard: React.NamedExoticComponent<QuestionWizardProps>;
21
+ export default QuestionWizard;
@@ -0,0 +1,152 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useState, useCallback, memo } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ const theme = {
5
+ border: '#2d3748',
6
+ accent: '#4fd1c5',
7
+ highlight: '#81e6d9',
8
+ text: '#e2e8f0',
9
+ dim: '#4a5568',
10
+ selected: '#4fd1c5',
11
+ unselected: '#718096',
12
+ answered: '#48bb78',
13
+ header: '#63b3ed',
14
+ no: '#e53e3e',
15
+ };
16
+ const QuestionWizardInner = ({ questions: initialQuestions, onComplete, onCancel, }) => {
17
+ // Single state object for atomic updates
18
+ const [state, setState] = useState({
19
+ questions: initialQuestions,
20
+ currentIndex: 0,
21
+ selectedOption: 0,
22
+ customInputMode: false,
23
+ customInputValue: '',
24
+ cursorPosition: 0,
25
+ });
26
+ const { questions, currentIndex, selectedOption, customInputMode, customInputValue, cursorPosition } = state;
27
+ const currentQuestion = questions[currentIndex];
28
+ const allOptions = [...currentQuestion.options, { label: 'No', recommended: false }];
29
+ const isOnNoOption = selectedOption === allOptions.length - 1;
30
+ const termWidth = process.stdout.columns || 80;
31
+ // Update state atomically
32
+ const updateState = useCallback((updates) => {
33
+ setState(prev => ({ ...prev, ...updates }));
34
+ }, []);
35
+ // Set answer and optionally advance
36
+ const selectOption = useCallback((answer, shouldAdvance) => {
37
+ setState(prev => {
38
+ const updatedQuestions = [...prev.questions];
39
+ updatedQuestions[prev.currentIndex] = {
40
+ ...updatedQuestions[prev.currentIndex],
41
+ answer
42
+ };
43
+ // Check if this is the last question and all are answered
44
+ const isLast = prev.currentIndex === prev.questions.length - 1;
45
+ const allAnswered = updatedQuestions.every(q => q.answer !== undefined);
46
+ if (isLast && allAnswered) {
47
+ // Will complete after state update
48
+ setTimeout(() => {
49
+ onComplete(updatedQuestions.map(q => ({
50
+ header: q.header,
51
+ answer: q.answer || '',
52
+ })));
53
+ }, 0);
54
+ return prev; // Keep current state, will unmount soon
55
+ }
56
+ return {
57
+ ...prev,
58
+ questions: updatedQuestions,
59
+ currentIndex: shouldAdvance && !isLast ? prev.currentIndex + 1 : prev.currentIndex,
60
+ selectedOption: shouldAdvance && !isLast ? 0 : prev.selectedOption,
61
+ customInputMode: false,
62
+ customInputValue: '',
63
+ cursorPosition: 0,
64
+ };
65
+ });
66
+ }, [onComplete]);
67
+ useInput((input, key) => {
68
+ if (customInputMode) {
69
+ if (key.escape) {
70
+ updateState({ customInputMode: false, customInputValue: '', cursorPosition: 0 });
71
+ }
72
+ else if (key.return && customInputValue.trim()) {
73
+ selectOption(customInputValue.trim(), true);
74
+ }
75
+ else if (key.backspace || key.delete) {
76
+ if (cursorPosition > 0) {
77
+ updateState({
78
+ customInputValue: customInputValue.slice(0, cursorPosition - 1) + customInputValue.slice(cursorPosition),
79
+ cursorPosition: cursorPosition - 1,
80
+ });
81
+ }
82
+ }
83
+ else if (key.leftArrow) {
84
+ updateState({ cursorPosition: Math.max(0, cursorPosition - 1) });
85
+ }
86
+ else if (key.rightArrow) {
87
+ updateState({ cursorPosition: Math.min(customInputValue.length, cursorPosition + 1) });
88
+ }
89
+ else if (!key.ctrl && !key.meta && input) {
90
+ updateState({
91
+ customInputValue: customInputValue.slice(0, cursorPosition) + input + customInputValue.slice(cursorPosition),
92
+ cursorPosition: cursorPosition + input.length,
93
+ });
94
+ }
95
+ return;
96
+ }
97
+ // Selection mode
98
+ if (key.upArrow) {
99
+ updateState({ selectedOption: selectedOption > 0 ? selectedOption - 1 : allOptions.length - 1 });
100
+ }
101
+ else if (key.downArrow) {
102
+ updateState({ selectedOption: selectedOption < allOptions.length - 1 ? selectedOption + 1 : 0 });
103
+ }
104
+ else if (key.leftArrow && currentIndex > 0) {
105
+ updateState({ currentIndex: currentIndex - 1, selectedOption: 0 });
106
+ }
107
+ else if (key.rightArrow && currentIndex < questions.length - 1 && currentQuestion.answer) {
108
+ updateState({ currentIndex: currentIndex + 1, selectedOption: 0 });
109
+ }
110
+ else if (key.tab) {
111
+ // Tab always opens custom input mode
112
+ updateState({ customInputMode: true, customInputValue: '', cursorPosition: 0 });
113
+ }
114
+ else if (key.return && isOnNoOption) {
115
+ // Enter on "No" also opens custom input
116
+ updateState({ customInputMode: true, customInputValue: '', cursorPosition: 0 });
117
+ }
118
+ else if (key.return && !isOnNoOption) {
119
+ selectOption(allOptions[selectedOption].label, true);
120
+ }
121
+ else if (key.escape) {
122
+ onCancel();
123
+ }
124
+ else {
125
+ const num = parseInt(input, 10);
126
+ if (!isNaN(num) && num > 0 && num <= allOptions.length) {
127
+ updateState({ selectedOption: num - 1 });
128
+ }
129
+ }
130
+ });
131
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border, paddingX: 2, paddingY: 1, children: [_jsx(Box, { children: questions.map((q, i) => {
132
+ const isCurrent = i === currentIndex;
133
+ const isAnswered = q.answer !== undefined;
134
+ const color = isCurrent ? theme.accent : isAnswered ? theme.answered : theme.unselected;
135
+ return (_jsxs(React.Fragment, { children: [_jsxs(Text, { color: color, bold: isCurrent, children: ["[", isAnswered ? `${q.header} ✓` : q.header, "]"] }), i < questions.length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, i));
136
+ }) }), _jsx(Box, { marginY: 1, children: questions.map((q, i) => {
137
+ const isAnswered = q.answer !== undefined;
138
+ const isCurrent = i === currentIndex;
139
+ return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: isAnswered ? theme.answered : isCurrent ? theme.accent : theme.dim, children: isAnswered ? '✓' : isCurrent ? '●' : '○' }), i < questions.length - 1 && _jsx(Text, { color: theme.dim, children: "\u2500\u2500\u2500\u2500" })] }, i));
140
+ }) }), _jsxs(Box, { children: [_jsx(Text, { color: theme.accent, children: "\u25C6 " }), _jsx(Text, { color: theme.header, bold: true, children: currentQuestion.header })] }), _jsx(Box, { marginLeft: 2, marginBottom: 1, children: _jsx(Text, { color: theme.text, children: currentQuestion.question }) }), _jsx(Box, { flexDirection: "column", marginLeft: 2, children: allOptions.map((opt, idx) => {
141
+ const isSelected = idx === selectedOption;
142
+ const isNo = idx === allOptions.length - 1;
143
+ if (isNo) {
144
+ // "No" option with inline custom input
145
+ return (_jsxs(Box, { children: [_jsxs(Text, { color: isSelected ? (customInputMode ? theme.selected : theme.no) : theme.unselected, children: [isSelected ? '❯' : ' ', " ", idx + 1, ". No"] }), customInputMode ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.dim, children: ", " }), _jsx(Text, { color: theme.text, children: customInputValue.slice(0, cursorPosition) }), _jsx(Text, { inverse: true, children: customInputValue[cursorPosition] || ' ' }), _jsx(Text, { color: theme.text, children: customInputValue.slice(cursorPosition + 1) })] })) : (_jsx(Text, { color: theme.dim, children: " (Tab to type custom)" }))] }, idx));
146
+ }
147
+ return (_jsxs(Text, { color: isSelected ? theme.selected : theme.unselected, children: [isSelected ? '❯' : ' ', " ", idx + 1, ". ", opt.recommended ? `${opt.label} (Recommended)` : opt.label] }, idx));
148
+ }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.dim, children: customInputMode ? 'Type your answer · Enter submit · Esc cancel' : '↑/↓ select · Enter confirm · Tab custom · ←/→ questions' }) })] }));
149
+ };
150
+ // Memoize to prevent unnecessary re-renders
151
+ export const QuestionWizard = memo(QuestionWizardInner);
152
+ export default QuestionWizard;
@@ -1,13 +1,19 @@
1
1
  import React from 'react';
2
2
  import { AgentName } from './AgentPanel.js';
3
+ type CouncilMode = 'solo' | 'council' | 'off';
3
4
  interface StatusBarProps {
4
5
  mode: 'dev' | 'ml';
6
+ executionMode: 'plan' | 'auto';
5
7
  tokens: number;
6
8
  startTime: Date;
7
9
  isProcessing?: boolean;
8
10
  activeAgent?: AgentName;
9
11
  completedAgents?: AgentName[];
10
12
  autoAccept?: boolean;
13
+ councilMode?: CouncilMode;
14
+ councilStage?: string | null;
15
+ availableModels?: Record<string, boolean>;
16
+ showExitHint?: boolean;
11
17
  }
12
18
  export declare const StatusBar: React.FC<StatusBarProps>;
13
19
  export default StatusBar;
@@ -23,7 +23,13 @@ const agentIcons = {
23
23
  'Data Engineer': '&',
24
24
  Evaluator: '^',
25
25
  };
26
- export const StatusBar = ({ mode, tokens, startTime, isProcessing = false, activeAgent, completedAgents = [], autoAccept = false, }) => {
26
+ // Model icons for council mode
27
+ const modelIcons = {
28
+ gpt: 'G',
29
+ gemini: 'M',
30
+ claude: 'C',
31
+ };
32
+ export const StatusBar = ({ mode, executionMode, tokens, startTime, isProcessing = false, activeAgent, completedAgents = [], autoAccept = false, councilMode = 'off', councilStage = null, availableModels = {}, showExitHint = false, }) => {
27
33
  const [elapsed, setElapsed] = useState('');
28
34
  const [spinnerFrame, setSpinnerFrame] = useState(0);
29
35
  const [pulseFrame, setPulseFrame] = useState(0);
@@ -77,11 +83,29 @@ export const StatusBar = ({ mode, tokens, startTime, isProcessing = false, activ
77
83
  return theme.done;
78
84
  return theme.dim;
79
85
  };
80
- return (_jsxs(Box, { children: [_jsx(Text, { color: theme.dim, children: " " }), _jsx(Text, { color: theme.accent, children: modeLabel }), _jsx(Text, { color: theme.border, children: " \u2502 " }), modeAgents.map((agent, i) => {
81
- const isActive = activeAgent === agent;
82
- const leftBracket = isActive ? pulseBrackets[pulseFrame] : '[';
83
- const rightBracket = isActive ? pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '<' ? '>' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '{' ? '}' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '(' ? ')' : ']' : ']';
84
- return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: getAgentColor(agent), children: leftBracket }), _jsx(Text, { color: getAgentColor(agent), children: agentIcons[agent] }), _jsx(Text, { color: getAgentColor(agent), children: rightBracket }), i < modeAgents.length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, agent));
85
- }), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: "? help" }), autoAccept && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.active, children: "AUTO" })] })), isProcessing && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: icons.spinner[spinnerFrame] })] })), elapsed && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: elapsed })] })), _jsx(Text, { color: theme.dim, children: ' '.repeat(3) }), _jsxs(Text, { color: theme.accent, children: ["\u2191 ", formatTokens(tokens)] }), _jsx(Text, { color: theme.dim, children: " tokens" })] }));
86
+ // Get stage label for council mode
87
+ const getStageLabel = () => {
88
+ if (!councilStage)
89
+ return null;
90
+ const stages = {
91
+ 'scout': 'Scout',
92
+ 'stage1': '1/3',
93
+ 'stage2': '2/3',
94
+ 'stage3': '3/3',
95
+ };
96
+ return stages[councilStage] || councilStage;
97
+ };
98
+ return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.dim, children: " " }), _jsx(Text, { color: theme.accent, children: modeLabel }), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: executionMode === 'auto' ? theme.active : theme.accent, children: executionMode.toUpperCase() }), _jsx(Text, { color: theme.border, children: " \u2502 " }), councilMode !== 'off' ? (_jsxs(_Fragment, { children: [Object.entries(modelIcons).map(([model, icon], i) => {
99
+ const isAvailable = availableModels[model];
100
+ const color = isAvailable ? theme.done : theme.dim;
101
+ return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: color, children: "[" }), _jsx(Text, { color: color, children: icon }), _jsx(Text, { color: color, children: "]" }), i < Object.keys(modelIcons).length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, model));
102
+ }), councilStage && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsxs(Text, { color: theme.active, children: ["Stage ", getStageLabel()] })] }))] })) : (
103
+ /* Agent boxes (standard mode) */
104
+ modeAgents.map((agent, i) => {
105
+ const isActive = activeAgent === agent;
106
+ const leftBracket = isActive ? pulseBrackets[pulseFrame] : '[';
107
+ const rightBracket = isActive ? pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '<' ? '>' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '{' ? '}' : pulseBrackets[(pulseFrame + 3) % pulseBrackets.length] === '(' ? ')' : ']' : ']';
108
+ return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: getAgentColor(agent), children: leftBracket }), _jsx(Text, { color: getAgentColor(agent), children: agentIcons[agent] }), _jsx(Text, { color: getAgentColor(agent), children: rightBracket }), i < modeAgents.length - 1 && _jsx(Text, { color: theme.dim, children: " " })] }, agent));
109
+ })), _jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: "? help" }), councilMode !== 'off' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: councilMode === 'council' ? 'COUNCIL' : 'SOLO' })] })), autoAccept && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.active, children: "FAST" })] })), isProcessing && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.highlight, children: icons.spinner[spinnerFrame] })] })), elapsed && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.border, children: " \u2502 " }), _jsx(Text, { color: theme.dim, children: elapsed })] }))] }), _jsxs(Box, { children: [showExitHint && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.dim, children: "Press Esc again to exit" }), _jsx(Text, { color: theme.border, children: " \u2502 " })] })), _jsxs(Text, { color: theme.accent, children: ["\u2191 ", formatTokens(tokens)] }), _jsx(Text, { color: theme.dim, children: " tokens " })] })] }));
86
110
  };
87
111
  export default StatusBar;
@@ -2,21 +2,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Box, Text } from 'ink';
4
4
  const theme = {
5
- border: '#4a5568',
6
- accent: '#4fd1c5',
7
- highlight: '#81e6d9',
5
+ border: '#2d3748', // gray-800
6
+ accent: '#a0aec0', // gray-400
7
+ highlight: '#e2e8f0', // gray-200
8
8
  dim: '#718096',
9
- text: '#e2e8f0',
10
- title: '#f6e05e',
11
- koi1: '#f6ad55', // orange koi
12
- koi2: '#e2e8f0', // white koi
13
- water: '#4299e1', // blue water
9
+ text: '#cbd5e0',
10
+ title: '#718096', // gray-500
11
+ c1: '#a0aec0', // gray-400
12
+ c2: '#4a5568', // gray-700
13
+ c3: '#63b3ed', // blue-400 (eye)
14
14
  };
15
15
  export const WelcomeBox = ({ version, mode }) => {
16
16
  const termWidth = Math.min(process.stdout.columns || 120, 120);
17
17
  const boxWidth = termWidth - 4;
18
- const leftWidth = Math.floor(boxWidth * 0.45);
19
- const rightWidth = boxWidth - leftWidth - 3;
18
+ const leftWidth = Math.floor(boxWidth * 0.55);
19
+ const rightWidth = boxWidth - leftWidth - 1;
20
20
  const modeLabel = mode === 'dev' ? 'Software Development' : 'ML Research';
21
21
  // Agent icons matching StatusBar
22
22
  const agentIcons = {
@@ -35,6 +35,12 @@ export const WelcomeBox = ({ version, mode }) => {
35
35
  const titleText = ` AGENT-K v${version} `;
36
36
  const titlePadLeft = Math.floor((boxWidth - titleText.length) / 2);
37
37
  const titlePadRight = boxWidth - titleText.length - titlePadLeft;
38
- return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u256D" }), _jsx(Text, { color: theme.border, children: '─'.repeat(titlePadLeft - 1) }), _jsx(Text, { color: theme.title, bold: true, children: titleText }), _jsx(Text, { color: theme.border, children: '─'.repeat(titlePadRight - 1) }), _jsx(Text, { color: theme.border, children: "\u256E" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Text, { children: ' '.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsxs(Box, { width: leftWidth, justifyContent: "center", children: [_jsx(Text, { color: theme.water, children: "~" }), _jsxs(Text, { color: theme.koi1, children: [" ><(((", "'", "> "] })] }), _jsx(Text, { color: theme.border, children: "\u2502" }), _jsxs(Box, { width: rightWidth, paddingLeft: 1, children: [_jsx(Text, { color: theme.text, children: "Welcome to " }), _jsx(Text, { color: theme.accent, bold: true, children: "AGENT-K" })] }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: leftWidth, justifyContent: "center", children: _jsx(Text, { color: theme.water, children: " ~ ~ " }) }), _jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: rightWidth, paddingLeft: 1, children: _jsx(Text, { color: theme.dim, children: "Multi-Agent Intelligence System" }) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsxs(Box, { width: leftWidth, justifyContent: "center", children: [_jsxs(Text, { color: theme.koi2, children: [" <", "'", ")))><"] }), _jsx(Text, { color: theme.water, children: " ~" })] }), _jsx(Text, { color: theme.border, children: "\u2502" }), _jsxs(Box, { width: rightWidth, paddingLeft: 1, children: [_jsx(Text, { color: theme.dim, children: "Mode: " }), _jsx(Text, { color: theme.highlight, children: modeLabel })] }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Text, { children: ' '.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: boxWidth, justifyContent: "center", children: agents.map((agent, i) => (_jsxs(React.Fragment, { children: [_jsxs(Text, { color: theme.accent, children: ["[", agentIcons[agent], "] "] }), _jsx(Text, { color: theme.text, children: agent }), i < agents.length - 1 && _jsx(Text, { color: theme.dim, children: " \u00B7 " })] }, agent))) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Text, { children: ' '.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: boxWidth, justifyContent: "center", children: _jsx(Text, { color: theme.dim, children: "/help for commands \u00B7 /plan or /auto to set mode \u00B7 Ctrl+C to exit" }) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2570" }), _jsx(Text, { color: theme.border, children: '─'.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u256F" })] })] }));
38
+ return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u256D" }), _jsx(Text, { color: theme.border, children: '─'.repeat(titlePadLeft) }), _jsx(Text, { color: theme.title, bold: true, children: titleText }), _jsx(Text, { color: theme.border, children: '─'.repeat(titlePadRight) }), _jsx(Text, { color: theme.border, children: "\u256E" })] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: leftWidth, justifyContent: "center", alignItems: "center", flexDirection: "column", children: _jsx(Text, { color: theme.c1, children: `
39
+ ___________________ ____....-----....____
40
+ (________________LL_) ==============================
41
+ ______\\ \\_______.--'. \`---..._____...---'
42
+ \`-------..__ \` ,/
43
+ \`-._ - - - |
44
+ \`-------'` }) }), _jsx(Text, { color: theme.border, children: "\u2502" }), _jsxs(Box, { width: rightWidth, flexDirection: "column", justifyContent: "center", paddingLeft: 2, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: theme.text, children: "Welcome to " }), _jsx(Text, { color: theme.accent, bold: true, children: "AGENT-K" })] }), _jsx(Text, { color: theme.dim, children: "Pack Intelligence System" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: theme.dim, children: "Mode: " }), _jsx(Text, { color: theme.highlight, children: modeLabel })] })] }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Text, { children: ' '.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: boxWidth, justifyContent: "center", children: agents.map((agent, i) => (_jsxs(React.Fragment, { children: [_jsxs(Text, { color: theme.accent, children: ["[", agentIcons[agent], "] "] }), _jsx(Text, { color: theme.text, children: agent }), i < agents.length - 1 && _jsx(Text, { color: theme.dim, children: " \u00B7 " })] }, agent))) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Text, { children: ' '.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2502" }), _jsx(Box, { width: boxWidth, justifyContent: "center", children: _jsx(Text, { color: theme.dim, children: "/help for commands \u00B7 /plan or /auto to set mode \u00B7 Esc Esc to exit" }) }), _jsx(Text, { color: theme.border, children: "\u2502" })] }), _jsxs(Box, { children: [_jsx(Text, { color: theme.border, children: "\u2570" }), _jsx(Text, { color: theme.border, children: '─'.repeat(boxWidth) }), _jsx(Text, { color: theme.border, children: "\u256F" })] })] }));
39
45
  };
40
46
  export default WelcomeBox;
@@ -9,3 +9,5 @@ export { RetroBox } from './Box.js';
9
9
  export { AgentStatus } from './AgentStatus.js';
10
10
  export { AgentPanel } from './AgentPanel.js';
11
11
  export type { AgentName, AgentState } from './AgentPanel.js';
12
+ export { QuestionWizard } from './QuestionWizard.js';
13
+ export type { Question, QuestionOption, QuestionWizardProps } from './QuestionWizard.js';
@@ -8,3 +8,4 @@ export { ThinkingIndicator } from './ThinkingIndicator.js';
8
8
  export { RetroBox } from './Box.js';
9
9
  export { AgentStatus } from './AgentStatus.js';
10
10
  export { AgentPanel } from './AgentPanel.js';
11
+ export { QuestionWizard } from './QuestionWizard.js';
@@ -127,32 +127,69 @@ You are the Orchestrator—the central intelligence coordinator in AGENT-K, a mu
127
127
  4. **Think Transparently**: Show your reasoning process
128
128
  5. **Synthesize Results**: Provide cohesive, actionable outputs
129
129
 
130
- ## RESPONSE PROTOCOL
131
-
132
- <thinking>
133
- For each request, analyze:
134
- - Task type and complexity (Simple | Moderate | Complex)
135
- - Required expertise areas
136
- - Dependencies between subtasks
137
- - Potential challenges or ambiguities
138
- </thinking>
139
-
140
- <task_analysis>
141
- ┌─────────────────────────────────────────────────────────
142
- │ COMPLEXITY: [Simple|Moderate|Complex]
143
- AGENTS: [List involved agents]
144
- SUBTASKS: [If complex, list decomposed tasks]
145
- └─────────────────────────────────────────────────────────
146
- </task_analysis>
147
-
148
- <response>
149
- [Your comprehensive response here]
150
- </response>
130
+ ## RESPONSE FORMAT
131
+
132
+ Structure your response with clear markdown headers (no XML tags in output):
133
+
134
+ ### Task Analysis
135
+ | Aspect | Assessment |
136
+ |--------|------------|
137
+ | **Complexity** | Simple / Moderate / Complex |
138
+ | **Agents** | List specialists needed |
139
+
140
+ ### Plan
141
+ Numbered steps for execution.
142
+
143
+ ### Notes
144
+ Any clarifications or considerations.
145
+
146
+ IMPORTANT: Do NOT output raw XML tags like <thinking>, <task_analysis>, or <response> in your response. Use clean markdown formatting only.
151
147
 
152
148
  ## COMPLEXITY SCALING
153
149
  - **Simple** (1 agent, direct response): Factual questions, single-file changes, explanations
154
150
  - **Moderate** (2-3 agents, coordinated): Feature implementation, debugging, code review
155
- - **Complex** (3+ agents, parallel): Architecture design, full features, multi-file refactors`;
151
+ - **Complex** (3+ agents, parallel): Architecture design, full features, multi-file refactors
152
+
153
+ ## ASKING QUESTIONS
154
+
155
+ When you need clarification or user input before proceeding, use this XML format for EACH question:
156
+
157
+ <question header="ShortLabel">
158
+ Your question text here?
159
+ <options>
160
+ <option recommended="true">First option (mark recommended if applicable)</option>
161
+ <option>Second option</option>
162
+ <option>Third option</option>
163
+ <option>Fourth option</option>
164
+ </options>
165
+ </question>
166
+
167
+ Guidelines for questions:
168
+ - header: Short label (1-2 words) like "Language", "Framework", "Approach"
169
+ - question: Clear, specific question ending with ?
170
+ - options: 2-4 concrete choices (user can also provide custom answer)
171
+ - recommended: Add recommended="true" to the best default option
172
+
173
+ Example with multiple questions:
174
+ <question header="Language">
175
+ What programming language should I use?
176
+ <options>
177
+ <option recommended="true">TypeScript</option>
178
+ <option>Python</option>
179
+ <option>Go</option>
180
+ </options>
181
+ </question>
182
+
183
+ <question header="Features">
184
+ Which features do you need?
185
+ <options>
186
+ <option recommended="true">Standard validation with error messages</option>
187
+ <option>NIST guidelines compliance</option>
188
+ <option>Password strength meter</option>
189
+ </options>
190
+ </question>
191
+
192
+ IMPORTANT: Only ask questions when genuinely needed. For straightforward requests, proceed directly with analysis and recommendations.`;
156
193
  if (mode === 'ml') {
157
194
  return `${orchestratorCore}
158
195
 
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Council Integration for AGENT-K
3
+ *
4
+ * Connects TypeScript UI to Python council backend.
5
+ * Supports two modes:
6
+ * - Council: Multi-LLM via LiteLLM (GPT, Gemini, Claude)
7
+ * - Solo: Multi-Claude CLI instances with personas
8
+ */
9
+ export interface StageUpdate {
10
+ stage: string;
11
+ message?: string;
12
+ responses?: Record<string, string>;
13
+ reviews?: Record<string, string>;
14
+ final?: string;
15
+ }
16
+ export interface CouncilResult {
17
+ query: string;
18
+ mode: 'council' | 'solo';
19
+ stages: Array<{
20
+ stage: number;
21
+ stage_name: string;
22
+ responses: Record<string, string>;
23
+ timestamp: string;
24
+ }>;
25
+ final_response: string;
26
+ chairman: string;
27
+ total_tokens: {
28
+ input: number;
29
+ output: number;
30
+ };
31
+ timestamp: string;
32
+ }
33
+ export interface CouncilOptions {
34
+ mode?: 'council' | 'solo';
35
+ skipScout?: boolean;
36
+ projectRoot?: string;
37
+ timeout?: number;
38
+ }
39
+ /**
40
+ * Run the council process.
41
+ *
42
+ * @param query User's query
43
+ * @param options Council options
44
+ * @param onStage Callback for stage updates
45
+ * @returns Promise resolving to final result
46
+ */
47
+ export declare function runCouncil(query: string, options?: CouncilOptions, onStage?: (update: StageUpdate) => void): Promise<CouncilResult>;
48
+ /**
49
+ * Check if the council backend is available.
50
+ */
51
+ export declare function checkCouncilAvailable(): Promise<boolean>;
52
+ /**
53
+ * Get available models status from the council backend.
54
+ */
55
+ export declare function getAvailableModels(): Promise<Record<string, boolean>>;
56
+ declare const _default: {
57
+ runCouncil: typeof runCouncil;
58
+ checkCouncilAvailable: typeof checkCouncilAvailable;
59
+ getAvailableModels: typeof getAvailableModels;
60
+ };
61
+ export default _default;