Compare commits

...

31 Commits

Author SHA1 Message Date
Robert Brennan
b4e8b7204f re-add assertion 2024-10-14 16:22:43 -04:00
Robert Brennan
7f4671f2bd regen integration tests simplified 2024-10-14 16:21:14 -04:00
Robert Brennan
9939b0e826 Merge branch 'main' into rb/hide-cmd 2024-10-14 15:50:36 -04:00
Robert Brennan
eed2b716d1 delete file 2024-10-14 15:50:24 -04:00
Robert Brennan
1c8960ec68 remove assertion 2024-10-14 15:46:57 -04:00
Robert Brennan
96b7fa32fd revert script 2024-10-14 15:19:22 -04:00
Robert Brennan
50528ddfe3 fix env var 2024-10-14 15:18:20 -04:00
Robert Brennan
4c13bc9ed3 fix another test 2024-10-14 09:21:10 -04:00
Robert Brennan
b73f6bb0ea fix test 2024-10-14 09:20:08 -04:00
Robert Brennan
ae8f82d0ab Merge branch 'rb/hide-cmd' of ssh://github.com/opendevin/opendevin into rb/hide-cmd 2024-10-11 11:40:52 -04:00
Robert Brennan
2fc8b82500 refix test 2024-10-11 11:40:49 -04:00
Robert Brennan
6603ca095e Merge branch 'main' into rb/hide-cmd 2024-10-11 11:06:42 -04:00
Robert Brennan
a39e2574bd Merge branch 'rb/hide-cmd' of ssh://github.com/opendevin/opendevin into rb/hide-cmd 2024-10-11 11:06:09 -04:00
Robert Brennan
c2102bb925 fix tests 2024-10-11 11:06:06 -04:00
sp.wack
ab14539828 Update frontend/src/entry.client.tsx 2024-10-11 08:11:06 +04:00
Robert Brennan
714fd7c505 Merge branch 'main' into rb/hide-cmd 2024-10-10 23:35:21 -04:00
Robert Brennan
0322b759f2 Merge branch 'rb/hide-cmd' of ssh://github.com/opendevin/opendevin into rb/hide-cmd 2024-10-10 23:34:56 -04:00
Robert Brennan
9bb54b78db optionalize 2024-10-10 23:34:53 -04:00
Robert Brennan
7d99e0b750 Update frontend/src/components/project-menu/ProjectMenuCard.tsx
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-10-10 23:33:44 -04:00
Robert Brennan
e2f07cf9ae fix checkout 2024-10-10 16:57:24 -04:00
Robert Brennan
5ad0b1ea7e question mark 2024-10-10 16:52:36 -04:00
Robert Brennan
74c2d8a02a update instructions 2024-10-10 16:51:41 -04:00
Robert Brennan
026958293c actually hide from agent too 2024-10-10 16:32:22 -04:00
Robert Brennan
0ed3ded82a actually hide command 2024-10-10 16:27:30 -04:00
Robert Brennan
a9f1a41d3d add hidden args 2024-10-10 16:23:50 -04:00
Robert Brennan
d86bf9c472 Update frontend/src/services/observations.ts 2024-10-10 16:20:46 -04:00
Robert Brennan
f611634dc1 fix lint 2024-10-10 16:15:36 -04:00
Robert Brennan
26b612cde2 revert dev mode 2024-10-10 16:13:15 -04:00
Robert Brennan
e8aa141287 hide on FE too 2024-10-10 16:11:21 -04:00
Robert Brennan
216a378a86 fix fe 2024-10-10 16:03:08 -04:00
Robert Brennan
8d774b6e82 hide commands 2024-10-10 16:00:53 -04:00
18 changed files with 62 additions and 40 deletions

View File

@@ -52,12 +52,7 @@ jobs:
- name: Build Environment
run: make build
- name: Regenerate integration tests
run: |
DEBUG=${{ inputs.debug }} \
LOG_TO_FILE=${{ inputs.log_to_file }} \
FORCE_REGENERATE_TESTS=${{ inputs.force_regenerate_tests }} \
FORCE_USE_LLM=${{ inputs.force_use_llm }} \
./tests/integration/regenerate.sh
run: ./tests/integration/regenerate.sh
- name: Commit changes
run: |
if git diff --quiet --exit-code; then

View File

