Skip to content

Commit dd16071

Browse files
汤圆汤圆
authored andcommitted
feat: deleta task
1 parent 0ea8cd2 commit dd16071

File tree

7 files changed

+87
-56
lines changed

7 files changed

+87
-56
lines changed

public/locales/en/chat.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"web-search": "Web search",
3131
"signin-tips": "<0> Please <1>sign in</1> to deploy an Agent! 🤖 </0> ",
3232
"generating-response": "🧠 Generating response...",
33-
"searching-web-for": "🌐 Searching the web for {{arg}} ..."
33+
"searching-web-for": "🌐 Searching the web for {{arg}} ...",
34+
"pause-mode": "Pause Mode"
3435
}

public/locales/zh/chat.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"web-search": "网络搜索",
3131
"signin-tips": "<0> 请 <1>登录</1> 以部署代理! 🤖 </0> ",
3232
"generating-response": "🧠 生成回复中...",
33-
"searching-web-for": "🌐 正在搜索 {{arg}} ..."
33+
"searching-web-for": "🌐 正在搜索 {{arg}} ...",
34+
"pause-mode": "暂停模式"
3435
}

src/components/AutonomousAgent.ts

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import type {
3030
Task,
3131
AgentPlaybackControl,
3232
} from "../types/agentTypes";
33-
import { useAgentStore } from "./stores";
33+
import { useAgentStore, useMessageStore } from "./stores";
3434
import { i18n } from "next-i18next";
3535

