@steventsao/agent-session 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,27 +1,87 @@
1
- /**
2
- * agent-session client SDK
3
- *
4
- * Connect to agent-session Cloudflare Worker via WebSocket.
5
- *
6
- * @example
7
- * ```ts
8
- * import { AgentSessionClient } from 'agent-session';
9
- *
10
- * const client = new AgentSessionClient({
11
- * url: 'wss://your-agent-session.workers.dev',
12
- * sessionId: 'doc-123',
13
- * userId: 'user-456',
14
- * });
15
- *
16
- * client.on('AGENT_MESSAGE', (event) => {
17
- * console.log('Agent:', event.message);
18
- * });
19
- *
20
- * client.connect();
21
- * client.sendAgentMessage('Hello!');
22
- * ```
23
- */
1
+ import * as _steventsao_agent_session_core from '@steventsao/agent-session-core';
2
+ import { ServerEvent, ClientEvent } from '@steventsao/agent-session-core';
24
3
  export * from '@steventsao/agent-session-core';
25
- export { AgentSessionClient } from './client';
26
- export type { AgentSessionClientOptions } from './client';
27
- //# sourceMappingURL=index.d.ts.map
4
+
5
+ type ServerEventHandler<T extends ServerEvent = ServerEvent> = (event: T) => void;
6
+ interface AgentSessionClientOptions {
7
+ /** WebSocket base URL (e.g., wss://your-worker.workers.dev) */
8
+ url: string;
9
+ /** Session ID to connect to */
10
+ sessionId: string;
11
+ /** User ID for session tracking */
12
+ userId?: string;
13
+ /** Max reconnection attempts (default: 5) */
14
+ maxReconnectAttempts?: number;
15
+ /** Auto-reconnect on disconnect (default: true) */
16
+ autoReconnect?: boolean;
17
+ /** Ping interval in ms (default: 30000) */
18
+ pingInterval?: number;
19
+ /** Auto-connect on instantiation (default: false) */
20
+ autoConnect?: boolean;
21
+ /** Initial lastEventId for resumption (loaded from storage) */
22
+ lastEventId?: string;
23
+ /** Callback when lastEventId changes (for persistence) */
24
+ onEventIdChange?: (eventId: string) => void;
25
+ }
26
+ declare class AgentSessionClient {
27
+ private ws;
28
+ private baseUrl;
29
+ private sessionId;
30
+ private userId;
31
+ private pingIntervalId;
32
+ private reconnectTimeout;
33
+ private reconnectAttempts;
34
+ private socketId;
35
+ private maxReconnectAttempts;
36
+ private autoReconnect;
37
+ private pingInterval;
38
+ private lastEventId;
39
+ private onEventIdChange;
40
+ private handlers;
41
+ private globalHandlers;
42
+ constructor(options: AgentSessionClientOptions);
43
+ connect(): void;
44
+ disconnect(): void;
45
+ get isConnected(): boolean;
46
+ /** Get current event cursor for persistence */
47
+ getLastEventId(): string | null;
48
+ /** Set event cursor (load from storage before connect) */
49
+ setLastEventId(eventId: string | null): void;
50
+ /** Clear event cursor (for new chat/reset) */
51
+ clearEventId(): void;
52
+ on<T extends ServerEvent['type']>(eventType: T, handler: ServerEventHandler<Extract<ServerEvent, {
53
+ type: T;
54
+ }>>): () => void;
55
+ onAny(handler: ServerEventHandler): () => void;
56
+ off(eventType: ServerEvent['type']): void;
57
+ offAll(): void;
58
+ private handleMessage;
59
+ private updateEventId;
60
+ private emit;
61
+ send(message: ClientEvent): void;
62
+ init(metadata?: Record<string, unknown>): void;
63
+ startSandbox(template?: string): void;
64
+ stopSandbox(): void;
65
+ exec(cmd: string, cwd?: string): void;
66
+ sendAgentMessage(content: string, model?: {
67
+ id: string;
68
+ provider?: string;
69
+ }, options?: {
70
+ config?: {
71
+ temperature?: number;
72
+ maxTokens?: number;
73
+ };
74
+ systemPrompt?: string;
75
+ agentType?: string;
76
+ clientMessageId?: string;
77
+ author?: _steventsao_agent_session_core.MessageAuthor;
78
+ }): void;
79
+ stopAgent(): void;
80
+ resetAgent(): void;
81
+ private startPing;
82
+ private stopPing;
83
+ private clearReconnect;
84
+ private maybeReconnect;
85
+ }
86
+
87
+ export { AgentSessionClient, type AgentSessionClientOptions };
package/dist/index.js CHANGED
@@ -1,39 +1,244 @@
1
- /**
2
- * agent-session client SDK
3
- *
4
- * Connect to agent-session Cloudflare Worker via WebSocket.
5
- *
6
- * @example
7
- * ```ts
8
- * import { AgentSessionClient } from 'agent-session';
9
- *
10
- * const client = new AgentSessionClient({
11
- * url: 'wss://your-agent-session.workers.dev',
12
- * sessionId: 'doc-123',
13
- * userId: 'user-456',
14
- * });
15
- *
16
- * client.on('AGENT_MESSAGE', (event) => {
17
- * console.log('Agent:', event.message);
18
- * });
19
- *
20
- * client.connect();
21
- * client.sendAgentMessage('Hello!');
22
- * ```
23
- */
24
- // Re-export types from core
25
- export * from '@steventsao/agent-session-core';
26
- // Export vanilla client
27
- export { AgentSessionClient } from './client';
28
- // Export RTK slice (import from '@agent-session/client/redux')
29
- // Usage:
30
- // ```ts
31
- // import agentSessionReducer, { connectSession, selectIsConnected } from '@agent-session/client/redux';
32
- //
33
- // const store = configureStore({
34
- // reducer: { agentSession: agentSessionReducer }
35
- // });
36
- //
37
- // dispatch(connectSession({ url: 'wss://...', sessionId: 'session-123' }));
38
- // ```
39
- //# sourceMappingURL=index.js.map
1
+ // src/index.ts
2
+ export * from "@steventsao/agent-session-core";
3
+
4
+ // src/client.ts
5
+ var AgentSessionClient = class {
6
+ ws = null;
7
+ baseUrl;
8
+ sessionId;
9
+ userId;
10
+ pingIntervalId = null;
11
+ reconnectTimeout = null;
12
+ reconnectAttempts = 0;
13
+ socketId = 0;
14
+ maxReconnectAttempts;
15
+ autoReconnect;
16
+ pingInterval;
17
+ // Event resumption (Manus pattern)
18
+ lastEventId = null;
19
+ onEventIdChange = null;
20
+ // Event handlers
21
+ handlers = /* @__PURE__ */ new Map();
22
+ globalHandlers = /* @__PURE__ */ new Set();
23
+ constructor(options) {
24
+ this.baseUrl = options.url.replace(/\/$/, "");
25
+ this.sessionId = options.sessionId;
26
+ this.userId = options.userId || null;
27
+ this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
28
+ this.autoReconnect = options.autoReconnect ?? true;
29
+ this.pingInterval = options.pingInterval ?? 3e4;
30
+ this.lastEventId = options.lastEventId || null;
31
+ this.onEventIdChange = options.onEventIdChange || null;
32
+ if (options.autoConnect) {
33
+ this.connect();
34
+ }
35
+ }
36
+ // ==========================================================================
37
+ // Connection Management
38
+ // ==========================================================================
39
+ connect() {
40
+ if (this.ws?.readyState === WebSocket.OPEN) {
41
+ return;
42
+ }
43
+ this.reconnectAttempts = 0;
44
+ const thisSocketId = ++this.socketId;
45
+ const params = new URLSearchParams();
46
+ if (this.userId) params.set("userId", this.userId);
47
+ const url = `${this.baseUrl}/session/${this.sessionId}/ws?${params}`;
48
+ console.log("[AgentSession] Connecting to:", url);
49
+ this.ws = new WebSocket(url);
50
+ this.ws.onopen = () => {
51
+ if (thisSocketId !== this.socketId) return;
52
+ console.log("[AgentSession] Connected");
53
+ this.reconnectAttempts = 0;
54
+ this.startPing();
55
+ this.send({
56
+ type: "JOIN_SESSION",
57
+ lastEventId: this.lastEventId || void 0
58
+ });
59
+ };
60
+ this.ws.onmessage = (event) => {
61
+ if (thisSocketId !== this.socketId) return;
62
+ try {
63
+ const data = JSON.parse(event.data);
64
+ this.handleMessage(data);
65
+ } catch (err) {
66
+ console.error("[AgentSession] Parse error:", err);
67
+ }
68
+ };
69
+ this.ws.onclose = (event) => {
70
+ if (thisSocketId !== this.socketId) return;
71
+ console.log("[AgentSession] Disconnected:", event.code);
72
+ this.stopPing();
73
+ this.emit({ type: "SYSTEM", msg: "Disconnected" });
74
+ if (this.autoReconnect) {
75
+ this.maybeReconnect();
76
+ }
77
+ };
78
+ this.ws.onerror = (event) => {
79
+ if (thisSocketId !== this.socketId) return;
80
+ console.error("[AgentSession] Error:", event);
81
+ };
82
+ }
83
+ disconnect() {
84
+ this.stopPing();
85
+ this.clearReconnect();
86
+ this.socketId++;
87
+ this.ws?.close();
88
+ this.ws = null;
89
+ }
90
+ get isConnected() {
91
+ return this.ws?.readyState === WebSocket.OPEN;
92
+ }
93
+ /** Get current event cursor for persistence */
94
+ getLastEventId() {
95
+ return this.lastEventId;
96
+ }
97
+ /** Set event cursor (load from storage before connect) */
98
+ setLastEventId(eventId) {
99
+ this.lastEventId = eventId;
100
+ }
101
+ /** Clear event cursor (for new chat/reset) */
102
+ clearEventId() {
103
+ this.lastEventId = null;
104
+ }
105
+ // ==========================================================================
106
+ // Event Handling
107
+ // ==========================================================================
108
+ on(eventType, handler) {
109
+ if (!this.handlers.has(eventType)) {
110
+ this.handlers.set(eventType, /* @__PURE__ */ new Set());
111
+ }
112
+ this.handlers.get(eventType).add(handler);
113
+ return () => this.handlers.get(eventType)?.delete(handler);
114
+ }
115
+ onAny(handler) {
116
+ this.globalHandlers.add(handler);
117
+ return () => this.globalHandlers.delete(handler);
118
+ }
119
+ off(eventType) {
120
+ this.handlers.delete(eventType);
121
+ }
122
+ offAll() {
123
+ this.handlers.clear();
124
+ this.globalHandlers.clear();
125
+ }
126
+ handleMessage(event) {
127
+ if (event.type === "EVENTS_BATCH") {
128
+ const batchEvent = event;
129
+ console.log(`[AgentSession] Replaying ${batchEvent.count} events from batch`);
130
+ for (const batchedEvent of batchEvent.events) {
131
+ this.handleMessage(batchedEvent);
132
+ }
133
+ if (batchEvent.lastEventId) {
134
+ this.updateEventId(batchEvent.lastEventId);
135
+ }
136
+ return;
137
+ }
138
+ const eventWithMeta = event;
139
+ if (eventWithMeta.eventId) {
140
+ this.updateEventId(eventWithMeta.eventId);
141
+ }
142
+ const handlers = this.handlers.get(event.type);
143
+ if (handlers) {
144
+ for (const handler of handlers) {
145
+ try {
146
+ handler(event);
147
+ } catch (err) {
148
+ console.error("[AgentSession] Handler error:", err);
149
+ }
150
+ }
151
+ }
152
+ for (const handler of this.globalHandlers) {
153
+ try {
154
+ handler(event);
155
+ } catch (err) {
156
+ console.error("[AgentSession] Global handler error:", err);
157
+ }
158
+ }
159
+ }
160
+ updateEventId(eventId) {
161
+ this.lastEventId = eventId;
162
+ this.onEventIdChange?.(eventId);
163
+ }
164
+ emit(event) {
165
+ this.handleMessage(event);
166
+ }
167
+ // ==========================================================================
168
+ // Client Commands
169
+ // ==========================================================================
170
+ send(message) {
171
+ if (this.ws?.readyState !== WebSocket.OPEN) {
172
+ console.warn("[AgentSession] Not connected");
173
+ return;
174
+ }
175
+ this.ws.send(JSON.stringify(message));
176
+ }
177
+ init(metadata) {
178
+ this.send({ type: "INIT", metadata });
179
+ }
180
+ startSandbox(template) {
181
+ this.send({ type: "START_SANDBOX", template });
182
+ }
183
+ stopSandbox() {
184
+ this.send({ type: "STOP_SANDBOX" });
185
+ }
186
+ exec(cmd, cwd) {
187
+ this.send({ type: "EXEC", cmd, cwd });
188
+ }
189
+ sendAgentMessage(content, model, options) {
190
+ this.send({
191
+ type: "AGENT_MESSAGE",
192
+ clientMessageId: options?.clientMessageId,
193
+ content,
194
+ model,
195
+ config: options?.config,
196
+ systemPrompt: options?.systemPrompt,
197
+ agentType: options?.agentType,
198
+ author: options?.author
199
+ });
200
+ }
201
+ stopAgent() {
202
+ this.send({ type: "AGENT_STOP" });
203
+ }
204
+ resetAgent() {
205
+ this.send({ type: "AGENT_RESET" });
206
+ }
207
+ // ==========================================================================
208
+ // Private Helpers
209
+ // ==========================================================================
210
+ startPing() {
211
+ this.stopPing();
212
+ this.pingIntervalId = setInterval(() => {
213
+ this.send({ type: "PING" });
214
+ }, this.pingInterval);
215
+ }
216
+ stopPing() {
217
+ if (this.pingIntervalId) {
218
+ clearInterval(this.pingIntervalId);
219
+ this.pingIntervalId = null;
220
+ }
221
+ }
222
+ clearReconnect() {
223
+ if (this.reconnectTimeout) {
224
+ clearTimeout(this.reconnectTimeout);
225
+ this.reconnectTimeout = null;
226
+ }
227
+ }
228
+ maybeReconnect() {
229
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
230
+ console.error("[AgentSession] Max reconnect attempts");
231
+ this.emit({ type: "ERROR", msg: "Max reconnect attempts reached" });
232
+ return;
233
+ }
234
+ this.reconnectAttempts++;
235
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), 3e4);
236
+ console.log(`[AgentSession] Reconnecting in ${delay}ms`);
237
+ this.reconnectTimeout = setTimeout(() => {
238
+ this.connect();
239
+ }, delay);
240
+ }
241
+ };
242
+ export {
243
+ AgentSessionClient
244
+ };
package/dist/react.d.ts CHANGED
@@ -1,26 +1,68 @@
1
+ import { SessionRefreshConfig, SandboxLifecycle, ServerEvent, SandboxStatus, ContentBlock } from '@steventsao/agent-session-core';
2
+ export * from '@steventsao/agent-session-core';
3
+
1
4
  /**
2
- * React bindings for agent-session
3
- *
4
- * @example
5
- * ```tsx
6
- * import { useAgentSession } from 'agent-session/react';
7
- *
8
- * function Chat() {
9
- * const { messages, sendMessage, isConnected } = useAgentSession({
10
- * url: 'wss://your-agent-session.workers.dev',
11
- * sessionId: 'doc-123',
12
- * });
13
- *
14
- * return (
15
- * <div>
16
- * {messages.map(m => <p key={m.id}>{m.content}</p>)}
17
- * <button onClick={() => sendMessage('Hello!')}>Send</button>
18
- * </div>
19
- * );
20
- * }
21
- * ```
5
+ * React Hook for agent-session
22
6
  */
