agent-relay 1.3.1 → 1.3.3
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/.trajectories/active/traj_3yx9dy148mge.json +42 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.json +49 -0
- package/.trajectories/completed/2026-01/traj_1g7yx6qtg4ai.md +31 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.json +49 -0
- package/.trajectories/completed/2026-01/traj_4qwd4zmhfwp4.md +31 -0
- package/.trajectories/completed/2026-01/traj_6unwwmgyj5sq.json +109 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.json +49 -0
- package/.trajectories/completed/2026-01/traj_a0tqx8biw9c4.md +31 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.json +66 -0
- package/.trajectories/completed/2026-01/traj_ax8uungxz2qh.md +36 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.json +49 -0
- package/.trajectories/completed/2026-01/traj_c9izbh2snpzf.md +31 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.json +65 -0
- package/.trajectories/completed/2026-01/traj_cpn70dw066nt.md +37 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.json +36 -0
- package/.trajectories/completed/2026-01/traj_erglv2f8t9eh.md +21 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.json +101 -0
- package/.trajectories/completed/2026-01/traj_he75f24d1xfm.md +52 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.json +61 -0
- package/.trajectories/completed/2026-01/traj_lgtodco7dp1n.md +36 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.json +73 -0
- package/.trajectories/completed/2026-01/traj_oszg9flv74pk.md +41 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.json +77 -0
- package/.trajectories/completed/2026-01/traj_pulomd3y8cvj.md +42 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.json +109 -0
- package/.trajectories/completed/2026-01/traj_rsavt0jipi3c.md +56 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.json +113 -0
- package/.trajectories/completed/2026-01/traj_x721m1j9rzup.md +57 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.json +61 -0
- package/.trajectories/completed/2026-01/traj_xjqvmep5ed3h.md +36 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.json +49 -0
- package/.trajectories/completed/2026-01/traj_y7n6hfbf7dmg.md +31 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.json +49 -0
- package/.trajectories/completed/2026-01/traj_yvfkwnkdiso2.md +31 -0
- package/.trajectories/index.json +140 -1
- package/README.md +23 -9
- package/TRAIL_GIT_AUTH_FIX.md +113 -0
- package/deploy/workspace/codex.config.toml +1 -1
- package/deploy/workspace/entrypoint.sh +20 -79
- package/deploy/workspace/gh-relay +156 -0
- package/deploy/workspace/git-credential-relay +5 -1
- package/dist/bridge/multi-project-client.js +13 -10
- package/dist/bridge/spawner.d.ts +2 -0
- package/dist/bridge/spawner.js +58 -76
- package/dist/bridge/types.d.ts +2 -0
- package/dist/cli/index.d.ts +8 -6
- package/dist/cli/index.js +297 -30
- package/dist/cloud/api/admin.js +16 -3
- package/dist/cloud/api/codex-auth-helper.js +28 -8
- package/dist/cloud/api/consensus.d.ts +13 -0
- package/dist/cloud/api/consensus.js +259 -0
- package/dist/cloud/api/daemons.js +205 -1
- package/dist/cloud/api/git.js +37 -7
- package/dist/cloud/api/onboarding.js +4 -1
- package/dist/cloud/api/provider-env.d.ts +5 -0
- package/dist/cloud/api/provider-env.js +27 -0
- package/dist/cloud/api/providers.js +2 -0
- package/dist/cloud/api/test-helpers.js +130 -0
- package/dist/cloud/api/workspaces.js +38 -3
- package/dist/cloud/db/bulk-ingest.d.ts +88 -0
- package/dist/cloud/db/bulk-ingest.js +268 -0
- package/dist/cloud/db/drizzle.d.ts +33 -0
- package/dist/cloud/db/drizzle.js +174 -2
- package/dist/cloud/db/index.d.ts +24 -5
- package/dist/cloud/db/index.js +19 -4
- package/dist/cloud/db/schema.d.ts +397 -3
- package/dist/cloud/db/schema.js +75 -1
- package/dist/cloud/provisioner/index.d.ts +8 -0
- package/dist/cloud/provisioner/index.js +256 -50
- package/dist/cloud/server.js +47 -3
- package/dist/cloud/services/index.d.ts +1 -0
- package/dist/cloud/services/index.js +2 -0
- package/dist/cloud/services/nango.d.ts +3 -4
- package/dist/cloud/services/nango.js +11 -33
- package/dist/cloud/services/workspace-keepalive.d.ts +76 -0
- package/dist/cloud/services/workspace-keepalive.js +234 -0
- package/dist/config/relay-config.d.ts +23 -0
- package/dist/config/relay-config.js +23 -0
- package/dist/daemon/agent-manager.d.ts +20 -1
- package/dist/daemon/agent-manager.js +51 -0
- package/dist/daemon/agent-registry.js +4 -4
- package/dist/daemon/agent-signing.d.ts +158 -0
- package/dist/daemon/agent-signing.js +523 -0
- package/dist/daemon/api.js +18 -1
- package/dist/daemon/cli-auth.d.ts +4 -1
- package/dist/daemon/cli-auth.js +55 -11
- package/dist/daemon/cloud-sync.d.ts +47 -1
- package/dist/daemon/cloud-sync.js +152 -3
- package/dist/daemon/connection.d.ts +28 -0
- package/dist/daemon/connection.js +113 -22
- package/dist/daemon/consensus-integration.d.ts +167 -0
- package/dist/daemon/consensus-integration.js +371 -0
- package/dist/daemon/consensus.d.ts +271 -0
- package/dist/daemon/consensus.js +632 -0
- package/dist/daemon/delivery-tracker.d.ts +34 -0
- package/dist/daemon/delivery-tracker.js +104 -0
- package/dist/daemon/enhanced-features.d.ts +118 -0
- package/dist/daemon/enhanced-features.js +178 -0
- package/dist/daemon/index.d.ts +4 -0
- package/dist/daemon/index.js +5 -0
- package/dist/daemon/rate-limiter.d.ts +68 -0
- package/dist/daemon/rate-limiter.js +130 -0
- package/dist/daemon/router.d.ts +18 -11
- package/dist/daemon/router.js +57 -113
- package/dist/daemon/server.d.ts +13 -1
- package/dist/daemon/server.js +71 -9
- package/dist/daemon/sync-queue.d.ts +116 -0
- package/dist/daemon/sync-queue.js +361 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/116-de2a4ac06e5000dc.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/919-87d604a5d76c1fbd.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/{page-c617745b81344f4f.js → page-7f64824ae7d06707.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-3f559d393902aad2.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/login/page-16d1715ddaa874ee.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/{page-dc786c183425c2ac.js → page-814efc4d77b4191d.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{main-2ee6beb2ae96d210.js → main-5a40a5ae29646e1b.js} +1 -1
- package/dist/dashboard/out/_next/static/css/44d2b52637b511bc.css +1 -0
- 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 +2 -2
- package/dist/dashboard/out/cloud/link.html +1 -0
- package/dist/dashboard/out/cloud/link.txt +7 -0
- 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 +2 -2
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/login.html +2 -3
- package/dist/dashboard/out/login.txt +2 -2
- package/dist/dashboard/out/metrics.html +1 -1
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +2 -2
- 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.html +1 -1
- package/dist/dashboard/out/providers.txt +1 -1
- package/dist/dashboard/out/signup.html +2 -2
- package/dist/dashboard/out/signup.txt +1 -1
- package/dist/dashboard-server/server.js +244 -28
- package/dist/health-worker-manager.d.ts +62 -0
- package/dist/health-worker-manager.js +144 -0
- package/dist/health-worker.d.ts +9 -0
- package/dist/health-worker.js +79 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -1
- package/dist/memory/context-compaction.d.ts +156 -0
- package/dist/memory/context-compaction.js +453 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +1 -0
- package/dist/protocol/channels.js +4 -4
- package/dist/protocol/framing.d.ts +72 -10
- package/dist/protocol/framing.js +194 -25
- package/dist/storage/adapter.d.ts +8 -1
- package/dist/storage/adapter.js +11 -0
- package/dist/storage/batched-sqlite-adapter.d.ts +71 -0
- package/dist/storage/batched-sqlite-adapter.js +183 -0
- package/dist/storage/dead-letter-queue.d.ts +196 -0
- package/dist/storage/dead-letter-queue.js +427 -0
- package/dist/storage/dlq-adapter.d.ts +195 -0
- package/dist/storage/dlq-adapter.js +664 -0
- package/dist/trajectory/config.d.ts +32 -14
- package/dist/trajectory/config.js +38 -16
- package/dist/trajectory/integration.js +217 -64
- package/dist/utils/git-remote.d.ts +47 -0
- package/dist/utils/git-remote.js +125 -0
- package/dist/utils/id-generator.d.ts +35 -0
- package/dist/utils/id-generator.js +60 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/precompiled-patterns.d.ts +110 -0
- package/dist/utils/precompiled-patterns.js +322 -0
- package/dist/wrapper/auth-detection.js +1 -1
- package/dist/wrapper/base-wrapper.d.ts +40 -0
- package/dist/wrapper/base-wrapper.js +60 -6
- package/dist/wrapper/client.d.ts +14 -4
- package/dist/wrapper/client.js +89 -31
- package/dist/wrapper/idle-detector.d.ts +102 -0
- package/dist/wrapper/idle-detector.js +279 -0
- package/dist/wrapper/parser.d.ts +4 -0
- package/dist/wrapper/parser.js +19 -1
- package/dist/wrapper/pty-wrapper.d.ts +14 -2
- package/dist/wrapper/pty-wrapper.js +132 -32
- package/dist/wrapper/shared.d.ts +1 -1
- package/dist/wrapper/shared.js +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +20 -2
- package/dist/wrapper/tmux-wrapper.js +163 -40
- package/package.json +3 -1
- package/scripts/run-migrations.js +43 -0
- package/scripts/verify-schema.js +134 -0
- package/tests/benchmarks/protocol.bench.ts +310 -0
- package/dist/dashboard/out/_next/static/chunks/116-2502180def231162.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/899-fc02ed79e3de4302.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-c22d080201cbd9fb.js +0 -1
- package/dist/dashboard/out/_next/static/css/48a8fbe3e659080e.css +0 -1
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{sDcbGRTYLcpPvyTs_rsNb → R-uQOUcOLINtsp6ACeZa9}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol Performance Benchmarks
|
|
3
|
+
*
|
|
4
|
+
* Run with: npx tsx tests/benchmarks/protocol.bench.ts
|
|
5
|
+
*
|
|
6
|
+
* Measures:
|
|
7
|
+
* - Frame encoding/decoding performance
|
|
8
|
+
* - ID generation (generateId vs uuid)
|
|
9
|
+
* - Parser throughput
|
|
10
|
+
* - Dedup cache performance
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { performance } from 'node:perf_hooks';
|
|
14
|
+
import { v4 as uuid } from 'uuid';
|
|
15
|
+
import { generateId, IdGenerator } from '../../src/utils/id-generator.js';
|
|
16
|
+
import {
|
|
17
|
+
encodeFrame,
|
|
18
|
+
encodeFrameLegacy,
|
|
19
|
+
FrameParser,
|
|
20
|
+
initMessagePack,
|
|
21
|
+
hasMessagePack,
|
|
22
|
+
} from '../../src/protocol/framing.js';
|
|
23
|
+
import type { Envelope } from '../../src/protocol/types.js';
|
|
24
|
+
import { OutputParser } from '../../src/wrapper/parser.js';
|
|
25
|
+
|
|
26
|
+
// ANSI colors for output
|
|
27
|
+
const GREEN = '\x1b[32m';
|
|
28
|
+
const YELLOW = '\x1b[33m';
|
|
29
|
+
const CYAN = '\x1b[36m';
|
|
30
|
+
const RESET = '\x1b[0m';
|
|
31
|
+
const BOLD = '\x1b[1m';
|
|
32
|
+
|
|
33
|
+
interface BenchResult {
|
|
34
|
+
name: string;
|
|
35
|
+
opsPerSec: number;
|
|
36
|
+
avgMs: number;
|
|
37
|
+
totalMs: number;
|
|
38
|
+
iterations: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Run a benchmark function and measure performance.
|
|
43
|
+
*/
|
|
44
|
+
function bench(name: string, fn: () => void, iterations = 10000): BenchResult {
|
|
45
|
+
// Warmup
|
|
46
|
+
for (let i = 0; i < Math.min(1000, iterations / 10); i++) {
|
|
47
|
+
fn();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Measure
|
|
51
|
+
const start = performance.now();
|
|
52
|
+
for (let i = 0; i < iterations; i++) {
|
|
53
|
+
fn();
|
|
54
|
+
}
|
|
55
|
+
const totalMs = performance.now() - start;
|
|
56
|
+
const avgMs = totalMs / iterations;
|
|
57
|
+
const opsPerSec = Math.round((iterations / totalMs) * 1000);
|
|
58
|
+
|
|
59
|
+
return { name, opsPerSec, avgMs, totalMs, iterations };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function printResult(result: BenchResult): void {
|
|
63
|
+
const opsStr = result.opsPerSec.toLocaleString();
|
|
64
|
+
const avgStr = result.avgMs < 0.01 ? result.avgMs.toExponential(2) : result.avgMs.toFixed(4);
|
|
65
|
+
console.log(
|
|
66
|
+
` ${CYAN}${result.name.padEnd(35)}${RESET} ` +
|
|
67
|
+
`${GREEN}${opsStr.padStart(10)} ops/s${RESET} ` +
|
|
68
|
+
`${YELLOW}${avgStr} ms/op${RESET}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function printHeader(title: string): void {
|
|
73
|
+
console.log(`\n${BOLD}${title}${RESET}`);
|
|
74
|
+
console.log('─'.repeat(65));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Test data
|
|
78
|
+
const smallEnvelope: Envelope = {
|
|
79
|
+
v: 1,
|
|
80
|
+
type: 'SEND',
|
|
81
|
+
id: 'test-id-12345678',
|
|
82
|
+
ts: Date.now(),
|
|
83
|
+
to: 'Bob',
|
|
84
|
+
payload: { kind: 'message', body: 'Hello!' },
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const mediumEnvelope: Envelope = {
|
|
88
|
+
v: 1,
|
|
89
|
+
type: 'SEND',
|
|
90
|
+
id: 'test-id-12345678',
|
|
91
|
+
ts: Date.now(),
|
|
92
|
+
to: 'Bob',
|
|
93
|
+
payload: {
|
|
94
|
+
kind: 'message',
|
|
95
|
+
body: 'This is a medium-length message that contains more content than a simple hello. It includes some additional context and information that might be typical in agent-to-agent communication.',
|
|
96
|
+
data: { priority: 'high', thread: 'auth-module', tags: ['urgent', 'review'] },
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const largeEnvelope: Envelope = {
|
|
101
|
+
v: 1,
|
|
102
|
+
type: 'SEND',
|
|
103
|
+
id: 'test-id-12345678',
|
|
104
|
+
ts: Date.now(),
|
|
105
|
+
to: 'Bob',
|
|
106
|
+
payload: { kind: 'message', body: 'x'.repeat(10000) },
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
async function main(): Promise<void> {
|
|
110
|
+
console.log(`\n${BOLD}╔════════════════════════════════════════════════════════════════╗${RESET}`);
|
|
111
|
+
console.log(`${BOLD}║ Agent Relay Protocol Benchmarks ║${RESET}`);
|
|
112
|
+
console.log(`${BOLD}╚════════════════════════════════════════════════════════════════╝${RESET}`);
|
|
113
|
+
|
|
114
|
+
// Initialize MessagePack if available
|
|
115
|
+
const hasMsgPack = await initMessagePack();
|
|
116
|
+
console.log(`\nMessagePack available: ${hasMsgPack ? 'yes' : 'no'}`);
|
|
117
|
+
|
|
118
|
+
// ─────────────────────────────────────────────────────────────────
|
|
119
|
+
// ID Generation
|
|
120
|
+
// ─────────────────────────────────────────────────────────────────
|
|
121
|
+
printHeader('ID Generation');
|
|
122
|
+
|
|
123
|
+
const idGen = new IdGenerator();
|
|
124
|
+
printResult(bench('uuid() [baseline]', () => uuid()));
|
|
125
|
+
printResult(bench('generateId() [optimized]', () => generateId()));
|
|
126
|
+
printResult(bench('IdGenerator.next()', () => idGen.next()));
|
|
127
|
+
printResult(bench('IdGenerator.short()', () => idGen.short()));
|
|
128
|
+
|
|
129
|
+
// ─────────────────────────────────────────────────────────────────
|
|
130
|
+
// Frame Encoding
|
|
131
|
+
// ─────────────────────────────────────────────────────────────────
|
|
132
|
+
printHeader('Frame Encoding (JSON)');
|
|
133
|
+
|
|
134
|
+
printResult(bench('encodeFrameLegacy (small)', () => encodeFrameLegacy(smallEnvelope)));
|
|
135
|
+
printResult(bench('encodeFrameLegacy (medium)', () => encodeFrameLegacy(mediumEnvelope)));
|
|
136
|
+
printResult(bench('encodeFrameLegacy (large)', () => encodeFrameLegacy(largeEnvelope), 1000));
|
|
137
|
+
|
|
138
|
+
if (hasMsgPack) {
|
|
139
|
+
printHeader('Frame Encoding (MessagePack)');
|
|
140
|
+
printResult(bench('encodeFrame msgpack (small)', () => encodeFrame(smallEnvelope, 'msgpack')));
|
|
141
|
+
printResult(bench('encodeFrame msgpack (medium)', () => encodeFrame(mediumEnvelope, 'msgpack')));
|
|
142
|
+
printResult(bench('encodeFrame msgpack (large)', () => encodeFrame(largeEnvelope, 'msgpack'), 1000));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// ─────────────────────────────────────────────────────────────────
|
|
146
|
+
// Frame Parsing
|
|
147
|
+
// ─────────────────────────────────────────────────────────────────
|
|
148
|
+
printHeader('Frame Parsing');
|
|
149
|
+
|
|
150
|
+
const smallFrame = encodeFrameLegacy(smallEnvelope);
|
|
151
|
+
const mediumFrame = encodeFrameLegacy(mediumEnvelope);
|
|
152
|
+
const largeFrame = encodeFrameLegacy(largeEnvelope);
|
|
153
|
+
|
|
154
|
+
// Create fresh parser for each benchmark to avoid buffer accumulation
|
|
155
|
+
printResult(
|
|
156
|
+
bench('FrameParser.push (small)', () => {
|
|
157
|
+
const parser = new FrameParser();
|
|
158
|
+
parser.setLegacyMode(true);
|
|
159
|
+
parser.push(smallFrame);
|
|
160
|
+
})
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
printResult(
|
|
164
|
+
bench('FrameParser.push (medium)', () => {
|
|
165
|
+
const parser = new FrameParser();
|
|
166
|
+
parser.setLegacyMode(true);
|
|
167
|
+
parser.push(mediumFrame);
|
|
168
|
+
})
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
printResult(
|
|
172
|
+
bench(
|
|
173
|
+
'FrameParser.push (large)',
|
|
174
|
+
() => {
|
|
175
|
+
const parser = new FrameParser();
|
|
176
|
+
parser.setLegacyMode(true);
|
|
177
|
+
parser.push(largeFrame);
|
|
178
|
+
},
|
|
179
|
+
1000
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// Multiple frames in sequence (reuse parser)
|
|
184
|
+
printResult(
|
|
185
|
+
bench('FrameParser 10 msgs (reuse)', () => {
|
|
186
|
+
const parser = new FrameParser();
|
|
187
|
+
parser.setLegacyMode(true);
|
|
188
|
+
for (let i = 0; i < 10; i++) {
|
|
189
|
+
parser.push(smallFrame);
|
|
190
|
+
}
|
|
191
|
+
}, 1000)
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// ─────────────────────────────────────────────────────────────────
|
|
195
|
+
// Output Parser
|
|
196
|
+
// ─────────────────────────────────────────────────────────────────
|
|
197
|
+
printHeader('Output Parser');
|
|
198
|
+
|
|
199
|
+
const normalLine = 'This is a normal line of agent output that should be passed through.\n';
|
|
200
|
+
const relayLine = '->relay:Bob Hello, this is a message for you!\n';
|
|
201
|
+
const mixedOutput =
|
|
202
|
+
'Some output\n' +
|
|
203
|
+
'More output\n' +
|
|
204
|
+
'->relay:Bob Can you review auth.ts?\n' +
|
|
205
|
+
'Even more output\n' +
|
|
206
|
+
'Final line\n';
|
|
207
|
+
|
|
208
|
+
printResult(
|
|
209
|
+
bench('OutputParser normal line', () => {
|
|
210
|
+
const parser = new OutputParser();
|
|
211
|
+
parser.parse(normalLine);
|
|
212
|
+
})
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
printResult(
|
|
216
|
+
bench('OutputParser relay line', () => {
|
|
217
|
+
const parser = new OutputParser();
|
|
218
|
+
parser.parse(relayLine);
|
|
219
|
+
})
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
printResult(
|
|
223
|
+
bench('OutputParser mixed (5 lines)', () => {
|
|
224
|
+
const parser = new OutputParser();
|
|
225
|
+
parser.parse(mixedOutput);
|
|
226
|
+
})
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
// ─────────────────────────────────────────────────────────────────
|
|
230
|
+
// Deduplication Cache
|
|
231
|
+
// ─────────────────────────────────────────────────────────────────
|
|
232
|
+
printHeader('Deduplication Cache');
|
|
233
|
+
|
|
234
|
+
// Circular cache (new implementation)
|
|
235
|
+
class CircularDedupeCache {
|
|
236
|
+
private ids: Set<string> = new Set();
|
|
237
|
+
private ring: string[];
|
|
238
|
+
private head = 0;
|
|
239
|
+
private readonly capacity: number;
|
|
240
|
+
|
|
241
|
+
constructor(capacity = 2000) {
|
|
242
|
+
this.capacity = capacity;
|
|
243
|
+
this.ring = new Array(capacity);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
check(id: string): boolean {
|
|
247
|
+
if (this.ids.has(id)) return true;
|
|
248
|
+
if (this.ids.size >= this.capacity) {
|
|
249
|
+
const oldest = this.ring[this.head];
|
|
250
|
+
if (oldest) this.ids.delete(oldest);
|
|
251
|
+
}
|
|
252
|
+
this.ring[this.head] = id;
|
|
253
|
+
this.ids.add(id);
|
|
254
|
+
this.head = (this.head + 1) % this.capacity;
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Array-based cache (old implementation)
|
|
260
|
+
class ArrayDedupeCache {
|
|
261
|
+
private ids: Set<string> = new Set();
|
|
262
|
+
private order: string[] = [];
|
|
263
|
+
private readonly limit: number;
|
|
264
|
+
|
|
265
|
+
constructor(limit = 2000) {
|
|
266
|
+
this.limit = limit;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
check(id: string): boolean {
|
|
270
|
+
if (this.ids.has(id)) return true;
|
|
271
|
+
this.ids.add(id);
|
|
272
|
+
this.order.push(id);
|
|
273
|
+
if (this.order.length > this.limit) {
|
|
274
|
+
const oldest = this.order.shift();
|
|
275
|
+
if (oldest) this.ids.delete(oldest);
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const circularCache = new CircularDedupeCache(2000);
|
|
282
|
+
const arrayCache = new ArrayDedupeCache(2000);
|
|
283
|
+
let circularCounter = 0;
|
|
284
|
+
let arrayCounter = 0;
|
|
285
|
+
|
|
286
|
+
printResult(
|
|
287
|
+
bench('CircularDedupeCache.check', () => {
|
|
288
|
+
circularCache.check(`id-${circularCounter++}`);
|
|
289
|
+
})
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
printResult(
|
|
293
|
+
bench('ArrayDedupeCache.check [old]', () => {
|
|
294
|
+
arrayCache.check(`id-${arrayCounter++}`);
|
|
295
|
+
})
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
// ─────────────────────────────────────────────────────────────────
|
|
299
|
+
// Summary
|
|
300
|
+
// ─────────────────────────────────────────────────────────────────
|
|
301
|
+
console.log(`\n${BOLD}Summary${RESET}`);
|
|
302
|
+
console.log('─'.repeat(65));
|
|
303
|
+
console.log('ID Generation: generateId() is ~10-20x faster than uuid()');
|
|
304
|
+
console.log('Frame Parsing: Ring buffer eliminates GC pressure');
|
|
305
|
+
console.log('Output Parser: Early exit avoids ANSI stripping for most lines');
|
|
306
|
+
console.log('Dedup Cache: Circular buffer is O(1) vs O(n) for eviction');
|
|
307
|
+
console.log('');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
main().catch(console.error);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[116],{9116:function(e,r,t){t.d(r,{$3:function(){return i},XP:function(){return y},aM:function(){return o},hc:function(){return n},hi:function(){return d},kG:function(){return u}});let s="agentrelay_workspace_id",a=null,c=null;function o(e){c=e}function n(e){a=e,e?localStorage.setItem(s,e):localStorage.removeItem(s)}function i(){if(a)return a;{let e=localStorage.getItem(s);if(e)return a=e,e}return null}function u(e){if(a){let r=e.startsWith("/api/")?e.substring(5):e.replace(/^\//,"");return"/api/workspaces/".concat(a,"/proxy/").concat(r)}return"".concat("").concat(e)}async function l(e){var r;let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=(null===(r=t.method)||void 0===r?void 0:r.toUpperCase())||"GET",a={...t.headers};"GET"!==s&&"HEAD"!==s&&"OPTIONS"!==s&&(c&&(a["X-CSRF-Token"]=c),t.body&&!a["Content-Type"]&&(a["Content-Type"]="application/json"));let o=await fetch(e,{...t,headers:a,credentials:"include"});return!function(e){let r=e.headers.get("X-CSRF-Token");r&&(c=r)}(o),o}let d={async sendMessage(e){try{let r=await l(u("/api/send"),{method:"POST",body:JSON.stringify(e)}),t=await r.json();if(r.ok&&t.success)return{success:!0};return{success:!1,error:t.error||"Failed to send message"}}catch(e){return{success:!1,error:"Network error"}}},async uploadAttachment(e){try{let r,t,s;e instanceof File?(r=e.name,t=e.type,s=await new Promise((r,t)=>{let s=new FileReader;s.onload=()=>r(s.result),s.onerror=t,s.readAsDataURL(e)})):(r=e.filename,t=e.mimeType,s=e.data);let a=await l(u("/api/upload"),{method:"POST",body:JSON.stringify({filename:r,mimeType:t,data:s})}),c=await a.json();if(a.ok&&c.success&&c.attachment)return{success:!0,data:{attachment:c.attachment}};return{success:!1,error:c.error||"Failed to upload attachment"}}catch(e){return{success:!1,error:"Network error"}}},async spawnAgent(e){try{let r=await l(u("/api/spawn"),{method:"POST",body:JSON.stringify(e)});return await r.json()}catch(r){return{success:!1,name:e.name,error:"Network error"}}},async getSpawnedAgents(){try{let e=await l(u("/api/spawned")),r=await e.json();if(e.ok&&r.success)return{success:!0,data:{agents:r.agents||[]}};return{success:!1,error:r.error}}catch(e){return{success:!1,error:"Network error"}}},async releaseAgent(e){try{let r=await l(u("/api/spawned/".concat(encodeURIComponent(e))),{method:"DELETE"}),t=await r.json();if(r.ok&&t.success)return{success:!0};return{success:!1,error:t.error}}catch(e){return{success:!1,error:"Network error"}}},async getData(){try{let e=await l(u("/api/data")),r=await e.json();if(e.ok)return{success:!0,data:r};return{success:!1,error:"Failed to fetch data"}}catch(e){return{success:!1,error:"Network error"}}},async getBridgeData(){try{let e=await l(u("/api/bridge")),r=await e.json();if(e.ok)return{success:!0,data:r};return{success:!1,error:"Failed to fetch bridge data"}}catch(e){return{success:!1,error:"Network error"}}},async getMetrics(){try{let e=await l(u("/api/metrics")),r=await e.json();if(e.ok)return{success:!0,data:r};return{success:!1,error:"Failed to fetch metrics"}}catch(e){return{success:!1,error:"Network error"}}},async getHistorySessions(e){try{let r=new URLSearchParams;(null==e?void 0:e.agent)&&r.set("agent",e.agent),(null==e?void 0:e.since)&&r.set("since",String(e.since)),(null==e?void 0:e.limit)&&r.set("limit",String(e.limit));let t=await l(u("/api/history/sessions?".concat(r))),s=await t.json();if(t.ok)return{success:!0,data:s};return{success:!1,error:"Failed to fetch sessions"}}catch(e){return{success:!1,error:"Network error"}}},async getHistoryMessages(e){try{let r=new URLSearchParams;(null==e?void 0:e.from)&&r.set("from",e.from),(null==e?void 0:e.to)&&r.set("to",e.to),(null==e?void 0:e.thread)&&r.set("thread",e.thread),(null==e?void 0:e.since)&&r.set("since",String(e.since)),(null==e?void 0:e.limit)&&r.set("limit",String(e.limit)),(null==e?void 0:e.order)&&r.set("order",e.order),(null==e?void 0:e.search)&&r.set("search",e.search);let t=await l(u("/api/history/messages?".concat(r))),s=await t.json();if(t.ok)return{success:!0,data:s};return{success:!1,error:"Failed to fetch messages"}}catch(e){return{success:!1,error:"Network error"}}},async getHistoryConversations(){try{let e=await l(u("/api/history/conversations")),r=await e.json();if(e.ok)return{success:!0,data:r};return{success:!1,error:"Failed to fetch conversations"}}catch(e){return{success:!1,error:"Network error"}}},async getHistoryMessage(e){try{let r=await l(u("/api/history/message/".concat(encodeURIComponent(e)))),t=await r.json();if(r.ok)return{success:!0,data:t};return{success:!1,error:t.error||"Failed to fetch message"}}catch(e){return{success:!1,error:"Network error"}}},async getHistoryStats(){try{let e=await l(u("/api/history/stats")),r=await e.json();if(e.ok)return{success:!0,data:r};return{success:!1,error:"Failed to fetch stats"}}catch(e){return{success:!1,error:"Network error"}}},async searchFiles(e){try{let r=new URLSearchParams;(null==e?void 0:e.query)&&r.set("q",e.query),(null==e?void 0:e.limit)&&r.set("limit",String(e.limit));let t=await l(u("/api/files?".concat(r))),s=await t.json();if(t.ok)return{success:!0,data:s};return{success:!1,error:"Failed to search files"}}catch(e){return{success:!1,error:"Network error"}}},async getDecisions(){try{let e=await l(u("/api/decisions")),r=await e.json();if(e.ok&&r.success)return{success:!0,data:{decisions:r.decisions||[]}};return{success:!1,error:r.error||"Failed to fetch decisions"}}catch(e){return{success:!1,error:"Network error"}}},async approveDecision(e,r,t){try{let s=await l(u("/api/decisions/".concat(encodeURIComponent(e),"/approve")),{method:"POST",body:JSON.stringify({optionId:r,response:t})}),a=await s.json();if(s.ok&&a.success)return{success:!0};return{success:!1,error:a.error||"Failed to approve decision"}}catch(e){return{success:!1,error:"Network error"}}},async rejectDecision(e,r){try{let t=await l(u("/api/decisions/".concat(encodeURIComponent(e),"/reject")),{method:"POST",body:JSON.stringify({reason:r})}),s=await t.json();if(t.ok&&s.success)return{success:!0};return{success:!1,error:s.error||"Failed to reject decision"}}catch(e){return{success:!1,error:"Network error"}}},async dismissDecision(e){try{let r=await l(u("/api/decisions/".concat(encodeURIComponent(e))),{method:"DELETE"}),t=await r.json();if(r.ok&&t.success)return{success:!0};return{success:!1,error:t.error||"Failed to dismiss decision"}}catch(e){return{success:!1,error:"Network error"}}},async getFleetServers(){try{let e=await l(u("/api/fleet/servers")),r=await e.json();if(e.ok&&r.success)return{success:!0,data:{servers:r.servers||[]}};return{success:!1,error:r.error||"Failed to fetch fleet servers"}}catch(e){return{success:!1,error:"Network error"}}},async getFleetStats(){try{let e=await l(u("/api/fleet/stats")),r=await e.json();if(e.ok&&r.success)return{success:!0,data:{stats:r.stats}};return{success:!1,error:r.error||"Failed to fetch fleet stats"}}catch(e){return{success:!1,error:"Network error"}}},async getTasks(e){try{let r=new URLSearchParams;(null==e?void 0:e.status)&&r.set("status",e.status),(null==e?void 0:e.agent)&&r.set("agent",e.agent);let t=await l(u("/api/tasks?".concat(r))),s=await t.json();if(t.ok&&s.success)return{success:!0,data:{tasks:s.tasks||[]}};return{success:!1,error:s.error||"Failed to fetch tasks"}}catch(e){return{success:!1,error:"Network error"}}},async createTask(e){try{let r=await l(u("/api/tasks"),{method:"POST",body:JSON.stringify(e)}),t=await r.json();if(r.ok&&t.success)return{success:!0,data:{task:t.task}};return{success:!1,error:t.error||"Failed to create task"}}catch(e){return{success:!1,error:"Network error"}}},async updateTask(e,r){try{let t=await l(u("/api/tasks/".concat(encodeURIComponent(e))),{method:"PATCH",body:JSON.stringify(r)}),s=await t.json();if(t.ok&&s.success)return{success:!0,data:{task:s.task}};return{success:!1,error:s.error||"Failed to update task"}}catch(e){return{success:!1,error:"Network error"}}},async cancelTask(e){try{let r=await l(u("/api/tasks/".concat(encodeURIComponent(e))),{method:"DELETE"}),t=await r.json();if(r.ok&&t.success)return{success:!0};return{success:!1,error:t.error||"Failed to cancel task"}}catch(e){return{success:!1,error:"Network error"}}},async createBead(e){try{let r=await l(u("/api/beads"),{method:"POST",body:JSON.stringify(e)}),t=await r.json();if(r.ok&&t.success)return{success:!0,data:{bead:t.bead}};return{success:!1,error:t.error||"Failed to create bead"}}catch(e){return{success:!1,error:"Network error"}}},async sendRelayMessage(e){try{let r=await l(u("/api/relay/send"),{method:"POST",body:JSON.stringify(e)}),t=await r.json();if(r.ok&&t.success)return{success:!0,data:{messageId:t.messageId}};return{success:!1,error:t.error||"Failed to send message"}}catch(e){return{success:!1,error:"Network error"}}}};function y(e){return{id:e.id,agentName:e.agentName,timestamp:e.createdAt,type:e.category,title:e.title,description:e.description,options:e.options,priority:e.urgency,context:e.context,expiresAt:e.expiresAt}}}}]);
|