Skip to content

Commit bfdb3ef

Browse files
Add Agent constructor class and fix API response handling
- Create Agent class with constructor-based API for consistency - Update README and examples to use new Agent() constructor - Fix RemoteState.getConversationInfo() to handle full_state wrapper - Export Agent class and AgentOptions type from main index - Update React example to use new Agent constructor pattern Co-authored-by: openhands <openhands@all-hands.dev>
1 parent f077c82 commit bfdb3ef

File tree

6 files changed

+69
-9
lines changed

6 files changed

+69
-9
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ npm install @openhands/agent-server-typescript-client
2323
```typescript
2424
import { Conversation, Agent, Workspace } from '@openhands/agent-server-typescript-client';
2525

26-
const agent: Agent = {
26+
const agent = new Agent({
2727
kind: 'CodeActAgent',
2828
llm: {
2929
model: 'gpt-4',
3030
api_key: 'your-openai-api-key'
3131
}
32-
};
32+
});
3333

3434
// Create a remote workspace
3535
const workspace = new Workspace({

example/src/components/ConversationManager.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,13 @@ export const ConversationManager: React.FC = () => {
192192
setError(null);
193193
try {
194194
// Create a simple agent configuration
195-
const agent: Agent = {
195+
const agent = new Agent({
196196
kind: 'Agent',
197197
llm: {
198198
model: settings.modelName,
199199
api_key: settings.apiKey || ''
200200
}
201-
};
201+
});
202202

203203
// Create a remote workspace
204204
const workspace = new Workspace({

src/agent/agent.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Agent class that provides a constructor-based API for creating agents.
3+
* Provides a cleaner API that matches the Python SDK naming.
4+
*/
5+
6+
import { AgentBase, LLM } from '../types/base';
7+
8+
export interface AgentOptions {
9+
llm: LLM;
10+
kind?: string;
11+
name?: string;
12+
[key: string]: any;
13+
}
14+
15+
/**
16+
* Agent class that implements AgentBase interface.
17+
* Provides a constructor-based API for creating agents.
18+
*
19+
* Usage:
20+
* const agent = new Agent({
21+
* llm: {
22+
* model: 'gpt-4',
23+
* api_key: 'your-key'
24+
* }
25+
* });
26+
*/
27+
export class Agent implements AgentBase {
28+
kind: string;
29+
llm: LLM;
30+
name?: string;
31+
[key: string]: any;
32+
33+
constructor(options: AgentOptions) {
34+
this.kind = options.kind || 'Agent';
35+
this.llm = options.llm;
36+
this.name = options.name;
37+
38+
// Copy any additional properties
39+
Object.keys(options).forEach(key => {
40+
if (key !== 'kind' && key !== 'llm' && key !== 'name') {
41+
this[key] = options[key];
42+
}
43+
});
44+
}
45+
}

src/agent/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Agent, AgentOptions } from './agent';

src/conversation/remote-state.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,20 @@ export class RemoteState {
4444
}
4545

4646
// Fallback to REST API if no cached state
47-
const response = await this.client.get<ConversationInfo>(
47+
const response = await this.client.get<any>(
4848
`/api/conversations/${this.conversationId}`
4949
);
50-
const state = response.data;
51-
this.cachedState = state;
52-
return state;
50+
51+
// Handle the case where the API returns a full_state wrapper
52+
let conversationInfo: ConversationInfo;
53+
if (response.data.full_state) {
54+
conversationInfo = response.data.full_state as ConversationInfo;
55+
} else {
56+
conversationInfo = response.data as ConversationInfo;
57+
}
58+
59+
this.cachedState = conversationInfo;
60+
return conversationInfo;
5361
});
5462
}
5563

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export { Workspace } from './workspace/workspace';
1414
export { RemoteState } from './conversation/remote-state';
1515
export { RemoteEventsList } from './events/remote-events-list';
1616

17+
// Agent classes
18+
export { Agent } from './agent/agent';
19+
1720
// WebSocket client for real-time events
1821
export { WebSocketCallbackClient } from './events/websocket-client';
1922

@@ -35,7 +38,6 @@ export type {
3538
TextContent,
3639
ImageContent,
3740
AgentBase,
38-
Agent,
3941
LLM,
4042
ServerInfo,
4143
Success,
@@ -48,6 +50,8 @@ export type {
4850
AlwaysConfirm,
4951
} from './types/base';
5052

53+
export type { AgentOptions } from './agent/agent';
54+
5155
export { EventSortOrder, AgentExecutionStatus } from './types/base';
5256

5357
// Workspace models
@@ -88,6 +92,7 @@ import { RemoteEventsList } from './events/remote-events-list';
8892
import { WebSocketCallbackClient } from './events/websocket-client';
8993
import { HttpClient, HttpError } from './client/http-client';
9094
import { EventSortOrder, AgentExecutionStatus } from './types/base';
95+
import { Agent } from './agent/agent';
9196

9297
// Default export for convenience
9398
export default {
@@ -103,4 +108,5 @@ export default {
103108
HttpError,
104109
EventSortOrder,
105110
AgentExecutionStatus,
111+
Agent,
106112
};

0 commit comments

Comments
 (0)