agent-relay 3.1.1 → 3.1.2
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/package.json +8 -8
- package/packages/acp-bridge/package.json +2 -2
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/openclaw/dist/__tests__/gateway-control.test.d.ts +2 -0
- package/packages/openclaw/dist/__tests__/gateway-control.test.d.ts.map +1 -0
- package/packages/openclaw/dist/__tests__/gateway-control.test.js +250 -0
- package/packages/openclaw/dist/__tests__/gateway-control.test.js.map +1 -0
- package/packages/openclaw/dist/__tests__/gateway-threads.test.js +617 -0
- package/packages/openclaw/dist/__tests__/gateway-threads.test.js.map +1 -1
- package/packages/openclaw/dist/__tests__/spawn-manager.test.js +29 -0
- package/packages/openclaw/dist/__tests__/spawn-manager.test.js.map +1 -1
- package/packages/openclaw/dist/__tests__/ws-client.test.d.ts +2 -0
- package/packages/openclaw/dist/__tests__/ws-client.test.d.ts.map +1 -0
- package/packages/openclaw/dist/__tests__/ws-client.test.js +324 -0
- package/packages/openclaw/dist/__tests__/ws-client.test.js.map +1 -0
- package/packages/openclaw/dist/cli.js +1 -1
- package/packages/openclaw/dist/cli.js.map +1 -1
- package/packages/openclaw/dist/gateway.d.ts +33 -7
- package/packages/openclaw/dist/gateway.d.ts.map +1 -1
- package/packages/openclaw/dist/gateway.js +101 -50
- package/packages/openclaw/dist/gateway.js.map +1 -1
- package/packages/openclaw/dist/types.d.ts +5 -1
- package/packages/openclaw/dist/types.d.ts.map +1 -1
- package/packages/openclaw/package.json +2 -2
- package/packages/openclaw/skill/SKILL.md +35 -13
- package/packages/openclaw/src/__tests__/SPEC-ws-client-testing.md +192 -0
- package/packages/openclaw/src/__tests__/gateway-control.test.ts +288 -0
- package/packages/openclaw/src/__tests__/gateway-threads.test.ts +746 -0
- package/packages/openclaw/src/__tests__/spawn-manager.test.ts +37 -0
- package/packages/openclaw/src/__tests__/ws-client.test.ts +395 -0
- package/packages/openclaw/src/cli.ts +1 -1
- package/packages/openclaw/src/gateway.ts +129 -56
- package/packages/openclaw/src/types.ts +5 -1
- package/packages/policy/package.json +2 -2
- package/packages/sdk/package.json +2 -2
- package/packages/sdk-py/pyproject.toml +1 -1
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +2 -2
|
@@ -3,7 +3,15 @@ import { createServer, type Server as HttpServer, type IncomingMessage, type Ser
|
|
|
3
3
|
|
|
4
4
|
import type { SendMessageInput } from '@agent-relay/sdk';
|
|
5
5
|
import { RelayCast, type AgentClient } from '@relaycast/sdk';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
MessageCreatedEvent,
|
|
8
|
+
ThreadReplyEvent,
|
|
9
|
+
DmReceivedEvent,
|
|
10
|
+
GroupDmReceivedEvent,
|
|
11
|
+
CommandInvokedEvent,
|
|
12
|
+
ReactionAddedEvent,
|
|
13
|
+
ReactionRemovedEvent,
|
|
14
|
+
} from '@relaycast/sdk';
|
|
7
15
|
import WebSocket from 'ws';
|
|
8
16
|
|
|
9
17
|
import type { GatewayConfig, InboundMessage, DeliveryResult } from './types.js';
|
|
@@ -106,7 +114,8 @@ interface PendingRpc {
|
|
|
106
114
|
timer: ReturnType<typeof setTimeout>;
|
|
107
115
|
}
|
|
108
116
|
|
|
109
|
-
|
|
117
|
+
/** @internal */
|
|
118
|
+
export class OpenClawGatewayClient {
|
|
110
119
|
private ws: WebSocket | null = null;
|
|
111
120
|
private authenticated = false;
|
|
112
121
|
private device: DeviceIdentity;
|
|
@@ -419,15 +428,12 @@ export class InboundGateway {
|
|
|
419
428
|
private relayAgentClient: AgentClient | null = null;
|
|
420
429
|
private readonly relaycast: RelayCast;
|
|
421
430
|
private readonly config: GatewayConfig;
|
|
422
|
-
private readonly fallbackPollMs: number;
|
|
423
431
|
private readonly dedupeTtlMs: number;
|
|
424
432
|
|
|
425
433
|
private running = false;
|
|
426
|
-
private pollTimer: ReturnType<typeof setInterval> | null = null;
|
|
427
434
|
private unsubscribeHandlers: Array<() => void> = [];
|
|
428
435
|
private seenMessageIds = new Map<string, number>();
|
|
429
436
|
private processingMessageIds = new Set<string>();
|
|
430
|
-
private channelCursor = new Map<string, string>();
|
|
431
437
|
|
|
432
438
|
/** Persistent WebSocket client for the local OpenClaw gateway. */
|
|
433
439
|
private openclawClient: OpenClawGatewayClient | null = null;
|
|
@@ -453,11 +459,6 @@ export class InboundGateway {
|
|
|
453
459
|
baseUrl: this.config.baseUrl,
|
|
454
460
|
});
|
|
455
461
|
|
|
456
|
-
const fallbackPollMs = Number(process.env.RELAYCAST_FALLBACK_POLL_MS ?? 15000);
|
|
457
|
-
this.fallbackPollMs = Number.isFinite(fallbackPollMs) && fallbackPollMs >= 1000
|
|
458
|
-
? Math.floor(fallbackPollMs)
|
|
459
|
-
: 15000;
|
|
460
|
-
|
|
461
462
|
const dedupeTtlMs = Number(process.env.RELAYCAST_DEDUPE_TTL_MS ?? 15 * 60 * 1000);
|
|
462
463
|
this.dedupeTtlMs = Number.isFinite(dedupeTtlMs) && dedupeTtlMs >= 1000
|
|
463
464
|
? Math.floor(dedupeTtlMs)
|
|
@@ -467,7 +468,7 @@ export class InboundGateway {
|
|
|
467
468
|
this.spawnManager = new SpawnManager({ spawnDepth: parentDepth + 1 });
|
|
468
469
|
}
|
|
469
470
|
|
|
470
|
-
/** Start the gateway — register agent
|
|
471
|
+
/** Start the gateway — register agent and subscribe for realtime events. */
|
|
471
472
|
async start(): Promise<void> {
|
|
472
473
|
if (this.running) return;
|
|
473
474
|
this.running = true;
|
|
@@ -521,6 +522,36 @@ export class InboundGateway {
|
|
|
521
522
|
void this.handleRealtimeThreadReply(event);
|
|
522
523
|
}),
|
|
523
524
|
);
|
|
525
|
+
this.unsubscribeHandlers.push(
|
|
526
|
+
this.relayAgentClient.on.dmReceived((event: DmReceivedEvent) => {
|
|
527
|
+
console.log(`[gateway] DM from @${event.message?.agentName} (conv: ${event.conversationId})`);
|
|
528
|
+
void this.handleRealtimeDm(event);
|
|
529
|
+
}),
|
|
530
|
+
);
|
|
531
|
+
this.unsubscribeHandlers.push(
|
|
532
|
+
this.relayAgentClient.on.groupDmReceived((event: GroupDmReceivedEvent) => {
|
|
533
|
+
console.log(`[gateway] Group DM from @${event.message?.agentName} (conv: ${event.conversationId})`);
|
|
534
|
+
void this.handleRealtimeGroupDm(event);
|
|
535
|
+
}),
|
|
536
|
+
);
|
|
537
|
+
this.unsubscribeHandlers.push(
|
|
538
|
+
this.relayAgentClient.on.commandInvoked((event: CommandInvokedEvent) => {
|
|
539
|
+
console.log(`[gateway] Command /${event.command} invoked by @${event.invokedBy} in #${event.channel}`);
|
|
540
|
+
void this.handleRealtimeCommand(event);
|
|
541
|
+
}),
|
|
542
|
+
);
|
|
543
|
+
this.unsubscribeHandlers.push(
|
|
544
|
+
this.relayAgentClient.on.reactionAdded((event: ReactionAddedEvent) => {
|
|
545
|
+
console.log(`[gateway] Reaction :${event.emoji}: added by @${event.agentName} on ${event.messageId}`);
|
|
546
|
+
void this.handleRealtimeReaction(event, 'added');
|
|
547
|
+
}),
|
|
548
|
+
);
|
|
549
|
+
this.unsubscribeHandlers.push(
|
|
550
|
+
this.relayAgentClient.on.reactionRemoved((event: ReactionRemovedEvent) => {
|
|
551
|
+
console.log(`[gateway] Reaction :${event.emoji}: removed by @${event.agentName} from ${event.messageId}`);
|
|
552
|
+
void this.handleRealtimeReaction(event, 'removed');
|
|
553
|
+
}),
|
|
554
|
+
);
|
|
524
555
|
this.unsubscribeHandlers.push(
|
|
525
556
|
this.relayAgentClient.on.reconnecting((attempt: number) => {
|
|
526
557
|
console.warn(`[gateway] Relaycast reconnecting (attempt ${attempt})`);
|
|
@@ -547,14 +578,6 @@ export class InboundGateway {
|
|
|
547
578
|
// Will subscribe on next connected event
|
|
548
579
|
}
|
|
549
580
|
|
|
550
|
-
// Initial catch-up in case messages arrived before realtime subscription was active.
|
|
551
|
-
await this.pollMessages();
|
|
552
|
-
|
|
553
|
-
// Keep a low-frequency poll as recovery/backfill only.
|
|
554
|
-
this.pollTimer = setInterval(() => {
|
|
555
|
-
void this.pollMessages();
|
|
556
|
-
}, this.fallbackPollMs);
|
|
557
|
-
|
|
558
581
|
console.log(
|
|
559
582
|
`[gateway] Realtime listening on channels: ${this.config.channels.join(', ')}`,
|
|
560
583
|
);
|
|
@@ -567,11 +590,6 @@ export class InboundGateway {
|
|
|
567
590
|
async stop(): Promise<void> {
|
|
568
591
|
this.running = false;
|
|
569
592
|
|
|
570
|
-
if (this.pollTimer) {
|
|
571
|
-
clearInterval(this.pollTimer);
|
|
572
|
-
this.pollTimer = null;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
593
|
for (const unsubscribe of this.unsubscribeHandlers) {
|
|
576
594
|
try {
|
|
577
595
|
unsubscribe();
|
|
@@ -603,7 +621,6 @@ export class InboundGateway {
|
|
|
603
621
|
await this.spawnManager.releaseAll();
|
|
604
622
|
|
|
605
623
|
this.processingMessageIds.clear();
|
|
606
|
-
this.channelCursor.clear();
|
|
607
624
|
this.seenMessageIds.clear();
|
|
608
625
|
}
|
|
609
626
|
|
|
@@ -681,40 +698,87 @@ export class InboundGateway {
|
|
|
681
698
|
await this.handleInbound(inbound);
|
|
682
699
|
}
|
|
683
700
|
|
|
684
|
-
private
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
701
|
+
private async handleRealtimeDm(event: DmReceivedEvent): Promise<void> {
|
|
702
|
+
const messageId = event.message?.id;
|
|
703
|
+
if (!messageId) return;
|
|
704
|
+
|
|
705
|
+
const inbound: InboundMessage = {
|
|
706
|
+
id: messageId,
|
|
707
|
+
channel: 'dm',
|
|
708
|
+
from: event.message.agentName,
|
|
709
|
+
text: event.message.text,
|
|
710
|
+
timestamp: new Date().toISOString(),
|
|
711
|
+
conversationId: event.conversationId,
|
|
712
|
+
kind: 'dm',
|
|
691
713
|
};
|
|
714
|
+
|
|
715
|
+
await this.handleInbound(inbound);
|
|
692
716
|
}
|
|
693
717
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
if (!
|
|
718
|
+
private async handleRealtimeGroupDm(event: GroupDmReceivedEvent): Promise<void> {
|
|
719
|
+
const messageId = event.message?.id;
|
|
720
|
+
if (!messageId) return;
|
|
697
721
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
722
|
+
const inbound: InboundMessage = {
|
|
723
|
+
id: messageId,
|
|
724
|
+
channel: `groupdm:${event.conversationId}`,
|
|
725
|
+
from: event.message.agentName,
|
|
726
|
+
text: event.message.text,
|
|
727
|
+
timestamp: new Date().toISOString(),
|
|
728
|
+
conversationId: event.conversationId,
|
|
729
|
+
kind: 'groupdm',
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
await this.handleInbound(inbound);
|
|
733
|
+
}
|
|
705
734
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
);
|
|
735
|
+
private async handleRealtimeCommand(event: CommandInvokedEvent): Promise<void> {
|
|
736
|
+
const channel = normalizeChannelName(event.channel);
|
|
737
|
+
if (!this.config.channels.includes(channel)) return;
|
|
710
738
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
}
|
|
739
|
+
// Commands lack a server-assigned event ID, so we synthesize one.
|
|
740
|
+
// We include args + timestamp to avoid silently dropping legitimate
|
|
741
|
+
// repeat invocations (e.g. /deploy twice in 15 min). This means SDK
|
|
742
|
+
// reconnection replays may deliver a duplicate, but that's less
|
|
743
|
+
// harmful than silently swallowing a real command.
|
|
744
|
+
const argsSlug = event.args ? `_${event.args}` : '';
|
|
745
|
+
const syntheticId = `cmd_${event.command}_${channel}_${event.invokedBy}${argsSlug}_${Date.now()}`;
|
|
746
|
+
const argsText = event.args ? ` ${event.args}` : '';
|
|
747
|
+
|
|
748
|
+
const inbound: InboundMessage = {
|
|
749
|
+
id: syntheticId,
|
|
750
|
+
channel,
|
|
751
|
+
from: event.invokedBy,
|
|
752
|
+
text: `[relaycast:command:${channel}] @${event.invokedBy} /${event.command}${argsText}`,
|
|
753
|
+
timestamp: new Date().toISOString(),
|
|
754
|
+
kind: 'command',
|
|
755
|
+
};
|
|
756
|
+
|
|
757
|
+
await this.handleInbound(inbound);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
private async handleRealtimeReaction(
|
|
761
|
+
event: ReactionAddedEvent | ReactionRemovedEvent,
|
|
762
|
+
action: 'added' | 'removed',
|
|
763
|
+
): Promise<void> {
|
|
764
|
+
// Include timestamp so add→remove→re-add of the same emoji isn't
|
|
765
|
+
// silently dropped within the 15-min dedup window. Reactions are soft
|
|
766
|
+
// notifications, so a rare duplicate on SDK reconnect is acceptable.
|
|
767
|
+
const syntheticId = `reaction_${event.messageId}_${event.emoji}_${event.agentName}_${action}_${Date.now()}`;
|
|
768
|
+
const text = action === 'added'
|
|
769
|
+
? `[relaycast:reaction] @${event.agentName} reacted ${event.emoji} to message ${event.messageId} (soft notification, no action required)`
|
|
770
|
+
: `[relaycast:reaction] @${event.agentName} removed ${event.emoji} from message ${event.messageId} (soft notification, no action required)`;
|
|
771
|
+
|
|
772
|
+
const inbound: InboundMessage = {
|
|
773
|
+
id: syntheticId,
|
|
774
|
+
channel: 'reaction',
|
|
775
|
+
from: event.agentName,
|
|
776
|
+
text,
|
|
777
|
+
timestamp: new Date().toISOString(),
|
|
778
|
+
kind: 'reaction',
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
await this.handleInbound(inbound);
|
|
718
782
|
}
|
|
719
783
|
|
|
720
784
|
private async handleInbound(message: InboundMessage): Promise<void> {
|
|
@@ -724,13 +788,13 @@ export class InboundGateway {
|
|
|
724
788
|
// Avoid echo loops — skip messages from this claw or its viewer identity.
|
|
725
789
|
const viewerName = `viewer-${this.config.clawName}`;
|
|
726
790
|
if (message.from === this.config.clawName || message.from === viewerName) {
|
|
727
|
-
|
|
791
|
+
// Only update cursor for real channels with real (non-synthetic) message IDs.
|
|
728
792
|
this.markSeen(message.id);
|
|
729
793
|
return;
|
|
730
794
|
}
|
|
731
795
|
|
|
732
796
|
// Mark as seen immediately to prevent duplicate delivery from concurrent
|
|
733
|
-
// realtime
|
|
797
|
+
// realtime events processing the same message.
|
|
734
798
|
this.markSeen(message.id);
|
|
735
799
|
this.processingMessageIds.add(message.id);
|
|
736
800
|
|
|
@@ -738,7 +802,6 @@ export class InboundGateway {
|
|
|
738
802
|
try {
|
|
739
803
|
const result = await this.onMessage(message);
|
|
740
804
|
console.log(`[gateway] Delivery result: ${result.method} ok=${result.ok}${result.error ? ' error=' + result.error : ''}`);
|
|
741
|
-
this.channelCursor.set(normalizeChannelName(message.channel), message.id);
|
|
742
805
|
} finally {
|
|
743
806
|
this.processingMessageIds.delete(message.id);
|
|
744
807
|
}
|
|
@@ -746,6 +809,16 @@ export class InboundGateway {
|
|
|
746
809
|
|
|
747
810
|
/** Format delivery text with channel, sender, and optional thread prefix. */
|
|
748
811
|
private formatDeliveryText(message: InboundMessage): string {
|
|
812
|
+
// Pre-formatted kinds (command, reaction) already have the full text.
|
|
813
|
+
if (message.kind === 'command' || message.kind === 'reaction') {
|
|
814
|
+
return message.text;
|
|
815
|
+
}
|
|
816
|
+
if (message.kind === 'dm') {
|
|
817
|
+
return `[relaycast:dm] @${message.from}: ${message.text}`;
|
|
818
|
+
}
|
|
819
|
+
if (message.kind === 'groupdm') {
|
|
820
|
+
return `[relaycast:groupdm] @${message.from}: ${message.text}`;
|
|
821
|
+
}
|
|
749
822
|
const threadPrefix = message.threadParentId ? '[thread] ' : '';
|
|
750
823
|
return `${threadPrefix}[relaycast:${message.channel}] @${message.from}: ${message.text}`;
|
|
751
824
|
}
|
|
@@ -16,7 +16,7 @@ export interface GatewayConfig {
|
|
|
16
16
|
export interface InboundMessage {
|
|
17
17
|
/** Relaycast message ID. */
|
|
18
18
|
id: string;
|
|
19
|
-
/** Channel the message was posted to. */
|
|
19
|
+
/** Channel the message was posted to. Synthetic for DMs (e.g. "dm", "groupdm:{id}"). */
|
|
20
20
|
channel: string;
|
|
21
21
|
/** Agent name of the sender. */
|
|
22
22
|
from: string;
|
|
@@ -26,6 +26,10 @@ export interface InboundMessage {
|
|
|
26
26
|
timestamp: string;
|
|
27
27
|
/** Parent message ID when this is a thread reply. */
|
|
28
28
|
threadParentId?: string;
|
|
29
|
+
/** Conversation ID for DMs / group DMs. */
|
|
30
|
+
conversationId?: string;
|
|
31
|
+
/** Message kind hint for formatting. */
|
|
32
|
+
kind?: 'channel' | 'thread' | 'dm' | 'groupdm' | 'command' | 'reaction';
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export interface DeliveryResult {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/policy",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Agent policy management with multi-level fallback (repo, local PRPM, cloud workspace)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test:watch": "vitest"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agent-relay/config": "3.1.
|
|
25
|
+
"@agent-relay/config": "3.1.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.19.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/sdk",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"typescript": "^5.7.3"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@agent-relay/config": "3.1.
|
|
84
|
+
"@agent-relay/config": "3.1.2",
|
|
85
85
|
"@relaycast/sdk": "^0.4.0",
|
|
86
86
|
"yaml": "^2.7.0"
|
|
87
87
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/trajectory",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Trajectory integration utilities (trail/PDERO) for Relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test:watch": "vitest"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agent-relay/config": "3.1.
|
|
25
|
+
"@agent-relay/config": "3.1.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.19.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/user-directory",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "User directory service for agent-relay (per-user credential storage)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"test:watch": "vitest"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agent-relay/utils": "3.1.
|
|
25
|
+
"@agent-relay/utils": "3.1.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.19.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/utils",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Shared utilities for agent-relay: logging, name generation, command resolution, update checking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"vitest": "^3.2.4"
|
|
113
113
|
},
|
|
114
114
|
"dependencies": {
|
|
115
|
-
"@agent-relay/config": "3.1.
|
|
115
|
+
"@agent-relay/config": "3.1.2",
|
|
116
116
|
"compare-versions": "^6.1.1"
|
|
117
117
|
},
|
|
118
118
|
"publishConfig": {
|