rax-flow 0.1.7 → 0.1.8
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.
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +35 -3
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/ChatPanel.d.ts +2 -1
- package/dist/tui/components/ChatPanel.d.ts.map +1 -1
- package/dist/tui/components/ChatPanel.js +3 -2
- package/dist/tui/components/ChatPanel.js.map +1 -1
- package/dist/tui/components/DAGPanel.d.ts +24 -0
- package/dist/tui/components/DAGPanel.d.ts.map +1 -0
- package/dist/tui/components/DAGPanel.js +30 -0
- package/dist/tui/components/DAGPanel.js.map +1 -0
- package/dist/tui/components/Header.d.ts +3 -1
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +11 -3
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/HelpOverlay.d.ts +6 -0
- package/dist/tui/components/HelpOverlay.d.ts.map +1 -0
- package/dist/tui/components/HelpOverlay.js +42 -0
- package/dist/tui/components/HelpOverlay.js.map +1 -0
- package/dist/tui/components/StatusPanel.d.ts +2 -1
- package/dist/tui/components/StatusPanel.d.ts.map +1 -1
- package/dist/tui/components/StatusPanel.js +7 -6
- package/dist/tui/components/StatusPanel.js.map +1 -1
- package/dist/tui/hooks/useAppState.d.ts +17 -0
- package/dist/tui/hooks/useAppState.d.ts.map +1 -1
- package/dist/tui/hooks/useAppState.js +91 -28
- package/dist/tui/hooks/useAppState.js.map +1 -1
- package/package.json +1 -1
- package/src/tui/App.tsx +71 -19
- package/src/tui/components/ChatPanel.tsx +8 -4
- package/src/tui/components/DAGPanel.tsx +116 -0
- package/src/tui/components/Header.tsx +42 -19
- package/src/tui/components/HelpOverlay.tsx +83 -0
- package/src/tui/components/StatusPanel.tsx +13 -8
- package/src/tui/hooks/useAppState.ts +124 -28
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAppState.js","sourceRoot":"","sources":["../../../src/tui/hooks/useAppState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useAppState.js","sourceRoot":"","sources":["../../../src/tui/hooks/useAppState.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/tui/App.tsx
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
2
|
import { Box, Text, useApp, useInput } from "ink";
|
|
3
3
|
import { Header } from "./components/Header.js";
|
|
4
4
|
import { ChatPanel } from "./components/ChatPanel.js";
|
|
5
5
|
import { StatusPanel } from "./components/StatusPanel.js";
|
|
6
|
+
import { DAGPanel } from "./components/DAGPanel.js";
|
|
6
7
|
import { InputBar } from "./components/InputBar.js";
|
|
8
|
+
import { HelpOverlay } from "./components/HelpOverlay.js";
|
|
7
9
|
import { useAppState } from "./hooks/useAppState.js";
|
|
8
10
|
|
|
11
|
+
type ActivePanel = "chat" | "dag" | "status";
|
|
12
|
+
|
|
9
13
|
export function App() {
|
|
10
14
|
const { exit } = useApp();
|
|
11
|
-
const { state,
|
|
15
|
+
const { state, processCommand } = useAppState();
|
|
16
|
+
const [activePanel, setActivePanel] = useState<ActivePanel>("chat");
|
|
17
|
+
const [showHelp, setShowHelp] = useState(false);
|
|
18
|
+
const [tick, setTick] = useState(0);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const interval = setInterval(() => {
|
|
22
|
+
setTick((t) => t + 1);
|
|
23
|
+
}, 100);
|
|
24
|
+
return () => clearInterval(interval);
|
|
25
|
+
}, []);
|
|
12
26
|
|
|
13
27
|
useInput((input, key) => {
|
|
14
28
|
if (key.ctrl && input === "c") {
|
|
@@ -17,6 +31,23 @@ export function App() {
|
|
|
17
31
|
if (key.ctrl && input === "d") {
|
|
18
32
|
exit();
|
|
19
33
|
}
|
|
34
|
+
if (key.escape) {
|
|
35
|
+
setShowHelp(false);
|
|
36
|
+
}
|
|
37
|
+
if (input === "?" && !showHelp) {
|
|
38
|
+
setShowHelp(true);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (showHelp) return;
|
|
42
|
+
|
|
43
|
+
if (key.return && input === "") {
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (key.tab) {
|
|
47
|
+
const panels: ActivePanel[] = ["chat", "dag", "status"];
|
|
48
|
+
const currentIndex = panels.indexOf(activePanel);
|
|
49
|
+
setActivePanel(panels[(currentIndex + 1) % panels.length]);
|
|
50
|
+
}
|
|
20
51
|
});
|
|
21
52
|
|
|
22
53
|
const handleSubmit = (input: string) => {
|
|
@@ -28,6 +59,11 @@ export function App() {
|
|
|
28
59
|
return;
|
|
29
60
|
}
|
|
30
61
|
|
|
62
|
+
if (trimmed === "?" || trimmed === "/help") {
|
|
63
|
+
setShowHelp(!showHelp);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
31
67
|
processCommand(trimmed);
|
|
32
68
|
};
|
|
33
69
|
|
|
@@ -38,24 +74,40 @@ export function App() {
|
|
|
38
74
|
agentCount={state.agentCount}
|
|
39
75
|
provider={state.provider}
|
|
40
76
|
status={state.status}
|
|
77
|
+
tick={tick}
|
|
78
|
+
activePanel={activePanel}
|
|
41
79
|
/>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
80
|
+
|
|
81
|
+
{showHelp ? (
|
|
82
|
+
<HelpOverlay onDismiss={() => setShowHelp(false)} />
|
|
83
|
+
) : (
|
|
84
|
+
<>
|
|
85
|
+
<Box flexGrow={1} flexDirection="row" width="100%">
|
|
86
|
+
<ChatPanel
|
|
87
|
+
messages={state.messages}
|
|
88
|
+
isProcessing={state.isProcessing}
|
|
89
|
+
isActive={activePanel === "chat"}
|
|
90
|
+
/>
|
|
91
|
+
<DAGPanel
|
|
92
|
+
workflowState={state.workflowState}
|
|
93
|
+
tick={tick}
|
|
94
|
+
isActive={activePanel === "dag"}
|
|
95
|
+
/>
|
|
96
|
+
<StatusPanel
|
|
97
|
+
agents={state.agents}
|
|
98
|
+
providers={state.providers}
|
|
99
|
+
fitness={state.fitness}
|
|
100
|
+
currentWorkflow={state.currentWorkflow}
|
|
101
|
+
isActive={activePanel === "status"}
|
|
102
|
+
/>
|
|
103
|
+
</Box>
|
|
104
|
+
<InputBar
|
|
105
|
+
onSubmit={handleSubmit}
|
|
106
|
+
suggestions={state.suggestions}
|
|
107
|
+
isProcessing={state.isProcessing}
|
|
108
|
+
/>
|
|
109
|
+
</>
|
|
110
|
+
)}
|
|
59
111
|
</Box>
|
|
60
112
|
);
|
|
61
113
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Box, Text
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
3
|
|
|
4
4
|
interface Message {
|
|
5
5
|
id: string;
|
|
@@ -12,6 +12,7 @@ interface Message {
|
|
|
12
12
|
interface ChatPanelProps {
|
|
13
13
|
messages: Message[];
|
|
14
14
|
isProcessing: boolean;
|
|
15
|
+
isActive: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
function formatTime(date: Date): string {
|
|
@@ -22,7 +23,7 @@ function formatTime(date: Date): string {
|
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
function MessageItem({ message }: { message: Message
|
|
26
|
+
function MessageItem({ message }: { message: Message }) {
|
|
26
27
|
const typeColors: Record<string, string> = {
|
|
27
28
|
user: "cyan",
|
|
28
29
|
system: "gray",
|
|
@@ -51,18 +52,21 @@ function MessageItem({ message }: { message: Message; key?: string }) {
|
|
|
51
52
|
);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
export function ChatPanel({ messages, isProcessing }: ChatPanelProps) {
|
|
55
|
+
export function ChatPanel({ messages, isProcessing, isActive }: ChatPanelProps) {
|
|
56
|
+
const borderColor = isActive ? "#f97316" : "gray";
|
|
57
|
+
|
|
55
58
|
return (
|
|
56
59
|
<Box
|
|
57
60
|
flexDirection="column"
|
|
58
61
|
flexGrow={2}
|
|
59
62
|
borderStyle="single"
|
|
60
|
-
borderColor=
|
|
63
|
+
borderColor={borderColor}
|
|
61
64
|
paddingX={1}
|
|
62
65
|
>
|
|
63
66
|
<Box borderStyle="single" borderColor="#f97316" marginBottom={1}>
|
|
64
67
|
<Text color="#f97316" bold>CHAT</Text>
|
|
65
68
|
<Text color="gray"> — Tapez /help pour les commandes</Text>
|
|
69
|
+
{isActive && <Text color="yellow"> [ACTIF]</Text>}
|
|
66
70
|
</Box>
|
|
67
71
|
<Box flexDirection="column" flexGrow={1} overflow="hidden">
|
|
68
72
|
{messages.slice(-15).map((msg) => (
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
|
|
4
|
+
interface DAGNode {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
status: "pending" | "running" | "done" | "error";
|
|
8
|
+
agent?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface DAGLevel {
|
|
12
|
+
name: string;
|
|
13
|
+
progress: number;
|
|
14
|
+
nodes: DAGNode[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface WorkflowState {
|
|
18
|
+
levels: DAGLevel[];
|
|
19
|
+
currentLevel: number;
|
|
20
|
+
totalProgress: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface DAGPanelProps {
|
|
24
|
+
workflowState: WorkflowState;
|
|
25
|
+
tick: number;
|
|
26
|
+
isActive: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const statusIcons: Record<string, { icon: string; color: string }> = {
|
|
30
|
+
pending: { icon: "○", color: "gray" },
|
|
31
|
+
running: { icon: "▶", color: "yellow" },
|
|
32
|
+
done: { icon: "●", color: "green" },
|
|
33
|
+
error: { icon: "✗", color: "red" },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const spinnerFrames = ["◐", "◓", "◑", "◒"];
|
|
37
|
+
|
|
38
|
+
function ProgressBar({ progress, width = 20 }: { progress: number; width?: number }) {
|
|
39
|
+
const filled = Math.round((progress / 100) * width);
|
|
40
|
+
const empty = width - filled;
|
|
41
|
+
const bar = "█".repeat(filled) + "░".repeat(empty);
|
|
42
|
+
return (
|
|
43
|
+
<Text color={progress >= 100 ? "green" : progress > 0 ? "yellow" : "gray"}>
|
|
44
|
+
{bar}
|
|
45
|
+
</Text>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function DAGNodeItem({ node, tick }: { node: DAGNode; tick: number }) {
|
|
50
|
+
const { icon, color } = statusIcons[node.status];
|
|
51
|
+
const animatedIcon = node.status === "running"
|
|
52
|
+
? spinnerFrames[tick % spinnerFrames.length]
|
|
53
|
+
: icon;
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Box flexDirection="row" marginLeft={2}>
|
|
57
|
+
<Text color={color}>{animatedIcon}</Text>
|
|
58
|
+
<Text color="white"> {node.name}</Text>
|
|
59
|
+
{node.agent && <Text color="gray"> [{node.agent}]</Text>}
|
|
60
|
+
</Box>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function DAGLevelView({ level, tick, isActive }: { level: DAGLevel; tick: number; isActive: boolean }) {
|
|
65
|
+
return (
|
|
66
|
+
<Box flexDirection="column" marginBottom={1}>
|
|
67
|
+
<Box flexDirection="row">
|
|
68
|
+
<Text color={isActive ? "#f97316" : "gray"} bold={isActive}>
|
|
69
|
+
{level.name}
|
|
70
|
+
</Text>
|
|
71
|
+
<Text color="gray"> </Text>
|
|
72
|
+
<ProgressBar progress={level.progress} width={12} />
|
|
73
|
+
<Text color="gray"> {level.progress}%</Text>
|
|
74
|
+
</Box>
|
|
75
|
+
{level.nodes.map((node) => (
|
|
76
|
+
<DAGNodeItem key={node.id} node={node} tick={tick} />
|
|
77
|
+
))}
|
|
78
|
+
</Box>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function DAGPanel({ workflowState, tick, isActive }: DAGPanelProps) {
|
|
83
|
+
const borderColor = isActive ? "#f97316" : "gray";
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Box
|
|
87
|
+
flexDirection="column"
|
|
88
|
+
width={40}
|
|
89
|
+
borderStyle="single"
|
|
90
|
+
borderColor={borderColor}
|
|
91
|
+
paddingX={1}
|
|
92
|
+
>
|
|
93
|
+
<Box borderStyle="single" borderColor="#f97316" marginBottom={1}>
|
|
94
|
+
<Text color="#f97316" bold>DAG</Text>
|
|
95
|
+
<Text color="gray"> EXECUTION</Text>
|
|
96
|
+
</Box>
|
|
97
|
+
|
|
98
|
+
<Box flexDirection="column" flexGrow={1}>
|
|
99
|
+
{workflowState.levels.map((level, index) => (
|
|
100
|
+
<DAGLevelView
|
|
101
|
+
key={level.name}
|
|
102
|
+
level={level}
|
|
103
|
+
tick={tick}
|
|
104
|
+
isActive={index === workflowState.currentLevel}
|
|
105
|
+
/>
|
|
106
|
+
))}
|
|
107
|
+
</Box>
|
|
108
|
+
|
|
109
|
+
<Box borderStyle="single" borderColor="gray" marginTop={1}>
|
|
110
|
+
<Text color="gray">Total: </Text>
|
|
111
|
+
<ProgressBar progress={workflowState.totalProgress} width={10} />
|
|
112
|
+
<Text color="white"> {workflowState.totalProgress}%</Text>
|
|
113
|
+
</Box>
|
|
114
|
+
</Box>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
@@ -6,9 +6,18 @@ interface HeaderProps {
|
|
|
6
6
|
agentCount: number;
|
|
7
7
|
provider: string;
|
|
8
8
|
status: "ready" | "running" | "error";
|
|
9
|
+
tick: number;
|
|
10
|
+
activePanel: string;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
const spinnerFrames = ["◐", "◓", "◑", "◒"];
|
|
14
|
+
const panelNames: Record<string, string> = {
|
|
15
|
+
chat: "CHAT",
|
|
16
|
+
dag: "DAG",
|
|
17
|
+
status: "STATUS",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function Header({ projectName, agentCount, provider, status, tick, activePanel }: HeaderProps) {
|
|
12
21
|
const statusColors = {
|
|
13
22
|
ready: "green",
|
|
14
23
|
running: "yellow",
|
|
@@ -21,32 +30,46 @@ export function Header({ projectName, agentCount, provider, status }: HeaderProp
|
|
|
21
30
|
error: "ERROR",
|
|
22
31
|
};
|
|
23
32
|
|
|
24
|
-
const
|
|
33
|
+
const animatedStatus = status === "running"
|
|
34
|
+
? spinnerFrames[tick % spinnerFrames.length]
|
|
35
|
+
: status === "error" ? "✗" : "●";
|
|
25
36
|
|
|
26
37
|
return (
|
|
27
38
|
<Box
|
|
28
|
-
flexDirection="
|
|
29
|
-
justifyContent="space-between"
|
|
30
|
-
alignItems="center"
|
|
31
|
-
paddingX={1}
|
|
39
|
+
flexDirection="column"
|
|
32
40
|
borderStyle="single"
|
|
33
41
|
borderColor="gray"
|
|
34
42
|
width="100%"
|
|
35
43
|
>
|
|
36
|
-
<Box
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
<Box
|
|
45
|
+
flexDirection="row"
|
|
46
|
+
justifyContent="space-between"
|
|
47
|
+
alignItems="center"
|
|
48
|
+
paddingX={1}
|
|
49
|
+
>
|
|
50
|
+
<Box flexDirection="row" alignItems="center">
|
|
51
|
+
<Text color="#f97316" bold>■</Text>
|
|
52
|
+
<Text color="white" bold> RAX-FLOW</Text>
|
|
53
|
+
<Text color="gray"> HUB</Text>
|
|
54
|
+
</Box>
|
|
55
|
+
<Box flexDirection="row" alignItems="center">
|
|
56
|
+
<Text color="gray">Project:</Text>
|
|
57
|
+
<Text color="cyan"> {projectName}</Text>
|
|
58
|
+
<Text color="gray"> │ Agents:</Text>
|
|
59
|
+
<Text color="green"> {agentCount}/12</Text>
|
|
60
|
+
<Text color="gray"> │ [{provider}]</Text>
|
|
61
|
+
<Text color={statusColors[status]}> {animatedStatus} {statusText[status]}</Text>
|
|
62
|
+
</Box>
|
|
40
63
|
</Box>
|
|
41
|
-
<Box flexDirection="row"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<Text color=
|
|
64
|
+
<Box flexDirection="row" paddingX={1}>
|
|
65
|
+
{(["chat", "dag", "status"] as const).map((panel) => (
|
|
66
|
+
<Box key={panel} marginRight={2}>
|
|
67
|
+
<Text color={activePanel === panel ? "#f97316" : "gray"} bold={activePanel === panel}>
|
|
68
|
+
[{panelNames[panel]}]
|
|
69
|
+
</Text>
|
|
70
|
+
</Box>
|
|
71
|
+
))}
|
|
72
|
+
<Text color="gray">| Tab: Changer │ ?: Aide │ Ctrl+C: Quitter</Text>
|
|
50
73
|
</Box>
|
|
51
74
|
</Box>
|
|
52
75
|
);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
|
|
4
|
+
interface HelpOverlayProps {
|
|
5
|
+
onDismiss: () => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function HelpOverlay({ onDismiss }: HelpOverlayProps) {
|
|
9
|
+
useInput((input, key) => {
|
|
10
|
+
if (key.escape || input === "q") {
|
|
11
|
+
onDismiss();
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const sections = [
|
|
16
|
+
{
|
|
17
|
+
title: "COMMANDES",
|
|
18
|
+
items: [
|
|
19
|
+
["/run <prompt>", "Exécuter un workflow"],
|
|
20
|
+
["/status", "État du système"],
|
|
21
|
+
["/agents", "Liste des agents"],
|
|
22
|
+
["/providers", "Liste des providers"],
|
|
23
|
+
["/workflows", "Blueprints disponibles"],
|
|
24
|
+
["/help, ?", "Cette aide"],
|
|
25
|
+
["/exit", "Quitter"],
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
title: "NAVIGATION",
|
|
30
|
+
items: [
|
|
31
|
+
["Tab", "Changer de panel actif"],
|
|
32
|
+
["F1-F8", "Aller au panel spécifique"],
|
|
33
|
+
["Ctrl+C", "Quitter"],
|
|
34
|
+
["Esc", "Fermer l'aide"],
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: "PANELS",
|
|
39
|
+
items: [
|
|
40
|
+
["CHAT", "Messages et interaction"],
|
|
41
|
+
["DAG", "Visualisation du workflow"],
|
|
42
|
+
["STATUS", "Agents et providers"],
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Box
|
|
49
|
+
flexDirection="column"
|
|
50
|
+
flexGrow={1}
|
|
51
|
+
borderStyle="double"
|
|
52
|
+
borderColor="#f97316"
|
|
53
|
+
paddingX={2}
|
|
54
|
+
>
|
|
55
|
+
<Box marginBottom={1}>
|
|
56
|
+
<Text color="#f97316" bold>■ RAX-FLOW HELP</Text>
|
|
57
|
+
<Text color="gray"> — [Esc] pour fermer</Text>
|
|
58
|
+
</Box>
|
|
59
|
+
|
|
60
|
+
<Box flexDirection="row" flexGrow={1}>
|
|
61
|
+
{sections.map((section) => (
|
|
62
|
+
<Box key={section.title} flexDirection="column" width={30}>
|
|
63
|
+
<Text color="gray" bold underline>
|
|
64
|
+
{section.title}
|
|
65
|
+
</Text>
|
|
66
|
+
<Box flexDirection="column" marginTop={1}>
|
|
67
|
+
{section.items.map(([cmd, desc]) => (
|
|
68
|
+
<Box key={cmd} flexDirection="row" marginBottom={1}>
|
|
69
|
+
<Text color="cyan">{cmd.padEnd(16)}</Text>
|
|
70
|
+
<Text color="white">{desc}</Text>
|
|
71
|
+
</Box>
|
|
72
|
+
))}
|
|
73
|
+
</Box>
|
|
74
|
+
</Box>
|
|
75
|
+
))}
|
|
76
|
+
</Box>
|
|
77
|
+
|
|
78
|
+
<Box borderStyle="single" borderColor="gray" marginTop={1}>
|
|
79
|
+
<Text color="gray">Pour exécuter un workflow, tapez simplement votre prompt ou /run "..."</Text>
|
|
80
|
+
</Box>
|
|
81
|
+
</Box>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -19,6 +19,7 @@ interface StatusPanelProps {
|
|
|
19
19
|
providers: Provider[];
|
|
20
20
|
fitness: number;
|
|
21
21
|
currentWorkflow: string | null;
|
|
22
|
+
isActive: boolean;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
const statusIcons: Record<string, { icon: string; color: string }> = {
|
|
@@ -28,10 +29,10 @@ const statusIcons: Record<string, { icon: string; color: string }> = {
|
|
|
28
29
|
done: { icon: "●", color: "green" },
|
|
29
30
|
};
|
|
30
31
|
|
|
31
|
-
function AgentRow({ agent
|
|
32
|
+
function AgentRow({ agent }: { agent: Agent }) {
|
|
32
33
|
const { icon, color } = statusIcons[agent.status];
|
|
33
34
|
return (
|
|
34
|
-
<Box
|
|
35
|
+
<Box flexDirection="row" justifyContent="space-between">
|
|
35
36
|
<Text color={color}>{icon}</Text>
|
|
36
37
|
<Text color="white">{agent.name.slice(0, 12).padEnd(12)}</Text>
|
|
37
38
|
<Text color="gray">[{agent.provider}]</Text>
|
|
@@ -39,9 +40,9 @@ function AgentRow({ agent, key }: { agent: Agent; key?: string }) {
|
|
|
39
40
|
);
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
function ProviderRow({ provider
|
|
43
|
+
function ProviderRow({ provider }: { provider: Provider }) {
|
|
43
44
|
return (
|
|
44
|
-
<Box
|
|
45
|
+
<Box flexDirection="row" justifyContent="space-between">
|
|
45
46
|
<Text color={provider.status === "active" ? "green" : "gray"}>
|
|
46
47
|
{provider.status === "active" ? "●" : "○"}
|
|
47
48
|
</Text>
|
|
@@ -51,20 +52,24 @@ function ProviderRow({ provider, key }: { provider: Provider; key?: string }) {
|
|
|
51
52
|
);
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
export function StatusPanel({ agents, providers, fitness, currentWorkflow }: StatusPanelProps) {
|
|
55
|
+
export function StatusPanel({ agents, providers, fitness, currentWorkflow, isActive }: StatusPanelProps) {
|
|
55
56
|
const fitnessColor = fitness >= 0.9 ? "green" : fitness >= 0.7 ? "yellow" : "red";
|
|
57
|
+
const borderColor = isActive ? "#f97316" : "gray";
|
|
56
58
|
|
|
57
59
|
return (
|
|
58
|
-
<Box flexDirection="column" width={
|
|
60
|
+
<Box flexDirection="column" width={30} borderStyle="single" borderColor={borderColor}>
|
|
59
61
|
<Box borderStyle="single" borderColor="#f97316" marginBottom={1}>
|
|
60
62
|
<Text color="#f97316" bold>STATUS</Text>
|
|
63
|
+
{isActive && <Text color="yellow"> [ACTIF]</Text>}
|
|
61
64
|
</Box>
|
|
62
65
|
|
|
63
66
|
<Box flexDirection="column" paddingX={1}>
|
|
64
67
|
<Text color="gray" bold>WORKFLOW</Text>
|
|
65
68
|
<Text color="white">{currentWorkflow || "Aucun"}</Text>
|
|
66
|
-
<
|
|
67
|
-
|
|
69
|
+
<Box flexDirection="row">
|
|
70
|
+
<Text color="gray">Fitness: </Text>
|
|
71
|
+
<Text color={fitnessColor} bold>{fitness.toFixed(2)}</Text>
|
|
72
|
+
</Box>
|
|
68
73
|
</Box>
|
|
69
74
|
|
|
70
75
|
<Box flexDirection="column" paddingX={1} marginTop={1}>
|