@tradejs/node 3.0.1 → 3.1.1
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/README.md +4 -0
- package/dist/ai.d.mts +26 -4
- package/dist/ai.d.ts +26 -4
- package/dist/ai.js +162 -165
- package/dist/ai.mjs +4 -1
- package/dist/backtest.js +515 -188
- package/dist/backtest.mjs +6 -4
- package/dist/chunk-3TWULKHV.mjs +595 -0
- package/dist/chunk-FB5NUEOQ.mjs +295 -0
- package/dist/chunk-LAJ7NA3Q.mjs +377 -0
- package/dist/{chunk-VRXU4E4O.mjs → chunk-SEQJ6V6B.mjs} +165 -446
- package/dist/{chunk-OGAWBO3Z.mjs → chunk-W26Y6IRP.mjs} +22 -3
- package/dist/chunk-XN7BC7XK.mjs +295 -0
- package/dist/cli.js +152 -161
- package/dist/cli.mjs +4 -2
- package/dist/connectors.d.mts +5 -2
- package/dist/connectors.d.ts +5 -2
- package/dist/connectors.js +329 -8
- package/dist/connectors.mjs +5 -1
- package/dist/registry-DHTLjQcr.d.mts +17 -0
- package/dist/registry-DHTLjQcr.d.ts +17 -0
- package/dist/registry.d.mts +2 -15
- package/dist/registry.d.ts +2 -15
- package/dist/registry.js +176 -161
- package/dist/registry.mjs +5 -2
- package/dist/runtimeDashboard.d.mts +12 -0
- package/dist/runtimeDashboard.d.ts +12 -0
- package/dist/runtimeDashboard.js +8502 -0
- package/dist/runtimeDashboard.mjs +1000 -0
- package/dist/runtimeStrategies.d.mts +38 -0
- package/dist/runtimeStrategies.d.ts +38 -0
- package/dist/runtimeStrategies.js +798 -0
- package/dist/runtimeStrategies.mjs +264 -0
- package/dist/runtimeTrades.d.mts +31 -0
- package/dist/runtimeTrades.d.ts +31 -0
- package/dist/runtimeTrades.js +321 -0
- package/dist/runtimeTrades.mjs +11 -0
- package/dist/strategies.d.mts +2 -2
- package/dist/strategies.d.ts +2 -2
- package/dist/strategies.js +194 -165
- package/dist/strategies.mjs +24 -379
- package/package.json +27 -6
- package/dist/chunk-V3YMKE4I.mjs +0 -271
package/dist/strategies.js
CHANGED
|
@@ -70,7 +70,10 @@ __export(strategies_exports, {
|
|
|
70
70
|
getRegisteredManifests: () => getRegisteredManifests,
|
|
71
71
|
getRegisteredStrategies: () => getRegisteredStrategies,
|
|
72
72
|
getStrategyCreator: () => getStrategyCreator,
|
|
73
|
+
getStrategyDefaults: () => getStrategyDefaults,
|
|
73
74
|
getStrategyManifest: () => getStrategyManifest,
|
|
75
|
+
getStrategyPluginSource: () => getStrategyPluginSource,
|
|
76
|
+
invokeAiChat: () => invokeAiChat,
|
|
74
77
|
isKnownStrategy: () => isKnownStrategy,
|
|
75
78
|
isTrackedHyperliquidPerp: () => isTrackedHyperliquidPerp,
|
|
76
79
|
isTrackedHyperliquidWhale: () => isTrackedHyperliquidWhale,
|
|
@@ -89,11 +92,8 @@ module.exports = __toCommonJS(strategies_exports);
|
|
|
89
92
|
__reExport(strategies_exports, require("@tradejs/core/strategies"), module.exports);
|
|
90
93
|
|
|
91
94
|
// src/ai.ts
|
|
92
|
-
var
|
|
93
|
-
var import_aiEndpoints = require("@tradejs/core/aiEndpoints");
|
|
94
|
-
var import_aiModels = require("@tradejs/core/aiModels");
|
|
95
|
+
var import_aiLanguages2 = require("@tradejs/core/aiLanguages");
|
|
95
96
|
var import_redis = require("@tradejs/infra/redis");
|
|
96
|
-
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
97
97
|
|
|
98
98
|
// src/aiShared.ts
|
|
99
99
|
var MAX_AI_SERIES_POINTS = 5;
|
|
@@ -966,6 +966,7 @@ var createStrategyRegistryState = () => ({
|
|
|
966
966
|
strategyCreators: /* @__PURE__ */ new Map(),
|
|
967
967
|
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
968
968
|
strategyEntriesMap: /* @__PURE__ */ new Map(),
|
|
969
|
+
strategySourcesMap: /* @__PURE__ */ new Map(),
|
|
969
970
|
pluginsLoadPromise: null
|
|
970
971
|
});
|
|
971
972
|
var registryStateByProjectRoot = sharedStrategyRegistry.registryStateByProjectRoot;
|
|
@@ -1036,6 +1037,7 @@ var registerEntries = (entries, source, state) => {
|
|
|
1036
1037
|
}
|
|
1037
1038
|
state.strategyManifestsMap.set(strategyName, entry.manifest);
|
|
1038
1039
|
state.strategyEntriesMap.set(strategyName, entry);
|
|
1040
|
+
state.strategySourcesMap.set(strategyName, source);
|
|
1039
1041
|
materializeStrategyCreator(strategyName, state);
|
|
1040
1042
|
}
|
|
1041
1043
|
};
|
|
@@ -1153,6 +1155,16 @@ var getStrategyCreator = async (name, cwd = getTradejsProjectCwd()) => {
|
|
|
1153
1155
|
const { state } = getStrategyRegistryState(cwd);
|
|
1154
1156
|
return state.strategyCreators.get(name);
|
|
1155
1157
|
};
|
|
1158
|
+
var getStrategyDefaults = async (name, cwd = getTradejsProjectCwd()) => {
|
|
1159
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
1160
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
1161
|
+
return state.strategyEntriesMap.get(name)?.defaults;
|
|
1162
|
+
};
|
|
1163
|
+
var getStrategyPluginSource = async (name, cwd = getTradejsProjectCwd()) => {
|
|
1164
|
+
await ensureStrategyPluginsLoaded(cwd);
|
|
1165
|
+
const { state } = getStrategyRegistryState(cwd);
|
|
1166
|
+
return state.strategySourcesMap.get(name);
|
|
1167
|
+
};
|
|
1156
1168
|
var getAvailableStrategyNames = async (cwd = getTradejsProjectCwd()) => {
|
|
1157
1169
|
await ensureStrategyPluginsLoaded(cwd);
|
|
1158
1170
|
const { state } = getStrategyRegistryState(cwd);
|
|
@@ -1335,7 +1347,149 @@ var postProcessLocalAiAnalysisByStrategy = (signal, analysis, payload = buildAiP
|
|
|
1335
1347
|
}) ?? strategyAnalysis;
|
|
1336
1348
|
};
|
|
1337
1349
|
|
|
1350
|
+
// src/aiProvider.ts
|
|
1351
|
+
var import_aiEndpoints = require("@tradejs/core/aiEndpoints");
|
|
1352
|
+
var import_aiModels = require("@tradejs/core/aiModels");
|
|
1353
|
+
var import_aiLanguages = require("@tradejs/core/aiLanguages");
|
|
1354
|
+
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
1355
|
+
var DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
1356
|
+
var userSettingsCache = /* @__PURE__ */ new Map();
|
|
1357
|
+
var aiModelCache = /* @__PURE__ */ new Map();
|
|
1358
|
+
var normalizeResponseContent = (content) => {
|
|
1359
|
+
if (typeof content === "string") return content;
|
|
1360
|
+
if (content && typeof content === "object" && !Array.isArray(content)) {
|
|
1361
|
+
return content;
|
|
1362
|
+
}
|
|
1363
|
+
if (Array.isArray(content)) {
|
|
1364
|
+
return content.map(
|
|
1365
|
+
(part) => typeof part?.text === "string" ? part.text : ""
|
|
1366
|
+
).join("\n").trim();
|
|
1367
|
+
}
|
|
1368
|
+
return String(content ?? "");
|
|
1369
|
+
};
|
|
1370
|
+
var getAiInvocationError = (error) => {
|
|
1371
|
+
const details = error instanceof Error && error.message.trim() ? error.message.trim() : String(error);
|
|
1372
|
+
const isEmptyCompletion = error instanceof TypeError && /Cannot read properties of undefined \(reading ['"]message['"]\)/.test(
|
|
1373
|
+
details
|
|
1374
|
+
);
|
|
1375
|
+
const wrapped = new Error(
|
|
1376
|
+
isEmptyCompletion ? "AI provider returned an empty chat completion" : `AI model invocation failed: ${details}`
|
|
1377
|
+
);
|
|
1378
|
+
wrapped.cause = error;
|
|
1379
|
+
return wrapped;
|
|
1380
|
+
};
|
|
1381
|
+
var isEmptyResponseContent = (content) => typeof content === "string" ? content.trim().length === 0 : Object.keys(content).length === 0;
|
|
1382
|
+
var getAiModelCacheKey = (userName, modelName, temperature) => `${userName}::${modelName}::${temperature}`;
|
|
1383
|
+
var resolveAiModelName = (settings, requestedModelName) => {
|
|
1384
|
+
const explicitModelName = requestedModelName?.trim() ?? "";
|
|
1385
|
+
if (explicitModelName) return explicitModelName;
|
|
1386
|
+
return settings.AI_MODEL?.trim() || DEFAULT_AI_MODEL;
|
|
1387
|
+
};
|
|
1388
|
+
var getOpenRouterModelKwargs = (apiEndpoint) => {
|
|
1389
|
+
const endpoint = String(apiEndpoint ?? "").trim();
|
|
1390
|
+
if (!endpoint) return {};
|
|
1391
|
+
let hostname = "";
|
|
1392
|
+
try {
|
|
1393
|
+
hostname = new URL(endpoint).hostname;
|
|
1394
|
+
} catch {
|
|
1395
|
+
hostname = endpoint;
|
|
1396
|
+
}
|
|
1397
|
+
return hostname.toLowerCase().includes("openrouter") ? { provider: { ignore: ["azure"] } } : {};
|
|
1398
|
+
};
|
|
1399
|
+
var getAiUserSettings = async (userName = "root") => {
|
|
1400
|
+
let settingsPromise = userSettingsCache.get(userName);
|
|
1401
|
+
if (!settingsPromise) {
|
|
1402
|
+
settingsPromise = (0, import_userSettings.getUserSettings)(userName).then((settings2) => {
|
|
1403
|
+
const endpoint = (0, import_aiEndpoints.normalizeAiEndpoint)(settings2.AI_API_ENDPOINT);
|
|
1404
|
+
return {
|
|
1405
|
+
...settings2,
|
|
1406
|
+
AI_API_ENDPOINT: endpoint,
|
|
1407
|
+
AI_MODEL: (0, import_aiModels.normalizeAiModel)(settings2.AI_MODEL, endpoint),
|
|
1408
|
+
AI_RESPONSE_LANGUAGE: (0, import_aiLanguages.normalizeAiResponseLanguage)(
|
|
1409
|
+
settings2.AI_RESPONSE_LANGUAGE
|
|
1410
|
+
)
|
|
1411
|
+
};
|
|
1412
|
+
});
|
|
1413
|
+
settingsPromise.catch(() => userSettingsCache.delete(userName));
|
|
1414
|
+
userSettingsCache.set(userName, settingsPromise);
|
|
1415
|
+
}
|
|
1416
|
+
const settings = await settingsPromise;
|
|
1417
|
+
if (!settings.AI_API_KEY || !settings.AI_API_ENDPOINT) {
|
|
1418
|
+
throw new Error(`AI settings are incomplete for user ${userName}`);
|
|
1419
|
+
}
|
|
1420
|
+
return settings;
|
|
1421
|
+
};
|
|
1422
|
+
var getAiModel = async (userName = "root", requestedModelName, temperature = 0.2) => {
|
|
1423
|
+
const settings = await getAiUserSettings(userName);
|
|
1424
|
+
const modelName = resolveAiModelName(settings, requestedModelName);
|
|
1425
|
+
const cacheKey = getAiModelCacheKey(userName, modelName, temperature);
|
|
1426
|
+
let modelPromise = aiModelCache.get(cacheKey);
|
|
1427
|
+
if (!modelPromise) {
|
|
1428
|
+
modelPromise = import("@langchain/openai").then(({ ChatOpenAI }) => {
|
|
1429
|
+
const modelKwargs = getOpenRouterModelKwargs(settings.AI_API_ENDPOINT);
|
|
1430
|
+
return new ChatOpenAI({
|
|
1431
|
+
temperature,
|
|
1432
|
+
modelName,
|
|
1433
|
+
apiKey: settings.AI_API_KEY,
|
|
1434
|
+
...Object.keys(modelKwargs).length ? { modelKwargs } : {},
|
|
1435
|
+
configuration: {
|
|
1436
|
+
baseURL: settings.AI_API_ENDPOINT,
|
|
1437
|
+
defaultHeaders: {
|
|
1438
|
+
"HTTP-Referer": "https://tradejs.dev",
|
|
1439
|
+
"X-Title": "Inv"
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
});
|
|
1443
|
+
});
|
|
1444
|
+
modelPromise.catch(() => aiModelCache.delete(cacheKey));
|
|
1445
|
+
aiModelCache.set(cacheKey, modelPromise);
|
|
1446
|
+
}
|
|
1447
|
+
try {
|
|
1448
|
+
return await modelPromise;
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
aiModelCache.delete(cacheKey);
|
|
1451
|
+
userSettingsCache.delete(userName);
|
|
1452
|
+
throw error;
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
var resetAiRuntimeCache = () => {
|
|
1456
|
+
aiModelCache.clear();
|
|
1457
|
+
userSettingsCache.clear();
|
|
1458
|
+
};
|
|
1459
|
+
var invokeAiChatWithUserMessageEncoding = async ({
|
|
1460
|
+
messages,
|
|
1461
|
+
userName = "root",
|
|
1462
|
+
model,
|
|
1463
|
+
temperature = 0.2
|
|
1464
|
+
}, resolveUserMessageEncoding) => {
|
|
1465
|
+
const [{ HumanMessage, SystemMessage }, aiModel] = await Promise.all([
|
|
1466
|
+
import("@langchain/core/messages"),
|
|
1467
|
+
getAiModel(userName, model, temperature)
|
|
1468
|
+
]);
|
|
1469
|
+
const providerMessages = messages.map(
|
|
1470
|
+
(message) => message.role === "system" ? new SystemMessage(message.content) : new HumanMessage(
|
|
1471
|
+
resolveUserMessageEncoding(message) === "text-block" ? { content: [{ type: "text", text: message.content }] } : message.content
|
|
1472
|
+
)
|
|
1473
|
+
);
|
|
1474
|
+
try {
|
|
1475
|
+
const response = await aiModel.invoke(providerMessages);
|
|
1476
|
+
const content = normalizeResponseContent(response?.content);
|
|
1477
|
+
if (isEmptyResponseContent(content)) {
|
|
1478
|
+
throw new Error("AI provider returned an empty chat completion");
|
|
1479
|
+
}
|
|
1480
|
+
return { content };
|
|
1481
|
+
} catch (error) {
|
|
1482
|
+
throw getAiInvocationError(error);
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
var invokeAiPromptChat = (options) => invokeAiChatWithUserMessageEncoding(options, () => "text-block");
|
|
1486
|
+
var invokeCompatibleAiChat = (options) => invokeAiChatWithUserMessageEncoding(
|
|
1487
|
+
options,
|
|
1488
|
+
(message) => message.format ?? "plain"
|
|
1489
|
+
);
|
|
1490
|
+
|
|
1338
1491
|
// src/ai.ts
|
|
1492
|
+
var invokeAiChat = (options) => invokeCompatibleAiChat(options);
|
|
1339
1493
|
var parseAIResponse = (input) => {
|
|
1340
1494
|
try {
|
|
1341
1495
|
if (typeof input === "object" && input !== null) return input;
|
|
@@ -1348,18 +1502,6 @@ var parseAIResponse = (input) => {
|
|
|
1348
1502
|
return {};
|
|
1349
1503
|
}
|
|
1350
1504
|
};
|
|
1351
|
-
var normalizeResponseContent = (content) => {
|
|
1352
|
-
if (typeof content === "string" || content && typeof content === "object") {
|
|
1353
|
-
if (typeof content !== "object" || !Array.isArray(content)) {
|
|
1354
|
-
return content;
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
if (Array.isArray(content)) {
|
|
1358
|
-
const text = content.map((part) => typeof part?.text === "string" ? part.text : "").join("\n").trim();
|
|
1359
|
-
return text;
|
|
1360
|
-
}
|
|
1361
|
-
return String(content ?? "");
|
|
1362
|
-
};
|
|
1363
1505
|
var normalizeAnalysis = (raw) => {
|
|
1364
1506
|
const direction = raw?.direction === "LONG" || raw?.direction === "SHORT" ? raw.direction : null;
|
|
1365
1507
|
const qualityNum = typeof raw?.quality === "number" ? Math.max(1, Math.min(5, Math.round(raw.quality))) : void 0;
|
|
@@ -1593,120 +1735,6 @@ Trade payload:
|
|
|
1593
1735
|
${JSON.stringify(payload)}
|
|
1594
1736
|
${buildAiHumanPromptAddonByStrategy(signal, payload)}
|
|
1595
1737
|
`;
|
|
1596
|
-
var getAiInvocationError = (error) => {
|
|
1597
|
-
const details = error instanceof Error && error.message.trim() ? error.message.trim() : String(error);
|
|
1598
|
-
const isEmptyCompletion = error instanceof TypeError && /Cannot read properties of undefined \(reading ['"]message['"]\)/.test(
|
|
1599
|
-
details
|
|
1600
|
-
);
|
|
1601
|
-
const wrapped = new Error(
|
|
1602
|
-
isEmptyCompletion ? "AI provider returned an empty chat completion" : `AI model invocation failed: ${details}`
|
|
1603
|
-
);
|
|
1604
|
-
wrapped.cause = error;
|
|
1605
|
-
return wrapped;
|
|
1606
|
-
};
|
|
1607
|
-
var isEmptyResponseContent = (content) => typeof content === "string" ? content.trim().length === 0 : Object.keys(content).length === 0;
|
|
1608
|
-
var DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
1609
|
-
var userSettingsCache = /* @__PURE__ */ new Map();
|
|
1610
|
-
var aiModelCache = /* @__PURE__ */ new Map();
|
|
1611
|
-
var getAiModelCacheKey = (userName, modelName) => `${userName}::${modelName}`;
|
|
1612
|
-
var resolveAiModelName = (settings, requestedModelName) => {
|
|
1613
|
-
const explicitModelName = typeof requestedModelName === "string" ? requestedModelName.trim() : "";
|
|
1614
|
-
if (explicitModelName) {
|
|
1615
|
-
return explicitModelName;
|
|
1616
|
-
}
|
|
1617
|
-
const settingsModelName = typeof settings.AI_MODEL === "string" ? settings.AI_MODEL.trim() : "";
|
|
1618
|
-
return settingsModelName || DEFAULT_AI_MODEL;
|
|
1619
|
-
};
|
|
1620
|
-
var getOpenRouterModelKwargs = (apiEndpoint) => {
|
|
1621
|
-
const endpoint = String(apiEndpoint ?? "").trim();
|
|
1622
|
-
if (!endpoint) {
|
|
1623
|
-
return {};
|
|
1624
|
-
}
|
|
1625
|
-
let hostname = "";
|
|
1626
|
-
try {
|
|
1627
|
-
hostname = new URL(endpoint).hostname;
|
|
1628
|
-
} catch {
|
|
1629
|
-
hostname = endpoint;
|
|
1630
|
-
}
|
|
1631
|
-
if (!hostname.toLowerCase().includes("openrouter")) {
|
|
1632
|
-
return {};
|
|
1633
|
-
}
|
|
1634
|
-
return {
|
|
1635
|
-
provider: {
|
|
1636
|
-
ignore: ["azure"]
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
};
|
|
1640
|
-
var getAiSettings = async (userName = "root") => {
|
|
1641
|
-
let settingsPromise = userSettingsCache.get(userName);
|
|
1642
|
-
if (!settingsPromise) {
|
|
1643
|
-
settingsPromise = (0, import_userSettings.getUserSettings)(userName).then((settings2) => {
|
|
1644
|
-
const endpoint = (0, import_aiEndpoints.normalizeAiEndpoint)(settings2.AI_API_ENDPOINT);
|
|
1645
|
-
return {
|
|
1646
|
-
...settings2,
|
|
1647
|
-
AI_API_ENDPOINT: endpoint,
|
|
1648
|
-
AI_MODEL: (0, import_aiModels.normalizeAiModel)(settings2.AI_MODEL, endpoint),
|
|
1649
|
-
AI_RESPONSE_LANGUAGE: (0, import_aiLanguages.normalizeAiResponseLanguage)(
|
|
1650
|
-
settings2.AI_RESPONSE_LANGUAGE
|
|
1651
|
-
)
|
|
1652
|
-
};
|
|
1653
|
-
});
|
|
1654
|
-
settingsPromise.catch(() => {
|
|
1655
|
-
userSettingsCache.delete(userName);
|
|
1656
|
-
});
|
|
1657
|
-
userSettingsCache.set(userName, settingsPromise);
|
|
1658
|
-
}
|
|
1659
|
-
const settings = await settingsPromise;
|
|
1660
|
-
if (!settings.AI_API_KEY || !settings.AI_API_ENDPOINT) {
|
|
1661
|
-
throw new Error(`AI settings are incomplete for user ${userName}`);
|
|
1662
|
-
}
|
|
1663
|
-
return settings;
|
|
1664
|
-
};
|
|
1665
|
-
var createAiModel = async (userName = "root", requestedModelName) => {
|
|
1666
|
-
const settings = await getAiSettings(userName);
|
|
1667
|
-
const modelName = resolveAiModelName(settings, requestedModelName);
|
|
1668
|
-
const cacheKey = getAiModelCacheKey(userName, modelName);
|
|
1669
|
-
let modelPromise = aiModelCache.get(cacheKey);
|
|
1670
|
-
if (!modelPromise) {
|
|
1671
|
-
modelPromise = (async () => {
|
|
1672
|
-
const { ChatOpenAI } = await import("@langchain/openai");
|
|
1673
|
-
const modelKwargs = getOpenRouterModelKwargs(settings.AI_API_ENDPOINT);
|
|
1674
|
-
return new ChatOpenAI({
|
|
1675
|
-
temperature: 0.2,
|
|
1676
|
-
modelName,
|
|
1677
|
-
apiKey: settings.AI_API_KEY,
|
|
1678
|
-
...Object.keys(modelKwargs).length ? { modelKwargs } : {},
|
|
1679
|
-
configuration: {
|
|
1680
|
-
baseURL: settings.AI_API_ENDPOINT,
|
|
1681
|
-
defaultHeaders: {
|
|
1682
|
-
"HTTP-Referer": "https://tradejs.dev",
|
|
1683
|
-
"X-Title": "Inv"
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
});
|
|
1687
|
-
})();
|
|
1688
|
-
modelPromise.catch(() => {
|
|
1689
|
-
aiModelCache.delete(cacheKey);
|
|
1690
|
-
});
|
|
1691
|
-
aiModelCache.set(cacheKey, modelPromise);
|
|
1692
|
-
}
|
|
1693
|
-
return modelPromise;
|
|
1694
|
-
};
|
|
1695
|
-
var getAiModel = async (userName = "root", requestedModelName) => {
|
|
1696
|
-
const settings = await getAiSettings(userName);
|
|
1697
|
-
const resolvedModelName = resolveAiModelName(settings, requestedModelName);
|
|
1698
|
-
try {
|
|
1699
|
-
return await createAiModel(userName, resolvedModelName);
|
|
1700
|
-
} catch (error) {
|
|
1701
|
-
aiModelCache.delete(getAiModelCacheKey(userName, resolvedModelName));
|
|
1702
|
-
userSettingsCache.delete(userName);
|
|
1703
|
-
throw error;
|
|
1704
|
-
}
|
|
1705
|
-
};
|
|
1706
|
-
var resetAiRuntimeCache = () => {
|
|
1707
|
-
aiModelCache.clear();
|
|
1708
|
-
userSettingsCache.clear();
|
|
1709
|
-
};
|
|
1710
1738
|
var buildAiPrompts = (signal) => {
|
|
1711
1739
|
const payload = buildAiPayload(signal);
|
|
1712
1740
|
return {
|
|
@@ -1715,42 +1743,23 @@ var buildAiPrompts = (signal) => {
|
|
|
1715
1743
|
};
|
|
1716
1744
|
};
|
|
1717
1745
|
var runAiPrompt = async ({ systemPrompt, humanPrompt }, options = {}) => {
|
|
1718
|
-
const
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
getAiSettings(options.userName)
|
|
1722
|
-
]);
|
|
1723
|
-
const messages = [];
|
|
1724
|
-
const responseLanguage = (0, import_aiLanguages.getAiResponseLanguagePromptName)(
|
|
1725
|
-
settings.AI_RESPONSE_LANGUAGE || import_aiLanguages.DEFAULT_AI_RESPONSE_LANGUAGE
|
|
1726
|
-
);
|
|
1727
|
-
messages.push(new SystemMessage(systemPrompt));
|
|
1728
|
-
messages.push(
|
|
1729
|
-
new SystemMessage(
|
|
1730
|
-
`Write all user-visible text fields in ${responseLanguage}. Keep field names and JSON syntax unchanged.`
|
|
1731
|
-
)
|
|
1746
|
+
const settings = await getAiUserSettings(options.userName);
|
|
1747
|
+
const responseLanguage = (0, import_aiLanguages2.getAiResponseLanguagePromptName)(
|
|
1748
|
+
settings.AI_RESPONSE_LANGUAGE || import_aiLanguages2.DEFAULT_AI_RESPONSE_LANGUAGE
|
|
1732
1749
|
);
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
} catch (error) {
|
|
1747
|
-
throw getAiInvocationError(error);
|
|
1748
|
-
}
|
|
1749
|
-
const responseContent = normalizeResponseContent(response?.content);
|
|
1750
|
-
if (isEmptyResponseContent(responseContent)) {
|
|
1751
|
-
throw new Error("AI provider returned an empty chat completion");
|
|
1752
|
-
}
|
|
1753
|
-
const parsed = parseAIResponse(responseContent);
|
|
1750
|
+
const response = await invokeAiPromptChat({
|
|
1751
|
+
userName: options.userName,
|
|
1752
|
+
model: options.model,
|
|
1753
|
+
messages: [
|
|
1754
|
+
{ role: "system", content: systemPrompt },
|
|
1755
|
+
{
|
|
1756
|
+
role: "system",
|
|
1757
|
+
content: `Write all user-visible text fields in ${responseLanguage}. Keep field names and JSON syntax unchanged.`
|
|
1758
|
+
},
|
|
1759
|
+
{ role: "user", content: humanPrompt }
|
|
1760
|
+
]
|
|
1761
|
+
});
|
|
1762
|
+
const parsed = parseAIResponse(response.content);
|
|
1754
1763
|
const normalized = normalizeAnalysis(parsed);
|
|
1755
1764
|
if (!options.signal) {
|
|
1756
1765
|
return normalized;
|
|
@@ -4537,6 +4546,7 @@ var executeEntryOrder = async ({
|
|
|
4537
4546
|
deploymentId: signal.deploymentId,
|
|
4538
4547
|
policyProfileId: signal.policyProfileId,
|
|
4539
4548
|
runtimeConfigId: signal.runtimeConfigId,
|
|
4549
|
+
runtimeReleaseVersion: signal.runtimeReleaseVersion,
|
|
4540
4550
|
runtimeLineage: signal.runtimeLineage,
|
|
4541
4551
|
...signal.aiAnalysis ? { aiAnalysis: signal.aiAnalysis } : {}
|
|
4542
4552
|
});
|
|
@@ -5461,6 +5471,9 @@ var createStrategyRuntime = ({
|
|
|
5461
5471
|
deploymentId: requestedDeploymentId,
|
|
5462
5472
|
policyProfileId,
|
|
5463
5473
|
runtimeConfigId,
|
|
5474
|
+
runtimeReleaseVersion,
|
|
5475
|
+
entriesPaused = false,
|
|
5476
|
+
runtimeLineage,
|
|
5464
5477
|
runtimeConfigSnapshot,
|
|
5465
5478
|
data,
|
|
5466
5479
|
btcData,
|
|
@@ -6119,6 +6132,7 @@ var createStrategyRuntime = ({
|
|
|
6119
6132
|
});
|
|
6120
6133
|
const signal = decision.signal;
|
|
6121
6134
|
if (signal) {
|
|
6135
|
+
if (runtimeLineage) signal.runtimeLineage = runtimeLineage;
|
|
6122
6136
|
if (universe) signal.universe = universe;
|
|
6123
6137
|
if (assetClass) signal.assetClass = assetClass;
|
|
6124
6138
|
if (accountId) signal.accountId = accountId;
|
|
@@ -6129,6 +6143,9 @@ var createStrategyRuntime = ({
|
|
|
6129
6143
|
signal.signalId = `${signal.signalId}:${runtimeConfigId}`;
|
|
6130
6144
|
}
|
|
6131
6145
|
}
|
|
6146
|
+
if (runtimeReleaseVersion) {
|
|
6147
|
+
signal.runtimeReleaseVersion = runtimeReleaseVersion;
|
|
6148
|
+
}
|
|
6132
6149
|
if (decisionHookCtx.policyProfileId) {
|
|
6133
6150
|
signal.policyProfileId = decisionHookCtx.policyProfileId;
|
|
6134
6151
|
}
|
|
@@ -6235,6 +6252,15 @@ var createStrategyRuntime = ({
|
|
|
6235
6252
|
quality,
|
|
6236
6253
|
minAiQuality
|
|
6237
6254
|
});
|
|
6255
|
+
if (entriesPaused) {
|
|
6256
|
+
const skipReason = "RUNTIME_ENTRIES_PAUSED";
|
|
6257
|
+
if (signal) {
|
|
6258
|
+
signal.orderStatus = "skipped";
|
|
6259
|
+
signal.orderSkipReason = skipReason;
|
|
6260
|
+
signal.runtimeReleaseVersion = runtimeReleaseVersion;
|
|
6261
|
+
}
|
|
6262
|
+
return signal ?? skipReason;
|
|
6263
|
+
}
|
|
6238
6264
|
if (!shouldMakeOrder) {
|
|
6239
6265
|
if (signal) {
|
|
6240
6266
|
signal.orderStatus = "skipped";
|
|
@@ -6749,7 +6775,10 @@ var createCloseAllOnGlobalProfitBeforeSignalsHook = ({
|
|
|
6749
6775
|
getRegisteredManifests,
|
|
6750
6776
|
getRegisteredStrategies,
|
|
6751
6777
|
getStrategyCreator,
|
|
6778
|
+
getStrategyDefaults,
|
|
6752
6779
|
getStrategyManifest,
|
|
6780
|
+
getStrategyPluginSource,
|
|
6781
|
+
invokeAiChat,
|
|
6753
6782
|
isKnownStrategy,
|
|
6754
6783
|
isTrackedHyperliquidPerp,
|
|
6755
6784
|
isTrackedHyperliquidWhale,
|