@teneo-protocol/sdk 1.0.0 ā 2.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/.github/workflows/publish-npm.yml +8 -6
- package/CHANGELOG.md +265 -0
- package/README.md +406 -53
- package/dist/core/websocket-client.d.ts +13 -0
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +34 -3
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts +76 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js +70 -0
- package/dist/handlers/message-handlers/agent-room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts +92 -38
- package/dist/handlers/message-handlers/agent-selected-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts +904 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js +51 -0
- package/dist/handlers/message-handlers/agent-status-update-handler.js.map +1 -0
- package/dist/handlers/message-handlers/auth-error-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/auth-error-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-message-handler.js +65 -5
- package/dist/handlers/message-handlers/auth-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/auth-required-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/auth-required-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.d.ts +6 -0
- package/dist/handlers/message-handlers/auth-success-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/auth-success-handler.js +46 -4
- package/dist/handlers/message-handlers/auth-success-handler.js.map +1 -1
- package/dist/handlers/message-handlers/challenge-handler.d.ts +45 -31
- package/dist/handlers/message-handlers/challenge-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/error-message-handler.d.ts +49 -31
- package/dist/handlers/message-handlers/error-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.d.ts +5 -0
- package/dist/handlers/message-handlers/index.d.ts.map +1 -1
- package/dist/handlers/message-handlers/index.js +23 -1
- package/dist/handlers/message-handlers/index.js.map +1 -1
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts +877 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js +38 -0
- package/dist/handlers/message-handlers/list-available-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts +886 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js +51 -0
- package/dist/handlers/message-handlers/list-room-agents-handler.js.map +1 -0
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts +178 -89
- package/dist/handlers/message-handlers/list-rooms-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts +62 -58
- package/dist/handlers/message-handlers/ping-pong-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.d.ts +31 -29
- package/dist/handlers/message-handlers/regular-message-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/regular-message-handler.js +1 -0
- package/dist/handlers/message-handlers/regular-message-handler.js.map +1 -1
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts +328 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.d.ts.map +1 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js +92 -0
- package/dist/handlers/message-handlers/room-operation-response-handler.js.map +1 -0
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/subscribe-response-handler.d.ts.map +1 -1
- package/dist/handlers/message-handlers/types.d.ts +2 -0
- package/dist/handlers/message-handlers/types.d.ts.map +1 -1
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts +53 -31
- package/dist/handlers/message-handlers/unsubscribe-response-handler.d.ts.map +1 -1
- package/dist/managers/agent-room-manager.d.ts +222 -0
- package/dist/managers/agent-room-manager.d.ts.map +1 -0
- package/dist/managers/agent-room-manager.js +508 -0
- package/dist/managers/agent-room-manager.js.map +1 -0
- package/dist/managers/index.d.ts +2 -0
- package/dist/managers/index.d.ts.map +1 -1
- package/dist/managers/index.js +5 -1
- package/dist/managers/index.js.map +1 -1
- package/dist/managers/message-router.d.ts +1 -1
- package/dist/managers/message-router.d.ts.map +1 -1
- package/dist/managers/message-router.js +41 -4
- package/dist/managers/message-router.js.map +1 -1
- package/dist/managers/room-management-manager.d.ts +213 -0
- package/dist/managers/room-management-manager.d.ts.map +1 -0
- package/dist/managers/room-management-manager.js +440 -0
- package/dist/managers/room-management-manager.js.map +1 -0
- package/dist/managers/room-manager.d.ts +4 -4
- package/dist/managers/room-manager.d.ts.map +1 -1
- package/dist/managers/room-manager.js +1 -1
- package/dist/managers/room-manager.js.map +1 -1
- package/dist/teneo-sdk.d.ts +362 -14
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +497 -7
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +63 -54
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +9 -5
- package/dist/types/config.js.map +1 -1
- package/dist/types/error-codes.d.ts +2 -0
- package/dist/types/error-codes.d.ts.map +1 -1
- package/dist/types/error-codes.js +3 -0
- package/dist/types/error-codes.js.map +1 -1
- package/dist/types/events.d.ts +132 -68
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +27 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/messages.d.ts +11396 -2559
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/messages.js +294 -27
- package/dist/types/messages.js.map +1 -1
- package/dist/types/validation.d.ts.map +1 -1
- package/dist/types/validation.js +1 -1
- package/dist/types/validation.js.map +1 -1
- package/dist/utils/bounded-queue.d.ts +1 -1
- package/dist/utils/bounded-queue.js +6 -6
- package/dist/utils/circuit-breaker.d.ts.map +1 -1
- package/dist/utils/circuit-breaker.js.map +1 -1
- package/dist/utils/event-waiter.d.ts.map +1 -1
- package/dist/utils/event-waiter.js +2 -1
- package/dist/utils/event-waiter.js.map +1 -1
- package/dist/utils/rate-limiter.d.ts.map +1 -1
- package/dist/utils/rate-limiter.js +4 -6
- package/dist/utils/rate-limiter.js.map +1 -1
- package/dist/utils/secure-private-key.d.ts.map +1 -1
- package/dist/utils/secure-private-key.js +9 -15
- package/dist/utils/secure-private-key.js.map +1 -1
- package/dist/utils/signature-verifier.d.ts +2 -2
- package/dist/utils/signature-verifier.d.ts.map +1 -1
- package/dist/utils/signature-verifier.js +5 -5
- package/dist/utils/signature-verifier.js.map +1 -1
- package/examples/.env.example +1 -1
- package/examples/agent-room-management-example.ts +334 -0
- package/examples/claude-agent-x-follower/.env.example +117 -0
- package/examples/claude-agent-x-follower/QUICKSTART.md +243 -0
- package/examples/claude-agent-x-follower/README.md +540 -0
- package/examples/claude-agent-x-follower/index.ts +248 -0
- package/examples/claude-agent-x-follower/package.json +37 -0
- package/examples/claude-agent-x-follower/tsconfig.json +20 -0
- package/examples/n8n-teneo/.env.example +127 -0
- package/examples/n8n-teneo/Dockerfile +42 -0
- package/examples/n8n-teneo/README.md +564 -0
- package/examples/n8n-teneo/docker-compose.yml +71 -0
- package/examples/n8n-teneo/index.ts +177 -0
- package/examples/n8n-teneo/package.json +22 -0
- package/examples/n8n-teneo/tsconfig.json +12 -0
- package/examples/n8n-teneo/workflows/x-timeline.json +66 -0
- package/examples/openai-teneo/.env.example +130 -0
- package/examples/openai-teneo/README.md +635 -0
- package/examples/openai-teneo/index.ts +280 -0
- package/examples/openai-teneo/package.json +24 -0
- package/examples/openai-teneo/tsconfig.json +16 -0
- package/examples/production-dashboard/.env.example +5 -3
- package/examples/production-dashboard/README.md +839 -0
- package/examples/production-dashboard/pnpm-lock.yaml +92 -0
- package/examples/production-dashboard/public/dashboard.html +1150 -504
- package/examples/production-dashboard/server.ts +428 -12
- package/examples/room-management-example.ts +285 -0
- package/examples/usage/.env.example +17 -0
- package/examples/usage/01-connect.ts +116 -0
- package/examples/usage/02-list-agents.ts +153 -0
- package/examples/usage/03-pick-agent.ts +201 -0
- package/examples/usage/04-find-by-capability.ts +237 -0
- package/examples/usage/05-webhook-example.ts +319 -0
- package/examples/usage/06-simple-api-server.ts +396 -0
- package/examples/usage/07-event-listener.ts +402 -0
- package/examples/usage/README.md +383 -0
- package/examples/usage/package.json +42 -0
- package/package.json +13 -3
- package/src/core/websocket-client.ts +43 -9
- package/src/formatters/response-formatter.test.ts +8 -2
- package/src/handlers/message-handlers/agent-room-operation-response-handler.ts +83 -0
- package/src/handlers/message-handlers/agent-status-update-handler.ts +58 -0
- package/src/handlers/message-handlers/auth-message-handler.ts +73 -5
- package/src/handlers/message-handlers/auth-success-handler.ts +58 -6
- package/src/handlers/message-handlers/index.ts +19 -0
- package/src/handlers/message-handlers/list-available-agents-handler.ts +41 -0
- package/src/handlers/message-handlers/list-room-agents-handler.ts +61 -0
- package/src/handlers/message-handlers/regular-message-handler.ts +1 -0
- package/src/handlers/message-handlers/room-operation-response-handler.ts +105 -0
- package/src/handlers/message-handlers/types.ts +6 -0
- package/src/handlers/webhook-handler.test.ts +13 -10
- package/src/managers/agent-room-manager.ts +609 -0
- package/src/managers/index.ts +2 -0
- package/src/managers/message-router.ts +48 -6
- package/src/managers/room-management-manager.ts +523 -0
- package/src/managers/room-manager.ts +12 -6
- package/src/teneo-sdk.ts +543 -10
- package/src/types/config.ts +13 -6
- package/src/types/error-codes.ts +4 -0
- package/src/types/events.ts +24 -0
- package/src/types/index.ts +55 -0
- package/src/types/messages.ts +374 -41
- package/src/types/validation.ts +4 -1
- package/src/utils/bounded-queue.ts +9 -9
- package/src/utils/circuit-breaker.ts +4 -1
- package/src/utils/deduplication-cache.test.ts +2 -6
- package/src/utils/event-waiter.test.ts +4 -1
- package/src/utils/event-waiter.ts +5 -7
- package/src/utils/rate-limiter.test.ts +5 -17
- package/src/utils/rate-limiter.ts +6 -9
- package/src/utils/secure-private-key.test.ts +66 -59
- package/src/utils/secure-private-key.ts +10 -16
- package/src/utils/signature-verifier.test.ts +75 -70
- package/src/utils/signature-verifier.ts +7 -8
- package/src/utils/ssrf-validator.test.ts +3 -3
- package/tests/integration/room-management.test.ts +514 -0
- package/tests/integration/websocket.test.ts +1 -1
- package/tests/unit/handlers/agent-room-operation-response-handler.test.ts +394 -0
- package/tests/unit/handlers/agent-status-update-handler.test.ts +407 -0
- package/tests/unit/handlers/auth-success-handler-rooms.test.ts +699 -0
- package/tests/unit/handlers/list-available-agents-handler.test.ts +256 -0
- package/tests/unit/handlers/list-room-agents-handler.test.ts +294 -0
- package/tests/unit/handlers/room-operation-response-handler.test.ts +527 -0
- package/tests/unit/managers/agent-room-manager.test.ts +534 -0
- package/tests/unit/managers/room-management-manager.test.ts +438 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 3: Pick and Communicate with Specific Agent
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates:
|
|
5
|
+
* - Finding a specific agent by ID or name
|
|
6
|
+
* - Sending a direct command to an agent (bypassing coordinator)
|
|
7
|
+
* - Waiting for and receiving agent responses
|
|
8
|
+
* - Handling response formats (raw, humanized, both)
|
|
9
|
+
*
|
|
10
|
+
* Run: npx tsx examples/usage/03-pick-agent.ts [agent-name-or-id]
|
|
11
|
+
* Example: npx tsx examples/usage/03-pick-agent.ts "X Platform Agent"
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import "dotenv/config";
|
|
15
|
+
import { TeneoSDK, SDKConfigBuilder, FormattedResponse } from "../../dist/index.js";
|
|
16
|
+
|
|
17
|
+
// Load configuration from environment
|
|
18
|
+
const WS_URL =
|
|
19
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
20
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
21
|
+
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
console.log("š Example 3: Pick and Communicate with Specific Agent\n");
|
|
25
|
+
|
|
26
|
+
if (!PRIVATE_KEY) {
|
|
27
|
+
console.error("ā ERROR: PRIVATE_KEY environment variable is required\n");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Get agent name/ID from command line or use default
|
|
32
|
+
const targetAgentName = process.argv[2];
|
|
33
|
+
|
|
34
|
+
// Build SDK with response format set to 'both' to see raw and humanized
|
|
35
|
+
const config = new SDKConfigBuilder()
|
|
36
|
+
.withWebSocketUrl(WS_URL)
|
|
37
|
+
.withAuthentication(PRIVATE_KEY)
|
|
38
|
+
// .withAutoJoinRooms([DEFAULT_ROOM])
|
|
39
|
+
.withResponseFormat({ format: "both", includeMetadata: true })
|
|
40
|
+
.withLogging("info")
|
|
41
|
+
.build();
|
|
42
|
+
|
|
43
|
+
const sdk = new TeneoSDK(config);
|
|
44
|
+
|
|
45
|
+
// Listen for agent responses
|
|
46
|
+
sdk.on("agent:response", (response) => {
|
|
47
|
+
console.log("šØ Agent response event received:");
|
|
48
|
+
console.log(` Agent: ${response.agentName || response.agentId}`);
|
|
49
|
+
console.log(` Task ID: ${response.taskId}`);
|
|
50
|
+
console.log(` Success: ${response.success}`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Connect
|
|
55
|
+
console.log("š Connecting to Teneo network...");
|
|
56
|
+
await sdk.connect();
|
|
57
|
+
console.log("ā
Connected!\n");
|
|
58
|
+
|
|
59
|
+
// Wait for agents to load
|
|
60
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
61
|
+
|
|
62
|
+
// Step 1: List available agents
|
|
63
|
+
console.log("āļø Step 1: Getting available agents...");
|
|
64
|
+
const agents = sdk.getAgents();
|
|
65
|
+
console.log(`ā
Found ${agents.length} agents\n`);
|
|
66
|
+
|
|
67
|
+
if (agents.length === 0) {
|
|
68
|
+
console.log("ā No agents available");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Display available agents
|
|
73
|
+
console.log("š Available Agents:");
|
|
74
|
+
agents.forEach((agent, index) => {
|
|
75
|
+
console.log(` ${index + 1}. ${agent.name || "Unnamed"} (${agent.id})`);
|
|
76
|
+
console.log(` Status: ${agent.status}`);
|
|
77
|
+
if (agent.description) {
|
|
78
|
+
console.log(` ${agent.description}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
console.log("");
|
|
82
|
+
|
|
83
|
+
// Step 2: Pick an agent
|
|
84
|
+
console.log("āļø Step 2: Selecting agent...");
|
|
85
|
+
let selectedAgent;
|
|
86
|
+
|
|
87
|
+
if (targetAgentName) {
|
|
88
|
+
// Find by name or ID from command line
|
|
89
|
+
console.log(` Searching for: "${targetAgentName}"`);
|
|
90
|
+
selectedAgent = agents.find(
|
|
91
|
+
(a) =>
|
|
92
|
+
a.name?.toLowerCase().includes(targetAgentName.toLowerCase()) ||
|
|
93
|
+
a.id.toLowerCase() === targetAgentName.toLowerCase()
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
if (!selectedAgent) {
|
|
97
|
+
console.log(`ā Agent "${targetAgentName}" not found`);
|
|
98
|
+
console.log(" Available agents listed above");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
// Pick first online agent
|
|
103
|
+
selectedAgent =
|
|
104
|
+
agents.find((a) => a.status === "online" && a.id !== "solidity-agent-v3") || agents[0];
|
|
105
|
+
console.log(" No agent specified, selecting first online agent");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log(`ā
Selected: ${selectedAgent.name || selectedAgent.id}`);
|
|
109
|
+
console.log(` ID: ${selectedAgent.id}`);
|
|
110
|
+
console.log(` Status: ${selectedAgent.status}`);
|
|
111
|
+
console.log("");
|
|
112
|
+
|
|
113
|
+
// Step 3: Send a direct command to the agent
|
|
114
|
+
console.log("āļø Step 3: Sending command to agent...");
|
|
115
|
+
|
|
116
|
+
// Construct a simple command based on agent type
|
|
117
|
+
let command;
|
|
118
|
+
if (
|
|
119
|
+
selectedAgent.name?.toLowerCase().includes("x platform") ||
|
|
120
|
+
selectedAgent.name?.toLowerCase().includes("twitter")
|
|
121
|
+
) {
|
|
122
|
+
command = "timeline @elonmusk 3";
|
|
123
|
+
console.log(` Command: ${command}`);
|
|
124
|
+
console.log(" (Getting Twitter timeline for @elonmusk)");
|
|
125
|
+
} else if (selectedAgent.commands && selectedAgent.commands.length > 0) {
|
|
126
|
+
// Use first available command
|
|
127
|
+
const firstCmd = selectedAgent.commands[0];
|
|
128
|
+
command = `${firstCmd.trigger} ${firstCmd.argument || "test"}`;
|
|
129
|
+
console.log(` Command: ${command}`);
|
|
130
|
+
console.log(` (Using agent's first command: ${firstCmd.description})`);
|
|
131
|
+
} else {
|
|
132
|
+
command = "hello";
|
|
133
|
+
console.log(` Command: ${command}`);
|
|
134
|
+
console.log(" (Sending simple greeting)");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
console.log(" Waiting for response (timeout: 30s)...");
|
|
138
|
+
console.log("");
|
|
139
|
+
|
|
140
|
+
const startTime = Date.now();
|
|
141
|
+
|
|
142
|
+
// Send direct command and wait for response
|
|
143
|
+
const response = await sdk.sendDirectCommand(
|
|
144
|
+
{
|
|
145
|
+
agent: selectedAgent.id,
|
|
146
|
+
command: command,
|
|
147
|
+
room: DEFAULT_ROOM
|
|
148
|
+
},
|
|
149
|
+
true
|
|
150
|
+
); // waitForResponse = true
|
|
151
|
+
|
|
152
|
+
if (!response) {
|
|
153
|
+
console.log("ā No response received");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const duration = Date.now() - startTime;
|
|
158
|
+
|
|
159
|
+
// Step 4: Display the response
|
|
160
|
+
console.log("ā
Response received!\n");
|
|
161
|
+
console.log("š Response Details:");
|
|
162
|
+
console.log("=".repeat(80));
|
|
163
|
+
|
|
164
|
+
if (response.humanized) {
|
|
165
|
+
console.log("\nš Humanized Response:");
|
|
166
|
+
console.log(response.humanized);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (response.raw) {
|
|
170
|
+
console.log("\nš Raw Response:");
|
|
171
|
+
console.log(JSON.stringify(response.raw, null, 2));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (response.metadata) {
|
|
175
|
+
console.log("\nš Metadata:");
|
|
176
|
+
console.log(` Task ID: ${response.metadata.taskId}`);
|
|
177
|
+
console.log(` Agent ID: ${response.metadata.agentId}`);
|
|
178
|
+
console.log(` Agent Name: ${response.metadata.agentName}`);
|
|
179
|
+
console.log(` Timestamp: ${response.metadata.timestamp}`);
|
|
180
|
+
console.log(` Duration: ${duration}ms`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
console.log("\n" + "=".repeat(80));
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error("\nā Error:", error);
|
|
186
|
+
if (error instanceof Error) {
|
|
187
|
+
console.error(" Message:", error.message);
|
|
188
|
+
if ("code" in error) {
|
|
189
|
+
console.error(" Code:", (error as any).code);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
process.exit(1);
|
|
193
|
+
} finally {
|
|
194
|
+
sdk.disconnect();
|
|
195
|
+
sdk.destroy();
|
|
196
|
+
console.log("\nā
Disconnected");
|
|
197
|
+
console.log("š Example completed!");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example 4: Find Agents by Capability
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates:
|
|
5
|
+
* - PERF-3: O(1) indexed agent lookups by capability
|
|
6
|
+
* - Finding agents by specific capabilities
|
|
7
|
+
* - Finding agents by status (online/offline)
|
|
8
|
+
* - Finding agents by name (token-based search)
|
|
9
|
+
* - Performance comparison of different search methods
|
|
10
|
+
*
|
|
11
|
+
* Run: npx tsx examples/usage/04-find-by-capability.ts
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import "dotenv/config";
|
|
15
|
+
import { TeneoSDK, SDKConfigBuilder } from "../../dist/index.js";
|
|
16
|
+
|
|
17
|
+
// Load configuration from environment
|
|
18
|
+
const WS_URL =
|
|
19
|
+
process.env.WS_URL || "wss://your-teneo-server.com/ws";
|
|
20
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
|
|
21
|
+
const DEFAULT_ROOM = process.env.DEFAULT_ROOM || "general";
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
console.log("š Example 4: Find Agents by Capability\n");
|
|
25
|
+
|
|
26
|
+
if (!PRIVATE_KEY) {
|
|
27
|
+
console.error("ā ERROR: PRIVATE_KEY environment variable is required\n");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Build SDK
|
|
32
|
+
const config = new SDKConfigBuilder()
|
|
33
|
+
.withWebSocketUrl(WS_URL)
|
|
34
|
+
.withAuthentication(PRIVATE_KEY)
|
|
35
|
+
// .withAutoJoinRooms([DEFAULT_ROOM])
|
|
36
|
+
.withLogging("info")
|
|
37
|
+
.build();
|
|
38
|
+
|
|
39
|
+
const sdk = new TeneoSDK(config);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
// Connect
|
|
43
|
+
console.log("š Connecting to Teneo network...");
|
|
44
|
+
await sdk.connect();
|
|
45
|
+
console.log("ā
Connected!\n");
|
|
46
|
+
|
|
47
|
+
// Wait for agents
|
|
48
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
49
|
+
|
|
50
|
+
// Get all agents
|
|
51
|
+
const allAgents = sdk.getAgents();
|
|
52
|
+
console.log(`š Total agents in network: ${allAgents.length}\n`);
|
|
53
|
+
|
|
54
|
+
if (allAgents.length === 0) {
|
|
55
|
+
console.log("ā No agents available");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Step 1: Display all available capabilities
|
|
60
|
+
console.log("āļø Step 1: Discovering available capabilities...");
|
|
61
|
+
const capabilitiesSet = new Set<string>();
|
|
62
|
+
|
|
63
|
+
allAgents.forEach((agent) => {
|
|
64
|
+
if (agent.capabilities) {
|
|
65
|
+
agent.capabilities.forEach((cap) => {
|
|
66
|
+
capabilitiesSet.add(cap.name);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const capabilities = Array.from(capabilitiesSet).sort();
|
|
72
|
+
console.log(`ā
Found ${capabilities.length} unique capabilities:\n`);
|
|
73
|
+
|
|
74
|
+
if (capabilities.length > 0) {
|
|
75
|
+
console.log("š Available Capabilities:");
|
|
76
|
+
capabilities.forEach((cap, index) => {
|
|
77
|
+
const agentsWithCap = allAgents.filter((a) => a.capabilities?.some((c) => c.name === cap));
|
|
78
|
+
console.log(` ${index + 1}. ${cap} (${agentsWithCap.length} agents)`);
|
|
79
|
+
});
|
|
80
|
+
console.log("");
|
|
81
|
+
} else {
|
|
82
|
+
console.log("ā ļø No capabilities defined for any agents\n");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Step 2: Find agents by capability (O(1) lookup)
|
|
86
|
+
if (capabilities.length > 0) {
|
|
87
|
+
console.log("āļø Step 2: Finding agents by capability (O(1) indexed lookup)...");
|
|
88
|
+
|
|
89
|
+
// Try to find agents with specific capabilities
|
|
90
|
+
const testCapabilities = [
|
|
91
|
+
capabilities[0], // First capability
|
|
92
|
+
"weather-forecast",
|
|
93
|
+
"social-media",
|
|
94
|
+
"data-analysis"
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
for (const capability of testCapabilities) {
|
|
98
|
+
console.log(`\nš Searching for capability: "${capability}"`);
|
|
99
|
+
const startTime = performance.now();
|
|
100
|
+
const agentsWithCap = sdk.findAgentsByCapability(capability);
|
|
101
|
+
const duration = performance.now() - startTime;
|
|
102
|
+
|
|
103
|
+
if (agentsWithCap.length > 0) {
|
|
104
|
+
console.log(`ā
Found ${agentsWithCap.length} agent(s) (${duration.toFixed(3)}ms):`);
|
|
105
|
+
agentsWithCap.forEach((agent) => {
|
|
106
|
+
console.log(` ⢠${agent.name || agent.id}`);
|
|
107
|
+
const cap = agent.capabilities?.find((c) => c.name === capability);
|
|
108
|
+
if (cap) {
|
|
109
|
+
console.log(` ${cap.description}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
} else {
|
|
113
|
+
console.log(
|
|
114
|
+
`ā No agents found with capability "${capability}" (${duration.toFixed(3)}ms)`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Step 3: Find agents by status (O(1) lookup)
|
|
121
|
+
console.log("\nāļø Step 3: Finding agents by status (O(1) indexed lookup)...");
|
|
122
|
+
|
|
123
|
+
console.log("\nš Online agents:");
|
|
124
|
+
const startTimeOnline = performance.now();
|
|
125
|
+
const onlineAgents = sdk.findAgentsByStatus("online");
|
|
126
|
+
const durationOnline = performance.now() - startTimeOnline;
|
|
127
|
+
console.log(`ā
Found ${onlineAgents.length} online agents (${durationOnline.toFixed(3)}ms):`);
|
|
128
|
+
onlineAgents.forEach((agent) => {
|
|
129
|
+
console.log(` ⢠${agent.name || agent.id} (${agent.status})`);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
console.log("\nš Offline agents:");
|
|
133
|
+
const startTimeOffline = performance.now();
|
|
134
|
+
const offlineAgents = sdk.findAgentsByStatus("offline");
|
|
135
|
+
const durationOffline = performance.now() - startTimeOffline;
|
|
136
|
+
console.log(
|
|
137
|
+
`ā
Found ${offlineAgents.length} offline agents (${durationOffline.toFixed(3)}ms):`
|
|
138
|
+
);
|
|
139
|
+
offlineAgents.forEach((agent) => {
|
|
140
|
+
console.log(` ⢠${agent.name || agent.id} (${agent.status})`);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Step 4: Find agents by name (O(k) token-based search)
|
|
144
|
+
console.log("\nāļø Step 4: Finding agents by name (token-based search)...");
|
|
145
|
+
|
|
146
|
+
const searchTerms = ["agent", "bot", "platform", "weather"];
|
|
147
|
+
|
|
148
|
+
for (const term of searchTerms) {
|
|
149
|
+
console.log(`\nš Searching for name containing: "${term}"`);
|
|
150
|
+
const startTime = performance.now();
|
|
151
|
+
const foundAgents = sdk.findAgentsByName(term);
|
|
152
|
+
const duration = performance.now() - startTime;
|
|
153
|
+
|
|
154
|
+
if (foundAgents.length > 0) {
|
|
155
|
+
console.log(`ā
Found ${foundAgents.length} agent(s) (${duration.toFixed(3)}ms):`);
|
|
156
|
+
foundAgents.forEach((agent) => {
|
|
157
|
+
console.log(` ⢠${agent.name || agent.id}`);
|
|
158
|
+
});
|
|
159
|
+
} else {
|
|
160
|
+
console.log(`ā No agents found with "${term}" in name (${duration.toFixed(3)}ms)`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Step 5: Performance summary
|
|
165
|
+
console.log("\nš Performance Summary:");
|
|
166
|
+
console.log("=".repeat(80));
|
|
167
|
+
console.log("\nThe SDK uses indexed lookups for optimal performance:");
|
|
168
|
+
console.log(" ⢠Capability search: O(1) - constant time");
|
|
169
|
+
console.log(" ⢠Status search: O(1) - constant time");
|
|
170
|
+
console.log(" ⢠Name search: O(k) - where k is the number of tokens");
|
|
171
|
+
console.log("\nAll searches complete in < 1ms even with many agents!");
|
|
172
|
+
console.log("=".repeat(80));
|
|
173
|
+
|
|
174
|
+
// Step 6: Practical example - find best agent for a task
|
|
175
|
+
console.log("\nāļø Step 6: Practical example - finding best agent for a task...");
|
|
176
|
+
console.log('\nTask: "Get Twitter timeline for a user"');
|
|
177
|
+
console.log("Strategy: Find online agents with social-media or twitter capabilities\n");
|
|
178
|
+
|
|
179
|
+
// First, try to find by specific capabilities
|
|
180
|
+
let candidates = sdk.findAgentsByCapability("social-media");
|
|
181
|
+
if (candidates.length === 0) {
|
|
182
|
+
candidates = sdk.findAgentsByCapability("twitter");
|
|
183
|
+
}
|
|
184
|
+
if (candidates.length === 0) {
|
|
185
|
+
candidates = sdk.findAgentsByCapability("x-platform");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Filter to only online agents
|
|
189
|
+
candidates = candidates.filter((a) => a.status === "online");
|
|
190
|
+
|
|
191
|
+
// If no capability match, try name search
|
|
192
|
+
if (candidates.length === 0) {
|
|
193
|
+
console.log("ā ļø No capability match, trying name search...");
|
|
194
|
+
const nameResults = sdk
|
|
195
|
+
.findAgentsByName("twitter")
|
|
196
|
+
.concat(sdk.findAgentsByName("x platform"))
|
|
197
|
+
.concat(sdk.findAgentsByName("social"));
|
|
198
|
+
|
|
199
|
+
// Remove duplicates and filter online
|
|
200
|
+
const uniqueIds = new Set<string>();
|
|
201
|
+
candidates = nameResults.filter((a) => {
|
|
202
|
+
if (uniqueIds.has(a.id) || a.status !== "online") {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
uniqueIds.add(a.id);
|
|
206
|
+
return true;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (candidates.length > 0) {
|
|
211
|
+
console.log(`ā
Found ${candidates.length} suitable agent(s):`);
|
|
212
|
+
candidates.forEach((agent, index) => {
|
|
213
|
+
console.log(`\n ${index + 1}. ${agent.name || agent.id}`);
|
|
214
|
+
console.log(` Status: ${agent.status}`);
|
|
215
|
+
if (agent.description) {
|
|
216
|
+
console.log(` Description: ${agent.description}`);
|
|
217
|
+
}
|
|
218
|
+
if (agent.capabilities && agent.capabilities.length > 0) {
|
|
219
|
+
console.log(` Capabilities: ${agent.capabilities.map((c) => c.name).join(", ")}`);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
console.log(`\nš” Recommendation: Use "${candidates[0].name || candidates[0].id}"`);
|
|
223
|
+
} else {
|
|
224
|
+
console.log("ā No suitable agents found for this task");
|
|
225
|
+
}
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error("\nā Error:", error);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
} finally {
|
|
230
|
+
sdk.disconnect();
|
|
231
|
+
sdk.destroy();
|
|
232
|
+
console.log("\nā
Disconnected");
|
|
233
|
+
console.log("š Example completed!");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
main().catch(console.error);
|