mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 05:37:20 +08:00
fix(frontend): display ThinkAction thought content in V1 UI (#12597)
Co-authored-by: hieptl <hieptl.developer@gmail.com>
This commit is contained in:
@@ -138,4 +138,72 @@ describe("handleEventForUI", () => {
|
||||
anotherActionEvent,
|
||||
]);
|
||||
});
|
||||
|
||||
it("should NOT replace ThinkAction with ThinkObservation", () => {
|
||||
const mockThinkAction: ActionEvent = {
|
||||
id: "test-think-action-1",
|
||||
timestamp: Date.now().toString(),
|
||||
source: "agent",
|
||||
thought: [{ type: "text", text: "I am thinking..." }],
|
||||
thinking_blocks: [],
|
||||
action: {
|
||||
kind: "ThinkAction",
|
||||
thought: "I am thinking...",
|
||||
},
|
||||
tool_name: "think",
|
||||
tool_call_id: "call_think_1",
|
||||
tool_call: {
|
||||
id: "call_think_1",
|
||||
type: "function",
|
||||
function: {
|
||||
name: "think",
|
||||
arguments: "",
|
||||
},
|
||||
},
|
||||
llm_response_id: "response_think",
|
||||
security_risk: SecurityRisk.UNKNOWN,
|
||||
};
|
||||
|
||||
const mockThinkObservation: ObservationEvent = {
|
||||
id: "test-think-observation-1",
|
||||
timestamp: Date.now().toString(),
|
||||
source: "environment",
|
||||
tool_name: "think",
|
||||
tool_call_id: "call_think_1",
|
||||
observation: {
|
||||
kind: "ThinkObservation",
|
||||
content: [{ type: "text", text: "Your thought has been logged." }],
|
||||
},
|
||||
action_id: "test-think-action-1",
|
||||
};
|
||||
|
||||
const initialUiEvents = [mockMessageEvent, mockThinkAction];
|
||||
const result = handleEventForUI(mockThinkObservation, initialUiEvents);
|
||||
|
||||
// ThinkObservation should NOT be added - ThinkAction should remain
|
||||
expect(result).toEqual([mockMessageEvent, mockThinkAction]);
|
||||
expect(result).not.toBe(initialUiEvents);
|
||||
});
|
||||
|
||||
it("should NOT add ThinkObservation even when ThinkAction is not found", () => {
|
||||
const mockThinkObservation: ObservationEvent = {
|
||||
id: "test-think-observation-1",
|
||||
timestamp: Date.now().toString(),
|
||||
source: "environment",
|
||||
tool_name: "think",
|
||||
tool_call_id: "call_think_1",
|
||||
observation: {
|
||||
kind: "ThinkObservation",
|
||||
content: [{ type: "text", text: "Your thought has been logged." }],
|
||||
},
|
||||
action_id: "test-think-action-not-found",
|
||||
};
|
||||
|
||||
const initialUiEvents = [mockMessageEvent];
|
||||
const result = handleEventForUI(mockThinkObservation, initialUiEvents);
|
||||
|
||||
// ThinkObservation should never be added to uiEvents
|
||||
expect(result).toEqual([mockMessageEvent]);
|
||||
expect(result).not.toBe(initialUiEvents);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,7 @@ import { isObservationEvent } from "#/types/v1/type-guards";
|
||||
/**
|
||||
* Handles adding an event to the UI events array
|
||||
* Replaces actions with observations when they arrive (so UI shows observation instead of action)
|
||||
* Exception: ThinkAction is NOT replaced because the thought content is in the action, not in the observation
|
||||
*/
|
||||
export const handleEventForUI = (
|
||||
event: OpenHandsEvent,
|
||||
@@ -12,12 +13,17 @@ export const handleEventForUI = (
|
||||
const newUiEvents = [...uiEvents];
|
||||
|
||||
if (isObservationEvent(event)) {
|
||||
// Don't add ThinkObservation at all - we keep the ThinkAction instead
|
||||
// The thought content is in the action, not the observation
|
||||
if (event.observation.kind === "ThinkObservation") {
|
||||
return newUiEvents;
|
||||
}
|
||||
|
||||
// Find and replace the corresponding action from uiEvents
|
||||
const actionIndex = newUiEvents.findIndex(
|
||||
(uiEvent) => uiEvent.id === event.action_id,
|
||||
);
|
||||
if (actionIndex !== -1) {
|
||||
// Replace the action with the observation
|
||||
newUiEvents[actionIndex] = event;
|
||||
} else {
|
||||
// Action not found in uiEvents, just add the observation
|
||||
|
||||
Reference in New Issue
Block a user