@exagent/agent 0.1.0 → 0.1.2
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-5PQNJMLK.mjs +1816 -0
- package/dist/chunk-7WZIS3RL.mjs +1841 -0
- package/dist/chunk-HXDTXMNM.mjs +1828 -0
- package/dist/chunk-JKVX2ZE2.mjs +2593 -0
- package/dist/chunk-KJJGA46E.mjs +2666 -0
- package/dist/chunk-S43QPE3R.mjs +1615 -0
- package/dist/chunk-WDT62ZH4.mjs +1615 -0
- package/dist/chunk-YNSV3HXM.mjs +2667 -0
- package/dist/cli.js +1257 -47
- package/dist/cli.mjs +110 -6
- package/dist/index.d.mts +301 -7
- package/dist/index.d.ts +301 -7
- package/dist/index.js +1159 -33
- package/dist/index.mjs +21 -1
- package/package.json +5 -2
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AgentRuntime,
|
|
4
|
+
encryptEnvFile,
|
|
4
5
|
getAllStrategyTemplates,
|
|
5
6
|
loadConfig,
|
|
7
|
+
loadSecureEnv,
|
|
6
8
|
validateConfig
|
|
7
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KJJGA46E.mjs";
|
|
8
10
|
|
|
9
11
|
// src/cli.ts
|
|
10
12
|
import { Command } from "commander";
|
|
@@ -58,6 +60,10 @@ function prompt(question, hidden = false) {
|
|
|
58
60
|
}
|
|
59
61
|
async function checkFirstRunSetup(configPath) {
|
|
60
62
|
const envPath = path.join(path.dirname(configPath), ".env");
|
|
63
|
+
const encPath = envPath + ".enc";
|
|
64
|
+
if (fs.existsSync(encPath)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
61
67
|
if (fs.existsSync(envPath)) {
|
|
62
68
|
const envContent2 = fs.readFileSync(envPath, "utf-8");
|
|
63
69
|
const hasPrivateKey = envContent2.includes("EXAGENT_PRIVATE_KEY=") && !envContent2.includes("EXAGENT_PRIVATE_KEY=\n") && !envContent2.includes("EXAGENT_PRIVATE_KEY=$");
|
|
@@ -186,10 +192,43 @@ ${llmEnvVar}EXAGENT_LLM_MODEL=${config.llm?.model || ""}
|
|
|
186
192
|
fs.writeFileSync(envPath, envContent, { mode: 384 });
|
|
187
193
|
console.log("");
|
|
188
194
|
console.log("=".repeat(60));
|
|
189
|
-
console.log("
|
|
195
|
+
console.log(" ENCRYPT YOUR SECRETS");
|
|
190
196
|
console.log("=".repeat(60));
|
|
191
197
|
console.log("");
|
|
192
|
-
console.log(" Your .env file
|
|
198
|
+
console.log(" Your .env file contains private keys and API credentials.");
|
|
199
|
+
console.log(" Encrypting it protects you if someone accesses your files.");
|
|
200
|
+
console.log("");
|
|
201
|
+
console.log(" Press Enter to skip (you can encrypt later with: npx @exagent/agent encrypt)");
|
|
202
|
+
console.log("");
|
|
203
|
+
const passphrase = await prompt(" Choose encryption passphrase (or Enter to skip): ", true);
|
|
204
|
+
if (passphrase && passphrase.length >= 4) {
|
|
205
|
+
const confirmPassphrase = await prompt(" Confirm passphrase: ", true);
|
|
206
|
+
if (passphrase === confirmPassphrase) {
|
|
207
|
+
console.log("");
|
|
208
|
+
encryptEnvFile(envPath, passphrase, true);
|
|
209
|
+
process.env.EXAGENT_PASSPHRASE = passphrase;
|
|
210
|
+
console.log(" Your secrets are encrypted. Plaintext .env has been deleted.");
|
|
211
|
+
console.log("");
|
|
212
|
+
console.log(" Remember your passphrase \u2014 you need it every time the agent starts.");
|
|
213
|
+
console.log(" Or set: export EXAGENT_PASSPHRASE=<your-passphrase>");
|
|
214
|
+
} else {
|
|
215
|
+
console.log("");
|
|
216
|
+
console.log(" Passphrases did not match. Skipping encryption.");
|
|
217
|
+
console.log(" Run: npx @exagent/agent encrypt");
|
|
218
|
+
}
|
|
219
|
+
} else if (passphrase && passphrase.length < 4) {
|
|
220
|
+
console.log("");
|
|
221
|
+
console.log(" Passphrase too short (min 4 chars). Skipping encryption.");
|
|
222
|
+
console.log(" Run: npx @exagent/agent encrypt");
|
|
223
|
+
} else {
|
|
224
|
+
console.log("");
|
|
225
|
+
console.log(" Skipped encryption. Your .env is stored in plaintext.");
|
|
226
|
+
console.log(" To encrypt later: npx @exagent/agent encrypt --delete");
|
|
227
|
+
}
|
|
228
|
+
console.log("");
|
|
229
|
+
console.log("=".repeat(60));
|
|
230
|
+
console.log(" SETUP COMPLETE");
|
|
231
|
+
console.log("=".repeat(60));
|
|
193
232
|
console.log("");
|
|
194
233
|
console.log(` Wallet: ${walletAddress}`);
|
|
195
234
|
console.log(` LLM: ${llmProvider}`);
|
|
@@ -201,11 +240,20 @@ ${llmEnvVar}EXAGENT_LLM_MODEL=${config.llm?.model || ""}
|
|
|
201
240
|
console.log("");
|
|
202
241
|
console.log(" The agent will now start...");
|
|
203
242
|
console.log("");
|
|
204
|
-
|
|
243
|
+
if (!process.env.EXAGENT_PASSPHRASE) {
|
|
244
|
+
loadEnvFile({ path: envPath, override: true });
|
|
245
|
+
}
|
|
205
246
|
}
|
|
206
|
-
program.command("run").description("Start the trading agent").option("-c, --config <path>", "Path to agent-config.json", "agent-config.json").action(async (options) => {
|
|
247
|
+
program.command("run").description("Start the trading agent").option("-c, --config <path>", "Path to agent-config.json", "agent-config.json").option("-p, --passphrase <passphrase>", "Passphrase to decrypt .env.enc").action(async (options) => {
|
|
207
248
|
try {
|
|
208
249
|
await checkFirstRunSetup(options.config);
|
|
250
|
+
const configDir = path.dirname(
|
|
251
|
+
options.config.startsWith("/") ? options.config : path.join(process.cwd(), options.config)
|
|
252
|
+
);
|
|
253
|
+
const usedEncrypted = loadSecureEnv(configDir, options.passphrase);
|
|
254
|
+
if (usedEncrypted) {
|
|
255
|
+
console.log("Loaded encrypted environment (.env.enc)");
|
|
256
|
+
}
|
|
209
257
|
console.log("Loading configuration...");
|
|
210
258
|
const config = loadConfig(options.config);
|
|
211
259
|
validateConfig(config);
|
|
@@ -314,9 +362,65 @@ program.command("api-keys").description("Show how to get API keys for each LLM p
|
|
|
314
362
|
console.log("OLLAMA (Local - No API Key Required)");
|
|
315
363
|
console.log(" Install: https://ollama.com/download");
|
|
316
364
|
console.log(" Run: ollama serve");
|
|
317
|
-
console.log(" Pull model: ollama pull
|
|
365
|
+
console.log(" Pull model: ollama pull llama3.2");
|
|
318
366
|
console.log("");
|
|
319
367
|
console.log("Note: Your API keys are stored locally in .env and never sent to Exagent servers.");
|
|
320
368
|
console.log("");
|
|
321
369
|
});
|
|
370
|
+
program.command("encrypt").description("Encrypt .env file to .env.enc for secure storage").option("-d, --dir <path>", "Directory containing .env file", ".").option("--delete", "Delete plaintext .env after encryption", false).action(async (options) => {
|
|
371
|
+
try {
|
|
372
|
+
const dir = options.dir.startsWith("/") ? options.dir : path.join(process.cwd(), options.dir);
|
|
373
|
+
const envPath = path.join(dir, ".env");
|
|
374
|
+
if (!fs.existsSync(envPath)) {
|
|
375
|
+
console.error("No .env file found in", dir);
|
|
376
|
+
process.exit(1);
|
|
377
|
+
}
|
|
378
|
+
const encPath = envPath + ".enc";
|
|
379
|
+
if (fs.existsSync(encPath)) {
|
|
380
|
+
const overwrite = await prompt(" .env.enc already exists. Overwrite? (y/n): ");
|
|
381
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
382
|
+
console.log("Aborted.");
|
|
383
|
+
process.exit(0);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
console.log("");
|
|
387
|
+
console.log("=".repeat(50));
|
|
388
|
+
console.log(" ENCRYPT ENVIRONMENT FILE");
|
|
389
|
+
console.log("=".repeat(50));
|
|
390
|
+
console.log("");
|
|
391
|
+
console.log(" This will encrypt your .env file using a passphrase.");
|
|
392
|
+
console.log(" You will need this passphrase every time the agent starts.");
|
|
393
|
+
console.log("");
|
|
394
|
+
console.log(" Alternatively, set EXAGENT_PASSPHRASE env var to skip");
|
|
395
|
+
console.log(" the prompt on startup.");
|
|
396
|
+
console.log("");
|
|
397
|
+
const passphrase = await prompt(" Enter encryption passphrase: ", true);
|
|
398
|
+
if (!passphrase || passphrase.length < 4) {
|
|
399
|
+
console.error(" Passphrase must be at least 4 characters.");
|
|
400
|
+
process.exit(1);
|
|
401
|
+
}
|
|
402
|
+
const confirm = await prompt(" Confirm passphrase: ", true);
|
|
403
|
+
if (passphrase !== confirm) {
|
|
404
|
+
console.error(" Passphrases do not match.");
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
console.log("");
|
|
408
|
+
encryptEnvFile(envPath, passphrase, options.delete);
|
|
409
|
+
console.log("");
|
|
410
|
+
console.log(" Encrypted file saved to: .env.enc");
|
|
411
|
+
if (options.delete) {
|
|
412
|
+
console.log(" Plaintext .env has been deleted.");
|
|
413
|
+
} else {
|
|
414
|
+
console.log(" Your plaintext .env file is still present.");
|
|
415
|
+
console.log(" Run with --delete to remove it after encryption.");
|
|
416
|
+
}
|
|
417
|
+
console.log("");
|
|
418
|
+
console.log(" To use: npx @exagent/agent run --passphrase <your-passphrase>");
|
|
419
|
+
console.log(" Or set: export EXAGENT_PASSPHRASE=<your-passphrase>");
|
|
420
|
+
console.log("");
|
|
421
|
+
} catch (error) {
|
|
422
|
+
console.error("Error:", error instanceof Error ? error.message : error);
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
322
426
|
program.parse();
|
package/dist/index.d.mts
CHANGED
|
@@ -71,6 +71,20 @@ declare const VaultConfigSchema: z.ZodObject<{
|
|
|
71
71
|
preferVaultTrading?: boolean | undefined;
|
|
72
72
|
}>;
|
|
73
73
|
type VaultConfig = z.infer<typeof VaultConfigSchema>;
|
|
74
|
+
declare const RelayConfigSchema: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
76
|
+
apiUrl: z.ZodString;
|
|
77
|
+
heartbeatIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
78
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
|
+
enabled: boolean;
|
|
80
|
+
apiUrl: string;
|
|
81
|
+
heartbeatIntervalMs: number;
|
|
82
|
+
}, {
|
|
83
|
+
apiUrl: string;
|
|
84
|
+
enabled?: boolean | undefined;
|
|
85
|
+
heartbeatIntervalMs?: number | undefined;
|
|
86
|
+
}>>;
|
|
87
|
+
type RelayConfig$1 = z.infer<typeof RelayConfigSchema>;
|
|
74
88
|
declare const AgentConfigSchema: z.ZodObject<{
|
|
75
89
|
agentId: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
76
90
|
name: z.ZodString;
|
|
@@ -143,6 +157,19 @@ declare const AgentConfigSchema: z.ZodObject<{
|
|
|
143
157
|
feeRecipient?: string | undefined;
|
|
144
158
|
preferVaultTrading?: boolean | undefined;
|
|
145
159
|
}>>;
|
|
160
|
+
relay: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
162
|
+
apiUrl: z.ZodString;
|
|
163
|
+
heartbeatIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
164
|
+
}, "strip", z.ZodTypeAny, {
|
|
165
|
+
enabled: boolean;
|
|
166
|
+
apiUrl: string;
|
|
167
|
+
heartbeatIntervalMs: number;
|
|
168
|
+
}, {
|
|
169
|
+
apiUrl: string;
|
|
170
|
+
enabled?: boolean | undefined;
|
|
171
|
+
heartbeatIntervalMs?: number | undefined;
|
|
172
|
+
}>>;
|
|
146
173
|
allowedTokens: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
147
174
|
}, "strip", z.ZodTypeAny, {
|
|
148
175
|
agentId: string | number;
|
|
@@ -174,6 +201,11 @@ declare const AgentConfigSchema: z.ZodObject<{
|
|
|
174
201
|
wallet?: {
|
|
175
202
|
setup: "generate" | "provide";
|
|
176
203
|
} | undefined;
|
|
204
|
+
relay?: {
|
|
205
|
+
enabled: boolean;
|
|
206
|
+
apiUrl: string;
|
|
207
|
+
heartbeatIntervalMs: number;
|
|
208
|
+
} | undefined;
|
|
177
209
|
allowedTokens?: string[] | undefined;
|
|
178
210
|
}, {
|
|
179
211
|
agentId: string | number;
|
|
@@ -205,6 +237,11 @@ declare const AgentConfigSchema: z.ZodObject<{
|
|
|
205
237
|
feeRecipient?: string | undefined;
|
|
206
238
|
preferVaultTrading?: boolean | undefined;
|
|
207
239
|
} | undefined;
|
|
240
|
+
relay?: {
|
|
241
|
+
apiUrl: string;
|
|
242
|
+
enabled?: boolean | undefined;
|
|
243
|
+
heartbeatIntervalMs?: number | undefined;
|
|
244
|
+
} | undefined;
|
|
208
245
|
allowedTokens?: string[] | undefined;
|
|
209
246
|
}>;
|
|
210
247
|
type AgentConfig = z.infer<typeof AgentConfigSchema>;
|
|
@@ -358,6 +395,51 @@ declare class VaultManager {
|
|
|
358
395
|
}>;
|
|
359
396
|
}
|
|
360
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Relay Types
|
|
400
|
+
*
|
|
401
|
+
* Shared types for the command center relay protocol.
|
|
402
|
+
* Used by both the SDK relay client and the API relay service.
|
|
403
|
+
*/
|
|
404
|
+
type AgentMode = 'idle' | 'trading';
|
|
405
|
+
type CommandType = 'start_trading' | 'stop_trading' | 'update_risk_params' | 'update_trading_interval' | 'create_vault' | 'refresh_status' | 'shutdown';
|
|
406
|
+
interface RelayCommand {
|
|
407
|
+
id: string;
|
|
408
|
+
type: CommandType;
|
|
409
|
+
params?: Record<string, unknown>;
|
|
410
|
+
}
|
|
411
|
+
type MessageType = 'trade_executed' | 'trade_failed' | 'funds_low' | 'risk_limit_hit' | 'vault_created' | 'config_updated' | 'llm_error' | 'command_result' | 'system';
|
|
412
|
+
type MessageLevel = 'info' | 'warning' | 'error' | 'success';
|
|
413
|
+
interface AgentStatusPayload {
|
|
414
|
+
mode: AgentMode;
|
|
415
|
+
agentId: string;
|
|
416
|
+
wallet?: string;
|
|
417
|
+
cycleCount?: number;
|
|
418
|
+
lastCycleAt?: number;
|
|
419
|
+
tradingIntervalMs?: number;
|
|
420
|
+
portfolioValue?: number;
|
|
421
|
+
ethBalance?: string;
|
|
422
|
+
llm?: {
|
|
423
|
+
provider: string;
|
|
424
|
+
model: string;
|
|
425
|
+
};
|
|
426
|
+
risk?: {
|
|
427
|
+
dailyPnL: number;
|
|
428
|
+
dailyLossLimit: number;
|
|
429
|
+
isLimitHit: boolean;
|
|
430
|
+
};
|
|
431
|
+
vault?: {
|
|
432
|
+
policy: string;
|
|
433
|
+
hasVault: boolean;
|
|
434
|
+
vaultAddress: string | null;
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
interface RelayConfig {
|
|
438
|
+
enabled: boolean;
|
|
439
|
+
apiUrl: string;
|
|
440
|
+
heartbeatIntervalMs?: number;
|
|
441
|
+
}
|
|
442
|
+
|
|
361
443
|
/**
|
|
362
444
|
* Agent Runtime
|
|
363
445
|
*
|
|
@@ -365,7 +447,9 @@ declare class VaultManager {
|
|
|
365
447
|
* 1. Initializes connection to blockchain
|
|
366
448
|
* 2. Ensures wallet is linked to agent identity
|
|
367
449
|
* 3. Loads user's strategy
|
|
368
|
-
* 4.
|
|
450
|
+
* 4. Connects to the command center relay
|
|
451
|
+
* 5. Enters idle mode (waiting for start command from website)
|
|
452
|
+
* 6. Runs the trading loop when commanded
|
|
369
453
|
*/
|
|
370
454
|
declare class AgentRuntime {
|
|
371
455
|
private config;
|
|
@@ -376,26 +460,38 @@ declare class AgentRuntime {
|
|
|
376
460
|
private riskManager;
|
|
377
461
|
private marketData;
|
|
378
462
|
private vaultManager;
|
|
463
|
+
private relay;
|
|
379
464
|
private isRunning;
|
|
465
|
+
private mode;
|
|
380
466
|
private configHash;
|
|
381
467
|
private lastVaultCheck;
|
|
468
|
+
private cycleCount;
|
|
469
|
+
private lastCycleAt;
|
|
470
|
+
private processAlive;
|
|
382
471
|
private readonly VAULT_CHECK_INTERVAL;
|
|
383
472
|
constructor(config: RuntimeConfig);
|
|
384
473
|
/**
|
|
385
474
|
* Initialize the agent runtime
|
|
386
475
|
*/
|
|
387
476
|
initialize(): Promise<void>;
|
|
477
|
+
/**
|
|
478
|
+
* Initialize the relay client for command center connectivity
|
|
479
|
+
*/
|
|
480
|
+
private initializeRelay;
|
|
388
481
|
/**
|
|
389
482
|
* Initialize the vault manager based on config
|
|
390
483
|
*/
|
|
391
484
|
private initializeVaultManager;
|
|
392
485
|
/**
|
|
393
|
-
* Ensure the current wallet is linked to the agent
|
|
486
|
+
* Ensure the current wallet is linked to the agent.
|
|
487
|
+
* If the trading wallet differs from the owner, enters a recovery loop
|
|
488
|
+
* that waits for the owner to link it from the website.
|
|
394
489
|
*/
|
|
395
490
|
private ensureWalletLinked;
|
|
396
491
|
/**
|
|
397
|
-
* Sync the LLM config hash to chain for epoch tracking
|
|
398
|
-
*
|
|
492
|
+
* Sync the LLM config hash to chain for epoch tracking.
|
|
493
|
+
* If the wallet has insufficient gas, enters a recovery loop
|
|
494
|
+
* that waits for the user to fund the wallet.
|
|
399
495
|
*/
|
|
400
496
|
private syncConfigHash;
|
|
401
497
|
/**
|
|
@@ -403,19 +499,35 @@ declare class AgentRuntime {
|
|
|
403
499
|
*/
|
|
404
500
|
getConfigHash(): `0x${string}`;
|
|
405
501
|
/**
|
|
406
|
-
* Start the
|
|
502
|
+
* Start the agent in daemon mode.
|
|
503
|
+
* The agent enters idle mode and waits for commands from the command center.
|
|
504
|
+
* Trading begins only when a start_trading command is received.
|
|
505
|
+
*
|
|
506
|
+
* If relay is not configured, falls back to immediate trading mode.
|
|
407
507
|
*/
|
|
408
508
|
run(): Promise<void>;
|
|
509
|
+
/**
|
|
510
|
+
* Handle a command from the command center
|
|
511
|
+
*/
|
|
512
|
+
private handleCommand;
|
|
513
|
+
/**
|
|
514
|
+
* Send current status to the relay
|
|
515
|
+
*/
|
|
516
|
+
private sendRelayStatus;
|
|
409
517
|
/**
|
|
410
518
|
* Run a single trading cycle
|
|
411
519
|
*/
|
|
412
520
|
private runCycle;
|
|
521
|
+
/**
|
|
522
|
+
* Check if ETH balance is below threshold and notify
|
|
523
|
+
*/
|
|
524
|
+
private checkFundsLow;
|
|
413
525
|
/**
|
|
414
526
|
* Check for vault auto-creation based on policy
|
|
415
527
|
*/
|
|
416
528
|
private checkVaultAutoCreation;
|
|
417
529
|
/**
|
|
418
|
-
* Stop the
|
|
530
|
+
* Stop the agent process completely
|
|
419
531
|
*/
|
|
420
532
|
stop(): void;
|
|
421
533
|
/**
|
|
@@ -432,6 +544,7 @@ declare class AgentRuntime {
|
|
|
432
544
|
*/
|
|
433
545
|
getStatus(): {
|
|
434
546
|
isRunning: boolean;
|
|
547
|
+
mode: AgentMode;
|
|
435
548
|
agentId: number;
|
|
436
549
|
wallet: string;
|
|
437
550
|
llm: {
|
|
@@ -449,6 +562,10 @@ declare class AgentRuntime {
|
|
|
449
562
|
hasVault: boolean;
|
|
450
563
|
vaultAddress: string | null;
|
|
451
564
|
};
|
|
565
|
+
relay: {
|
|
566
|
+
connected: boolean;
|
|
567
|
+
};
|
|
568
|
+
cycleCount: number;
|
|
452
569
|
};
|
|
453
570
|
/**
|
|
454
571
|
* Get detailed vault status (async)
|
|
@@ -516,6 +633,58 @@ declare class AnthropicAdapter extends BaseLLMAdapter {
|
|
|
516
633
|
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
517
634
|
}
|
|
518
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Google AI (Gemini) LLM Adapter
|
|
638
|
+
* Uses the Gemini REST API directly (no SDK dependency)
|
|
639
|
+
*/
|
|
640
|
+
declare class GoogleAdapter extends BaseLLMAdapter {
|
|
641
|
+
private apiKey;
|
|
642
|
+
private baseUrl;
|
|
643
|
+
constructor(config: LLMConfig);
|
|
644
|
+
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* DeepSeek LLM Adapter
|
|
649
|
+
* Uses OpenAI-compatible API format
|
|
650
|
+
*/
|
|
651
|
+
declare class DeepSeekAdapter extends BaseLLMAdapter {
|
|
652
|
+
private client;
|
|
653
|
+
constructor(config: LLMConfig);
|
|
654
|
+
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Mistral AI LLM Adapter
|
|
659
|
+
* Uses Mistral's native API format
|
|
660
|
+
*/
|
|
661
|
+
declare class MistralAdapter extends BaseLLMAdapter {
|
|
662
|
+
private apiKey;
|
|
663
|
+
private baseUrl;
|
|
664
|
+
constructor(config: LLMConfig);
|
|
665
|
+
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Groq LLM Adapter
|
|
670
|
+
* Uses OpenAI-compatible API format with ultra-fast inference
|
|
671
|
+
*/
|
|
672
|
+
declare class GroqAdapter extends BaseLLMAdapter {
|
|
673
|
+
private client;
|
|
674
|
+
constructor(config: LLMConfig);
|
|
675
|
+
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Together AI LLM Adapter
|
|
680
|
+
* Uses OpenAI-compatible API format
|
|
681
|
+
*/
|
|
682
|
+
declare class TogetherAdapter extends BaseLLMAdapter {
|
|
683
|
+
private client;
|
|
684
|
+
constructor(config: LLMConfig);
|
|
685
|
+
chat(messages: LLMMessage[]): Promise<LLMResponse>;
|
|
686
|
+
}
|
|
687
|
+
|
|
519
688
|
/**
|
|
520
689
|
* Ollama Local LLM Adapter
|
|
521
690
|
* Runs models locally without API keys
|
|
@@ -670,4 +839,129 @@ declare class MarketDataService {
|
|
|
670
839
|
private calculatePortfolioValue;
|
|
671
840
|
}
|
|
672
841
|
|
|
673
|
-
|
|
842
|
+
/**
|
|
843
|
+
* Relay Client
|
|
844
|
+
*
|
|
845
|
+
* WebSocket client that connects the agent to the API command center.
|
|
846
|
+
* Handles authentication, heartbeats, message sending, and command receiving.
|
|
847
|
+
*
|
|
848
|
+
* Features:
|
|
849
|
+
* - Auto-reconnect with exponential backoff
|
|
850
|
+
* - Wallet signature authentication
|
|
851
|
+
* - Heartbeat keepalive
|
|
852
|
+
* - Command callback for runtime integration
|
|
853
|
+
*/
|
|
854
|
+
|
|
855
|
+
interface RelayClientConfig {
|
|
856
|
+
agentId: string;
|
|
857
|
+
privateKey: `0x${string}`;
|
|
858
|
+
relay: RelayConfig;
|
|
859
|
+
onCommand?: (command: RelayCommand) => void;
|
|
860
|
+
}
|
|
861
|
+
declare class RelayClient {
|
|
862
|
+
private config;
|
|
863
|
+
private ws;
|
|
864
|
+
private authenticated;
|
|
865
|
+
private reconnectAttempts;
|
|
866
|
+
private maxReconnectAttempts;
|
|
867
|
+
private reconnectTimer;
|
|
868
|
+
private heartbeatTimer;
|
|
869
|
+
private stopped;
|
|
870
|
+
constructor(config: RelayClientConfig);
|
|
871
|
+
/**
|
|
872
|
+
* Connect to the relay server
|
|
873
|
+
*/
|
|
874
|
+
connect(): Promise<void>;
|
|
875
|
+
/**
|
|
876
|
+
* Authenticate with the relay server using wallet signature
|
|
877
|
+
*/
|
|
878
|
+
private authenticate;
|
|
879
|
+
/**
|
|
880
|
+
* Handle incoming messages from the relay server
|
|
881
|
+
*/
|
|
882
|
+
private handleMessage;
|
|
883
|
+
/**
|
|
884
|
+
* Send a status heartbeat
|
|
885
|
+
*/
|
|
886
|
+
sendHeartbeat(status: AgentStatusPayload): void;
|
|
887
|
+
/**
|
|
888
|
+
* Send a status update (outside of regular heartbeat)
|
|
889
|
+
*/
|
|
890
|
+
sendStatusUpdate(status: Partial<AgentStatusPayload>): void;
|
|
891
|
+
/**
|
|
892
|
+
* Send a message to the command center
|
|
893
|
+
*/
|
|
894
|
+
sendMessage(messageType: MessageType, level: MessageLevel, title: string, body: string, data?: Record<string, unknown>): void;
|
|
895
|
+
/**
|
|
896
|
+
* Send a command execution result
|
|
897
|
+
*/
|
|
898
|
+
sendCommandResult(commandId: string, success: boolean, result?: string): void;
|
|
899
|
+
/**
|
|
900
|
+
* Start the heartbeat timer
|
|
901
|
+
*/
|
|
902
|
+
private startHeartbeat;
|
|
903
|
+
/**
|
|
904
|
+
* Stop the heartbeat timer
|
|
905
|
+
*/
|
|
906
|
+
private stopHeartbeat;
|
|
907
|
+
/**
|
|
908
|
+
* Schedule a reconnection with exponential backoff
|
|
909
|
+
*/
|
|
910
|
+
private scheduleReconnect;
|
|
911
|
+
/**
|
|
912
|
+
* Send a JSON message to the WebSocket
|
|
913
|
+
*/
|
|
914
|
+
private send;
|
|
915
|
+
/**
|
|
916
|
+
* Check if connected and authenticated
|
|
917
|
+
*/
|
|
918
|
+
get isConnected(): boolean;
|
|
919
|
+
/**
|
|
920
|
+
* Disconnect and stop reconnecting
|
|
921
|
+
*/
|
|
922
|
+
disconnect(): void;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Secure Environment Storage
|
|
927
|
+
*
|
|
928
|
+
* Encrypts sensitive environment variables at rest using AES-256-GCM.
|
|
929
|
+
* Private keys and API keys should never be stored in plaintext on disk.
|
|
930
|
+
*
|
|
931
|
+
* Usage:
|
|
932
|
+
* npx @exagent/agent encrypt — encrypt .env → .env.enc, delete plaintext
|
|
933
|
+
* The runtime loads .env.enc automatically if it exists
|
|
934
|
+
*
|
|
935
|
+
* Encryption:
|
|
936
|
+
* - AES-256-GCM for authenticated encryption
|
|
937
|
+
* - PBKDF2 with 100k iterations for key derivation
|
|
938
|
+
* - Random salt and IV per encryption
|
|
939
|
+
* - Only sensitive fields are encrypted (keys matching *_KEY, *_SECRET, PRIVATE_KEY)
|
|
940
|
+
*/
|
|
941
|
+
/**
|
|
942
|
+
* Encrypt a .env file and write .env.enc
|
|
943
|
+
*
|
|
944
|
+
* @param envPath Path to the .env file
|
|
945
|
+
* @param passphrase User-provided passphrase for encryption
|
|
946
|
+
* @param deleteOriginal Whether to delete the plaintext .env after encryption
|
|
947
|
+
* @returns Path to the encrypted file
|
|
948
|
+
*/
|
|
949
|
+
declare function encryptEnvFile(envPath: string, passphrase: string, deleteOriginal?: boolean): string;
|
|
950
|
+
/**
|
|
951
|
+
* Decrypt a .env.enc file and return the env vars as a Record
|
|
952
|
+
*
|
|
953
|
+
* @param encPath Path to the .env.enc file
|
|
954
|
+
* @param passphrase User-provided passphrase for decryption
|
|
955
|
+
* @returns Record of decrypted env vars
|
|
956
|
+
*/
|
|
957
|
+
declare function decryptEnvFile(encPath: string, passphrase: string): Record<string, string>;
|
|
958
|
+
/**
|
|
959
|
+
* Load environment variables, preferring .env.enc over .env
|
|
960
|
+
*
|
|
961
|
+
* @param basePath Directory containing .env / .env.enc
|
|
962
|
+
* @param passphrase Passphrase for decryption (from env or prompt)
|
|
963
|
+
* @returns Whether encrypted env was loaded
|
|
964
|
+
*/
|
|
965
|
+
declare function loadSecureEnv(basePath: string, passphrase?: string): boolean;
|
|
966
|
+
|
|
967
|
+
export { type AgentConfig, AgentConfigSchema, type AgentMode, AgentRuntime, type AgentStatusPayload, AnthropicAdapter, BaseLLMAdapter, type CommandType, DeepSeekAdapter, GoogleAdapter, GroqAdapter, type LLMAdapter, type LLMConfig, LLMConfigSchema, type LLMMessage, type LLMMetadata, type LLMProvider, LLMProviderSchema, type LLMResponse, type MarketData, MarketDataService, type MessageLevel, type MessageType, MistralAdapter, OllamaAdapter, OpenAIAdapter, RelayClient, type RelayCommand, type RelayConfig$1 as RelayConfig, RelayConfigSchema, RiskManager, type RiskUniverse, RiskUniverseSchema, type RuntimeConfig, STRATEGY_TEMPLATES, type StrategyFunction, type StrategyTemplate, TogetherAdapter, TradeExecutor, type TradeSignal, type TradingConfig, TradingConfigSchema, type VaultConfig, VaultConfigSchema, VaultManager, type VaultManagerConfig, type VaultPolicy, VaultPolicySchema, type VaultStatus, createLLMAdapter, createSampleConfig, decryptEnvFile, encryptEnvFile, getAllStrategyTemplates, getStrategyTemplate, loadConfig, loadSecureEnv, loadStrategy, validateConfig, validateStrategy };
|