Compare commits

...

3 Commits

Author SHA1 Message Date
openhands 47fb0f1a15 Fix linting issues in chat-slice.ts 2025-02-17 19:22:55 +00:00
openhands 9f4795e9d0 Update error detection to use 'ERROR:\n' and adjust tests accordingly 2025-02-17 19:16:19 +00:00
openhands cc6418a435 Fix status indicator for 'Read the contents of a file' operations 2025-02-17 19:13:31 +00:00
4 changed files with 125 additions and 8 deletions
+116
View File
@@ -0,0 +1,116 @@
import { chatSlice, addAssistantObservation } from '../src/state/chat-slice';
import { OpenHandsObservation } from '../src/types/core/observations';
describe('chatSlice', () => {
it('should handle successful read operations', () => {
const initialState = {
messages: [
{
type: 'action',
sender: 'assistant',
eventID: 'test-event-id',
content: 'Reading file: test.txt',
imageUrls: [],
timestamp: new Date().toISOString(),
},
],
};
const readObservation: OpenHandsObservation = {
id: 'test-observation-id',
observation: 'read',
cause: 'test-event-id',
content: 'File content',
extras: {},
};
const action = addAssistantObservation(readObservation);
const newState = chatSlice.reducer(initialState, action);
expect(newState.messages[0].success).toBe(true);
});
it('should handle successful read operations with empty content', () => {
const initialState = {
messages: [
{
type: 'action',
sender: 'assistant',
eventID: 'test-event-id',
content: 'Reading file: empty.txt',
imageUrls: [],
timestamp: new Date().toISOString(),
},
],
};
const readObservation: OpenHandsObservation = {
id: 'test-observation-id',
observation: 'read',
cause: 'test-event-id',
content: '',
extras: {},
};
const action = addAssistantObservation(readObservation);
const newState = chatSlice.reducer(initialState, action);
expect(newState.messages[0].success).toBe(true);
});
it('should handle failed read operations', () => {
const initialState = {
messages: [
{
type: 'action',
sender: 'assistant',
eventID: 'test-event-id',
content: 'Reading file: nonexistent.txt',
imageUrls: [],
timestamp: new Date().toISOString(),
},
],
};
const readObservation: OpenHandsObservation = {
id: 'test-observation-id',
observation: 'read',
cause: 'test-event-id',
content: 'ERROR:\nFile not found',
extras: {},
};
const action = addAssistantObservation(readObservation);
const newState = chatSlice.reducer(initialState, action);
expect(newState.messages[0].success).toBe(false);
});
it('should handle read operations with non-error content containing "error"', () => {
const initialState = {
messages: [
{
type: 'action',
sender: 'assistant',
eventID: 'test-event-id',
content: 'Reading file: error_description.txt',
imageUrls: [],
timestamp: new Date().toISOString(),
},
],
};
const readObservation: OpenHandsObservation = {
id: 'test-observation-id',
observation: 'read',
cause: 'test-event-id',
content: 'This file contains a description of an error, but is not itself an error.',
extras: {},
};
const action = addAssistantObservation(readObservation);
const newState = chatSlice.reducer(initialState, action);
expect(newState.messages[0].success).toBe(true);
});
});
+1 -1
View File
@@ -88,7 +88,7 @@
"typescript": "^5.7.3",
"vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.2"
"vitest": "^3.0.5"
},
"engines": {
"node": ">=20.0.0"
+1 -1
View File
@@ -115,7 +115,7 @@
"typescript": "^5.7.3",
"vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.0.2"
"vitest": "^3.0.5"
},
"packageManager": "npm@10.5.0",
"volta": {
+7 -6
View File
@@ -152,14 +152,15 @@ export const chatSlice = createSlice({
} else if (observationID === "run_ipython") {
// For IPython, we consider it successful if there's no error message
const ipythonObs = observation.payload as IPythonObservation;
causeMessage.success = !ipythonObs.content
.toLowerCase()
.includes("error:");
causeMessage.success = !ipythonObs.content.includes("ERROR:\n");
} else if (observationID === "read" || observationID === "edit") {
// For read/edit operations, we consider it successful if there's content and no error
// For read operations, we consider it successful if there's no error
// For edit operations, we consider it successful if there's content and no error
causeMessage.success =
observation.payload.content.length > 0 &&
!observation.payload.content.toLowerCase().includes("error:");
observationID === "read"
? !observation.payload.content.includes("ERROR:\n")
: observation.payload.content.length > 0 &&
!observation.payload.content.includes("ERROR:\n");
}
if (observationID === "run" || observationID === "run_ipython") {