aiexecode 1.0.126 → 1.0.128
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.
Potentially problematic release.
This version of aiexecode might be problematic. Click here for more details.
- package/index.js +134 -20
- package/package.json +1 -1
- package/payload_viewer/out/404/index.html +1 -1
- package/payload_viewer/out/404.html +1 -1
- package/payload_viewer/out/index.html +1 -1
- package/payload_viewer/out/index.txt +1 -1
- package/prompts/completion_judge.txt +4 -0
- package/prompts/orchestrator.txt +59 -0
- package/src/ai_based/orchestrator.js +5 -2
- package/src/commands/bg.js +129 -0
- package/src/frontend/App.js +100 -1
- package/src/frontend/components/BackgroundProcessList.js +175 -0
- package/src/system/ai_request.js +0 -19
- package/src/system/background_process.js +317 -0
- package/src/system/code_executer.js +487 -57
- package/src/system/output_helper.js +52 -9
- package/src/system/session.js +89 -10
- package/src/system/session_memory.js +2 -1
- package/src/util/exit_handler.js +8 -0
- /package/payload_viewer/out/_next/static/{Ciog50_gZfMGwKNqVaI0v → s1c0-hQ_HEGmr_04DEOse}/_buildManifest.js +0 -0
- /package/payload_viewer/out/_next/static/{Ciog50_gZfMGwKNqVaI0v → s1c0-hQ_HEGmr_04DEOse}/_clientMiddlewareManifest.json +0 -0
- /package/payload_viewer/out/_next/static/{Ciog50_gZfMGwKNqVaI0v → s1c0-hQ_HEGmr_04DEOse}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { listBackgroundProcesses, killBackgroundProcess, getBackgroundProcess } from '../system/background_process.js';
|
|
2
|
+
import { uiEvents } from '../system/ui_events.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* /bg 커맨드 - 백그라운드 프로세스 관리
|
|
6
|
+
*
|
|
7
|
+
* 사용법:
|
|
8
|
+
* /bg - 프로세스 목록 표시
|
|
9
|
+
* /bg list - 프로세스 목록 표시
|
|
10
|
+
* /bg kill <id> - 프로세스 종료
|
|
11
|
+
* /bg killall - 모든 실행 중인 프로세스 종료
|
|
12
|
+
*/
|
|
13
|
+
export default {
|
|
14
|
+
name: 'bg',
|
|
15
|
+
description: 'Manage background processes',
|
|
16
|
+
usage: '/bg [list|kill <id>|killall]',
|
|
17
|
+
handler: async (args, context) => {
|
|
18
|
+
const subcommand = args[0]?.toLowerCase() || 'list';
|
|
19
|
+
|
|
20
|
+
switch (subcommand) {
|
|
21
|
+
case 'list':
|
|
22
|
+
case 'ls': {
|
|
23
|
+
const processes = listBackgroundProcesses({ running: true });
|
|
24
|
+
if (processes.length === 0) {
|
|
25
|
+
uiEvents.addSystemMessage('No running background processes');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const lines = ['Background Processes:'];
|
|
30
|
+
for (const proc of processes) {
|
|
31
|
+
const statusIcon = proc.status === 'running' ? '●' :
|
|
32
|
+
proc.status === 'completed' ? '✓' :
|
|
33
|
+
proc.status === 'failed' ? '✗' : '⊘';
|
|
34
|
+
const duration = formatDuration(proc.startedAt, proc.endedAt);
|
|
35
|
+
lines.push(` ${statusIcon} [${proc.id}] pid:${proc.pid} ${duration} - ${proc.command.substring(0, 50)}${proc.command.length > 50 ? '...' : ''}`);
|
|
36
|
+
}
|
|
37
|
+
uiEvents.addSystemMessage(lines.join('\n'));
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
case 'kill': {
|
|
42
|
+
const id = args[1];
|
|
43
|
+
if (!id) {
|
|
44
|
+
uiEvents.addErrorMessage('Usage: /bg kill <process_id>');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const proc = getBackgroundProcess(id);
|
|
49
|
+
if (!proc) {
|
|
50
|
+
uiEvents.addErrorMessage(`Process not found: ${id}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (proc.status !== 'running') {
|
|
55
|
+
uiEvents.addSystemMessage(`Process ${id} is already ${proc.status}`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const killed = killBackgroundProcess(id);
|
|
60
|
+
if (killed) {
|
|
61
|
+
uiEvents.addSystemMessage(`Killed process: ${id} (pid: ${proc.pid})`);
|
|
62
|
+
} else {
|
|
63
|
+
uiEvents.addErrorMessage(`Failed to kill process: ${id}`);
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
case 'killall': {
|
|
69
|
+
const processes = listBackgroundProcesses({ running: true });
|
|
70
|
+
if (processes.length === 0) {
|
|
71
|
+
uiEvents.addSystemMessage('No running background processes');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let killedCount = 0;
|
|
76
|
+
for (const proc of processes) {
|
|
77
|
+
if (killBackgroundProcess(proc.id)) {
|
|
78
|
+
killedCount++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
uiEvents.addSystemMessage(`Killed ${killedCount} background process(es)`);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
case 'show': {
|
|
86
|
+
const id = args[1];
|
|
87
|
+
if (!id) {
|
|
88
|
+
uiEvents.addErrorMessage('Usage: /bg show <process_id>');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const proc = getBackgroundProcess(id);
|
|
93
|
+
if (!proc) {
|
|
94
|
+
uiEvents.addErrorMessage(`Process not found: ${id}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const lines = [
|
|
99
|
+
`Process: ${proc.id}`,
|
|
100
|
+
` PID: ${proc.pid}`,
|
|
101
|
+
` Status: ${proc.status}`,
|
|
102
|
+
` Command: ${proc.command}`,
|
|
103
|
+
` Started: ${proc.startedAt.toISOString()}`,
|
|
104
|
+
proc.endedAt ? ` Ended: ${proc.endedAt.toISOString()}` : null,
|
|
105
|
+
proc.exitCode !== null ? ` Exit Code: ${proc.exitCode}` : null,
|
|
106
|
+
proc.stdout ? ` Stdout (last 200 chars): ${proc.stdout.slice(-200)}` : null,
|
|
107
|
+
proc.stderr ? ` Stderr (last 200 chars): ${proc.stderr.slice(-200)}` : null,
|
|
108
|
+
].filter(Boolean);
|
|
109
|
+
|
|
110
|
+
uiEvents.addSystemMessage(lines.join('\n'));
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
default:
|
|
115
|
+
uiEvents.addErrorMessage(`Unknown subcommand: ${subcommand}\nUsage: /bg [list|kill <id>|killall|show <id>]`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
function formatDuration(startedAt, endedAt) {
|
|
121
|
+
const end = endedAt ? new Date(endedAt) : new Date();
|
|
122
|
+
const start = new Date(startedAt);
|
|
123
|
+
const diffMs = end - start;
|
|
124
|
+
|
|
125
|
+
if (diffMs < 1000) return `${diffMs}ms`;
|
|
126
|
+
if (diffMs < 60000) return `${Math.round(diffMs / 1000)}s`;
|
|
127
|
+
if (diffMs < 3600000) return `${Math.round(diffMs / 60000)}m`;
|
|
128
|
+
return `${Math.round(diffMs / 3600000)}h`;
|
|
129
|
+
}
|
package/src/frontend/App.js
CHANGED
|
@@ -13,6 +13,7 @@ import { ConversationItem } from './components/ConversationItem.js';
|
|
|
13
13
|
import { BlankLine } from './components/BlankLine.js';
|
|
14
14
|
import { TodoList } from './components/TodoList.js';
|
|
15
15
|
import { LoadingIndicator } from './components/LoadingIndicator.js';
|
|
16
|
+
import { BackgroundProcessList } from './components/BackgroundProcessList.js';
|
|
16
17
|
import { useTextBuffer } from './utils/inputBuffer.js';
|
|
17
18
|
import { uiEvents } from '../system/ui_events.js';
|
|
18
19
|
import { getToolDisplayConfig, extractMessageFromArgs, formatToolCall, formatToolResult, getToolDisplayName } from '../system/tool_registry.js';
|
|
@@ -361,6 +362,9 @@ export function App({ onSubmit, onClearScreen, onExit, commands = [], model, ver
|
|
|
361
362
|
const [approvalRequest, setApprovalRequest] = useState(null);
|
|
362
363
|
const [showSetupWizard, setShowSetupWizard] = useState(false);
|
|
363
364
|
const [todos, setTodos] = useState([]);
|
|
365
|
+
const [backgroundProcesses, setBackgroundProcesses] = useState([]);
|
|
366
|
+
const [showBackgroundPanel, setShowBackgroundPanel] = useState(false);
|
|
367
|
+
const [backgroundPanelFocused, setBackgroundPanelFocused] = useState(false);
|
|
364
368
|
|
|
365
369
|
// Static items: 메모이제이션된 React 엘리먼트들 (Static 컴포넌트 제거로 스크롤 문제 해결)
|
|
366
370
|
const [staticItems, setStaticItems] = useState(() => []);
|
|
@@ -967,6 +971,94 @@ export function App({ onSubmit, onClearScreen, onExit, commands = [], model, ver
|
|
|
967
971
|
};
|
|
968
972
|
}, [addToHistory, handleSessionTransition, version]);
|
|
969
973
|
|
|
974
|
+
// 백그라운드 프로세스 이벤트 핸들링
|
|
975
|
+
const showBackgroundPanelRef = useRef(showBackgroundPanel);
|
|
976
|
+
useEffect(() => {
|
|
977
|
+
showBackgroundPanelRef.current = showBackgroundPanel;
|
|
978
|
+
}, [showBackgroundPanel]);
|
|
979
|
+
|
|
980
|
+
useEffect(() => {
|
|
981
|
+
let manager = null;
|
|
982
|
+
let updateInterval = null;
|
|
983
|
+
let cleanupFn = null;
|
|
984
|
+
let isMounted = true;
|
|
985
|
+
|
|
986
|
+
const setupBackgroundProcessListener = async () => {
|
|
987
|
+
const { getBackgroundProcessManager } = await import('../system/background_process.js');
|
|
988
|
+
if (!isMounted) return;
|
|
989
|
+
|
|
990
|
+
manager = getBackgroundProcessManager();
|
|
991
|
+
|
|
992
|
+
const updateProcessList = () => {
|
|
993
|
+
if (!isMounted) return;
|
|
994
|
+
const processes = manager.list();
|
|
995
|
+
// 실행 중인 프로세스만 표시
|
|
996
|
+
const runningProcesses = processes.filter(p => p.status === 'running');
|
|
997
|
+
setBackgroundProcesses(runningProcesses);
|
|
998
|
+
|
|
999
|
+
// 실행 중인 프로세스가 있으면 패널 자동 표시
|
|
1000
|
+
if (runningProcesses.length > 0 && !showBackgroundPanelRef.current) {
|
|
1001
|
+
setShowBackgroundPanel(true);
|
|
1002
|
+
}
|
|
1003
|
+
// 실행 중인 프로세스가 없으면 패널 숨기기
|
|
1004
|
+
if (runningProcesses.length === 0) {
|
|
1005
|
+
setShowBackgroundPanel(false);
|
|
1006
|
+
setBackgroundPanelFocused(false);
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
// 이벤트 핸들러
|
|
1011
|
+
const handleStarted = () => {
|
|
1012
|
+
updateProcessList();
|
|
1013
|
+
};
|
|
1014
|
+
const handleClose = () => updateProcessList();
|
|
1015
|
+
const handleKilled = () => updateProcessList();
|
|
1016
|
+
|
|
1017
|
+
manager.on('started', handleStarted);
|
|
1018
|
+
manager.on('close', handleClose);
|
|
1019
|
+
manager.on('killed', handleKilled);
|
|
1020
|
+
|
|
1021
|
+
// 초기 로드
|
|
1022
|
+
updateProcessList();
|
|
1023
|
+
|
|
1024
|
+
// 주기적 업데이트 (실행 시간 표시용)
|
|
1025
|
+
updateInterval = setInterval(updateProcessList, 1000);
|
|
1026
|
+
|
|
1027
|
+
cleanupFn = () => {
|
|
1028
|
+
manager.off('started', handleStarted);
|
|
1029
|
+
manager.off('close', handleClose);
|
|
1030
|
+
manager.off('killed', handleKilled);
|
|
1031
|
+
if (updateInterval) clearInterval(updateInterval);
|
|
1032
|
+
};
|
|
1033
|
+
};
|
|
1034
|
+
|
|
1035
|
+
setupBackgroundProcessListener();
|
|
1036
|
+
|
|
1037
|
+
return () => {
|
|
1038
|
+
isMounted = false;
|
|
1039
|
+
if (cleanupFn) cleanupFn();
|
|
1040
|
+
if (updateInterval) clearInterval(updateInterval);
|
|
1041
|
+
};
|
|
1042
|
+
}, []);
|
|
1043
|
+
|
|
1044
|
+
// 백그라운드 프로세스 kill 핸들러
|
|
1045
|
+
const handleKillBackgroundProcess = useCallback(async (id) => {
|
|
1046
|
+
const { killBackgroundProcess } = await import('../system/background_process.js');
|
|
1047
|
+
killBackgroundProcess(id);
|
|
1048
|
+
}, []);
|
|
1049
|
+
|
|
1050
|
+
// 백그라운드 패널 닫기 핸들러
|
|
1051
|
+
const handleCloseBackgroundPanel = useCallback(() => {
|
|
1052
|
+
setBackgroundPanelFocused(false);
|
|
1053
|
+
}, []);
|
|
1054
|
+
|
|
1055
|
+
// 백그라운드 패널 포커스 토글 핸들러
|
|
1056
|
+
const handleToggleBackgroundPanelFocus = useCallback(() => {
|
|
1057
|
+
if (backgroundProcesses.length > 0 && showBackgroundPanel) {
|
|
1058
|
+
setBackgroundPanelFocused(prev => !prev);
|
|
1059
|
+
}
|
|
1060
|
+
}, [backgroundProcesses.length, showBackgroundPanel]);
|
|
1061
|
+
|
|
970
1062
|
// 승인 요청 처리
|
|
971
1063
|
const handleApprovalDecision = useCallback((decision) => {
|
|
972
1064
|
if (approvalRequest && approvalRequest.resolve) {
|
|
@@ -1111,13 +1203,20 @@ export function App({ onSubmit, onClearScreen, onExit, commands = [], model, ver
|
|
|
1111
1203
|
!approvalRequest && todos.length > 0 && React.createElement(TodoList, {
|
|
1112
1204
|
todos: todos
|
|
1113
1205
|
}),
|
|
1206
|
+
!approvalRequest && showBackgroundPanel && backgroundProcesses.length > 0 && React.createElement(BackgroundProcessList, {
|
|
1207
|
+
processes: backgroundProcesses,
|
|
1208
|
+
isActive: backgroundPanelFocused && !isSessionRunning && !approvalRequest,
|
|
1209
|
+
onKill: handleKillBackgroundProcess,
|
|
1210
|
+
onClose: handleCloseBackgroundPanel,
|
|
1211
|
+
onToggleFocus: handleToggleBackgroundPanelFocus
|
|
1212
|
+
}),
|
|
1114
1213
|
!approvalRequest && React.createElement(Input, {
|
|
1115
1214
|
buffer,
|
|
1116
1215
|
onSubmit: handleSubmit,
|
|
1117
1216
|
onClearScreen: handleClearScreen,
|
|
1118
1217
|
onExit: onExit,
|
|
1119
1218
|
commands,
|
|
1120
|
-
focus:
|
|
1219
|
+
focus: !backgroundPanelFocused,
|
|
1121
1220
|
isSessionRunning
|
|
1122
1221
|
}),
|
|
1123
1222
|
React.createElement(MemoizedFooter, { model: currentModel, reasoningEffort })
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BackgroundProcessList Component
|
|
3
|
+
* 백그라운드 프로세스 목록을 표시하고 관리하는 컴포넌트
|
|
4
|
+
*
|
|
5
|
+
* - 방향키로 선택
|
|
6
|
+
* - k 키로 선택된 프로세스 종료
|
|
7
|
+
* - q 키로 목록 닫기
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React, { useState, useEffect } from 'react';
|
|
11
|
+
import { Box, Text, useInput } from 'ink';
|
|
12
|
+
import { theme } from '../design/themeColors.js';
|
|
13
|
+
|
|
14
|
+
const getStatusIcon = (status) => {
|
|
15
|
+
switch (status) {
|
|
16
|
+
case 'running':
|
|
17
|
+
return '●';
|
|
18
|
+
case 'completed':
|
|
19
|
+
return '✓';
|
|
20
|
+
case 'failed':
|
|
21
|
+
return '✗';
|
|
22
|
+
case 'killed':
|
|
23
|
+
return '⊘';
|
|
24
|
+
default:
|
|
25
|
+
return '?';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const getStatusColor = (status) => {
|
|
30
|
+
switch (status) {
|
|
31
|
+
case 'running':
|
|
32
|
+
return theme.brand.light;
|
|
33
|
+
case 'completed':
|
|
34
|
+
return 'green';
|
|
35
|
+
case 'failed':
|
|
36
|
+
return theme.status.error;
|
|
37
|
+
case 'killed':
|
|
38
|
+
return theme.text.secondary;
|
|
39
|
+
default:
|
|
40
|
+
return theme.text.primary;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const formatDuration = (startedAt, endedAt) => {
|
|
45
|
+
const end = endedAt ? new Date(endedAt) : new Date();
|
|
46
|
+
const start = new Date(startedAt);
|
|
47
|
+
const diffMs = end - start;
|
|
48
|
+
|
|
49
|
+
if (diffMs < 1000) return `${diffMs}ms`;
|
|
50
|
+
if (diffMs < 60000) return `${Math.round(diffMs / 1000)}s`;
|
|
51
|
+
if (diffMs < 3600000) return `${Math.round(diffMs / 60000)}m`;
|
|
52
|
+
return `${Math.round(diffMs / 3600000)}h`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const truncateCommand = (command, maxLength = 50) => {
|
|
56
|
+
if (command.length <= maxLength) return command;
|
|
57
|
+
return command.substring(0, maxLength - 3) + '...';
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export function BackgroundProcessList({
|
|
61
|
+
processes,
|
|
62
|
+
isActive,
|
|
63
|
+
onKill,
|
|
64
|
+
onClose,
|
|
65
|
+
onSelect,
|
|
66
|
+
onToggleFocus
|
|
67
|
+
}) {
|
|
68
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
69
|
+
|
|
70
|
+
// 프로세스 목록이 변경되면 선택 인덱스 조정
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (selectedIndex >= processes.length) {
|
|
73
|
+
setSelectedIndex(Math.max(0, processes.length - 1));
|
|
74
|
+
}
|
|
75
|
+
}, [processes.length, selectedIndex]);
|
|
76
|
+
|
|
77
|
+
// 키보드 입력 처리
|
|
78
|
+
useInput((input, key) => {
|
|
79
|
+
if (!isActive) return;
|
|
80
|
+
|
|
81
|
+
if (key.upArrow) {
|
|
82
|
+
setSelectedIndex(prev => Math.max(0, prev - 1));
|
|
83
|
+
} else if (key.downArrow) {
|
|
84
|
+
setSelectedIndex(prev => Math.min(processes.length - 1, prev + 1));
|
|
85
|
+
} else if (input === 'k' || input === 'K') {
|
|
86
|
+
const selected = processes[selectedIndex];
|
|
87
|
+
if (selected && selected.status === 'running' && onKill) {
|
|
88
|
+
onKill(selected.id);
|
|
89
|
+
}
|
|
90
|
+
} else if (input === 'q' || input === 'Q' || key.escape) {
|
|
91
|
+
if (onClose) onClose();
|
|
92
|
+
} else if (key.return) {
|
|
93
|
+
const selected = processes[selectedIndex];
|
|
94
|
+
if (selected && onSelect) {
|
|
95
|
+
onSelect(selected);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}, { isActive });
|
|
99
|
+
|
|
100
|
+
if (!processes || processes.length === 0) {
|
|
101
|
+
return React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
102
|
+
React.createElement(Text, { color: theme.text.secondary },
|
|
103
|
+
'No background processes'
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return React.createElement(Box, { flexDirection: "column", marginTop: 1 },
|
|
109
|
+
// 프로세스 목록
|
|
110
|
+
...processes.map((proc, index) => {
|
|
111
|
+
const isSelected = index === selectedIndex && isActive;
|
|
112
|
+
const statusIcon = getStatusIcon(proc.status);
|
|
113
|
+
const statusColor = getStatusColor(proc.status);
|
|
114
|
+
const duration = formatDuration(proc.startedAt, proc.endedAt);
|
|
115
|
+
const command = truncateCommand(proc.command);
|
|
116
|
+
|
|
117
|
+
return React.createElement(Box, {
|
|
118
|
+
key: proc.id,
|
|
119
|
+
marginLeft: 1
|
|
120
|
+
},
|
|
121
|
+
// 선택 표시
|
|
122
|
+
React.createElement(Text, {
|
|
123
|
+
color: isSelected ? theme.brand.light : theme.text.secondary
|
|
124
|
+
}, isSelected ? '▸ ' : ' '),
|
|
125
|
+
|
|
126
|
+
// 상태 아이콘
|
|
127
|
+
React.createElement(Text, { color: statusColor }, statusIcon),
|
|
128
|
+
React.createElement(Text, null, ' '),
|
|
129
|
+
|
|
130
|
+
// ID
|
|
131
|
+
React.createElement(Text, {
|
|
132
|
+
color: theme.text.secondary,
|
|
133
|
+
dimColor: !isSelected
|
|
134
|
+
}, `[${proc.id}]`),
|
|
135
|
+
React.createElement(Text, null, ' '),
|
|
136
|
+
|
|
137
|
+
// PID
|
|
138
|
+
React.createElement(Text, {
|
|
139
|
+
color: theme.text.secondary,
|
|
140
|
+
dimColor: !isSelected
|
|
141
|
+
}, `pid:${proc.pid}`),
|
|
142
|
+
React.createElement(Text, null, ' '),
|
|
143
|
+
|
|
144
|
+
// 시간
|
|
145
|
+
React.createElement(Text, {
|
|
146
|
+
color: proc.status === 'running' ? theme.brand.light : theme.text.secondary,
|
|
147
|
+
dimColor: !isSelected && proc.status !== 'running'
|
|
148
|
+
}, duration),
|
|
149
|
+
React.createElement(Text, null, ' '),
|
|
150
|
+
|
|
151
|
+
// 명령어
|
|
152
|
+
React.createElement(Text, {
|
|
153
|
+
color: isSelected ? theme.text.primary : theme.text.secondary,
|
|
154
|
+
bold: isSelected
|
|
155
|
+
}, command)
|
|
156
|
+
);
|
|
157
|
+
})
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 간단한 백그라운드 프로세스 상태 표시 (헤더용)
|
|
163
|
+
*/
|
|
164
|
+
export function BackgroundProcessBadge({ count, onClick }) {
|
|
165
|
+
if (count === 0) return null;
|
|
166
|
+
|
|
167
|
+
return React.createElement(Box, {
|
|
168
|
+
marginLeft: 1
|
|
169
|
+
},
|
|
170
|
+
React.createElement(Text, {
|
|
171
|
+
color: theme.brand.light,
|
|
172
|
+
bold: true
|
|
173
|
+
}, `[BG: ${count}]`)
|
|
174
|
+
);
|
|
175
|
+
}
|
package/src/system/ai_request.js
CHANGED
|
@@ -7,7 +7,6 @@ import { getReasoningModels, supportsReasoningEffort, DEFAULT_MODEL, getModelInf
|
|
|
7
7
|
import { createDebugLogger } from "../util/debug_log.js";
|
|
8
8
|
import { formatReadFileStdout } from "../util/output_formatter.js";
|
|
9
9
|
import { UnifiedLLMClient } from "../LLMClient/index.js";
|
|
10
|
-
import { uiEvents } from "./ui_events.js";
|
|
11
10
|
|
|
12
11
|
const debugLog = createDebugLogger('ai_request.log', 'ai_request');
|
|
13
12
|
|
|
@@ -212,20 +211,6 @@ function toAbsolutePath(anyPath) {
|
|
|
212
211
|
export async function request(taskName, requestPayload) {
|
|
213
212
|
debugLog(`[request] ========== START: ${taskName} ==========`);
|
|
214
213
|
|
|
215
|
-
// 설정에서 API payload 표시 여부 확인
|
|
216
|
-
const settings = await loadSettings();
|
|
217
|
-
const showApiPayload = settings?.SHOW_API_PAYLOAD === true;
|
|
218
|
-
|
|
219
|
-
// 화면에 요청 시작 표시 (설정이 켜져 있을 때만)
|
|
220
|
-
if (showApiPayload) {
|
|
221
|
-
const taskDisplayNames = {
|
|
222
|
-
'orchestrator': '🤖 Orchestrator',
|
|
223
|
-
'completion_judge': '✅ Completion Judge'
|
|
224
|
-
};
|
|
225
|
-
const displayName = taskDisplayNames[taskName] || taskName;
|
|
226
|
-
uiEvents.addSystemMessage(`📡 API Request: ${displayName}`);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
214
|
const provider = await getCurrentProvider();
|
|
230
215
|
debugLog(`[request] Provider: ${provider}`);
|
|
231
216
|
|
|
@@ -682,10 +667,6 @@ export async function request(taskName, requestPayload) {
|
|
|
682
667
|
})()
|
|
683
668
|
};
|
|
684
669
|
|
|
685
|
-
// 화면에 응답 내용 표시 (설정이 켜져 있을 때만)
|
|
686
|
-
if (showApiPayload) {
|
|
687
|
-
uiEvents.addSystemMessage(` └─ Response:\n${JSON.stringify(rawOutput, null, 2)}`);
|
|
688
|
-
}
|
|
689
670
|
|
|
690
671
|
debugLog(`[request] ========== END: ${taskName} ==========`);
|
|
691
672
|
|