@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.
- package/dist/chunk-7UGLJO6W.js +6392 -0
- package/dist/chunk-EHAOPCTJ.js +6406 -0
- package/dist/chunk-FGMXTW5I.js +6540 -0
- package/dist/chunk-IVA2SCSN.js +6756 -0
- package/dist/chunk-JHXCSGPC.js +6352 -0
- package/dist/chunk-V6O4UXVN.js +6345 -0
- package/dist/chunk-WTECTX2Z.js +6345 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +1 -1
- package/package.json +12 -9
- package/src/bridge/across.ts +0 -240
- package/src/bridge/bridge-manager.ts +0 -87
- package/src/bridge/index.ts +0 -9
- package/src/bridge/types.ts +0 -77
- package/src/chains.ts +0 -105
- package/src/cli.ts +0 -250
- package/src/config.ts +0 -502
- package/src/diagnostics.ts +0 -335
- package/src/index.ts +0 -98
- package/src/llm/anthropic.ts +0 -63
- package/src/llm/base.ts +0 -264
- package/src/llm/deepseek.ts +0 -48
- package/src/llm/google.ts +0 -63
- package/src/llm/groq.ts +0 -48
- package/src/llm/index.ts +0 -42
- package/src/llm/mistral.ts +0 -48
- package/src/llm/ollama.ts +0 -52
- package/src/llm/openai.ts +0 -94
- package/src/llm/together.ts +0 -48
- package/src/llm-providers.ts +0 -8
- package/src/logger.ts +0 -137
- package/src/paper/executor.ts +0 -201
- package/src/paper/index.ts +0 -1
- package/src/perp/client.ts +0 -200
- package/src/perp/index.ts +0 -12
- package/src/perp/msgpack.ts +0 -272
- package/src/perp/orders.ts +0 -234
- package/src/perp/positions.ts +0 -126
- package/src/perp/signer.ts +0 -277
- package/src/perp/types.ts +0 -192
- package/src/perp/websocket.ts +0 -274
- package/src/position-tracker.ts +0 -243
- package/src/prediction/client.ts +0 -288
- package/src/prediction/index.ts +0 -3
- package/src/prediction/order-manager.ts +0 -297
- package/src/prediction/types.ts +0 -151
- package/src/relay.ts +0 -254
- package/src/runtime.ts +0 -1755
- package/src/scrub-secrets.ts +0 -39
- package/src/setup.ts +0 -392
- package/src/signal.ts +0 -212
- package/src/spot/aerodrome.ts +0 -158
- package/src/spot/client.ts +0 -138
- package/src/spot/index.ts +0 -11
- package/src/spot/swap-manager.ts +0 -219
- package/src/spot/types.ts +0 -203
- package/src/spot/uniswap.ts +0 -150
- package/src/store.ts +0 -50
- package/src/strategy/index.ts +0 -2
- package/src/strategy/loader.ts +0 -265
- package/src/strategy/templates.ts +0 -74
- package/src/trading/index.ts +0 -2
- package/src/trading/market.ts +0 -120
- package/src/trading/risk.ts +0 -107
- package/src/ui.ts +0 -75
- package/test/strategy-loader.test.ts +0 -150
- package/tsconfig.json +0 -8
package/src/prediction/types.ts
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Polymarket Prediction Market Types
|
|
3
|
-
*
|
|
4
|
-
* Core type definitions for prediction market trading via Polymarket CLOB on Polygon.
|
|
5
|
-
* Fills are reported to the command center via WebSocket relay — no on-chain recording.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// ============================================================
|
|
9
|
-
// CONFIG
|
|
10
|
-
// ============================================================
|
|
11
|
-
|
|
12
|
-
export interface PredictionConfig {
|
|
13
|
-
enabled: boolean;
|
|
14
|
-
clobApiUrl: string;
|
|
15
|
-
gammaApiUrl: string;
|
|
16
|
-
maxNotionalUSD: number;
|
|
17
|
-
maxTotalExposureUSD: number;
|
|
18
|
-
allowedCategories?: string[];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const DEFAULT_PREDICTION_CONFIG: PredictionConfig = {
|
|
22
|
-
enabled: false,
|
|
23
|
-
clobApiUrl: 'https://clob.polymarket.com',
|
|
24
|
-
gammaApiUrl: 'https://gamma-api.polymarket.com',
|
|
25
|
-
maxNotionalUSD: 1_000,
|
|
26
|
-
maxTotalExposureUSD: 5_000,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// ============================================================
|
|
30
|
-
// SIGNALS
|
|
31
|
-
// ============================================================
|
|
32
|
-
|
|
33
|
-
export type PredictionAction =
|
|
34
|
-
| 'buy_yes'
|
|
35
|
-
| 'buy_no'
|
|
36
|
-
| 'sell_yes'
|
|
37
|
-
| 'sell_no'
|
|
38
|
-
| 'hold';
|
|
39
|
-
|
|
40
|
-
export interface PredictionTradeSignal {
|
|
41
|
-
action: PredictionAction;
|
|
42
|
-
marketConditionId: string;
|
|
43
|
-
marketQuestion: string;
|
|
44
|
-
outcomeIndex: number;
|
|
45
|
-
amount: number;
|
|
46
|
-
limitPrice: number;
|
|
47
|
-
orderType: 'limit' | 'market';
|
|
48
|
-
confidence: number;
|
|
49
|
-
reasoning?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ============================================================
|
|
53
|
-
// POSITIONS
|
|
54
|
-
// ============================================================
|
|
55
|
-
|
|
56
|
-
export interface PredictionPosition {
|
|
57
|
-
marketConditionId: string;
|
|
58
|
-
marketQuestion: string;
|
|
59
|
-
outcomeIndex: number;
|
|
60
|
-
outcomeLabel: string;
|
|
61
|
-
tokenId: string;
|
|
62
|
-
balance: number;
|
|
63
|
-
averageEntryPrice: number;
|
|
64
|
-
currentPrice: number;
|
|
65
|
-
unrealizedPnl: number;
|
|
66
|
-
costBasis: number;
|
|
67
|
-
endDate?: number;
|
|
68
|
-
category?: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// ============================================================
|
|
72
|
-
// MARKETS
|
|
73
|
-
// ============================================================
|
|
74
|
-
|
|
75
|
-
export interface PredictionMarket {
|
|
76
|
-
conditionId: string;
|
|
77
|
-
question: string;
|
|
78
|
-
description: string;
|
|
79
|
-
category: string;
|
|
80
|
-
outcomes: string[];
|
|
81
|
-
outcomeTokenIds: string[];
|
|
82
|
-
outcomePrices: number[];
|
|
83
|
-
volume24h: number;
|
|
84
|
-
liquidity: number;
|
|
85
|
-
endDate: number;
|
|
86
|
-
active: boolean;
|
|
87
|
-
resolved: boolean;
|
|
88
|
-
winningOutcome?: number;
|
|
89
|
-
resolutionSource?: string;
|
|
90
|
-
uniqueTraders?: number;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// ============================================================
|
|
94
|
-
// FILLS & ORDER RESULTS
|
|
95
|
-
// ============================================================
|
|
96
|
-
|
|
97
|
-
export interface PredictionFill {
|
|
98
|
-
orderId: string;
|
|
99
|
-
tradeId: string;
|
|
100
|
-
marketConditionId: string;
|
|
101
|
-
outcomeIndex: number;
|
|
102
|
-
side: 'BUY' | 'SELL';
|
|
103
|
-
price: string;
|
|
104
|
-
size: string;
|
|
105
|
-
fee: string;
|
|
106
|
-
timestamp: number;
|
|
107
|
-
marketQuestion?: string;
|
|
108
|
-
isMaker: boolean;
|
|
109
|
-
tokenId?: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface PredictionOrderResult {
|
|
113
|
-
success: boolean;
|
|
114
|
-
orderId?: string;
|
|
115
|
-
status: 'filled' | 'partially_filled' | 'resting' | 'cancelled' | 'error';
|
|
116
|
-
avgPrice?: number;
|
|
117
|
-
filledSize?: number;
|
|
118
|
-
error?: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// ============================================================
|
|
122
|
-
// ACCOUNT
|
|
123
|
-
// ============================================================
|
|
124
|
-
|
|
125
|
-
export interface PredictionAccountSummary {
|
|
126
|
-
totalExposure: number;
|
|
127
|
-
totalUnrealizedPnl: number;
|
|
128
|
-
openMarketCount: number;
|
|
129
|
-
openPositionCount: number;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ============================================================
|
|
133
|
-
// CONSTANTS
|
|
134
|
-
// ============================================================
|
|
135
|
-
|
|
136
|
-
export const POLYGON_CHAIN_ID = 137;
|
|
137
|
-
export const PREDICTION_INSTRUMENT_PREFIX = 'POLY:';
|
|
138
|
-
export const PREDICTION_FEE_BPS = 20;
|
|
139
|
-
|
|
140
|
-
/** Encode a prediction instrument string: POLY:{conditionId}:{outcomeIndex} */
|
|
141
|
-
export function encodePredictionInstrument(conditionId: string, outcomeIndex: number): string {
|
|
142
|
-
return `${PREDICTION_INSTRUMENT_PREFIX}${conditionId}:${outcomeIndex}`;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** Decode a POLY: instrument string back to components */
|
|
146
|
-
export function decodePredictionInstrument(instrument: string): { conditionId: string; outcomeIndex: number } | null {
|
|
147
|
-
if (!instrument.startsWith(PREDICTION_INSTRUMENT_PREFIX)) return null;
|
|
148
|
-
const parts = instrument.slice(PREDICTION_INSTRUMENT_PREFIX.length).split(':');
|
|
149
|
-
if (parts.length !== 2) return null;
|
|
150
|
-
return { conditionId: parts[0], outcomeIndex: parseInt(parts[1], 10) };
|
|
151
|
-
}
|
package/src/relay.ts
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
import type {
|
|
3
|
-
AgentStatusPayload,
|
|
4
|
-
AgentToAPIMessage,
|
|
5
|
-
APIToAgentMessage,
|
|
6
|
-
RelayCommand,
|
|
7
|
-
TradeSignal,
|
|
8
|
-
MessageType,
|
|
9
|
-
MessageLevel,
|
|
10
|
-
} from '@exagent/sdk';
|
|
11
|
-
import { getLogger } from './logger.js';
|
|
12
|
-
|
|
13
|
-
export interface RelayClientConfig {
|
|
14
|
-
url: string;
|
|
15
|
-
agentId: string;
|
|
16
|
-
token: string;
|
|
17
|
-
heartbeatIntervalMs?: number;
|
|
18
|
-
reconnectMaxAttempts?: number;
|
|
19
|
-
onCommand?: (command: RelayCommand) => void;
|
|
20
|
-
onConnected?: () => void;
|
|
21
|
-
onDisconnected?: () => void;
|
|
22
|
-
onReconnected?: () => void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export class RelayClient {
|
|
26
|
-
private ws: WebSocket | null = null;
|
|
27
|
-
private config: Required<Omit<RelayClientConfig, 'onCommand' | 'onConnected' | 'onDisconnected' | 'onReconnected'>>;
|
|
28
|
-
private heartbeatTimer: ReturnType<typeof setInterval> | null = null;
|
|
29
|
-
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
|
30
|
-
private reconnectAttempts = 0;
|
|
31
|
-
private intentionalClose = false;
|
|
32
|
-
private authenticated = false;
|
|
33
|
-
private lastStatus: AgentStatusPayload | null = null;
|
|
34
|
-
private hasConnectedBefore = false;
|
|
35
|
-
|
|
36
|
-
onCommand?: (command: RelayCommand) => void;
|
|
37
|
-
onConnected?: () => void;
|
|
38
|
-
onDisconnected?: () => void;
|
|
39
|
-
onReconnected?: () => void;
|
|
40
|
-
|
|
41
|
-
constructor(config: RelayClientConfig) {
|
|
42
|
-
this.config = {
|
|
43
|
-
url: config.url,
|
|
44
|
-
agentId: config.agentId,
|
|
45
|
-
token: config.token,
|
|
46
|
-
heartbeatIntervalMs: config.heartbeatIntervalMs ?? 30000,
|
|
47
|
-
reconnectMaxAttempts: config.reconnectMaxAttempts ?? 50,
|
|
48
|
-
};
|
|
49
|
-
this.onCommand = config.onCommand;
|
|
50
|
-
this.onConnected = config.onConnected;
|
|
51
|
-
this.onDisconnected = config.onDisconnected;
|
|
52
|
-
this.onReconnected = config.onReconnected;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
get isConnected(): boolean {
|
|
56
|
-
return this.ws?.readyState === WebSocket.OPEN && this.authenticated;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async connect(): Promise<void> {
|
|
60
|
-
return new Promise((resolve, reject) => {
|
|
61
|
-
try {
|
|
62
|
-
this.intentionalClose = false;
|
|
63
|
-
this.ws = new WebSocket(this.config.url);
|
|
64
|
-
|
|
65
|
-
const timeout = setTimeout(() => {
|
|
66
|
-
if (this.ws && this.ws.readyState !== WebSocket.OPEN) {
|
|
67
|
-
this.ws.terminate();
|
|
68
|
-
reject(new Error('Connection timeout (15s)'));
|
|
69
|
-
}
|
|
70
|
-
}, 15000);
|
|
71
|
-
|
|
72
|
-
this.ws.on('open', () => {
|
|
73
|
-
clearTimeout(timeout);
|
|
74
|
-
this.reconnectAttempts = 0;
|
|
75
|
-
this.authenticate();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
this.ws.on('message', (data: WebSocket.Data) => {
|
|
79
|
-
try {
|
|
80
|
-
const msg = JSON.parse(data.toString()) as APIToAgentMessage;
|
|
81
|
-
this.handleMessage(msg, resolve);
|
|
82
|
-
} catch {
|
|
83
|
-
getLogger().error('relay', 'Failed to parse message');
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
this.ws.on('close', () => {
|
|
88
|
-
this.cleanup();
|
|
89
|
-
this.onDisconnected?.();
|
|
90
|
-
if (!this.intentionalClose) {
|
|
91
|
-
this.scheduleReconnect();
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
this.ws.on('error', (err: Error) => {
|
|
96
|
-
getLogger().error('relay', `WebSocket error: ${err.message}`);
|
|
97
|
-
if (!this.authenticated) {
|
|
98
|
-
clearTimeout(timeout);
|
|
99
|
-
reject(err);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
} catch (err) {
|
|
103
|
-
reject(err);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
disconnect(): void {
|
|
109
|
-
this.intentionalClose = true;
|
|
110
|
-
this.cleanup();
|
|
111
|
-
if (this.ws) {
|
|
112
|
-
this.ws.close();
|
|
113
|
-
this.ws = null;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private authenticate(): void {
|
|
118
|
-
this.send({
|
|
119
|
-
type: 'auth',
|
|
120
|
-
agentId: this.config.agentId,
|
|
121
|
-
token: this.config.token,
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private handleMessage(msg: APIToAgentMessage, onAuth?: (value: void) => void): void {
|
|
126
|
-
switch (msg.type) {
|
|
127
|
-
case 'auth_success':
|
|
128
|
-
this.authenticated = true;
|
|
129
|
-
this.startHeartbeat();
|
|
130
|
-
this.onConnected?.();
|
|
131
|
-
|
|
132
|
-
// Emit reconnected event if this is not the first connection
|
|
133
|
-
if (this.hasConnectedBefore) {
|
|
134
|
-
this.onReconnected?.();
|
|
135
|
-
}
|
|
136
|
-
this.hasConnectedBefore = true;
|
|
137
|
-
|
|
138
|
-
onAuth?.();
|
|
139
|
-
getLogger().info('relay', 'Authenticated', { agentId: this.config.agentId });
|
|
140
|
-
break;
|
|
141
|
-
|
|
142
|
-
case 'auth_error':
|
|
143
|
-
getLogger().error('relay', `Auth failed: ${msg.error}`);
|
|
144
|
-
this.disconnect();
|
|
145
|
-
break;
|
|
146
|
-
|
|
147
|
-
case 'command':
|
|
148
|
-
this.onCommand?.(msg.command);
|
|
149
|
-
break;
|
|
150
|
-
|
|
151
|
-
case 'pong':
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
sendCommandAck(commandId: string, success: boolean, message?: string): void {
|
|
157
|
-
this.send({
|
|
158
|
-
type: 'command_ack',
|
|
159
|
-
agentId: this.config.agentId,
|
|
160
|
-
commandId,
|
|
161
|
-
success,
|
|
162
|
-
message,
|
|
163
|
-
timestamp: Date.now(),
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private send(msg: AgentToAPIMessage | { type: 'auth'; agentId: string; token: string }): void {
|
|
168
|
-
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
169
|
-
this.ws.send(JSON.stringify(msg));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
sendHeartbeat(status: AgentStatusPayload): void {
|
|
174
|
-
this.lastStatus = status;
|
|
175
|
-
this.send({
|
|
176
|
-
type: 'heartbeat',
|
|
177
|
-
agentId: this.config.agentId,
|
|
178
|
-
status,
|
|
179
|
-
timestamp: Date.now(),
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
sendMessage(
|
|
184
|
-
messageType: MessageType,
|
|
185
|
-
level: MessageLevel,
|
|
186
|
-
title: string,
|
|
187
|
-
body: string,
|
|
188
|
-
data?: Record<string, unknown>,
|
|
189
|
-
): void {
|
|
190
|
-
this.send({
|
|
191
|
-
type: 'message',
|
|
192
|
-
agentId: this.config.agentId,
|
|
193
|
-
messageType,
|
|
194
|
-
level,
|
|
195
|
-
title,
|
|
196
|
-
body,
|
|
197
|
-
data,
|
|
198
|
-
timestamp: Date.now(),
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
sendTradeSignal(signal: TradeSignal): void {
|
|
203
|
-
this.send({
|
|
204
|
-
type: 'trade_signal',
|
|
205
|
-
agentId: this.config.agentId,
|
|
206
|
-
signal,
|
|
207
|
-
timestamp: Date.now(),
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
private startHeartbeat(): void {
|
|
212
|
-
this.stopHeartbeat();
|
|
213
|
-
this.heartbeatTimer = setInterval(() => {
|
|
214
|
-
if (this.lastStatus) {
|
|
215
|
-
this.sendHeartbeat(this.lastStatus);
|
|
216
|
-
}
|
|
217
|
-
}, this.config.heartbeatIntervalMs);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private stopHeartbeat(): void {
|
|
221
|
-
if (this.heartbeatTimer) {
|
|
222
|
-
clearInterval(this.heartbeatTimer);
|
|
223
|
-
this.heartbeatTimer = null;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
private cleanup(): void {
|
|
228
|
-
this.stopHeartbeat();
|
|
229
|
-
this.authenticated = false;
|
|
230
|
-
if (this.reconnectTimer) {
|
|
231
|
-
clearTimeout(this.reconnectTimer);
|
|
232
|
-
this.reconnectTimer = null;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
private scheduleReconnect(): void {
|
|
237
|
-
if (this.reconnectAttempts >= this.config.reconnectMaxAttempts) {
|
|
238
|
-
getLogger().error('relay', 'Max reconnect attempts reached', { max: this.config.reconnectMaxAttempts });
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
|
|
243
|
-
this.reconnectAttempts++;
|
|
244
|
-
getLogger().info('relay', 'Reconnecting', { delayMs: delay, attempt: this.reconnectAttempts });
|
|
245
|
-
|
|
246
|
-
this.reconnectTimer = setTimeout(async () => {
|
|
247
|
-
try {
|
|
248
|
-
await this.connect();
|
|
249
|
-
} catch (err) {
|
|
250
|
-
getLogger().error('relay', `Reconnect failed: ${(err as Error).message}`);
|
|
251
|
-
}
|
|
252
|
-
}, delay);
|
|
253
|
-
}
|
|
254
|
-
}
|