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:
Boxuan Li
2024-06-26 00:30:10 -07:00
committed by GitHub
parent cd91d45b44
commit ee86d8d25e
12 changed files with 47 additions and 4 deletions

View File

@@ -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],

View File

@@ -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,

View File

@@ -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.",

View File

@@ -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));

View File

@@ -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;

View File

@@ -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",

View File

@@ -6,6 +6,7 @@ enum AgentState {
PAUSED = "paused",
STOPPED = "stopped",
FINISHED = "finished",
REJECTED = "rejected",
ERROR = "error",
}

View File

@@ -19,6 +19,9 @@ enum ObservationType {
// Agent state has changed
AGENT_STATE_CHANGED = "agent_state_changed",
// Delegate result
DELEGATE = "delegate",
}
export default ObservationType;

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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.