@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
package/src/chains.ts DELETED
@@ -1,105 +0,0 @@
1
- import { type Chain, base, arbitrum, polygon, mainnet } from 'viem/chains';
2
-
3
- export interface ChainConfig {
4
- chainId: number;
5
- name: string;
6
- viemChain: Chain;
7
- rpcUrl: string;
8
- nativeCurrency: string;
9
- blockExplorer: string;
10
- wethAddress: `0x${string}`;
11
- usdcAddress: `0x${string}`;
12
- dexRouters: Record<string, `0x${string}`>;
13
- uniswapQuoter?: `0x${string}`;
14
- acrossSpokePool?: `0x${string}`;
15
- }
16
-
17
- export const CHAIN_CONFIGS: Record<string, ChainConfig> = {
18
- base: {
19
- chainId: 8453,
20
- name: 'base',
21
- viemChain: base,
22
- rpcUrl: 'https://mainnet.base.org',
23
- nativeCurrency: 'ETH',
24
- blockExplorer: 'https://basescan.org',
25
- wethAddress: '0x4200000000000000000000000000000000000006',
26
- usdcAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
27
- dexRouters: {
28
- uniswap: '0x2626664c2603336E57B271c5C0b26F421741e481',
29
- aerodrome: '0xcF77a3Ba9A5CA399B7c97c74d54e5b1Beb874E43',
30
- },
31
- uniswapQuoter: '0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a',
32
- acrossSpokePool: '0x09aea4b2242abC8bb4BB78D537A67a245A7bEC64',
33
- },
34
- ethereum: {
35
- chainId: 1,
36
- name: 'ethereum',
37
- viemChain: mainnet,
38
- rpcUrl: 'https://eth.llamarpc.com',
39
- nativeCurrency: 'ETH',
40
- blockExplorer: 'https://etherscan.io',
41
- wethAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
42
- usdcAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
43
- dexRouters: {
44
- uniswap: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
45
- },
46
- uniswapQuoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
47
- acrossSpokePool: '0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5',
48
- },
49
- arbitrum: {
50
- chainId: 42161,
51
- name: 'arbitrum',
52
- viemChain: arbitrum,
53
- rpcUrl: 'https://arb1.arbitrum.io/rpc',
54
- nativeCurrency: 'ETH',
55
- blockExplorer: 'https://arbiscan.io',
56
- wethAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
57
- usdcAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
58
- dexRouters: {
59
- uniswap: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
60
- },
61
- uniswapQuoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
62
- acrossSpokePool: '0xe35e9842fceaCA96570B734083f4a58e8F7C5f2A',
63
- },
64
- polygon: {
65
- chainId: 137,
66
- name: 'polygon',
67
- viemChain: polygon,
68
- rpcUrl: 'https://polygon-bor-rpc.publicnode.com',
69
- nativeCurrency: 'POL',
70
- blockExplorer: 'https://polygonscan.com',
71
- wethAddress: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
72
- usdcAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
73
- dexRouters: {
74
- uniswap: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
75
- },
76
- uniswapQuoter: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
77
- acrossSpokePool: '0x9295ee1d8C5b022Be115A2AD3c30C72E34e7F096',
78
- },
79
- };
80
-
81
- /**
82
- * Apply custom RPC endpoint overrides. Call once at startup.
83
- * Accepts a map of chain name (or chain ID string) → RPC URL.
84
- */
85
- export function applyRpcOverrides(overrides: Record<string, string>): void {
86
- for (const [key, url] of Object.entries(overrides)) {
87
- // Support both chain name ("base") and chain ID ("8453")
88
- const chain = CHAIN_CONFIGS[key.toLowerCase()]
89
- ?? Object.values(CHAIN_CONFIGS).find(c => c.chainId.toString() === key);
90
-
91
- if (chain) {
92
- chain.rpcUrl = url;
93
- console.log(`[chains] RPC override: ${chain.name} → ${url}`);
94
- } else {
95
- console.warn(`[chains] Unknown chain for RPC override: ${key}`);
96
- }
97
- }
98
- }
99
-
100
- export function getChainConfig(nameOrId: string | number): ChainConfig | undefined {
101
- if (typeof nameOrId === 'number') {
102
- return Object.values(CHAIN_CONFIGS).find(c => c.chainId === nameOrId);
103
- }
104
- return CHAIN_CONFIGS[nameOrId.toLowerCase()];
105
- }
package/src/cli.ts DELETED
@@ -1,250 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import { loadConfig, readConfigFile, writeConfigFile, updateSecureStore, writeSampleConfig } from './config.js';
4
- import { AgentRuntime } from './runtime.js';
5
- import { listTemplates } from './strategy/index.js';
6
- import { ensureLocalSetup, promptSecretPassword } from './setup.js';
7
- import { printBanner, printDone, printError, printInfo, printSuccess, pc } from './ui.js';
8
- import * as clack from '@clack/prompts';
9
-
10
- const program = new Command();
11
-
12
- program
13
- .name('exagent')
14
- .description('Exagent — LLM trading agent runtime')
15
- .version('0.3.5');
16
-
17
- program
18
- .command('init')
19
- .description('Create a sample agent configuration file')
20
- .option('--agent-id <id>', 'Agent ID (from dashboard)', 'my-agent')
21
- .option('--api-url <url>', 'API server URL', 'http://localhost:3002')
22
- .option('--config <path>', 'Config file path', 'agent-config.json')
23
- .action((opts) => {
24
- printBanner();
25
- writeSampleConfig(opts.agentId, opts.apiUrl, opts.config);
26
- printDone(`Created ${pc.cyan(opts.config)}`);
27
- console.log();
28
- console.log(` Edit only the public strategy/venue/risk settings.`);
29
- console.log(` Then run: ${pc.cyan(`exagent setup --config ${opts.config}`)}`);
30
- console.log();
31
- });
32
-
33
- program
34
- .command('setup')
35
- .description('Run first-time secure local setup for agent secrets')
36
- .option('--config <path>', 'Config file path', 'agent-config.json')
37
- .action(async (opts) => {
38
- try {
39
- await ensureLocalSetup(opts.config);
40
- } catch (err) {
41
- printError((err as Error).message);
42
- process.exit(1);
43
- }
44
- });
45
-
46
- program
47
- .command('run')
48
- .description('Start the agent')
49
- .option('--config <path>', 'Config file path', 'agent-config.json')
50
- .action(async (opts) => {
51
- try {
52
- await ensureLocalSetup(opts.config);
53
- printBanner();
54
- const config = await loadConfig(opts.config, {
55
- getSecretPassword: async () => promptSecretPassword(),
56
- });
57
- printDone(`Agent ${pc.cyan(config.agentId)} starting...`);
58
- console.log();
59
- const runtime = new AgentRuntime(config);
60
- await runtime.start();
61
-
62
- // Keep the process running
63
- await new Promise(() => {});
64
- } catch (err) {
65
- printError((err as Error).message);
66
- process.exit(1);
67
- }
68
- });
69
-
70
- program
71
- .command('templates')
72
- .description('List available strategy templates')
73
- .action(() => {
74
- printBanner();
75
- const templates = listTemplates();
76
- console.log(pc.bold(' Strategy Templates'));
77
- console.log();
78
- for (const t of templates) {
79
- console.log(` ${pc.cyan(t.id)}`);
80
- console.log(` ${t.name} — ${pc.dim(t.description)}`);
81
- console.log(` ${pc.dim(`Risk: ${t.riskLevel} | Venues: ${t.venues.join(', ') || 'any'}`)}`);
82
- console.log();
83
- }
84
- });
85
-
86
- program
87
- .command('status')
88
- .description('Check agent status')
89
- .option('--config <path>', 'Config file path', 'agent-config.json')
90
- .action(async (opts) => {
91
- try {
92
- await ensureLocalSetup(opts.config);
93
- printBanner();
94
- const config = await loadConfig(opts.config, {
95
- getSecretPassword: async () => promptSecretPassword(),
96
- });
97
- const res = await fetch(`${config.apiUrl}/v1/agents/${config.agentId}`, {
98
- headers: { Authorization: `Bearer ${config.apiToken}` },
99
- });
100
-
101
- if (!res.ok) {
102
- printError(`API error: ${res.status}`);
103
- process.exit(1);
104
- }
105
-
106
- const agent = await res.json() as Record<string, unknown>;
107
- const name = (agent.name as string) || config.agentId;
108
- const status = (agent.status as string) || 'unknown';
109
-
110
- const statusColor = status === 'online' ? pc.green : status === 'error' ? pc.red : pc.yellow;
111
-
112
- printSuccess(name, [
113
- `${pc.dim('Status:')} ${statusColor(status)}`,
114
- `${pc.dim('Agent:')} ${pc.cyan(config.agentId)}`,
115
- `${pc.dim('API:')} ${pc.dim(config.apiUrl)}`,
116
- ]);
117
- } catch (err) {
118
- printError((err as Error).message);
119
- process.exit(1);
120
- }
121
- });
122
-
123
- import { LLM_PROVIDERS, getProvider, providerRequiresApiKey } from './llm-providers.js';
124
-
125
- program
126
- .command('config')
127
- .description('Change LLM provider, model, or API key')
128
- .option('--config <path>', 'Config file path', 'agent-config.json')
129
- .action(async (opts) => {
130
- try {
131
- printBanner();
132
- const config = readConfigFile(opts.config);
133
- const secureStorePath = config.secrets?.secureStorePath;
134
-
135
- if (!secureStorePath) {
136
- printError('No secure store found. Run setup first: npx exagent setup');
137
- process.exit(1);
138
- }
139
-
140
- clack.intro(pc.bold('Agent Configuration'));
141
-
142
- // Decrypt current secrets
143
- const password = await promptSecretPassword();
144
- const currentConfig = await loadConfig(opts.config, {
145
- getSecretPassword: async () => password,
146
- });
147
-
148
- // Show current LLM settings
149
- const currentProvider = currentConfig.llm.provider;
150
- const currentModel = currentConfig.llm.model || 'not set';
151
- const currentKey = currentConfig.llm.apiKey;
152
- const maskedKey = currentKey
153
- ? `${currentKey.slice(0, 7)}...${currentKey.slice(-4)}`
154
- : 'not set';
155
-
156
- printInfo(`Provider: ${pc.cyan(currentProvider)}`);
157
- printInfo(`Model: ${pc.cyan(currentModel)}`);
158
- printInfo(`API key: ${pc.dim(maskedKey)}`);
159
- console.log();
160
-
161
- const action = await clack.select({
162
- message: 'What would you like to change?',
163
- options: [
164
- { value: 'key', label: 'LLM API key' },
165
- { value: 'all', label: 'Provider, model, and API key' },
166
- ],
167
- });
168
- if (clack.isCancel(action)) {
169
- clack.cancel('Cancelled.');
170
- process.exit(0);
171
- }
172
-
173
- let newProvider: string = currentProvider;
174
- let newModel: string = currentModel;
175
-
176
- if (action === 'all') {
177
- const selectedProvider = await clack.select({
178
- message: 'LLM provider:',
179
- options: LLM_PROVIDERS.map(p => ({ value: p.id, label: p.label })),
180
- initialValue: currentProvider || undefined,
181
- });
182
- if (clack.isCancel(selectedProvider)) {
183
- clack.cancel('Cancelled.');
184
- process.exit(0);
185
- }
186
- newProvider = selectedProvider;
187
-
188
- const provider = getProvider(newProvider);
189
- const modelOptions = provider
190
- ? provider.models.map(m => ({ value: m.id, label: m.label }))
191
- : [{ value: currentModel, label: currentModel }];
192
-
193
- const selectedModel = await clack.select({
194
- message: 'LLM model:',
195
- options: modelOptions,
196
- initialValue: currentModel || undefined,
197
- });
198
- if (clack.isCancel(selectedModel)) {
199
- clack.cancel('Cancelled.');
200
- process.exit(0);
201
- }
202
- newModel = selectedModel;
203
- }
204
-
205
- let newKey: string | undefined;
206
- if (providerRequiresApiKey(newProvider)) {
207
- const enteredKey = await clack.password({
208
- message: 'New LLM API key:',
209
- validate: (val) => {
210
- if (!val?.trim()) return 'API key is required.';
211
- if (val.length < 10) return 'API key seems too short.';
212
- },
213
- });
214
- if (clack.isCancel(enteredKey)) {
215
- clack.cancel('Cancelled.');
216
- process.exit(0);
217
- }
218
- newKey = enteredKey;
219
- } else {
220
- printInfo('Ollama uses your local server; no API key needed.');
221
- }
222
-
223
- // Update secure store with new API key
224
- updateSecureStore(secureStorePath, password, { llmApiKey: newKey });
225
-
226
- // Update config file with new provider/model
227
- const updatedConfig = readConfigFile(opts.config);
228
- updatedConfig.llm = {
229
- ...updatedConfig.llm,
230
- provider: newProvider as typeof updatedConfig.llm.provider,
231
- model: newModel,
232
- };
233
- writeConfigFile(opts.config, updatedConfig);
234
-
235
- clack.outro(pc.green('Configuration updated'));
236
-
237
- printSuccess('Updated', [
238
- `${pc.dim('Provider:')} ${pc.cyan(newProvider)}`,
239
- `${pc.dim('Model:')} ${pc.cyan(newModel)}`,
240
- `${pc.dim('API key:')} ${newKey ? pc.dim(`${newKey.slice(0, 7)}...${newKey.slice(-4)}`) : pc.dim('not required')}`,
241
- '',
242
- `Run ${pc.cyan('npx exagent run')} to start with the new configuration.`,
243
- ]);
244
- } catch (err) {
245
- printError((err as Error).message);
246
- process.exit(1);
247
- }
248
- });
249
-
250
- program.parse();