diff --git a/frontend/.eslintrc b/frontend/.eslintrc
index c0b7a8c9be..d5cb543bd7 100644
--- a/frontend/.eslintrc
+++ b/frontend/.eslintrc
@@ -84,4 +84,4 @@
}
}
]
-}
\ No newline at end of file
+}
diff --git a/frontend/.gitignore b/frontend/.gitignore
index 44029f58cb..471b78551b 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -1,4 +1,4 @@
# i18n translation files make by script using `make build`
public/locales/**/*
src/i18n/declaration.ts
-.env
\ No newline at end of file
+.env
diff --git a/frontend/src/assets/arrow-send.svg b/frontend/src/assets/arrow-send.svg
index b353657406..a42795073c 100644
--- a/frontend/src/assets/arrow-send.svg
+++ b/frontend/src/assets/arrow-send.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/branding/all-hands-logo-spark.svg b/frontend/src/assets/branding/all-hands-logo-spark.svg
index 439dff9778..bb4070944a 100644
--- a/frontend/src/assets/branding/all-hands-logo-spark.svg
+++ b/frontend/src/assets/branding/all-hands-logo-spark.svg
@@ -32,4 +32,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/branding/github-logo.svg b/frontend/src/assets/branding/github-logo.svg
index 975e5fa3ca..fcf918efac 100644
--- a/frontend/src/assets/branding/github-logo.svg
+++ b/frontend/src/assets/branding/github-logo.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/clip.svg b/frontend/src/assets/clip.svg
index aaebcbc4df..26a6acb485 100644
--- a/frontend/src/assets/clip.svg
+++ b/frontend/src/assets/clip.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/clipboard.svg b/frontend/src/assets/clipboard.svg
index 6da359d380..abf4e5a315 100644
--- a/frontend/src/assets/clipboard.svg
+++ b/frontend/src/assets/clipboard.svg
@@ -32,4 +32,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/default-user.svg b/frontend/src/assets/default-user.svg
index b67e64cf78..620ab2f3f9 100644
--- a/frontend/src/assets/default-user.svg
+++ b/frontend/src/assets/default-user.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/docs.svg b/frontend/src/assets/docs.svg
index 23475a3da1..33eb3a374c 100644
--- a/frontend/src/assets/docs.svg
+++ b/frontend/src/assets/docs.svg
@@ -24,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/external-link.svg b/frontend/src/assets/external-link.svg
index 96294735b2..e554116711 100644
--- a/frontend/src/assets/external-link.svg
+++ b/frontend/src/assets/external-link.svg
@@ -4,4 +4,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/lightbulb.svg b/frontend/src/assets/lightbulb.svg
index 9f61d275ef..aa703e60ab 100644
--- a/frontend/src/assets/lightbulb.svg
+++ b/frontend/src/assets/lightbulb.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/loading-outer.svg b/frontend/src/assets/loading-outer.svg
index da669d7da4..aebe42c8e5 100644
--- a/frontend/src/assets/loading-outer.svg
+++ b/frontend/src/assets/loading-outer.svg
@@ -1,4 +1,4 @@
\ No newline at end of file
+
diff --git a/frontend/src/assets/message.svg b/frontend/src/assets/message.svg
index cf1e6fc409..3bf0a6e3e2 100644
--- a/frontend/src/assets/message.svg
+++ b/frontend/src/assets/message.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/new-project.svg b/frontend/src/assets/new-project.svg
index e7573f625a..550d656e35 100644
--- a/frontend/src/assets/new-project.svg
+++ b/frontend/src/assets/new-project.svg
@@ -3,4 +3,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/refresh.svg b/frontend/src/assets/refresh.svg
index ae9e2bac38..4bba1daa1a 100644
--- a/frontend/src/assets/refresh.svg
+++ b/frontend/src/assets/refresh.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/thumbs-down.svg b/frontend/src/assets/thumbs-down.svg
index 08394d2034..971681051c 100644
--- a/frontend/src/assets/thumbs-down.svg
+++ b/frontend/src/assets/thumbs-down.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/assets/thumbs-up.svg b/frontend/src/assets/thumbs-up.svg
index d5d55d7af9..90f8e0cc49 100644
--- a/frontend/src/assets/thumbs-up.svg
+++ b/frontend/src/assets/thumbs-up.svg
@@ -2,4 +2,4 @@
-
\ No newline at end of file
+
diff --git a/frontend/src/utils/suggestions/non-repo-suggestions.ts b/frontend/src/utils/suggestions/non-repo-suggestions.ts
index da7207dc78..d9cf04992a 100644
--- a/frontend/src/utils/suggestions/non-repo-suggestions.ts
+++ b/frontend/src/utils/suggestions/non-repo-suggestions.ts
@@ -1,6 +1,6 @@
const KEY_1 = "Build an app to view pull requests";
-const VALUE_1 = `I want to create a React app to view all of the open pull
-requests that exist on all of my team's github repos. Here
+const VALUE_1 = `I want to create a React app to view all of the open pull
+requests that exist on all of my team's github repos. Here
are some details:
1. Please initialize the app using vite and react-ts.
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index be5fe7a7cd..dcd184186d 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -39,4 +39,4 @@
// Vite takes care of building everything, not tsc.
"noEmit": true
}
-}
\ No newline at end of file
+}
diff --git a/openhands/runtime/plugins/agent_skills/file_ops/file_ops.py b/openhands/runtime/plugins/agent_skills/file_ops/file_ops.py
index e30cdd78fd..7632d154b7 100644
--- a/openhands/runtime/plugins/agent_skills/file_ops/file_ops.py
+++ b/openhands/runtime/plugins/agent_skills/file_ops/file_ops.py
@@ -696,9 +696,33 @@ def edit_file_by_replace(file_name: str, to_replace: str, new_content: str) -> N
_output_error(f'File {file_name} not found.')
return None
- # search for `to_replace` in the file
- # if found, replace it with `new_content`
- # if not found, perform a fuzzy search to find the closest match and replace it with `new_content`
+ # Preserve the original file permissions
+ original_permissions = os.stat(file_name).st_mode
+
+ try:
+ # search for `to_replace` in the file
+ # if found, replace it with `new_content`
+ # if not found, perform a fuzzy search to find the closest match and replace it with `new_content`
+ with open(file_name, 'r') as file:
+ content = file.read()
+
+ if to_replace in content:
+ new_content = content.replace(to_replace, new_content)
+ with open(file_name, 'w') as file:
+ file.write(new_content)
+ else:
+ _output_error(f'Content to replace not found in {file_name}.')
+ return None
+
+ except Exception as e:
+ _output_error(f'An error occurred while editing the file: {str(e)}')
+ return None
+
+ finally:
+ # Restore the original file permissions
+ os.chmod(file_name, original_permissions)
+
+ return _edit_file_impl(file_name, content=new_content)
with open(file_name, 'r') as file:
file_content = file.read()
diff --git a/openhands/security/invariant/analyzer.py b/openhands/security/invariant/analyzer.py
index ed32325d7c..644740ea90 100644
--- a/openhands/security/invariant/analyzer.py
+++ b/openhands/security/invariant/analyzer.py
@@ -146,7 +146,9 @@ class InvariantAnalyzer(SecurityAnalyzer):
{'action': 'change_agent_state', 'args': {'agent_state': 'user_confirmed'}}
)
event_source = event.source if event.source else EventSource.AGENT
- await asyncio.get_event_loop().run_in_executor(None, self.event_stream.add_event, new_event, event_source)
+ await asyncio.get_event_loop().run_in_executor(
+ None, self.event_stream.add_event, new_event, event_source
+ )
async def security_risk(self, event: Action) -> ActionSecurityRisk:
logger.info('Calling security_risk on InvariantAnalyzer')
diff --git a/pyproject.toml b/pyproject.toml
index af07e270c6..8ca6219b8b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ packages = [
]
[tool.poetry.dependencies]
-python = "^3.12"
+python = "^3.11"
datasets = "*"
pandas = "*"
litellm = "*"