diff --git a/frontend/src/assets/confirm.tsx b/frontend/src/assets/confirm.tsx
new file mode 100644
index 000000000000..f982f14cef38
--- /dev/null
+++ b/frontend/src/assets/confirm.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+function ConfirmIcon(): JSX.Element {
+ return (
+
+ );
+}
+
+export default ConfirmIcon;
diff --git a/frontend/src/assets/reject.tsx b/frontend/src/assets/reject.tsx
new file mode 100644
index 000000000000..1713d93cd5b5
--- /dev/null
+++ b/frontend/src/assets/reject.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+
+function RejectIcon(): JSX.Element {
+ return (
+
+ );
+}
+
+export default RejectIcon;
diff --git a/frontend/src/components/AgentControlBar.tsx b/frontend/src/components/AgentControlBar.tsx
index e33dd8d9e265..04f1775b2323 100644
--- a/frontend/src/components/AgentControlBar.tsx
+++ b/frontend/src/components/AgentControlBar.tsx
@@ -17,6 +17,7 @@ const IgnoreTaskStateMap: { [k: string]: AgentState[] } = {
AgentState.FINISHED,
AgentState.REJECTED,
AgentState.AWAITING_USER_INPUT,
+ AgentState.AWAITING_USER_CONFIRMATION,
],
[AgentState.RUNNING]: [
AgentState.INIT,
@@ -25,8 +26,12 @@ const IgnoreTaskStateMap: { [k: string]: AgentState[] } = {
AgentState.FINISHED,
AgentState.REJECTED,
AgentState.AWAITING_USER_INPUT,
+ AgentState.AWAITING_USER_CONFIRMATION,
],
[AgentState.STOPPED]: [AgentState.INIT, AgentState.STOPPED],
+ [AgentState.USER_CONFIRMED]: [AgentState.RUNNING],
+ [AgentState.USER_REJECTED]: [AgentState.RUNNING],
+ [AgentState.AWAITING_USER_CONFIRMATION]: [],
};
interface ButtonProps {
@@ -101,42 +106,44 @@ function AgentControlBar() {
}, [curAgentState]);
return (
-
- {curAgentState === AgentState.PAUSED ? (
+
+
+ {curAgentState === AgentState.PAUSED ? (
+
+
+
+ ) : (
+
+
+
+ )}
-
+
- ) : (
-
-
-
- )}
-
-
-
+
);
}
diff --git a/frontend/src/components/AgentStatusBar.tsx b/frontend/src/components/AgentStatusBar.tsx
index bdcb3e6773d9..9c38e3e20bf6 100644
--- a/frontend/src/components/AgentStatusBar.tsx
+++ b/frontend/src/components/AgentStatusBar.tsx
@@ -58,6 +58,20 @@ function AgentStatusBar() {
message: t(I18nKey.CHAT_INTERFACE$AGENT_ERROR_MESSAGE),
indicator: IndicatorColor.RED,
},
+ [AgentState.AWAITING_USER_CONFIRMATION]: {
+ message: t(
+ I18nKey.CHAT_INTERFACE$AGENT_AWAITING_USER_CONFIRMATION_MESSAGE,
+ ),
+ indicator: IndicatorColor.ORANGE,
+ },
+ [AgentState.USER_CONFIRMED]: {
+ message: t(I18nKey.CHAT_INTERFACE$AGENT_ACTION_USER_CONFIRMED_MESSAGE),
+ indicator: IndicatorColor.GREEN,
+ },
+ [AgentState.USER_REJECTED]: {
+ message: t(I18nKey.CHAT_INTERFACE$AGENT_ACTION_USER_REJECTED_MESSAGE),
+ indicator: IndicatorColor.RED,
+ },
};
// TODO: Extend the agent status, e.g.:
diff --git a/frontend/src/components/chat/Chat.test.tsx b/frontend/src/components/chat/Chat.test.tsx
index eee37dd4bd6e..1753236c8afa 100644
--- a/frontend/src/components/chat/Chat.test.tsx
+++ b/frontend/src/components/chat/Chat.test.tsx
@@ -1,6 +1,7 @@
import React from "react";
-import { render, screen } from "@testing-library/react";
+import { screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
+import { renderWithProviders } from "test-utils";
import Chat from "./Chat";
const MESSAGES: Message[] = [
@@ -13,7 +14,7 @@ HTMLElement.prototype.scrollTo = vi.fn(() => {});
describe("Chat", () => {
it("should render chat messages", () => {
- render(
);
+ renderWithProviders(
);
const messages = screen.getAllByTestId("message");
diff --git a/frontend/src/components/chat/Chat.tsx b/frontend/src/components/chat/Chat.tsx
index 4f82d1889efc..06122b4d8879 100644
--- a/frontend/src/components/chat/Chat.tsx
+++ b/frontend/src/components/chat/Chat.tsx
@@ -1,15 +1,24 @@
import React from "react";
import ChatMessage from "./ChatMessage";
+import AgentState from "#/types/AgentState";
interface ChatProps {
messages: Message[];
+ curAgentState?: AgentState;
}
-function Chat({ messages }: ChatProps) {
+function Chat({ messages, curAgentState }: ChatProps) {
return (
{messages.map((message, index) => (
-
+
))}
);
diff --git a/frontend/src/components/chat/ChatInterface.tsx b/frontend/src/components/chat/ChatInterface.tsx
index c4fde682af2f..5dcdae3c8f91 100644
--- a/frontend/src/components/chat/ChatInterface.tsx
+++ b/frontend/src/components/chat/ChatInterface.tsx
@@ -123,7 +123,7 @@ function ChatInterface() {
className="overflow-y-auto p-3"
onScroll={(e) => onChatBodyScroll(e.currentTarget)}
>
-
+
@@ -169,7 +169,10 @@ function ChatInterface() {
({
describe("Message", () => {
it("should render a user message", () => {
- render();
+ render(
+ ,
+ );
expect(screen.getByTestId("message")).toBeInTheDocument();
expect(screen.getByTestId("message")).toHaveClass("self-end"); // user message should be on the right side
});
it("should render an assistant message", () => {
- render();
+ render(
+ ,
+ );
expect(screen.getByTestId("message")).toBeInTheDocument();
expect(screen.getByTestId("message")).not.toHaveClass("self-end"); // assistant message should be on the left side
@@ -30,6 +40,7 @@ describe("Message", () => {
sender: "user",
content: "```js\nconsole.log('Hello')\n```",
}}
+ isLastMessage={false}
/>,
);
diff --git a/frontend/src/components/chat/ChatMessage.tsx b/frontend/src/components/chat/ChatMessage.tsx
index 522696195f37..a78eaef738a0 100644
--- a/frontend/src/components/chat/ChatMessage.tsx
+++ b/frontend/src/components/chat/ChatMessage.tsx
@@ -3,15 +3,26 @@ import Markdown from "react-markdown";
import { FaClipboard, FaClipboardCheck } from "react-icons/fa";
import { twMerge } from "tailwind-merge";
import { useTranslation } from "react-i18next";
+import { Tooltip } from "@nextui-org/react";
+import AgentState from "#/types/AgentState";
import { code } from "../markdown/code";
import toast from "#/utils/toast";
import { I18nKey } from "#/i18n/declaration";
+import ConfirmIcon from "#/assets/confirm";
+import RejectIcon from "#/assets/reject";
+import { changeAgentState } from "#/services/agentStateService";
interface MessageProps {
message: Message;
+ isLastMessage?: boolean;
+ awaitingUserConfirmation?: boolean;
}
-function ChatMessage({ message }: MessageProps) {
+function ChatMessage({
+ message,
+ isLastMessage,
+ awaitingUserConfirmation,
+}: MessageProps) {
const [isCopy, setIsCopy] = useState(false);
const [isHovering, setIsHovering] = useState(false);
@@ -58,6 +69,45 @@ function ChatMessage({ message }: MessageProps) {
)}
{message.content}
+ {isLastMessage &&
+ message.sender === "assistant" &&
+ awaitingUserConfirmation && (
+
+
{t(I18nKey.CHAT_INTERFACE$USER_ASK_CONFIRMATION)}
+
+
+
+
+
+
+
+
+
+ )}
);
}
diff --git a/frontend/src/components/modals/settings/SettingsForm.test.tsx b/frontend/src/components/modals/settings/SettingsForm.test.tsx
index af44d9ad40ab..e8ade8dcf0cb 100644
--- a/frontend/src/components/modals/settings/SettingsForm.test.tsx
+++ b/frontend/src/components/modals/settings/SettingsForm.test.tsx
@@ -9,6 +9,7 @@ const onModelChangeMock = vi.fn();
const onAgentChangeMock = vi.fn();
const onLanguageChangeMock = vi.fn();
const onAPIKeyChangeMock = vi.fn();
+const onConfirmationModeChangeMock = vi.fn();
const renderSettingsForm = (settings?: Settings) => {
renderWithProviders(
@@ -20,6 +21,7 @@ const renderSettingsForm = (settings?: Settings) => {
AGENT: "agent1",
LANGUAGE: "en",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
}
}
models={["model1", "model2", "model3"]}
@@ -28,6 +30,7 @@ const renderSettingsForm = (settings?: Settings) => {
onAgentChange={onAgentChangeMock}
onLanguageChange={onLanguageChangeMock}
onAPIKeyChange={onAPIKeyChangeMock}
+ onConfirmationModeChange={onConfirmationModeChangeMock}
/>,
);
};
@@ -40,11 +43,13 @@ describe("SettingsForm", () => {
const agentInput = screen.getByRole("combobox", { name: "agent" });
const languageInput = screen.getByRole("combobox", { name: "language" });
const apiKeyInput = screen.getByTestId("apikey");
+ const confirmationModeInput = screen.getByTestId("confirmationmode");
expect(modelInput).toHaveValue("model1");
expect(agentInput).toHaveValue("agent1");
expect(languageInput).toHaveValue("English");
expect(apiKeyInput).toHaveValue("sk-...");
+ expect(confirmationModeInput).toHaveAttribute("data-selected", "true");
});
it("should display the existing values if it they are present", () => {
@@ -53,6 +58,7 @@ describe("SettingsForm", () => {
AGENT: "agent2",
LANGUAGE: "es",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
});
const modelInput = screen.getByRole("combobox", { name: "model" });
@@ -72,6 +78,7 @@ describe("SettingsForm", () => {
AGENT: "agent1",
LANGUAGE: "en",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
}}
models={["model1", "model2", "model3"]}
agents={["agent1", "agent2", "agent3"]}
@@ -80,15 +87,18 @@ describe("SettingsForm", () => {
onAgentChange={onAgentChangeMock}
onLanguageChange={onLanguageChangeMock}
onAPIKeyChange={onAPIKeyChangeMock}
+ onConfirmationModeChange={onConfirmationModeChangeMock}
/>,
);
const modelInput = screen.getByRole("combobox", { name: "model" });
const agentInput = screen.getByRole("combobox", { name: "agent" });
const languageInput = screen.getByRole("combobox", { name: "language" });
+ const confirmationModeInput = screen.getByTestId("confirmationmode");
expect(modelInput).toBeDisabled();
expect(agentInput).toBeDisabled();
expect(languageInput).toBeDisabled();
+ expect(confirmationModeInput).toHaveAttribute("data-disabled", "true");
});
describe("onChange handlers", () => {
diff --git a/frontend/src/components/modals/settings/SettingsForm.tsx b/frontend/src/components/modals/settings/SettingsForm.tsx
index 62b47bafeb00..927db98883c2 100644
--- a/frontend/src/components/modals/settings/SettingsForm.tsx
+++ b/frontend/src/components/modals/settings/SettingsForm.tsx
@@ -1,4 +1,4 @@
-import { Input, useDisclosure } from "@nextui-org/react";
+import { Input, Switch, Tooltip, useDisclosure } from "@nextui-org/react";
import React from "react";
import { useTranslation } from "react-i18next";
import { FaEye, FaEyeSlash } from "react-icons/fa";
@@ -17,6 +17,7 @@ interface SettingsFormProps {
onAPIKeyChange: (apiKey: string) => void;
onAgentChange: (agent: string) => void;
onLanguageChange: (language: string) => void;
+ onConfirmationModeChange: (confirmationMode: boolean) => void;
}
function SettingsForm({
@@ -28,6 +29,7 @@ function SettingsForm({
onAPIKeyChange,
onAgentChange,
onLanguageChange,
+ onConfirmationModeChange,
}: SettingsFormProps) {
const { t } = useTranslation();
const { isOpen: isVisible, onOpenChange: onVisibleChange } = useDisclosure();
@@ -86,6 +88,21 @@ function SettingsForm({
tooltip={t(I18nKey.SETTINGS$LANGUAGE_TOOLTIP)}
disabled={disabled}
/>
+
+
+ {t(I18nKey.SETTINGS$CONFIRMATION_MODE)}
+
+
>
);
}
diff --git a/frontend/src/components/modals/settings/SettingsModal.test.tsx b/frontend/src/components/modals/settings/SettingsModal.test.tsx
index 7af0f9e55792..45dbad06f2ed 100644
--- a/frontend/src/components/modals/settings/SettingsModal.test.tsx
+++ b/frontend/src/components/modals/settings/SettingsModal.test.tsx
@@ -27,12 +27,14 @@ vi.mock("#/services/settings", async (importOriginal) => ({
AGENT: "CodeActAgent",
LANGUAGE: "en",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
}),
getDefaultSettings: vi.fn().mockReturnValue({
LLM_MODEL: "gpt-4o",
AGENT: "CodeActAgent",
LANGUAGE: "en",
LLM_API_KEY: "",
+ CONFIRMATION_MODE: false,
}),
settingsAreUpToDate: vi.fn().mockReturnValue(true),
saveSettings: vi.fn(),
@@ -107,6 +109,7 @@ describe("SettingsModal", () => {
AGENT: "CodeActAgent",
LANGUAGE: "en",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
};
it("should save the settings", async () => {
@@ -196,7 +199,7 @@ describe("SettingsModal", () => {
await userEvent.click(saveButton);
});
- expect(toastSpy).toHaveBeenCalledTimes(2);
+ expect(toastSpy).toHaveBeenCalledTimes(3);
});
it("should change the language", async () => {
diff --git a/frontend/src/components/modals/settings/SettingsModal.tsx b/frontend/src/components/modals/settings/SettingsModal.tsx
index 3eecccb2c547..45ce2adcff8f 100644
--- a/frontend/src/components/modals/settings/SettingsModal.tsx
+++ b/frontend/src/components/modals/settings/SettingsModal.tsx
@@ -48,7 +48,8 @@ function SettingsModal({ isOpen, onOpenChange }: SettingsProps) {
const isRunning =
curAgentState === AgentState.RUNNING ||
curAgentState === AgentState.PAUSED ||
- curAgentState === AgentState.AWAITING_USER_INPUT;
+ curAgentState === AgentState.AWAITING_USER_INPUT ||
+ curAgentState === AgentState.AWAITING_USER_CONFIRMATION;
setAgentIsRunning(isRunning);
}, [curAgentState]);
@@ -89,6 +90,10 @@ function SettingsModal({ isOpen, onOpenChange }: SettingsProps) {
setSettings((prev) => ({ ...prev, LLM_API_KEY: key }));
};
+ const handleConfirmationModeChange = (confirmationMode: boolean) => {
+ setSettings((prev) => ({ ...prev, CONFIRMATION_MODE: confirmationMode }));
+ };
+
const handleResetSettings = () => {
setSettings(getDefaultSettings);
};
@@ -170,6 +175,7 @@ function SettingsModal({ isOpen, onOpenChange }: SettingsProps) {
onAgentChange={handleAgentChange}
onLanguageChange={handleLanguageChange}
onAPIKeyChange={handleAPIKeyChange}
+ onConfirmationModeChange={handleConfirmationModeChange}
/>
)}
diff --git a/frontend/src/i18n/translation.json b/frontend/src/i18n/translation.json
index 745fffb97e7b..487b4535ed13 100644
--- a/frontend/src/i18n/translation.json
+++ b/frontend/src/i18n/translation.json
@@ -567,6 +567,21 @@
"de": "Agent ist auf einen Fehler gelaufen.",
"zh-CN": "智能体遇到错误"
},
+ "CHAT_INTERFACE$AGENT_AWAITING_USER_CONFIRMATION_MESSAGE": {
+ "en": "Agent is awaiting user confirmation for the pending action.",
+ "de": "Agent wartet auf die Bestätigung des Benutzers für die ausstehende Aktion.",
+ "zh-CN": "代理正在等待用户确认待处理的操作。"
+ },
+ "CHAT_INTERFACE$AGENT_ACTION_USER_CONFIRMED_MESSAGE": {
+ "en": "Agent action has been confirmed!",
+ "de": "Die Aktion des Agenten wurde bestätigt!",
+ "zh-CN": "代理操作已确认!"
+ },
+ "CHAT_INTERFACE$AGENT_ACTION_USER_REJECTED_MESSAGE": {
+ "en": "Agent action has been rejected!",
+ "de": "Die Aktion des Agenten wurde abgelehnt!",
+ "zh-CN": "代理操作已被拒绝!"
+ },
"CHAT_INTERFACE$INPUT_PLACEHOLDER": {
"en": "Message assistant...",
"zh-CN": "给助理发消息",
@@ -586,6 +601,21 @@
"zh-CN": "继续",
"de": "Fortfahren"
},
+ "CHAT_INTERFACE$USER_ASK_CONFIRMATION": {
+ "en": "Do you want to continue with this action?",
+ "de": "Möchten Sie mit dieser Aktion fortfahren?",
+ "zh-CN": "您要继续此操作吗?"
+ },
+ "CHAT_INTERFACE$USER_CONFIRMED": {
+ "en": "Confirm the requested action",
+ "de": "Bestätigen Sie die angeforderte Aktion",
+ "zh-CN": "确认请求的操作"
+ },
+ "CHAT_INTERFACE$USER_REJECTED": {
+ "en": "Reject the requested action",
+ "de": "Lehnen Sie die angeforderte Aktion ab",
+ "zh-CN": "拒绝请求的操作"
+ },
"CHAT_INTERFACE$INPUT_SEND_MESSAGE_BUTTON_CONTENT": {
"en": "Send",
"zh-CN": "发送",
@@ -681,6 +711,16 @@
"zh-TW": "輸入您的 API 金鑰。",
"de": "Modell API Schlüssel."
},
+ "SETTINGS$CONFIRMATION_MODE": {
+ "en": "Enable Confirmation Mode",
+ "de": "Bestätigungsmodus aktivieren",
+ "zh-CN": "启用确认模式"
+ },
+ "SETTINGS$CONFIRMATION_MODE_TOOLTIP": {
+ "en": "Awaits for user confirmation before executing code.",
+ "de": "Wartet auf die Bestätigung des Benutzers, bevor der Code ausgeführt wird.",
+ "zh-CN": "在执行代码之前等待用户确认。"
+ },
"BROWSER$EMPTY_MESSAGE": {
"en": "No page loaded.",
"zh-CN": "页面未加载",
diff --git a/frontend/src/services/actions.ts b/frontend/src/services/actions.ts
index 64c424572956..b1d91f5485fc 100644
--- a/frontend/src/services/actions.ts
+++ b/frontend/src/services/actions.ts
@@ -46,13 +46,23 @@ const messageActions = {
if (message.args.thought) {
store.dispatch(addAssistantMessage(message.args.thought));
}
- store.dispatch(appendInput(message.args.command));
+ if (
+ !message.args.is_confirmed ||
+ message.args.is_confirmed !== "rejected"
+ ) {
+ store.dispatch(appendInput(message.args.command));
+ }
},
[ActionType.RUN_IPYTHON]: (message: ActionMessage) => {
if (message.args.thought) {
store.dispatch(addAssistantMessage(message.args.thought));
}
- store.dispatch(appendJupyterInput(message.args.code));
+ if (
+ !message.args.is_confirmed ||
+ message.args.is_confirmed !== "rejected"
+ ) {
+ store.dispatch(appendJupyterInput(message.args.code));
+ }
},
[ActionType.ADD_TASK]: () => {
getRootTask().then((fetchedRootTask) =>
@@ -67,6 +77,32 @@ const messageActions = {
};
export function handleActionMessage(message: ActionMessage) {
+ if (
+ (message.action === ActionType.RUN ||
+ message.action === ActionType.RUN_IPYTHON) &&
+ message.args.is_confirmed === "awaiting_confirmation"
+ ) {
+ if (message.args.thought) {
+ store.dispatch(addAssistantMessage(message.args.thought));
+ }
+ if (message.args.command) {
+ store.dispatch(
+ addAssistantMessage(
+ `Running this command now: \n\`\`\`\`bash\n${message.args.command}\n\`\`\`\`\n`,
+ ),
+ );
+ } else if (message.args.code) {
+ store.dispatch(
+ addAssistantMessage(
+ `Running this code now: \n\`\`\`\`python\n${message.args.code}\n\`\`\`\`\n`,
+ ),
+ );
+ } else {
+ store.dispatch(addAssistantMessage(message.message));
+ }
+ return;
+ }
+
if (message.action in messageActions) {
const actionFn =
messageActions[message.action as keyof typeof messageActions];
diff --git a/frontend/src/services/session.test.ts b/frontend/src/services/session.test.ts
index bf23b06bf5a0..194ef0a9b85b 100644
--- a/frontend/src/services/session.test.ts
+++ b/frontend/src/services/session.test.ts
@@ -20,6 +20,7 @@ describe("startNewSession", () => {
AGENT: "agent_value",
LANGUAGE: "language_value",
LLM_API_KEY: "sk-...",
+ CONFIRMATION_MODE: true,
};
const event = {
diff --git a/frontend/src/services/settings.test.ts b/frontend/src/services/settings.test.ts
index eebda7aadcae..7f62e690b070 100644
--- a/frontend/src/services/settings.test.ts
+++ b/frontend/src/services/settings.test.ts
@@ -20,7 +20,8 @@ describe("getSettings", () => {
.mockReturnValueOnce("llm_value")
.mockReturnValueOnce("agent_value")
.mockReturnValueOnce("language_value")
- .mockReturnValueOnce("api_key");
+ .mockReturnValueOnce("api_key")
+ .mockReturnValueOnce("true");
const settings = getSettings();
@@ -29,6 +30,7 @@ describe("getSettings", () => {
AGENT: "agent_value",
LANGUAGE: "language_value",
LLM_API_KEY: "api_key",
+ CONFIRMATION_MODE: true,
});
});
@@ -46,6 +48,7 @@ describe("getSettings", () => {
AGENT: DEFAULT_SETTINGS.AGENT,
LANGUAGE: DEFAULT_SETTINGS.LANGUAGE,
LLM_API_KEY: "",
+ CONFIRMATION_MODE: DEFAULT_SETTINGS.CONFIRMATION_MODE,
});
});
});
@@ -57,6 +60,7 @@ describe("saveSettings", () => {
AGENT: "agent_value",
LANGUAGE: "language_value",
LLM_API_KEY: "some_key",
+ CONFIRMATION_MODE: true,
};
saveSettings(settings);
diff --git a/frontend/src/services/settings.ts b/frontend/src/services/settings.ts
index 310a420d198a..b3fc85a862af 100644
--- a/frontend/src/services/settings.ts
+++ b/frontend/src/services/settings.ts
@@ -5,13 +5,17 @@ export type Settings = {
AGENT: string;
LANGUAGE: string;
LLM_API_KEY: string;
+ CONFIRMATION_MODE: boolean;
};
+type SettingsInput = Settings[keyof Settings];
+
export const DEFAULT_SETTINGS: Settings = {
LLM_MODEL: "gpt-4o",
AGENT: "CodeActAgent",
LANGUAGE: "en",
LLM_API_KEY: "",
+ CONFIRMATION_MODE: false,
};
const validKeys = Object.keys(DEFAULT_SETTINGS) as (keyof Settings)[];
@@ -51,12 +55,14 @@ export const getSettings = (): Settings => {
const agent = localStorage.getItem("AGENT");
const language = localStorage.getItem("LANGUAGE");
const apiKey = localStorage.getItem("LLM_API_KEY");
+ const confirmationMode = localStorage.getItem("CONFIRMATION_MODE") === "true";
return {
LLM_MODEL: model || DEFAULT_SETTINGS.LLM_MODEL,
AGENT: agent || DEFAULT_SETTINGS.AGENT,
LANGUAGE: language || DEFAULT_SETTINGS.LANGUAGE,
LLM_API_KEY: apiKey || DEFAULT_SETTINGS.LLM_API_KEY,
+ CONFIRMATION_MODE: confirmationMode || DEFAULT_SETTINGS.CONFIRMATION_MODE,
};
};
@@ -69,7 +75,8 @@ export const saveSettings = (settings: Partial) => {
const isValid = validKeys.includes(key as keyof Settings);
const value = settings[key as keyof Settings];
- if (isValid && value) localStorage.setItem(key, value);
+ if (isValid && (value || typeof value === "boolean"))
+ localStorage.setItem(key, value.toString());
});
localStorage.setItem("SETTINGS_VERSION", LATEST_SETTINGS_VERSION.toString());
};
@@ -91,11 +98,14 @@ export const getSettingsDifference = (settings: Partial) => {
const updatedSettings: Partial = {};
Object.keys(settings).forEach((key) => {
+ const typedKey = key as keyof Settings;
if (
- validKeys.includes(key as keyof Settings) &&
- settings[key as keyof Settings] !== currentSettings[key as keyof Settings]
+ validKeys.includes(typedKey) &&
+ settings[typedKey] !== currentSettings[typedKey]
) {
- updatedSettings[key as keyof Settings] = settings[key as keyof Settings];
+ (updatedSettings[typedKey] as SettingsInput) = settings[
+ typedKey
+ ] as SettingsInput;
}
});
diff --git a/frontend/src/types/AgentState.tsx b/frontend/src/types/AgentState.tsx
index 61db70d53aac..d2751627df09 100644
--- a/frontend/src/types/AgentState.tsx
+++ b/frontend/src/types/AgentState.tsx
@@ -8,6 +8,9 @@ enum AgentState {
FINISHED = "finished",
REJECTED = "rejected",
ERROR = "error",
+ AWAITING_USER_CONFIRMATION = "awaiting_user_confirmation",
+ USER_CONFIRMED = "user_confirmed",
+ USER_REJECTED = "user_rejected",
}
export default AgentState;
diff --git a/opendevin/controller/agent_controller.py b/opendevin/controller/agent_controller.py
index 9b66bf6b705e..73ce2fac1730 100644
--- a/opendevin/controller/agent_controller.py
+++ b/opendevin/controller/agent_controller.py
@@ -16,11 +16,14 @@
from opendevin.events import EventSource, EventStream, EventStreamSubscriber
from opendevin.events.action import (
Action,
+ ActionConfirmationStatus,
AddTaskAction,
AgentDelegateAction,
AgentFinishAction,
AgentRejectAction,
ChangeAgentStateAction,
+ CmdRunAction,
+ IPythonRunCellAction,
MessageAction,
ModifyTaskAction,
NullAction,
@@ -49,6 +52,7 @@ class AgentController:
max_iterations: int
event_stream: EventStream
state: State
+ confirmation_mode: bool
agent_task: Optional[asyncio.Task] = None
parent: 'AgentController | None' = None
delegate: 'AgentController | None' = None
@@ -60,6 +64,7 @@ def __init__(
event_stream: EventStream,
sid: str = 'default',
max_iterations: int | None = MAX_ITERATIONS,
+ confirmation_mode: bool = False,
max_budget_per_task: float | None = MAX_BUDGET_PER_TASK,
initial_state: State | None = None,
is_delegate: bool = False,
@@ -92,6 +97,7 @@ def __init__(
self.set_initial_state(
state=initial_state,
max_iterations=max_iterations,
+ confirmation_mode=confirmation_mode,
)
self.max_budget_per_task = max_budget_per_task
@@ -170,8 +176,19 @@ async def on_event(self, event: Event):
self.state.outputs = event.outputs # type: ignore[attr-defined]
await self.set_agent_state_to(AgentState.REJECTED)
elif isinstance(event, Observation):
+ if (
+ self._pending_action
+ and hasattr(self._pending_action, 'is_confirmed')
+ and self._pending_action.is_confirmed
+ == ActionConfirmationStatus.AWAITING_CONFIRMATION
+ ):
+ return
if self._pending_action and self._pending_action.id == event.cause:
self._pending_action = None
+ if self.state.agent_state == AgentState.USER_CONFIRMED:
+ await self.set_agent_state_to(AgentState.RUNNING)
+ if self.state.agent_state == AgentState.USER_REJECTED:
+ await self.set_agent_state_to(AgentState.AWAITING_USER_INPUT)
logger.info(event, extra={'msg_type': 'OBSERVATION'})
elif isinstance(event, CmdOutputObservation):
logger.info(event, extra={'msg_type': 'OBSERVATION'})
@@ -205,6 +222,18 @@ async def set_agent_state_to(self, new_state: AgentState):
if new_state == AgentState.STOPPED or new_state == AgentState.ERROR:
self.reset_task()
+ if self._pending_action is not None and (
+ new_state == AgentState.USER_CONFIRMED
+ or new_state == AgentState.USER_REJECTED
+ ):
+ if hasattr(self._pending_action, 'thought'):
+ self._pending_action.thought = '' # type: ignore[union-attr]
+ if new_state == AgentState.USER_CONFIRMED:
+ self._pending_action.is_confirmed = ActionConfirmationStatus.CONFIRMED # type: ignore[attr-defined]
+ else:
+ self._pending_action.is_confirmed = ActionConfirmationStatus.REJECTED # type: ignore[attr-defined]
+ self.event_stream.add_event(self._pending_action, EventSource.AGENT)
+
self.event_stream.add_event(
AgentStateChangedObservation('', self.state.agent_state), EventSource.AGENT
)
@@ -346,9 +375,19 @@ async def _step(self):
return
if action.runnable:
+ if self.state.confirmation_mode and (
+ type(action) is CmdRunAction or type(action) is IPythonRunCellAction
+ ):
+ action.is_confirmed = ActionConfirmationStatus.AWAITING_CONFIRMATION
self._pending_action = action
if not isinstance(action, NullAction):
+ if (
+ hasattr(action, 'is_confirmed')
+ and action.is_confirmed
+ == ActionConfirmationStatus.AWAITING_CONFIRMATION
+ ):
+ await self.set_agent_state_to(AgentState.AWAITING_USER_CONFIRMATION)
self.event_stream.add_event(action, EventSource.AGENT)
await self.update_state_after_step()
@@ -362,12 +401,19 @@ def get_state(self):
return self.state
def set_initial_state(
- self, state: State | None, max_iterations: int = MAX_ITERATIONS
+ self,
+ state: State | None,
+ max_iterations: int = MAX_ITERATIONS,
+ confirmation_mode: bool = False,
):
# state from the previous session, state from a parent agent, or a new state
# note that this is called twice when restoring a previous session, first with state=None
if state is None:
- self.state = State(inputs={}, max_iterations=max_iterations)
+ self.state = State(
+ inputs={},
+ max_iterations=max_iterations,
+ confirmation_mode=confirmation_mode,
+ )
else:
self.state = state
diff --git a/opendevin/controller/state/state.py b/opendevin/controller/state/state.py
index 06c35811e1ba..30269ca5863a 100644
--- a/opendevin/controller/state/state.py
+++ b/opendevin/controller/state/state.py
@@ -39,6 +39,7 @@ class State:
root_task: RootTask = field(default_factory=RootTask)
iteration: int = 0
max_iterations: int = 100
+ confirmation_mode: bool = False
history: ShortTermHistory = field(default_factory=ShortTermHistory)
inputs: dict = field(default_factory=dict)
outputs: dict = field(default_factory=dict)
diff --git a/opendevin/core/config.py b/opendevin/core/config.py
index 1163074d7fc1..1f7a2e4d4866 100644
--- a/opendevin/core/config.py
+++ b/opendevin/core/config.py
@@ -223,6 +223,7 @@ class AppConfig(metaclass=Singleton):
workspace_mount_rewrite: str | None = None
cache_dir: str = '/tmp/cache'
run_as_devin: bool = True
+ confirmation_mode: bool = False
max_iterations: int = 100
max_budget_per_task: float | None = None
e2b_api_key: str = ''
diff --git a/opendevin/core/schema/agent.py b/opendevin/core/schema/agent.py
index 64742b8f2ac6..4ea09d7afc2a 100644
--- a/opendevin/core/schema/agent.py
+++ b/opendevin/core/schema/agent.py
@@ -37,3 +37,15 @@ class AgentState(str, Enum):
ERROR = 'error'
"""An error occurred during the task.
"""
+
+ AWAITING_USER_CONFIRMATION = 'awaiting_user_confirmation'
+ """The agent is awaiting user confirmation.
+ """
+
+ USER_CONFIRMED = 'user_confirmed'
+ """The user confirmed the agent's action.
+ """
+
+ USER_REJECTED = 'user_rejected'
+ """The user rejected the agent's action.
+ """
diff --git a/opendevin/core/schema/config.py b/opendevin/core/schema/config.py
index b6bb71bdccba..4b8c05c4aca3 100644
--- a/opendevin/core/schema/config.py
+++ b/opendevin/core/schema/config.py
@@ -20,6 +20,7 @@ class ConfigType(str, Enum):
WORKSPACE_MOUNT_PATH_IN_SANDBOX = 'WORKSPACE_MOUNT_PATH_IN_SANDBOX'
CACHE_DIR = 'CACHE_DIR'
LLM_MODEL = 'LLM_MODEL'
+ CONFIRMATION_MODE = 'CONFIRMATION_MODE'
SANDBOX_CONTAINER_IMAGE = 'SANDBOX_CONTAINER_IMAGE'
RUN_AS_DEVIN = 'RUN_AS_DEVIN'
LLM_EMBEDDING_MODEL = 'LLM_EMBEDDING_MODEL'
diff --git a/opendevin/core/schema/observation.py b/opendevin/core/schema/observation.py
index 0a8afbc9a9db..3a2ec0e01979 100644
--- a/opendevin/core/schema/observation.py
+++ b/opendevin/core/schema/observation.py
@@ -44,5 +44,7 @@ class ObservationTypeSchema(BaseModel):
AGENT_STATE_CHANGED: str = Field(default='agent_state_changed')
+ USER_REJECTED: str = Field(default='user_rejected')
+
ObservationType = ObservationTypeSchema()
diff --git a/opendevin/events/action/__init__.py b/opendevin/events/action/__init__.py
index 16bf6ccf0f31..cbb4a134525c 100644
--- a/opendevin/events/action/__init__.py
+++ b/opendevin/events/action/__init__.py
@@ -1,4 +1,4 @@
-from .action import Action
+from .action import Action, ActionConfirmationStatus
from .agent import (
AgentDelegateAction,
AgentFinishAction,
@@ -32,4 +32,5 @@
'ChangeAgentStateAction',
'IPythonRunCellAction',
'MessageAction',
+ 'ActionConfirmationStatus',
]
diff --git a/opendevin/events/action/action.py b/opendevin/events/action/action.py
index 386e64146d65..f6d7d65f4c69 100644
--- a/opendevin/events/action/action.py
+++ b/opendevin/events/action/action.py
@@ -1,9 +1,16 @@
from dataclasses import dataclass
+from enum import Enum
from typing import ClassVar
from opendevin.events.event import Event
+class ActionConfirmationStatus(str, Enum):
+ CONFIRMED = 'confirmed'
+ REJECTED = 'rejected'
+ AWAITING_CONFIRMATION = 'awaiting_confirmation'
+
+
@dataclass
class Action(Event):
runnable: ClassVar[bool] = False
diff --git a/opendevin/events/action/commands.py b/opendevin/events/action/commands.py
index 451da57310df..0edccf82982e 100644
--- a/opendevin/events/action/commands.py
+++ b/opendevin/events/action/commands.py
@@ -3,7 +3,7 @@
from opendevin.core.schema import ActionType
-from .action import Action
+from .action import Action, ActionConfirmationStatus
@dataclass
@@ -12,6 +12,7 @@ class CmdRunAction(Action):
thought: str = ''
action: str = ActionType.RUN
runnable: ClassVar[bool] = True
+ is_confirmed: ActionConfirmationStatus = ActionConfirmationStatus.CONFIRMED
@property
def message(self) -> str:
@@ -31,6 +32,7 @@ class IPythonRunCellAction(Action):
thought: str = ''
action: str = ActionType.RUN_IPYTHON
runnable: ClassVar[bool] = True
+ is_confirmed: ActionConfirmationStatus = ActionConfirmationStatus.CONFIRMED
kernel_init_code: str = '' # code to run in the kernel (if the kernel is restarted)
def __str__(self) -> str:
diff --git a/opendevin/events/observation/__init__.py b/opendevin/events/observation/__init__.py
index 34a93c60fac3..67fa1ccacd60 100644
--- a/opendevin/events/observation/__init__.py
+++ b/opendevin/events/observation/__init__.py
@@ -7,6 +7,7 @@
from .files import FileReadObservation, FileWriteObservation
from .observation import Observation
from .recall import AgentRecallObservation
+from .reject import RejectObservation
from .success import SuccessObservation
__all__ = [
@@ -22,4 +23,5 @@
'AgentStateChangedObservation',
'AgentDelegateObservation',
'SuccessObservation',
+ 'RejectObservation',
]
diff --git a/opendevin/events/observation/reject.py b/opendevin/events/observation/reject.py
new file mode 100644
index 000000000000..81b32fefe57d
--- /dev/null
+++ b/opendevin/events/observation/reject.py
@@ -0,0 +1,18 @@
+from dataclasses import dataclass
+
+from opendevin.core.schema import ObservationType
+
+from .observation import Observation
+
+
+@dataclass
+class RejectObservation(Observation):
+ """
+ This data class represents the result of a successful action.
+ """
+
+ observation: str = ObservationType.USER_REJECTED
+
+ @property
+ def message(self) -> str:
+ return self.content
diff --git a/opendevin/events/serialization/observation.py b/opendevin/events/serialization/observation.py
index 5bec2ff0be62..97d167144c8a 100644
--- a/opendevin/events/serialization/observation.py
+++ b/opendevin/events/serialization/observation.py
@@ -10,6 +10,7 @@
from opendevin.events.observation.files import FileReadObservation, FileWriteObservation
from opendevin.events.observation.observation import Observation
from opendevin.events.observation.recall import AgentRecallObservation
+from opendevin.events.observation.reject import RejectObservation
from opendevin.events.observation.success import SuccessObservation
observations = (
@@ -24,6 +25,7 @@
SuccessObservation,
ErrorObservation,
AgentStateChangedObservation,
+ RejectObservation,
)
OBSERVATION_TYPE_TO_CLASS = {
diff --git a/opendevin/runtime/runtime.py b/opendevin/runtime/runtime.py
index fecaf431ea61..9b3410b49921 100644
--- a/opendevin/runtime/runtime.py
+++ b/opendevin/runtime/runtime.py
@@ -7,6 +7,7 @@
from opendevin.events import EventStream, EventStreamSubscriber
from opendevin.events.action import (
Action,
+ ActionConfirmationStatus,
AgentRecallAction,
BrowseInteractiveAction,
BrowseURLAction,
@@ -20,6 +21,7 @@
ErrorObservation,
NullObservation,
Observation,
+ RejectObservation,
)
from opendevin.events.serialization.action import ACTION_TYPE_TO_CLASS
from opendevin.runtime import (
@@ -115,6 +117,11 @@ async def run_action(self, action: Action) -> Observation:
"""
if not action.runnable:
return NullObservation('')
+ if (
+ hasattr(action, 'is_confirmed')
+ and action.is_confirmed == ActionConfirmationStatus.AWAITING_CONFIRMATION
+ ):
+ return NullObservation('')
action_type = action.action # type: ignore[attr-defined]
if action_type not in ACTION_TYPE_TO_CLASS:
return ErrorObservation(f'Action {action_type} does not exist.')
@@ -122,6 +129,13 @@ async def run_action(self, action: Action) -> Observation:
return ErrorObservation(
f'Action {action_type} is not supported in the current runtime.'
)
+ if (
+ hasattr(action, 'is_confirmed')
+ and action.is_confirmed == ActionConfirmationStatus.REJECTED
+ ):
+ return RejectObservation(
+ 'Action has been rejected by the user! Waiting for further user input.'
+ )
observation = await getattr(self, action_type)(action)
observation._parent = action.id # type: ignore[attr-defined]
return observation
diff --git a/opendevin/server/listen.py b/opendevin/server/listen.py
index ca94c87bea78..b43eb785f041 100644
--- a/opendevin/server/listen.py
+++ b/opendevin/server/listen.py
@@ -217,7 +217,7 @@ async def websocket_endpoint(websocket: WebSocket):
```
- Run a command:
```json
- {"action": "run", "args": {"command": "ls -l", "thought": ""}}
+ {"action": "run", "args": {"command": "ls -l", "thought": "", "is_confirmed": "confirmed"}}
```
- Run an IPython command:
```json
diff --git a/opendevin/server/session/agent.py b/opendevin/server/session/agent.py
index e75a93cca304..a5e614f14484 100644
--- a/opendevin/server/session/agent.py
+++ b/opendevin/server/session/agent.py
@@ -91,6 +91,9 @@ async def _create_controller(self, start_event: dict):
model = args.get(ConfigType.LLM_MODEL, llm_config.model)
api_key = args.get(ConfigType.LLM_API_KEY, llm_config.api_key)
api_base = llm_config.base_url
+ confirmation_mode = args.get(
+ ConfigType.CONFIRMATION_MODE, config.confirmation_mode
+ )
max_iterations = args.get(ConfigType.MAX_ITERATIONS, config.max_iterations)
logger.info(f'Creating agent {agent_cls} using LLM {model}')
@@ -110,6 +113,7 @@ async def _create_controller(self, start_event: dict):
event_stream=self.event_stream,
agent=agent,
max_iterations=int(max_iterations),
+ confirmation_mode=confirmation_mode,
)
try:
agent_state = State.restore_from_session(self.sid)
diff --git a/tests/integration/mock/DelegatorAgent/test_edits/prompt_002.log b/tests/integration/mock/DelegatorAgent/test_edits/prompt_002.log
index 828f19341a6e..af5206d72018 100644
--- a/tests/integration/mock/DelegatorAgent/test_edits/prompt_002.log
+++ b/tests/integration/mock/DelegatorAgent/test_edits/prompt_002.log
@@ -41,7 +41,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": ""}}, {"source": "agent", "observation": "run", "content": "bad.txt", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}]
+[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "bad.txt", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/DelegatorAgent/test_edits/prompt_003.log b/tests/integration/mock/DelegatorAgent/test_edits/prompt_003.log
index 3f0b617a875f..5019fbdf7fef 100644
--- a/tests/integration/mock/DelegatorAgent/test_edits/prompt_003.log
+++ b/tests/integration/mock/DelegatorAgent/test_edits/prompt_003.log
@@ -41,7 +41,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": ""}}, {"source": "agent", "observation": "run", "content": "bad.txt", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}, {"source": "agent", "action": "read", "args": {"path": "bad.txt", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "This is a stupid typoo.\nReally?\nNo mor typos!\nEnjoy!\n", "extras": {"path": "bad.txt"}}]
+[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "bad.txt", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}, {"source": "agent", "action": "read", "args": {"path": "bad.txt", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "This is a stupid typoo.\nReally?\nNo mor typos!\nEnjoy!\n", "extras": {"path": "bad.txt"}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_002.log b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_002.log
index a646e046dce8..e7d8a3babee5 100644
--- a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_002.log
+++ b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_002.log
@@ -41,7 +41,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": ""}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}]
+[{"source": "agent", "action": "run", "args": {"command": "ls", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "ls", "exit_code": 0}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_005.log b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_005.log
index afab1bb7d405..86546d623227 100644
--- a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_005.log
+++ b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_005.log
@@ -41,7 +41,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "thought": ""}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}]
+[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_006.log b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_006.log
index 49ccb65d13d2..8567550de535 100644
--- a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_006.log
+++ b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_006.log
@@ -41,7 +41,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "thought": ""}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}, {"source": "agent", "action": "run", "args": {"command": "./hello.sh", "thought": ""}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "./hello.sh", "exit_code": 0}}]
+[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}, {"source": "agent", "action": "run", "args": {"command": "./hello.sh", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "./hello.sh", "exit_code": 0}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_009.log b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_009.log
index e44c5d635456..20b2296e332f 100644
--- a/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_009.log
+++ b/tests/integration/mock/DelegatorAgent/test_write_simple_script/prompt_009.log
@@ -39,7 +39,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "read", "args": {"path": "hello.sh", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'\n", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "bash hello.sh", "thought": ""}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "bash hello.sh", "exit_code": 0}}]
+[{"source": "agent", "action": "read", "args": {"path": "hello.sh", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "#!/bin/bash\n\n# Print hello\necho 'hello'\n", "extras": {"path": "hello.sh"}}, {"source": "agent", "action": "run", "args": {"command": "bash hello.sh", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "bash hello.sh", "exit_code": 0}}]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_003.log b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_003.log
index d53f4a40ec80..14893e42170b 100644
--- a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_003.log
+++ b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_003.log
@@ -28,7 +28,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": ""}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}]
+[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}]
If the last item in the history is an error, you should try to fix it.
diff --git a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_004.log b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_004.log
index 614284723122..29f1dc839254 100644
--- a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_004.log
+++ b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_004.log
@@ -28,7 +28,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": ""}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}]
+[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}]
If the last item in the history is an error, you should try to fix it.
diff --git a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_005.log b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_005.log
index e66ff7490809..07713e2d3ba6 100644
--- a/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_005.log
+++ b/tests/integration/mock/ManagerAgent/test_simple_task_rejection/prompt_005.log
@@ -28,7 +28,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": ""}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}]
+[{"source": "agent", "action": "run", "args": {"command": "git status", "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "fatal: not a git repository (or any parent up to mount point /)\r\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", "extras": {"command_id": -1, "command": "git status", "exit_code": 128}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}, {"source": "agent", "observation": "error", "content": "action={'action': 'reject', 'args': {'reason': 'Not a valid git repository.'}} has the wrong arguments", "extras": {}}]
If the last item in the history is an error, you should try to fix it.
diff --git a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_004.log b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_004.log
index 5bc5b3e102cb..d7463dbaf3e5 100644
--- a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_004.log
+++ b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_004.log
@@ -38,7 +38,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "background": false, "thought": ""}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}]]
+[[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "background": false, "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}]]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_005.log b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_005.log
index b0bf89e29b39..b12e03344f5d 100644
--- a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_005.log
+++ b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_005.log
@@ -38,7 +38,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "background": false, "thought": ""}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}], [{"source": "agent", "action": "run", "args": {"command": "./hello.sh", "background": false, "thought": ""}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "./hello.sh", "exit_code": 0}}]]
+[[{"source": "agent", "action": "write", "args": {"path": "hello.sh", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "write", "content": "", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "chmod +x hello.sh", "background": false, "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "", "extras": {"command_id": -1, "command": "chmod +x hello.sh", "exit_code": 0}}], [{"source": "agent", "action": "run", "args": {"command": "./hello.sh", "background": false, "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "./hello.sh", "exit_code": 0}}]]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_006.log b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_006.log
index 5877182c2266..5c732af1da22 100644
--- a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_006.log
+++ b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_006.log
@@ -60,7 +60,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[[{"source": "user", "action": "message", "args": {"content": "Write a shell script 'hello.sh' that prints 'hello'. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CoderAgent", "inputs": {"task": "Write a shell script 'hello.sh' that prints 'hello'.", "summary": ""}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {}}}]]
+[[{"source": "user", "action": "message", "args": {"content": "Write a shell script 'hello.sh' that prints 'hello'. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CoderAgent", "inputs": {"task": "Write a shell script 'hello.sh' that prints 'hello'.", "summary": ""}, "thought": "", "is_confirmed": "confirmed"}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {}}}]]
## Available Actions
* `delegate` - send a task to another agent from the list provided. Arguments:
diff --git a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_009.log b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_009.log
index 62475ca12ab0..c04a8cd0e889 100644
--- a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_009.log
+++ b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_009.log
@@ -40,7 +40,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[[{"source": "agent", "action": "read", "args": {"path": "hello.sh", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'\n", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "bash hello.sh", "background": false, "thought": ""}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "bash hello.sh", "exit_code": 0}}]]
+[[{"source": "agent", "action": "read", "args": {"path": "hello.sh", "start": 0, "end": -1, "thought": ""}}, {"source": "agent", "observation": "read", "content": "#!/bin/bash\n\n# Print 'hello'\necho 'hello'\n", "extras": {"path": "hello.sh"}}], [{"source": "agent", "action": "run", "args": {"command": "bash hello.sh", "background": false, "thought": "", "is_confirmed": "confirmed"}}, {"source": "agent", "observation": "run", "content": "hello", "extras": {"command_id": -1, "command": "bash hello.sh", "exit_code": 0}}]]
## Format
Your response MUST be in JSON format. It must be an object, and it must contain two fields:
diff --git a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_010.log b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_010.log
index daac6cb7ab2d..a8d42cbf75ea 100644
--- a/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_010.log
+++ b/tests/integration/mock/ManagerAgent/test_write_simple_script/prompt_010.log
@@ -60,7 +60,7 @@ as well as observations you've made. This only includes the MOST RECENT
actions and observations--more may have happened before that.
They are time-ordered, with your most recent action at the bottom.
-[[{"source": "user", "action": "message", "args": {"content": "Write a shell script 'hello.sh' that prints 'hello'. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CoderAgent", "inputs": {"task": "Write a shell script 'hello.sh' that prints 'hello'.", "summary": ""}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {}}}], [{"source": "agent", "action": "delegate", "args": {"agent": "VerifierAgent", "inputs": {"task": "Verify that the shell script 'hello.sh' prints 'hello'."}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {"completed": true}}}]]
+[[{"source": "user", "action": "message", "args": {"content": "Write a shell script 'hello.sh' that prints 'hello'. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CoderAgent", "inputs": {"task": "Write a shell script 'hello.sh' that prints 'hello'.", "summary": ""}, "thought": "", "is_confirmed": "confirmed"}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {}}}], [{"source": "agent", "action": "delegate", "args": {"agent": "VerifierAgent", "inputs": {"task": "Verify that the shell script 'hello.sh' prints 'hello'."}, "thought": "", "is_confirmed": "confirmed"}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {"completed": true}}}]]
## Available Actions
* `delegate` - send a task to another agent from the list provided. Arguments:
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_001.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_001.log
index 235daf8e7573..d992f863f829 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_001.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_001.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_002.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_002.log
index ebe37d8806dd..1ae7016724dc 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_002.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_002.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_003.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_003.log
index 694a381b2cd8..62ee248ac452 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_003.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_003.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_004.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_004.log
index c50bb57bff38..03d6ac76fd8f 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_004.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_004.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_005.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_005.log
index 294026f0ead5..f66f36ecfee7 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_005.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_005.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_006.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_006.log
index 9c3ddc704e55..5c64143d9235 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_006.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_006.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_007.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_007.log
index c511644ff1c5..17efe8a9a2c7 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_007.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_007.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
@@ -401,7 +405,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "chmod +x hello.sh",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_008.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_008.log
index 8caa1d6c53f1..84723709d2e6 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_008.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/prompt_008.log
@@ -135,7 +135,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -182,7 +183,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -330,7 +332,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "pwd",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -348,7 +351,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
},
{
@@ -401,7 +405,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "chmod +x hello.sh",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
@@ -419,7 +424,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "./hello.sh",
- "thought": "I need to run the 'hello.sh' script to verify that it prints 'hello'."
+ "thought": "I need to run the 'hello.sh' script to verify that it prints 'hello'.",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/MonologueAgent/test_write_simple_script/response_002.log b/tests/integration/mock/MonologueAgent/test_write_simple_script/response_002.log
index f37c6b4aa7cb..a610d3e35900 100644
--- a/tests/integration/mock/MonologueAgent/test_write_simple_script/response_002.log
+++ b/tests/integration/mock/MonologueAgent/test_write_simple_script/response_002.log
@@ -3,7 +3,8 @@
"action": "run",
"args": {
"command": "ls",
- "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better."
+ "thought": "I need to see the contents of the current directory to ensure there are no conflicts and to understand the environment better.",
+ "is_confirmed": "confirmed"
}
}
```
diff --git a/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_010.log b/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_010.log
index e2666fca9d41..c3211d8b7131 100644
--- a/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_010.log
+++ b/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_010.log
@@ -196,7 +196,8 @@ ten actions--more happened before that.
"action": "run",
"args": {
"command": "bash hello.sh",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_011.log b/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_011.log
index 92fa4bd751d5..f576303ee15f 100644
--- a/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_011.log
+++ b/tests/integration/mock/PlannerAgent/test_write_simple_script/prompt_011.log
@@ -195,7 +195,8 @@ ten actions--more happened before that.
"action": "run",
"args": {
"command": "bash hello.sh",
- "thought": ""
+ "thought": "",
+ "is_confirmed": "confirmed"
}
},
{
diff --git a/tests/unit/test_action_serialization.py b/tests/unit/test_action_serialization.py
index ceb0db5ccfc1..969a3212d0a5 100644
--- a/tests/unit/test_action_serialization.py
+++ b/tests/unit/test_action_serialization.py
@@ -13,6 +13,7 @@
MessageAction,
ModifyTaskAction,
)
+from opendevin.events.action.action import ActionConfirmationStatus
from opendevin.events.serialization import (
event_from_dict,
event_to_dict,
@@ -90,7 +91,11 @@ def test_agent_reject_action_serialization_deserialization():
def test_cmd_run_action_serialization_deserialization():
original_action_dict = {
'action': 'run',
- 'args': {'command': 'echo "Hello world"', 'thought': ''},
+ 'args': {
+ 'command': 'echo "Hello world"',
+ 'thought': '',
+ 'is_confirmed': ActionConfirmationStatus.CONFIRMED,
+ },
}
serialization_deserialization(original_action_dict, CmdRunAction)