@exagent/agent 0.3.6 → 0.3.7

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.
Files changed (68) hide show
  1. package/dist/chunk-7UGLJO6W.js +6392 -0
  2. package/dist/chunk-EHAOPCTJ.js +6406 -0
  3. package/dist/chunk-FGMXTW5I.js +6540 -0
  4. package/dist/chunk-IVA2SCSN.js +6756 -0
  5. package/dist/chunk-JHXCSGPC.js +6352 -0
  6. package/dist/chunk-V6O4UXVN.js +6345 -0
  7. package/dist/chunk-WTECTX2Z.js +6345 -0
  8. package/dist/cli.js +2 -2
  9. package/dist/index.d.ts +24 -2
  10. package/dist/index.js +1 -1
  11. package/package.json +12 -9
  12. package/src/bridge/across.ts +0 -240
  13. package/src/bridge/bridge-manager.ts +0 -87
  14. package/src/bridge/index.ts +0 -9
  15. package/src/bridge/types.ts +0 -77
  16. package/src/chains.ts +0 -105
  17. package/src/cli.ts +0 -250
  18. package/src/config.ts +0 -502
  19. package/src/diagnostics.ts +0 -335
  20. package/src/index.ts +0 -98
  21. package/src/llm/anthropic.ts +0 -63
  22. package/src/llm/base.ts +0 -264
  23. package/src/llm/deepseek.ts +0 -48
  24. package/src/llm/google.ts +0 -63
  25. package/src/llm/groq.ts +0 -48
  26. package/src/llm/index.ts +0 -42
  27. package/src/llm/mistral.ts +0 -48
  28. package/src/llm/ollama.ts +0 -52
  29. package/src/llm/openai.ts +0 -94
  30. package/src/llm/together.ts +0 -48
  31. package/src/llm-providers.ts +0 -8
  32. package/src/logger.ts +0 -137
  33. package/src/paper/executor.ts +0 -201
  34. package/src/paper/index.ts +0 -1
  35. package/src/perp/client.ts +0 -200
  36. package/src/perp/index.ts +0 -12
  37. package/src/perp/msgpack.ts +0 -272
  38. package/src/perp/orders.ts +0 -234
  39. package/src/perp/positions.ts +0 -126
  40. package/src/perp/signer.ts +0 -277
  41. package/src/perp/types.ts +0 -192
  42. package/src/perp/websocket.ts +0 -274
  43. package/src/position-tracker.ts +0 -243
  44. package/src/prediction/client.ts +0 -288
  45. package/src/prediction/index.ts +0 -3
  46. package/src/prediction/order-manager.ts +0 -297
  47. package/src/prediction/types.ts +0 -151
  48. package/src/relay.ts +0 -254
  49. package/src/runtime.ts +0 -1755
  50. package/src/scrub-secrets.ts +0 -39
  51. package/src/setup.ts +0 -392
  52. package/src/signal.ts +0 -212
  53. package/src/spot/aerodrome.ts +0 -158
  54. package/src/spot/client.ts +0 -138
  55. package/src/spot/index.ts +0 -11
  56. package/src/spot/swap-manager.ts +0 -219
  57. package/src/spot/types.ts +0 -203
  58. package/src/spot/uniswap.ts +0 -150
  59. package/src/store.ts +0 -50
  60. package/src/strategy/index.ts +0 -2
  61. package/src/strategy/loader.ts +0 -265
  62. package/src/strategy/templates.ts +0 -74
  63. package/src/trading/index.ts +0 -2
  64. package/src/trading/market.ts +0 -120
  65. package/src/trading/risk.ts +0 -107
  66. package/src/ui.ts +0 -75
  67. package/test/strategy-loader.test.ts +0 -150
  68. package/tsconfig.json +0 -8