3636
const TIMEOUT_LONG = 1000;
@@ -50,9 +50,8 @@ class AutonomousAgent {
5050
mode: AgentMode;
5151
playbackControl: AgentPlaybackControl;
5252

53-
tasks: Task[] = [];
5453
completedTasks: string[] = [];
55-
isRunning = true;
54+
isRunning = false;
5655
numLoops = 0;
5756
currentTask?: Task;
5857

@@ -88,6 +87,18 @@ class AutonomousAgent {
8887
}
8988

9089
async run() {
90+
if (!this.isRunning) {
91+
this.isRunning = true;
92+
await this.startGoal();
93+
}
94+
95+
await this.loop();
96+
if (this.mode === PAUSE_MODE && !this.isRunning) {
97+
this.handlePause({ agentPlaybackControl: this.playbackControl });
98+
}
99+
}
100+
101+
async startGoal() {
91102
const { isGuestMode, isValidGuest } = this.guestSettings;
92103
if (isGuestMode && !isValidGuest && !this.modelSettings.customApiKey) {
93104
this.sendErrorMessage(
@@ -96,49 +107,38 @@ class AutonomousAgent {
96107
this.stopAgent();
97108
return;
98109
}
99-
if (this.tasks.length === 0) {
100-
this.sendGoalMessage();
101-
this.sendThinkingMessage();
102-
103-
// Initialize by getting tasks
104-
try {
105-
const taskValues = await this.getInitialTasks();
106-
for (const value of taskValues) {
107-
await new Promise((r) => setTimeout(r, TIMOUT_SHORT));
108-
const task: Task = {
109-
taskId: v1().toString(),
110-
value,
111-
status: TASK_STATUS_STARTED,
112-
type: MESSAGE_TYPE_TASK,
113-
};
114-
this.sendMessage(task);
115-
this.tasks.push(task);
116-
}
117-
} catch (e) {
118-
console.log(e);
119-
this.sendErrorMessage(getMessageFromError(e));
120-
this.shutdown();
121-
return;
122-
}
123-
}
110+
this.sendGoalMessage();
111+
this.sendThinkingMessage();
124112

125-
await this.loop();
126-
if (this.mode === PAUSE_MODE && !this.isRunning) {
127-
this.handlePause({ agentPlaybackControl: this.playbackControl });
113+
// Initialize by getting taskValues
114+
try {
115+
const taskValues = await this.getInitialTasks();
116+
for (const value of taskValues) {
117+
await new Promise((r) => setTimeout(r, TIMOUT_SHORT));
118+
const task: Task = {
119+
taskId: v1().toString(),
120+
value,
121+
status: TASK_STATUS_STARTED,
122+
type: MESSAGE_TYPE_TASK,
123+
};
124+
this.sendMessage(task);
125+
}
126+
} catch (e) {
127+
console.log(e);
128+
this.sendErrorMessage(getMessageFromError(e));
129+
this.shutdown();
130+
return;
128131
}
129132
}
130133

131134
async loop() {
132-
console.log(`Loop ${this.numLoops}`);
133-
console.log(this.tasks);
134-
135135
this.conditionalPause();
136136

137137
if (!this.isRunning) {
138138
return;
139139
}
140140

141-
if (this.tasks.length === 0) {
141+
if (this.getRemainingTasks().length === 0) {
142142
this.sendCompletedMessage();
143143
this.shutdown();
144144
return;
@@ -155,7 +155,9 @@ class AutonomousAgent {
155155
// Wait before starting
156156
await new Promise((r) => setTimeout(r, TIMEOUT_LONG));
157157

158-
const currentTask = this.tasks.shift() as Task;
158+
// Start with first task
159+
const currentTask = this.getRemainingTasks()[0] as Task;
160+
this.sendMessage({ ...currentTask, status: TASK_STATUS_EXECUTING });
159161

160162
this.currentTask = currentTask;
161163

@@ -171,19 +173,15 @@ class AutonomousAgent {
171173
this.sendAnalysisMessage(analysis, currentTask.taskId);
172174
}
173175

174-
// Execute first task
175-
// Get and remove first task
176-
this.completedTasks.push(this.tasks[0]?.value || "");
177-
178-
this.sendMessage({ ...currentTask, status: TASK_STATUS_EXECUTING });
179-
180176
const result = await this.executeTask(currentTask.value, analysis);
181177
this.sendMessage({
182178
...currentTask,
183179
info: result,
184180
status: TASK_STATUS_COMPLETED,
185181
});
186182

183+
this.completedTasks.push(currentTask.value || "");
184+
187185
// Wait before adding tasks
188186
await new Promise((r) => setTimeout(r, TIMEOUT_LONG));
189187
this.sendThinkingMessage(currentTask.taskId);
@@ -202,10 +200,9 @@ class AutonomousAgent {
202200
};
203201
return task;
204202
});
205-
this.tasks = newTasks.concat(this.tasks);
203+
206204
for (const task of newTasks) {
207205
await new Promise((r) => setTimeout(r, TIMOUT_SHORT));
208-
// this.tasks.push(task);
209206
this.sendMessage(task);
210207
}
211208

@@ -223,8 +220,13 @@ class AutonomousAgent {
223220
await this.loop();
224221
}
225222

223+
getRemainingTasks() {
224+
const tasks = useMessageStore.getState().tasks;
225+
return tasks.filter((task: Task) => task.status === TASK_STATUS_STARTED);
226+
}
227+
226228
private conditionalPause() {
227-
if (this.mode !== PAUSE_MODE) {
229+
if (this.mode != PAUSE_MODE) {
228230
return;
229231
}
230232

@@ -275,7 +277,7 @@ class AutonomousAgent {
275277
currentTask: string,
276278
result: string
277279
): Promise<string[]> {
278-
const taskValues = this.tasks.map((task) => task.value);
280+
const taskValues = this.getRemainingTasks().map((task) => task.value);
279281

280282
if (this.shouldRunClientSide()) {
281283
return await AgentService.createTasksAgent(

src/components/ChatWindow.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,14 @@ const ChatWindow = ({
185185
</div>
186186
{displaySettings && (
187187
<div className="flex flex-col items-center justify-center md:flex-row">
188-
<SwitchContainer label="Web Search">
188+
<SwitchContainer label={t("web-search")}>
189189
<Switch
190190
disabled={agent !== null}
191191
value={isWebSearchEnabled}
192192
onChange={handleChangeWebSearch}
193193
/>
194194
</SwitchContainer>
195-
<SwitchContainer label={PAUSE_MODE}>
195+
<SwitchContainer label={t("pause-mode")}>
196196
<Switch
197197
disabled={agent !== null}
198198
value={agentMode === PAUSE_MODE}

src/components/Input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const Input = (props: InputProps) => {
8585
inputElement = (
8686
<textarea
8787
className={clsx(
88-
"border:black delay-50 h-20 w-full resize-none rounded-xl border-[2px] border-white/10 bg-[#3a3a3a] p-2 text-sm tracking-wider outline-0 transition-all placeholder:text-white/20 hover:border-[#1E88E5]/40 focus:border-[#1E88E5] md:text-lg",
88+
"border:black delay-50 h-15 w-full resize-none rounded-xl border-[2px] border-white/10 bg-[#3a3a3a] p-2 text-sm tracking-wider outline-0 transition-all placeholder:text-white/20 hover:border-[#1E88E5]/40 focus:border-[#1E88E5] sm:h-20 md:text-lg",
8989
disabled && " cursor-not-allowed hover:border-white/10",
9090
left && "md:rounded-l-none"
9191
)}

src/components/TaskWindow.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Expand from "./motions/expand";
44
import { Task } from "../types/agentTypes";
55
import { getMessageContainerStyle, getTaskStatusIcon } from "./utils/helpers";
66
import { useMessageStore } from "./stores";
7-
import { FaListAlt } from "react-icons/fa";
7+
import { FaListAlt, FaTimesCircle } from "react-icons/fa";
88
import { useAgentStore } from "./stores";
99
import clsx from "clsx";
1010
import { useTranslation } from "next-i18next";
@@ -31,6 +31,15 @@ export const TaskWindow = () => {
3131

3232
const Task = ({ task }: { task: Task }) => {
3333
const isAgentStopped = useAgentStore.use.isAgentStopped();
34+
const deleteTask = useMessageStore.use.deleteTask();
35+
const isTaskDeletable =
36+
task.taskId && !isAgentStopped && task.status === "started";
37+
38+
const handleDeleteTask = () => {
39+
if (isTaskDeletable) {
40+
deleteTask(task.taskId as string);
41+
}
42+
};
3443
return (
3544
<FadeIn>
3645
<div
@@ -42,6 +51,16 @@ const Task = ({ task }: { task: Task }) => {
4251
>
4352
{getTaskStatusIcon(task, { isAgentStopped })}
4453
<span>{task.value}</span>
54+
<div className="flex justify-end">
55+
<FaTimesCircle
56+
onClick={handleDeleteTask}
57+
className={clsx(
58+
isTaskDeletable && "cursor-pointer hover:text-red-500",
59+
!isTaskDeletable && "cursor-not-allowed opacity-30"
60+
)}
61+
size={12}
62+
/>
63+
</div>
4564
</div>
4665
</FadeIn>
4766
);

src/components/stores/messageStore.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const initialMessageState = {
2424
interface MessageSlice {
2525
messages: Message[];
2626
addMessage: (newMessage: Message) => void;
27+
deleteTask: (taskId: string) => void;
2728
}
2829

2930
const createMessageSlice: StateCreator<
@@ -49,17 +50,24 @@ const createMessageSlice: StateCreator<
4950
0,
5051
newMessage
5152
);
53+
const tasks =
54+
isTask(newTask) && !isExistingTask(newTask)
55+
? [newTask, ...state.tasks]
56+
: [...state.tasks];
5257
return {
5358
...state,
5459
messages: messagesCopy,
5560
// messages: [...state.messages, newMessage],
56-
tasks:
57-
isTask(newTask) && !isExistingTask(newTask)
58-
? [...state.tasks, newTask]
59-
: [...state.tasks],
61+
tasks,
6062
};
6163
});
6264
},
65+
deleteTask: (taskId) => {
66+
set((state) => ({
67+
...state,
68+
tasks: state.tasks.filter((task) => task.taskId !== taskId),
69+
}));
70+
},
6371
};
6472
};
6573

0 commit comments

Comments
 (0)