Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Jupyter Frontend #1363

Merged
merged 196 commits into from May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
196 commits
Select commit Hold shift + click to select a range
7c76759
initialize plugin definition
xingyaoww Apr 20, 2024
ba07415
initialize plugin definition
xingyaoww Apr 20, 2024
fdc5109
simplify mixin
xingyaoww Apr 20, 2024
1ada575
further improve plugin mixin
xingyaoww Apr 20, 2024
9bed95f
add cache dir for pip
xingyaoww Apr 20, 2024
abf0fbb
support clean up cache
xingyaoww Apr 20, 2024
bbac1a6
add script for setup jupyter and execution server
xingyaoww Apr 20, 2024
18cf4ba
integrate JupyterRequirement to ssh_box
xingyaoww Apr 20, 2024
b7f2f60
source bashrc at the end of plugin load
xingyaoww Apr 20, 2024
cf33615
add execute_cli that accept code via stdin
xingyaoww Apr 20, 2024
3908ae7
make JUPYTER_EXEC_SERVER_PORT configurable via env var
xingyaoww Apr 20, 2024
fadb609
increase background cmd sleep time
xingyaoww Apr 20, 2024
d3c829c
Update opendevin/sandbox/plugins/mixin.py
xingyaoww Apr 21, 2024
9481c7b
add mixin to base class
xingyaoww Apr 21, 2024
456d9cb
make jupyter requirement a dataclass
xingyaoww Apr 21, 2024
0d788ef
source plugins only when >0 requirements
xingyaoww Apr 21, 2024
a436c8b
add `sandbox_plugins` for each agent & have controller take care of it
xingyaoww Apr 21, 2024
bac492a
update build.sh to make logs available in /opendevin/logs
xingyaoww Apr 21, 2024
3f5030d
switch to use config for lib and cache dir
xingyaoww Apr 21, 2024
71983cb
Merge commit '3f5030de8e4b9cd972bf5883f827d8a3842a32d3' into fully-in…
xingyaoww Apr 21, 2024
31a1b53
Add SANDBOX_WORKSPACE_DIR into config
xingyaoww Apr 21, 2024
fcaff71
Add SANDBOX_WORKSPACE_DIR into config
xingyaoww Apr 21, 2024
9ad9b2d
Merge commit 'fcaff711649d8c37d3b239ea98b314a5a1fe6e32' into fully-in…
xingyaoww Apr 21, 2024
97f5faf
fix occurence of /workspace
xingyaoww Apr 21, 2024
4471bf7
Merge commit '97f5faf5deb8f463c03a3614ff36ddc0d86f87b1' into fully-in…
xingyaoww Apr 21, 2024
a7b4f2e
fix permission issue with /workspace
xingyaoww Apr 21, 2024
b029f5d
Merge commit 'a7b4f2ebac440a1f785a7653e3615a9bdd123321' into fully-in…
xingyaoww Apr 21, 2024
6be6ac8
use python to implement execute_cli to avoid stdin escape issue
xingyaoww Apr 21, 2024
a21a54f
Merge commit '6be6ac8a19b304e58b5be4dc222520c0f7113f78' into fully-in…
xingyaoww Apr 21, 2024
9514491
add IPythonRunCellAction and get it working
xingyaoww Apr 21, 2024
c1a4e56
wait until jupyter is avaialble
xingyaoww Apr 22, 2024
76b5cfa
Merge commit '2242702cf94eab7275f2cb148859135018d9b280' into integrat…
xingyaoww Apr 22, 2024
da1b3ba
support plugin via copying instead of mounting
xingyaoww Apr 22, 2024
b89d030
Merge commit 'da1b3bafde18a76baa37617ee00114c098267458' into fully-in…
xingyaoww Apr 22, 2024
86113f6
add agent talk action
xingyaoww Apr 22, 2024
7f6e939
support follow-up user language feedback
xingyaoww Apr 22, 2024
148b136
add __str__ for action to be printed better
xingyaoww Apr 22, 2024
d10c586
only print PLAN at the beginning
xingyaoww Apr 22, 2024
956a1a4
wip: update codeact agent
xingyaoww Apr 22, 2024
87f4159
get rid the initial messate
xingyaoww Apr 22, 2024
f9f2ed8
update codeact agent to handle null action;
xingyaoww Apr 22, 2024
9ffcef0
dispatch thought for RUN action as well
xingyaoww Apr 23, 2024
51f1629
Merge commit 'fc5e075ea0646caa0e22180384476e14710a1d55' into fully-in…
xingyaoww Apr 23, 2024
8358c5c
Merge commit '960f17a565081d8ce65a443f857c4299eb864a14' into fully-in…
xingyaoww Apr 23, 2024
c537e6c
fix weird behavior of pxssh where the output would not flush correctly
xingyaoww Apr 23, 2024
c2c9014
make ssh box can handle exit_code properly as well
xingyaoww Apr 23, 2024
ddaabd7
add initial version of swe-agent plugin;
xingyaoww Apr 23, 2024
912fee1
rename swe cursors
xingyaoww Apr 23, 2024
f1a65fc
split setup script into two and create two requirements
xingyaoww Apr 23, 2024
e825829
print SWE-agent command documentation
xingyaoww Apr 23, 2024
6615b80
update swe-agent to default to no custom docs
xingyaoww Apr 23, 2024
e7b26c1
add initial version of swe-agent plugin;
xingyaoww Apr 23, 2024
0e659e0
rename swe cursors
xingyaoww Apr 23, 2024
a3f6408
split setup script into two and create two requirements
xingyaoww Apr 23, 2024
6f3338a
print SWE-agent command documentation
xingyaoww Apr 23, 2024
af7a50e
update swe-agent to default to no custom docs
xingyaoww Apr 23, 2024
d68d6ef
update dockerfile with dependency from swe-agent
xingyaoww Apr 23, 2024
d70f8cb
make env setup a separate script for .bashrc source
xingyaoww Apr 23, 2024
d5fbf8e
add wip prompt
xingyaoww Apr 24, 2024
4fc9b84
fix mount_dir for ssh_box
xingyaoww Apr 24, 2024
67d244f
update prompt
xingyaoww Apr 24, 2024
0b8a2cb
fix mount_dir for ssh_box
xingyaoww Apr 24, 2024
5fabf19
default to use host network
xingyaoww Apr 24, 2024
a8790ab
default to use host network
xingyaoww Apr 24, 2024
d2bb7c0
move prompt to a separate file
xingyaoww Apr 24, 2024
a2e628c
fix swe-tool plugins;
xingyaoww Apr 24, 2024
7c08853
remove hostname from sshbox
xingyaoww Apr 24, 2024
e420638
update the prompt with edit functionality
xingyaoww Apr 24, 2024
960ef6a
fix swe-tool plugins;
xingyaoww Apr 24, 2024
ee91c1e
Merge commit '0b6ab238f946f6e85117824d88a4aa1fcede2a4b' into fully-in…
xingyaoww Apr 24, 2024
76399c3
Merge commit '960ef6a0f65e8717ebc06fbf0da10414bf075d6f' into fully-in…
xingyaoww Apr 24, 2024
7da3d84
add awaiting into status bar
xingyaoww Apr 24, 2024
0e355dd
fix the bug of additional send event
xingyaoww Apr 24, 2024
1130024
remove some print action
xingyaoww Apr 24, 2024
544e94e
move logic to config.py
xingyaoww Apr 24, 2024
9b97909
Merge commit '544e94e61c22972143debaf496d0f2efbe4d6a3a' into fully-in…
xingyaoww Apr 24, 2024
7bcb4dc
remove debugging comments
xingyaoww Apr 24, 2024
a5e8322
make host network as default
xingyaoww Apr 24, 2024
3d37035
Merge commit 'a5e832273be8fc8463b18f79adc5a96514561993' into fully-in…
xingyaoww Apr 24, 2024
6e0fed5
make WORKSPACE_MOUNT_PATH as abspath
xingyaoww Apr 25, 2024
06f0155
implement execute_cli via file cp
xingyaoww Apr 25, 2024
9cf4332
Revert "implement execute_cli via file cp"
xingyaoww Apr 25, 2024
63cbaf2
add codeact dependencies to default container
xingyaoww Apr 25, 2024
3159d41
add IPythonRunCellObservation
xingyaoww Apr 25, 2024
9b9f942
add back cache dir and default to /tmp
xingyaoww Apr 25, 2024
5b8888c
Merge commit '9b9f942302f3bebba65811816f304129035eb0bc' into fully-in…
xingyaoww Apr 25, 2024
72866b3
make USE_HOST_NETWORK a bool
xingyaoww Apr 25, 2024
70cdde2
revert use host network to false
xingyaoww Apr 25, 2024
b1907ac
add temporarily fix for IPython RUN action
xingyaoww Apr 25, 2024
ab2b553
preliminary implementation of CodeActAgent's jupyter
xingyaoww Apr 25, 2024
459b103
update node module
xingyaoww Apr 25, 2024
a59b1a2
update prompt
xingyaoww Apr 25, 2024
6781650
Merge commit 'a1a076768137fdf3bf5a188f387ad1681054a1db' into fully-in…
xingyaoww Apr 25, 2024
f025049
revert USE_HOST_NETWORK to true since it is not affecting anything
xingyaoww Apr 25, 2024
4ee04a2
attempt to fix lint
xingyaoww Apr 25, 2024
076a2d1
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 26, 2024
71d752a
remove newline
xingyaoww Apr 26, 2024
bb2fbc5
update prompt
xingyaoww Apr 25, 2024
20c668b
Refactor browser style. (#1358)
iFurySt Apr 25, 2024
2a5886e
Add integration test framework with mock llm (#1301)
li-boxuan Apr 25, 2024
94b392e
Revert "refactor(frontend): Terminal (#1315)" (#1360)
rbren Apr 25, 2024
3d0c8b4
revert USE_HOST_NETWORK to true since it is not affecting anything
xingyaoww Apr 25, 2024
9c1b2e5
attempt to fix lint
xingyaoww Apr 25, 2024
e9de174
handle IsADirectory errors (#1365)
rbren Apr 25, 2024
f033ad7
update to 0.4.0 (#1362)
rbren Apr 25, 2024
71f9668
feat(frontend): multiple design changes (#1370)
Sparkier Apr 25, 2024
5c52651
fix/improve terminal hook (#1371)
amanape Apr 25, 2024
6da6650
Merge branch 'main' into jupyter-frontend
xingyaoww Apr 26, 2024
0049309
Revert "update node module"
xingyaoww Apr 26, 2024
a6673e0
support SyntaxHighlighter and markdown for jupyter visualization
xingyaoww Apr 26, 2024
9040772
fix jupyter execution server
xingyaoww Apr 26, 2024
777241c
Merge commit '90407721a9a00b2903858bb94a77951b92cae4bb' into jupyter-…
xingyaoww Apr 26, 2024
c46f221
make jupyter active
xingyaoww Apr 26, 2024
a6f6b71
improve the display of markdown and raw text
xingyaoww Apr 26, 2024
53191dd
get base64 image display for react
xingyaoww Apr 26, 2024
5af0458
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 26, 2024
9fd4417
add `thought` to most action class
xingyaoww Apr 26, 2024
72f8afb
fix unit tests for current action abstraction
xingyaoww Apr 26, 2024
68de201
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 26, 2024
e4f9303
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 27, 2024
7c7a516
support user exit
xingyaoww Apr 27, 2024
148b632
update test cases with the latest action format (added 'thought')
xingyaoww Apr 27, 2024
ccca95d
fix integration test for CodeActAGent by mocking stdin
xingyaoww Apr 27, 2024
45d560a
only mock stdin for tests with user_responses.log
xingyaoww Apr 27, 2024
ee7cbd8
remove -exec integration test for CodeActAgent since it is not supported
xingyaoww Apr 27, 2024
3e7fb43
remove specific stop word
xingyaoww Apr 27, 2024
85b943a
fix comments
xingyaoww Apr 27, 2024
cd2101d
improve clarity of prompt
xingyaoww Apr 27, 2024
ec31763
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 27, 2024
c1019c6
Merge commit 'ec31763f8cb3f034f5afd4bbc9dcbbbe17bc6f69' into jupyter-…
xingyaoww Apr 27, 2024
3cd6180
attempt to fix lint
xingyaoww Apr 27, 2024
38c1afe
attempt to fix lint yet agiain
xingyaoww Apr 27, 2024
b9f0a84
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 27, 2024
3517ebd
fix py lint
xingyaoww Apr 27, 2024
5b67cc2
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww Apr 27, 2024
38ed37c
fix integration tests
xingyaoww Apr 27, 2024
5d2712e
sandbox might failed in chown due to mounting, but it won't be fatal
xingyaoww Apr 28, 2024
9bea2fb
update debug instruction for sshbox
xingyaoww Apr 28, 2024
1e487fb
Merge commit '9bea2fbc88030dc27542f173f7a1cd758a07d705' into fully-in…
xingyaoww Apr 28, 2024
e38b3ab
fix typo
xingyaoww Apr 28, 2024
0caf63f
Merge commit 'e38b3ab1efdbadb990988318ecd4a3faf741233a' into fully-in…
xingyaoww Apr 28, 2024
7895404
get RUN_AS_DEVIN and network=host working with app sandbox
xingyaoww Apr 28, 2024
2f2e3d4
get RUN_AS_DEVIN and network=host working with app sandbox
xingyaoww Apr 28, 2024
ce6426d
attempt to fix the workspace base permission
xingyaoww Apr 28, 2024
ac341fe
sandbox might failed in chown due to mounting, but it won't be fatal
xingyaoww Apr 28, 2024
e3157ae
update sshbox instruction
xingyaoww Apr 28, 2024
a92b889
remove default user id since it will be passed in the instruction
xingyaoww Apr 28, 2024
b6e179e
revert permission fix since it should be resolved by correct SANDBOX_…
xingyaoww Apr 28, 2024
96996e5
the permission issue can be fixed by simply provide correct env var
xingyaoww Apr 28, 2024
a564e0f
remove log
xingyaoww Apr 28, 2024
199e9ca
set sandbox user id to getuid by default
xingyaoww Apr 28, 2024
ee36c82
move logging to initializer
xingyaoww Apr 28, 2024
d3699dc
Merge commit 'ee36c827741c3644509f552fde2e8d873d834cd4' into fully-in…
xingyaoww Apr 28, 2024
7282e21
make the uid consistent across host, app container, and sandbox
xingyaoww Apr 28, 2024
680d2c0
remove hostname as it causes sudo issue
xingyaoww Apr 28, 2024
f3a252e
fix permission of entrypoint script
xingyaoww Apr 28, 2024
3c556cb
Merge commit 'f3a252e8752ea186a48bbb839ce62f54fdf9e4e9' into fully-in…
xingyaoww Apr 28, 2024
2e6d759
make the uvicron app run as host user uid for jupyter plugin
xingyaoww Apr 28, 2024
49bdda7
Merge commit '2e6d75963fe8a4aecb45390e1f945ca3c4500d6a' into fully-in…
xingyaoww Apr 28, 2024
0a6dca9
add warning message
xingyaoww Apr 28, 2024
245e498
Merge commit '0a6dca959b78d0b5c371334e334b5721d02f5284' into jupyter-…
xingyaoww Apr 28, 2024
000ecdf
fix frontend lint
xingyaoww Apr 28, 2024
313c16f
Merge branch 'main' into run-as-devin-and-network-host
xingyaoww Apr 28, 2024
ae744bf
Merge commit '8954855ba3c742e2e1b4aacd6fedc10127600ed6' into fully-in…
xingyaoww Apr 29, 2024
bb70acf
update dev md for instruction of running unit tests
xingyaoww Apr 30, 2024
0f496ef
add back unit tests
xingyaoww Apr 30, 2024
d77ce67
revert back to the original sandbox implementation to fix testcases
xingyaoww Apr 30, 2024
fcc5897
Merge commit '31c1a2d748f1b0f286f5fce678e7b9311a288fa9' into run-as-d…
xingyaoww Apr 30, 2024
1ce8d5d
revert use host network
xingyaoww Apr 30, 2024
cac18c7
get docker socket gid and usermod instead of chmod 777
xingyaoww Apr 30, 2024
dd0c20f
allow unit test workflow to find docker.sock
xingyaoww Apr 30, 2024
12c29a4
make sandbox test working via patch
xingyaoww Apr 30, 2024
6cc8961
fix arg parser that's broken for some reason
xingyaoww Apr 30, 2024
ec8e5ca
try to fix app build disk space issue
xingyaoww Apr 30, 2024
968615d
fix integration test
xingyaoww Apr 30, 2024
d31224e
Revert "fix arg parser that's broken for some reason"
xingyaoww Apr 30, 2024
0ad2b55
update Development.md
xingyaoww Apr 30, 2024
2c366cf
Merge commit '0ad2b55e66d4b30bd377ec6289d705a0864385a9' into fully-in…
xingyaoww Apr 30, 2024
a0fc027
Merge commit 'ec8e5ca2de7a635275f859b7a91af15742052610' into fully-in…
xingyaoww Apr 30, 2024
76be9d8
Merge commit 'a0fc0273d29462e1a3036c89d530e40c2816698a' into jupyter-…
xingyaoww Apr 30, 2024
d675609
cleanup intergration tests & add exception for CodeAct+execbox
xingyaoww Apr 30, 2024
a150b4e
Merge commit 'd6756091c3e2df433b5d98cab8559810fb591286' into jupyter-…
xingyaoww Apr 30, 2024
0f4e92a
Merge branch 'main' into fully-integrate-CodeActAgent
rbren Apr 30, 2024
cadb3f2
Merge branch 'main' into fully-integrate-CodeActAgent
rbren Apr 30, 2024
a667ad0
fix config
xingyaoww Apr 30, 2024
eb084b8
implement user_message action
rbren Apr 30, 2024
2796f7f
Merge pull request #1 from rbren/rb/codeact
xingyaoww May 1, 2024
5a87322
fix doc
xingyaoww May 1, 2024
a422772
Merge branch 'main' into fully-integrate-CodeActAgent
xingyaoww May 1, 2024
17c66fd
fix event dict error
xingyaoww May 1, 2024
bbcad2d
fix frontend lint
xingyaoww May 1, 2024
52870a8
revert accidentally changes to integration tests
xingyaoww May 1, 2024
8ef9330
revert accidentally changes to integration tests
xingyaoww May 1, 2024
0b9655c
Merge commit '8ef9330e2b47e2743ddf3d63a4bf4cfe9aad9323' into jupyter-…
xingyaoww May 1, 2024
7448461
Merge branch 'main' into jupyter-frontend
xingyaoww May 1, 2024
fa2e0f4
Merge branch 'main' into jupyter-frontend
xingyaoww May 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions agenthub/codeact_agent/codeact_agent.py
Expand Up @@ -122,6 +122,12 @@ def step(self, state: State) -> Action:
self.messages.append({'role': 'user', 'content': content})
elif isinstance(obs, IPythonRunCellObservation):
content = 'OBSERVATION:\n' + obs.content
# replace base64 images with a placeholder
splited = content.split('\n')
for i, line in enumerate(splited):
if '![image](data:image/png;base64,' in line:
splited[i] = '![image](data:image/png;base64, ...) already displayed to user'
content = '\n'.join(splited)
self.messages.append({'role': 'user', 'content': content})
else:
raise NotImplementedError(
Expand Down
19 changes: 19 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions frontend/package.json
Expand Up @@ -25,6 +25,7 @@
"react": "^18.2.0",
"react-accessible-treeview": "^2.8.3",
"react-dom": "^18.2.0",
"react-highlight": "^0.15.0",
"react-hot-toast": "^2.4.1",
"react-i18next": "^14.1.0",
"react-icons": "^5.0.1",
Expand Down Expand Up @@ -64,6 +65,7 @@
"@types/node": "^18.0.0 ",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@types/react-highlight": "^0.12.8",
"@types/react-syntax-highlighter": "^15.5.11",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.0.0",
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/components/Jupyter.tsx
@@ -0,0 +1,77 @@
import React from "react";
import { useSelector } from "react-redux";
import SyntaxHighlighter from "react-syntax-highlighter";
import Markdown from "react-markdown";
import { atomOneDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
import { RootState } from "#/store";
import { Cell } from "#/state/jupyterSlice";

interface IJupyterCell {
cell: Cell;
}

function JupyterCell({ cell }: IJupyterCell): JSX.Element {
const code = cell.content;

if (cell.type === "input") {
return (
<div className="rounded-lg bg-gray-800 dark:bg-gray-900 p-2 text-xs">
<div className="mb-1 text-gray-400">EXECUTE</div>
<pre
className="scrollbar-custom scrollbar-thumb-gray-500 hover:scrollbar-thumb-gray-400 dark:scrollbar-thumb-white/10 dark:hover:scrollbar-thumb-white/20 overflow-auto px-5"
style={{ padding: 0, marginBottom: 0, fontSize: "0.75rem" }}
>
<SyntaxHighlighter language="python" style={atomOneDark}>
{code}
</SyntaxHighlighter>
</pre>
</div>
);
}
return (
<div className="rounded-lg bg-gray-800 dark:bg-gray-900 p-2 text-xs">
<div className="mb-1 text-gray-400">STDOUT/STDERR</div>
<pre
className="scrollbar-custom scrollbar-thumb-gray-500 hover:scrollbar-thumb-gray-400 dark:scrollbar-thumb-white/10 dark:hover:scrollbar-thumb-white/20 overflow-auto px-5 max-h-[60vh] bg-gray-800"
style={{ padding: 0, marginBottom: 0, fontSize: "0.75rem" }}
>
{/* split code by newline and render each line as a plaintext, except it starts with `![image]` so we render it as markdown */}
{code.split("\n").map((line, index) => {
if (line.startsWith("![image](data:image/png;base64,")) {
// add new line before and after the image
return (
<div key={index}>
<Markdown urlTransform={(value: string) => value}>
{line}
</Markdown>
<br />
</div>
);
}
return (
<div key={index}>
<SyntaxHighlighter language="plaintext" style={atomOneDark}>
{line}
</SyntaxHighlighter>
<br />
</div>
);
})}
</pre>
</div>
);
}

function Jupyter(): JSX.Element {
const { cells } = useSelector((state: RootState) => state.jupyter);

return (
<div className="flex-1 overflow-y-auto flex flex-col">
{cells.map((cell, index) => (
<JupyterCell key={index} cell={cell} />
))}
</div>
);
}

export default Jupyter;
17 changes: 16 additions & 1 deletion frontend/src/components/Workspace.tsx
Expand Up @@ -12,6 +12,7 @@
import Browser from "./Browser";
import CodeEditor from "./CodeEditor";
import Planner from "./Planner";
import Jupyter from "./Jupyter";

function Workspace() {
const { t } = useTranslation();
Expand All @@ -20,12 +21,13 @@
const screenshotSrc = useSelector(
(state: RootState) => state.browser.screenshotSrc,
);

const jupyterCells = useSelector((state: RootState) => state.jupyter.cells);
const [activeTab, setActiveTab] = useState<TabType>(TabOption.CODE);
const [changes, setChanges] = useState<Record<TabType, boolean>>({
[TabOption.PLANNER]: false,
[TabOption.CODE]: false,
[TabOption.BROWSER]: false,
[TabOption.JUPYTER]: false,
});

const tabData = useMemo(
Expand All @@ -45,6 +47,11 @@
icon: <IoIosGlobe size={18} />,
component: <Browser key="browser" />,
},
[TabOption.JUPYTER]: {
name: t(I18nKey.WORKSPACE$JUPYTER_TAB_LABEL),
icon: <VscCode size={18} />,
component: <Jupyter key="jupyter" />,
},
}),
[t],
);
Expand Down Expand Up @@ -73,6 +80,14 @@
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [screenshotSrc]);

useEffect(() => {
if (activeTab !== TabOption.JUPYTER && jupyterCells.length > 0) {
// FIXME: This is a temporary solution to show the jupyter tab when the first cell is added
// Only need to show the tab only when a cell is added
setChanges((prev) => ({ ...prev, [TabOption.JUPYTER]: true }));
}
}, [jupyterCells]);

Check warning on line 89 in frontend/src/components/Workspace.tsx

View workflow job for this annotation

GitHub Actions / Lint frontend

React Hook useEffect has a missing dependency: 'activeTab'. Either include it or remove the dependency array

return (
<div className="flex flex-col min-h-0 grow">
<div
Expand Down
13 changes: 13 additions & 0 deletions frontend/src/i18n/translation.json
Expand Up @@ -39,6 +39,19 @@
"pt": "Planejador",
"es": "Planificador"
},
"WORKSPACE$JUPYTER_TAB_LABEL": {
"en": "Jupyter IPython",
"zh-CN": "Jupyter IPython",
"de": "Jupyter IPython",
"ko-KR": "Jupyter IPython",
"no": "Jupyter IPython",
"zh-TW": "Jupyter IPython",
"ar": "Jupyter IPython",
"fr": "Jupyter IPython",
"it": "Jupyter IPython",
"pt": "Jupyter IPython",
"es": "Jupyter IPython"
},
"WORKSPACE$CODE_EDITOR_TAB_LABEL": {
"en": "Code Editor",
"zh-CN": "代码编辑器",
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/services/actions.ts
Expand Up @@ -3,6 +3,7 @@ import { setScreenshotSrc, setUrl } from "#/state/browserSlice";
import { appendAssistantMessage } from "#/state/chatSlice";
import { setCode, updatePath } from "#/state/codeSlice";
import { appendInput } from "#/state/commandSlice";
import { appendJupyterInput } from "#/state/jupyterSlice";
import { setPlan } from "#/state/planSlice";
import { setInitialized } from "#/state/taskSlice";
import store from "#/store";
Expand Down Expand Up @@ -45,7 +46,7 @@ const messageActions = {
if (message.args.thought) {
store.dispatch(appendAssistantMessage(message.args.thought));
}
store.dispatch(appendInput(message.args.code));
store.dispatch(appendJupyterInput(message.args.code));
},
[ActionType.ADD_TASK]: () => {
getPlan().then((fetchedPlan) => store.dispatch(setPlan(fetchedPlan)));
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/services/observations.ts
Expand Up @@ -3,6 +3,7 @@ import { setUrl, setScreenshotSrc } from "#/state/browserSlice";
import store from "#/store";
import { ObservationMessage } from "#/types/Message";
import { appendOutput } from "#/state/commandSlice";
import { appendJupyterOutput } from "#/state/jupyterSlice";
import ObservationType from "#/types/ObservationType";

export function handleObservationMessage(message: ObservationMessage) {
Expand All @@ -12,7 +13,7 @@ export function handleObservationMessage(message: ObservationMessage) {
break;
case ObservationType.RUN_IPYTHON:
// FIXME: render this as markdown
store.dispatch(appendOutput(message.content));
store.dispatch(appendJupyterOutput(message.content));
break;
case ObservationType.BROWSE:
if (message.extras?.screenshot) {
Expand Down
27 changes: 27 additions & 0 deletions frontend/src/state/jupyterSlice.ts
@@ -0,0 +1,27 @@
import { createSlice } from "@reduxjs/toolkit";

export type Cell = {
content: string;
type: "input" | "output";
};

const initialCells: Cell[] = [];

export const cellSlice = createSlice({
name: "cell",
initialState: {
cells: initialCells,
},
reducers: {
appendJupyterInput: (state, action) => {
state.cells.push({ content: action.payload, type: "input" });
},
appendJupyterOutput: (state, action) => {
state.cells.push({ content: action.payload, type: "output" });
},
},
});

export const { appendJupyterInput, appendJupyterOutput } = cellSlice.actions;

export default cellSlice.reducer;
2 changes: 2 additions & 0 deletions frontend/src/store.ts
Expand Up @@ -7,6 +7,7 @@ import commandReducer from "./state/commandSlice";
import errorsReducer from "./state/errorsSlice";
import planReducer from "./state/planSlice";
import taskReducer from "./state/taskSlice";
import jupyterReducer from "./state/jupyterSlice";

export const rootReducer = combineReducers({
browser: browserReducer,
Expand All @@ -17,6 +18,7 @@ export const rootReducer = combineReducers({
errors: errorsReducer,
plan: planReducer,
agent: agentReducer,
jupyter: jupyterReducer,
});

const store = configureStore({
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/types/TabOption.tsx
Expand Up @@ -2,10 +2,20 @@ enum TabOption {
PLANNER = "planner",
CODE = "code",
BROWSER = "browser",
JUPYTER = "jupyter",
}

type TabType = TabOption.PLANNER | TabOption.CODE | TabOption.BROWSER;
type TabType =
| TabOption.PLANNER
| TabOption.CODE
| TabOption.BROWSER
| TabOption.JUPYTER;

const AllTabs = [TabOption.CODE, TabOption.BROWSER, TabOption.PLANNER];
const AllTabs = [
TabOption.CODE,
TabOption.BROWSER,
TabOption.PLANNER,
TabOption.JUPYTER,
];

export { AllTabs, TabOption, type TabType };
3 changes: 1 addition & 2 deletions opendevin/sandbox/plugins/jupyter/execute_server
Expand Up @@ -187,8 +187,7 @@ class JupyterKernel:
outputs.append(msg['content']['data']['text/plain'])
if 'image/png' in msg['content']['data']:
# use markdone to display image (in case of large image)
# outputs.append(f"\n<img src=\'data:image/png;base64,{msg['content']['data']['image/png']}\'/>\n")
outputs.append(f"![image](data:image/png;base64,{msg['content']['data']['image/png']})")
outputs.append(f"\n![image](data:image/png;base64,{msg['content']['data']['image/png']})\n")

elif msg_type == 'execute_reply':
execution_done = True
Expand Down