@@ -1,335 +0,0 @@
1
- /**
2
- * Diagnostics collector for the agent SDK.
3
- *
4
- * Tracks: per-cycle timing, error categorization, LLM call stats,
5
- * and produces health-check snapshots for the heartbeat payload.
6
- */
7
-
8
- import type { LLMUsageStats } from './llm/base.js';
9
-
10
- // ── Error Categories ─────────────────────────────────────────
11
-
12
- export type ErrorCategory =
13
- | 'network' // Timeout, ECONNREFUSED, DNS, socket errors
14
- | 'auth' // 401, 403, token expired
15
- | 'venue' // Order rejected, insufficient balance, venue API errors
16
- | 'strategy' // LLM parse failure, strategy threw, invalid signals
17
- | 'risk' // Daily limit hit, position size rejected, leverage rejected
18
- | 'internal'; // Unexpected errors, code bugs
19
-
20
- export interface CategorizedError {
21
- category: ErrorCategory;
22
- message: string;
23
- timestamp: number;
24
- }
25
-
26
- // ── Cycle Metrics ────────────────────────────────────────────
27
-
28
- export interface CycleTimings {
29
- totalMs: number;
30
- priceRefreshMs: number;
31
- strategyMs: number;
32
- riskFilterMs: number;
33
- executionMs: number;
34
- }
35
-
36
- export interface CycleMetrics {
37
- cycleNumber: number;
38
- startedAt: number;
39
- timings: CycleTimings;
40
- signalsGenerated: number;
41
- signalsFiltered: number;
42
- tradesExecuted: number;
43
- success: boolean;
44
- error?: string;
45
- }
46
-
47
- // ── LLM Call Log ─────────────────────────────────────────────
48
-
49
- export interface LLMCallRecord {
50
- timestamp: number;
51
- provider: string;
52
- model: string;
53
- inputTokens: number;
54
- outputTokens: number;
55
- latencyMs: number;
56
- success: boolean;
57
- error?: string;
58
- retries: number;
59
- }
60
-
61
- // ── Health Snapshot ───────────────────────────────────────────
62
-
63
- export interface HealthSnapshot {
64
- uptime: number;
65
- uptimeHuman: string;
66
- memoryMB: number;
67
- cycleStats: {
68
- total: number;
69
- succeeded: number;
70
- failed: number;
71
- successRate: number;
72
- avgCycleMs: number;
73
- lastCycleMs: number;
74
- };
75
- errorCounts: Record<ErrorCategory, number>;
76
- recentErrors: CategorizedError[];
77
- llmStats: {
78
- totalCalls: number;
79
- avgLatencyMs: number;
80
- errorRate: number;
81
- recentCalls: number;
82
- };
83
- signalQueue: {
84
- pending: number;
85
- flushedTotal: number;
86
- };
87
- }
88
-
89
- // ── Diagnostics Collector ────────────────────────────────────
90
-
91
- /** Rolling window size for recent items */
92
- const MAX_RECENT_ERRORS = 50;
93
- const MAX_RECENT_CYCLES = 100;
94
- const MAX_LLM_CALLS = 200;
95
-
96
- export class DiagnosticsCollector {
97
- private startTime = Date.now();
98
-
99
- // Cycle tracking
100
- private cycles: CycleMetrics[] = [];
101
- private totalCycles = 0;
102
- private succeededCycles = 0;
103
- private failedCycles = 0;
104
-
105
- // Error tracking
106
- private errorCounts: Record<ErrorCategory, number> = {
107
- network: 0,
108
- auth: 0,
109
- venue: 0,
110
- strategy: 0,
111
- risk: 0,
112
- internal: 0,
113
- };
114
- private recentErrors: CategorizedError[] = [];
115
-
116
- // LLM call tracking
117
- private llmCalls: LLMCallRecord[] = [];
118
- private totalLLMCalls = 0;
119
- private failedLLMCalls = 0;
120
- private totalLLMLatency = 0;
121
-
122
- // Signal queue tracking
123
- private flushedSignalsTotal = 0;
124
-
125
- // ── Cycle Recording ──────────────────────────────────────
126
-
127
- recordCycle(metrics: CycleMetrics): void {
128
- this.totalCycles++;
129
- if (metrics.success) {
130
- this.succeededCycles++;
131
- } else {
132
- this.failedCycles++;
133
- }
134
-
135
- this.cycles.push(metrics);
136
- if (this.cycles.length > MAX_RECENT_CYCLES) {
137
- this.cycles.shift();
138
- }
139
- }
140
-
141
- /** Get the latest cycle metrics (for heartbeat) */
142
- getLastCycle(): CycleMetrics | null {
143
- return this.cycles.length > 0 ? this.cycles[this.cycles.length - 1]! : null;
144
- }
145
-
146
- /** Average cycle duration from recent cycles */
147
- getAvgCycleMs(): number {
148
- if (this.cycles.length === 0) return 0;
149
- const total = this.cycles.reduce((sum, c) => sum + c.timings.totalMs, 0);
150
- return Math.round(total / this.cycles.length);
151
- }
152
-
153
- // ── Error Recording ──────────────────────────────────────
154
-
155
- /** Categorize and record an error */
156
- recordError(error: Error | string, category?: ErrorCategory): CategorizedError {
157
- const msg = typeof error === 'string' ? error : error.message;
158
- const cat = category ?? this.categorizeError(msg);
159
-
160
- this.errorCounts[cat]++;
161
-
162
- const entry: CategorizedError = {
163
- category: cat,
164
- message: msg,
165
- timestamp: Date.now(),
166
- };
167
-
168
- this.recentErrors.push(entry);
169
- if (this.recentErrors.length > MAX_RECENT_ERRORS) {
170
- this.recentErrors.shift();
171
- }
172
-
173
- return entry;
174
- }
175
-
176
- /** Auto-categorize an error from its message */
177
- categorizeError(msg: string): ErrorCategory {
178
- const lower = msg.toLowerCase();
179
-
180
- // Network errors
181
- if (
182
- lower.includes('timed out') ||
183
- lower.includes('econnrefused') ||
184
- lower.includes('econnreset') ||
185
- lower.includes('etimedout') ||
186
- lower.includes('enotfound') ||
187
- lower.includes('socket hang up') ||
188
- lower.includes('fetch failed') ||
189
- lower.includes('network') ||
190
- lower.includes('dns')
191
- ) {
192
- return 'network';
193
- }
194
-
195
- // Auth errors
196
- if (
197
- lower.includes('401') ||
198
- lower.includes('403') ||
199
- lower.includes('unauthorized') ||
200
- lower.includes('forbidden') ||
201
- lower.includes('auth') ||
202
- lower.includes('token expired') ||
203
- lower.includes('invalid token')
204
- ) {
205
- return 'auth';
206
- }
207
-
208
- // Venue errors
209
- if (
210
- lower.includes('order rejected') ||
211
- lower.includes('insufficient balance') ||
212
- lower.includes('insufficient margin') ||
213
- lower.includes('not enough balance') ||
214
- lower.includes('user does not exist') ||
215
- lower.includes('max notional') ||
216
- lower.includes('max leverage') ||
217
- lower.includes('max swap') ||
218
- lower.includes('max bridge') ||
219
- lower.includes('reverted')
220
- ) {
221
- return 'venue';
222
- }
223
-
224
- // Strategy errors
225
- if (
226
- lower.includes('strategy') ||
227
- lower.includes('llm') ||
228
- lower.includes('parse') ||
229
- lower.includes('json') ||
230
- lower.includes('budget exceeded')
231
- ) {
232
- return 'strategy';
233
- }
234
-
235
- // Risk errors
236
- if (
237
- lower.includes('daily loss') ||
238
- lower.includes('position size') ||
239
- lower.includes('risk') ||
240
- lower.includes('slippage')
241
- ) {
242
- return 'risk';
243
- }
244
-
245
- return 'internal';
246
- }
247
-
248
- getErrorCounts(): Record<ErrorCategory, number> {
249
- return { ...this.errorCounts };
250
- }
251
-
252
- // ── LLM Call Recording ───────────────────────────────────
253
-
254
- recordLLMCall(record: LLMCallRecord): void {
255
- this.totalLLMCalls++;
256
- this.totalLLMLatency += record.latencyMs;
257
- if (!record.success) {
258
- this.failedLLMCalls++;
259
- }
260
-
261
- this.llmCalls.push(record);
262
- if (this.llmCalls.length > MAX_LLM_CALLS) {
263
- this.llmCalls.shift();
264
- }
265
- }
266
-
267
- getRecentLLMCalls(count = 10): LLMCallRecord[] {
268
- return this.llmCalls.slice(-count);
269
- }
270
-
271
- // ── Signal Queue Tracking ────────────────────────────────
272
-
273
- recordSignalFlush(count: number): void {
274
- this.flushedSignalsTotal += count;
275
- }
276
-
277
- // ── Health Snapshot ──────────────────────────────────────
278
-
279
- getHealthSnapshot(pendingSignals: number): HealthSnapshot {
280
- const uptimeMs = Date.now() - this.startTime;
281
- const memUsage = process.memoryUsage();
282
-
283
- const lastCycle = this.getLastCycle();
284
- const avgLLMLatency = this.totalLLMCalls > 0
285
- ? Math.round(this.totalLLMLatency / this.totalLLMCalls)
286
- : 0;
287
- const llmErrorRate = this.totalLLMCalls > 0
288
- ? this.failedLLMCalls / this.totalLLMCalls
289
- : 0;
290
-
291
- // Count LLM calls in the last 5 minutes
292
- const fiveMinAgo = Date.now() - 300_000;
293
- const recentLLMCalls = this.llmCalls.filter(c => c.timestamp > fiveMinAgo).length;
294
-
295
- return {
296
- uptime: uptimeMs,
297
- uptimeHuman: this.formatUptime(uptimeMs),
298
- memoryMB: Math.round(memUsage.rss / 1024 / 1024),
299
- cycleStats: {
300
- total: this.totalCycles,
301
- succeeded: this.succeededCycles,
302
- failed: this.failedCycles,
303
- successRate: this.totalCycles > 0
304
- ? Math.round((this.succeededCycles / this.totalCycles) * 10000) / 100
305
- : 100,
306
- avgCycleMs: this.getAvgCycleMs(),
307
- lastCycleMs: lastCycle?.timings.totalMs ?? 0,
308
- },
309
- errorCounts: this.getErrorCounts(),
310
- recentErrors: this.recentErrors.slice(-10),
311
- llmStats: {
312
- totalCalls: this.totalLLMCalls,
313
- avgLatencyMs: avgLLMLatency,
314
- errorRate: Math.round(llmErrorRate * 10000) / 100,
315
- recentCalls: recentLLMCalls,
316
- },
317
- signalQueue: {
318
- pending: pendingSignals,
319
- flushedTotal: this.flushedSignalsTotal,
320
- },
321
- };
322
- }
323
-
324
- private formatUptime(ms: number): string {
325
- const seconds = Math.floor(ms / 1000);
326
- const minutes = Math.floor(seconds / 60);
327
- const hours = Math.floor(minutes / 60);
328
- const days = Math.floor(hours / 24);
329
-
330
- if (days > 0) return `${days}d ${hours % 24}h`;
331
- if (hours > 0) return `${hours}h ${minutes % 60}m`;
332
- if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
333
- return `${seconds}s`;
334
- }
335
- }
package/src/index.ts DELETED
@@ -1,98 +0,0 @@
1
- export { AgentRuntime } from './runtime.js';
2
- export { RelayClient } from './relay.js';
3
- export { SignalReporter } from './signal.js';
4
- export { FileStore } from './store.js';
5
- export { PositionTracker } from './position-tracker.js';
6
- export { createLLMAdapter, BaseLLMAdapter } from './llm/index.js';
7
- export { loadStrategy, listTemplates, getTemplate } from './strategy/index.js';
8
- export { RiskManager } from './trading/risk.js';
9
- export { MarketDataService } from './trading/market.js';
10
- export { PaperExecutor } from './paper/index.js';
11
- export { loadConfig, generateSampleConfig, writeSampleConfig } from './config.js';
12
- export type { RuntimeConfig } from './config.js';
13
- export type { RelayClientConfig } from './relay.js';
14
-
15
- // Observability
16
- export { Logger, getLogger, configureLogger } from './logger.js';
17
- export type { LogLevel, LogCategory, LogEntry, LoggerConfig } from './logger.js';
18
- export { DiagnosticsCollector } from './diagnostics.js';
19
- export type {
20
- ErrorCategory,
21
- CategorizedError,
22
- CycleTimings,
23
- CycleMetrics,
24
- LLMCallRecord,
25
- HealthSnapshot,
26
- } from './diagnostics.js';
27
-
28
- // Hyperliquid perps
29
- export {
30
- HyperliquidClient,
31
- HyperliquidSigner,
32
- HyperliquidOrderManager,
33
- HyperliquidPositionManager,
34
- HyperliquidWebSocket,
35
- getNextNonce,
36
- HYPERLIQUID_DOMAIN,
37
- HYPERLIQUID_USER_DOMAIN,
38
- USER_ACTION_TYPES,
39
- } from './perp/index.js';
40
- export type {
41
- PerpConfig,
42
- PerpTradeSignal,
43
- PerpPosition,
44
- AccountSummary,
45
- PerpFill,
46
- OrderResult as PerpOrderResult,
47
- FillCallback,
48
- FundingCallback,
49
- LiquidationCallback,
50
- FundingPayment,
51
- } from './perp/index.js';
52
-
53
- // Polymarket predictions
54
- export {
55
- PolymarketClient,
56
- PolymarketOrderManager,
57
- encodePredictionInstrument,
58
- decodePredictionInstrument,
59
- } from './prediction/index.js';
60
- export type {
61
- PredictionConfig,
62
- PredictionTradeSignal,
63
- PredictionPosition,
64
- PredictionMarket,
65
- PredictionFill,
66
- } from './prediction/index.js';
67
-
68
- // Spot DEX trading
69
- export {
70
- SpotDEXClient,
71
- UniswapAdapter,
72
- AerodromeAdapter,
73
- SpotSwapManager,
74
- DEFAULT_SPOT_CONFIG,
75
- } from './spot/index.js';
76
- export type {
77
- SpotConfig,
78
- SpotSwapParams,
79
- SpotQuoteResult,
80
- SpotSwapResult,
81
- } from './spot/index.js';
82
-
83
- // Cross-chain bridges
84
- export {
85
- AcrossAdapter,
86
- BridgeManager,
87
- DEFAULT_BRIDGE_CONFIG,
88
- } from './bridge/index.js';
89
- export type {
90
- BridgeConfig,
91
- BridgeRequest,
92
- BridgeFeeEstimate,
93
- BridgeResult,
94
- } from './bridge/index.js';
95
-
96
- // Chain configs
97
- export { CHAIN_CONFIGS, getChainConfig, applyRpcOverrides } from './chains.js';
98
- export type { ChainConfig } from './chains.js';
@@ -1,63 +0,0 @@
1
- import { getDefaultModel, type LLMMessage, type LLMResponse, type LLMMetadata, type LLMConfig } from '@exagent/sdk';
2
- import { BaseLLMAdapter } from './base.js';
3
-
4
- export class AnthropicAdapter extends BaseLLMAdapter {
5
- private endpoint: string;
6
-
7
- constructor(config: LLMConfig) {
8
- super(config);
9
- this.endpoint = config.endpoint || 'https://api.anthropic.com';
10
- }
11
-
12
- protected async chatImpl(messages: LLMMessage[]): Promise<LLMResponse> {
13
- const systemMessage = messages.find(m => m.role === 'system');
14
- const nonSystemMessages = messages.filter(m => m.role !== 'system');
15
-
16
- const body: Record<string, unknown> = {
17
- model: this.config.model || getDefaultModel('anthropic'),
18
- messages: nonSystemMessages.map(m => ({ role: m.role, content: m.content })),
19
- max_tokens: this.getMaxTokens(),
20
- temperature: this.getTemperature(),
21
- };
22
-
23
- if (systemMessage) {
24
- body.system = systemMessage.content;
25
- }
26
-
27
- const res = await this.fetchWithTimeout(`${this.endpoint}/v1/messages`, {
28
- method: 'POST',
29
- headers: {
30
- 'Content-Type': 'application/json',
31
- 'x-api-key': this.config.apiKey || '',
32
- 'anthropic-version': '2023-06-01',
33
- },
34
- body: JSON.stringify(body),
35
- });
36
-
37
- if (!res.ok) {
38
- const text = await res.text();
39
- throw new Error(`Anthropic API error ${res.status}: ${text}`);
40
- }
41
-
42
- const data = await res.json() as {
43
- content: { type: string; text: string }[];
44
- usage?: { input_tokens: number; output_tokens: number };
45
- };
46
-
47
- const textContent = data.content.find(c => c.type === 'text');
48
-
49
- return {
50
- content: textContent?.text || '',
51
- tokens: data.usage
52
- ? { input: data.usage.input_tokens, output: data.usage.output_tokens }
53
- : undefined,
54
- };
55
- }
56
-
57
- getMetadata(): LLMMetadata {
58
- return {
59
- provider: 'anthropic',
60
- model: this.config.model || getDefaultModel('anthropic'),
61
- };
62
- }
63
- }