Compare commits

...

11 Commits

Author SHA1 Message Date
tofarr 1a3354404e Fix text wrap on context menu (#7468) 2025-03-24 16:44:04 +00:00
Ryan H. Tran 80279f9d36 Upgrade openhands-aci to 0.2.7 (#7462) 2025-03-25 00:15:59 +08:00
Zach 0b3d15a4d7 Fix missing 'fi' statement in GAIA benchmark scripts/run_infer.sh (#7465) 2025-03-24 16:04:25 +00:00
Marco Dalalba 8b68d086f0 fix #7267: adding base url to axios (#7267) 2025-03-24 09:25:52 -04:00
Engel Nyst 0f143a43c9 Add support for .openhands/setup.sh script in all entry points (#7459)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-03-24 13:37:08 +01:00
Engel Nyst e61e4d57d9 Fix #7451: Add guidance to use git add . in system prompt (#7458)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
Co-authored-by: Robert Brennan <accounts@rbren.io>
2025-03-24 13:33:45 +01:00
Xingyao Wang 4e86bdf3d9 (frontend): Implement BrowseInteractiveAction in frontend (#7452)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-03-23 22:17:56 -04:00
Robert Brennan 3cef499b81 Fix conversation list: remove GitHub link and show created_at date (#7435)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-03-23 20:08:02 -06:00
Xingyao Wang e2a0884ecd Update repo.md to remind the agent about PR template (#7456) 2025-03-24 02:03:56 +00:00
Robert Brennan 2849974729 [WIP] better code display (#7453)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-03-23 18:10:07 -07:00
Kento Sugita daa4af18d1 fix timeout to impove stability (#7443) 2025-03-23 15:06:05 -07:00
31 changed files with 188 additions and 92 deletions
+5
View File
@@ -41,3 +41,8 @@ Frontend:
- Available variables: VITE_BACKEND_HOST, VITE_USE_TLS, VITE_INSECURE_SKIP_VERIFY, VITE_FRONTEND_PORT
- Internationalization:
- Generate i18n declaration file: `npm run make-i18n`
## Template for Github Pull Request
If you are starting a pull request (PR), please follow the template in `.github/pull_request_template.md`.
+1 -1
View File
@@ -57,7 +57,7 @@ docker run -it --rm --pull=always \
```
> [!WARNING]
> On a public network? See our [Hardened Docker Installation](https://docs.all-hands.dev/modules/usage/runtimes/docker#hardened-docker-installation) guide
> On a public network? See our [Hardened Docker Installation](https://docs.all-hands.dev/modules/usage/runtimes/docker#hardened-docker-installation) guide
> to secure your deployment by restricting network binding and implementing additional security measures.
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000)!
+1 -1
View File
@@ -21,4 +21,4 @@ OpenHands supports several different runtime environments:
- [OpenHands Remote Runtime](./runtimes/remote.md) - Cloud-based runtime for parallel execution (beta)
- [Modal Runtime](./runtimes/modal.md) - Runtime provided by our partners at Modal
- [Daytona Runtime](./runtimes/daytona.md) - Runtime provided by Daytona
- [Local Runtime](./runtimes/local.md) - Direct execution on your local machine without Docker
- [Local Runtime](./runtimes/local.md) - Direct execution on your local machine without Docker
+1 -1
View File
@@ -29,4 +29,4 @@ bash -i <(curl -sL https://get.daytona.io/openhands)
Once executed, OpenHands should be running locally and ready for use.
For more details and manual initialization, view the entire [README.md](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/impl/daytona/README.md)
For more details and manual initialization, view the entire [README.md](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/impl/daytona/README.md)
+1 -1
View File
@@ -59,4 +59,4 @@ The Local Runtime is particularly useful for:
- CI/CD pipelines where Docker is not available.
- Testing and development of OpenHands itself.
- Environments where container usage is restricted.
- Scenarios where direct file system access is required.
- Scenarios where direct file system access is required.
+1 -1
View File
@@ -10,4 +10,4 @@ docker run # ...
-e RUNTIME=modal \
-e MODAL_API_TOKEN_ID="your-id" \
-e MODAL_API_TOKEN_SECRET="your-secret" \
```
```
+1 -1
View File
@@ -3,4 +3,4 @@
OpenHands Remote Runtime is currently in beta (read [here](https://runtime.all-hands.dev/) for more details), it allows you to launch runtimes in parallel in the cloud.
Fill out [this form](https://docs.google.com/forms/d/e/1FAIpQLSckVz_JFwg2_mOxNZjCtr7aoBFI2Mwdan3f75J_TrdMS1JV2g/viewform) to apply if you want to try this out!
NOTE: This runtime is specifically designed for agent evaluation purposes only through [OpenHands evaluation harness](https://github.com/All-Hands-AI/OpenHands/tree/main/evaluation). It should not be used to launch production OpenHands applications.
NOTE: This runtime is specifically designed for agent evaluation purposes only through [OpenHands evaluation harness](https://github.com/All-Hands-AI/OpenHands/tree/main/evaluation). It should not be used to launch production OpenHands applications.
@@ -53,6 +53,7 @@ fi
if [ -n "$AGENT_CONFIG" ]; then
echo "AGENT_CONFIG: $AGENT_CONFIG"
COMMAND="$COMMAND --agent-config $AGENT_CONFIG"
fi
# Run the command
eval $COMMAND
@@ -9,67 +9,67 @@ describe("formatTimeDelta", () => {
it("formats the yearly time correctly", () => {
const oneYearAgo = new Date("2023-01-01T00:00:00Z");
expect(formatTimeDelta(oneYearAgo)).toBe("1 year");
expect(formatTimeDelta(oneYearAgo)).toBe("1y");
const twoYearsAgo = new Date("2022-01-01T00:00:00Z");
expect(formatTimeDelta(twoYearsAgo)).toBe("2 years");
expect(formatTimeDelta(twoYearsAgo)).toBe("2y");
const threeYearsAgo = new Date("2021-01-01T00:00:00Z");
expect(formatTimeDelta(threeYearsAgo)).toBe("3 years");
expect(formatTimeDelta(threeYearsAgo)).toBe("3y");
});
it("formats the monthly time correctly", () => {
const oneMonthAgo = new Date("2023-12-01T00:00:00Z");
expect(formatTimeDelta(oneMonthAgo)).toBe("1 month");
expect(formatTimeDelta(oneMonthAgo)).toBe("1mo");
const twoMonthsAgo = new Date("2023-11-01T00:00:00Z");
expect(formatTimeDelta(twoMonthsAgo)).toBe("2 months");
expect(formatTimeDelta(twoMonthsAgo)).toBe("2mo");
const threeMonthsAgo = new Date("2023-10-01T00:00:00Z");
expect(formatTimeDelta(threeMonthsAgo)).toBe("3 months");
expect(formatTimeDelta(threeMonthsAgo)).toBe("3mo");
});
it("formats the daily time correctly", () => {
const oneDayAgo = new Date("2023-12-31T00:00:00Z");
expect(formatTimeDelta(oneDayAgo)).toBe("1 day");
expect(formatTimeDelta(oneDayAgo)).toBe("1d");
const twoDaysAgo = new Date("2023-12-30T00:00:00Z");
expect(formatTimeDelta(twoDaysAgo)).toBe("2 days");
expect(formatTimeDelta(twoDaysAgo)).toBe("2d");
const threeDaysAgo = new Date("2023-12-29T00:00:00Z");
expect(formatTimeDelta(threeDaysAgo)).toBe("3 days");
expect(formatTimeDelta(threeDaysAgo)).toBe("3d");
});
it("formats the hourly time correctly", () => {
const oneHourAgo = new Date("2023-12-31T23:00:00Z");
expect(formatTimeDelta(oneHourAgo)).toBe("1 hour");
expect(formatTimeDelta(oneHourAgo)).toBe("1h");
const twoHoursAgo = new Date("2023-12-31T22:00:00Z");
expect(formatTimeDelta(twoHoursAgo)).toBe("2 hours");
expect(formatTimeDelta(twoHoursAgo)).toBe("2h");
const threeHoursAgo = new Date("2023-12-31T21:00:00Z");
expect(formatTimeDelta(threeHoursAgo)).toBe("3 hours");
expect(formatTimeDelta(threeHoursAgo)).toBe("3h");
});
it("formats the minute time correctly", () => {
const oneMinuteAgo = new Date("2023-12-31T23:59:00Z");
expect(formatTimeDelta(oneMinuteAgo)).toBe("1 minute");
expect(formatTimeDelta(oneMinuteAgo)).toBe("1m");
const twoMinutesAgo = new Date("2023-12-31T23:58:00Z");
expect(formatTimeDelta(twoMinutesAgo)).toBe("2 minutes");
expect(formatTimeDelta(twoMinutesAgo)).toBe("2m");
const threeMinutesAgo = new Date("2023-12-31T23:57:00Z");
expect(formatTimeDelta(threeMinutesAgo)).toBe("3 minutes");
expect(formatTimeDelta(threeMinutesAgo)).toBe("3m");
});
it("formats the second time correctly", () => {
const oneSecondAgo = new Date("2023-12-31T23:59:59Z");
expect(formatTimeDelta(oneSecondAgo)).toBe("1 second");
expect(formatTimeDelta(oneSecondAgo)).toBe("1s");
const twoSecondsAgo = new Date("2023-12-31T23:59:58Z");
expect(formatTimeDelta(twoSecondsAgo)).toBe("2 seconds");
expect(formatTimeDelta(twoSecondsAgo)).toBe("2s");
const threeSecondsAgo = new Date("2023-12-31T23:59:57Z");
expect(formatTimeDelta(threeSecondsAgo)).toBe("3 seconds");
expect(formatTimeDelta(threeSecondsAgo)).toBe("3s");
});
});
+3 -2
View File
@@ -1,7 +1,8 @@
import axios from "axios";
export const openHands = axios.create();
export const openHands = axios.create({
baseURL: `${window.location.protocol}//${import.meta.env.VITE_BACKEND_BASE_URL || window?.location.host}`,
});
export const setAuthTokenHeader = (token: string) => {
openHands.defaults.headers.common.Authorization = `Bearer ${token}`;
};
@@ -20,7 +20,7 @@ export function ContextMenuListItem({
disabled={isDisabled}
className={cn(
"text-sm px-4 py-2 w-full text-start hover:bg-white/10 first-of-type:rounded-t-md last-of-type:rounded-b-md",
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent",
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent text-nowrap",
)}
>
{children}
@@ -18,7 +18,7 @@ export function ContextMenu({
<ul
data-testid={testId}
ref={ref}
className={cn("bg-tertiary rounded-md w-[140px]", className)}
className={cn("bg-tertiary rounded-md", className)}
>
{children}
</ul>
@@ -22,11 +22,14 @@ interface ConversationCardProps {
title: string;
selectedRepository: string | null;
lastUpdatedAt: string; // ISO 8601
createdAt?: string; // ISO 8601
status?: ProjectStatus;
variant?: "compact" | "default";
conversationId?: string; // Optional conversation ID for VS Code URL
}
const MAX_TIME_BETWEEN_CREATION_AND_UPDATE = 1000 * 60 * 30; // 30 minutes
export function ConversationCard({
onClick,
onDelete,
@@ -35,7 +38,10 @@ export function ConversationCard({
isActive,
title,
selectedRepository,
// lastUpdatedAt is kept in props for backward compatibility
// eslint-disable-next-line @typescript-eslint/no-unused-vars
lastUpdatedAt,
createdAt,
status = "STOPPED",
variant = "default",
conversationId,
@@ -105,11 +111,10 @@ export function ConversationCard({
if (data.vscode_url) {
window.open(data.vscode_url, "_blank");
} else {
console.error("VS Code URL not available", data.error);
}
// VS Code URL not available
} catch (error) {
console.error("Failed to fetch VS Code URL", error);
// Failed to fetch VS Code URL
}
}
@@ -128,6 +133,12 @@ export function ConversationCard({
}, [titleMode]);
const hasContextMenu = !!(onDelete || onChangeTitle || showDisplayCostOption);
const timeBetweenUpdateAndCreation = createdAt
? new Date(lastUpdatedAt).getTime() - new Date(createdAt).getTime()
: 0;
const showUpdateTime =
createdAt &&
timeBetweenUpdateAndCreation > MAX_TIME_BETWEEN_CREATION_AND_UPDATE;
return (
<>
@@ -205,7 +216,16 @@ export function ConversationCard({
<ConversationRepoLink selectedRepository={selectedRepository} />
)}
<p className="text-xs text-neutral-400">
<time>{formatTimeDelta(new Date(lastUpdatedAt))} ago</time>
<span>Created </span>
<time>
{formatTimeDelta(new Date(createdAt || lastUpdatedAt))} ago
</time>
{showUpdateTime && (
<>
<span>, updated </span>
<time>{formatTimeDelta(new Date(lastUpdatedAt))} ago</time>
</>
)}
</p>
</div>
</div>
@@ -108,7 +108,9 @@ export function ConversationPanel({ onClose }: ConversationPanelProps) {
title={project.title}
selectedRepository={project.selected_repository}
lastUpdatedAt={project.last_updated_at}
createdAt={project.created_at}
status={project.status}
conversationId={project.conversation_id}
/>
)}
</NavLink>
@@ -5,23 +5,12 @@ interface ConversationRepoLinkProps {
export function ConversationRepoLink({
selectedRepository,
}: ConversationRepoLinkProps) {
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
window.open(
`https://github.com/${selectedRepository}`,
"_blank",
"noopener,noreferrer",
);
};
return (
<button
type="button"
<span
data-testid="conversation-card-selected-repository"
onClick={handleClick}
className="text-xs text-neutral-400 hover:text-neutral-200"
className="text-xs text-neutral-400"
>
{selectedRepository}
</button>
</span>
);
}
+1
View File
@@ -281,6 +281,7 @@ export enum I18nKey {
ACTION_MESSAGE$EDIT = "ACTION_MESSAGE$EDIT",
ACTION_MESSAGE$WRITE = "ACTION_MESSAGE$WRITE",
ACTION_MESSAGE$BROWSE = "ACTION_MESSAGE$BROWSE",
ACTION_MESSAGE$BROWSE_INTERACTIVE = "ACTION_MESSAGE$BROWSE_INTERACTIVE",
ACTION_MESSAGE$THINK = "ACTION_MESSAGE$THINK",
OBSERVATION_MESSAGE$RUN = "OBSERVATION_MESSAGE$RUN",
OBSERVATION_MESSAGE$RUN_IPYTHON = "OBSERVATION_MESSAGE$RUN_IPYTHON",
+15
View File
@@ -4193,6 +4193,21 @@
"es": "Navegando en la web",
"tr": "Web'de geziniyor"
},
"ACTION_MESSAGE$BROWSE_INTERACTIVE": {
"en": "Interactive browsing in progress...",
"zh-CN": "交互式浏览进行中...",
"zh-TW": "互動式瀏覽進行中...",
"ko-KR": "인터랙티브 브라우징 진행 중...",
"ja": "インタラクティブブラウジング進行中...",
"no": "Interaktiv surfing pågår...",
"ar": "التصفح التفاعلي قيد التقدم...",
"de": "Interaktives Browsen läuft...",
"fr": "Navigation interactive en cours...",
"it": "Navigazione interattiva in corso...",
"pt": "Navegação interativa em andamento...",
"es": "Navegación interactiva en progreso...",
"tr": "Etkileşimli tarama devam ediyor..."
},
"ACTION_MESSAGE$THINK": {
"en": "Thinking",
"zh-CN": "思考",
+4 -6
View File
@@ -78,20 +78,18 @@ function FileViewer() {
<div className="flex h-full bg-base-secondary relative">
<FileExplorer isOpen={fileExplorerIsOpen} onToggle={toggleFileExplorer} />
<div className="w-full h-full flex flex-col">
{selectedPath && (
<div className="flex w-full items-center justify-between self-end p-2">
<span className="text-sm text-neutral-500">{selectedPath}</span>
</div>
)}
{selectedPath && files[selectedPath] && (
<div className="p-4 flex-1 overflow-auto">
<div className="h-full w-full overflow-auto">
<SyntaxHighlighter
language={getLanguageFromPath(selectedPath)}
style={vscDarkPlus}
customStyle={{
margin: 0,
padding: "10px",
height: "100%",
background: "#171717",
fontSize: "0.875rem",
borderRadius: 0,
}}
>
{files[selectedPath]}
+41
View File
@@ -30,6 +30,7 @@ export function handleObservationMessage(message: ObservationMessage) {
store.dispatch(appendJupyterOutput(message.content));
break;
case ObservationType.BROWSE:
case ObservationType.BROWSE_INTERACTIVE:
if (message.extras?.screenshot) {
store.dispatch(setScreenshotSrc(message.extras?.screenshot));
}
@@ -178,6 +179,46 @@ export function handleObservationMessage(message: ObservationMessage) {
}),
);
break;
case "browse_interactive":
store.dispatch(
addAssistantObservation({
...baseObservation,
observation: "browse_interactive" as const,
extras: {
url: String(message.extras.url || ""),
screenshot: String(message.extras.screenshot || ""),
error: Boolean(message.extras.error),
open_page_urls: Array.isArray(message.extras.open_page_urls)
? message.extras.open_page_urls
: [],
active_page_index: Number(message.extras.active_page_index || 0),
dom_object:
typeof message.extras.dom_object === "object"
? (message.extras.dom_object as Record<string, unknown>)
: {},
axtree_object:
typeof message.extras.axtree_object === "object"
? (message.extras.axtree_object as Record<string, unknown>)
: {},
extra_element_properties:
typeof message.extras.extra_element_properties === "object"
? (message.extras.extra_element_properties as Record<
string,
unknown
>)
: {},
last_browser_action: String(
message.extras.last_browser_action || "",
),
last_browser_action_error:
message.extras.last_browser_action_error,
focused_element_bid: String(
message.extras.focused_element_bid || "",
),
},
}),
);
break;
case "error":
store.dispatch(
addAssistantObservation({
+8 -3
View File
@@ -20,6 +20,7 @@ const HANDLED_ACTIONS: OpenHandsEventType[] = [
"write",
"read",
"browse",
"browse_interactive",
"edit",
];
@@ -108,6 +109,9 @@ export const chatSlice = createSlice({
text = `${action.payload.args.path}\n${content}`;
} else if (actionID === "browse") {
text = `Browsing ${action.payload.args.url}`;
} else if (actionID === "browse_interactive") {
// Include the browser_actions in the content
text = `**Action:**\n\n\`\`\`python\n${action.payload.args.browser_actions}\n\`\`\``;
}
if (actionID === "run" || actionID === "run_ipython") {
if (
@@ -127,6 +131,7 @@ export const chatSlice = createSlice({
imageUrls: [],
timestamp: new Date().toISOString(),
};
state.messages.push(message);
},
@@ -191,11 +196,11 @@ export const chatSlice = createSlice({
} else if (observationID === "browse") {
let content = `**URL:** ${observation.payload.extras.url}\n`;
if (observation.payload.extras.error) {
content += `**Error:**\n${observation.payload.extras.error}\n`;
content += `\n\n**Error:**\n${observation.payload.extras.error}\n`;
}
content += `**Output:**\n${observation.payload.content}`;
content += `\n\n**Output:**\n${observation.payload.content}`;
if (content.length > MAX_CONTENT_LENGTH) {
content = `${content.slice(0, MAX_CONTENT_LENGTH)}...`;
content = `${content.slice(0, MAX_CONTENT_LENGTH)}...(truncated)`;
}
causeMessage.content = content;
}
+19
View File
@@ -51,6 +51,24 @@ export interface BrowseObservation extends OpenHandsObservationEvent<"browse"> {
};
}
export interface BrowseInteractiveObservation
extends OpenHandsObservationEvent<"browse_interactive"> {
source: "agent";
extras: {
url: string;
screenshot: string;
error: boolean;
open_page_urls: string[];
active_page_index: number;
dom_object: Record<string, unknown>;
axtree_object: Record<string, unknown>;
extra_element_properties: Record<string, unknown>;
last_browser_action: string;
last_browser_action_error: unknown;
focused_element_bid: string;
};
}
export interface WriteObservation extends OpenHandsObservationEvent<"write"> {
source: "agent";
extras: {
@@ -98,6 +116,7 @@ export type OpenHandsObservation =
| IPythonObservation
| DelegateObservation
| BrowseObservation
| BrowseInteractiveObservation
| WriteObservation
| ReadObservation
| EditObservation
+3
View File
@@ -8,6 +8,9 @@ enum ObservationType {
// The HTML contents of a URL
BROWSE = "browse",
// Interactive browsing
BROWSE_INTERACTIVE = "browse_interactive",
// The output of a command
RUN = "run",
+10 -11
View File
@@ -1,12 +1,12 @@
/**
* Formats a date into a human-readable string representing the time delta between the given date and the current date.
* Formats a date into a compact string representing the time delta between the given date and the current date.
* @param date The date to format
* @returns A human-readable string representing the time delta between the given date and the current date
* @returns A compact string representing the time delta between the given date and the current date
*
* @example
* // now is 2024-01-01T00:00:00Z
* formatTimeDelta(new Date("2023-12-31T23:59:59Z")); // "1 second"
* formatTimeDelta(new Date("2022-01-01T00:00:00Z")); // "2 years"
* formatTimeDelta(new Date("2023-12-31T23:59:59Z")); // "1s"
* formatTimeDelta(new Date("2022-01-01T00:00:00Z")); // "2y"
*/
export const formatTimeDelta = (date: Date) => {
const now = new Date();
@@ -19,11 +19,10 @@ export const formatTimeDelta = (date: Date) => {
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);
if (seconds < 60) return seconds === 1 ? "1 second" : `${seconds} seconds`;
if (minutes < 60) return minutes === 1 ? "1 minute" : `${minutes} minutes`;
if (hours < 24) return hours === 1 ? "1 hour" : `${hours} hours`;
if (days < 30) return days === 1 ? "1 day" : `${days} days`;
if (months < 12) return months === 1 ? "1 month" : `${months} months`;
return years === 1 ? "1 year" : `${years} years`;
if (seconds < 60) return `${seconds}s`;
if (minutes < 60) return `${minutes}m`;
if (hours < 24) return `${hours}h`;
if (days < 30) return `${days}d`;
if (months < 12) return `${months}mo`;
return `${years}y`;
};
@@ -26,6 +26,7 @@ Your primary role is to assist users by executing commands, modifying code, and
<VERSION_CONTROL>
* When configuring git credentials, use "openhands" as the user.name and "openhands@all-hands.dev" as the user.email by default, unless explicitly instructed otherwise.
* Exercise caution with git operations. Do NOT make potentially dangerous changes (e.g., pushing to main, deleting repositories) unless explicitly asked to do so.
* When committing changes, use `git status` to see all modified files, and stage all files necessary for the commit. Use `git commit -a` whenever possible.
</VERSION_CONTROL>
<PROBLEM_SOLVING_WORKFLOW>
+2
View File
@@ -122,6 +122,8 @@ def initialize_repository_for_runtime(
selected_repository,
None,
)
# Run setup script if it exists
runtime.maybe_run_setup_script()
return repo_directory
+1 -1
View File
@@ -238,7 +238,7 @@ class ActionExecutor:
await wait_all(
(self._init_plugin(plugin) for plugin in self.plugins_to_load),
timeout=30,
timeout=60,
)
logger.debug('All plugins initialized')
@@ -60,7 +60,7 @@ class ActionExecutionClient(Runtime):
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
):
self.session = HttpSession()
self.action_semaphore = threading.Semaphore(1) # Ensure one action at a time
@@ -1,4 +1,3 @@
from types import MappingProxyType
from pydantic import Field
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
@@ -16,4 +15,4 @@ class ConversationInitData(Settings):
model_config = {
'arbitrary_types_allowed': True,
}
}
-1
View File
@@ -23,7 +23,6 @@ from openhands.events.observation import (
from openhands.events.observation.error import ErrorObservation
from openhands.events.serialization import event_from_dict, event_to_dict
from openhands.events.stream import EventStreamSubscriber
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.llm.llm import LLM
from openhands.server.session.agent_session import AgentSession
from openhands.server.session.conversation_init_data import ConversationInitData
Generated
+16 -20
View File
@@ -4943,18 +4943,20 @@ realtime = ["websockets (>=13,<15)"]
[[package]]
name = "openhands-aci"
version = "0.2.6"
version = "0.2.7"
description = "An Agent-Computer Interface (ACI) designed for software development agents OpenHands."
optional = false
python-versions = "^3.12"
python-versions = "<4.0,>=3.12"
groups = ["main"]
files = []
develop = false
files = [
{file = "openhands_aci-0.2.7-py3-none-any.whl", hash = "sha256:6b36fa465db6643d909efdf40ec303d27a03e6c9f568447df4bc1d9fdd7104b2"},
{file = "openhands_aci-0.2.7.tar.gz", hash = "sha256:892c33d741e94b78ec65df178afe018869e6039ea484f7f232ee8c1bb4e440ef"},
]
[package.dependencies]
binaryornot = "^0.4.4"
cachetools = "^5.5.2"
chardet = "^5.0.0"
binaryornot = ">=0.4.4,<0.5.0"
cachetools = ">=5.5.2,<6.0.0"
charset-normalizer = ">=3.4.1,<4.0.0"
flake8 = "*"
gitpython = "*"
grep-ast = "0.3.3"
@@ -4963,18 +4965,12 @@ networkx = "*"
numpy = "*"
pandas = "*"
scipy = "*"
tree-sitter = "^0.24.0"
tree-sitter-javascript = "^0.23.1"
tree-sitter-python = "^0.23.6"
tree-sitter-ruby = "^0.23.1"
tree-sitter-typescript = "^0.23.2"
whatthepatch = "^1.0.6"
[package.source]
type = "git"
url = "https://github.com/All-Hands-AI/openhands-aci.git"
reference = "add-encoding-detection"
resolved_reference = "040d9578d90894409f51ecca877b120fe696fe0b"
tree-sitter = ">=0.24.0,<0.25.0"
tree-sitter-javascript = ">=0.23.1,<0.24.0"
tree-sitter-python = ">=0.23.6,<0.24.0"
tree-sitter-ruby = ">=0.23.1,<0.24.0"
tree-sitter-typescript = ">=0.23.2,<0.24.0"
whatthepatch = ">=1.0.6,<2.0.0"
[[package]]
name = "opentelemetry-api"
@@ -9316,4 +9312,4 @@ testing = ["coverage[toml]", "zope.event", "zope.testing"]
[metadata]
lock-version = "2.1"
python-versions = "^3.12"
content-hash = "d3ec6b8a6c7e48420d76b7e17d5f1a3f253fa603205f90d4a8e4a614ab5e2c67"
content-hash = "7c5c7d26747d7b42a1a7bbdc3b7e4d87bbbef851f3c51a022bf7a15082273e5a"
+1 -1
View File
@@ -67,7 +67,7 @@ runloop-api-client = "0.26.0"
libtmux = ">=0.37,<0.40"
pygithub = "^2.5.0"
joblib = "*"
openhands-aci = "^0.2.6"
openhands-aci = "^0.2.7"
python-socketio = "^5.11.4"
redis = "^5.2.0"
sse-starlette = "^2.1.3"