mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 04112e4a24 | |||
| 7b19ee0d5e |
@@ -26,7 +26,6 @@ Backend:
|
||||
- Located in the `openhands` directory
|
||||
- Testing:
|
||||
- All tests are in `tests/unit/test_*.py`
|
||||
- To run all the unit tests, run `poetry run pytest --forked -n auto -svv ./tests/unit`
|
||||
- To test new code, run `poetry run pytest tests/unit/test_xxx.py` where `xxx` is the appropriate file for the current functionality
|
||||
- Write all tests with pytest
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
[ ] Rename `Conversation` in openhands/server to `ServerConversation`
|
||||
[ ] Replace all instances of `sid` in openhands/* to `conversation_id`
|
||||
[ ] Make EventStream take in a `conversation_id` in its constructor.
|
||||
* remove `conversation_id` from all methods on EventStream and use self.conversation_id instead.
|
||||
* fix all callers of EventStream to pass in `conversation_id` in the constructor and remove it from the method calls.
|
||||
[ ] Rename AppConfig to OpenHandsConfig
|
||||
[ ] Create a new class `Conversation` in openhands/core/ that will be the main interface for conversations.
|
||||
* Its constructor will take in a:
|
||||
* conversation_id (string)
|
||||
* Runtime
|
||||
* LLM
|
||||
* EventStream
|
||||
* AgentController
|
||||
* No logic, it's just a dataclass
|
||||
[ ] Add a new OpenHands class to openhands/core/ which will take care of creating Conversations
|
||||
* Constructor is ONLY an OpenHandsConfig
|
||||
* Only one method: `create_conversation()`
|
||||
* This will create a Runtime, LLM, EventStream, and AgentController, and return a Conversation object.
|
||||
* These objects will be created according to the OpenHandsConfig passed in to the constructor.
|
||||
@@ -0,0 +1,84 @@
|
||||
# Using OpenHands as a library
|
||||
|
||||
|
||||
## Hello World
|
||||
```python
|
||||
import asyncio
|
||||
from openhands.core.config import OpenHandsConfig, LLMConfig, AgentConfig
|
||||
from openhands.core.setup import run_agent
|
||||
|
||||
async def run_openhands_agent():
|
||||
final_state = await run_agent(
|
||||
config=OpenHandsConfig(
|
||||
llm=LLMConfig(
|
||||
model="claude-sonnet-4-20250514",
|
||||
api_key="your_api_key_here", # Replace with your actual API key
|
||||
),
|
||||
),
|
||||
initial_user_message="Flip a coin",
|
||||
context_message="You build simple programs and run them.",
|
||||
)
|
||||
|
||||
return final_state
|
||||
|
||||
# Run the async function
|
||||
if __name__ == "__main__":
|
||||
final_state = asyncio.run(run_openhands_agent())
|
||||
print("Agent execution completed!")
|
||||
```
|
||||
|
||||
## Using the internals
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import OpenHandsConfig, LLMConfig, AgentConfig
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.core.setup import (
|
||||
create_runtime,
|
||||
create_memory,
|
||||
generate_sid,
|
||||
)
|
||||
from openhands.core.main import run_controller
|
||||
|
||||
async def run_openhands_agent():
|
||||
config = OpenHandsConfig(
|
||||
runtime="local",
|
||||
file_store="memory",
|
||||
llm=LLMConfig(
|
||||
model="claude-sonnet-4-20250514", # Choose your preferred model
|
||||
api_key="your_api_key_here", # Replace with your actual API key
|
||||
temperature=0.0, # Set temperature to 0 for deterministic output
|
||||
),
|
||||
agent=AgentConfig(
|
||||
enable_browsing=False,
|
||||
),
|
||||
)
|
||||
|
||||
oh = OpenHands(config=config)
|
||||
|
||||
conversation = oh.create_conversation(
|
||||
conversation_id='hello-world',
|
||||
)
|
||||
await conversation.runtime.connect()
|
||||
|
||||
def on_event(event: Event) -> None:
|
||||
print(f"Event received: {event}")
|
||||
conversation.event_stream.subscribe(EventStreamSubscriber.MAIN, on_event)
|
||||
|
||||
initial_user_action = MessageAction(content="Flip a coin")
|
||||
conversation.event_stream.add_event(initial_user_action, EventSource.USER)
|
||||
|
||||
while conversation.state.agent_state not in end_states:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
await runtime.close()
|
||||
|
||||
return conversation.state
|
||||
|
||||
# Run the async function
|
||||
if __name__ == "__main__":
|
||||
final_state = asyncio.run(run_openhands_agent())
|
||||
print("Agent execution completed!")
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"items": ["python/python"],
|
||||
"items": ["python/python", "python/using-openhands-as-library"],
|
||||
"label": "Backend",
|
||||
"type": "category"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
# Using OpenHands as a Library
|
||||
|
||||
OpenHands can be used as a Python library in your own applications. This guide will show you how to integrate OpenHands into your Python projects, allowing you to build custom applications that leverage OpenHands' powerful agent capabilities.
|
||||
|
||||
## Installation
|
||||
|
||||
First, install the OpenHands library from PyPI:
|
||||
|
||||
```bash
|
||||
pip install openhands-ai
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Here's a simple example of how to use OpenHands in your Python code:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import AppConfig, LLMConfig, AgentConfig
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.core.setup import (
|
||||
create_runtime,
|
||||
create_memory,
|
||||
generate_sid,
|
||||
)
|
||||
from openhands.core.main import run_controller
|
||||
|
||||
async def run_openhands_agent():
|
||||
# 1. Create configuration
|
||||
config = AppConfig(
|
||||
runtime="local", # Use local runtime
|
||||
file_store="memory", # Store events in memory
|
||||
)
|
||||
|
||||
# 2. Configure LLM
|
||||
llm_config = LLMConfig(
|
||||
model="claude-sonnet-4-20250514", # Choose your preferred model
|
||||
api_key="your_api_key_here", # Replace with your actual API key
|
||||
temperature=0.0,
|
||||
)
|
||||
config.set_llm_config(llm_config)
|
||||
|
||||
# 3. Configure Agent
|
||||
agent_config = AgentConfig(
|
||||
enable_browsing=False, # Disable browsing for this example
|
||||
)
|
||||
config.set_agent_config(agent_config)
|
||||
|
||||
# 4. Create Agent
|
||||
agent = Agent(
|
||||
llm=LLM(config=llm_config),
|
||||
config=agent_config,
|
||||
)
|
||||
|
||||
# 5. Generate a session ID
|
||||
sid = generate_sid(config)
|
||||
|
||||
# 6. Create Runtime
|
||||
runtime = create_runtime(
|
||||
config=config,
|
||||
sid=sid,
|
||||
headless_mode=True,
|
||||
agent=agent,
|
||||
)
|
||||
|
||||
# 7. Connect to the runtime
|
||||
await runtime.connect()
|
||||
|
||||
# 8. Create Memory
|
||||
memory = create_memory(
|
||||
runtime=runtime,
|
||||
event_stream=runtime.event_stream,
|
||||
sid=sid,
|
||||
)
|
||||
|
||||
# 9. Define the initial task
|
||||
initial_user_action = MessageAction(content="Write a Python function that calculates the factorial of a number")
|
||||
|
||||
# 10. Run the agent
|
||||
final_state = await run_controller(
|
||||
config=config,
|
||||
initial_user_action=initial_user_action,
|
||||
sid=sid,
|
||||
runtime=runtime,
|
||||
agent=agent,
|
||||
memory=memory,
|
||||
headless_mode=True,
|
||||
exit_on_message=True, # Exit when the agent asks for user input
|
||||
)
|
||||
|
||||
# 11. Close the runtime
|
||||
await runtime.close()
|
||||
|
||||
return final_state
|
||||
|
||||
# Run the async function
|
||||
if __name__ == "__main__":
|
||||
final_state = asyncio.run(run_openhands_agent())
|
||||
print("Agent execution completed!")
|
||||
```
|
||||
|
||||
## Components Overview
|
||||
|
||||
### AppConfig
|
||||
|
||||
The `AppConfig` class is the main configuration object for OpenHands. It contains settings for the runtime, agent, LLM, and more.
|
||||
|
||||
```python
|
||||
from openhands.core.config import AppConfig
|
||||
|
||||
config = AppConfig(
|
||||
runtime="local", # Options: "local", "docker", "e2b", "modal", etc.
|
||||
file_store="memory", # Options: "memory", "local", etc.
|
||||
file_store_path="/path/to/store", # Only needed for "local" file_store
|
||||
max_iterations=100, # Maximum number of agent iterations
|
||||
)
|
||||
```
|
||||
|
||||
### LLMConfig
|
||||
|
||||
The `LLMConfig` class configures the language model used by the agent.
|
||||
|
||||
```python
|
||||
from openhands.core.config import LLMConfig
|
||||
|
||||
llm_config = LLMConfig(
|
||||
model="claude-sonnet-4-20250514", # Model name
|
||||
api_key="your_api_key_here", # API key
|
||||
temperature=0.0, # Temperature for generation
|
||||
max_output_tokens=4096, # Maximum tokens in the response
|
||||
)
|
||||
```
|
||||
|
||||
### AgentConfig
|
||||
|
||||
The `AgentConfig` class configures the agent's behavior and available tools.
|
||||
|
||||
```python
|
||||
from openhands.core.config import AgentConfig
|
||||
|
||||
agent_config = AgentConfig(
|
||||
enable_browsing=True, # Enable web browsing
|
||||
enable_cmd=True, # Enable bash commands
|
||||
enable_editor=True, # Enable file editing
|
||||
enable_jupyter=True, # Enable Jupyter notebook
|
||||
enable_think=True, # Enable thinking tool
|
||||
enable_finish=True, # Enable finish tool
|
||||
)
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
The `Agent` class represents the AI agent that will perform tasks.
|
||||
|
||||
```python
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.llm.llm import LLM
|
||||
|
||||
agent = Agent(
|
||||
llm=LLM(config=llm_config),
|
||||
config=agent_config,
|
||||
)
|
||||
```
|
||||
|
||||
### Runtime
|
||||
|
||||
The runtime is the environment where the agent executes commands and interacts with the system.
|
||||
|
||||
```python
|
||||
from openhands.core.setup import create_runtime
|
||||
|
||||
runtime = create_runtime(
|
||||
config=config,
|
||||
sid=sid,
|
||||
headless_mode=True,
|
||||
agent=agent,
|
||||
)
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
The memory component manages the agent's context and conversation history.
|
||||
|
||||
```python
|
||||
from openhands.core.setup import create_memory
|
||||
|
||||
memory = create_memory(
|
||||
runtime=runtime,
|
||||
event_stream=runtime.event_stream,
|
||||
sid=sid,
|
||||
)
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Custom Sandbox Configuration
|
||||
|
||||
You can customize the sandbox environment by configuring the `SandboxConfig`:
|
||||
|
||||
```python
|
||||
from openhands.core.config import SandboxConfig
|
||||
|
||||
sandbox_config = SandboxConfig(
|
||||
selected_repo="username/repo", # GitHub repository to clone
|
||||
base_image="ubuntu:22.04", # Base Docker image
|
||||
)
|
||||
config.sandbox = sandbox_config
|
||||
```
|
||||
|
||||
### Security Configuration
|
||||
|
||||
Configure security settings using the `SecurityConfig`:
|
||||
|
||||
```python
|
||||
from openhands.core.config import SecurityConfig
|
||||
|
||||
security_config = SecurityConfig(
|
||||
confirmation_mode=False, # Whether to require confirmation for actions
|
||||
security_analyzer="default", # Security analyzer to use
|
||||
)
|
||||
config.security = security_config
|
||||
```
|
||||
|
||||
### Custom Agent Response Handling
|
||||
|
||||
You can provide a custom function to handle agent responses:
|
||||
|
||||
```python
|
||||
def custom_response_handler(state):
|
||||
# Process the agent's state and generate a response
|
||||
return "Continue with your current approach"
|
||||
|
||||
final_state = await run_controller(
|
||||
config=config,
|
||||
initial_user_action=initial_user_action,
|
||||
fake_user_response_fn=custom_response_handler,
|
||||
)
|
||||
```
|
||||
|
||||
## Building a Complete Application
|
||||
|
||||
Here's an example of a more complete application that uses OpenHands to assist with code generation:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import os
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.core.config import AppConfig, LLMConfig, AgentConfig, SandboxConfig
|
||||
from openhands.events.action import MessageAction
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.core.setup import create_runtime, create_memory, generate_sid
|
||||
from openhands.core.main import run_controller
|
||||
from openhands.events import EventStreamSubscriber
|
||||
from openhands.events.observation import AgentStateChangedObservation
|
||||
from openhands.core.schema import AgentState
|
||||
|
||||
class CodeAssistant:
|
||||
def __init__(self, api_key, model="claude-sonnet-4-20250514"):
|
||||
self.api_key = api_key
|
||||
self.model = model
|
||||
self.config = None
|
||||
self.agent = None
|
||||
self.runtime = None
|
||||
self.memory = None
|
||||
self.sid = None
|
||||
self.event_stream = None
|
||||
|
||||
async def initialize(self):
|
||||
# Create configuration
|
||||
self.config = AppConfig(
|
||||
runtime="docker",
|
||||
file_store="memory",
|
||||
)
|
||||
|
||||
# Configure LLM
|
||||
llm_config = LLMConfig(
|
||||
model=self.model,
|
||||
api_key=self.api_key,
|
||||
temperature=0.0,
|
||||
)
|
||||
self.config.set_llm_config(llm_config)
|
||||
|
||||
# Configure Agent
|
||||
agent_config = AgentConfig(
|
||||
enable_browsing=True,
|
||||
enable_cmd=True,
|
||||
enable_editor=True,
|
||||
enable_jupyter=True,
|
||||
)
|
||||
self.config.set_agent_config(agent_config)
|
||||
|
||||
# Configure Sandbox
|
||||
sandbox_config = SandboxConfig(
|
||||
base_image="ubuntu:22.04",
|
||||
)
|
||||
self.config.sandbox = sandbox_config
|
||||
|
||||
# Create Agent
|
||||
self.agent = Agent(
|
||||
llm=LLM(config=llm_config),
|
||||
config=agent_config,
|
||||
)
|
||||
|
||||
# Generate a session ID
|
||||
self.sid = generate_sid(self.config)
|
||||
|
||||
# Create Runtime
|
||||
self.runtime = create_runtime(
|
||||
config=self.config,
|
||||
sid=self.sid,
|
||||
headless_mode=True,
|
||||
agent=self.agent,
|
||||
)
|
||||
|
||||
# Connect to the runtime
|
||||
await self.runtime.connect()
|
||||
|
||||
# Create Memory
|
||||
self.memory = create_memory(
|
||||
runtime=self.runtime,
|
||||
event_stream=self.runtime.event_stream,
|
||||
sid=self.sid,
|
||||
)
|
||||
|
||||
self.event_stream = self.runtime.event_stream
|
||||
|
||||
async def run_task(self, task_description, callback=None):
|
||||
# Define the initial task
|
||||
initial_user_action = MessageAction(content=task_description)
|
||||
|
||||
# Set up event callback if provided
|
||||
if callback:
|
||||
def on_event(event):
|
||||
if isinstance(event, AgentStateChangedObservation):
|
||||
callback(event)
|
||||
|
||||
self.event_stream.subscribe(
|
||||
EventStreamSubscriber.MAIN,
|
||||
on_event,
|
||||
self.sid
|
||||
)
|
||||
|
||||
# Run the agent
|
||||
final_state = await run_controller(
|
||||
config=self.config,
|
||||
initial_user_action=initial_user_action,
|
||||
sid=self.sid,
|
||||
runtime=self.runtime,
|
||||
agent=self.agent,
|
||||
memory=self.memory,
|
||||
headless_mode=True,
|
||||
exit_on_message=True,
|
||||
)
|
||||
|
||||
return final_state
|
||||
|
||||
async def close(self):
|
||||
if self.runtime:
|
||||
await self.runtime.close()
|
||||
|
||||
# Example usage
|
||||
async def main():
|
||||
# Initialize the code assistant
|
||||
assistant = CodeAssistant(api_key=os.environ.get("ANTHROPIC_API_KEY"))
|
||||
await assistant.initialize()
|
||||
|
||||
# Define a callback to process events
|
||||
def event_callback(event):
|
||||
if isinstance(event, AgentStateChangedObservation):
|
||||
print(f"Agent state changed to: {event.agent_state}")
|
||||
|
||||
# Run a task
|
||||
task = """
|
||||
Create a simple Flask API with the following endpoints:
|
||||
1. GET /users - Returns a list of users
|
||||
2. GET /users/{id} - Returns a specific user
|
||||
3. POST /users - Creates a new user
|
||||
|
||||
Use SQLite as the database and implement proper error handling.
|
||||
"""
|
||||
|
||||
final_state = await assistant.run_task(task, callback=event_callback)
|
||||
|
||||
# Close the assistant
|
||||
await assistant.close()
|
||||
|
||||
print("Task completed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Using OpenHands as a library gives you the flexibility to integrate AI agents into your own applications. You can customize the agent's behavior, runtime environment, and how it interacts with your application.
|
||||
|
||||
For more advanced usage, refer to the OpenHands source code and API documentation. The library is highly customizable and can be adapted to a wide range of use cases.
|
||||
@@ -26,6 +26,7 @@ import { downloadTrajectory } from "#/utils/download-trajectory";
|
||||
import { displayErrorToast } from "#/utils/custom-toast-handlers";
|
||||
import { useOptimisticUserMessage } from "#/hooks/use-optimistic-user-message";
|
||||
import { useWSErrorMessage } from "#/hooks/use-ws-error-message";
|
||||
import i18n from "#/i18n";
|
||||
import { ErrorMessageBanner } from "./error-message-banner";
|
||||
import { shouldRenderEvent } from "./event-content-helpers/should-render-event";
|
||||
|
||||
@@ -180,7 +181,11 @@ export function ChatInterface() {
|
||||
{!hitBottom && <ScrollToBottomButton onClick={scrollDomToBottom} />}
|
||||
</div>
|
||||
|
||||
{errorMessage && <ErrorMessageBanner message={errorMessage} />}
|
||||
{errorMessage && (
|
||||
<ErrorMessageBanner
|
||||
message={i18n.exists(errorMessage) ? t(errorMessage) : errorMessage}
|
||||
/>
|
||||
)}
|
||||
|
||||
<InteractiveChatBox
|
||||
onSubmit={handleSendMessage}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import { Trans } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
import i18n from "#/i18n";
|
||||
|
||||
interface ErrorMessageBannerProps {
|
||||
message: string;
|
||||
}
|
||||
@@ -9,23 +5,7 @@ interface ErrorMessageBannerProps {
|
||||
export function ErrorMessageBanner({ message }: ErrorMessageBannerProps) {
|
||||
return (
|
||||
<div className="w-full rounded-lg p-2 text-black border border-red-800 bg-red-500">
|
||||
{i18n.exists(message) ? (
|
||||
<Trans
|
||||
i18nKey={message}
|
||||
components={{
|
||||
a: (
|
||||
<Link
|
||||
className="underline font-bold cursor-pointer"
|
||||
to="/settings/billing"
|
||||
>
|
||||
link
|
||||
</Link>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
message
|
||||
)}
|
||||
{message}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -217,14 +217,9 @@ export function WsClientProvider({
|
||||
isFileWriteAction(event) ||
|
||||
isCommandAction(event)
|
||||
) {
|
||||
queryClient.invalidateQueries(
|
||||
{
|
||||
queryKey: ["file_changes", conversationId],
|
||||
},
|
||||
// Do not refetch if we are still receiving messages at a high rate (e.g., loading an existing conversation)
|
||||
// This prevents unnecessary refetches when the user is still receiving messages
|
||||
{ cancelRefetch: false },
|
||||
);
|
||||
queryClient.removeQueries({
|
||||
queryKey: ["file_changes", conversationId],
|
||||
});
|
||||
|
||||
// Invalidate file diff cache when a file is edited or written
|
||||
if (!isCommandAction(event)) {
|
||||
|
||||
@@ -228,6 +228,8 @@ export enum I18nKey {
|
||||
FEEDBACK$FAILED_TO_SHARE = "FEEDBACK$FAILED_TO_SHARE",
|
||||
FEEDBACK$COPY_LABEL = "FEEDBACK$COPY_LABEL",
|
||||
FEEDBACK$SHARING_SETTINGS_LABEL = "FEEDBACK$SHARING_SETTINGS_LABEL",
|
||||
FEEDBACK$SUBMITTING_LABEL = "FEEDBACK$SUBMITTING_LABEL",
|
||||
FEEDBACK$SUBMITTING_MESSAGE = "FEEDBACK$SUBMITTING_MESSAGE",
|
||||
SECURITY$UNKNOWN_ANALYZER_LABEL = "SECURITY$UNKNOWN_ANALYZER_LABEL",
|
||||
INVARIANT$UPDATE_POLICY_LABEL = "INVARIANT$UPDATE_POLICY_LABEL",
|
||||
INVARIANT$UPDATE_SETTINGS_LABEL = "INVARIANT$UPDATE_SETTINGS_LABEL",
|
||||
@@ -548,6 +550,4 @@ export enum I18nKey {
|
||||
TIPS$API_USAGE = "TIPS$API_USAGE",
|
||||
TIPS$LEARN_MORE = "TIPS$LEARN_MORE",
|
||||
TIPS$PROTIP = "TIPS$PROTIP",
|
||||
FEEDBACK$SUBMITTING_LABEL = "FEEDBACK$SUBMITTING_LABEL",
|
||||
FEEDBACK$SUBMITTING_MESSAGE = "FEEDBACK$SUBMITTING_MESSAGE",
|
||||
}
|
||||
|
||||
@@ -6400,20 +6400,20 @@
|
||||
"uk": "Запит не вдалося виконати через внутрішню помилку сервера."
|
||||
},
|
||||
"STATUS$ERROR_LLM_OUT_OF_CREDITS": {
|
||||
"en": "You're out of OpenHands Credits. <a>Add funds</a>",
|
||||
"ja": "OpenHandsクレジットが不足しています。<a>資金を追加</a>",
|
||||
"zh-CN": "您的OpenHands点数已用完。<a>添加资金</a>",
|
||||
"zh-TW": "您的OpenHands點數已用完。<a>添加資金</a>",
|
||||
"ko-KR": "OpenHands 크레딧이 소진되었습니다. <a>자금 추가</a>",
|
||||
"no": "Du er tom for OpenHands-kreditter. <a>Legg til midler</a>",
|
||||
"it": "Hai esaurito i crediti OpenHands. <a>Aggiungi fondi</a>",
|
||||
"pt": "Você está sem créditos OpenHands. <a>Adicionar fundos</a>",
|
||||
"es": "Te has quedado sin créditos de OpenHands. <a>Añadir fondos</a>",
|
||||
"ar": "لقد نفدت رصيدك من OpenHands. <a>إضافة رصيد</a>",
|
||||
"fr": "Vous n'avez plus de crédits OpenHands. <a>Ajouter des fonds</a>",
|
||||
"tr": "OpenHands kredileriniz tükendi. <a>Bakiye ekle</a>",
|
||||
"de": "Ihre OpenHands-Guthaben sind aufgebraucht. <a>Guthaben hinzufügen</a>",
|
||||
"uk": "У вас закінчилися кредити OpenHands. <a>Додати кошти</a>"
|
||||
"en": "You're out of OpenHands Credits",
|
||||
"ja": "OpenHandsクレジットが不足しています",
|
||||
"zh-CN": "您的OpenHands点数已用完",
|
||||
"zh-TW": "您的OpenHands點數已用完",
|
||||
"ko-KR": "OpenHands 크레딧이 소진되었습니다",
|
||||
"no": "Du er tom for OpenHands-kreditter",
|
||||
"it": "Hai esaurito i crediti OpenHands",
|
||||
"pt": "Você está sem créditos OpenHands",
|
||||
"es": "Te has quedado sin créditos de OpenHands",
|
||||
"ar": "لقد نفدت رصيدك من OpenHands",
|
||||
"fr": "Vous n'avez plus de crédits OpenHands",
|
||||
"tr": "OpenHands kredileriniz tükendi",
|
||||
"de": "Ihre OpenHands-Guthaben sind aufgebraucht",
|
||||
"uk": "У вас закінчилися кредити OpenHands"
|
||||
},
|
||||
"STATUS$ERROR_LLM_CONTENT_POLICY_VIOLATION": {
|
||||
"en": "Content policy violation. The output was blocked by content filtering policy.",
|
||||
@@ -8780,7 +8780,7 @@
|
||||
"ar": "إرسال...",
|
||||
"fr": "Envoi...",
|
||||
"tr": "Gönderiliyor...",
|
||||
"de": "Senden...",
|
||||
"de": "Senden...",
|
||||
"uk": "Відправляємо..."
|
||||
},
|
||||
"FEEDBACK$SUBMITTING_MESSAGE": {
|
||||
|
||||
Reference in New Issue
Block a user