@teneo-protocol/sdk 3.0.1 → 3.1.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/CHANGELOG.md +21 -0
- package/README.md +106 -1
- package/dist/managers/message-router.d.ts +35 -0
- package/dist/managers/message-router.d.ts.map +1 -1
- package/dist/managers/message-router.js +143 -2
- package/dist/managers/message-router.js.map +1 -1
- package/dist/payments/payment-client.d.ts.map +1 -1
- package/dist/payments/payment-client.js +5 -3
- package/dist/payments/payment-client.js.map +1 -1
- package/dist/teneo-sdk.d.ts +1 -1
- package/dist/teneo-sdk.d.ts.map +1 -1
- package/dist/teneo-sdk.js +20 -2
- package/dist/teneo-sdk.js.map +1 -1
- package/dist/types/config.d.ts +29 -3
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +21 -2
- package/dist/types/config.js.map +1 -1
- package/dist/types/error-codes.d.ts +3 -0
- package/dist/types/error-codes.d.ts.map +1 -1
- package/dist/types/error-codes.js +4 -0
- package/dist/types/error-codes.js.map +1 -1
- package/dist/types/events.d.ts +3 -0
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js.map +1 -1
- package/package.json +1 -1
- package/src/managers/message-router.ts +183 -3
- package/src/payments/payment-client.ts +6 -3
- package/src/teneo-sdk.ts +21 -2
- package/src/types/config.ts +23 -2
- package/src/types/error-codes.ts +5 -0
- package/src/types/events.ts +5 -0
- package/tests/unit/managers/message-router-autosummon.test.ts +338 -0
package/dist/types/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
TaskQuoteMessage,
|
|
21
21
|
PricingInfo
|
|
22
22
|
} from "../types";
|
|
23
|
-
import { SDKEvents, SDKError, ValidationError, AgentResponse, PaymentError } from "../types/events";
|
|
23
|
+
import { SDKEvents, SDKError, ValidationError, type AgentResponse, PaymentError, MessageError } from "../types/events";
|
|
24
|
+
import type { AgentRoomManager } from "./agent-room-manager";
|
|
24
25
|
import { ErrorCode } from "../types/error-codes";
|
|
25
26
|
import { TIMEOUTS } from "../constants";
|
|
26
27
|
import {
|
|
@@ -88,6 +89,7 @@ export interface MessageRouterConfig {
|
|
|
88
89
|
paymentNetwork?: string; // CAIP-2 format (e.g., "eip155:3338")
|
|
89
90
|
paymentAsset?: string;
|
|
90
91
|
network?: string; // Network name (e.g., "peaq", "base", "avalanche")
|
|
92
|
+
autoSummon?: boolean; // Auto-add agents to room on "Agent not found" (v2.4.0)
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
@@ -109,6 +111,10 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
109
111
|
private readonly paymentAsset: string;
|
|
110
112
|
private readonly networkName: string; // Network name (peaq, base, avalanche)
|
|
111
113
|
|
|
114
|
+
// Auto-summon (v2.4.0)
|
|
115
|
+
private readonly autoSummon: boolean;
|
|
116
|
+
private agentRoomManager: AgentRoomManager | null = null;
|
|
117
|
+
|
|
112
118
|
constructor(
|
|
113
119
|
wsClient: WebSocketClient,
|
|
114
120
|
webhookHandler: WebhookHandler,
|
|
@@ -135,6 +141,7 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
135
141
|
this.paymentNetwork = config.paymentNetwork ?? "";
|
|
136
142
|
this.paymentAsset = config.paymentAsset ?? "";
|
|
137
143
|
this.networkName = config.network ?? "";
|
|
144
|
+
this.autoSummon = config.autoSummon ?? false;
|
|
138
145
|
|
|
139
146
|
this.setupEventForwarding();
|
|
140
147
|
}
|
|
@@ -187,6 +194,13 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
187
194
|
});
|
|
188
195
|
}
|
|
189
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Sets the agent room manager for auto-summon functionality (v2.4.0).
|
|
199
|
+
*/
|
|
200
|
+
public setAgentRoomManager(manager: AgentRoomManager): void {
|
|
201
|
+
this.agentRoomManager = manager;
|
|
202
|
+
}
|
|
203
|
+
|
|
190
204
|
/**
|
|
191
205
|
* Sends a message to agents via the coordinator.
|
|
192
206
|
* The coordinator intelligently selects the most appropriate agent.
|
|
@@ -359,6 +373,16 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
359
373
|
* Returns the quote data for manual confirmation.
|
|
360
374
|
*/
|
|
361
375
|
public async requestQuote(content: string, room: string, networkOverride?: string | number): Promise<QuoteResult> {
|
|
376
|
+
return this._requestQuoteInternal(content, room, networkOverride, false);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Internal quote request with error racing and auto-summon support.
|
|
381
|
+
* @param isRetry - true on auto-summon retry to prevent infinite loops
|
|
382
|
+
*/
|
|
383
|
+
private async _requestQuoteInternal(
|
|
384
|
+
content: string, room: string, networkOverride: string | number | undefined, isRetry: boolean
|
|
385
|
+
): Promise<QuoteResult> {
|
|
362
386
|
if (!this.wsClient.isConnected) {
|
|
363
387
|
throw new SDKError("Not connected to Teneo network", ErrorCode.NOT_CONNECTED);
|
|
364
388
|
}
|
|
@@ -366,15 +390,77 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
366
390
|
// Include payment network in request so backend returns correct contract addresses
|
|
367
391
|
const resolvedNetwork = this.getResolvedPaymentNetwork(networkOverride);
|
|
368
392
|
const message = createRequestTask(content, room, resolvedNetwork);
|
|
369
|
-
this.logger.debug("MessageRouter: Requesting quote", { content, room, network: resolvedNetwork });
|
|
393
|
+
this.logger.debug("MessageRouter: Requesting quote", { content, room, network: resolvedNetwork, isRetry });
|
|
394
|
+
|
|
395
|
+
// Pre-flight autosummon: check cache before sending to avoid reject-retry cycle
|
|
396
|
+
if (this.autoSummon && this.agentRoomManager && !isRetry) {
|
|
397
|
+
const match = content.match(/^@(\S+)/);
|
|
398
|
+
if (match) {
|
|
399
|
+
const agentName = match[1];
|
|
400
|
+
const inRoom = this.agentRoomManager.checkAgentInRoom(room, agentName);
|
|
401
|
+
if (inRoom === false) {
|
|
402
|
+
this.logger.info("MessageRouter: Pre-flight autosummon", { agentName, room });
|
|
403
|
+
try {
|
|
404
|
+
await this.preFlightAutoSummon(agentName, room);
|
|
405
|
+
} catch (e) {
|
|
406
|
+
this.logger.debug("MessageRouter: Pre-flight failed, falling back", { error: (e as Error).message });
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
370
411
|
|
|
371
412
|
await this.wsClient.sendMessage(message);
|
|
372
413
|
|
|
373
|
-
|
|
414
|
+
// Race quote:received against error events to detect "Agent not found" quickly.
|
|
415
|
+
// The backend may signal "agent not in room" via:
|
|
416
|
+
// 1. An "error" event with "agent ... not found"
|
|
417
|
+
// 2. An "agent:response" from the coordinator with content like
|
|
418
|
+
// "agent X does not have access to room Y"
|
|
419
|
+
// We race all three to catch whichever arrives first.
|
|
420
|
+
const quotePromise = waitForEvent<TaskQuoteMessage>(this.wsClient, "quote:received", {
|
|
374
421
|
timeout: this.quoteTimeout,
|
|
375
422
|
timeoutMessage: `Quote request timed out after ${this.quoteTimeout}ms`
|
|
376
423
|
});
|
|
377
424
|
|
|
425
|
+
const errorPromise = waitForEvent<MessageError>(this.wsClient, "error", {
|
|
426
|
+
timeout: this.quoteTimeout + 1000,
|
|
427
|
+
filter: (err: MessageError) => {
|
|
428
|
+
const msg = (err.message || "").toLowerCase();
|
|
429
|
+
return this.isAgentAccessErrorMessage(msg);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
// Also race against agent:response that contains an access-denied error from the coordinator
|
|
434
|
+
const agentErrorPromise = waitForEvent<AgentResponse>(this.wsClient, "agent:response", {
|
|
435
|
+
timeout: this.quoteTimeout + 1000,
|
|
436
|
+
filter: (resp: AgentResponse) => {
|
|
437
|
+
const msg = (resp.content || "").toLowerCase();
|
|
438
|
+
return this.isAgentAccessErrorMessage(msg);
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
let quote: TaskQuoteMessage;
|
|
443
|
+
try {
|
|
444
|
+
quote = await Promise.race([
|
|
445
|
+
quotePromise,
|
|
446
|
+
errorPromise.then((err) => { throw err; }),
|
|
447
|
+
agentErrorPromise.then((resp) => {
|
|
448
|
+
throw new SDKError(resp.content, ErrorCode.AGENT_NOT_IN_ROOM);
|
|
449
|
+
})
|
|
450
|
+
]);
|
|
451
|
+
} catch (error) {
|
|
452
|
+
if (this.isAgentNotFoundError(error) && !isRetry) {
|
|
453
|
+
if (this.autoSummon) {
|
|
454
|
+
return this.handleAutoSummon(content, room, networkOverride);
|
|
455
|
+
}
|
|
456
|
+
throw new SDKError(
|
|
457
|
+
"Agent not found in room. Enable autoSummon to automatically add agents.",
|
|
458
|
+
ErrorCode.AGENT_NOT_IN_ROOM
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
|
|
378
464
|
const result: QuoteResult = {
|
|
379
465
|
taskId: quote.data.task_id,
|
|
380
466
|
agentId: quote.data.agent_id,
|
|
@@ -405,6 +491,100 @@ export class MessageRouter extends EventEmitter<SDKEvents> {
|
|
|
405
491
|
return result;
|
|
406
492
|
}
|
|
407
493
|
|
|
494
|
+
/**
|
|
495
|
+
* Pre-flight autosummon: adds agent to room before sending the command.
|
|
496
|
+
* Called when cache confirms agent is NOT in room, avoiding the reject-retry cycle.
|
|
497
|
+
*/
|
|
498
|
+
private async preFlightAutoSummon(agentName: string, room: string): Promise<void> {
|
|
499
|
+
if (!this.agentRoomManager) {
|
|
500
|
+
throw new SDKError("Auto-summon requires AgentRoomManager", ErrorCode.AUTOSUMMON_FAILED);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
this.wsClient.emit("autosummon:start", agentName, room);
|
|
504
|
+
|
|
505
|
+
const available = await this.agentRoomManager.listAvailableAgents(room, false);
|
|
506
|
+
const agent = available.find(
|
|
507
|
+
(a) => a.agent_id === agentName || a.agent_name === agentName
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
if (!agent) {
|
|
511
|
+
this.wsClient.emit("autosummon:failed", agentName, room, "Agent not found or offline");
|
|
512
|
+
throw new SDKError(
|
|
513
|
+
`Agent '${agentName}' does not exist or is offline`,
|
|
514
|
+
ErrorCode.AGENT_NOT_FOUND
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
await this.agentRoomManager.addAgentToRoom(room, agent.agent_id);
|
|
519
|
+
this.wsClient.emit("autosummon:success", agentName, agent.agent_id, room);
|
|
520
|
+
this.logger.info("MessageRouter: Pre-flight autosummon succeeded", { agentId: agent.agent_id });
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Handles auto-summon: finds the agent, adds it to the room, and retries the quote.
|
|
525
|
+
* Fallback path triggered by coordinator reject when pre-flight was skipped (cache empty).
|
|
526
|
+
*/
|
|
527
|
+
private async handleAutoSummon(
|
|
528
|
+
content: string, room: string, networkOverride?: string | number
|
|
529
|
+
): Promise<QuoteResult> {
|
|
530
|
+
if (!this.agentRoomManager) {
|
|
531
|
+
throw new SDKError("Auto-summon requires AgentRoomManager", ErrorCode.AUTOSUMMON_FAILED);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
const match = content.match(/^@(\S+)/);
|
|
535
|
+
if (!match) {
|
|
536
|
+
throw new SDKError("Cannot extract agent name for auto-summon", ErrorCode.AUTOSUMMON_FAILED);
|
|
537
|
+
}
|
|
538
|
+
const agentName = match[1];
|
|
539
|
+
|
|
540
|
+
this.logger.info("MessageRouter: Auto-summoning agent", { agentName, room });
|
|
541
|
+
this.wsClient.emit("autosummon:start", agentName, room);
|
|
542
|
+
|
|
543
|
+
const available = await this.agentRoomManager.listAvailableAgents(room, false);
|
|
544
|
+
const agent = available.find(
|
|
545
|
+
(a) => a.agent_id === agentName || a.agent_name === agentName
|
|
546
|
+
);
|
|
547
|
+
|
|
548
|
+
if (!agent) {
|
|
549
|
+
this.wsClient.emit("autosummon:failed", agentName, room, "Agent not found or offline");
|
|
550
|
+
throw new SDKError(
|
|
551
|
+
`Agent '${agentName}' does not exist or is offline`,
|
|
552
|
+
ErrorCode.AGENT_NOT_FOUND
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
await this.agentRoomManager.addAgentToRoom(room, agent.agent_id);
|
|
557
|
+
this.wsClient.emit("autosummon:success", agentName, agent.agent_id, room);
|
|
558
|
+
this.logger.info("MessageRouter: Agent auto-summoned, retrying", { agentId: agent.agent_id });
|
|
559
|
+
|
|
560
|
+
return this._requestQuoteInternal(content, room, networkOverride, true);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Checks if a message string indicates an agent-access error from the backend.
|
|
565
|
+
* Matches patterns like:
|
|
566
|
+
* - "agent X not found"
|
|
567
|
+
* - "agent X does not have access to room Y"
|
|
568
|
+
* - "Agent not found. Check the agent name..."
|
|
569
|
+
*/
|
|
570
|
+
private isAgentAccessErrorMessage(msg: string): boolean {
|
|
571
|
+
if (!msg.includes("agent")) return false;
|
|
572
|
+
return (
|
|
573
|
+
msg.includes("not found") ||
|
|
574
|
+
msg.includes("does not have access") ||
|
|
575
|
+
msg.includes("not in room") ||
|
|
576
|
+
msg.includes("no access")
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Checks if an error is an "Agent not found / not in room" error from the backend.
|
|
582
|
+
*/
|
|
583
|
+
private isAgentNotFoundError(error: unknown): boolean {
|
|
584
|
+
const msg = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
585
|
+
return this.isAgentAccessErrorMessage(msg);
|
|
586
|
+
}
|
|
587
|
+
|
|
408
588
|
/**
|
|
409
589
|
* Confirms a quote and executes the task with payment.
|
|
410
590
|
* Can optionally wait for the task response.
|
|
@@ -243,6 +243,9 @@ export class PaymentClient {
|
|
|
243
243
|
const settlementRouter = settlementData?.settlementRouter ?? network.settlementRouter;
|
|
244
244
|
const hook = settlementData?.hook ?? network.transferHook;
|
|
245
245
|
|
|
246
|
+
// Total ERC-3009 value = agent price + facilitator fee (fee is added on top, not deducted)
|
|
247
|
+
const totalValueStr = (BigInt(amountStr) + BigInt(facilitatorFee)).toString();
|
|
248
|
+
|
|
246
249
|
// Calculate commitment hash (becomes the EIP-3009 nonce)
|
|
247
250
|
// This cryptographically binds all settlement parameters to the signature
|
|
248
251
|
const commitment = keccak256(
|
|
@@ -268,7 +271,7 @@ export class PaymentClient {
|
|
|
268
271
|
settlementRouter as Hex,
|
|
269
272
|
asset as Hex,
|
|
270
273
|
account.address,
|
|
271
|
-
BigInt(
|
|
274
|
+
BigInt(totalValueStr),
|
|
272
275
|
BigInt(validAfter),
|
|
273
276
|
BigInt(validBefore),
|
|
274
277
|
salt as Hex,
|
|
@@ -293,7 +296,7 @@ export class PaymentClient {
|
|
|
293
296
|
const message = {
|
|
294
297
|
from: account.address,
|
|
295
298
|
to: settlementRouter as `0x${string}`, // Router receives funds first
|
|
296
|
-
value: BigInt(
|
|
299
|
+
value: BigInt(totalValueStr),
|
|
297
300
|
validAfter: BigInt(validAfter),
|
|
298
301
|
validBefore: BigInt(validBefore),
|
|
299
302
|
nonce: commitment // Commitment hash as nonce
|
|
@@ -313,7 +316,7 @@ export class PaymentClient {
|
|
|
313
316
|
authorization: {
|
|
314
317
|
from: account.address,
|
|
315
318
|
to: settlementRouter, // Router address
|
|
316
|
-
value:
|
|
319
|
+
value: totalValueStr,
|
|
317
320
|
validAfter: validAfter.toString(),
|
|
318
321
|
validBefore: validBefore.toString(),
|
|
319
322
|
nonce: commitment // Commitment hash
|
package/src/teneo-sdk.ts
CHANGED
|
@@ -167,7 +167,13 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
167
167
|
if (typeof config.privateKey === "object" && "use" in config.privateKey) {
|
|
168
168
|
this.secureKey = config.privateKey;
|
|
169
169
|
} else {
|
|
170
|
-
|
|
170
|
+
// Ensure the private key has 0x prefix before encrypting (matches websocket-client normalization)
|
|
171
|
+
const pkStr = (config.privateKey as string).trim();
|
|
172
|
+
const normalized = pkStr.startsWith("0x") ? pkStr : `0x${pkStr}`;
|
|
173
|
+
if (normalized.length < 66) {
|
|
174
|
+
throw new Error("Invalid private key: expected 32 bytes (64 hex characters)");
|
|
175
|
+
}
|
|
176
|
+
this.secureKey = new SecurePrivateKey(normalized);
|
|
171
177
|
}
|
|
172
178
|
}
|
|
173
179
|
|
|
@@ -206,9 +212,11 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
206
212
|
wsUrl: this.config.wsUrl,
|
|
207
213
|
paymentNetwork: this.config.paymentNetwork,
|
|
208
214
|
paymentAsset: this.config.paymentAsset,
|
|
209
|
-
network: this.config.network // Network name from withNetwork()
|
|
215
|
+
network: this.config.network, // Network name from withNetwork()
|
|
216
|
+
autoSummon: this.config.autoSummon // Auto-summon (v2.4.0)
|
|
210
217
|
}
|
|
211
218
|
);
|
|
219
|
+
this.messages.setAgentRoomManager(this.agentRoom); // Enable auto-summon (v2.4.0)
|
|
212
220
|
|
|
213
221
|
// NOTE: Payment client is set up in connect() after networks are initialized
|
|
214
222
|
|
|
@@ -2080,6 +2088,17 @@ export class TeneoSDK extends EventEmitter<SDKEvents> {
|
|
|
2080
2088
|
this.emit("agent_room:list_available_error", error);
|
|
2081
2089
|
});
|
|
2082
2090
|
|
|
2091
|
+
// Forward autosummon lifecycle events (v2.5.0)
|
|
2092
|
+
this.wsClient.on("autosummon:start", (agentName, roomId) => {
|
|
2093
|
+
this.emit("autosummon:start", agentName, roomId);
|
|
2094
|
+
});
|
|
2095
|
+
this.wsClient.on("autosummon:success", (agentName, agentId, roomId) => {
|
|
2096
|
+
this.emit("autosummon:success", agentName, agentId, roomId);
|
|
2097
|
+
});
|
|
2098
|
+
this.wsClient.on("autosummon:failed", (agentName, roomId, reason) => {
|
|
2099
|
+
this.emit("autosummon:failed", agentName, roomId, reason);
|
|
2100
|
+
});
|
|
2101
|
+
|
|
2083
2102
|
// Forward admin events from AdminManager
|
|
2084
2103
|
this._admin.on("user_count", (data) => {
|
|
2085
2104
|
this.emit("admin:user_count", data);
|
package/src/types/config.ts
CHANGED
|
@@ -152,7 +152,10 @@ const SDKConfigBaseSchema = z.object({
|
|
|
152
152
|
|
|
153
153
|
// Multi-network support (v2.3.0)
|
|
154
154
|
network: z.string().optional(), // Network name (peaq, base, avalanche)
|
|
155
|
-
networkChainId: z.number().optional() // Or chain ID directly
|
|
155
|
+
networkChainId: z.number().optional(), // Or chain ID directly
|
|
156
|
+
|
|
157
|
+
// Auto-summon (v2.4.0)
|
|
158
|
+
autoSummon: z.boolean().optional() // Auto-add agents to room on "Agent not found"
|
|
156
159
|
});
|
|
157
160
|
|
|
158
161
|
// SDK Configuration schema with transform for backward compatibility
|
|
@@ -193,7 +196,7 @@ export const AuthenticationStateSchema = z.object({
|
|
|
193
196
|
walletAddress: z.string().optional(),
|
|
194
197
|
isWhitelisted: z.boolean().optional(),
|
|
195
198
|
isAdmin: z.boolean().optional(),
|
|
196
|
-
nftVerified: z.boolean().optional(),
|
|
199
|
+
nftVerified: z.union([z.boolean(), z.string()]).optional(),
|
|
197
200
|
rooms: z.array(z.string()).optional(), // Room IDs for backward compatibility (deprecated)
|
|
198
201
|
roomObjects: z.array(RoomInfoSchema).optional(), // Full room objects from auth (v2.0.0: uses RoomInfo)
|
|
199
202
|
privateRoomId: z.string().optional(), // DEPRECATED: Single room ID (use privateRoomIds instead)
|
|
@@ -948,6 +951,24 @@ export class SDKConfigBuilder {
|
|
|
948
951
|
return this;
|
|
949
952
|
}
|
|
950
953
|
|
|
954
|
+
/**
|
|
955
|
+
* Enables or disables auto-summon (v2.4.0).
|
|
956
|
+
* When enabled, the SDK automatically adds agents to the room if they are
|
|
957
|
+
* not present when a command is sent, then retries the command.
|
|
958
|
+
*
|
|
959
|
+
* @param enabled - Whether to enable auto-summon (default: false)
|
|
960
|
+
* @returns this builder for method chaining
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* ```typescript
|
|
964
|
+
* builder.withAutoSummon(true) // Auto-add agents to room when not found
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
967
|
+
withAutoSummon(enabled: boolean): this {
|
|
968
|
+
this.config.autoSummon = z.boolean().parse(enabled);
|
|
969
|
+
return this;
|
|
970
|
+
}
|
|
971
|
+
|
|
951
972
|
/**
|
|
952
973
|
* Builds and validates the final SDK configuration.
|
|
953
974
|
* Performs comprehensive validation including custom refinements (e.g., webhook security).
|
package/src/types/error-codes.ts
CHANGED
|
@@ -52,6 +52,11 @@ export enum ErrorCode {
|
|
|
52
52
|
PAYMENT_FAILED = "PAYMENT_FAILED",
|
|
53
53
|
PAYMENT_SIGNATURE_FAILED = "PAYMENT_SIGNATURE_FAILED",
|
|
54
54
|
|
|
55
|
+
// Auto-summon errors (v2.4.0)
|
|
56
|
+
AGENT_NOT_IN_ROOM = "AGENT_NOT_IN_ROOM",
|
|
57
|
+
AGENT_NOT_FOUND = "AGENT_NOT_FOUND",
|
|
58
|
+
AUTOSUMMON_FAILED = "AUTOSUMMON_FAILED",
|
|
59
|
+
|
|
55
60
|
// Generic timeout (for backward compatibility)
|
|
56
61
|
TIMEOUT_ERROR = "TIMEOUT_ERROR",
|
|
57
62
|
TIMEOUT = "TIMEOUT"
|
package/src/types/events.ts
CHANGED
|
@@ -408,6 +408,11 @@ export interface SDKEvents {
|
|
|
408
408
|
room?: string;
|
|
409
409
|
}) => void;
|
|
410
410
|
|
|
411
|
+
// Autosummon lifecycle events (v2.5.0)
|
|
412
|
+
"autosummon:start": (agentName: string, roomId: string) => void;
|
|
413
|
+
"autosummon:success": (agentName: string, agentId: string, roomId: string) => void;
|
|
414
|
+
"autosummon:failed": (agentName: string, roomId: string, reason: string) => void;
|
|
415
|
+
|
|
411
416
|
// Webhook events
|
|
412
417
|
"webhook:sent": (payload: any, url: string) => void;
|
|
413
418
|
"webhook:success": (response: any, url: string) => void;
|