@synergenius/flow-weaver-pack-weaver 0.9.199 → 0.9.201
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/ai-chat-provider.js +5 -5
- package/dist/ai-chat-provider.js.map +1 -1
- package/dist/bot/acceptance-merge.d.ts +21 -0
- package/dist/bot/acceptance-merge.d.ts.map +1 -0
- package/dist/bot/acceptance-merge.js +46 -0
- package/dist/bot/acceptance-merge.js.map +1 -0
- package/dist/bot/ai-client.d.ts +14 -2
- package/dist/bot/ai-client.d.ts.map +1 -1
- package/dist/bot/ai-client.js +71 -24
- package/dist/bot/ai-client.js.map +1 -1
- package/dist/bot/assistant-tools.js +3 -3
- package/dist/bot/assistant-tools.js.map +1 -1
- package/dist/bot/audit-logger.d.ts.map +1 -1
- package/dist/bot/audit-logger.js +34 -14
- package/dist/bot/audit-logger.js.map +1 -1
- package/dist/bot/audit-trail.d.ts +67 -0
- package/dist/bot/audit-trail.d.ts.map +1 -0
- package/dist/bot/audit-trail.js +153 -0
- package/dist/bot/audit-trail.js.map +1 -0
- package/dist/bot/behavior-defaults.d.ts +1 -1
- package/dist/bot/behavior-defaults.d.ts.map +1 -1
- package/dist/bot/behavior-defaults.js +7 -3
- package/dist/bot/behavior-defaults.js.map +1 -1
- package/dist/bot/capability-registry.d.ts +9 -0
- package/dist/bot/capability-registry.d.ts.map +1 -1
- package/dist/bot/capability-registry.js +81 -27
- package/dist/bot/capability-registry.js.map +1 -1
- package/dist/bot/capability-types.d.ts +10 -0
- package/dist/bot/capability-types.d.ts.map +1 -1
- package/dist/bot/cli-provider.d.ts.map +1 -1
- package/dist/bot/cli-provider.js +8 -7
- package/dist/bot/cli-provider.js.map +1 -1
- package/dist/bot/preflight.d.ts +48 -0
- package/dist/bot/preflight.d.ts.map +1 -0
- package/dist/bot/preflight.js +247 -0
- package/dist/bot/preflight.js.map +1 -0
- package/dist/bot/provider-shim.d.ts +74 -0
- package/dist/bot/provider-shim.d.ts.map +1 -0
- package/dist/bot/provider-shim.js +176 -0
- package/dist/bot/provider-shim.js.map +1 -0
- package/dist/bot/runner.d.ts +2 -0
- package/dist/bot/runner.d.ts.map +1 -1
- package/dist/bot/runner.js +60 -17
- package/dist/bot/runner.js.map +1 -1
- package/dist/bot/step-executor.d.ts.map +1 -1
- package/dist/bot/step-executor.js +72 -115
- package/dist/bot/step-executor.js.map +1 -1
- package/dist/bot/swarm-controller.d.ts +2 -0
- package/dist/bot/swarm-controller.d.ts.map +1 -1
- package/dist/bot/swarm-controller.js +92 -20
- package/dist/bot/swarm-controller.js.map +1 -1
- package/dist/bot/task-create-handler.d.ts +37 -0
- package/dist/bot/task-create-handler.d.ts.map +1 -0
- package/dist/bot/task-create-handler.js +124 -0
- package/dist/bot/task-create-handler.js.map +1 -0
- package/dist/bot/task-store.d.ts +1 -0
- package/dist/bot/task-store.d.ts.map +1 -1
- package/dist/bot/task-store.js +67 -0
- package/dist/bot/task-store.js.map +1 -1
- package/dist/bot/types.d.ts +1 -1
- package/dist/bot/types.d.ts.map +1 -1
- package/dist/bot/weaver-tools.d.ts.map +1 -1
- package/dist/bot/weaver-tools.js +7 -39
- package/dist/bot/weaver-tools.js.map +1 -1
- package/dist/node-types/agent-execute.d.ts +25 -8
- package/dist/node-types/agent-execute.d.ts.map +1 -1
- package/dist/node-types/agent-execute.js +89 -23
- package/dist/node-types/agent-execute.js.map +1 -1
- package/dist/node-types/bot-report.d.ts.map +1 -1
- package/dist/node-types/bot-report.js +24 -3
- package/dist/node-types/bot-report.js.map +1 -1
- package/dist/node-types/plan-task.d.ts +8 -17
- package/dist/node-types/plan-task.d.ts.map +1 -1
- package/dist/node-types/plan-task.js +217 -256
- package/dist/node-types/plan-task.js.map +1 -1
- package/dist/node-types/review-result.js +8 -6
- package/dist/node-types/review-result.js.map +1 -1
- package/dist/palindrome.d.ts +9 -0
- package/dist/palindrome.d.ts.map +1 -0
- package/dist/palindrome.js +14 -0
- package/dist/palindrome.js.map +1 -0
- package/dist/ui/approval-card.js +91 -82
- package/dist/ui/bot-activity.js +73 -56
- package/dist/ui/bot-config.js +48 -31
- package/dist/ui/bot-dashboard.js +52 -36
- package/dist/ui/bot-panel.js +230 -228
- package/dist/ui/bot-slot-card.js +100 -90
- package/dist/ui/bot-status.js +37 -15
- package/dist/ui/budget-bar.js +57 -31
- package/dist/ui/capability-editor.js +447 -378
- package/dist/ui/chat-task-result.js +78 -71
- package/dist/ui/decision-log.js +68 -81
- package/dist/ui/genesis-block.js +86 -95
- package/dist/ui/instance-stream-view.js +722 -0
- package/dist/ui/profile-card.js +96 -221
- package/dist/ui/profile-editor.js +532 -575
- package/dist/ui/settings-section.js +41 -45
- package/dist/ui/swarm-controls.js +212 -135
- package/dist/ui/swarm-dashboard.js +3992 -2715
- package/dist/ui/task-detail-view.js +415 -521
- package/dist/ui/task-editor.js +339 -390
- package/dist/ui/task-pool-list.js +60 -55
- package/dist/workflows/src/palindrome.d.ts +11 -0
- package/dist/workflows/src/palindrome.d.ts.map +1 -0
- package/dist/workflows/src/palindrome.js +16 -0
- package/dist/workflows/src/palindrome.js.map +1 -0
- package/dist/workflows/tests/palindrome.test.d.ts +2 -0
- package/dist/workflows/tests/palindrome.test.d.ts.map +1 -0
- package/dist/workflows/tests/palindrome.test.js +41 -0
- package/dist/workflows/tests/palindrome.test.js.map +1 -0
- package/dist/workflows/weaver-bot-batch.js +1 -1
- package/dist/workflows/weaver-bot-batch.js.map +1 -1
- package/dist/workflows/weaver-bot.js +1 -1
- package/dist/workflows/weaver-bot.js.map +1 -1
- package/flowweaver.manifest.json +1 -1
- package/package.json +8 -2
- package/src/ai-chat-provider.ts +5 -5
- package/src/bot/acceptance-merge.ts +62 -0
- package/src/bot/ai-client.ts +77 -21
- package/src/bot/assistant-tools.ts +3 -3
- package/src/bot/audit-logger.ts +42 -14
- package/src/bot/audit-trail.ts +211 -0
- package/src/bot/behavior-defaults.ts +7 -2
- package/src/bot/capability-registry.ts +84 -28
- package/src/bot/capability-types.ts +11 -0
- package/src/bot/cli-provider.ts +8 -7
- package/src/bot/preflight.ts +285 -0
- package/src/bot/provider-shim.ts +218 -0
- package/src/bot/runner.ts +68 -20
- package/src/bot/step-executor.ts +69 -127
- package/src/bot/swarm-controller.ts +94 -20
- package/src/bot/task-create-handler.ts +164 -0
- package/src/bot/task-store.ts +83 -0
- package/src/bot/types.ts +4 -1
- package/src/bot/weaver-tools.ts +7 -45
- package/src/node-types/agent-execute.ts +102 -16
- package/src/node-types/bot-report.ts +24 -3
- package/src/node-types/plan-task.ts +238 -280
- package/src/node-types/review-result.ts +8 -6
- package/src/palindrome.ts +14 -0
- package/src/ui/approval-card.tsx +78 -62
- package/src/ui/bot-activity.tsx +12 -10
- package/src/ui/bot-config.tsx +12 -10
- package/src/ui/bot-dashboard.tsx +13 -11
- package/src/ui/bot-panel.tsx +189 -171
- package/src/ui/bot-slot-card.tsx +125 -70
- package/src/ui/bot-status.tsx +4 -4
- package/src/ui/budget-bar.tsx +86 -25
- package/src/ui/capability-editor.tsx +392 -257
- package/src/ui/chat-task-result.tsx +81 -78
- package/src/ui/decision-log.tsx +76 -73
- package/src/ui/genesis-block.tsx +91 -61
- package/src/ui/instance-stream-view.tsx +861 -0
- package/src/ui/profile-card.tsx +195 -168
- package/src/ui/profile-editor.tsx +453 -370
- package/src/ui/settings-section.tsx +46 -39
- package/src/ui/swarm-controls.tsx +252 -123
- package/src/ui/swarm-dashboard.tsx +999 -466
- package/src/ui/task-detail-view.tsx +485 -428
- package/src/ui/task-editor.tsx +329 -271
- package/src/ui/task-pool-list.tsx +68 -62
- package/src/workflows/src/palindrome.ts +16 -0
- package/src/workflows/tests/palindrome.test.ts +49 -0
- package/src/workflows/weaver-bot-batch.ts +1 -1
- package/src/workflows/weaver-bot.ts +1 -1
- package/dist/ui/bot-constants.d.ts +0 -14
- package/dist/ui/bot-constants.d.ts.map +0 -1
- package/dist/ui/bot-constants.js +0 -189
- package/dist/ui/bot-constants.js.map +0 -1
- package/dist/ui/steer-api.d.ts +0 -7
- package/dist/ui/steer-api.d.ts.map +0 -1
- package/dist/ui/steer-api.js +0 -11
- package/dist/ui/steer-api.js.map +0 -1
- package/dist/ui/trace-to-timeline.d.ts +0 -91
- package/dist/ui/trace-to-timeline.d.ts.map +0 -1
- package/dist/ui/trace-to-timeline.js +0 -116
- package/dist/ui/trace-to-timeline.js.map +0 -1
- package/dist/ui/use-stream-timeline.d.ts +0 -50
- package/dist/ui/use-stream-timeline.d.ts.map +0 -1
- package/dist/ui/use-stream-timeline.js +0 -245
- package/dist/ui/use-stream-timeline.js.map +0 -1
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* SettingsSection — inline collapsible settings, rendered inside workspace.
|
|
3
3
|
* Starts collapsed; fetches provider/insight data on mount.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { Flex, Typography, Button, CollapsibleSection, KeyValueRow, toast } = require('@fw/plugin-ui-kit');
|
|
5
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
6
|
+
import { Flex, Typography, Button, CollapsibleSection, KeyValueRow, toast } from '@fw/plugin-ui-kit';
|
|
8
7
|
|
|
9
8
|
interface SettingsSectionProps {
|
|
10
9
|
callTool: (tool: string, args?: Record<string, unknown>) => Promise<unknown>;
|
|
@@ -54,42 +53,50 @@ function SettingsSection({ callTool, dispatchEvent }: SettingsSectionProps) {
|
|
|
54
53
|
? (trustScore <= 1 ? (trustScore * 100).toFixed(0) : Math.round(trustScore)) + '%'
|
|
55
54
|
: '\u2014';
|
|
56
55
|
|
|
57
|
-
return
|
|
58
|
-
title
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
variant
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
56
|
+
return (
|
|
57
|
+
<CollapsibleSection title="Settings" variant="list" defaultExpanded={false}>
|
|
58
|
+
<Flex variant="column-start-start-nowrap-4" style={{ width: '100%' }}>
|
|
59
|
+
{activeProvider && (
|
|
60
|
+
<KeyValueRow
|
|
61
|
+
keyName="Provider"
|
|
62
|
+
value={`${activeProvider.name} (${activeProvider.source})`}
|
|
63
|
+
size="small"
|
|
64
|
+
/>
|
|
65
|
+
)}
|
|
66
|
+
{insights?.trust && (
|
|
67
|
+
<KeyValueRow
|
|
68
|
+
keyName="Trust"
|
|
69
|
+
value={`Phase ${insights.trust.phase} · ${trustDisplay}`}
|
|
70
|
+
size="small"
|
|
71
|
+
/>
|
|
72
|
+
)}
|
|
73
|
+
{insights?.health && (
|
|
74
|
+
<KeyValueRow
|
|
75
|
+
keyName="Health"
|
|
76
|
+
value={`${insights.health.overall}/100`}
|
|
77
|
+
size="small"
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
{insights?.cost && (
|
|
81
|
+
<KeyValueRow
|
|
82
|
+
keyName="Cost (7d)"
|
|
83
|
+
value={`$${insights.cost.last7Days?.toFixed(2) ?? '0.00'} · ${insights.cost.trend ?? 'stable'}`}
|
|
84
|
+
size="small"
|
|
85
|
+
/>
|
|
86
|
+
)}
|
|
87
|
+
<Flex
|
|
88
|
+
variant="row-center-space-between-nowrap-8"
|
|
89
|
+
style={{ width: '100%', marginTop: '4px' }}
|
|
90
|
+
>
|
|
91
|
+
<Button size="xs" variant="outlined" color="danger" onClick={handleClear}>
|
|
92
|
+
Clear Run History
|
|
93
|
+
</Button>
|
|
94
|
+
<Typography variant="smallCaption-regular" color="color-text-subtle">
|
|
95
|
+
Edit settings in .weaver.json
|
|
96
|
+
</Typography>
|
|
97
|
+
</Flex>
|
|
98
|
+
</Flex>
|
|
99
|
+
</CollapsibleSection>
|
|
93
100
|
);
|
|
94
101
|
}
|
|
95
102
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SwarmControls — control bar for the swarm: start/pause/stop, status badge, active bots count.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* When idle and Start is clicked, expands an inline config form for concurrency + budget params.
|
|
5
|
+
* When running, shows editable max concurrency inline in the stats area.
|
|
4
6
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
import React, { useState, useCallback } from 'react';
|
|
8
|
+
import {
|
|
9
|
+
Flex, Button, Typography, IconButton, StatusIcon, Input, Slider, Field, Section,
|
|
10
|
+
CollapsibleSection, toast, usePackWorkspace,
|
|
11
|
+
} from '@fw/plugin-ui-kit';
|
|
10
12
|
|
|
11
13
|
// ---------------------------------------------------------------------------
|
|
12
14
|
// Types
|
|
@@ -19,6 +21,13 @@ interface InstanceInfo {
|
|
|
19
21
|
currentTaskId?: string;
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
interface SwarmBudgetLayer {
|
|
25
|
+
limitTokens: number;
|
|
26
|
+
usedTokens: number;
|
|
27
|
+
limitCost: number;
|
|
28
|
+
usedCost: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
22
31
|
interface SwarmStatus {
|
|
23
32
|
status: 'idle' | 'running' | 'paused' | 'stopping';
|
|
24
33
|
instances: Record<string, InstanceInfo>;
|
|
@@ -28,6 +37,7 @@ interface SwarmStatus {
|
|
|
28
37
|
totalTokensUsed: number;
|
|
29
38
|
totalCost: number;
|
|
30
39
|
startedAt?: string;
|
|
40
|
+
budgets?: { workspace: SwarmBudgetLayer; session: SwarmBudgetLayer };
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
interface SwarmControlsProps {
|
|
@@ -74,6 +84,16 @@ function SwarmControls({ swarmStatus, onRefresh }: SwarmControlsProps) {
|
|
|
74
84
|
const [starting, setStarting] = useState(false);
|
|
75
85
|
const [pausing, setPausing] = useState(false);
|
|
76
86
|
const [stopping, setStopping] = useState(false);
|
|
87
|
+
const [showStartConfig, setShowStartConfig] = useState(false);
|
|
88
|
+
|
|
89
|
+
// Start config form state
|
|
90
|
+
const [maxConcurrent, setMaxConcurrent] = useState(5);
|
|
91
|
+
const [sessionTokenBudget, setSessionTokenBudget] = useState('');
|
|
92
|
+
const [sessionCostBudget, setSessionCostBudget] = useState('');
|
|
93
|
+
|
|
94
|
+
// Live concurrency edit
|
|
95
|
+
const [editingConcurrency, setEditingConcurrency] = useState(false);
|
|
96
|
+
const [liveConcurrency, setLiveConcurrency] = useState('');
|
|
77
97
|
|
|
78
98
|
const status = swarmStatus?.status ?? 'idle';
|
|
79
99
|
const instances = swarmStatus?.instances ?? {};
|
|
@@ -86,38 +106,39 @@ function SwarmControls({ swarmStatus, onRefresh }: SwarmControlsProps) {
|
|
|
86
106
|
|
|
87
107
|
// --- Actions ---
|
|
88
108
|
|
|
89
|
-
const
|
|
109
|
+
const handleStartWithConfig = useCallback(async () => {
|
|
90
110
|
setStarting(true);
|
|
91
111
|
try {
|
|
92
|
-
const
|
|
112
|
+
const args: Record<string, unknown> = {};
|
|
113
|
+
if (maxConcurrent > 0) args.maxConcurrent = maxConcurrent;
|
|
114
|
+
const st = parseInt(sessionTokenBudget, 10);
|
|
115
|
+
if (st > 0) args.sessionBudgetTokens = st;
|
|
116
|
+
const sc = parseFloat(sessionCostBudget);
|
|
117
|
+
if (sc > 0) args.sessionBudgetCost = sc;
|
|
118
|
+
|
|
119
|
+
const result = await ctx.callTool('fw_weaver_swarm_start', args);
|
|
93
120
|
const data = result as Record<string, unknown> | null;
|
|
94
121
|
if (data?.error) {
|
|
95
122
|
toast(String(data.error), { type: 'error' });
|
|
96
123
|
} else {
|
|
97
124
|
toast('Swarm started', { type: 'success' });
|
|
125
|
+
setShowStartConfig(false);
|
|
98
126
|
}
|
|
99
127
|
onRefresh();
|
|
100
128
|
} catch (err: unknown) {
|
|
101
|
-
|
|
102
|
-
toast(msg, { type: 'error' });
|
|
129
|
+
toast(err instanceof Error ? err.message : 'Failed to start swarm', { type: 'error' });
|
|
103
130
|
}
|
|
104
131
|
setStarting(false);
|
|
105
|
-
}, [ctx, onRefresh]);
|
|
132
|
+
}, [ctx, onRefresh, maxConcurrent, sessionTokenBudget, sessionCostBudget]);
|
|
106
133
|
|
|
107
134
|
const handlePause = useCallback(async () => {
|
|
108
135
|
setPausing(true);
|
|
109
136
|
try {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (data?.error) {
|
|
113
|
-
toast(String(data.error), { type: 'error' });
|
|
114
|
-
} else {
|
|
115
|
-
toast('Swarm paused', { type: 'info' });
|
|
116
|
-
}
|
|
137
|
+
await ctx.callTool('fw_weaver_swarm_pause', {});
|
|
138
|
+
toast('Swarm paused', { type: 'info' });
|
|
117
139
|
onRefresh();
|
|
118
140
|
} catch (err: unknown) {
|
|
119
|
-
|
|
120
|
-
toast(msg, { type: 'error' });
|
|
141
|
+
toast(err instanceof Error ? err.message : 'Failed to pause', { type: 'error' });
|
|
121
142
|
}
|
|
122
143
|
setPausing(false);
|
|
123
144
|
}, [ctx, onRefresh]);
|
|
@@ -125,17 +146,11 @@ function SwarmControls({ swarmStatus, onRefresh }: SwarmControlsProps) {
|
|
|
125
146
|
const handleResume = useCallback(async () => {
|
|
126
147
|
setStarting(true);
|
|
127
148
|
try {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (data?.error) {
|
|
131
|
-
toast(String(data.error), { type: 'error' });
|
|
132
|
-
} else {
|
|
133
|
-
toast('Swarm resumed', { type: 'success' });
|
|
134
|
-
}
|
|
149
|
+
await ctx.callTool('fw_weaver_swarm_start', {});
|
|
150
|
+
toast('Swarm resumed', { type: 'success' });
|
|
135
151
|
onRefresh();
|
|
136
152
|
} catch (err: unknown) {
|
|
137
|
-
|
|
138
|
-
toast(msg, { type: 'error' });
|
|
153
|
+
toast(err instanceof Error ? err.message : 'Failed to resume', { type: 'error' });
|
|
139
154
|
}
|
|
140
155
|
setStarting(false);
|
|
141
156
|
}, [ctx, onRefresh]);
|
|
@@ -149,112 +164,226 @@ function SwarmControls({ swarmStatus, onRefresh }: SwarmControlsProps) {
|
|
|
149
164
|
});
|
|
150
165
|
if (!ok) { setStopping(false); return; }
|
|
151
166
|
try {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (data?.error) {
|
|
155
|
-
toast(String(data.error), { type: 'error' });
|
|
156
|
-
} else {
|
|
157
|
-
toast('Swarm stopped', { type: 'info' });
|
|
158
|
-
}
|
|
167
|
+
await ctx.callTool('fw_weaver_swarm_stop', {});
|
|
168
|
+
toast('Swarm stopped', { type: 'info' });
|
|
159
169
|
onRefresh();
|
|
160
170
|
} catch (err: unknown) {
|
|
161
|
-
|
|
162
|
-
toast(msg, { type: 'error' });
|
|
171
|
+
toast(err instanceof Error ? err.message : 'Failed to stop', { type: 'error' });
|
|
163
172
|
}
|
|
164
173
|
setStopping(false);
|
|
165
174
|
}, [ctx, onRefresh]);
|
|
166
175
|
|
|
176
|
+
const handleConcurrencyChange = useCallback(async () => {
|
|
177
|
+
const mc = parseInt(liveConcurrency, 10);
|
|
178
|
+
if (!mc || mc < 1) { setEditingConcurrency(false); return; }
|
|
179
|
+
try {
|
|
180
|
+
await ctx.callTool('fw_weaver_swarm_config', { maxConcurrent: mc });
|
|
181
|
+
toast(`Max concurrency set to ${mc}`, { type: 'success' });
|
|
182
|
+
onRefresh();
|
|
183
|
+
} catch (err: unknown) {
|
|
184
|
+
toast(err instanceof Error ? err.message : 'Failed to update config', { type: 'error' });
|
|
185
|
+
}
|
|
186
|
+
setEditingConcurrency(false);
|
|
187
|
+
}, [ctx, onRefresh, liveConcurrency]);
|
|
188
|
+
|
|
167
189
|
// --- Render ---
|
|
168
190
|
|
|
169
191
|
const anyLoading = starting || pausing || stopping;
|
|
170
192
|
|
|
171
|
-
return
|
|
172
|
-
variant
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
: isPaused
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
193
|
+
return (
|
|
194
|
+
<Flex variant="column-stretch-start-nowrap-0">
|
|
195
|
+
|
|
196
|
+
{/* Main control bar */}
|
|
197
|
+
<Section
|
|
198
|
+
padding="compact"
|
|
199
|
+
border="bottom"
|
|
200
|
+
shrink={true}
|
|
201
|
+
background={isRunning ? 'none' : isPaused ? 'none' : 'none'}
|
|
202
|
+
>
|
|
203
|
+
<Flex variant="row-center-space-between-nowrap-10">
|
|
204
|
+
|
|
205
|
+
{/* Left: status icon + label */}
|
|
206
|
+
<Flex variant="row-center-start-nowrap-8">
|
|
207
|
+
<StatusIcon
|
|
208
|
+
status={swarmStatusToIconStatus(status)}
|
|
209
|
+
size="sm"
|
|
210
|
+
/>
|
|
211
|
+
<Typography variant="caption-bold">{statusLabel(status)}</Typography>
|
|
212
|
+
</Flex>
|
|
213
|
+
|
|
214
|
+
{/* Center: bot count + stats + live concurrency */}
|
|
215
|
+
<Flex variant="row-center-start-nowrap-12">
|
|
216
|
+
{total > 0 && (
|
|
217
|
+
<Typography variant="caption-regular" color="color-text-medium">
|
|
218
|
+
{`${active}/${total} bots active`}
|
|
219
|
+
</Typography>
|
|
220
|
+
)}
|
|
221
|
+
|
|
222
|
+
{/* Concurrency display (when running) — edit in Control tab */}
|
|
223
|
+
{(isRunning || isPaused) && (
|
|
224
|
+
<Typography variant="caption-regular" color="color-text-subtle">
|
|
225
|
+
{`max ${swarmStatus?.maxConcurrent ?? '?'}`}
|
|
226
|
+
</Typography>
|
|
227
|
+
)}
|
|
228
|
+
|
|
229
|
+
{swarmStatus && swarmStatus.tasksCompleted > 0 && (
|
|
230
|
+
<Typography variant="caption-regular" color="color-text-subtle">
|
|
231
|
+
{`${swarmStatus.tasksCompleted} done`}
|
|
232
|
+
</Typography>
|
|
233
|
+
)}
|
|
234
|
+
{swarmStatus && swarmStatus.runsIncomplete > 0 && (
|
|
235
|
+
<Typography variant="caption-regular" color="color-status-negative">
|
|
236
|
+
{`${swarmStatus.runsIncomplete} incomplete`}
|
|
237
|
+
</Typography>
|
|
238
|
+
)}
|
|
239
|
+
</Flex>
|
|
240
|
+
|
|
241
|
+
{/* Right: action buttons */}
|
|
242
|
+
<Flex variant="row-center-start-nowrap-4">
|
|
243
|
+
{/* Start button (idle) — opens config form */}
|
|
244
|
+
{isIdle && !showStartConfig && (
|
|
245
|
+
<Button
|
|
246
|
+
size="xs"
|
|
247
|
+
variant="outlined"
|
|
248
|
+
color="primary"
|
|
249
|
+
onClick={() => setShowStartConfig(true)}
|
|
250
|
+
disabled={anyLoading}
|
|
251
|
+
>
|
|
252
|
+
Start
|
|
253
|
+
</Button>
|
|
254
|
+
)}
|
|
255
|
+
|
|
256
|
+
{/* Resume button (paused) */}
|
|
257
|
+
{isPaused && (
|
|
258
|
+
<Button
|
|
259
|
+
size="xs"
|
|
260
|
+
variant="outlined"
|
|
261
|
+
color="primary"
|
|
262
|
+
onClick={handleResume}
|
|
263
|
+
loading={starting}
|
|
264
|
+
disabled={anyLoading}
|
|
265
|
+
>
|
|
266
|
+
Resume
|
|
267
|
+
</Button>
|
|
268
|
+
)}
|
|
269
|
+
|
|
270
|
+
{/* Pause button (running) */}
|
|
271
|
+
{isRunning && (
|
|
272
|
+
<Button
|
|
273
|
+
size="xs"
|
|
274
|
+
variant="outlined"
|
|
275
|
+
color="warning"
|
|
276
|
+
onClick={handlePause}
|
|
277
|
+
loading={pausing}
|
|
278
|
+
disabled={anyLoading}
|
|
279
|
+
>
|
|
280
|
+
Pause
|
|
281
|
+
</Button>
|
|
282
|
+
)}
|
|
283
|
+
|
|
284
|
+
{/* Stop button (running or paused) */}
|
|
285
|
+
{(isRunning || isPaused) && (
|
|
286
|
+
<Button
|
|
287
|
+
size="xs"
|
|
288
|
+
variant="outlined"
|
|
289
|
+
color="danger"
|
|
290
|
+
onClick={handleStop}
|
|
291
|
+
loading={stopping}
|
|
292
|
+
disabled={anyLoading || isStopping}
|
|
293
|
+
>
|
|
294
|
+
Stop
|
|
295
|
+
</Button>
|
|
296
|
+
)}
|
|
297
|
+
|
|
298
|
+
{/* Cancel start config */}
|
|
299
|
+
{isIdle && showStartConfig && (
|
|
300
|
+
<IconButton
|
|
301
|
+
icon="close"
|
|
302
|
+
size="xs"
|
|
303
|
+
variant="clear"
|
|
304
|
+
onClick={() => setShowStartConfig(false)}
|
|
305
|
+
/>
|
|
306
|
+
)}
|
|
307
|
+
|
|
308
|
+
{/* Refresh */}
|
|
309
|
+
<IconButton
|
|
310
|
+
icon="reset"
|
|
311
|
+
size="xs"
|
|
312
|
+
variant="outlined"
|
|
313
|
+
onClick={onRefresh}
|
|
314
|
+
disabled={anyLoading}
|
|
315
|
+
/>
|
|
316
|
+
</Flex>
|
|
317
|
+
</Flex>
|
|
318
|
+
</Section>
|
|
319
|
+
|
|
320
|
+
{/* Start config form (inline, when Start is clicked) */}
|
|
321
|
+
{isIdle && showStartConfig && (
|
|
322
|
+
<Section padding="default" border="bottom" shrink={true}>
|
|
323
|
+
<Flex variant="column-stretch-start-nowrap-8">
|
|
324
|
+
<Typography variant="caption-thick" color="color-text-high">
|
|
325
|
+
Start Configuration
|
|
326
|
+
</Typography>
|
|
327
|
+
|
|
328
|
+
<Flex variant="row-center-start-nowrap-12">
|
|
329
|
+
<Flex variant="row-center-start-nowrap-8">
|
|
330
|
+
<Typography variant="smallCaption-regular" color="color-text-subtle">Max</Typography>
|
|
331
|
+
<Slider
|
|
332
|
+
value={maxConcurrent}
|
|
333
|
+
min={1}
|
|
334
|
+
max={20}
|
|
335
|
+
step={1}
|
|
336
|
+
onChange={(val: number) => setMaxConcurrent(val)}
|
|
337
|
+
/>
|
|
338
|
+
<Typography variant="caption-thick" color="color-text-high">{maxConcurrent}</Typography>
|
|
339
|
+
</Flex>
|
|
340
|
+
<Field label="Token Budget" labelWidth={100}>
|
|
341
|
+
<Input
|
|
342
|
+
value={sessionTokenBudget}
|
|
343
|
+
onChange={(value: string) => setSessionTokenBudget(value)}
|
|
344
|
+
type="number"
|
|
345
|
+
size="small"
|
|
346
|
+
placeholder="No limit"
|
|
347
|
+
/>
|
|
348
|
+
</Field>
|
|
349
|
+
<Field label="Cost Budget ($)" labelWidth={100}>
|
|
350
|
+
<Input
|
|
351
|
+
value={sessionCostBudget}
|
|
352
|
+
onChange={(value: string) => setSessionCostBudget(value)}
|
|
353
|
+
type="number"
|
|
354
|
+
size="small"
|
|
355
|
+
placeholder="No limit"
|
|
356
|
+
/>
|
|
357
|
+
</Field>
|
|
358
|
+
</Flex>
|
|
359
|
+
|
|
360
|
+
<Flex variant="row-center-start-nowrap-8">
|
|
361
|
+
<Button
|
|
362
|
+
size="xs"
|
|
363
|
+
variant="fill"
|
|
364
|
+
color="primary"
|
|
365
|
+
onClick={handleStartWithConfig}
|
|
366
|
+
loading={starting}
|
|
367
|
+
disabled={anyLoading}
|
|
368
|
+
leftIcon="playArrow"
|
|
369
|
+
>
|
|
370
|
+
Start Swarm
|
|
371
|
+
</Button>
|
|
372
|
+
<Button
|
|
373
|
+
size="xs"
|
|
374
|
+
variant="clear"
|
|
375
|
+
color="secondary"
|
|
376
|
+
onClick={() => setShowStartConfig(false)}
|
|
377
|
+
>
|
|
378
|
+
Cancel
|
|
379
|
+
</Button>
|
|
380
|
+
</Flex>
|
|
381
|
+
</Flex>
|
|
382
|
+
</Section>
|
|
383
|
+
)}
|
|
384
|
+
</Flex>
|
|
255
385
|
);
|
|
256
386
|
}
|
|
257
387
|
|
|
258
388
|
export { SwarmControls };
|
|
259
389
|
export default SwarmControls;
|
|
260
|
-
module.exports = SwarmControls;
|