connectonion 0.0.1
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/LICENSE +21 -0
- package/README.md +362 -0
- package/dist/connect.d.ts +35 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +149 -0
- package/dist/console.d.ts +30 -0
- package/dist/console.d.ts.map +1 -0
- package/dist/console.js +124 -0
- package/dist/core/agent.d.ts +233 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +500 -0
- package/dist/examples/comprehensive-test.js +314 -0
- package/dist/examples/simple-test.js +80 -0
- package/dist/history/index.d.ts +42 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/index.js +140 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/llm/anthropic.d.ts +23 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +139 -0
- package/dist/llm/gemini.d.ts +20 -0
- package/dist/llm/gemini.d.ts.map +1 -0
- package/dist/llm/gemini.js +136 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +76 -0
- package/dist/llm/llm-do.d.ts +8 -0
- package/dist/llm/llm-do.d.ts.map +1 -0
- package/dist/llm/llm-do.js +25 -0
- package/dist/llm/noop.d.ts +16 -0
- package/dist/llm/noop.d.ts.map +1 -0
- package/dist/llm/noop.js +23 -0
- package/dist/llm/openai.d.ts +21 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +131 -0
- package/dist/src/core/agent.js +368 -0
- package/dist/src/history/index.js +140 -0
- package/dist/src/index.js +34 -0
- package/dist/src/llm/index.js +22 -0
- package/dist/src/llm/openai.js +78 -0
- package/dist/src/tools/tool-utils.js +348 -0
- package/dist/src/types.js +8 -0
- package/dist/tools/email.d.ts +13 -0
- package/dist/tools/email.d.ts.map +1 -0
- package/dist/tools/email.js +98 -0
- package/dist/tools/replay.d.ts +19 -0
- package/dist/tools/replay.d.ts.map +1 -0
- package/dist/tools/replay.js +62 -0
- package/dist/tools/tool-executor.d.ts +58 -0
- package/dist/tools/tool-executor.d.ts.map +1 -0
- package/dist/tools/tool-executor.js +100 -0
- package/dist/tools/tool-utils.d.ts +133 -0
- package/dist/tools/tool-utils.d.ts.map +1 -0
- package/dist/tools/tool-utils.js +380 -0
- package/dist/tools/xray.d.ts +58 -0
- package/dist/tools/xray.d.ts.map +1 -0
- package/dist/tools/xray.js +110 -0
- package/dist/trust/index.d.ts +26 -0
- package/dist/trust/index.d.ts.map +1 -0
- package/dist/trust/index.js +47 -0
- package/dist/trust/tools.d.ts +4 -0
- package/dist/trust/tools.d.ts.map +1 -0
- package/dist/trust/tools.js +71 -0
- package/dist/types.d.ts +141 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 ConnectOnion Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# 🚀 ConnectOnion TypeScript SDK
|
|
2
|
+
|
|
3
|
+
> **Build AI agents that actually DO things** - Zero boilerplate, maximum power
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/connectonion)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
## ✨ What is ConnectOnion?
|
|
10
|
+
|
|
11
|
+
ConnectOnion is a TypeScript SDK that makes building AI agents ridiculously simple. Your functions become tools. Your classes become toolsets. Your agents just work.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
// This is all you need for a working AI agent
|
|
15
|
+
import { Agent } from 'connectonion';
|
|
16
|
+
|
|
17
|
+
function calculateTip(bill: number, percentage: number): number {
|
|
18
|
+
return bill * (percentage / 100);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const agent = new Agent({
|
|
22
|
+
name: 'assistant',
|
|
23
|
+
tools: [calculateTip] // Your function is now an AI tool!
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const response = await agent.input('What\'s a 20% tip on $85?');
|
|
27
|
+
// "A 20% tip on $85 would be $17.00"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**That's it.** No schemas. No configurations. No boilerplate.
|
|
31
|
+
|
|
32
|
+
## 🆕 Python-Parity Highlights
|
|
33
|
+
|
|
34
|
+
- Default LLM: Anthropic Claude Sonnet 3.5 (`claude-3-5-sonnet-20241022`)
|
|
35
|
+
- LLM factory: routes `claude-*`, `gpt-*`/`o*`, `gemini-*`, and `co/*` (OpenOnion)
|
|
36
|
+
- Structured output: `llm.structuredComplete(messages, schema)` returns validated JSON
|
|
37
|
+
- Multi‑turn: agent now keeps conversation state until `resetConversation()`
|
|
38
|
+
- Console logging: progress printed and logged to `./.co/logs/{name}.log` by default
|
|
39
|
+
- Env override: set `CONNECTONION_LOG` to choose a custom log file
|
|
40
|
+
|
|
41
|
+
## 🎯 Why CO?
|
|
42
|
+
|
|
43
|
+
### 🧠 **Smart by Default**
|
|
44
|
+
- Agents automatically understand when and how to use tools
|
|
45
|
+
- Built-in conversation memory and context management
|
|
46
|
+
- Parallel tool execution for maximum efficiency
|
|
47
|
+
|
|
48
|
+
### 🛠️ **Any Function is a Tool**
|
|
49
|
+
```typescript
|
|
50
|
+
// These all become tools automatically
|
|
51
|
+
function sendEmail(to: string, subject: string) { }
|
|
52
|
+
async function fetchWeather(city: string) { }
|
|
53
|
+
const calculate = (x: number, y: number) => x + y;
|
|
54
|
+
|
|
55
|
+
// Even class methods!
|
|
56
|
+
class Database {
|
|
57
|
+
query(sql: string) { }
|
|
58
|
+
insert(table: string, data: any) { }
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 📝 **TypeScript Superpowers**
|
|
63
|
+
- Full type safety and IntelliSense support
|
|
64
|
+
- Compile-time parameter validation
|
|
65
|
+
- Auto-completion for all APIs
|
|
66
|
+
- JSDoc comments become tool descriptions
|
|
67
|
+
|
|
68
|
+
### 💾 **Session & Trace**
|
|
69
|
+
Agents keep an in-memory session (messages + tool execution trace). Inspect it with `agent.getSession()` and reset with `agent.resetConversation()`.
|
|
70
|
+
|
|
71
|
+
## 🚀 Quick Start (60 seconds)
|
|
72
|
+
|
|
73
|
+
### 1. Install
|
|
74
|
+
```bash
|
|
75
|
+
npm install connectonion
|
|
76
|
+
# or
|
|
77
|
+
yarn add connectonion
|
|
78
|
+
# or
|
|
79
|
+
pnpm add connectonion
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 2. Set API Key
|
|
83
|
+
```bash
|
|
84
|
+
export OPENAI_API_KEY=sk-...
|
|
85
|
+
# or use .env file
|
|
86
|
+
|
|
87
|
+
# Anthropic (default)
|
|
88
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
89
|
+
|
|
90
|
+
# Gemini (optional)
|
|
91
|
+
export GEMINI_API_KEY=sk-gem-... # or GOOGLE_API_KEY
|
|
92
|
+
|
|
93
|
+
# OpenOnion managed keys (optional, for co/* models)
|
|
94
|
+
export OPENONION_API_KEY=oo-...
|
|
95
|
+
export OPENONION_BASE_URL=https://oo.openonion.ai/v1
|
|
96
|
+
# Dev mode: uses http://localhost:8000/v1
|
|
97
|
+
export OPENONION_DEV=1
|
|
98
|
+
|
|
99
|
+
# Console log override (otherwise ./.co/logs/{name}.log)
|
|
100
|
+
export CONNECTONION_LOG=./my-agent.log
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. Create Your First Agent
|
|
104
|
+
```typescript
|
|
105
|
+
import { Agent } from 'connectonion';
|
|
106
|
+
|
|
107
|
+
// Define what your agent can do
|
|
108
|
+
function searchWeb(query: string): string {
|
|
109
|
+
// Your search logic here
|
|
110
|
+
return `Results for ${query}...`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function sendMessage(to: string, message: string): string {
|
|
114
|
+
// Your messaging logic here
|
|
115
|
+
return `Message sent to ${to}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Create the agent
|
|
119
|
+
const agent = new Agent({
|
|
120
|
+
name: 'personal-assistant',
|
|
121
|
+
tools: [searchWeb, sendMessage],
|
|
122
|
+
systemPrompt: 'You are a helpful personal assistant.'
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Use it!
|
|
126
|
+
const response = await agent.input(
|
|
127
|
+
'Search for TypeScript tutorials and send the link to John'
|
|
128
|
+
);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## 🎨 Real-World Examples
|
|
132
|
+
|
|
133
|
+
### Example 1: Customer Service Bot
|
|
134
|
+
```typescript
|
|
135
|
+
class CustomerService {
|
|
136
|
+
// Each method becomes a tool automatically
|
|
137
|
+
async lookupOrder(orderId: string): Promise<Order> {
|
|
138
|
+
return await db.orders.findOne({ id: orderId });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async processRefund(orderId: string, reason: string): Promise<RefundResult> {
|
|
142
|
+
const order = await this.lookupOrder(orderId);
|
|
143
|
+
return await payments.refund(order, reason);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async sendEmail(to: string, subject: string, body: string): Promise<void> {
|
|
147
|
+
await emailService.send({ to, subject, body });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Create an agent with all methods as tools
|
|
152
|
+
const agent = new Agent({
|
|
153
|
+
name: 'customer-service',
|
|
154
|
+
tools: [new CustomerService()], // All methods become tools!
|
|
155
|
+
systemPrompt: 'You are a helpful customer service representative.'
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Handle customer requests naturally
|
|
159
|
+
const response = await agent.input(
|
|
160
|
+
'Order #12345 arrived damaged, I want a refund'
|
|
161
|
+
);
|
|
162
|
+
// Agent will: lookup order → process refund → send confirmation email
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Example 2: Data Analysis Agent
|
|
166
|
+
```typescript
|
|
167
|
+
import { Agent } from 'connectonion';
|
|
168
|
+
import * as fs from 'fs';
|
|
169
|
+
import * as csv from 'csv-parse';
|
|
170
|
+
|
|
171
|
+
// Tools for data analysis
|
|
172
|
+
function readCSV(filepath: string): any[] {
|
|
173
|
+
const data = fs.readFileSync(filepath, 'utf-8');
|
|
174
|
+
return csv.parse(data, { columns: true });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function analyzeData(data: any[], column: string): Statistics {
|
|
178
|
+
// Statistical analysis logic
|
|
179
|
+
return {
|
|
180
|
+
mean: calculateMean(data, column),
|
|
181
|
+
median: calculateMedian(data, column),
|
|
182
|
+
stdDev: calculateStdDev(data, column)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function createChart(data: any[], type: string): string {
|
|
187
|
+
// Chart generation logic
|
|
188
|
+
return `chart_${Date.now()}.png`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Create the analyst
|
|
192
|
+
const analyst = new Agent({
|
|
193
|
+
name: 'data-analyst',
|
|
194
|
+
tools: [readCSV, analyzeData, createChart],
|
|
195
|
+
model: 'gpt-4', // Use GPT-4 for complex analysis
|
|
196
|
+
systemPrompt: 'You are an expert data analyst. Provide insights and visualizations.'
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Analyze data with natural language
|
|
200
|
+
const report = await analyst.input(
|
|
201
|
+
'Analyze sales.csv, focus on Q4 performance, and create a bar chart'
|
|
202
|
+
);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Example 3: DevOps Automation
|
|
206
|
+
```typescript
|
|
207
|
+
class DevOpsTools {
|
|
208
|
+
async deployToProduction(service: string, version: string) {
|
|
209
|
+
// Kubernetes deployment logic
|
|
210
|
+
return `Deployed ${service}:${version} to production`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async checkSystemHealth(service: string) {
|
|
214
|
+
// Health check logic
|
|
215
|
+
return { status: 'healthy', uptime: '99.9%' };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async rollback(service: string) {
|
|
219
|
+
// Rollback logic
|
|
220
|
+
return `Rolled back ${service} to previous version`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async queryLogs(service: string, timeRange: string, filter?: string) {
|
|
224
|
+
// Log querying logic
|
|
225
|
+
return [`[ERROR] Connection timeout`, `[WARN] High memory usage`];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const devops = new Agent({
|
|
230
|
+
name: 'devops-assistant',
|
|
231
|
+
tools: [new DevOpsTools()],
|
|
232
|
+
maxIterations: 20, // Complex operations might need more iterations
|
|
233
|
+
systemPrompt: 'You are a DevOps expert. Be cautious with production changes.'
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Natural language DevOps
|
|
237
|
+
await devops.input(
|
|
238
|
+
'Check if api-service is healthy, if not check logs and consider rollback'
|
|
239
|
+
);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## 🔧 Advanced Features
|
|
243
|
+
|
|
244
|
+
### Dynamic Tool Management
|
|
245
|
+
```typescript
|
|
246
|
+
// Add tools at runtime
|
|
247
|
+
agent.addTool(newFunction);
|
|
248
|
+
|
|
249
|
+
// Remove tools
|
|
250
|
+
agent.removeTool('oldToolName');
|
|
251
|
+
|
|
252
|
+
// List available tools
|
|
253
|
+
const tools = agent.getTools();
|
|
254
|
+
console.log(tools.map(t => `${t.name}: ${t.description}`));
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Custom LLM Providers
|
|
258
|
+
```typescript
|
|
259
|
+
import { LLM, Agent } from 'connectonion';
|
|
260
|
+
|
|
261
|
+
class CustomLLM implements LLM {
|
|
262
|
+
async complete(messages, tools) {
|
|
263
|
+
// Your LLM implementation
|
|
264
|
+
return { content: '...', toolCalls: [], rawResponse: {} };
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const agent = new Agent({
|
|
269
|
+
name: 'custom-agent',
|
|
270
|
+
llm: new CustomLLM()
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Session & Trace
|
|
275
|
+
```typescript
|
|
276
|
+
const { messages, trace } = agent.getSession();
|
|
277
|
+
console.log(messages.length, trace.length);
|
|
278
|
+
agent.clearHistory(); // clear in-memory trace
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Override Iterations for Complex Tasks
|
|
282
|
+
```typescript
|
|
283
|
+
// Simple task - use default
|
|
284
|
+
await agent.input('What is 2+2?');
|
|
285
|
+
|
|
286
|
+
// Complex multi-step task - allow more iterations
|
|
287
|
+
await agent.input(
|
|
288
|
+
'Analyze all CSV files, generate reports, and email summaries',
|
|
289
|
+
30 // Allow up to 30 iterations
|
|
290
|
+
);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## 📚 Documentation
|
|
294
|
+
|
|
295
|
+
- **[Getting Started Guide](docs/getting-started.md)** - Complete setup walkthrough
|
|
296
|
+
- **[API Reference](docs/api.md)** - Full API documentation
|
|
297
|
+
- **[Examples](docs/examples.md)** - More real-world examples
|
|
298
|
+
- **[Tool System](docs/tools.md)** - Deep dive into tools
|
|
299
|
+
- **[Troubleshooting](docs/troubleshooting.md)** - Common issues & solutions
|
|
300
|
+
|
|
301
|
+
## 🏗️ Project Structure
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
your-project/
|
|
305
|
+
├── src/
|
|
306
|
+
│ ├── agents/ # Your agent definitions
|
|
307
|
+
│ ├── tools/ # Custom tool implementations
|
|
308
|
+
│ └── index.ts # Main entry point
|
|
309
|
+
├── .env # API keys (never commit!)
|
|
310
|
+
├── package.json
|
|
311
|
+
└── tsconfig.json
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## 🤝 Contributing
|
|
315
|
+
|
|
316
|
+
We love contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
317
|
+
|
|
318
|
+
### Development Setup
|
|
319
|
+
```bash
|
|
320
|
+
# Clone the repo
|
|
321
|
+
git clone https://github.com/connectonion/connectonion-ts
|
|
322
|
+
cd connectonion-ts
|
|
323
|
+
|
|
324
|
+
# Install dependencies
|
|
325
|
+
npm install
|
|
326
|
+
|
|
327
|
+
# Run tests
|
|
328
|
+
npm test
|
|
329
|
+
|
|
330
|
+
# Build
|
|
331
|
+
npm run build
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 📄 License
|
|
335
|
+
|
|
336
|
+
MIT © [CO Team](https://github.com/connectonion)
|
|
337
|
+
|
|
338
|
+
## 🔗 Links
|
|
339
|
+
|
|
340
|
+
- **[Python Version](https://github.com/connectonion/connectonion)** - Original Python SDK
|
|
341
|
+
- **[Discord Community](https://discord.gg/connectonion)** - Get help & share ideas
|
|
342
|
+
- **[Blog](https://connectonion.com/blog)** - Tutorials and updates
|
|
343
|
+
|
|
344
|
+
## 🌟 Why TypeScript?
|
|
345
|
+
|
|
346
|
+
While our Python SDK is great, TypeScript offers unique advantages:
|
|
347
|
+
|
|
348
|
+
- **Type Safety**: Catch errors at compile time
|
|
349
|
+
- **IDE Support**: Unmatched IntelliSense and auto-completion
|
|
350
|
+
- **Modern Async**: Native async/await and Promise handling
|
|
351
|
+
- **NPM Ecosystem**: Access to millions of packages
|
|
352
|
+
- **Browser Ready**: Build agents that run in browsers (coming soon!)
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
<p align="center">
|
|
357
|
+
Built with ❤️ by developers, for developers
|
|
358
|
+
</p>
|
|
359
|
+
|
|
360
|
+
<p align="center">
|
|
361
|
+
<a href="https://github.com/connectonion/connectonion-ts">⭐ Star us on GitHub</a>
|
|
362
|
+
</p>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connect to remote agents via the relay network.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors Python SDK connect(): returns a RemoteAgent proxy with input().
|
|
5
|
+
*/
|
|
6
|
+
type WebSocketLike = {
|
|
7
|
+
onopen: ((ev?: any) => any) | null;
|
|
8
|
+
onmessage: ((ev: {
|
|
9
|
+
data: any;
|
|
10
|
+
}) => any) | null;
|
|
11
|
+
onerror: ((ev: any) => any) | null;
|
|
12
|
+
onclose: ((ev: any) => any) | null;
|
|
13
|
+
send(data: any): void;
|
|
14
|
+
close(): void;
|
|
15
|
+
};
|
|
16
|
+
type WebSocketCtor = new (url: string) => WebSocketLike;
|
|
17
|
+
/** Proxy to a remote agent reachable via the relay */
|
|
18
|
+
export declare class RemoteAgent {
|
|
19
|
+
private address;
|
|
20
|
+
private relayUrl;
|
|
21
|
+
private WS;
|
|
22
|
+
constructor(address: string, relayUrl: string, wsCtor?: WebSocketCtor);
|
|
23
|
+
/** Send task to remote agent and await result */
|
|
24
|
+
input(prompt: string, timeoutMs?: number): Promise<string>;
|
|
25
|
+
toString(): string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Connect to a remote agent.
|
|
29
|
+
*
|
|
30
|
+
* @param address Agent public key (0x...)
|
|
31
|
+
* @param relayUrl Relay announce URL (default production)
|
|
32
|
+
*/
|
|
33
|
+
export declare function connect(address: string, relayUrl?: string, wsCtor?: WebSocketCtor): RemoteAgent;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,KAAK,aAAa,GAAG;IACnB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QAAE,IAAI,EAAE,GAAG,CAAA;KAAE,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC;IACnC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAEF,KAAK,aAAa,GAAG,KAAK,GAAG,EAAE,MAAM,KAAK,aAAa,CAAC;AAmBxD,sDAAsD;AACtD,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,EAAE,CAAgB;gBAEd,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa;IAMrE,iDAAiD;IAC3C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAiF/D,QAAQ;CAIT;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAqE,EAC/E,MAAM,CAAC,EAAE,aAAa,GACrB,WAAW,CAEb"}
|
package/dist/connect.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Connect to remote agents via the relay network.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors Python SDK connect(): returns a RemoteAgent proxy with input().
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RemoteAgent = void 0;
|
|
12
|
+
exports.connect = connect;
|
|
13
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
14
|
+
function defaultWebSocketCtor() {
|
|
15
|
+
// Prefer global WebSocket (browser), else require('ws') in Node
|
|
16
|
+
const g = globalThis;
|
|
17
|
+
if (typeof g.WebSocket === 'function') {
|
|
18
|
+
return g.WebSocket;
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
22
|
+
const WS = require('ws');
|
|
23
|
+
return WS;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error("No WebSocket implementation found. Install 'ws' (npm i ws) or provide a custom WebSocket factory.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Proxy to a remote agent reachable via the relay */
|
|
30
|
+
class RemoteAgent {
|
|
31
|
+
constructor(address, relayUrl, wsCtor) {
|
|
32
|
+
this.address = address;
|
|
33
|
+
this.relayUrl = relayUrl;
|
|
34
|
+
this.WS = wsCtor || defaultWebSocketCtor();
|
|
35
|
+
}
|
|
36
|
+
/** Send task to remote agent and await result */
|
|
37
|
+
async input(prompt, timeoutMs = 30000) {
|
|
38
|
+
const inputId = crypto_1.default.randomUUID();
|
|
39
|
+
const relayInputUrl = this.relayUrl.replace('/ws/announce', '/ws/input');
|
|
40
|
+
const ws = new this.WS(relayInputUrl);
|
|
41
|
+
return await new Promise((resolve, reject) => {
|
|
42
|
+
let settled = false;
|
|
43
|
+
const timer = setTimeout(() => {
|
|
44
|
+
if (!settled) {
|
|
45
|
+
settled = true;
|
|
46
|
+
try {
|
|
47
|
+
ws.close();
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
50
|
+
reject(new Error('Connection timed out'));
|
|
51
|
+
}
|
|
52
|
+
}, timeoutMs);
|
|
53
|
+
ws.onopen = () => {
|
|
54
|
+
// Send INPUT message
|
|
55
|
+
const msg = {
|
|
56
|
+
type: 'INPUT',
|
|
57
|
+
input_id: inputId,
|
|
58
|
+
to: this.address,
|
|
59
|
+
prompt,
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
ws.send(JSON.stringify(msg));
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
if (!settled) {
|
|
67
|
+
settled = true;
|
|
68
|
+
try {
|
|
69
|
+
ws.close();
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
reject(e);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
ws.onmessage = (evt) => {
|
|
77
|
+
if (settled)
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
const raw = typeof evt.data === 'string' ? evt.data : evt.data?.toString?.() ?? '';
|
|
81
|
+
const data = JSON.parse(raw);
|
|
82
|
+
if (data?.type === 'OUTPUT' && data?.input_id === inputId) {
|
|
83
|
+
settled = true;
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
try {
|
|
86
|
+
ws.close();
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
resolve(data?.result ?? '');
|
|
90
|
+
}
|
|
91
|
+
else if (data?.type === 'ERROR') {
|
|
92
|
+
settled = true;
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
try {
|
|
95
|
+
ws.close();
|
|
96
|
+
}
|
|
97
|
+
catch { }
|
|
98
|
+
reject(new Error(String(data?.error || 'Agent error')));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Ignore unrelated message; keep waiting
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
settled = true;
|
|
106
|
+
clearTimeout(timer);
|
|
107
|
+
try {
|
|
108
|
+
ws.close();
|
|
109
|
+
}
|
|
110
|
+
catch { }
|
|
111
|
+
reject(e);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
ws.onerror = (err) => {
|
|
115
|
+
if (settled)
|
|
116
|
+
return;
|
|
117
|
+
settled = true;
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
try {
|
|
120
|
+
ws.close();
|
|
121
|
+
}
|
|
122
|
+
catch { }
|
|
123
|
+
reject(new Error(`WebSocket error: ${String(err?.message || err)}`));
|
|
124
|
+
};
|
|
125
|
+
ws.onclose = () => {
|
|
126
|
+
// If closed without settling, treat as error
|
|
127
|
+
if (!settled) {
|
|
128
|
+
settled = true;
|
|
129
|
+
clearTimeout(timer);
|
|
130
|
+
reject(new Error('Connection closed before response'));
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
toString() {
|
|
136
|
+
const short = this.address.length > 12 ? this.address.slice(0, 12) + '...' : this.address;
|
|
137
|
+
return `RemoteAgent(${short})`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.RemoteAgent = RemoteAgent;
|
|
141
|
+
/**
|
|
142
|
+
* Connect to a remote agent.
|
|
143
|
+
*
|
|
144
|
+
* @param address Agent public key (0x...)
|
|
145
|
+
* @param relayUrl Relay announce URL (default production)
|
|
146
|
+
*/
|
|
147
|
+
function connect(address, relayUrl = process.env.RELAY_URL || 'wss://oo.openonion.ai/ws/announce', wsCtor) {
|
|
148
|
+
return new RemoteAgent(address, relayUrl, wsCtor);
|
|
149
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose Dual-output logging system (terminal + optional file) that mirrors Python SDK UX with colored terminal output and @xray tool tracing
|
|
3
|
+
* @llm-note
|
|
4
|
+
* Dependencies: imports from [node:fs, node:path] | imported by [src/core/agent.ts, src/tools/tool-executor.ts] | tested by agent tests
|
|
5
|
+
* Data flow: receives log messages/xray traces → formats with timestamps/colors → writes to stderr + optional file (.co/logs/{name}.log)
|
|
6
|
+
* State/Effects: writes to stderr via console.error | appends to logFile if configured | creates log directories with fs.mkdirSync
|
|
7
|
+
* Integration: exposes print(message), printXray(toolName, args, result, timing, context) | used by Agent for all output | ANSI color support via isTTY detection
|
|
8
|
+
*/
|
|
9
|
+
export declare class Console {
|
|
10
|
+
private logPath?;
|
|
11
|
+
private colorEnabled;
|
|
12
|
+
constructor(logFile?: string);
|
|
13
|
+
private initLogFile;
|
|
14
|
+
print(message: string): void;
|
|
15
|
+
printXray(toolName: string, toolArgs: Record<string, any>, result: any, timingMs: number, context?: {
|
|
16
|
+
agent?: string;
|
|
17
|
+
iteration?: number;
|
|
18
|
+
userPrompt?: string;
|
|
19
|
+
}): void;
|
|
20
|
+
private toPlain;
|
|
21
|
+
private stylize;
|
|
22
|
+
private code;
|
|
23
|
+
private green;
|
|
24
|
+
private red;
|
|
25
|
+
private yellow;
|
|
26
|
+
private cyan;
|
|
27
|
+
private dim;
|
|
28
|
+
private bold;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;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"}
|