23
- export { useAgentSession } from './use-agent-session';
24
- export type { UseAgentSessionOptions, UseAgentSessionReturn, AgentMessage } from './use-agent-session';
25
- export * from '@steventsao/agent-session-core';
26
- //# sourceMappingURL=react.d.ts.map
7
+
8
+ interface AgentMessage {
9
+ id: string;
10
+ role: 'user' | 'assistant';
11
+ content: string | ContentBlock[];
12
+ timestamp: number;
13
+ }
14
+ interface UseAgentSessionOptions {
15
+ /** WebSocket base URL (e.g., wss://your-worker.workers.dev) */
16
+ url: string;
17
+ /** Session ID to connect to */
18
+ sessionId?: string;
19
+ /** User ID for session tracking */
20
+ userId?: string;
21
+ /** Auto-connect on mount (default: true if sessionId provided) */
22
+ autoConnect?: boolean;
23
+ /**
24
+ * Session refresh configuration - controls behavior when sessionId changes.
25
+ * Default: 'reset' - clears all state when switching sessions (recommended for document isolation)
26
+ */
27
+ refreshConfig?: SessionRefreshConfig;
28
+ /** Event callbacks */
29
+ onLifecycle?: (phase: SandboxLifecycle, message?: string) => void;
30
+ onAgentMessage?: (event: ServerEvent) => void;
31
+ onError?: (error: string) => void;
32
+ }
33
+ interface UseAgentSessionReturn {
34
+ isConnected: boolean;
35
+ clientId: string | null;
36
+ sessionId: string | null;
37
+ sandboxStatus: SandboxStatus;
38
+ sandboxId: string | null;
39
+ sandboxUrl: string | null;
40
+ lifecycle: SandboxLifecycle;
41
+ lifecycleMessage: string | null;
42
+ agentStatus: 'idle' | 'streaming' | 'error';
43
+ agentSessionId: string | null;
44
+ messages: AgentMessage[];
45
+ error: string | null;
46
+ connect: (sessionId: string, userId?: string) => void;
47
+ disconnect: () => void;
48
+ startSandbox: (template?: string) => void;
49
+ stopSandbox: () => void;
50
+ exec: (cmd: string, cwd?: string) => void;
51
+ sendMessage: (content: string, model?: {
52
+ id: string;
53
+ provider?: string;
54
+ }, options?: {
55
+ config?: {
56
+ temperature?: number;
57
+ maxTokens?: number;
58
+ };
59
+ systemPrompt?: string;
60
+ agentType?: string;
61
+ }) => void;
62
+ stopAgent: () => void;
63
+ resetAgent: () => void;
64
+ clearMessages: () => void;
65
+ }
66
+ declare function useAgentSession(options: UseAgentSessionOptions): UseAgentSessionReturn;
67
+
68
+ export { type AgentMessage, type UseAgentSessionOptions, type UseAgentSessionReturn, useAgentSession };