agent-relay 2.0.19 → 2.0.21
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 +217 -24
- package/bin/relay-pty-darwin-arm64 +0 -0
- package/bin/relay-pty-darwin-x64 +0 -0
- package/bin/relay-pty-linux-x64 +0 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/app/onboarding.html +1 -1
- package/dist/dashboard/out/app/onboarding.txt +1 -1
- package/dist/dashboard/out/app.html +1 -1
- package/dist/dashboard/out/app.txt +1 -1
- package/dist/dashboard/out/cloud/link.html +1 -1
- package/dist/dashboard/out/cloud/link.txt +1 -1
- package/dist/dashboard/out/complete-profile.html +1 -1
- package/dist/dashboard/out/complete-profile.txt +1 -1
- package/dist/dashboard/out/connect-repos.html +1 -1
- package/dist/dashboard/out/connect-repos.txt +1 -1
- package/dist/dashboard/out/history.html +1 -1
- package/dist/dashboard/out/history.txt +1 -1
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +1 -1
- package/dist/dashboard/out/login.html +1 -1
- package/dist/dashboard/out/login.txt +1 -1
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +1 -1
- package/dist/dashboard/out/pricing.html +1 -1
- package/dist/dashboard/out/pricing.txt +1 -1
- package/dist/dashboard/out/providers/setup/claude.html +1 -1
- package/dist/dashboard/out/providers/setup/claude.txt +1 -1
- package/dist/dashboard/out/providers/setup/codex.html +1 -1
- package/dist/dashboard/out/providers/setup/codex.txt +1 -1
- package/dist/dashboard/out/providers/setup/cursor.html +1 -1
- package/dist/dashboard/out/providers/setup/cursor.txt +1 -1
- package/dist/dashboard/out/providers.html +1 -1
- package/dist/dashboard/out/providers.txt +1 -1
- package/dist/dashboard/out/signup.html +1 -1
- package/dist/dashboard/out/signup.txt +1 -1
- package/package.json +23 -17
- package/packages/api-types/package.json +2 -2
- package/packages/bridge/dist/spawner.d.ts +2 -0
- package/packages/bridge/dist/spawner.js +76 -24
- package/packages/bridge/package.json +8 -8
- package/packages/cli-tester/README.md +277 -0
- package/packages/cli-tester/dist/index.d.ts +21 -0
- package/packages/cli-tester/dist/index.js +21 -0
- package/packages/cli-tester/dist/utils/credential-check.d.ts +56 -0
- package/packages/cli-tester/dist/utils/credential-check.js +230 -0
- package/packages/cli-tester/dist/utils/socket-client.d.ts +76 -0
- package/packages/cli-tester/dist/utils/socket-client.js +153 -0
- package/packages/cli-tester/docker/entrypoint.sh +58 -0
- package/packages/cli-tester/package.json +32 -0
- package/packages/cli-tester/scripts/clear-auth.sh +101 -0
- package/packages/cli-tester/scripts/inject-message.sh +42 -0
- package/packages/cli-tester/scripts/start.sh +71 -0
- package/packages/cli-tester/scripts/test-cli.sh +56 -0
- package/packages/cli-tester/scripts/test-full-spawn.sh +238 -0
- package/packages/cli-tester/scripts/test-registration.sh +182 -0
- package/packages/cli-tester/scripts/test-setup-flow.sh +202 -0
- package/packages/cli-tester/scripts/test-spawn.sh +140 -0
- package/packages/cli-tester/scripts/test-with-daemon.sh +247 -0
- package/packages/cli-tester/scripts/verify-auth.sh +112 -0
- package/packages/cloud/package.json +6 -6
- package/packages/config/dist/cli-auth-config.js +65 -0
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/dist/router.js +4 -4
- package/packages/daemon/dist/server.js +38 -19
- package/packages/daemon/dist/spawn-manager.d.ts +4 -0
- package/packages/daemon/dist/spawn-manager.js +2 -0
- package/packages/daemon/package.json +12 -12
- package/packages/dashboard/dist/server.js +4 -0
- package/packages/dashboard/package.json +14 -14
- package/packages/dashboard/ui-dist/404.html +1 -1
- package/packages/dashboard/ui-dist/app/onboarding.html +1 -1
- package/packages/dashboard/ui-dist/app/onboarding.txt +1 -1
- package/packages/dashboard/ui-dist/app.html +1 -1
- package/packages/dashboard/ui-dist/app.txt +1 -1
- package/packages/dashboard/ui-dist/cloud/link.html +1 -1
- package/packages/dashboard/ui-dist/cloud/link.txt +1 -1
- package/packages/dashboard/ui-dist/complete-profile.html +1 -1
- package/packages/dashboard/ui-dist/complete-profile.txt +1 -1
- package/packages/dashboard/ui-dist/connect-repos.html +1 -1
- package/packages/dashboard/ui-dist/connect-repos.txt +1 -1
- package/packages/dashboard/ui-dist/history.html +1 -1
- package/packages/dashboard/ui-dist/history.txt +1 -1
- package/packages/dashboard/ui-dist/index.html +1 -1
- package/packages/dashboard/ui-dist/index.txt +1 -1
- package/packages/dashboard/ui-dist/login.html +1 -1
- package/packages/dashboard/ui-dist/login.txt +1 -1
- package/packages/dashboard/ui-dist/metrics.html +1 -1
- package/packages/dashboard/ui-dist/metrics.txt +1 -1
- package/packages/dashboard/ui-dist/pricing.html +1 -1
- package/packages/dashboard/ui-dist/pricing.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.txt +1 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.html +1 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.txt +1 -1
- package/packages/dashboard/ui-dist/providers.html +1 -1
- package/packages/dashboard/ui-dist/providers.txt +1 -1
- package/packages/dashboard/ui-dist/signup.html +1 -1
- package/packages/dashboard/ui-dist/signup.txt +1 -1
- package/packages/dashboard-server/dist/server.js +4 -0
- package/packages/dashboard-server/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/README.md +512 -58
- package/packages/sdk/dist/client.d.ts +135 -1
- package/packages/sdk/dist/client.js +338 -0
- package/packages/sdk/dist/index.d.ts +2 -1
- package/packages/sdk/dist/index.js +2 -0
- package/packages/sdk/dist/logs.d.ts +61 -0
- package/packages/sdk/dist/logs.js +95 -0
- package/packages/sdk/dist/protocol/index.d.ts +1 -1
- package/packages/sdk/dist/protocol/types.d.ts +186 -1
- package/packages/sdk/package.json +3 -3
- package/packages/spawner/package.json +2 -2
- package/packages/state/package.json +1 -1
- package/packages/storage/dist/sqlite-adapter.js +2 -0
- package/packages/storage/package.json +2 -2
- 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 +1 -1
- package/packages/wrapper/dist/base-wrapper.js +27 -10
- package/packages/wrapper/dist/relay-pty-orchestrator.js +16 -16
- package/packages/wrapper/dist/tmux-wrapper.js +16 -0
- package/packages/wrapper/package.json +7 -7
- package/scripts/hooks/install.sh +16 -0
- package/scripts/hooks/pre-commit +60 -0
- package/specs/PRIMITIVES_ROADMAP.md +2154 -0
- /package/dist/dashboard/out/_next/static/{cREcLZyPb-5NyVZje0Qfe → 7MZPqYkVGw3EGzVBkVmY9}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{cREcLZyPb-5NyVZje0Qfe → 7MZPqYkVGw3EGzVBkVmY9}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{N3ajGnJqRESKyCjDvyU52 → 7MZPqYkVGw3EGzVBkVmY9}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{N3ajGnJqRESKyCjDvyU52 → 7MZPqYkVGw3EGzVBkVmY9}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{UQiyWwBxIP-9it3GYVBDL → iJ3Uiz3IrqUJL7IxKZHiV}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{UQiyWwBxIP-9it3GYVBDL → iJ3Uiz3IrqUJL7IxKZHiV}/_ssgManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{cREcLZyPb-5NyVZje0Qfe → l-jd878zUJ_IlraqEWMZc}/_buildManifest.js +0 -0
- /package/packages/dashboard/ui-dist/_next/static/{cREcLZyPb-5NyVZje0Qfe → l-jd878zUJ_IlraqEWMZc}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log reading utilities for Agent Relay SDK.
|
|
3
|
+
*
|
|
4
|
+
* These utilities read agent logs from the local filesystem.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
/**
|
|
9
|
+
* Get the default logs directory path.
|
|
10
|
+
*/
|
|
11
|
+
function getDefaultLogsDir() {
|
|
12
|
+
return join(process.cwd(), '.agent-relay', 'worker-logs');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read the last N lines from a file.
|
|
16
|
+
*/
|
|
17
|
+
async function tailFile(filePath, lines) {
|
|
18
|
+
try {
|
|
19
|
+
const content = await readFile(filePath, 'utf-8');
|
|
20
|
+
const allLines = content.split('\n');
|
|
21
|
+
const tailLines = allLines.slice(-lines);
|
|
22
|
+
return tailLines.join('\n').trim();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get logs for a specific agent.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { getLogs } from '@agent-relay/sdk';
|
|
34
|
+
*
|
|
35
|
+
* const result = await getLogs('Worker1', { lines: 100 });
|
|
36
|
+
* if (result.found) {
|
|
37
|
+
* console.log(result.content);
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param agent - Agent name
|
|
42
|
+
* @param options - Options for reading logs
|
|
43
|
+
* @returns Log content and metadata
|
|
44
|
+
*/
|
|
45
|
+
export async function getLogs(agent, options = {}) {
|
|
46
|
+
const logsDir = options.logsDir ?? getDefaultLogsDir();
|
|
47
|
+
const lines = options.lines ?? 50;
|
|
48
|
+
const logFile = join(logsDir, `${agent}.log`);
|
|
49
|
+
try {
|
|
50
|
+
await stat(logFile);
|
|
51
|
+
const content = await tailFile(logFile, lines);
|
|
52
|
+
const lineCount = content ? content.split('\n').length : 0;
|
|
53
|
+
return {
|
|
54
|
+
agent,
|
|
55
|
+
content,
|
|
56
|
+
found: true,
|
|
57
|
+
lineCount,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return {
|
|
62
|
+
agent,
|
|
63
|
+
content: '',
|
|
64
|
+
found: false,
|
|
65
|
+
lineCount: 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* List all agents that have log files.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { listLoggedAgents } from '@agent-relay/sdk';
|
|
75
|
+
*
|
|
76
|
+
* const agents = await listLoggedAgents();
|
|
77
|
+
* console.log('Agents with logs:', agents);
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @param logsDir - Directory containing worker logs
|
|
81
|
+
* @returns Array of agent names
|
|
82
|
+
*/
|
|
83
|
+
export async function listLoggedAgents(logsDir) {
|
|
84
|
+
const dir = logsDir ?? getDefaultLogsDir();
|
|
85
|
+
try {
|
|
86
|
+
const files = await readdir(dir);
|
|
87
|
+
return files
|
|
88
|
+
.filter((f) => f.endsWith('.log'))
|
|
89
|
+
.map((f) => f.replace('.log', ''));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Protocol exports for @agent-relay/sdk
|
|
3
3
|
*/
|
|
4
|
-
export { PROTOCOL_VERSION, type MessageType, type PayloadKind, type Envelope, type EntityType, type HelloPayload, type WelcomePayload, type SendPayload, type SendMeta, type SyncMeta, type DeliveryInfo, type AckPayload, type NackPayload, type BusyPayload, type PingPayload, type PongPayload, type ErrorCode, type ErrorPayload, type LogPayload, type SyncStream, type SyncPayload, type SpeakOnTrigger, type ShadowConfig, type ShadowBindPayload, type ShadowUnbindPayload, type SpawnPayload, type SpawnPolicyDecision, type SpawnResultPayload, type ReleasePayload, type ReleaseResultPayload, type MessageAttachment, type ChannelJoinPayload, type ChannelLeavePayload, type ChannelMessagePayload, type HelloEnvelope, type WelcomeEnvelope, type SendEnvelope, type DeliverEnvelope, type AckEnvelope, type NackEnvelope, type PingEnvelope, type PongEnvelope, type ErrorEnvelope, type BusyEnvelope, type LogEnvelope, type SyncEnvelope, type ShadowBindEnvelope, type ShadowUnbindEnvelope, type SpawnEnvelope, type SpawnResultEnvelope, type ReleaseEnvelope, type ReleaseResultEnvelope, type ChannelJoinEnvelope, type ChannelLeaveEnvelope, type ChannelMessageEnvelope, } from './types.js';
|
|
4
|
+
export { PROTOCOL_VERSION, type MessageType, type PayloadKind, type Envelope, type EntityType, type HelloPayload, type WelcomePayload, type SendPayload, type SendMeta, type SyncMeta, type DeliveryInfo, type AckPayload, type NackPayload, type BusyPayload, type PingPayload, type PongPayload, type ErrorCode, type ErrorPayload, type LogPayload, type SyncStream, type SyncPayload, type SpeakOnTrigger, type ShadowConfig, type ShadowBindPayload, type ShadowUnbindPayload, type SpawnPayload, type SpawnPolicyDecision, type SpawnResultPayload, type ReleasePayload, type ReleaseResultPayload, type ConsensusType, type VoteValue, type ProposalStatus, type CreateProposalOptions, type VoteOptions, type MessageAttachment, type ChannelJoinPayload, type ChannelLeavePayload, type ChannelMessagePayload, type StatusPayload, type StatusResponsePayload, type InboxPayload, type InboxMessage, type InboxResponsePayload, type ListAgentsPayload, type AgentInfo, type ListAgentsResponsePayload, type HealthPayload, type CrashRecord, type AlertRecord, type HealthResponsePayload, type MetricsPayload, type AgentMetrics, type MetricsResponsePayload, type HelloEnvelope, type WelcomeEnvelope, type SendEnvelope, type DeliverEnvelope, type AckEnvelope, type NackEnvelope, type PingEnvelope, type PongEnvelope, type ErrorEnvelope, type BusyEnvelope, type LogEnvelope, type SyncEnvelope, type ShadowBindEnvelope, type ShadowUnbindEnvelope, type SpawnEnvelope, type SpawnResultEnvelope, type ReleaseEnvelope, type ReleaseResultEnvelope, type ChannelJoinEnvelope, type ChannelLeaveEnvelope, type ChannelMessageEnvelope, type StatusEnvelope, type StatusResponseEnvelope, type InboxEnvelope, type InboxResponseEnvelope, type ListAgentsEnvelope, type ListAgentsResponseEnvelope, type HealthEnvelope, type HealthResponseEnvelope, type MetricsEnvelope, type MetricsResponseEnvelope, } from './types.js';
|
|
5
5
|
export { MAX_FRAME_BYTES, HEADER_SIZE, LEGACY_HEADER_SIZE, type WireFormat, initMessagePack, hasMessagePack, encodeFrame, encodeFrameLegacy, FrameParser, } from './framing.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* These types define the wire protocol for agent-to-agent communication.
|
|
6
6
|
*/
|
|
7
7
|
export declare const PROTOCOL_VERSION = 1;
|
|
8
|
-
export type MessageType = 'HELLO' | 'WELCOME' | 'SEND' | 'DELIVER' | 'ACK' | 'NACK' | 'PING' | 'PONG' | 'ERROR' | 'BUSY' | 'RESUME' | 'BYE' | 'STATE' | 'SYNC' | 'SYNC_SNAPSHOT' | 'SYNC_DELTA' | 'SUBSCRIBE' | 'UNSUBSCRIBE' | 'SHADOW_BIND' | 'SHADOW_UNBIND' | 'LOG' | 'CHANNEL_JOIN' | 'CHANNEL_LEAVE' | 'CHANNEL_MESSAGE' | 'CHANNEL_INFO' | 'CHANNEL_MEMBERS' | 'CHANNEL_TYPING' | 'SPAWN' | 'SPAWN_RESULT' | 'RELEASE' | 'RELEASE_RESULT';
|
|
8
|
+
export type MessageType = 'HELLO' | 'WELCOME' | 'SEND' | 'DELIVER' | 'ACK' | 'NACK' | 'PING' | 'PONG' | 'ERROR' | 'BUSY' | 'RESUME' | 'BYE' | 'STATE' | 'SYNC' | 'SYNC_SNAPSHOT' | 'SYNC_DELTA' | 'SUBSCRIBE' | 'UNSUBSCRIBE' | 'SHADOW_BIND' | 'SHADOW_UNBIND' | 'LOG' | 'CHANNEL_JOIN' | 'CHANNEL_LEAVE' | 'CHANNEL_MESSAGE' | 'CHANNEL_INFO' | 'CHANNEL_MEMBERS' | 'CHANNEL_TYPING' | 'SPAWN' | 'SPAWN_RESULT' | 'RELEASE' | 'RELEASE_RESULT' | 'STATUS' | 'STATUS_RESPONSE' | 'INBOX' | 'INBOX_RESPONSE' | 'LIST_AGENTS' | 'LIST_AGENTS_RESPONSE' | 'HEALTH' | 'HEALTH_RESPONSE' | 'METRICS' | 'METRICS_RESPONSE';
|
|
9
9
|
export type PayloadKind = 'message' | 'action' | 'state' | 'thinking';
|
|
10
10
|
/**
|
|
11
11
|
* Base envelope structure for all protocol messages.
|
|
@@ -312,6 +312,181 @@ export interface ReleaseResultPayload {
|
|
|
312
312
|
/** Error message (if failed) */
|
|
313
313
|
error?: string;
|
|
314
314
|
}
|
|
315
|
+
export type ConsensusType = 'majority' | 'supermajority' | 'unanimous' | 'weighted' | 'quorum';
|
|
316
|
+
export type VoteValue = 'approve' | 'reject' | 'abstain';
|
|
317
|
+
export type ProposalStatus = 'pending' | 'approved' | 'rejected' | 'expired' | 'cancelled';
|
|
318
|
+
/**
|
|
319
|
+
* Options for creating a consensus proposal.
|
|
320
|
+
*/
|
|
321
|
+
export interface CreateProposalOptions {
|
|
322
|
+
/** Proposal title */
|
|
323
|
+
title: string;
|
|
324
|
+
/** Detailed description */
|
|
325
|
+
description: string;
|
|
326
|
+
/** Agents allowed to vote */
|
|
327
|
+
participants: string[];
|
|
328
|
+
/** Consensus type (default: majority) */
|
|
329
|
+
consensusType?: ConsensusType;
|
|
330
|
+
/** Timeout in milliseconds (default: 5 minutes) */
|
|
331
|
+
timeoutMs?: number;
|
|
332
|
+
/** Minimum votes required (for quorum type) */
|
|
333
|
+
quorum?: number;
|
|
334
|
+
/** Threshold for supermajority (0-1, default 0.67) */
|
|
335
|
+
threshold?: number;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Options for voting on a proposal.
|
|
339
|
+
*/
|
|
340
|
+
export interface VoteOptions {
|
|
341
|
+
/** Proposal ID to vote on */
|
|
342
|
+
proposalId: string;
|
|
343
|
+
/** Vote value */
|
|
344
|
+
value: VoteValue;
|
|
345
|
+
/** Optional reason for the vote */
|
|
346
|
+
reason?: string;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Payload for STATUS request.
|
|
350
|
+
*/
|
|
351
|
+
export interface StatusPayload {
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Response payload for STATUS request.
|
|
355
|
+
*/
|
|
356
|
+
export interface StatusResponsePayload {
|
|
357
|
+
version?: string;
|
|
358
|
+
uptime?: number;
|
|
359
|
+
agentCount?: number;
|
|
360
|
+
messageCount?: number;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Payload for INBOX request.
|
|
364
|
+
*/
|
|
365
|
+
export interface InboxPayload {
|
|
366
|
+
agent: string;
|
|
367
|
+
limit?: number;
|
|
368
|
+
unreadOnly?: boolean;
|
|
369
|
+
from?: string;
|
|
370
|
+
channel?: string;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* A stored message in the inbox.
|
|
374
|
+
*/
|
|
375
|
+
export interface InboxMessage {
|
|
376
|
+
id: string;
|
|
377
|
+
from: string;
|
|
378
|
+
body: string;
|
|
379
|
+
channel?: string;
|
|
380
|
+
thread?: string;
|
|
381
|
+
timestamp: number;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Response payload for INBOX request.
|
|
385
|
+
*/
|
|
386
|
+
export interface InboxResponsePayload {
|
|
387
|
+
messages: InboxMessage[];
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Payload for LIST_AGENTS request.
|
|
391
|
+
*/
|
|
392
|
+
export interface ListAgentsPayload {
|
|
393
|
+
includeIdle?: boolean;
|
|
394
|
+
project?: string;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Agent info returned by LIST_AGENTS.
|
|
398
|
+
*/
|
|
399
|
+
export interface AgentInfo {
|
|
400
|
+
name: string;
|
|
401
|
+
cli?: string;
|
|
402
|
+
idle?: boolean;
|
|
403
|
+
parent?: string;
|
|
404
|
+
task?: string;
|
|
405
|
+
connectedAt?: number;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Response payload for LIST_AGENTS request.
|
|
409
|
+
*/
|
|
410
|
+
export interface ListAgentsResponsePayload {
|
|
411
|
+
agents: AgentInfo[];
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Payload for HEALTH request.
|
|
415
|
+
*/
|
|
416
|
+
export interface HealthPayload {
|
|
417
|
+
includeCrashes?: boolean;
|
|
418
|
+
includeAlerts?: boolean;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* A crash record.
|
|
422
|
+
*/
|
|
423
|
+
export interface CrashRecord {
|
|
424
|
+
id: string;
|
|
425
|
+
agentName: string;
|
|
426
|
+
crashedAt: string;
|
|
427
|
+
likelyCause: string;
|
|
428
|
+
summary?: string;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* An alert record.
|
|
432
|
+
*/
|
|
433
|
+
export interface AlertRecord {
|
|
434
|
+
id: string;
|
|
435
|
+
agentName: string;
|
|
436
|
+
alertType: string;
|
|
437
|
+
message: string;
|
|
438
|
+
createdAt: string;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Response payload for HEALTH request.
|
|
442
|
+
*/
|
|
443
|
+
export interface HealthResponsePayload {
|
|
444
|
+
healthScore: number;
|
|
445
|
+
summary: string;
|
|
446
|
+
issues: Array<{
|
|
447
|
+
severity: string;
|
|
448
|
+
message: string;
|
|
449
|
+
}>;
|
|
450
|
+
recommendations: string[];
|
|
451
|
+
crashes: CrashRecord[];
|
|
452
|
+
alerts: AlertRecord[];
|
|
453
|
+
stats: {
|
|
454
|
+
totalCrashes24h: number;
|
|
455
|
+
totalAlerts24h: number;
|
|
456
|
+
agentCount: number;
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Payload for METRICS request.
|
|
461
|
+
*/
|
|
462
|
+
export interface MetricsPayload {
|
|
463
|
+
agent?: string;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Metrics for a single agent.
|
|
467
|
+
*/
|
|
468
|
+
export interface AgentMetrics {
|
|
469
|
+
name: string;
|
|
470
|
+
pid?: number;
|
|
471
|
+
status: string;
|
|
472
|
+
rssBytes?: number;
|
|
473
|
+
cpuPercent?: number;
|
|
474
|
+
trend?: string;
|
|
475
|
+
alertLevel?: string;
|
|
476
|
+
highWatermark?: number;
|
|
477
|
+
uptimeMs?: number;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Response payload for METRICS request.
|
|
481
|
+
*/
|
|
482
|
+
export interface MetricsResponsePayload {
|
|
483
|
+
agents: AgentMetrics[];
|
|
484
|
+
system: {
|
|
485
|
+
totalMemory: number;
|
|
486
|
+
freeMemory: number;
|
|
487
|
+
heapUsed: number;
|
|
488
|
+
};
|
|
489
|
+
}
|
|
315
490
|
export type HelloEnvelope = Envelope<HelloPayload>;
|
|
316
491
|
export type WelcomeEnvelope = Envelope<WelcomePayload>;
|
|
317
492
|
export type SendEnvelope = Envelope<SendPayload> & {
|
|
@@ -338,4 +513,14 @@ export type ReleaseResultEnvelope = Envelope<ReleaseResultPayload>;
|
|
|
338
513
|
export type ChannelJoinEnvelope = Envelope<ChannelJoinPayload>;
|
|
339
514
|
export type ChannelLeaveEnvelope = Envelope<ChannelLeavePayload>;
|
|
340
515
|
export type ChannelMessageEnvelope = Envelope<ChannelMessagePayload>;
|
|
516
|
+
export type StatusEnvelope = Envelope<StatusPayload>;
|
|
517
|
+
export type StatusResponseEnvelope = Envelope<StatusResponsePayload>;
|
|
518
|
+
export type InboxEnvelope = Envelope<InboxPayload>;
|
|
519
|
+
export type InboxResponseEnvelope = Envelope<InboxResponsePayload>;
|
|
520
|
+
export type ListAgentsEnvelope = Envelope<ListAgentsPayload>;
|
|
521
|
+
export type ListAgentsResponseEnvelope = Envelope<ListAgentsResponsePayload>;
|
|
522
|
+
export type HealthEnvelope = Envelope<HealthPayload>;
|
|
523
|
+
export type HealthResponseEnvelope = Envelope<HealthResponsePayload>;
|
|
524
|
+
export type MetricsEnvelope = Envelope<MetricsPayload>;
|
|
525
|
+
export type MetricsResponseEnvelope = Envelope<MetricsResponsePayload>;
|
|
341
526
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
4
4
|
"description": "Lightweight SDK for agent-to-agent communication via Agent Relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"sdk"
|
|
46
46
|
],
|
|
47
47
|
"author": "Khaliq Gant",
|
|
48
|
-
"license": "
|
|
48
|
+
"license": "Apache-2.0",
|
|
49
49
|
"repository": {
|
|
50
50
|
"type": "git",
|
|
51
51
|
"url": "git+https://github.com/AgentWorkforce/relay.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@agent-relay/protocol": "2.0.
|
|
58
|
+
"@agent-relay/protocol": "2.0.21"
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": ">=18.0.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/spawner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
4
4
|
"description": "Agent spawning types and utilities for Agent Relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"url": "git+https://github.com/AgentWorkforce/relay.git",
|
|
44
44
|
"directory": "packages/spawner"
|
|
45
45
|
},
|
|
46
|
-
"license": "
|
|
46
|
+
"license": "Apache-2.0"
|
|
47
47
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/storage",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
4
4
|
"description": "Storage adapters and interfaces for Relay message/session persistence",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@agent-relay/protocol": "2.0.
|
|
59
|
+
"@agent-relay/protocol": "2.0.21"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^22.19.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/trajectory",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
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": "2.0.
|
|
25
|
+
"@agent-relay/config": "2.0.21"
|
|
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": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
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/resiliency": "2.0.
|
|
25
|
+
"@agent-relay/resiliency": "2.0.21"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.19.3",
|
|
@@ -317,14 +317,7 @@ export class BaseWrapper extends EventEmitter {
|
|
|
317
317
|
console.error(`[base-wrapper] Skipped duplicate message to ${cmd.to}`);
|
|
318
318
|
return;
|
|
319
319
|
}
|
|
320
|
-
|
|
321
|
-
// Limit hash set size
|
|
322
|
-
if (this.sentMessageHashes.size > 500) {
|
|
323
|
-
const oldest = this.sentMessageHashes.values().next().value;
|
|
324
|
-
if (oldest)
|
|
325
|
-
this.sentMessageHashes.delete(oldest);
|
|
326
|
-
}
|
|
327
|
-
// Only send if client ready
|
|
320
|
+
// Only send if client ready - check BEFORE adding hash to avoid blocking retries
|
|
328
321
|
if (this.client.state !== 'READY') {
|
|
329
322
|
console.error(`[base-wrapper] Client not ready (state=${this.client.state}), dropping message to ${cmd.to}`);
|
|
330
323
|
return;
|
|
@@ -338,14 +331,30 @@ export class BaseWrapper extends EventEmitter {
|
|
|
338
331
|
requires_ack: cmd.meta.ackRequired,
|
|
339
332
|
};
|
|
340
333
|
}
|
|
334
|
+
// Helper to mark message as sent (only after successful transmission)
|
|
335
|
+
const markSent = () => {
|
|
336
|
+
this.sentMessageHashes.add(hash);
|
|
337
|
+
// Limit hash set size
|
|
338
|
+
if (this.sentMessageHashes.size > 500) {
|
|
339
|
+
const oldest = this.sentMessageHashes.values().next().value;
|
|
340
|
+
if (oldest)
|
|
341
|
+
this.sentMessageHashes.delete(oldest);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
341
344
|
// Check if target is a channel (starts with #)
|
|
342
345
|
if (cmd.to.startsWith('#')) {
|
|
343
346
|
// Use CHANNEL_MESSAGE protocol for channel targets
|
|
344
347
|
console.error(`[base-wrapper] Sending CHANNEL_MESSAGE to ${cmd.to}`);
|
|
345
|
-
this.client.sendChannelMessage(cmd.to, cmd.body, {
|
|
348
|
+
const success = this.client.sendChannelMessage(cmd.to, cmd.body, {
|
|
346
349
|
thread: cmd.thread,
|
|
347
350
|
data: cmd.data,
|
|
348
351
|
});
|
|
352
|
+
if (success) {
|
|
353
|
+
markSent();
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
console.error(`[base-wrapper] sendChannelMessage failed for ${cmd.to}`);
|
|
357
|
+
}
|
|
349
358
|
}
|
|
350
359
|
else {
|
|
351
360
|
// Use SEND protocol for direct messages and broadcasts
|
|
@@ -355,12 +364,20 @@ export class BaseWrapper extends EventEmitter {
|
|
|
355
364
|
kind: cmd.kind,
|
|
356
365
|
data: cmd.data,
|
|
357
366
|
thread: cmd.thread,
|
|
367
|
+
}).then(() => {
|
|
368
|
+
markSent();
|
|
358
369
|
}).catch((err) => {
|
|
359
370
|
console.error(`[base-wrapper] sendAndWait failed for ${cmd.to}: ${err.message}`);
|
|
360
371
|
});
|
|
361
372
|
}
|
|
362
373
|
else {
|
|
363
|
-
this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread, sendMeta);
|
|
374
|
+
const success = this.client.sendMessage(cmd.to, cmd.body, cmd.kind, cmd.data, cmd.thread, sendMeta);
|
|
375
|
+
if (success) {
|
|
376
|
+
markSent();
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
console.error(`[base-wrapper] sendMessage failed for ${cmd.to}`);
|
|
380
|
+
}
|
|
364
381
|
}
|
|
365
382
|
}
|
|
366
383
|
}
|
|
@@ -19,6 +19,7 @@ import { spawn } from 'node:child_process';
|
|
|
19
19
|
import { createConnection } from 'node:net';
|
|
20
20
|
import { createHash } from 'node:crypto';
|
|
21
21
|
import { join, dirname } from 'node:path';
|
|
22
|
+
import { homedir } from 'node:os';
|
|
22
23
|
import { existsSync, unlinkSync, mkdirSync, symlinkSync, lstatSync, rmSync, watch, readdirSync, readlinkSync, writeFileSync, appendFileSync } from 'node:fs';
|
|
23
24
|
import { getProjectPaths } from '@agent-relay/config/project-namespace';
|
|
24
25
|
import { fileURLToPath } from 'node:url';
|
|
@@ -140,17 +141,12 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
140
141
|
this._legacyOutboxPath = `/tmp/relay-outbox/${config.name}`;
|
|
141
142
|
}
|
|
142
143
|
else {
|
|
143
|
-
// Local mode: use
|
|
144
|
+
// Local mode: use project paths directly (no symlinks needed)
|
|
144
145
|
this._outboxPath = this._canonicalOutboxPath;
|
|
145
|
-
// Socket
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
const tmpSocketPath = `/tmp/relay-local/${projectPaths.projectId}/sockets/${config.name}.sock`;
|
|
150
|
-
console.warn(`[relay-pty-orchestrator:${config.name}] Socket path too long (${localSocketPath.length} chars); using /tmp fallback`);
|
|
151
|
-
localSocketPath = tmpSocketPath;
|
|
152
|
-
}
|
|
153
|
-
this.socketPath = localSocketPath;
|
|
146
|
+
// Socket path: use ~/.agent-relay/sockets/{projectId}/{agentName}.sock
|
|
147
|
+
// This keeps paths short (uses 12-char hashed projectId) while staying organized
|
|
148
|
+
// Example: /Users/foo/.agent-relay/sockets/abc123def456/MyAgent.sock (~65 chars)
|
|
149
|
+
this.socketPath = join(homedir(), '.agent-relay', 'sockets', projectPaths.projectId, `${config.name}.sock`);
|
|
154
150
|
// Legacy path for backwards compat (older agents might still use /tmp/relay-outbox)
|
|
155
151
|
// Even in local mode, we need this symlink for agents with stale instructions
|
|
156
152
|
this._legacyOutboxPath = `/tmp/relay-outbox/${config.name}`;
|
|
@@ -385,7 +381,13 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
385
381
|
throw new Error('relay-pty binary not found. Build with: cd relay-pty && cargo build --release');
|
|
386
382
|
}
|
|
387
383
|
this.log(` Using binary: ${binaryPath}`);
|
|
388
|
-
//
|
|
384
|
+
// Spawn relay-pty process FIRST (before connecting to daemon)
|
|
385
|
+
// This ensures the CLI is actually running before we register with the daemon
|
|
386
|
+
await this.spawnRelayPty(binaryPath);
|
|
387
|
+
// Wait for socket to become available and connect
|
|
388
|
+
await this.connectToSocket();
|
|
389
|
+
// Connect to relay daemon AFTER CLI is spawned
|
|
390
|
+
// This prevents the spawner from seeing us as "registered" before the CLI runs
|
|
389
391
|
try {
|
|
390
392
|
await this.client.connect();
|
|
391
393
|
this.log(` Relay daemon connected`);
|
|
@@ -393,10 +395,6 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
393
395
|
catch (err) {
|
|
394
396
|
this.logError(` Relay connect failed: ${err.message}`);
|
|
395
397
|
}
|
|
396
|
-
// Spawn relay-pty process
|
|
397
|
-
await this.spawnRelayPty(binaryPath);
|
|
398
|
-
// Wait for socket to become available and connect
|
|
399
|
-
await this.connectToSocket();
|
|
400
398
|
this.running = true;
|
|
401
399
|
// DON'T set readyForMessages yet - wait for CLI to be ready first
|
|
402
400
|
// This prevents messages from being injected during CLI startup
|
|
@@ -649,7 +647,9 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
649
647
|
// Wait for process to start
|
|
650
648
|
await sleep(500);
|
|
651
649
|
if (proc.exitCode !== null) {
|
|
652
|
-
|
|
650
|
+
// Include any captured stderr in the error for debugging
|
|
651
|
+
const stderrInfo = stderrBuffer ? `\nStderr: ${stderrBuffer.slice(0, 500)}` : '';
|
|
652
|
+
throw new Error(`relay-pty exited immediately with code ${proc.exitCode}${stderrInfo}`);
|
|
653
653
|
}
|
|
654
654
|
// Register for memory/CPU monitoring
|
|
655
655
|
if (proc.pid) {
|
|
@@ -805,6 +805,22 @@ export class TmuxWrapper extends BaseWrapper {
|
|
|
805
805
|
requires_ack: cmd.meta.ackRequired,
|
|
806
806
|
};
|
|
807
807
|
}
|
|
808
|
+
// Check if target is a channel (starts with #)
|
|
809
|
+
if (cmd.to.startsWith('#')) {
|
|
810
|
+
// Use CHANNEL_MESSAGE protocol for channel targets
|
|
811
|
+
this.logStderr(`→ [channel] ${cmd.to}: ${cmd.body.substring(0, Math.min(RELAY_LOG_TRUNCATE_LENGTH, cmd.body.length))}...`);
|
|
812
|
+
const success = this.client.sendChannelMessage(cmd.to, cmd.body, {
|
|
813
|
+
thread: cmd.thread,
|
|
814
|
+
data: cmd.data,
|
|
815
|
+
});
|
|
816
|
+
if (success) {
|
|
817
|
+
this.sentMessageHashes.add(msgHash);
|
|
818
|
+
this.queuedMessageHashes.delete(msgHash);
|
|
819
|
+
this.trajectory?.message('sent', this.config.name, cmd.to, cmd.body);
|
|
820
|
+
}
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
// Use SEND protocol for direct messages and broadcasts
|
|
808
824
|
if (cmd.sync?.blocking) {
|
|
809
825
|
this.client.sendAndWait(cmd.to, cmd.body, {
|
|
810
826
|
timeoutMs: cmd.sync.timeoutMs,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/wrapper",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.21",
|
|
4
4
|
"description": "CLI agent wrappers for Agent Relay - tmux, pty integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"clean": "rm -rf dist"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@agent-relay/api-types": "2.0.
|
|
34
|
-
"@agent-relay/protocol": "2.0.
|
|
35
|
-
"@agent-relay/config": "2.0.
|
|
36
|
-
"@agent-relay/continuity": "2.0.
|
|
37
|
-
"@agent-relay/resiliency": "2.0.
|
|
33
|
+
"@agent-relay/api-types": "2.0.21",
|
|
34
|
+
"@agent-relay/protocol": "2.0.21",
|
|
35
|
+
"@agent-relay/config": "2.0.21",
|
|
36
|
+
"@agent-relay/continuity": "2.0.21",
|
|
37
|
+
"@agent-relay/resiliency": "2.0.21"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"typescript": "^5.9.3",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"url": "git+https://github.com/AgentWorkforce/relay.git",
|
|
60
60
|
"directory": "packages/wrapper"
|
|
61
61
|
},
|
|
62
|
-
"license": "
|
|
62
|
+
"license": "Apache-2.0"
|
|
63
63
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Install git hooks for agent-relay
|
|
3
|
+
# Usage: ./scripts/hooks/install.sh
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
7
|
+
HOOKS_DIR="$REPO_ROOT/.git/hooks"
|
|
8
|
+
|
|
9
|
+
echo "Installing git hooks..."
|
|
10
|
+
|
|
11
|
+
# Install pre-commit hook
|
|
12
|
+
cp "$SCRIPT_DIR/pre-commit" "$HOOKS_DIR/pre-commit"
|
|
13
|
+
chmod +x "$HOOKS_DIR/pre-commit"
|
|
14
|
+
echo " Installed pre-commit hook"
|
|
15
|
+
|
|
16
|
+
echo "Done! Git hooks installed."
|