@exagent/agent 0.1.12 → 0.1.14
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-BSNYL2DK.mjs +3005 -0
- package/dist/chunk-YWPRVCRB.mjs +3009 -0
- package/dist/cli.js +189 -203
- package/dist/cli.mjs +3 -3
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +216 -230
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/templates/.env.template +3 -4
- package/templates/docker-compose.yml +1 -1
- package/templates/strategy.template.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -820,7 +820,7 @@ export const generateSignals: StrategyFunction = async (marketData, llm, config)
|
|
|
820
820
|
riskWarnings: [
|
|
821
821
|
"Custom strategies have no guardrails - you are fully responsible",
|
|
822
822
|
"LLMs can hallucinate or make errors - always validate outputs",
|
|
823
|
-
"
|
|
823
|
+
"Start with small amounts before scaling up",
|
|
824
824
|
"Consider edge cases: what happens if the LLM returns invalid JSON?",
|
|
825
825
|
"Your prompts and strategy logic are your competitive advantage - protect them",
|
|
826
826
|
"Agents may not behave exactly as expected based on your prompts"
|
|
@@ -878,6 +878,187 @@ function getAllStrategyTemplates() {
|
|
|
878
878
|
return STRATEGY_TEMPLATES;
|
|
879
879
|
}
|
|
880
880
|
|
|
881
|
+
// src/config.ts
|
|
882
|
+
var import_fs2 = require("fs");
|
|
883
|
+
var import_path2 = require("path");
|
|
884
|
+
var import_dotenv = require("dotenv");
|
|
885
|
+
|
|
886
|
+
// src/types.ts
|
|
887
|
+
var import_zod = require("zod");
|
|
888
|
+
var WalletSetupSchema = import_zod.z.enum(["generate", "provide"]);
|
|
889
|
+
var LLMProviderSchema = import_zod.z.enum(["openai", "anthropic", "google", "deepseek", "mistral", "groq", "together", "ollama", "custom"]);
|
|
890
|
+
var LLMConfigSchema = import_zod.z.object({
|
|
891
|
+
provider: LLMProviderSchema,
|
|
892
|
+
model: import_zod.z.string().optional(),
|
|
893
|
+
apiKey: import_zod.z.string().optional(),
|
|
894
|
+
endpoint: import_zod.z.string().url().optional(),
|
|
895
|
+
temperature: import_zod.z.number().min(0).max(2).default(0.7),
|
|
896
|
+
maxTokens: import_zod.z.number().positive().default(4096)
|
|
897
|
+
});
|
|
898
|
+
var RiskUniverseSchema = import_zod.z.enum(["core", "established", "derivatives", "emerging", "frontier"]);
|
|
899
|
+
var TradingConfigSchema = import_zod.z.object({
|
|
900
|
+
timeHorizon: import_zod.z.enum(["intraday", "swing", "position"]).default("swing"),
|
|
901
|
+
maxPositionSizeBps: import_zod.z.number().min(100).max(1e4).default(1e3),
|
|
902
|
+
// 1-100%
|
|
903
|
+
maxDailyLossBps: import_zod.z.number().min(0).max(1e4).default(500),
|
|
904
|
+
// 0-100%
|
|
905
|
+
maxConcurrentPositions: import_zod.z.number().min(1).max(100).default(5),
|
|
906
|
+
tradingIntervalMs: import_zod.z.number().min(1e3).default(6e4),
|
|
907
|
+
// minimum 1 second
|
|
908
|
+
maxSlippageBps: import_zod.z.number().min(10).max(1e3).default(100),
|
|
909
|
+
// 0.1-10%, default 1%
|
|
910
|
+
minTradeValueUSD: import_zod.z.number().min(0).default(1)
|
|
911
|
+
// minimum trade value in USD
|
|
912
|
+
});
|
|
913
|
+
var VaultPolicySchema = import_zod.z.enum([
|
|
914
|
+
"disabled",
|
|
915
|
+
// Never create a vault - trade with agent's own capital only
|
|
916
|
+
"manual"
|
|
917
|
+
// Only create vault when explicitly directed by owner
|
|
918
|
+
]);
|
|
919
|
+
var VaultConfigSchema = import_zod.z.object({
|
|
920
|
+
// Policy for vault creation (asked during deployment)
|
|
921
|
+
policy: VaultPolicySchema.default("manual"),
|
|
922
|
+
// Default vault name (auto-generated from agent name if not set)
|
|
923
|
+
defaultName: import_zod.z.string().optional(),
|
|
924
|
+
// Default vault symbol (auto-generated if not set)
|
|
925
|
+
defaultSymbol: import_zod.z.string().optional(),
|
|
926
|
+
// Fee recipient for vault fees (default: agent wallet)
|
|
927
|
+
feeRecipient: import_zod.z.string().optional(),
|
|
928
|
+
// When vault exists, trade through vault instead of direct trading
|
|
929
|
+
// This pools depositors' capital with the agent's trades
|
|
930
|
+
preferVaultTrading: import_zod.z.boolean().default(true)
|
|
931
|
+
});
|
|
932
|
+
var WalletConfigSchema = import_zod.z.object({
|
|
933
|
+
setup: WalletSetupSchema.default("provide")
|
|
934
|
+
}).optional();
|
|
935
|
+
var RelayConfigSchema = import_zod.z.object({
|
|
936
|
+
enabled: import_zod.z.boolean().default(false),
|
|
937
|
+
apiUrl: import_zod.z.string().url(),
|
|
938
|
+
heartbeatIntervalMs: import_zod.z.number().min(5e3).default(3e4)
|
|
939
|
+
}).optional();
|
|
940
|
+
var AgentConfigSchema = import_zod.z.object({
|
|
941
|
+
// Identity (from on-chain registration)
|
|
942
|
+
agentId: import_zod.z.union([import_zod.z.number().positive(), import_zod.z.string()]),
|
|
943
|
+
name: import_zod.z.string().min(3).max(32),
|
|
944
|
+
// Network
|
|
945
|
+
network: import_zod.z.literal("mainnet").default("mainnet"),
|
|
946
|
+
// Wallet setup preference
|
|
947
|
+
wallet: WalletConfigSchema,
|
|
948
|
+
// LLM
|
|
949
|
+
llm: LLMConfigSchema,
|
|
950
|
+
// Trading parameters
|
|
951
|
+
riskUniverse: RiskUniverseSchema.default("established"),
|
|
952
|
+
trading: TradingConfigSchema.default({}),
|
|
953
|
+
// Vault configuration (copy trading)
|
|
954
|
+
vault: VaultConfigSchema.default({}),
|
|
955
|
+
// Relay configuration (command center)
|
|
956
|
+
relay: RelayConfigSchema,
|
|
957
|
+
// Allowed tokens (addresses)
|
|
958
|
+
allowedTokens: import_zod.z.array(import_zod.z.string()).optional()
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
// src/config.ts
|
|
962
|
+
function loadConfig(configPath) {
|
|
963
|
+
(0, import_dotenv.config)();
|
|
964
|
+
const configFile = configPath || process.env.EXAGENT_CONFIG || "agent-config.json";
|
|
965
|
+
const fullPath = configFile.startsWith("/") ? configFile : (0, import_path2.join)(process.cwd(), configFile);
|
|
966
|
+
if (!(0, import_fs2.existsSync)(fullPath)) {
|
|
967
|
+
throw new Error(`Config file not found: ${fullPath}`);
|
|
968
|
+
}
|
|
969
|
+
const rawConfig = JSON.parse((0, import_fs2.readFileSync)(fullPath, "utf-8"));
|
|
970
|
+
const config = AgentConfigSchema.parse(rawConfig);
|
|
971
|
+
const privateKey = process.env.EXAGENT_PRIVATE_KEY;
|
|
972
|
+
if (privateKey && (!privateKey.startsWith("0x") || privateKey.length !== 66)) {
|
|
973
|
+
throw new Error("EXAGENT_PRIVATE_KEY must be a valid 32-byte hex string starting with 0x");
|
|
974
|
+
}
|
|
975
|
+
const llmConfig = { ...config.llm };
|
|
976
|
+
if (process.env.OPENAI_API_KEY && config.llm.provider === "openai") {
|
|
977
|
+
llmConfig.apiKey = process.env.OPENAI_API_KEY;
|
|
978
|
+
}
|
|
979
|
+
if (process.env.ANTHROPIC_API_KEY && config.llm.provider === "anthropic") {
|
|
980
|
+
llmConfig.apiKey = process.env.ANTHROPIC_API_KEY;
|
|
981
|
+
}
|
|
982
|
+
if (process.env.GOOGLE_AI_API_KEY && config.llm.provider === "google") {
|
|
983
|
+
llmConfig.apiKey = process.env.GOOGLE_AI_API_KEY;
|
|
984
|
+
}
|
|
985
|
+
if (process.env.DEEPSEEK_API_KEY && config.llm.provider === "deepseek") {
|
|
986
|
+
llmConfig.apiKey = process.env.DEEPSEEK_API_KEY;
|
|
987
|
+
}
|
|
988
|
+
if (process.env.MISTRAL_API_KEY && config.llm.provider === "mistral") {
|
|
989
|
+
llmConfig.apiKey = process.env.MISTRAL_API_KEY;
|
|
990
|
+
}
|
|
991
|
+
if (process.env.GROQ_API_KEY && config.llm.provider === "groq") {
|
|
992
|
+
llmConfig.apiKey = process.env.GROQ_API_KEY;
|
|
993
|
+
}
|
|
994
|
+
if (process.env.TOGETHER_API_KEY && config.llm.provider === "together") {
|
|
995
|
+
llmConfig.apiKey = process.env.TOGETHER_API_KEY;
|
|
996
|
+
}
|
|
997
|
+
if (process.env.EXAGENT_LLM_URL) {
|
|
998
|
+
llmConfig.endpoint = process.env.EXAGENT_LLM_URL;
|
|
999
|
+
}
|
|
1000
|
+
if (process.env.EXAGENT_LLM_MODEL) {
|
|
1001
|
+
llmConfig.model = process.env.EXAGENT_LLM_MODEL;
|
|
1002
|
+
}
|
|
1003
|
+
const network = process.env.EXAGENT_NETWORK || config.network;
|
|
1004
|
+
return {
|
|
1005
|
+
...config,
|
|
1006
|
+
llm: llmConfig,
|
|
1007
|
+
network,
|
|
1008
|
+
privateKey: privateKey || ""
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
function validateConfig(config) {
|
|
1012
|
+
if (!config.privateKey) {
|
|
1013
|
+
throw new Error("Private key is required");
|
|
1014
|
+
}
|
|
1015
|
+
if (config.llm.provider !== "ollama" && !config.llm.apiKey) {
|
|
1016
|
+
throw new Error(`API key required for ${config.llm.provider} provider`);
|
|
1017
|
+
}
|
|
1018
|
+
if (config.llm.provider === "ollama" && !config.llm.endpoint) {
|
|
1019
|
+
config.llm.endpoint = "http://localhost:11434";
|
|
1020
|
+
}
|
|
1021
|
+
if (config.llm.provider === "custom" && !config.llm.endpoint) {
|
|
1022
|
+
throw new Error("Endpoint required for custom LLM provider");
|
|
1023
|
+
}
|
|
1024
|
+
if (!config.agentId || Number(config.agentId) <= 0) {
|
|
1025
|
+
throw new Error("Valid agent ID required");
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
var DEFAULT_RPC_URL = "https://base-rpc.publicnode.com";
|
|
1029
|
+
function getRpcUrl() {
|
|
1030
|
+
return process.env.BASE_RPC_URL || process.env.EXAGENT_RPC_URL || DEFAULT_RPC_URL;
|
|
1031
|
+
}
|
|
1032
|
+
function createSampleConfig(agentId, name) {
|
|
1033
|
+
return {
|
|
1034
|
+
agentId,
|
|
1035
|
+
name,
|
|
1036
|
+
network: "mainnet",
|
|
1037
|
+
llm: {
|
|
1038
|
+
provider: "openai",
|
|
1039
|
+
model: "gpt-4.1",
|
|
1040
|
+
temperature: 0.7,
|
|
1041
|
+
maxTokens: 4096
|
|
1042
|
+
},
|
|
1043
|
+
riskUniverse: "established",
|
|
1044
|
+
trading: {
|
|
1045
|
+
timeHorizon: "swing",
|
|
1046
|
+
maxPositionSizeBps: 1e3,
|
|
1047
|
+
maxDailyLossBps: 500,
|
|
1048
|
+
maxConcurrentPositions: 5,
|
|
1049
|
+
tradingIntervalMs: 6e4,
|
|
1050
|
+
maxSlippageBps: 100,
|
|
1051
|
+
minTradeValueUSD: 1
|
|
1052
|
+
},
|
|
1053
|
+
vault: {
|
|
1054
|
+
// Default to manual - user must explicitly enable auto-creation
|
|
1055
|
+
policy: "manual",
|
|
1056
|
+
// Will use agent name for vault name if not set
|
|
1057
|
+
preferVaultTrading: true
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
}
|
|
1061
|
+
|
|
881
1062
|
// src/trading/executor.ts
|
|
882
1063
|
var TradeExecutor = class {
|
|
883
1064
|
client;
|
|
@@ -991,11 +1172,8 @@ var TOKEN_DECIMALS = {
|
|
|
991
1172
|
// cbBTC
|
|
992
1173
|
"0x2416092f143378750bb29b79ed961ab195cceea5": 18,
|
|
993
1174
|
// ezETH (Renzo)
|
|
994
|
-
"0xc1cba3fcea344f92d9239c08c0568f6f2f0ee452": 18
|
|
1175
|
+
"0xc1cba3fcea344f92d9239c08c0568f6f2f0ee452": 18
|
|
995
1176
|
// wstETH (Lido)
|
|
996
|
-
// Base Sepolia
|
|
997
|
-
"0x036cbd53842c5426634e7929541ec2318f3dcf7e": 6
|
|
998
|
-
// USDC testnet
|
|
999
1177
|
};
|
|
1000
1178
|
function getTokenDecimals(address) {
|
|
1001
1179
|
const decimals = TOKEN_DECIMALS[address.toLowerCase()];
|
|
@@ -1363,16 +1541,10 @@ var import_viem2 = require("viem");
|
|
|
1363
1541
|
var import_accounts = require("viem/accounts");
|
|
1364
1542
|
var import_chains = require("viem/chains");
|
|
1365
1543
|
var ADDRESSES = {
|
|
1366
|
-
testnet: {
|
|
1367
|
-
vaultFactory: "0x5c099daaE33801a907Bb57011c6749655b55dc75",
|
|
1368
|
-
registry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
1369
|
-
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
1370
|
-
},
|
|
1371
1544
|
mainnet: {
|
|
1372
1545
|
vaultFactory: process.env.EXAGENT_VAULT_FACTORY_ADDRESS || "0x0000000000000000000000000000000000000000",
|
|
1373
1546
|
registry: process.env.EXAGENT_REGISTRY_ADDRESS || "0x0000000000000000000000000000000000000000",
|
|
1374
1547
|
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
1375
|
-
// Base mainnet USDC
|
|
1376
1548
|
}
|
|
1377
1549
|
};
|
|
1378
1550
|
var VAULT_FACTORY_ABI = [
|
|
@@ -1454,8 +1626,8 @@ var VaultManager = class {
|
|
|
1454
1626
|
this.config = config;
|
|
1455
1627
|
this.addresses = ADDRESSES[config.network];
|
|
1456
1628
|
this.account = (0, import_accounts.privateKeyToAccount)(config.walletKey);
|
|
1457
|
-
this.chain =
|
|
1458
|
-
const rpcUrl =
|
|
1629
|
+
this.chain = import_chains.base;
|
|
1630
|
+
const rpcUrl = getRpcUrl();
|
|
1459
1631
|
this.publicClient = (0, import_viem2.createPublicClient)({
|
|
1460
1632
|
chain: this.chain,
|
|
1461
1633
|
transport: (0, import_viem2.http)(rpcUrl)
|
|
@@ -2163,7 +2335,7 @@ var AgentRuntime = class {
|
|
|
2163
2335
|
const message = error instanceof Error ? error.message : String(error);
|
|
2164
2336
|
if (message.includes("insufficient funds") || message.includes("gas") || message.includes("intrinsic gas too low") || message.includes("exceeds the balance")) {
|
|
2165
2337
|
const ccUrl = `https://exagent.io/agents/${encodeURIComponent(this.config.name)}/command-center`;
|
|
2166
|
-
const chain =
|
|
2338
|
+
const chain = import_chains2.base;
|
|
2167
2339
|
const publicClientInstance = (0, import_viem3.createPublicClient)({
|
|
2168
2340
|
chain,
|
|
2169
2341
|
transport: (0, import_viem3.http)(this.getRpcUrl())
|
|
@@ -2583,13 +2755,10 @@ var AgentRuntime = class {
|
|
|
2583
2755
|
}
|
|
2584
2756
|
}
|
|
2585
2757
|
/**
|
|
2586
|
-
* Get RPC URL
|
|
2758
|
+
* Get RPC URL from environment or default
|
|
2587
2759
|
*/
|
|
2588
2760
|
getRpcUrl() {
|
|
2589
|
-
|
|
2590
|
-
return "https://mainnet.base.org";
|
|
2591
|
-
}
|
|
2592
|
-
return "https://sepolia.base.org";
|
|
2761
|
+
return getRpcUrl();
|
|
2593
2762
|
}
|
|
2594
2763
|
/**
|
|
2595
2764
|
* Default tokens to track.
|
|
@@ -2597,42 +2766,36 @@ var AgentRuntime = class {
|
|
|
2597
2766
|
* agents in restricted risk universes will have ineligible tokens filtered out.
|
|
2598
2767
|
*/
|
|
2599
2768
|
getDefaultTokens() {
|
|
2600
|
-
if (this.config.network === "mainnet") {
|
|
2601
|
-
return [
|
|
2602
|
-
// Core
|
|
2603
|
-
"0x4200000000000000000000000000000000000006",
|
|
2604
|
-
// WETH
|
|
2605
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
2606
|
-
// USDC
|
|
2607
|
-
"0x2Ae3F1Ec7F1F5012CFEab0185bFC7aa3cf0DEC22",
|
|
2608
|
-
// cbETH
|
|
2609
|
-
"0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA",
|
|
2610
|
-
// USDbC
|
|
2611
|
-
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
2612
|
-
// DAI
|
|
2613
|
-
// Established
|
|
2614
|
-
"0x940181a94A35A4569E4529A3CDfB74e38FD98631",
|
|
2615
|
-
// AERO
|
|
2616
|
-
"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
|
2617
|
-
// cbBTC
|
|
2618
|
-
"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
|
2619
|
-
// wstETH
|
|
2620
|
-
"0x2416092f143378750bb29b79eD961ab195CcEea5",
|
|
2621
|
-
// ezETH
|
|
2622
|
-
// Emerging (filtered by risk universe at init)
|
|
2623
|
-
"0x532f27101965dd16442E59d40670FaF5eBB142E4",
|
|
2624
|
-
// BRETT
|
|
2625
|
-
"0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed",
|
|
2626
|
-
// DEGEN
|
|
2627
|
-
"0x0b3e328455c4059EEb9e3f84b5543F74E24e7E1b",
|
|
2628
|
-
// VIRTUAL
|
|
2629
|
-
"0xAC1Bd2486Aaf3B5C0fc3Fd868558b082a531B2B4"
|
|
2630
|
-
// TOSHI
|
|
2631
|
-
];
|
|
2632
|
-
}
|
|
2633
2769
|
return [
|
|
2634
|
-
|
|
2770
|
+
// Core
|
|
2771
|
+
"0x4200000000000000000000000000000000000006",
|
|
2635
2772
|
// WETH
|
|
2773
|
+
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
2774
|
+
// USDC
|
|
2775
|
+
"0x2Ae3F1Ec7F1F5012CFEab0185bFC7aa3cf0DEC22",
|
|
2776
|
+
// cbETH
|
|
2777
|
+
"0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA",
|
|
2778
|
+
// USDbC
|
|
2779
|
+
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
2780
|
+
// DAI
|
|
2781
|
+
// Established
|
|
2782
|
+
"0x940181a94A35A4569E4529A3CDfB74e38FD98631",
|
|
2783
|
+
// AERO
|
|
2784
|
+
"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
|
2785
|
+
// cbBTC
|
|
2786
|
+
"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
|
2787
|
+
// wstETH
|
|
2788
|
+
"0x2416092f143378750bb29b79eD961ab195CcEea5",
|
|
2789
|
+
// ezETH
|
|
2790
|
+
// Emerging (filtered by risk universe at init)
|
|
2791
|
+
"0x532f27101965dd16442E59d40670FaF5eBB142E4",
|
|
2792
|
+
// BRETT
|
|
2793
|
+
"0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed",
|
|
2794
|
+
// DEGEN
|
|
2795
|
+
"0x0b3e328455c4059EEb9e3f84b5543F74E24e7E1b",
|
|
2796
|
+
// VIRTUAL
|
|
2797
|
+
"0xAC1Bd2486Aaf3B5C0fc3Fd868558b082a531B2B4"
|
|
2798
|
+
// TOSHI
|
|
2636
2799
|
];
|
|
2637
2800
|
}
|
|
2638
2801
|
sleep(ms) {
|
|
@@ -2690,183 +2853,6 @@ var AgentRuntime = class {
|
|
|
2690
2853
|
}
|
|
2691
2854
|
};
|
|
2692
2855
|
|
|
2693
|
-
// src/config.ts
|
|
2694
|
-
var import_fs2 = require("fs");
|
|
2695
|
-
var import_path2 = require("path");
|
|
2696
|
-
var import_dotenv = require("dotenv");
|
|
2697
|
-
|
|
2698
|
-
// src/types.ts
|
|
2699
|
-
var import_zod = require("zod");
|
|
2700
|
-
var WalletSetupSchema = import_zod.z.enum(["generate", "provide"]);
|
|
2701
|
-
var LLMProviderSchema = import_zod.z.enum(["openai", "anthropic", "google", "deepseek", "mistral", "groq", "together", "ollama", "custom"]);
|
|
2702
|
-
var LLMConfigSchema = import_zod.z.object({
|
|
2703
|
-
provider: LLMProviderSchema,
|
|
2704
|
-
model: import_zod.z.string().optional(),
|
|
2705
|
-
apiKey: import_zod.z.string().optional(),
|
|
2706
|
-
endpoint: import_zod.z.string().url().optional(),
|
|
2707
|
-
temperature: import_zod.z.number().min(0).max(2).default(0.7),
|
|
2708
|
-
maxTokens: import_zod.z.number().positive().default(4096)
|
|
2709
|
-
});
|
|
2710
|
-
var RiskUniverseSchema = import_zod.z.enum(["core", "established", "derivatives", "emerging", "frontier"]);
|
|
2711
|
-
var TradingConfigSchema = import_zod.z.object({
|
|
2712
|
-
timeHorizon: import_zod.z.enum(["intraday", "swing", "position"]).default("swing"),
|
|
2713
|
-
maxPositionSizeBps: import_zod.z.number().min(100).max(1e4).default(1e3),
|
|
2714
|
-
// 1-100%
|
|
2715
|
-
maxDailyLossBps: import_zod.z.number().min(0).max(1e4).default(500),
|
|
2716
|
-
// 0-100%
|
|
2717
|
-
maxConcurrentPositions: import_zod.z.number().min(1).max(100).default(5),
|
|
2718
|
-
tradingIntervalMs: import_zod.z.number().min(1e3).default(6e4),
|
|
2719
|
-
// minimum 1 second
|
|
2720
|
-
maxSlippageBps: import_zod.z.number().min(10).max(1e3).default(100),
|
|
2721
|
-
// 0.1-10%, default 1%
|
|
2722
|
-
minTradeValueUSD: import_zod.z.number().min(0).default(1)
|
|
2723
|
-
// minimum trade value in USD
|
|
2724
|
-
});
|
|
2725
|
-
var VaultPolicySchema = import_zod.z.enum([
|
|
2726
|
-
"disabled",
|
|
2727
|
-
// Never create a vault - trade with agent's own capital only
|
|
2728
|
-
"manual"
|
|
2729
|
-
// Only create vault when explicitly directed by owner
|
|
2730
|
-
]);
|
|
2731
|
-
var VaultConfigSchema = import_zod.z.object({
|
|
2732
|
-
// Policy for vault creation (asked during deployment)
|
|
2733
|
-
policy: VaultPolicySchema.default("manual"),
|
|
2734
|
-
// Default vault name (auto-generated from agent name if not set)
|
|
2735
|
-
defaultName: import_zod.z.string().optional(),
|
|
2736
|
-
// Default vault symbol (auto-generated if not set)
|
|
2737
|
-
defaultSymbol: import_zod.z.string().optional(),
|
|
2738
|
-
// Fee recipient for vault fees (default: agent wallet)
|
|
2739
|
-
feeRecipient: import_zod.z.string().optional(),
|
|
2740
|
-
// When vault exists, trade through vault instead of direct trading
|
|
2741
|
-
// This pools depositors' capital with the agent's trades
|
|
2742
|
-
preferVaultTrading: import_zod.z.boolean().default(true)
|
|
2743
|
-
});
|
|
2744
|
-
var WalletConfigSchema = import_zod.z.object({
|
|
2745
|
-
setup: WalletSetupSchema.default("provide")
|
|
2746
|
-
}).optional();
|
|
2747
|
-
var RelayConfigSchema = import_zod.z.object({
|
|
2748
|
-
enabled: import_zod.z.boolean().default(false),
|
|
2749
|
-
apiUrl: import_zod.z.string().url(),
|
|
2750
|
-
heartbeatIntervalMs: import_zod.z.number().min(5e3).default(3e4)
|
|
2751
|
-
}).optional();
|
|
2752
|
-
var AgentConfigSchema = import_zod.z.object({
|
|
2753
|
-
// Identity (from on-chain registration)
|
|
2754
|
-
agentId: import_zod.z.union([import_zod.z.number().positive(), import_zod.z.string()]),
|
|
2755
|
-
name: import_zod.z.string().min(3).max(32),
|
|
2756
|
-
// Network
|
|
2757
|
-
network: import_zod.z.enum(["mainnet", "testnet"]).default("testnet"),
|
|
2758
|
-
// Wallet setup preference
|
|
2759
|
-
wallet: WalletConfigSchema,
|
|
2760
|
-
// LLM
|
|
2761
|
-
llm: LLMConfigSchema,
|
|
2762
|
-
// Trading parameters
|
|
2763
|
-
riskUniverse: RiskUniverseSchema.default("established"),
|
|
2764
|
-
trading: TradingConfigSchema.default({}),
|
|
2765
|
-
// Vault configuration (copy trading)
|
|
2766
|
-
vault: VaultConfigSchema.default({}),
|
|
2767
|
-
// Relay configuration (command center)
|
|
2768
|
-
relay: RelayConfigSchema,
|
|
2769
|
-
// Allowed tokens (addresses)
|
|
2770
|
-
allowedTokens: import_zod.z.array(import_zod.z.string()).optional()
|
|
2771
|
-
});
|
|
2772
|
-
|
|
2773
|
-
// src/config.ts
|
|
2774
|
-
function loadConfig(configPath) {
|
|
2775
|
-
(0, import_dotenv.config)();
|
|
2776
|
-
const configFile = configPath || process.env.EXAGENT_CONFIG || "agent-config.json";
|
|
2777
|
-
const fullPath = configFile.startsWith("/") ? configFile : (0, import_path2.join)(process.cwd(), configFile);
|
|
2778
|
-
if (!(0, import_fs2.existsSync)(fullPath)) {
|
|
2779
|
-
throw new Error(`Config file not found: ${fullPath}`);
|
|
2780
|
-
}
|
|
2781
|
-
const rawConfig = JSON.parse((0, import_fs2.readFileSync)(fullPath, "utf-8"));
|
|
2782
|
-
const config = AgentConfigSchema.parse(rawConfig);
|
|
2783
|
-
const privateKey = process.env.EXAGENT_PRIVATE_KEY;
|
|
2784
|
-
if (privateKey && (!privateKey.startsWith("0x") || privateKey.length !== 66)) {
|
|
2785
|
-
throw new Error("EXAGENT_PRIVATE_KEY must be a valid 32-byte hex string starting with 0x");
|
|
2786
|
-
}
|
|
2787
|
-
const llmConfig = { ...config.llm };
|
|
2788
|
-
if (process.env.OPENAI_API_KEY && config.llm.provider === "openai") {
|
|
2789
|
-
llmConfig.apiKey = process.env.OPENAI_API_KEY;
|
|
2790
|
-
}
|
|
2791
|
-
if (process.env.ANTHROPIC_API_KEY && config.llm.provider === "anthropic") {
|
|
2792
|
-
llmConfig.apiKey = process.env.ANTHROPIC_API_KEY;
|
|
2793
|
-
}
|
|
2794
|
-
if (process.env.GOOGLE_AI_API_KEY && config.llm.provider === "google") {
|
|
2795
|
-
llmConfig.apiKey = process.env.GOOGLE_AI_API_KEY;
|
|
2796
|
-
}
|
|
2797
|
-
if (process.env.DEEPSEEK_API_KEY && config.llm.provider === "deepseek") {
|
|
2798
|
-
llmConfig.apiKey = process.env.DEEPSEEK_API_KEY;
|
|
2799
|
-
}
|
|
2800
|
-
if (process.env.MISTRAL_API_KEY && config.llm.provider === "mistral") {
|
|
2801
|
-
llmConfig.apiKey = process.env.MISTRAL_API_KEY;
|
|
2802
|
-
}
|
|
2803
|
-
if (process.env.GROQ_API_KEY && config.llm.provider === "groq") {
|
|
2804
|
-
llmConfig.apiKey = process.env.GROQ_API_KEY;
|
|
2805
|
-
}
|
|
2806
|
-
if (process.env.TOGETHER_API_KEY && config.llm.provider === "together") {
|
|
2807
|
-
llmConfig.apiKey = process.env.TOGETHER_API_KEY;
|
|
2808
|
-
}
|
|
2809
|
-
if (process.env.EXAGENT_LLM_URL) {
|
|
2810
|
-
llmConfig.endpoint = process.env.EXAGENT_LLM_URL;
|
|
2811
|
-
}
|
|
2812
|
-
if (process.env.EXAGENT_LLM_MODEL) {
|
|
2813
|
-
llmConfig.model = process.env.EXAGENT_LLM_MODEL;
|
|
2814
|
-
}
|
|
2815
|
-
const network = process.env.EXAGENT_NETWORK || config.network;
|
|
2816
|
-
return {
|
|
2817
|
-
...config,
|
|
2818
|
-
llm: llmConfig,
|
|
2819
|
-
network,
|
|
2820
|
-
privateKey: privateKey || ""
|
|
2821
|
-
};
|
|
2822
|
-
}
|
|
2823
|
-
function validateConfig(config) {
|
|
2824
|
-
if (!config.privateKey) {
|
|
2825
|
-
throw new Error("Private key is required");
|
|
2826
|
-
}
|
|
2827
|
-
if (config.llm.provider !== "ollama" && !config.llm.apiKey) {
|
|
2828
|
-
throw new Error(`API key required for ${config.llm.provider} provider`);
|
|
2829
|
-
}
|
|
2830
|
-
if (config.llm.provider === "ollama" && !config.llm.endpoint) {
|
|
2831
|
-
config.llm.endpoint = "http://localhost:11434";
|
|
2832
|
-
}
|
|
2833
|
-
if (config.llm.provider === "custom" && !config.llm.endpoint) {
|
|
2834
|
-
throw new Error("Endpoint required for custom LLM provider");
|
|
2835
|
-
}
|
|
2836
|
-
if (!config.agentId || Number(config.agentId) <= 0) {
|
|
2837
|
-
throw new Error("Valid agent ID required");
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
function createSampleConfig(agentId, name) {
|
|
2841
|
-
return {
|
|
2842
|
-
agentId,
|
|
2843
|
-
name,
|
|
2844
|
-
network: "testnet",
|
|
2845
|
-
llm: {
|
|
2846
|
-
provider: "openai",
|
|
2847
|
-
model: "gpt-4.1",
|
|
2848
|
-
temperature: 0.7,
|
|
2849
|
-
maxTokens: 4096
|
|
2850
|
-
},
|
|
2851
|
-
riskUniverse: "established",
|
|
2852
|
-
trading: {
|
|
2853
|
-
timeHorizon: "swing",
|
|
2854
|
-
maxPositionSizeBps: 1e3,
|
|
2855
|
-
maxDailyLossBps: 500,
|
|
2856
|
-
maxConcurrentPositions: 5,
|
|
2857
|
-
tradingIntervalMs: 6e4,
|
|
2858
|
-
maxSlippageBps: 100,
|
|
2859
|
-
minTradeValueUSD: 1
|
|
2860
|
-
},
|
|
2861
|
-
vault: {
|
|
2862
|
-
// Default to manual - user must explicitly enable auto-creation
|
|
2863
|
-
policy: "manual",
|
|
2864
|
-
// Will use agent name for vault name if not set
|
|
2865
|
-
preferVaultTrading: true
|
|
2866
|
-
}
|
|
2867
|
-
};
|
|
2868
|
-
}
|
|
2869
|
-
|
|
2870
2856
|
// src/secure-env.ts
|
|
2871
2857
|
var crypto = __toESM(require("crypto"));
|
|
2872
2858
|
var fs = __toESM(require("fs"));
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exagent/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "Autonomous trading agent runtime for Exagent",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"clean": "rm -rf dist"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@exagent/sdk": "^0.1.
|
|
32
|
+
"@exagent/sdk": "^0.1.6",
|
|
33
33
|
"chalk": "^5.3.0",
|
|
34
34
|
"commander": "^12.0.0",
|
|
35
35
|
"dotenv": "^16.4.0",
|
package/templates/.env.template
CHANGED
|
@@ -15,11 +15,10 @@
|
|
|
15
15
|
EXAGENT_PRIVATE_KEY=
|
|
16
16
|
|
|
17
17
|
# ============================================
|
|
18
|
-
#
|
|
18
|
+
# Network
|
|
19
19
|
# ============================================
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
EXAGENT_NETWORK=testnet
|
|
20
|
+
# Base mainnet
|
|
21
|
+
EXAGENT_NETWORK=mainnet
|
|
23
22
|
|
|
24
23
|
# ============================================
|
|
25
24
|
# LLM API Keys (choose one based on your config)
|
|
@@ -19,7 +19,7 @@ services:
|
|
|
19
19
|
environment:
|
|
20
20
|
- NODE_ENV=production
|
|
21
21
|
- EXAGENT_PRIVATE_KEY=${EXAGENT_PRIVATE_KEY}
|
|
22
|
-
- EXAGENT_NETWORK=${EXAGENT_NETWORK:-
|
|
22
|
+
- EXAGENT_NETWORK=${EXAGENT_NETWORK:-mainnet}
|
|
23
23
|
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
|
24
24
|
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
|
|
25
25
|
- EXAGENT_LLM_URL=${EXAGENT_LLM_URL:-}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* IMPORTANT WARNINGS:
|
|
9
9
|
* - LLMs can hallucinate or make errors. Always validate outputs.
|
|
10
|
-
* -
|
|
10
|
+
* - Start with small amounts before scaling up.
|
|
11
11
|
* - Agents may not behave exactly as expected based on your prompts.
|
|
12
12
|
* - You are fully responsible for your trading decisions.
|
|
13
13
|
*/
|