Skip to content

Commit e6aab15

Browse files
authored
Merge pull request #146 from Dogtiti/feature/task
Feature/task
2 parents 5b0eb0e + d9d20f9 commit e6aab15

File tree

12 files changed

+177
-97
lines changed

12 files changed

+177
-97
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/en/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,7 @@
3333
"donation": "Donation",
3434
"continue": "Continue",
3535
"placeholder-agent-goal": "Make the world a better place.",
36-
"paused": "Paused"
36+
"paused": "Paused",
37+
"add-task": "Add Task",
38+
"custom-task":"Custom Task"
3739
}

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
}

public/locales/zh/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,7 @@
3333
"donation": "捐赠",
3434
"continue": "继续",
3535
"placeholder-agent-goal": "让世界变得更美好。",
36-
"paused": "已暂停"
36+
"paused": "已暂停",
37+
"add-task": "新增任务",
38+
"custom-task": "自定义任务"
3739
}

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: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
TASK_STATUS_COMPLETED,
2121
TASK_STATUS_FINAL,
2222
PAUSE_MODE,
23+
AUTOMATIC_MODE,
2324
} from "../types/agentTypes";
2425
import clsx from "clsx";
2526
import { getMessageContainerStyle, getTaskStatusIcon } from "./utils/helpers";
@@ -61,6 +62,7 @@ const ChatWindow = ({
6162
const agent = useAgentStore.use.agent();
6263
const isWebSearchEnabled = useAgentStore.use.isWebSearchEnabled();
6364
const setIsWebSearchEnabled = useAgentStore.use.setIsWebSearchEnabled();
65+
const updateAgentMode = useAgentStore.use.updateAgentMode();
6466

6567
const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {
6668
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
@@ -116,6 +118,10 @@ const ChatWindow = ({
116118
return depth;
117119
};
118120

121+
const handleUpdateAgentMode = (value: boolean) => {
122+
updateAgentMode(value ? PAUSE_MODE : AUTOMATIC_MODE);
123+
};
124+
119125
return (
120126
<div
121127
className={
@@ -178,20 +184,42 @@ const ChatWindow = ({
178184
)}
179185
</div>
180186
{displaySettings && (
181-
<div className="flex items-center justify-center">
182-
<div className="m-1 flex items-center gap-2 rounded-lg border-[2px] border-white/20 bg-zinc-700 px-2 py-1">
183-
<p className="font-mono text-sm">{t("web-search")}</p>
187+
<div className="flex flex-col items-center justify-center md:flex-row">
188+
<SwitchContainer label={t("web-search")}>
184189
<Switch
190+
disabled={agent !== null}
185191
value={isWebSearchEnabled}
186192
onChange={handleChangeWebSearch}
187193
/>
188-
</div>
194+
</SwitchContainer>
195+
<SwitchContainer label={t("pause-mode")}>
196+
<Switch
197+
disabled={agent !== null}
198+
value={agentMode === PAUSE_MODE}
199+
onChange={handleUpdateAgentMode}
200+
/>
201+
</SwitchContainer>
189202
</div>
190203
)}
191204
</div>
192205
);
193206
};
194207

208+
const SwitchContainer = ({
209+
label,
210+
children,
211+
}: {
212+
label: string;
213+
children: React.ReactNode;
214+
}) => {
215+
return (
216+
<div className="m-1 flex w-36 items-center justify-center gap-2 rounded-lg border-[2px] border-white/20 bg-zinc-700 px-2 py-1">
217+
<p className="font-mono text-sm">{label}</p>
218+
{children}
219+
</div>
220+
);
221+
};
222+
195223
interface HeaderProps {
196224
title?: string | ReactNode;
197225
messages: Message[];

src/components/Input.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { isArrayOfType } from "../utils/helpers";
66
import type { toolTipProperties } from "./types";
77

88
interface InputProps {
9+
small?: boolean; // Will lower padding and font size. Currently only works for the default input
910
left?: React.ReactNode;
1011
value: string | number | undefined;
1112
onChange: (
@@ -30,6 +31,7 @@ interface InputProps {
3031

3132
const Input = (props: InputProps) => {
3233
const {
34+
small,
3335
placeholder,
3436
left,
3537
value,
@@ -85,9 +87,10 @@ const Input = (props: InputProps) => {
8587
inputElement = (
8688
<textarea
8789
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",
90+
"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",
8991
disabled && " cursor-not-allowed hover:border-white/10",
90-
left && "md:rounded-l-none"
92+
left && "md:rounded-l-none",
93+
small && "text-sm sm:py-[0]"
9194
)}
9295
placeholder={placeholder}
9396
value={value}
@@ -120,9 +123,11 @@ const Input = (props: InputProps) => {
120123

121124
return (
122125
<div
123-
className={`items-left z-5 flex w-full flex-col rounded-xl font-mono text-lg text-white/75 shadow-xl md:flex-row md:items-center md:bg-[#3a3a3a] ${
124-
isTypeRange() ? "md: border-white/10 md:border-[2px]" : ""
125-
} shadow-xl md:flex-row md:items-center`}
126+
className={clsx(
127+
`items-left z-5 flex h-fit w-full flex-col rounded-xl font-mono text-lg text-white/75 shadow-xl md:flex-row md:items-center md:bg-[#3a3a3a]`,
128+
isTypeRange() && "md: border-white/10 md:border-[2px]",
129+
`shadow-xl md:flex-row md:items-center`
130+
)}
126131
>
127132
{left && (
128133
<Label left={left} type={type} toolTipProperties={toolTipProperties} />

src/components/SettingsDialog.tsx

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
FaCoins,
1111
FaCode,
1212
FaServer,
13-
FaTachometerAlt,
1413
} from "react-icons/fa";
1514
import Dialog from "./Dialog";
1615
import Input from "./Input";
@@ -19,8 +18,6 @@ import Accordion from "./Accordion";
1918
import type { ModelSettings, SettingModel } from "../utils/types";
2019
import { useGuestMode } from "../hooks/useGuestMode";
2120
import clsx from "clsx";
22-
import { AUTOMATIC_MODE, PAUSE_MODE } from "../types/agentTypes";
23-
import { useAgentStore } from "./stores";
2421

2522
export const SettingsDialog: React.FC<{
2623
show: boolean;
@@ -32,9 +29,6 @@ export const SettingsDialog: React.FC<{
3229
});
3330
const { isGuestMode } = useGuestMode(settings.customGuestKey);
3431
const { t } = useTranslation(["settings", "common"]);
35-
const agent = useAgentStore.use.agent();
36-
const agentMode = useAgentStore.use.agentMode();
37-
const updateAgentMode = useAgentStore.use.updateAgentMode();
3832

3933
useEffect(() => {
4034
setSettings(customSettings.settings);
@@ -253,24 +247,6 @@ export const SettingsDialog: React.FC<{
253247
type="password"
254248
/>
255249
)}
256-
<Input
257-
left={
258-
<>
259-
<FaTachometerAlt />
260-
<span className="ml-2">{t("mode")}</span>
261-
</>
262-
}
263-
value={agentMode}
264-
disabled={agent !== null}
265-
onChange={() => null}
266-
setValue={updateAgentMode as (agentMode: string) => void}
267-
type="combobox"
268-
toolTipProperties={{
269-
message: t("mode-tips") as string,
270-
disabled: false,
271-
}}
272-
attributes={{ options: [AUTOMATIC_MODE, PAUSE_MODE] }}
273-
/>
274250
<Accordion
275251
child={advancedSettings}
276252
name={t("advanced-settings")}

0 commit comments

Comments
 (0)