mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 13:47:19 +08:00
Frontend support for delegation and rejection (#2608)
1. Add support for rejection action on frontend 2. Show users the reason for rejection 3. Get rid of weird empty box after delegation 4. On web GUI, show customer when a delegation starts and ends
This commit is contained in:
@@ -15,6 +15,7 @@ const IgnoreTaskStateMap: { [k: string]: AgentState[] } = {
|
||||
AgentState.PAUSED,
|
||||
AgentState.STOPPED,
|
||||
AgentState.FINISHED,
|
||||
AgentState.REJECTED,
|
||||
AgentState.AWAITING_USER_INPUT,
|
||||
],
|
||||
[AgentState.RUNNING]: [
|
||||
@@ -22,6 +23,7 @@ const IgnoreTaskStateMap: { [k: string]: AgentState[] } = {
|
||||
AgentState.RUNNING,
|
||||
AgentState.STOPPED,
|
||||
AgentState.FINISHED,
|
||||
AgentState.REJECTED,
|
||||
AgentState.AWAITING_USER_INPUT,
|
||||
],
|
||||
[AgentState.STOPPED]: [AgentState.INIT, AgentState.STOPPED],
|
||||
|
||||
@@ -49,6 +49,10 @@ function AgentStatusBar() {
|
||||
message: t(I18nKey.CHAT_INTERFACE$AGENT_FINISHED_MESSAGE),
|
||||
indicator: IndicatorColor.GREEN,
|
||||
},
|
||||
[AgentState.REJECTED]: {
|
||||
message: t(I18nKey.CHAT_INTERFACE$AGENT_REJECTED_MESSAGE),
|
||||
indicator: IndicatorColor.YELLOW,
|
||||
},
|
||||
[AgentState.ERROR]: {
|
||||
message: t(I18nKey.CHAT_INTERFACE$AGENT_ERROR_MESSAGE),
|
||||
indicator: IndicatorColor.RED,
|
||||
|
||||
@@ -397,6 +397,11 @@
|
||||
"de": "Agent hat die Aufgabe erledigt.",
|
||||
"zh-CN": "智能体已完成任务"
|
||||
},
|
||||
"CHAT_INTERFACE$AGENT_REJECTED_MESSAGE": {
|
||||
"en": "Agent has rejected the task.",
|
||||
"de": "Agent hat die Aufgabe abgelehnt.",
|
||||
"zh-CN": "智能体拒绝任务"
|
||||
},
|
||||
"CHAT_INTERFACE$AGENT_ERROR_MESSAGE": {
|
||||
"en": "Agent encountered an error.",
|
||||
"de": "Agent ist auf einen Fehler gelaufen.",
|
||||
|
||||
@@ -36,6 +36,12 @@ const messageActions = {
|
||||
[ActionType.FINISH]: (message: ActionMessage) => {
|
||||
store.dispatch(addAssistantMessage(message.message));
|
||||
},
|
||||
[ActionType.REJECT]: (message: ActionMessage) => {
|
||||
store.dispatch(addAssistantMessage(message.message));
|
||||
},
|
||||
[ActionType.DELEGATE]: (message: ActionMessage) => {
|
||||
store.dispatch(addAssistantMessage(message.message));
|
||||
},
|
||||
[ActionType.RUN]: (message: ActionMessage) => {
|
||||
if (message.args.thought) {
|
||||
store.dispatch(addAssistantMessage(message.args.thought));
|
||||
|
||||
@@ -27,6 +27,12 @@ export function handleObservationMessage(message: ObservationMessage) {
|
||||
case ObservationType.AGENT_STATE_CHANGED:
|
||||
store.dispatch(changeAgentState(message.extras.agent_state));
|
||||
break;
|
||||
case ObservationType.DELEGATE:
|
||||
// TODO: better UI for delegation result (#2309)
|
||||
if (message.content) {
|
||||
store.dispatch(addAssistantMessage(message.content));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
store.dispatch(addAssistantMessage(message.message));
|
||||
break;
|
||||
|
||||
@@ -26,6 +26,9 @@ enum ActionType {
|
||||
// Interact with the browser instance.
|
||||
BROWSE_INTERACTIVE = "browse_interactive",
|
||||
|
||||
// Delegate a (sub)task to another agent.
|
||||
DELEGATE = "delegate",
|
||||
|
||||
// Searches long-term memory.
|
||||
RECALL = "recall",
|
||||
|
||||
@@ -33,6 +36,9 @@ enum ActionType {
|
||||
// use the finish action to stop working.
|
||||
FINISH = "finish",
|
||||
|
||||
// Reject a request from user or another agent.
|
||||
REJECT = "reject",
|
||||
|
||||
// Adds a task to the plan.
|
||||
ADD_TASK = "add_task",
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ enum AgentState {
|
||||
PAUSED = "paused",
|
||||
STOPPED = "stopped",
|
||||
FINISHED = "finished",
|
||||
REJECTED = "rejected",
|
||||
ERROR = "error",
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ enum ObservationType {
|
||||
|
||||
// Agent state has changed
|
||||
AGENT_STATE_CHANGED = "agent_state_changed",
|
||||
|
||||
// Delegate result
|
||||
DELEGATE = "delegate",
|
||||
}
|
||||
|
||||
export default ObservationType;
|
||||
|
||||
@@ -284,7 +284,14 @@ class AgentController:
|
||||
self.delegateAction = None
|
||||
|
||||
# update delegate result observation
|
||||
obs: Observation = AgentDelegateObservation(outputs=outputs, content='')
|
||||
# TODO: replace this with AI-generated summary (#2395)
|
||||
formatted_output = ', '.join(
|
||||
f'{key}: {value}' for key, value in outputs.items()
|
||||
)
|
||||
content = f'Delegate agent finishes task with {formatted_output}'
|
||||
obs: Observation = AgentDelegateObservation(
|
||||
outputs=outputs, content=content
|
||||
)
|
||||
await self.event_stream.add_event(obs, EventSource.AGENT)
|
||||
return
|
||||
|
||||
|
||||
@@ -65,7 +65,10 @@ class AgentRejectAction(Action):
|
||||
|
||||
@property
|
||||
def message(self) -> str:
|
||||
return 'Task is rejected by the agent.'
|
||||
msg: str = 'Task is rejected by the agent.'
|
||||
if 'reason' in self.outputs:
|
||||
msg += ' Reason: ' + self.outputs['reason']
|
||||
return msg
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
@@ -70,7 +70,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": "Fix typos in bad.txt. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "TypoFixerAgent", "inputs": {"task": "Fix typos in bad.txt"}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {"summary": {"file": "bad.txt", "typos_fixed": [{"original": "typoo", "corrected": "typo"}, {"original": "mor", "corrected": "more"}]}}}}]]
|
||||
[[{"source": "user", "action": "message", "args": {"content": "Fix typos in bad.txt. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "TypoFixerAgent", "inputs": {"task": "Fix typos in bad.txt"}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "Delegate agent finishes task with summary: {'file': 'bad.txt', 'typos_fixed': [{'original': 'typoo', 'corrected': 'typo'}, {'original': 'mor', 'corrected': 'more'}]}", "extras": {"outputs": {"summary": {"file": "bad.txt", "typos_fixed": [{"original": "typoo", "corrected": "typo"}, {"original": "mor", "corrected": "more"}]}}}}]]
|
||||
|
||||
If the last item in the history is an error, you should try to fix it. If you
|
||||
cannot fix it, call the `reject` action.
|
||||
|
||||
@@ -70,7 +70,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 git commit message for the current staging area. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CommitWriterAgent", "inputs": {}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "", "extras": {"outputs": {"reason": "Not a valid git repository."}}}]]
|
||||
[[{"source": "user", "action": "message", "args": {"content": "Write a git commit message for the current staging area. Do not ask me for confirmation at any point.", "wait_for_response": false}}, {"observation": "null", "content": "", "extras": {}}], [{"source": "agent", "action": "delegate", "args": {"agent": "CommitWriterAgent", "inputs": {}, "thought": ""}}, {"observation": "null", "content": "", "extras": {}}], [{"action": "null", "args": {}}, {"source": "agent", "observation": "delegate", "content": "Delegate agent finishes task with reason: Not a valid git repository.", "extras": {"outputs": {"reason": "Not a valid git repository."}}}]]
|
||||
|
||||
If the last item in the history is an error, you should try to fix it. If you
|
||||
cannot fix it, call the `reject` action.
|
||||
|
||||
Reference in New Issue
Block a user