⚠️ ALPHA SOFTWARE WARNING⚠️ This TypeScript SDK is currently in alpha and is not stable. The API may change significantly between versions without notice. This software is intended for early testing and development purposes only.
- Breaking changes may occur in any release
- Features may be incomplete or contain bugs
- Documentation may be outdated or incomplete
- Not recommended for production use
Please use with caution and expect frequent updates.
A TypeScript client library for the OpenHands Agent Server API. Mirrors the structure and functionality of the Python OpenHands Software Agent SDK, but only supports remote conversations.
You'll need an AgentServer running somewhere for the client to connect to. You can run one in docker:
docker run -p 8000:8000 -p 8001:8001 \
-e OH_ENABLE_VNC=false \
-e SESSION_API_KEY="$SESSION_API_KEY" \
-e OH_ALLOW_CORS_ORIGINS='["*"]' \
ghcr.io/all-hands-ai/agent-server:78938ee-pythonimport { Conversation, Agent, Workspace } from '@openhands/agent-server-typescript-client';
const agent = new Agent({
llm: {
model: 'gpt-4',
api_key: 'your-openai-api-key'
}
});
// Create a remote workspace
const workspace = new Workspace({
host: 'http://localhost:3000',
workingDir: '/tmp',
apiKey: 'your-session-api-key'
});
const conversation = new Conversation(agent, workspace, {
callback: (event) => {
console.log('Received event:', event);
}
});
// Start the conversation with an initial message
await conversation.start({
initialMessage: 'Hello, can you help me write some code?'
});
// Start WebSocket for real-time events
await conversation.startWebSocketClient();
// Send a message and run the agent
await conversation.sendMessage('Create a simple Python script that prints "Hello World"');
await conversation.run();// Create a remote workspace for the existing conversation
const workspace = new Workspace({
host: 'http://localhost:3000',
workingDir: '/tmp',
apiKey: 'your-session-api-key'
});
const conversation = new Conversation(agent, workspace, {
conversationId: 'conversation-id-here'
});
// Connect to the existing conversation
await conversation.start();// Execute commands
const result = await conversation.workspace.executeCommand('ls -la');
console.log('Command output:', result.stdout);
console.log('Exit code:', result.exit_code);
// Upload a file
const uploadResult = await conversation.workspace.fileUpload(
'./local-file.txt',
'/remote/path/file.txt'
);
// Download a file
const downloadResult = await conversation.workspace.fileDownload(
'/remote/path/file.txt',
'./downloaded-file.txt'
);// Access the events list
const events = await conversation.state.events.getEvents();
console.log(`Total events: ${events.length}`);
// Iterate through events
for await (const event of conversation.state.events) {
console.log(`Event: ${event.kind} at ${event.timestamp}`);
}// Get conversation status
const status = await conversation.state.getAgentStatus();
console.log('Agent status:', status);
// Get conversation stats
const stats = await conversation.conversationStats();
console.log('Total events:', stats.total_events);
// Set confirmation policy
await conversation.setConfirmationPolicy({ type: 'always' });
// Update secrets
await conversation.updateSecrets({
'API_KEY': 'secret-value',
'DATABASE_URL': () => process.env.DATABASE_URL || 'default-url'
});Factory function that creates conversations with OpenHands agents.
new Conversation(agent, workspace, options?)- Create a new conversation instance
-
start(options?)- Start the conversation (creates new or connects to existing) -
sendMessage(message)- Send a message to the agent -
run()- Start agent execution -
pause()- Pause agent execution -
setConfirmationPolicy(policy)- Set confirmation policy -
sendConfirmationResponse(accept, reason?)- Respond to confirmation requests -
generateTitle(maxLength?, llm?)- Generate a title for the conversation -
updateSecrets(secrets)- Update conversation secrets -
startWebSocketClient()- Start real-time event streaming -
stopWebSocketClient()- Stop real-time event streaming -
conversationStats()- Get conversation statistics -
close()- Clean up resources
id- Conversation IDstate- RemoteState instance for accessing conversation stateworkspace- RemoteWorkspace instance for command execution and file operations
Handles remote command execution and file operations.
executeCommand(command, cwd?, timeout?)- Execute a bash commandfileUpload(sourcePath, destinationPath)- Upload a filefileDownload(sourcePath, destinationPath)- Download a filegitChanges(path)- Get git changes for a pathgitDiff(path)- Get git diff for a pathclose()- Clean up resources
Manages conversation state and provides access to events.
id- Conversation IDevents- RemoteEventsList instance
getAgentStatus()- Get current agent execution statusgetConfirmationPolicy()- Get current confirmation policygetActivatedKnowledgeSkills()- Get activated knowledge skillsgetAgent()- Get agent configurationgetWorkspace()- Get workspace configurationgetPersistenceDir()- Get persistence directorymodelDump()- Get state as plain objectmodelDumpJson()- Get state as JSON string
Manages conversation events with caching and synchronization.
addEvent(event)- Add an event to the cachelength()- Get number of cached eventsgetEvent(index)- Get event by indexgetEvents(start?, end?)- Get events slicecreateDefaultCallback()- Create a default event callback
Handles real-time event streaming via WebSocket.
start()- Start WebSocket connectionstop()- Stop WebSocket connection
The library includes comprehensive TypeScript type definitions:
ConversationID- Conversation identifier typeEvent- Base event interfaceMessage- Message interface with contentAgentBase- Agent configuration interfaceCommandResult- Command execution resultFileOperationResult- File operation resultConversationStats- Conversation statisticsAgentExecutionStatus- Agent status enum- And many more...
The client includes proper error handling with custom error types:
import { HttpError } from '@openhands/agent-server-typescript-client';
try {
await conversation.sendMessage('Hello');
} catch (error) {
if (error instanceof HttpError) {
console.error(`HTTP Error ${error.status}: ${error.statusText}`);
console.error('Response:', error.response);
} else {
console.error('Unexpected error:', error);
}
}npm run buildnpm run devnpm run lintnpm run formatMIT
Contributions are welcome! Please feel free to submit a Pull Request.