connectonion 0.0.8 β 0.0.9
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/README.md +120 -1
- package/dist/connect.d.ts +66 -20
- package/dist/connect.d.ts.map +1 -1
- package/dist/connect.js +146 -31
- package/dist/console.d.ts +31 -0
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +31 -0
- package/dist/core/agent.d.ts +57 -0
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +57 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -0
- package/dist/llm/anthropic.d.ts +28 -0
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +28 -0
- package/dist/llm/gemini.d.ts +30 -0
- package/dist/llm/gemini.d.ts.map +1 -1
- package/dist/llm/gemini.js +30 -0
- package/dist/llm/index.d.ts +36 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +36 -0
- package/dist/llm/llm-do.d.ts.map +1 -1
- package/dist/llm/llm-do.js +32 -0
- package/dist/llm/noop.d.ts +14 -0
- package/dist/llm/noop.d.ts.map +1 -1
- package/dist/llm/noop.js +14 -0
- package/dist/llm/openai.d.ts +39 -0
- package/dist/llm/openai.d.ts.map +1 -1
- package/dist/llm/openai.js +39 -0
- package/dist/react/index.d.ts +9 -23
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +22 -27
- package/dist/tools/email.d.ts.map +1 -1
- package/dist/tools/email.js +20 -0
- package/dist/tools/replay.d.ts +32 -0
- package/dist/tools/replay.d.ts.map +1 -1
- package/dist/tools/replay.js +32 -0
- package/dist/tools/tool-executor.d.ts +40 -0
- package/dist/tools/tool-executor.d.ts.map +1 -1
- package/dist/tools/tool-executor.js +40 -0
- package/dist/tools/tool-utils.d.ts +56 -0
- package/dist/tools/tool-utils.d.ts.map +1 -1
- package/dist/tools/tool-utils.js +56 -0
- package/dist/tools/xray.d.ts +48 -0
- package/dist/tools/xray.d.ts.map +1 -1
- package/dist/tools/xray.js +48 -0
- package/dist/trust/index.d.ts +27 -0
- package/dist/trust/index.d.ts.map +1 -1
- package/dist/trust/index.js +27 -0
- package/dist/trust/tools.d.ts.map +1 -1
- package/dist/trust/tools.js +26 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +40 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -205,7 +205,98 @@ While we recommend building agents in Python, you can also build simple agents d
|
|
|
205
205
|
|
|
206
206
|
If you encounter bugs building agents in TypeScript, please [report them on GitHub](https://github.com/openonion/connectonion-ts/issues).
|
|
207
207
|
|
|
208
|
-
## ποΈ
|
|
208
|
+
## ποΈ Architecture
|
|
209
|
+
|
|
210
|
+
### System Overview
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
214
|
+
β ConnectOnion TypeScript SDK β
|
|
215
|
+
β β
|
|
216
|
+
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββββ β
|
|
217
|
+
β β Agent β β connect() β β llmDo() β β
|
|
218
|
+
β β (local AI) β β (remote) β β (one-shot LLM call) β β
|
|
219
|
+
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββββββββ¬ββββββββββββ β
|
|
220
|
+
β β β β β
|
|
221
|
+
β βΌ βΌ β β
|
|
222
|
+
β βββββββββββββββββββββββββββββββ β β
|
|
223
|
+
β β LLM Factory βββββββββββββββββββββ β
|
|
224
|
+
β β createLLM(model) β β
|
|
225
|
+
β ββββββββββββ¬βββββββββββββββββββ β
|
|
226
|
+
β βββββββββΌβββββββββββ¬βββββββββββββ β
|
|
227
|
+
β βΌ βΌ βΌ βΌ β
|
|
228
|
+
β Anthropic OpenAI Gemini OpenOnion β
|
|
229
|
+
β (claude-*) (gpt-*) (gemini-*) (co/*) β
|
|
230
|
+
β β
|
|
231
|
+
β ββββββββββββββββ ββββββββββββ βββββββββββββ βββββββββββββ β
|
|
232
|
+
β β Tool System β β Trust β β Console β β Xray β β
|
|
233
|
+
β β funcβschema β β Levels β β Logging β β Debugger β β
|
|
234
|
+
β ββββββββββββββββ ββββββββββββ βββββββββββββ βββββββββββββ β
|
|
235
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Agent Execution Flow
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
agent.input("What is 2+2?")
|
|
242
|
+
β
|
|
243
|
+
βΌ
|
|
244
|
+
βββββββββββββββββββ
|
|
245
|
+
β Init messages β [system prompt] + [user message]
|
|
246
|
+
ββββββββββ¬βββββββββ
|
|
247
|
+
β
|
|
248
|
+
βΌ
|
|
249
|
+
βββββββββββββββββββββββββββββββββββββββ
|
|
250
|
+
β Main Loop (max 10 iter) β
|
|
251
|
+
β β
|
|
252
|
+
β LLM.complete(messages, tools) β
|
|
253
|
+
β β β
|
|
254
|
+
β βββ No tool calls βββΆ EXIT β
|
|
255
|
+
β β β
|
|
256
|
+
β βββ Tool calls found: β
|
|
257
|
+
β Promise.all( β
|
|
258
|
+
β tool_1.run(args), β
|
|
259
|
+
β tool_2.run(args) β
|
|
260
|
+
β ) β
|
|
261
|
+
β β β
|
|
262
|
+
β βΌ β
|
|
263
|
+
β Append results β LOOP β
|
|
264
|
+
βββββββββββββββββββββββββββββββββββββββ
|
|
265
|
+
β
|
|
266
|
+
βΌ
|
|
267
|
+
Return final text response
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Tool Conversion
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
Your code SDK internals
|
|
274
|
+
|
|
275
|
+
function add(a: number, Tool {
|
|
276
|
+
b: number): number { βββΆ name: "add",
|
|
277
|
+
return a + b; description: "...",
|
|
278
|
+
} run(args) β add(a, b),
|
|
279
|
+
toFunctionSchema() β {
|
|
280
|
+
class API { type: "object",
|
|
281
|
+
search(q: string) {} βββΆ properties: {a: {type: "number"}, ...}
|
|
282
|
+
fetch(id: number) {} }
|
|
283
|
+
} }
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### LLM Provider Routing
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
createLLM(model)
|
|
290
|
+
β
|
|
291
|
+
βββ "co/*" βββΆ OpenAI LLM + OpenOnion baseURL
|
|
292
|
+
βββ "claude-*" βββΆ Anthropic LLM (default)
|
|
293
|
+
βββ "gpt-*" βββΆ OpenAI LLM
|
|
294
|
+
βββ "o*" βββΆ OpenAI LLM
|
|
295
|
+
βββ "gemini-*" βββΆ Gemini LLM
|
|
296
|
+
βββ (unknown) βββΆ Anthropic (fallback) or NoopLLM
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Project Structure
|
|
209
300
|
|
|
210
301
|
```
|
|
211
302
|
your-project/
|
|
@@ -218,6 +309,34 @@ your-project/
|
|
|
218
309
|
βββ tsconfig.json
|
|
219
310
|
```
|
|
220
311
|
|
|
312
|
+
### SDK Internal Structure
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
src/
|
|
316
|
+
βββ core/
|
|
317
|
+
β βββ agent.ts # Main Agent class (orchestrator)
|
|
318
|
+
βββ llm/
|
|
319
|
+
β βββ index.ts # LLM factory (routes model names)
|
|
320
|
+
β βββ anthropic.ts # Anthropic Claude provider (default)
|
|
321
|
+
β βββ openai.ts # OpenAI GPT/O-series provider
|
|
322
|
+
β βββ gemini.ts # Google Gemini provider
|
|
323
|
+
β βββ noop.ts # Fallback for missing config
|
|
324
|
+
β βββ llm-do.ts # One-shot llmDo() helper
|
|
325
|
+
βββ tools/
|
|
326
|
+
β βββ tool-utils.ts # Function β Tool conversion
|
|
327
|
+
β βββ tool-executor.ts # Execution + trace recording
|
|
328
|
+
β βββ xray.ts # Debug context injection (@xray)
|
|
329
|
+
β βββ replay.ts # Replay decorator for debugging
|
|
330
|
+
β βββ email.ts # Mock email tools for demos/tests
|
|
331
|
+
βββ trust/
|
|
332
|
+
β βββ index.ts # Trust levels (open/careful/strict)
|
|
333
|
+
β βββ tools.ts # Whitelist checks & verification
|
|
334
|
+
βββ connect.ts # Remote agent connection via relay
|
|
335
|
+
βββ console.ts # Dual logging (stderr + file)
|
|
336
|
+
βββ types.ts # Core TypeScript interfaces
|
|
337
|
+
βββ index.ts # Public API exports
|
|
338
|
+
```
|
|
339
|
+
|
|
221
340
|
---
|
|
222
341
|
|
|
223
342
|
## π¬ Join the Community
|
package/dist/connect.d.ts
CHANGED
|
@@ -1,30 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @purpose Client for connecting to remote agents via WebSocket with automatic keep-alive, session recovery, and polling fallback
|
|
3
|
+
*
|
|
4
|
+
* @graph Connection Modes
|
|
5
|
+
*
|
|
6
|
+
* connect('0xAddr', options?)
|
|
7
|
+
* β
|
|
8
|
+
* βββ directUrl set? ββyesβββΆ Direct: wss://{directUrl}/ws
|
|
9
|
+
* β
|
|
10
|
+
* βββ resolveEndpoint()? ββfoundβββΆ Direct: resolved wsUrl
|
|
11
|
+
* β
|
|
12
|
+
* βββ fallback βββΆ Relay: {relayUrl}/ws/input
|
|
13
|
+
*
|
|
14
|
+
* @graph Remote Agent Communication Flow
|
|
15
|
+
*
|
|
16
|
+
* Client (TS) Relay / Agent
|
|
17
|
+
* β β
|
|
18
|
+
* β connect('0xAddr') β
|
|
19
|
+
* β βββΆ RemoteAgent β
|
|
20
|
+
* β (lazy-load Ed25519 keys) β
|
|
21
|
+
* β β
|
|
22
|
+
* β agent.input("prompt") β
|
|
23
|
+
* β βββΆ WebSocket open ββββββββββΆ β
|
|
24
|
+
* β INPUT{prompt, sig, to} β βββΆ agent processes
|
|
25
|
+
* β β
|
|
26
|
+
* β βββ PING ββββββββββββββββββ β (every 30s keep-alive)
|
|
27
|
+
* β βββΆ PONG βββββββββββββββββββΆ β
|
|
28
|
+
* β β
|
|
29
|
+
* β βββ stream events βββββββββ β (thinking, tool_call,
|
|
30
|
+
* β (update agent.ui[]) β tool_result, assistant)
|
|
31
|
+
* β β
|
|
32
|
+
* β βββ OUTPUT{result, session} β β
|
|
33
|
+
* β ws.close() β
|
|
34
|
+
* βΌ βΌ
|
|
35
|
+
*
|
|
36
|
+
* @graph Recovery Flow (on disconnect/timeout)
|
|
37
|
+
*
|
|
38
|
+
* WebSocket fails
|
|
39
|
+
* β
|
|
40
|
+
* βΌ
|
|
41
|
+
* Poll GET /sessions/{session_id} (every 10s)
|
|
42
|
+
* β
|
|
43
|
+
* βββ status: "running" βββΆ retry poll
|
|
44
|
+
* βββ status: "done" βββΆ return result
|
|
45
|
+
* βββ 404 / max attempts βββΆ throw Error
|
|
46
|
+
*
|
|
3
47
|
* @llm-note
|
|
4
48
|
* Dependencies: imports from [src/address.ts (AddressData, generate, load, sign, etc.), src/types.ts (SessionStatus)] | imported by [src/index.ts, src/react/index.ts, examples/connect-example.ts, tests/connect.test.ts] | tested by [tests/connect.test.ts]
|
|
5
49
|
* Data flow: connect(address, options) β creates RemoteAgent β agent.input(prompt) β generates session_id (UUID) β saves to localStorage β opens WebSocket β sends INPUT{type, input_id, to, prompt, session{session_id}, signature?} β receives PING every 30s, responds with PONG β receives stream events (tool_call, tool_result, thinking, assistant) β receives OUTPUT{result, session_id, session} β clears localStorage β returns Response{text, done} | On disconnect/timeout: polls GET /sessions/{session_id} every 10s until result ready
|
|
6
50
|
* State/Effects: opens WebSocket connections | sends signed/unsigned messages | updates internal UI events array | syncs session from server | generates/loads Ed25519 keys | saves keys to localStorage (browser) or .co/keys/ (Node.js) | saves active session_id to localStorage for recovery | polls server via HTTP fetch on connection failure | health check interval detects dead connections
|
|
7
51
|
* Integration: exposes connect(address, options), RemoteAgent class, Response, ChatItem types, AgentStatus, ConnectOptions{enablePolling, pollIntervalMs, maxPollAttempts} | supports relay mode (wss://oo.openonion.ai) and direct mode (deployed agent URL) | Ed25519 signing for authentication | session persistence across calls | automatic recovery from network failures, timeouts, page refreshes
|
|
8
|
-
* Performance: 600s timeout default (10 min
|
|
9
|
-
* Errors: throws on timeout (600s default) after polling exhausted | throws on WebSocket errors after polling attempt | throws on connection close after polling attempt | throws on ERROR messages from server | throws if session expired (404) during polling |
|
|
10
|
-
*
|
|
11
|
-
* Architecture:
|
|
12
|
-
* Normal Flow:
|
|
13
|
-
* Client β /ws/input β Relay β Agent β OUTPUT β Relay β Client
|
|
14
|
-
*
|
|
15
|
-
* Keep-Alive:
|
|
16
|
-
* Server sends PING every 30s β Client responds PONG β Health check every 10s
|
|
17
|
-
*
|
|
18
|
-
* Recovery Flow (on disconnect/timeout):
|
|
19
|
-
* WebSocket fails β Poll GET /sessions/{session_id} every 10s β Status="done" β Return result
|
|
20
|
-
*
|
|
21
|
-
* Related Files:
|
|
22
|
-
* - oo-api/relay/routes.py: Relay server WebSocket endpoints
|
|
23
|
-
* - connectonion/network/connect.py: Python equivalent of this file
|
|
24
|
-
* - connectonion/network/asgi/websocket.py: Server-side PING sender
|
|
25
|
-
* - connectonion/network/host/session.py: SessionStorage for 24h TTL
|
|
26
|
-
* - src/react/index.ts: useAgent hook built on RemoteAgent
|
|
27
|
-
* - src/types.ts: SessionStatus, PollResult interfaces
|
|
52
|
+
* Performance: 600s timeout default (10 min) | real-time WebSocket streaming | PING/PONG keep-alive every 30s | health check every 10s | polling fallback on failures | results persist 24h server-side
|
|
53
|
+
* Errors: throws on timeout (600s default) after polling exhausted | throws on WebSocket errors after polling attempt | throws on connection close after polling attempt | throws on ERROR messages from server | throws if session expired (404) during polling | graceful fallback to polling prevents data loss
|
|
28
54
|
*/
|
|
29
55
|
import * as address from './address';
|
|
30
56
|
export type { AddressData } from './address';
|
|
@@ -205,6 +231,7 @@ export interface SessionState {
|
|
|
205
231
|
}>;
|
|
206
232
|
trace?: unknown[];
|
|
207
233
|
turn?: number;
|
|
234
|
+
_savedAt?: number;
|
|
208
235
|
}
|
|
209
236
|
/** Agent status */
|
|
210
237
|
export type AgentStatus = 'idle' | 'working' | 'waiting';
|
|
@@ -330,8 +357,27 @@ export declare class RemoteAgent {
|
|
|
330
357
|
private _saveSessionId;
|
|
331
358
|
/**
|
|
332
359
|
* Clear session ID from localStorage (browser only).
|
|
360
|
+
* Also clears the full session data.
|
|
333
361
|
*/
|
|
334
362
|
private _clearSessionId;
|
|
363
|
+
/**
|
|
364
|
+
* Save full session state to localStorage (browser only).
|
|
365
|
+
* Enables conversation recovery after browser refresh.
|
|
366
|
+
*/
|
|
367
|
+
private _saveSession;
|
|
368
|
+
/**
|
|
369
|
+
* Load session state from localStorage (browser only).
|
|
370
|
+
* Returns null if session doesn't exist.
|
|
371
|
+
*/
|
|
372
|
+
private _loadSession;
|
|
373
|
+
/**
|
|
374
|
+
* Load active session ID from localStorage (browser only).
|
|
375
|
+
*/
|
|
376
|
+
private _loadActiveSessionId;
|
|
377
|
+
/**
|
|
378
|
+
* Clear specific session from localStorage (browser only).
|
|
379
|
+
*/
|
|
380
|
+
private _clearSession;
|
|
335
381
|
/**
|
|
336
382
|
* Start health check interval to detect dead connections.
|
|
337
383
|
* Checks if PING received within 60 seconds, attempts reconnect if not.
|
package/dist/connect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
|
package/dist/connect.js
CHANGED
|
@@ -1,31 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @purpose Client for connecting to remote agents via WebSocket with automatic keep-alive, session recovery, and polling fallback
|
|
4
|
+
*
|
|
5
|
+
* @graph Connection Modes
|
|
6
|
+
*
|
|
7
|
+
* connect('0xAddr', options?)
|
|
8
|
+
* β
|
|
9
|
+
* βββ directUrl set? ββyesβββΆ Direct: wss://{directUrl}/ws
|
|
10
|
+
* β
|
|
11
|
+
* βββ resolveEndpoint()? ββfoundβββΆ Direct: resolved wsUrl
|
|
12
|
+
* β
|
|
13
|
+
* βββ fallback βββΆ Relay: {relayUrl}/ws/input
|
|
14
|
+
*
|
|
15
|
+
* @graph Remote Agent Communication Flow
|
|
16
|
+
*
|
|
17
|
+
* Client (TS) Relay / Agent
|
|
18
|
+
* β β
|
|
19
|
+
* β connect('0xAddr') β
|
|
20
|
+
* β βββΆ RemoteAgent β
|
|
21
|
+
* β (lazy-load Ed25519 keys) β
|
|
22
|
+
* β β
|
|
23
|
+
* β agent.input("prompt") β
|
|
24
|
+
* β βββΆ WebSocket open ββββββββββΆ β
|
|
25
|
+
* β INPUT{prompt, sig, to} β βββΆ agent processes
|
|
26
|
+
* β β
|
|
27
|
+
* β βββ PING ββββββββββββββββββ β (every 30s keep-alive)
|
|
28
|
+
* β βββΆ PONG βββββββββββββββββββΆ β
|
|
29
|
+
* β β
|
|
30
|
+
* β βββ stream events βββββββββ β (thinking, tool_call,
|
|
31
|
+
* β (update agent.ui[]) β tool_result, assistant)
|
|
32
|
+
* β β
|
|
33
|
+
* β βββ OUTPUT{result, session} β β
|
|
34
|
+
* β ws.close() β
|
|
35
|
+
* βΌ βΌ
|
|
36
|
+
*
|
|
37
|
+
* @graph Recovery Flow (on disconnect/timeout)
|
|
38
|
+
*
|
|
39
|
+
* WebSocket fails
|
|
40
|
+
* β
|
|
41
|
+
* βΌ
|
|
42
|
+
* Poll GET /sessions/{session_id} (every 10s)
|
|
43
|
+
* β
|
|
44
|
+
* βββ status: "running" βββΆ retry poll
|
|
45
|
+
* βββ status: "done" βββΆ return result
|
|
46
|
+
* βββ 404 / max attempts βββΆ throw Error
|
|
47
|
+
*
|
|
4
48
|
* @llm-note
|
|
5
49
|
* Dependencies: imports from [src/address.ts (AddressData, generate, load, sign, etc.), src/types.ts (SessionStatus)] | imported by [src/index.ts, src/react/index.ts, examples/connect-example.ts, tests/connect.test.ts] | tested by [tests/connect.test.ts]
|
|
6
50
|
* Data flow: connect(address, options) β creates RemoteAgent β agent.input(prompt) β generates session_id (UUID) β saves to localStorage β opens WebSocket β sends INPUT{type, input_id, to, prompt, session{session_id}, signature?} β receives PING every 30s, responds with PONG β receives stream events (tool_call, tool_result, thinking, assistant) β receives OUTPUT{result, session_id, session} β clears localStorage β returns Response{text, done} | On disconnect/timeout: polls GET /sessions/{session_id} every 10s until result ready
|
|
7
51
|
* State/Effects: opens WebSocket connections | sends signed/unsigned messages | updates internal UI events array | syncs session from server | generates/loads Ed25519 keys | saves keys to localStorage (browser) or .co/keys/ (Node.js) | saves active session_id to localStorage for recovery | polls server via HTTP fetch on connection failure | health check interval detects dead connections
|
|
8
52
|
* Integration: exposes connect(address, options), RemoteAgent class, Response, ChatItem types, AgentStatus, ConnectOptions{enablePolling, pollIntervalMs, maxPollAttempts} | supports relay mode (wss://oo.openonion.ai) and direct mode (deployed agent URL) | Ed25519 signing for authentication | session persistence across calls | automatic recovery from network failures, timeouts, page refreshes
|
|
9
|
-
* Performance: 600s timeout default (10 min
|
|
10
|
-
* Errors: throws on timeout (600s default) after polling exhausted | throws on WebSocket errors after polling attempt | throws on connection close after polling attempt | throws on ERROR messages from server | throws if session expired (404) during polling |
|
|
11
|
-
*
|
|
12
|
-
* Architecture:
|
|
13
|
-
* Normal Flow:
|
|
14
|
-
* Client β /ws/input β Relay β Agent β OUTPUT β Relay β Client
|
|
15
|
-
*
|
|
16
|
-
* Keep-Alive:
|
|
17
|
-
* Server sends PING every 30s β Client responds PONG β Health check every 10s
|
|
18
|
-
*
|
|
19
|
-
* Recovery Flow (on disconnect/timeout):
|
|
20
|
-
* WebSocket fails β Poll GET /sessions/{session_id} every 10s β Status="done" β Return result
|
|
21
|
-
*
|
|
22
|
-
* Related Files:
|
|
23
|
-
* - oo-api/relay/routes.py: Relay server WebSocket endpoints
|
|
24
|
-
* - connectonion/network/connect.py: Python equivalent of this file
|
|
25
|
-
* - connectonion/network/asgi/websocket.py: Server-side PING sender
|
|
26
|
-
* - connectonion/network/host/session.py: SessionStorage for 24h TTL
|
|
27
|
-
* - src/react/index.ts: useAgent hook built on RemoteAgent
|
|
28
|
-
* - src/types.ts: SessionStatus, PollResult interfaces
|
|
53
|
+
* Performance: 600s timeout default (10 min) | real-time WebSocket streaming | PING/PONG keep-alive every 30s | health check every 10s | polling fallback on failures | results persist 24h server-side
|
|
54
|
+
* Errors: throws on timeout (600s default) after polling exhausted | throws on WebSocket errors after polling attempt | throws on connection close after polling attempt | throws on ERROR messages from server | throws if session expired (404) during polling | graceful fallback to polling prevents data loss
|
|
29
55
|
*/
|
|
30
56
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
31
57
|
if (k2 === undefined) k2 = k;
|
|
@@ -346,6 +372,11 @@ class RemoteAgent {
|
|
|
346
372
|
catch { /* ignore */ }
|
|
347
373
|
this._activeWs = null;
|
|
348
374
|
}
|
|
375
|
+
// Clear session from localStorage
|
|
376
|
+
if (this._currentSession?.session_id) {
|
|
377
|
+
this._clearSession(this._currentSession.session_id);
|
|
378
|
+
}
|
|
379
|
+
this._clearSessionId();
|
|
349
380
|
this._currentSession = null;
|
|
350
381
|
this._chatItems = [];
|
|
351
382
|
this._status = 'idle';
|
|
@@ -508,10 +539,16 @@ class RemoteAgent {
|
|
|
508
539
|
}
|
|
509
540
|
/**
|
|
510
541
|
* Clear session ID from localStorage (browser only).
|
|
542
|
+
* Also clears the full session data.
|
|
511
543
|
*/
|
|
512
544
|
_clearSessionId() {
|
|
513
545
|
if (isBrowserEnv() && typeof globalThis !== 'undefined' && 'localStorage' in globalThis) {
|
|
514
546
|
try {
|
|
547
|
+
// Get active session_id and clear its data
|
|
548
|
+
const activeId = globalThis.localStorage.getItem('connectonion_active_session');
|
|
549
|
+
if (activeId) {
|
|
550
|
+
this._clearSession(activeId);
|
|
551
|
+
}
|
|
515
552
|
globalThis.localStorage.removeItem('connectonion_active_session');
|
|
516
553
|
}
|
|
517
554
|
catch {
|
|
@@ -519,6 +556,75 @@ class RemoteAgent {
|
|
|
519
556
|
}
|
|
520
557
|
}
|
|
521
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Save full session state to localStorage (browser only).
|
|
561
|
+
* Enables conversation recovery after browser refresh.
|
|
562
|
+
*/
|
|
563
|
+
_saveSession(session) {
|
|
564
|
+
if (isBrowserEnv() && typeof globalThis !== 'undefined' && 'localStorage' in globalThis && session.session_id) {
|
|
565
|
+
try {
|
|
566
|
+
const sessionWithTimestamp = {
|
|
567
|
+
...session,
|
|
568
|
+
_savedAt: Date.now()
|
|
569
|
+
};
|
|
570
|
+
const key = `connectonion_session_${session.session_id}`;
|
|
571
|
+
globalThis.localStorage.setItem(key, JSON.stringify(sessionWithTimestamp));
|
|
572
|
+
}
|
|
573
|
+
catch {
|
|
574
|
+
// Ignore localStorage errors (quota exceeded, etc.)
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Load session state from localStorage (browser only).
|
|
580
|
+
* Returns null if session doesn't exist.
|
|
581
|
+
*/
|
|
582
|
+
_loadSession(sessionId) {
|
|
583
|
+
if (isBrowserEnv() && typeof globalThis !== 'undefined' && 'localStorage' in globalThis) {
|
|
584
|
+
try {
|
|
585
|
+
const key = `connectonion_session_${sessionId}`;
|
|
586
|
+
const stored = globalThis.localStorage.getItem(key);
|
|
587
|
+
if (stored) {
|
|
588
|
+
const data = JSON.parse(stored);
|
|
589
|
+
// Remove timestamp before returning
|
|
590
|
+
delete data._savedAt;
|
|
591
|
+
return data;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
catch {
|
|
595
|
+
// Ignore localStorage errors
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Load active session ID from localStorage (browser only).
|
|
602
|
+
*/
|
|
603
|
+
_loadActiveSessionId() {
|
|
604
|
+
if (isBrowserEnv() && typeof globalThis !== 'undefined' && 'localStorage' in globalThis) {
|
|
605
|
+
try {
|
|
606
|
+
return globalThis.localStorage.getItem('connectonion_active_session');
|
|
607
|
+
}
|
|
608
|
+
catch {
|
|
609
|
+
return null;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Clear specific session from localStorage (browser only).
|
|
616
|
+
*/
|
|
617
|
+
_clearSession(sessionId) {
|
|
618
|
+
if (isBrowserEnv() && typeof globalThis !== 'undefined' && 'localStorage' in globalThis) {
|
|
619
|
+
try {
|
|
620
|
+
const key = `connectonion_session_${sessionId}`;
|
|
621
|
+
globalThis.localStorage.removeItem(key);
|
|
622
|
+
}
|
|
623
|
+
catch {
|
|
624
|
+
// Ignore localStorage errors
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
522
628
|
/**
|
|
523
629
|
* Start health check interval to detect dead connections.
|
|
524
630
|
* Checks if PING received within 60 seconds, attempts reconnect if not.
|
|
@@ -596,6 +702,14 @@ class RemoteAgent {
|
|
|
596
702
|
// Set status to working
|
|
597
703
|
this._status = 'working';
|
|
598
704
|
const inputId = generateUUID();
|
|
705
|
+
// Try to restore session from localStorage if not in memory
|
|
706
|
+
const activeSessionId = this._loadActiveSessionId();
|
|
707
|
+
if (activeSessionId && !this._currentSession) {
|
|
708
|
+
const loaded = this._loadSession(activeSessionId);
|
|
709
|
+
if (loaded) {
|
|
710
|
+
this._currentSession = loaded;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
599
713
|
// Generate or reuse session_id for tracking and polling fallback
|
|
600
714
|
const sessionId = this._currentSession?.session_id || generateUUID();
|
|
601
715
|
this._saveSessionId(sessionId);
|
|
@@ -634,16 +748,16 @@ class RemoteAgent {
|
|
|
634
748
|
if (this._enablePolling) {
|
|
635
749
|
try {
|
|
636
750
|
const result = await this._pollForResult(sessionId);
|
|
637
|
-
|
|
751
|
+
// Don't clear session - keep for next message
|
|
638
752
|
resolve({ text: result, done: true });
|
|
639
753
|
}
|
|
640
754
|
catch (pollError) {
|
|
641
|
-
|
|
755
|
+
// Don't clear session - keep for retry with context
|
|
642
756
|
reject(new Error(`Connection timed out and polling failed: ${pollError}`));
|
|
643
757
|
}
|
|
644
758
|
}
|
|
645
759
|
else {
|
|
646
|
-
|
|
760
|
+
// Don't clear session - keep for retry with context
|
|
647
761
|
reject(new Error('Connection timed out'));
|
|
648
762
|
}
|
|
649
763
|
}
|
|
@@ -808,9 +922,10 @@ class RemoteAgent {
|
|
|
808
922
|
clearTimeout(timer);
|
|
809
923
|
this._stopHealthCheck();
|
|
810
924
|
this._status = 'idle';
|
|
811
|
-
// Sync session from server
|
|
925
|
+
// Sync session from server and persist to localStorage
|
|
812
926
|
if (data.session) {
|
|
813
927
|
this._currentSession = data.session;
|
|
928
|
+
this._saveSession(data.session); // Save for next message
|
|
814
929
|
}
|
|
815
930
|
// Add agent response to UI (skip if already added via 'assistant' event)
|
|
816
931
|
const result = data.result || '';
|
|
@@ -821,7 +936,7 @@ class RemoteAgent {
|
|
|
821
936
|
}
|
|
822
937
|
}
|
|
823
938
|
this._activeWs = null; // Clear before close
|
|
824
|
-
|
|
939
|
+
// Don't clear session - keep for next message in conversation
|
|
825
940
|
try {
|
|
826
941
|
ws.close();
|
|
827
942
|
}
|
|
@@ -835,7 +950,7 @@ class RemoteAgent {
|
|
|
835
950
|
this._stopHealthCheck();
|
|
836
951
|
this._status = 'idle';
|
|
837
952
|
this._activeWs = null; // Clear before close
|
|
838
|
-
|
|
953
|
+
// Don't clear session - keep for retry with context
|
|
839
954
|
try {
|
|
840
955
|
ws.close();
|
|
841
956
|
}
|
|
@@ -848,7 +963,7 @@ class RemoteAgent {
|
|
|
848
963
|
clearTimeout(timer);
|
|
849
964
|
this._stopHealthCheck();
|
|
850
965
|
this._status = 'idle';
|
|
851
|
-
|
|
966
|
+
// Don't clear session - keep for retry with context
|
|
852
967
|
try {
|
|
853
968
|
ws.close();
|
|
854
969
|
}
|
|
@@ -871,7 +986,7 @@ class RemoteAgent {
|
|
|
871
986
|
if (this._enablePolling) {
|
|
872
987
|
try {
|
|
873
988
|
const result = await this._pollForResult(sessionId);
|
|
874
|
-
|
|
989
|
+
// Don't clear session - keep for next message
|
|
875
990
|
resolve({ text: result, done: true });
|
|
876
991
|
return;
|
|
877
992
|
}
|
|
@@ -879,7 +994,7 @@ class RemoteAgent {
|
|
|
879
994
|
// Polling failed, fall through to original error
|
|
880
995
|
}
|
|
881
996
|
}
|
|
882
|
-
|
|
997
|
+
// Don't clear session - keep for retry with context
|
|
883
998
|
reject(new Error(`WebSocket error: ${String(err)}`));
|
|
884
999
|
};
|
|
885
1000
|
ws.onclose = async () => {
|
|
@@ -893,7 +1008,7 @@ class RemoteAgent {
|
|
|
893
1008
|
if (this._enablePolling) {
|
|
894
1009
|
try {
|
|
895
1010
|
const result = await this._pollForResult(sessionId);
|
|
896
|
-
|
|
1011
|
+
// Don't clear session - keep for next message
|
|
897
1012
|
resolve({ text: result, done: true });
|
|
898
1013
|
return;
|
|
899
1014
|
}
|
|
@@ -901,7 +1016,7 @@ class RemoteAgent {
|
|
|
901
1016
|
// Polling failed, fall through to original error
|
|
902
1017
|
}
|
|
903
1018
|
}
|
|
904
|
-
|
|
1019
|
+
// Don't clear session - keep for retry with context
|
|
905
1020
|
reject(new Error('Connection closed before response'));
|
|
906
1021
|
}
|
|
907
1022
|
};
|
package/dist/console.d.ts
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @purpose Dual-output logging system (terminal + optional file) that mirrors Python SDK UX with colored terminal output and @xray tool tracing
|
|
3
|
+
*
|
|
4
|
+
* @graph Dual Output Flow
|
|
5
|
+
*
|
|
6
|
+
* Agent / Tool Executor
|
|
7
|
+
* β
|
|
8
|
+
* βΌ
|
|
9
|
+
* console.print(message)
|
|
10
|
+
* β
|
|
11
|
+
* ββββββββββββββββββββββββββββββββ
|
|
12
|
+
* βΌ βΌ
|
|
13
|
+
* ββββββββββββββββββββ βββββββββββββββββββββββββ
|
|
14
|
+
* β stderr (TTY) β β Log File (optional) β
|
|
15
|
+
* β β β β
|
|
16
|
+
* β [HH:MM:SS] β β .co/logs/{name}.log β
|
|
17
|
+
* β + ANSI colors β β plain text, no ANSI β
|
|
18
|
+
* β + dim timestamp β β + [timestamp] prefix β
|
|
19
|
+
* ββββββββββββββββββββ βββββββββββββββββββββββββ
|
|
20
|
+
*
|
|
21
|
+
* @graph @xray Output Block
|
|
22
|
+
*
|
|
23
|
+
* printXray(toolName, args, result, timing, context)
|
|
24
|
+
* β
|
|
25
|
+
* βΌ
|
|
26
|
+
* βββββββββββββββββββββββββββββββββββββββββ
|
|
27
|
+
* β @xray: toolName β
|
|
28
|
+
* β agent: myAgent iter: 3 β
|
|
29
|
+
* β args: { query: "hello" } β
|
|
30
|
+
* β result: "world" β
|
|
31
|
+
* β timing: 42ms β
|
|
32
|
+
* βββββββββββββββββββββββββββββββββββββββββ
|
|
33
|
+
*
|
|
3
34
|
* @llm-note
|
|
4
35
|
* Dependencies: imports from [node:fs, node:path] | imported by [src/core/agent.ts, src/tools/tool-executor.ts] | tested by agent tests
|
|
5
36
|
* Data flow: receives log messages/xray traces β formats with timestamps/colors β writes to stderr + optional file (.co/logs/{name}.log)
|
package/dist/console.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAKH,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,YAAY,CAAU;gBAElB,OAAO,CAAC,EAAE,MAAM;IAM5B,OAAO,CAAC,WAAW;IASnB,KAAK,CAAC,OAAO,EAAE,MAAM;IAUrB,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAgBvE,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;CACb"}
|
package/dist/console.js
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* @purpose Dual-output logging system (terminal + optional file) that mirrors Python SDK UX with colored terminal output and @xray tool tracing
|
|
4
|
+
*
|
|
5
|
+
* @graph Dual Output Flow
|
|
6
|
+
*
|
|
7
|
+
* Agent / Tool Executor
|
|
8
|
+
* β
|
|
9
|
+
* βΌ
|
|
10
|
+
* console.print(message)
|
|
11
|
+
* β
|
|
12
|
+
* ββββββββββββββββββββββββββββββββ
|
|
13
|
+
* βΌ βΌ
|
|
14
|
+
* ββββββββββββββββββββ βββββββββββββββββββββββββ
|
|
15
|
+
* β stderr (TTY) β β Log File (optional) β
|
|
16
|
+
* β β β β
|
|
17
|
+
* β [HH:MM:SS] β β .co/logs/{name}.log β
|
|
18
|
+
* β + ANSI colors β β plain text, no ANSI β
|
|
19
|
+
* β + dim timestamp β β + [timestamp] prefix β
|
|
20
|
+
* ββββββββββββββββββββ βββββββββββββββββββββββββ
|
|
21
|
+
*
|
|
22
|
+
* @graph @xray Output Block
|
|
23
|
+
*
|
|
24
|
+
* printXray(toolName, args, result, timing, context)
|
|
25
|
+
* β
|
|
26
|
+
* βΌ
|
|
27
|
+
* βββββββββββββββββββββββββββββββββββββββββ
|
|
28
|
+
* β @xray: toolName β
|
|
29
|
+
* β agent: myAgent iter: 3 β
|
|
30
|
+
* β args: { query: "hello" } β
|
|
31
|
+
* β result: "world" β
|
|
32
|
+
* β timing: 42ms β
|
|
33
|
+
* βββββββββββββββββββββββββββββββββββββββββ
|
|
34
|
+
*
|
|
4
35
|
* @llm-note
|
|
5
36
|
* Dependencies: imports from [node:fs, node:path] | imported by [src/core/agent.ts, src/tools/tool-executor.ts] | tested by agent tests
|
|
6
37
|
* Data flow: receives log messages/xray traces β formats with timestamps/colors β writes to stderr + optional file (.co/logs/{name}.log)
|