@@ -37,8 +37,12 @@ export function ProjectMenuCard({
const handlePushToGitHub = () => {
const rawEvent = {
content:
"Please create a new branch and commit the changes. Then push them to the remote repository, and open up a pull request using the GitHub API and the token in the GITHUB_TOKEN environment variable",
content: `
Let's push the code to GitHub.
If we're currently on the openhands-workspace branch, please create a new branch with a descriptive name.
Commit any changes and push them to the remote repository.
Finally, open up a pull request using the GitHub API and the token in the GITHUB_TOKEN environment variable, then show me the URL of the pull request.
`,
imageUrls: [],
timestamp: new Date().toISOString(),
};

View File

@@ -2,7 +2,7 @@ import { FitAddon } from "@xterm/addon-fit";
import { Terminal } from "@xterm/xterm";
import React from "react";
import { Command } from "#/state/commandSlice";
import { sendTerminalCommand } from "#/services/terminalService";
import { getTerminalCommand } from "#/services/terminalService";
import { parseTerminalOutput } from "#/utils/parseTerminalOutput";
import { useSocket } from "#/context/socket";
@@ -69,7 +69,7 @@ export const useTerminal = (commands: Command[] = []) => {
const handleEnter = (command: string) => {
terminal.current?.write("\r\n");
send(sendTerminalCommand(command));
send(getTerminalCommand(command));
};
const handleBackspace = (command: string) => {

View File

@@ -167,7 +167,7 @@ export function TaskForm({ importedProjectZip, textareaRef }: TaskFormProps) {
disabled={navigation.state === "submitting"}
placeholder={
selectedRepository
? `What would you like to change in ${selectedRepository}`
? `What would you like to change in ${selectedRepository}?`
: "What do you want to build?"
}
onChange={handleChange}

View File

@@ -21,8 +21,11 @@ import ActionType from "#/types/ActionType";
import { handleAssistantMessage } from "#/services/actions";
import { addUserMessage, clearMessages } from "#/state/chatSlice";
import { useSocket } from "#/context/socket";
import { sendTerminalCommand } from "#/services/terminalService";
import { appendInput, clearTerminal } from "#/state/commandSlice";
import {
getGitHubTokenCommand,
getCloneRepoCommand,
} from "#/services/terminalService";
import { clearTerminal } from "#/state/commandSlice";
import { useEffectOnce } from "#/utils/use-effect-once";
import CodeIcon from "#/assets/code.svg?react";
import GlobeIcon from "#/assets/globe.svg?react";
@@ -122,26 +125,6 @@ function App() {
[],
);
const exportGitHubTokenToTerminal = (gitHubToken: string) => {
const command = `export GITHUB_TOKEN=${gitHubToken}`;
const event = sendTerminalCommand(command);
send(event);
dispatch(appendInput(command.replace(gitHubToken, "***")));
};
const sendCloneRepoCommandToTerminal = (
gitHubToken: string,
repository: string,
) => {
const url = `https://${gitHubToken}@github.com/${repository}.git`;
const command = `git clone ${url}`;
const event = sendTerminalCommand(command);
send(event);
dispatch(appendInput(command.replace(gitHubToken, "***")));
};
const addIntialQueryToChat = (
query: string,
base64Files: string[],
@@ -199,7 +182,7 @@ function App() {
// handle new session
if (!token) {
if (ghToken && repo) {
sendCloneRepoCommandToTerminal(ghToken, repo);
send(getCloneRepoCommand(ghToken, repo));
dispatch(clearSelectedRepository()); // reset selected repository; maybe better to move this to '/'?
}
@@ -232,7 +215,7 @@ function App() {
React.useEffect(() => {
// Export if the user valid, this could happen mid-session so it is handled here
if (userId && ghToken && runtimeActive) {
exportGitHubTokenToTerminal(ghToken);
send(getGitHubTokenCommand(ghToken));
}
}, [userId, ghToken, runtimeActive]);

View File

@@ -52,6 +52,7 @@ const messageActions = {
store.dispatch(addAssistantMessage(message.message));
},
[ActionType.RUN]: (message: ActionMessage) => {
if (message.args.hidden) return;
if (message.args.thought) {
store.dispatch(addAssistantMessage(message.args.thought));
}

View File

@@ -10,6 +10,7 @@ import { addAssistantMessage } from "#/state/chatSlice";
export function handleObservationMessage(message: ObservationMessage) {
switch (message.observation) {
case ObservationType.RUN:
if (message.extras.hidden) break;
store.dispatch(appendOutput(message.content));
break;
case ObservationType.RUN_IPYTHON:

View File

@@ -1,6 +1,20 @@
import ActionType from "#/types/ActionType";
export function sendTerminalCommand(command: string) {
const event = { action: ActionType.RUN, args: { command } };
export function getTerminalCommand(command: string, hidden: boolean = false) {
const event = { action: ActionType.RUN, args: { command, hidden } };
return JSON.stringify(event);
}
export function getGitHubTokenCommand(gitHubToken: string) {
const command = `export GITHUB_TOKEN=${gitHubToken}`;
const event = getTerminalCommand(command, true);
return event;
}
export function getCloneRepoCommand(gitHubToken: string, repository: string) {
const url = `https://${gitHubToken}@github.com/${repository}.git`;
const dirName = repository.split("/")[1];
const command = `git clone ${url} ${dirName} ; cd ${dirName} ; git checkout -b openhands-workspace`;
const event = getTerminalCommand(command, true);
return event;
}

View File

@@ -14,6 +14,7 @@ export interface CommandAction extends OpenHandsActionEvent<"run"> {
command: string;
is_confirmed: "confirmed" | "rejected" | "awaiting_confirmation";
thought: string;
hidden?: boolean;
};
}

View File

@@ -15,6 +15,7 @@ export interface CommandObservation extends OpenHandsObservationEvent<"run"> {
command: string;
command_id: number;
exit_code: number;
hidden?: boolean;
};
}

View File

@@ -174,6 +174,8 @@ class AgentController:
Args:
event (Event): The incoming event to process.
"""
if hasattr(event, 'hidden') and event.hidden:
return
if isinstance(event, Action):
await self._handle_action(event)
elif isinstance(event, Observation):

View File

@@ -25,6 +25,7 @@ class CmdRunAction(Action):
# file2.txt
# root@sandbox:~# <-- this is the command prompt
hidden: bool = False
action: str = ActionType.RUN
runnable: ClassVar[bool] = True
is_confirmed: ActionConfirmationStatus = ActionConfirmationStatus.CONFIRMED

View File

@@ -11,6 +11,7 @@ class CmdOutputObservation(Observation):
command_id: int
command: str
exit_code: int = 0
hidden: bool = False
observation: str = ObservationType.RUN
@property

View File

@@ -49,7 +49,10 @@ class ShortTermHistory(list[Event]):
return list(self.get_events(include_delegates=include_delegates))
def get_events(
self, reverse: bool = False, include_delegates: bool = False
self,
reverse: bool = False,
include_delegates: bool = False,
include_hidden=False,
) -> Iterable[Event]:
"""Return the events as a stream of Event objects."""
# TODO handle AgentRejectAction, if it's not part of a chunk ending with an AgentDelegateObservation
@@ -69,6 +72,8 @@ class ShortTermHistory(list[Event]):
reverse=reverse,
filter_out_type=self.filter_out,
):
if not include_hidden and hasattr(event, 'hidden') and event.hidden:
continue
# TODO add summaries
# and filter out events that were included in a summary

View File

@@ -466,6 +466,7 @@ class RuntimeClient:
command_id=-1,
content=all_output.rstrip('\r\n'),
command=action.command,
hidden=action.hidden,
exit_code=exit_code,
)
except UnicodeDecodeError:

View File

@@ -102,6 +102,7 @@ def test_cmd_run_action_serialization_deserialization():
'command': 'echo "Hello world"',
'thought': '',
'keep_prompt': True,
'hidden': False,
'is_confirmed': ActionConfirmationStatus.CONFIRMED,
},
}

View File

@@ -47,7 +47,12 @@ def test_observation_event_props_serialization_deserialization():
'timestamp': '2021-08-01T12:00:00',
'observation': 'run',
'message': 'Command `ls -l` executed with exit code 0.',
'extras': {'exit_code': 0, 'command': 'ls -l', 'command_id': 3},
'extras': {
'exit_code': 0,
'command': 'ls -l',
'command_id': 3,
'hidden': False,
},
'content': 'foo.txt',
}
serialization_deserialization(original_observation_dict, CmdOutputObservation)
@@ -56,7 +61,12 @@ def test_observation_event_props_serialization_deserialization():
def test_command_output_observation_serialization_deserialization():
original_observation_dict = {
'observation': 'run',
'extras': {'exit_code': 0, 'command': 'ls -l', 'command_id': 3},
'extras': {
'exit_code': 0,
'command': 'ls -l',
'command_id': 3,
'hidden': False,
},
'message': 'Command `ls -l` executed with exit code 0.',
'content': 'foo.txt',
}

View File

@@ -220,6 +220,7 @@ def test_unsafe_bash_command(temp_dir: str):
arguments={
'blocking': False,
'command': 'ls',
'hidden': False,
'keep_prompt': True,
'is_confirmed': ActionConfirmationStatus.CONFIRMED,
},