@agentxjs/portagent 0.1.8 → 1.0.0

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 ADDED
@@ -0,0 +1,357 @@
1
+ # Portagent
2
+
3
+ ![Portagent Demo](./public/Portagent.gif)
4
+
5
+ Portagent is a multi-user AI Agent gateway powered by [AgentX](https://github.com/Deepractice/AgentX). It provides a web-based interface for interacting with Claude AI agents, with built-in user authentication and session management.
6
+
7
+ ## Features
8
+
9
+ - **Multi-User Support**: User registration and authentication with JWT tokens
10
+ - **WebSocket Communication**: Real-time bidirectional communication with AI agents
11
+ - **Invite Code System**: Optional invite code for controlled access
12
+ - **Persistent Storage**: SQLite-based storage for users, sessions, and agent data
13
+ - **Docker Ready**: Pre-built Docker images for easy deployment
14
+ - **Claude Integration**: Powered by Anthropic's Claude API via Claude Agent SDK
15
+
16
+ ## Quick Start
17
+
18
+ ### Using Docker (Recommended)
19
+
20
+ ```bash
21
+ docker run -d \
22
+ --name portagent \
23
+ -p 5200:5200 \
24
+ -e LLM_PROVIDER_KEY=sk-ant-xxxxx \
25
+ -v ./data:/home/agentx/.agentx \
26
+ deepracticexs/portagent:latest
27
+ ```
28
+
29
+ Then open <http://localhost:5200> in your browser.
30
+
31
+ ### Using Docker Compose
32
+
33
+ Create a `.env` file:
34
+
35
+ ```env
36
+ LLM_PROVIDER_KEY=sk-ant-xxxxx
37
+ JWT_SECRET=your-secure-random-secret
38
+ ```
39
+
40
+ Create `docker-compose.yml`:
41
+
42
+ ```yaml
43
+ services:
44
+ portagent:
45
+ image: deepracticexs/portagent:latest
46
+ container_name: portagent
47
+ restart: unless-stopped
48
+ ports:
49
+ - "5200:5200"
50
+ environment:
51
+ - LLM_PROVIDER_KEY=${LLM_PROVIDER_KEY}
52
+ - LLM_PROVIDER_URL=${LLM_PROVIDER_URL:-https://api.anthropic.com}
53
+ - LLM_PROVIDER_MODEL=${LLM_PROVIDER_MODEL:-claude-sonnet-4-20250514}
54
+ - JWT_SECRET=${JWT_SECRET}
55
+ - INVITE_CODE_REQUIRED=${INVITE_CODE_REQUIRED:-false}
56
+ - LOG_LEVEL=${LOG_LEVEL:-info}
57
+ volumes:
58
+ - ./data:/home/agentx/.agentx
59
+ healthcheck:
60
+ test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5200/health"]
61
+ interval: 30s
62
+ timeout: 10s
63
+ start_period: 5s
64
+ retries: 3
65
+ ```
66
+
67
+ Run:
68
+
69
+ ```bash
70
+ docker compose up -d
71
+ ```
72
+
73
+ ### Using npm
74
+
75
+ ```bash
76
+ # Install globally
77
+ npm install -g @agentxjs/portagent
78
+
79
+ # Run with required API key
80
+ export LLM_PROVIDER_KEY=sk-ant-xxxxx
81
+ portagent
82
+ ```
83
+
84
+ ## Configuration
85
+
86
+ ### Environment Variables
87
+
88
+ | Variable | Required | Default | Description |
89
+ | ---------------------- | -------- | --------------------------- | ------------------------------------------- |
90
+ | `LLM_PROVIDER_KEY` | **Yes** | - | Anthropic API key (starts with `sk-ant-`) |
91
+ | `LLM_PROVIDER_URL` | No | `https://api.anthropic.com` | API base URL |
92
+ | `LLM_PROVIDER_MODEL` | No | `claude-sonnet-4-20250514` | Claude model to use |
93
+ | `PORT` | No | `5200` | Server port |
94
+ | `DATA_DIR` | No | `~/.agentx` | Data directory path |
95
+ | `JWT_SECRET` | No | Auto-generated | Secret for JWT token signing |
96
+ | `INVITE_CODE_REQUIRED` | No | `false` | Require invite code for registration |
97
+ | `LOG_LEVEL` | No | `info` | Log level: `debug`, `info`, `warn`, `error` |
98
+ | `NODE_ENV` | No | `production` | Environment mode |
99
+
100
+ ### CLI Options
101
+
102
+ ```bash
103
+ portagent [options]
104
+
105
+ Options:
106
+ -p, --port <port> Port to listen on (default: 5200)
107
+ -d, --data-dir <path> Data directory (default: ~/.agentx)
108
+ -e, --env-file <path> Path to environment file
109
+ --jwt-secret <secret> JWT secret for token signing
110
+ --api-key <key> LLM provider API key
111
+ --api-url <url> LLM provider base URL
112
+ --model <model> LLM model name
113
+ -h, --help Display help
114
+ -V, --version Display version
115
+ ```
116
+
117
+ ### Data Directory Structure
118
+
119
+ ```text
120
+ ~/.agentx/ # Default data directory (configurable via DATA_DIR)
121
+ ├── data/ # Database files
122
+ │ ├── agentx.db # AgentX data (containers, images, sessions)
123
+ │ └── portagent.db # User authentication data
124
+ └── logs/ # Log files
125
+ └── portagent.log
126
+ ```
127
+
128
+ ## Invite Code System
129
+
130
+ Portagent uses a daily rotating invite code for registration security. The invite code is the **Unix timestamp (in seconds) of today's 00:00:01** in the server's timezone.
131
+
132
+ ### Calculating the Invite Code
133
+
134
+ **Linux/macOS:**
135
+
136
+ ```bash
137
+ # For server's local timezone
138
+ date -d "today 00:00:01" +%s
139
+
140
+ # For UTC (Docker default)
141
+ TZ=UTC date -d "today 00:00:01" +%s
142
+
143
+ # macOS syntax
144
+ date -j -f "%Y-%m-%d %H:%M:%S" "$(date +%Y-%m-%d) 00:00:01" "+%s"
145
+ ```
146
+
147
+ **JavaScript:**
148
+
149
+ ```javascript
150
+ // Server's local timezone
151
+ const now = new Date();
152
+ const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1);
153
+ const inviteCode = Math.floor(todayStart.getTime() / 1000);
154
+ console.log(inviteCode);
155
+ ```
156
+
157
+ **Note:** Docker containers typically run in UTC timezone. Make sure to calculate the invite code for the correct timezone.
158
+
159
+ ### Enabling Invite Codes
160
+
161
+ Set `INVITE_CODE_REQUIRED=true` to require invite codes for registration:
162
+
163
+ ```bash
164
+ docker run -e INVITE_CODE_REQUIRED=true ...
165
+ ```
166
+
167
+ ## API Endpoints
168
+
169
+ | Method | Path | Auth | Description |
170
+ | ------ | -------------------- | ---- | ---------------------- |
171
+ | GET | `/health` | No | Health check |
172
+ | GET | `/api/auth/config` | No | Get auth configuration |
173
+ | POST | `/api/auth/register` | No | Register new user |
174
+ | POST | `/api/auth/login` | No | Login |
175
+ | GET | `/api/auth/verify` | Yes | Verify token |
176
+ | POST | `/api/auth/logout` | No | Logout (client-side) |
177
+ | GET | `/agentx/info` | Yes | Get platform info |
178
+ | WS | `/ws` | Yes | WebSocket connection |
179
+
180
+ ### Authentication
181
+
182
+ All protected endpoints require a JWT token in the Authorization header:
183
+
184
+ ```text
185
+ Authorization: Bearer <token>
186
+ ```
187
+
188
+ For WebSocket connections (which don't support headers), pass the token as a query parameter:
189
+
190
+ ```text
191
+ ws://localhost:5200/ws?token=<token>
192
+ ```
193
+
194
+ ### Register
195
+
196
+ ```bash
197
+ curl -X POST http://localhost:5200/api/auth/register \
198
+ -H "Content-Type: application/json" \
199
+ -d '{
200
+ "username": "john",
201
+ "password": "secret123",
202
+ "inviteCode": "1765152001",
203
+ "email": "john@example.com",
204
+ "displayName": "John Doe"
205
+ }'
206
+ ```
207
+
208
+ ### Login
209
+
210
+ ```bash
211
+ curl -X POST http://localhost:5200/api/auth/login \
212
+ -H "Content-Type: application/json" \
213
+ -d '{
214
+ "usernameOrEmail": "john",
215
+ "password": "secret123"
216
+ }'
217
+ ```
218
+
219
+ ## Docker Images
220
+
221
+ Pre-built images are available on Docker Hub:
222
+
223
+ ```bash
224
+ # Latest version
225
+ docker pull deepracticexs/portagent:latest
226
+
227
+ # Specific version
228
+ docker pull deepracticexs/portagent:0.1.9
229
+
230
+ # Available architectures: linux/amd64, linux/arm64
231
+ ```
232
+
233
+ ### Building Locally
234
+
235
+ ```bash
236
+ # From repository root
237
+ docker build -t portagent:local -f apps/portagent/Dockerfile .
238
+
239
+ # Run local build
240
+ docker run -d \
241
+ --name portagent \
242
+ -p 5200:5200 \
243
+ -e LLM_PROVIDER_KEY=sk-ant-xxxxx \
244
+ portagent:local
245
+ ```
246
+
247
+ ## Production Deployment
248
+
249
+ ### Recommended Settings
250
+
251
+ ```yaml
252
+ services:
253
+ portagent:
254
+ image: deepracticexs/portagent:0.1.9 # Pin to specific version
255
+ restart: unless-stopped
256
+ environment:
257
+ - LLM_PROVIDER_KEY=${LLM_PROVIDER_KEY}
258
+ - JWT_SECRET=${JWT_SECRET} # Use a strong, persistent secret
259
+ - INVITE_CODE_REQUIRED=true # Enable for production
260
+ - LOG_LEVEL=info
261
+ volumes:
262
+ - ./data:/home/agentx/.agentx # Persist data
263
+ ports:
264
+ - "5200:5200"
265
+ ```
266
+
267
+ ### Security Considerations
268
+
269
+ 1. **API Key**: Never expose `LLM_PROVIDER_KEY` in client-side code or logs
270
+ 2. **JWT Secret**: Use a strong, random secret and keep it consistent across restarts
271
+ 3. **Invite Codes**: Enable invite codes in production to control access
272
+ 4. **HTTPS**: Use a reverse proxy (nginx, Caddy) with TLS in production
273
+ 5. **Volume Permissions**: The container runs as non-root user (uid 1001)
274
+
275
+ ### Reverse Proxy (nginx example)
276
+
277
+ ```nginx
278
+ server {
279
+ listen 443 ssl;
280
+ server_name portagent.example.com;
281
+
282
+ ssl_certificate /path/to/cert.pem;
283
+ ssl_certificate_key /path/to/key.pem;
284
+
285
+ location / {
286
+ proxy_pass http://localhost:5200;
287
+ proxy_http_version 1.1;
288
+ proxy_set_header Upgrade $http_upgrade;
289
+ proxy_set_header Connection "upgrade";
290
+ proxy_set_header Host $host;
291
+ proxy_set_header X-Real-IP $remote_addr;
292
+ }
293
+ }
294
+ ```
295
+
296
+ ## Troubleshooting
297
+
298
+ ### "LLM_PROVIDER_KEY is required"
299
+
300
+ - Ensure `LLM_PROVIDER_KEY` environment variable is set
301
+ - For Docker, use `-e LLM_PROVIDER_KEY=xxx` or `environment:` in compose
302
+
303
+ ### "Invalid invite code"
304
+
305
+ - Invite code changes daily at midnight (server timezone)
306
+ - Docker uses UTC by default
307
+ - Calculate code for correct timezone (see Invite Code section)
308
+ - Set `INVITE_CODE_REQUIRED=false` to disable
309
+
310
+ ### Permission denied errors
311
+
312
+ - Docker container runs as user `agentx` (uid 1001)
313
+ - Ensure mounted volumes have correct permissions:
314
+
315
+ ```bash
316
+ sudo chown -R 1001:1001 ./data
317
+ ```
318
+
319
+ ### WebSocket connection fails
320
+
321
+ - Ensure token is passed as query parameter for WS connections
322
+ - Check reverse proxy WebSocket configuration
323
+
324
+ ### Viewing Logs
325
+
326
+ ```bash
327
+ # Docker logs
328
+ docker logs portagent
329
+
330
+ # Follow logs
331
+ docker logs -f portagent
332
+
333
+ # Log files inside container
334
+ docker exec portagent cat /home/agentx/.agentx/logs/portagent.log
335
+ ```
336
+
337
+ ## Development
338
+
339
+ ```bash
340
+ # Clone repository
341
+ git clone https://github.com/Deepractice/AgentX.git
342
+ cd AgentX
343
+
344
+ # Install dependencies
345
+ pnpm install
346
+
347
+ # Build all packages
348
+ pnpm build
349
+
350
+ # Start development server
351
+ cd apps/portagent
352
+ pnpm dev
353
+ ```
354
+
355
+ ## License
356
+
357
+ MIT License - see [LICENSE](./LICENSE) for details.
Binary file
@@ -0,0 +1,2 @@
1
+ import{_ as w}from"./index-Bq2LVeC5.js";var p=Object.defineProperty,m=(e,r,t)=>r in e?p(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,c=(e,r,t)=>m(e,typeof r!="symbol"?r+"":r,t),b=class u{constructor(r,t={}){c(this,"name"),c(this,"level"),c(this,"colors"),c(this,"timestamps"),this.name=r,this.level=t.level??"info",this.colors=t.colors??this.isNodeEnvironment(),this.timestamps=t.timestamps??!0}debug(r,t){this.isDebugEnabled()&&this.log("DEBUG",r,t)}info(r,t){this.isInfoEnabled()&&this.log("INFO",r,t)}warn(r,t){this.isWarnEnabled()&&this.log("WARN",r,t)}error(r,t){this.isErrorEnabled()&&(r instanceof Error?this.log("ERROR",r.message,{...t,stack:r.stack}):this.log("ERROR",r,t))}isDebugEnabled(){return this.getLevelValue(this.level)<=this.getLevelValue("debug")}isInfoEnabled(){return this.getLevelValue(this.level)<=this.getLevelValue("info")}isWarnEnabled(){return this.getLevelValue(this.level)<=this.getLevelValue("warn")}isErrorEnabled(){return this.getLevelValue(this.level)<=this.getLevelValue("error")}getLevelValue(r){return{debug:0,info:1,warn:2,error:3,silent:4}[r]}log(r,t,o){const s=[];if(this.timestamps&&s.push(new Date().toISOString()),this.colors){const d=u.COLORS[r];s.push(`${d}${r.padEnd(5)}${u.COLORS.RESET}`)}else s.push(r.padEnd(5));s.push(`[${this.name}]`),s.push(t);const n=s.join(" "),l=this.getConsoleMethod(r);o&&Object.keys(o).length>0?l(n,o):l(n)}getConsoleMethod(r){switch(r){case"DEBUG":return console.debug.bind(console);case"INFO":return console.info.bind(console);case"WARN":return console.warn.bind(console);case"ERROR":return console.error.bind(console);default:return console.log.bind(console)}}isNodeEnvironment(){var r;return typeof process<"u"&&((r=process.versions)==null?void 0:r.node)!==void 0}};c(b,"COLORS",{DEBUG:"\x1B[36m",INFO:"\x1B[32m",WARN:"\x1B[33m",ERROR:"\x1B[31m",RESET:"\x1B[0m"});var E=b,h=null,g=class{static getLogger(e){const r=typeof e=="string"?e:e.name;if(this.loggers.has(r))return this.loggers.get(r);const t=this.createLazyLogger(r);return this.loggers.set(r,t),t}static configure(e){this.config={...this.config,...e}}static reset(){this.loggers.clear(),this.config={defaultLevel:"info"},h=null}static createLazyLogger(e){let r=null;const t=()=>(r||(r=this.createLogger(e)),r);return{name:e,level:this.config.defaultLevel||"info",debug:(o,s)=>t().debug(o,s),info:(o,s)=>t().info(o,s),warn:(o,s)=>t().warn(o,s),error:(o,s)=>t().error(o,s),isDebugEnabled:()=>t().isDebugEnabled(),isInfoEnabled:()=>t().isInfoEnabled(),isWarnEnabled:()=>t().isWarnEnabled(),isErrorEnabled:()=>t().isErrorEnabled()}}static createLogger(e){return h?h.getLogger(e):this.config.defaultImplementation?this.config.defaultImplementation(e):new E(e,{level:this.config.defaultLevel,...this.config.consoleOptions})}};c(g,"loggers",new Map);c(g,"config",{defaultLevel:"info"});function v(e){return g.getLogger(e)}var S=Object.defineProperty,H=(e,r,t)=>r in e?S(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,i=(e,r,t)=>H(e,typeof r!="symbol"?r+"":r,t),a=v("network/WebSocketClient"),f=typeof globalThis<"u"&&typeof globalThis.window<"u"&&typeof globalThis.window.WebSocket<"u",L=class{constructor(e){if(i(this,"ws",null),i(this,"serverUrl"),i(this,"messageHandlers",new Set),i(this,"openHandlers",new Set),i(this,"closeHandlers",new Set),i(this,"errorHandlers",new Set),f)throw new Error("Use createBrowserWebSocketClient() in browser environment for auto-reconnect support");this.serverUrl=e.serverUrl}get readyState(){if(!this.ws)return"closed";const e=this.ws.readyState;return e===0?"connecting":e===1?"open":e===2?"closing":"closed"}async connect(){if(this.ws)throw new Error("Already connected or connecting");const{WebSocket:e}=await w(async()=>{const{WebSocket:r}=await import("./browser-C0DG1J1h.js").then(t=>t.b);return{WebSocket:r}},[]);return this.ws=new e(this.serverUrl),new Promise((r,t)=>{const o=()=>{a.info("WebSocket connected",{serverUrl:this.serverUrl});for(const n of this.openHandlers)n();r()},s=n=>{a.error("WebSocket connection failed",{serverUrl:this.serverUrl,error:n==null?void 0:n.message}),t(n||new Error("WebSocket connection failed"))};this.ws.once("open",o),this.ws.once("error",s),this.ws.on("message",n=>{const l=n.toString();for(const d of this.messageHandlers)d(l)}),this.ws.on("close",()=>{a.warn("WebSocket closed");for(const n of this.closeHandlers)n()}),this.ws.on("error",n=>{a.error("WebSocket error",{error:n.message});for(const l of this.errorHandlers)l(n)})})}send(e){if(!this.ws||this.ws.readyState!==1)throw new Error("WebSocket is not open");this.ws.send(e)}onMessage(e){return this.messageHandlers.add(e),()=>{this.messageHandlers.delete(e)}}onOpen(e){return this.openHandlers.add(e),()=>{this.openHandlers.delete(e)}}onClose(e){return this.closeHandlers.add(e),()=>{this.closeHandlers.delete(e)}}onError(e){return this.errorHandlers.add(e),()=>{this.errorHandlers.delete(e)}}close(){this.ws&&(this.ws.close(),this.ws=null)}dispose(){this.close(),this.messageHandlers.clear(),this.openHandlers.clear(),this.closeHandlers.clear(),this.errorHandlers.clear()}},W=class{constructor(e){if(i(this,"ws",null),i(this,"serverUrl"),i(this,"options"),i(this,"messageHandlers",new Set),i(this,"openHandlers",new Set),i(this,"closeHandlers",new Set),i(this,"errorHandlers",new Set),i(this,"hasConnectedBefore",!1),!f)throw new Error("BrowserWebSocketClient can only be used in browser environment");this.serverUrl=e.serverUrl,this.options={autoReconnect:!0,minReconnectionDelay:1e3,maxReconnectionDelay:1e4,maxRetries:1/0,connectionTimeout:4e3,debug:!1,...e}}get readyState(){if(!this.ws)return"closed";const e=this.ws.readyState;return e===0?"connecting":e===1?"open":e===2?"closing":"closed"}async connect(){if(this.ws)throw new Error("Already connected or connecting");if(this.options.autoReconnect){const e=(await w(async()=>{const{default:r}=await import("./reconnecting-websocket-mjs-Dd04wD44.js");return{default:r}},[])).default;this.ws=new e(this.serverUrl,[],{maxReconnectionDelay:this.options.maxReconnectionDelay,minReconnectionDelay:this.options.minReconnectionDelay,reconnectionDelayGrowFactor:1.3,connectionTimeout:this.options.connectionTimeout,maxRetries:this.options.maxRetries,debug:this.options.debug})}else this.ws=new WebSocket(this.serverUrl);return new Promise((e,r)=>{const t=()=>{this.hasConnectedBefore?a.info("WebSocket reconnected successfully",{serverUrl:this.serverUrl}):(a.info("WebSocket connected",{serverUrl:this.serverUrl}),this.hasConnectedBefore=!0);for(const s of this.openHandlers)s();e()},o=s=>{a.error("WebSocket connection failed",{serverUrl:this.serverUrl});const n=new Error("WebSocket connection failed");for(const l of this.errorHandlers)l(n);r(n)};this.ws.addEventListener("open",t,{once:!0}),this.ws.addEventListener("error",o,{once:!0}),this.ws.addEventListener("message",(s=>{const n=s.data;for(const l of this.messageHandlers)l(n)})),this.ws.addEventListener("close",(()=>{a.info("WebSocket closed, attempting to reconnect...");for(const s of this.closeHandlers)s()})),this.ws.addEventListener("error",(s=>{a.error("WebSocket error");const n=new Error("WebSocket error");for(const l of this.errorHandlers)l(n)}))})}send(e){if(!this.ws||this.ws.readyState!==1)throw new Error("WebSocket is not open");this.ws.send(e)}onMessage(e){return this.messageHandlers.add(e),()=>{this.messageHandlers.delete(e)}}onOpen(e){return this.openHandlers.add(e),()=>{this.openHandlers.delete(e)}}onClose(e){return this.closeHandlers.add(e),()=>{this.closeHandlers.delete(e)}}onError(e){return this.errorHandlers.add(e),()=>{this.errorHandlers.delete(e)}}close(){this.ws&&(this.ws.close(),this.ws=null)}dispose(){this.close(),this.messageHandlers.clear(),this.openHandlers.clear(),this.closeHandlers.clear(),this.errorHandlers.clear()}};async function y(e){if(f){const r=new W(e);return await r.connect(),r}else{const r=new L(e);return await r.connect(),r}}v("network/WebSocketServer");export{L as WebSocketClient,y as createWebSocketClient};
2
+ //# sourceMappingURL=index-1uLnFQV1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":["__defProp","__defNormalProp","obj","key","value","__publicField","_ConsoleLogger","name","options","message","context","level","parts","color","logLine","consoleMethod","_a","ConsoleLogger","externalFactory","LoggerFactoryImpl","nameOrClass","lazyLogger","config","realLogger","getRealLogger","createLogger","logger","isBrowser","WebSocketClient","state","NodeWebSocket","__vitePreload","n","resolve","reject","onOpen","handler","onError","err","data","BrowserWebSocketClient","ReconnectingWebSocket","__vite_default__","_event","error","event","createWebSocketClient","client"],"ignoreList":[],"sources":["../../../../../packages/common/dist/index.js","../../../../../packages/network/dist/chunk-63P5VUHB.js","../../../../../packages/network/dist/index.js"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n\n// src/logger/ConsoleLogger.ts\nvar _ConsoleLogger = class _ConsoleLogger {\n constructor(name, options = {}) {\n __publicField(this, \"name\");\n __publicField(this, \"level\");\n __publicField(this, \"colors\");\n __publicField(this, \"timestamps\");\n this.name = name;\n this.level = options.level ?? \"info\";\n this.colors = options.colors ?? this.isNodeEnvironment();\n this.timestamps = options.timestamps ?? true;\n }\n debug(message, context) {\n if (this.isDebugEnabled()) {\n this.log(\"DEBUG\", message, context);\n }\n }\n info(message, context) {\n if (this.isInfoEnabled()) {\n this.log(\"INFO\", message, context);\n }\n }\n warn(message, context) {\n if (this.isWarnEnabled()) {\n this.log(\"WARN\", message, context);\n }\n }\n error(message, context) {\n if (this.isErrorEnabled()) {\n if (message instanceof Error) {\n this.log(\"ERROR\", message.message, { ...context, stack: message.stack });\n } else {\n this.log(\"ERROR\", message, context);\n }\n }\n }\n isDebugEnabled() {\n return this.getLevelValue(this.level) <= this.getLevelValue(\"debug\");\n }\n isInfoEnabled() {\n return this.getLevelValue(this.level) <= this.getLevelValue(\"info\");\n }\n isWarnEnabled() {\n return this.getLevelValue(this.level) <= this.getLevelValue(\"warn\");\n }\n isErrorEnabled() {\n return this.getLevelValue(this.level) <= this.getLevelValue(\"error\");\n }\n getLevelValue(level) {\n const levels = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4\n };\n return levels[level];\n }\n log(level, message, context) {\n const parts = [];\n if (this.timestamps) {\n parts.push((/* @__PURE__ */ new Date()).toISOString());\n }\n if (this.colors) {\n const color = _ConsoleLogger.COLORS[level];\n parts.push(`${color}${level.padEnd(5)}${_ConsoleLogger.COLORS.RESET}`);\n } else {\n parts.push(level.padEnd(5));\n }\n parts.push(`[${this.name}]`);\n parts.push(message);\n const logLine = parts.join(\" \");\n const consoleMethod = this.getConsoleMethod(level);\n if (context && Object.keys(context).length > 0) {\n consoleMethod(logLine, context);\n } else {\n consoleMethod(logLine);\n }\n }\n getConsoleMethod(level) {\n switch (level) {\n case \"DEBUG\":\n return console.debug.bind(console);\n case \"INFO\":\n return console.info.bind(console);\n case \"WARN\":\n return console.warn.bind(console);\n case \"ERROR\":\n return console.error.bind(console);\n default:\n return console.log.bind(console);\n }\n }\n isNodeEnvironment() {\n return typeof process !== \"undefined\" && process.versions?.node !== void 0;\n }\n};\n__publicField(_ConsoleLogger, \"COLORS\", {\n DEBUG: \"\\x1B[36m\",\n INFO: \"\\x1B[32m\",\n WARN: \"\\x1B[33m\",\n ERROR: \"\\x1B[31m\",\n RESET: \"\\x1B[0m\"\n});\nvar ConsoleLogger = _ConsoleLogger;\n\n// src/logger/LoggerFactoryImpl.ts\nvar externalFactory = null;\nvar LoggerFactoryImpl = class {\n static getLogger(nameOrClass) {\n const name = typeof nameOrClass === \"string\" ? nameOrClass : nameOrClass.name;\n if (this.loggers.has(name)) {\n return this.loggers.get(name);\n }\n const lazyLogger = this.createLazyLogger(name);\n this.loggers.set(name, lazyLogger);\n return lazyLogger;\n }\n static configure(config) {\n this.config = { ...this.config, ...config };\n }\n static reset() {\n this.loggers.clear();\n this.config = { defaultLevel: \"info\" };\n externalFactory = null;\n }\n static createLazyLogger(name) {\n let realLogger = null;\n const getRealLogger = () => {\n if (!realLogger) {\n realLogger = this.createLogger(name);\n }\n return realLogger;\n };\n return {\n name,\n level: this.config.defaultLevel || \"info\",\n debug: (message, context) => getRealLogger().debug(message, context),\n info: (message, context) => getRealLogger().info(message, context),\n warn: (message, context) => getRealLogger().warn(message, context),\n error: (message, context) => getRealLogger().error(message, context),\n isDebugEnabled: () => getRealLogger().isDebugEnabled(),\n isInfoEnabled: () => getRealLogger().isInfoEnabled(),\n isWarnEnabled: () => getRealLogger().isWarnEnabled(),\n isErrorEnabled: () => getRealLogger().isErrorEnabled()\n };\n }\n static createLogger(name) {\n if (externalFactory) {\n return externalFactory.getLogger(name);\n }\n if (this.config.defaultImplementation) {\n return this.config.defaultImplementation(name);\n }\n return new ConsoleLogger(name, {\n level: this.config.defaultLevel,\n ...this.config.consoleOptions\n });\n }\n};\n__publicField(LoggerFactoryImpl, \"loggers\", /* @__PURE__ */ new Map());\n__publicField(LoggerFactoryImpl, \"config\", {\n defaultLevel: \"info\"\n});\nfunction setLoggerFactory(factory) {\n externalFactory = factory;\n LoggerFactoryImpl.reset();\n externalFactory = factory;\n}\nfunction createLogger(name) {\n return LoggerFactoryImpl.getLogger(name);\n}\nexport {\n ConsoleLogger,\n LoggerFactoryImpl,\n createLogger,\n setLoggerFactory\n};\n//# sourceMappingURL=index.js.map","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\n\n// src/WebSocketClient.ts\nimport { createLogger } from \"@agentxjs/common\";\nvar logger = createLogger(\"network/WebSocketClient\");\nvar isBrowser = typeof globalThis !== \"undefined\" && typeof globalThis.window !== \"undefined\" && typeof globalThis.window.WebSocket !== \"undefined\";\nvar WebSocketClient = class {\n constructor(options) {\n __publicField(this, \"ws\", null);\n __publicField(this, \"serverUrl\");\n __publicField(this, \"messageHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"openHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"closeHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"errorHandlers\", /* @__PURE__ */ new Set());\n if (isBrowser) {\n throw new Error(\n \"Use createBrowserWebSocketClient() in browser environment for auto-reconnect support\"\n );\n }\n this.serverUrl = options.serverUrl;\n }\n get readyState() {\n if (!this.ws) return \"closed\";\n const state = this.ws.readyState;\n if (state === 0) return \"connecting\";\n if (state === 1) return \"open\";\n if (state === 2) return \"closing\";\n return \"closed\";\n }\n async connect() {\n if (this.ws) {\n throw new Error(\"Already connected or connecting\");\n }\n const { WebSocket: NodeWebSocket } = await import(\"ws\");\n this.ws = new NodeWebSocket(this.serverUrl);\n return new Promise((resolve, reject) => {\n const onOpen = () => {\n logger.info(\"WebSocket connected\", { serverUrl: this.serverUrl });\n for (const handler of this.openHandlers) {\n handler();\n }\n resolve();\n };\n const onError = (err) => {\n logger.error(\"WebSocket connection failed\", {\n serverUrl: this.serverUrl,\n error: err?.message\n });\n reject(err || new Error(\"WebSocket connection failed\"));\n };\n this.ws.once(\"open\", onOpen);\n this.ws.once(\"error\", onError);\n this.ws.on(\"message\", (data) => {\n const message = data.toString();\n for (const handler of this.messageHandlers) {\n handler(message);\n }\n });\n this.ws.on(\"close\", () => {\n logger.warn(\"WebSocket closed\");\n for (const handler of this.closeHandlers) {\n handler();\n }\n });\n this.ws.on(\"error\", (err) => {\n logger.error(\"WebSocket error\", { error: err.message });\n for (const handler of this.errorHandlers) {\n handler(err);\n }\n });\n });\n }\n send(message) {\n if (!this.ws || this.ws.readyState !== 1) {\n throw new Error(\"WebSocket is not open\");\n }\n this.ws.send(message);\n }\n onMessage(handler) {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n onOpen(handler) {\n this.openHandlers.add(handler);\n return () => {\n this.openHandlers.delete(handler);\n };\n }\n onClose(handler) {\n this.closeHandlers.add(handler);\n return () => {\n this.closeHandlers.delete(handler);\n };\n }\n onError(handler) {\n this.errorHandlers.add(handler);\n return () => {\n this.errorHandlers.delete(handler);\n };\n }\n close() {\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n dispose() {\n this.close();\n this.messageHandlers.clear();\n this.openHandlers.clear();\n this.closeHandlers.clear();\n this.errorHandlers.clear();\n }\n};\nvar BrowserWebSocketClient = class {\n // Track if this is a reconnection\n constructor(options) {\n __publicField(this, \"ws\", null);\n __publicField(this, \"serverUrl\");\n __publicField(this, \"options\");\n __publicField(this, \"messageHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"openHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"closeHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"errorHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"hasConnectedBefore\", false);\n if (!isBrowser) {\n throw new Error(\"BrowserWebSocketClient can only be used in browser environment\");\n }\n this.serverUrl = options.serverUrl;\n this.options = {\n autoReconnect: true,\n minReconnectionDelay: 1e3,\n maxReconnectionDelay: 1e4,\n maxRetries: Infinity,\n connectionTimeout: 4e3,\n debug: false,\n ...options\n };\n }\n get readyState() {\n if (!this.ws) return \"closed\";\n const state = this.ws.readyState;\n if (state === 0) return \"connecting\";\n if (state === 1) return \"open\";\n if (state === 2) return \"closing\";\n return \"closed\";\n }\n async connect() {\n if (this.ws) {\n throw new Error(\"Already connected or connecting\");\n }\n if (this.options.autoReconnect) {\n const ReconnectingWebSocket = (await import(\"reconnecting-websocket\")).default;\n this.ws = new ReconnectingWebSocket(this.serverUrl, [], {\n maxReconnectionDelay: this.options.maxReconnectionDelay,\n minReconnectionDelay: this.options.minReconnectionDelay,\n reconnectionDelayGrowFactor: 1.3,\n connectionTimeout: this.options.connectionTimeout,\n maxRetries: this.options.maxRetries,\n debug: this.options.debug\n });\n } else {\n this.ws = new WebSocket(this.serverUrl);\n }\n return new Promise((resolve, reject) => {\n const onOpen = () => {\n if (this.hasConnectedBefore) {\n logger.info(\"WebSocket reconnected successfully\", { serverUrl: this.serverUrl });\n } else {\n logger.info(\"WebSocket connected\", { serverUrl: this.serverUrl });\n this.hasConnectedBefore = true;\n }\n for (const handler of this.openHandlers) {\n handler();\n }\n resolve();\n };\n const onError = (_event) => {\n logger.error(\"WebSocket connection failed\", { serverUrl: this.serverUrl });\n const error = new Error(\"WebSocket connection failed\");\n for (const handler of this.errorHandlers) {\n handler(error);\n }\n reject(error);\n };\n this.ws.addEventListener(\"open\", onOpen, { once: true });\n this.ws.addEventListener(\"error\", onError, { once: true });\n this.ws.addEventListener(\"message\", ((event) => {\n const message = event.data;\n for (const handler of this.messageHandlers) {\n handler(message);\n }\n }));\n this.ws.addEventListener(\"close\", (() => {\n logger.info(\"WebSocket closed, attempting to reconnect...\");\n for (const handler of this.closeHandlers) {\n handler();\n }\n }));\n this.ws.addEventListener(\"error\", ((_event) => {\n logger.error(\"WebSocket error\");\n const error = new Error(\"WebSocket error\");\n for (const handler of this.errorHandlers) {\n handler(error);\n }\n }));\n });\n }\n send(message) {\n if (!this.ws || this.ws.readyState !== 1) {\n throw new Error(\"WebSocket is not open\");\n }\n this.ws.send(message);\n }\n onMessage(handler) {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n onOpen(handler) {\n this.openHandlers.add(handler);\n return () => {\n this.openHandlers.delete(handler);\n };\n }\n onClose(handler) {\n this.closeHandlers.add(handler);\n return () => {\n this.closeHandlers.delete(handler);\n };\n }\n onError(handler) {\n this.errorHandlers.add(handler);\n return () => {\n this.errorHandlers.delete(handler);\n };\n }\n close() {\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n dispose() {\n this.close();\n this.messageHandlers.clear();\n this.openHandlers.clear();\n this.closeHandlers.clear();\n this.errorHandlers.clear();\n }\n};\nasync function createWebSocketClient(options) {\n if (isBrowser) {\n const client = new BrowserWebSocketClient(options);\n await client.connect();\n return client;\n } else {\n const client = new WebSocketClient(options);\n await client.connect();\n return client;\n }\n}\n\nexport {\n __publicField,\n WebSocketClient,\n BrowserWebSocketClient,\n createWebSocketClient\n};\n//# sourceMappingURL=chunk-63P5VUHB.js.map","import {\n WebSocketClient,\n __publicField,\n createWebSocketClient\n} from \"./chunk-63P5VUHB.js\";\n\n// src/WebSocketServer.ts\nimport { createLogger } from \"@agentxjs/common\";\nvar logger = createLogger(\"network/WebSocketServer\");\nvar WebSocketConnection = class {\n constructor(ws, options) {\n __publicField(this, \"id\");\n __publicField(this, \"ws\");\n __publicField(this, \"messageHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"closeHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"errorHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"heartbeatInterval\");\n __publicField(this, \"isAlive\", true);\n this.ws = ws;\n this.id = `conn_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;\n if (options.heartbeat !== false) {\n const interval = options.heartbeatInterval || 3e4;\n ws.on(\"pong\", () => {\n this.isAlive = true;\n logger.debug(\"Heartbeat pong received\", { id: this.id });\n });\n this.heartbeatInterval = setInterval(() => {\n if (!this.isAlive) {\n logger.warn(\"Client heartbeat timeout, terminating connection\", { id: this.id });\n clearInterval(this.heartbeatInterval);\n ws.terminate();\n return;\n }\n this.isAlive = false;\n ws.ping();\n logger.debug(\"Heartbeat ping sent\", { id: this.id });\n }, interval);\n }\n ws.on(\"message\", (data) => {\n const message = data.toString();\n for (const handler of this.messageHandlers) {\n handler(message);\n }\n });\n ws.on(\"close\", () => {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n }\n for (const handler of this.closeHandlers) {\n handler();\n }\n });\n ws.on(\"error\", (err) => {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n }\n for (const handler of this.errorHandlers) {\n handler(err);\n }\n });\n }\n send(message) {\n if (this.ws.readyState === 1) {\n this.ws.send(message);\n }\n }\n onMessage(handler) {\n this.messageHandlers.add(handler);\n return () => {\n this.messageHandlers.delete(handler);\n };\n }\n onClose(handler) {\n this.closeHandlers.add(handler);\n return () => {\n this.closeHandlers.delete(handler);\n };\n }\n onError(handler) {\n this.errorHandlers.add(handler);\n return () => {\n this.errorHandlers.delete(handler);\n };\n }\n close() {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval);\n }\n this.ws.close();\n }\n};\nvar WebSocketServer = class {\n constructor(options = {}) {\n __publicField(this, \"wss\", null);\n __publicField(this, \"connections\", /* @__PURE__ */ new Set());\n __publicField(this, \"connectionHandlers\", /* @__PURE__ */ new Set());\n __publicField(this, \"options\");\n __publicField(this, \"attachedToServer\", false);\n this.options = options;\n }\n async listen(port, host = \"0.0.0.0\") {\n if (this.wss) {\n throw new Error(\"Server already listening\");\n }\n if (this.attachedToServer) {\n throw new Error(\n \"Cannot listen when attached to existing server. The server should call listen() instead.\"\n );\n }\n const { WebSocketServer: WSS } = await import(\"ws\");\n this.wss = new WSS({ port, host });\n this.wss.on(\"connection\", (ws) => {\n this.handleConnection(ws);\n });\n logger.info(\"WebSocket server listening\", { port, host });\n }\n attach(server, path = \"/ws\") {\n if (this.wss) {\n throw new Error(\"Server already initialized\");\n }\n import(\"ws\").then(({ WebSocketServer: WSS }) => {\n this.wss = new WSS({ noServer: true });\n server.on(\"upgrade\", (request, socket, head) => {\n const url = new URL(request.url || \"\", `http://${request.headers.host}`);\n if (url.pathname === path) {\n this.wss.handleUpgrade(request, socket, head, (ws) => {\n this.wss.emit(\"connection\", ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n this.wss.on(\"connection\", (ws) => {\n this.handleConnection(ws);\n });\n this.attachedToServer = true;\n logger.info(\"WebSocket attached to existing HTTP server\", { path });\n });\n }\n handleConnection(ws) {\n const connection = new WebSocketConnection(ws, this.options);\n this.connections.add(connection);\n logger.info(\"Client connected\", {\n connectionId: connection.id,\n totalConnections: this.connections.size\n });\n connection.onClose(() => {\n this.connections.delete(connection);\n logger.info(\"Client disconnected\", {\n connectionId: connection.id,\n totalConnections: this.connections.size\n });\n });\n for (const handler of this.connectionHandlers) {\n handler(connection);\n }\n }\n onConnection(handler) {\n this.connectionHandlers.add(handler);\n return () => {\n this.connectionHandlers.delete(handler);\n };\n }\n broadcast(message) {\n for (const connection of this.connections) {\n connection.send(message);\n }\n }\n async close() {\n if (!this.wss) return;\n for (const connection of this.connections) {\n connection.close();\n }\n this.connections.clear();\n if (!this.attachedToServer) {\n await new Promise((resolve) => {\n this.wss.close(() => resolve());\n });\n }\n this.wss = null;\n }\n async dispose() {\n await this.close();\n this.connectionHandlers.clear();\n }\n};\nexport {\n WebSocketClient,\n WebSocketServer,\n createWebSocketClient\n};\n//# sourceMappingURL=index.js.map"],"file":"assets/index-1uLnFQV1.js"}