@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/README.md
CHANGED
|
@@ -63,6 +63,8 @@ Import only explicit subpaths:
|
|
|
63
63
|
- `@tradejs/node/connectors`
|
|
64
64
|
- `@tradejs/node/cli`
|
|
65
65
|
- `@tradejs/node/constants`
|
|
66
|
+
- `@tradejs/node/runtimeTrades`
|
|
67
|
+
- `@tradejs/node/runtimeDashboard`
|
|
66
68
|
|
|
67
69
|
There is no root `@tradejs/node` import surface.
|
|
68
70
|
|
|
@@ -78,3 +80,5 @@ import { createStrategyRuntime } from '@tradejs/node/strategies';
|
|
|
78
80
|
- Do not import it into browser/client bundles.
|
|
79
81
|
- For plugin/config declaration and browser-safe helpers, use `@tradejs/core`.
|
|
80
82
|
- For shared contracts, use `@tradejs/types`.
|
|
83
|
+
|
|
84
|
+
Keywords: ai, claude, codex.
|
package/dist/ai.d.mts
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { Signal, AiPayload, SignalAnalysis, AiPromptPair } from '@tradejs/types';
|
|
2
2
|
|
|
3
|
+
interface AiChatMessage$1 {
|
|
4
|
+
role: 'system' | 'user';
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
interface InvokeAiChatOptions$1 {
|
|
8
|
+
messages: AiChatMessage$1[];
|
|
9
|
+
userName?: string;
|
|
10
|
+
model?: string;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
}
|
|
13
|
+
declare const DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
14
|
+
declare const getOpenRouterModelKwargs: (apiEndpoint?: string | null) => Record<string, unknown>;
|
|
15
|
+
declare const resetAiRuntimeCache: () => void;
|
|
16
|
+
|
|
3
17
|
declare const MAX_AI_SERIES_POINTS = 5;
|
|
4
18
|
declare const trimSeriesDeep: (value: any) => any;
|
|
5
19
|
declare const buildCompactAiIndicatorsSnapshot: (value: any) => any;
|
|
6
20
|
|
|
21
|
+
interface AiChatMessage extends AiChatMessage$1 {
|
|
22
|
+
/** @deprecated Provider formatting is retained for API compatibility only. */
|
|
23
|
+
format?: 'plain' | 'text-block';
|
|
24
|
+
}
|
|
25
|
+
type InvokeAiChatOptions = Omit<InvokeAiChatOptions$1, 'messages'> & {
|
|
26
|
+
messages: AiChatMessage[];
|
|
27
|
+
};
|
|
28
|
+
declare const invokeAiChat: (options: InvokeAiChatOptions) => Promise<{
|
|
29
|
+
content: string | object;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
7
32
|
type DeterministicAiGateContext = {
|
|
8
33
|
approvalAllowedNow?: boolean;
|
|
9
34
|
deterministicQuality?: number;
|
|
@@ -22,12 +47,9 @@ interface AiRequestOptions {
|
|
|
22
47
|
payload?: AiPayload;
|
|
23
48
|
model?: string;
|
|
24
49
|
}
|
|
25
|
-
declare const DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
26
|
-
declare const getOpenRouterModelKwargs: (apiEndpoint?: string | null) => Record<string, unknown>;
|
|
27
|
-
declare const resetAiRuntimeCache: () => void;
|
|
28
50
|
declare const buildAiPrompts: (signal: Signal) => AiPromptPair;
|
|
29
51
|
declare const runAiPrompt: ({ systemPrompt, humanPrompt }: AiPromptPair, options?: AiRequestOptions) => Promise<Partial<SignalAnalysis>>;
|
|
30
52
|
declare const runAiPromptLocal: (signal: Signal, options?: Omit<AiRequestOptions, "model" | "userName">) => Promise<Partial<SignalAnalysis>>;
|
|
31
53
|
declare const askAI: (signal: Signal, options?: AiRequestOptions) => Promise<Partial<SignalAnalysis>>;
|
|
32
54
|
|
|
33
|
-
export { DEFAULT_AI_MODEL, MAX_AI_SERIES_POINTS, askAI, buildAiHumanPrompt, buildAiPayload, buildAiPrompts, buildAiSystemPrompt, buildCompactAiIndicatorsSnapshot, getDeterministicAiGateContext, getOpenRouterModelKwargs, resetAiRuntimeCache, runAiPrompt, runAiPromptLocal, trimSeriesDeep };
|
|
55
|
+
export { type AiChatMessage, DEFAULT_AI_MODEL, type InvokeAiChatOptions, MAX_AI_SERIES_POINTS, askAI, buildAiHumanPrompt, buildAiPayload, buildAiPrompts, buildAiSystemPrompt, buildCompactAiIndicatorsSnapshot, getDeterministicAiGateContext, getOpenRouterModelKwargs, invokeAiChat, resetAiRuntimeCache, runAiPrompt, runAiPromptLocal, trimSeriesDeep };
|
package/dist/ai.d.ts
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
import { Signal, AiPayload, SignalAnalysis, AiPromptPair } from '@tradejs/types';
|
|
2
2
|
|
|
3
|
+
interface AiChatMessage$1 {
|
|
4
|
+
role: 'system' | 'user';
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
interface InvokeAiChatOptions$1 {
|
|
8
|
+
messages: AiChatMessage$1[];
|
|
9
|
+
userName?: string;
|
|
10
|
+
model?: string;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
}
|
|
13
|
+
declare const DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
14
|
+
declare const getOpenRouterModelKwargs: (apiEndpoint?: string | null) => Record<string, unknown>;
|
|
15
|
+
declare const resetAiRuntimeCache: () => void;
|
|
16
|
+
|
|
3
17
|
declare const MAX_AI_SERIES_POINTS = 5;
|
|
4
18
|
declare const trimSeriesDeep: (value: any) => any;
|
|
5
19
|
declare const buildCompactAiIndicatorsSnapshot: (value: any) => any;
|
|
6
20
|
|
|
21
|
+
interface AiChatMessage extends AiChatMessage$1 {
|
|
22
|
+
/** @deprecated Provider formatting is retained for API compatibility only. */
|
|
23
|
+
format?: 'plain' | 'text-block';
|
|
24
|
+
}
|
|
25
|
+
type InvokeAiChatOptions = Omit<InvokeAiChatOptions$1, 'messages'> & {
|
|
26
|
+
messages: AiChatMessage[];
|
|
27
|
+
};
|
|
28
|
+
declare const invokeAiChat: (options: InvokeAiChatOptions) => Promise<{
|
|
29
|
+
content: string | object;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
7
32
|
type DeterministicAiGateContext = {
|
|
8
33
|
approvalAllowedNow?: boolean;
|
|
9
34
|
deterministicQuality?: number;
|
|
@@ -22,12 +47,9 @@ interface AiRequestOptions {
|
|
|
22
47
|
payload?: AiPayload;
|
|
23
48
|
model?: string;
|
|
24
49
|
}
|
|
25
|
-
declare const DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
26
|
-
declare const getOpenRouterModelKwargs: (apiEndpoint?: string | null) => Record<string, unknown>;
|
|
27
|
-
declare const resetAiRuntimeCache: () => void;
|
|
28
50
|
declare const buildAiPrompts: (signal: Signal) => AiPromptPair;
|
|
29
51
|
declare const runAiPrompt: ({ systemPrompt, humanPrompt }: AiPromptPair, options?: AiRequestOptions) => Promise<Partial<SignalAnalysis>>;
|
|
30
52
|
declare const runAiPromptLocal: (signal: Signal, options?: Omit<AiRequestOptions, "model" | "userName">) => Promise<Partial<SignalAnalysis>>;
|
|
31
53
|
declare const askAI: (signal: Signal, options?: AiRequestOptions) => Promise<Partial<SignalAnalysis>>;
|
|
32
54
|
|
|
33
|
-
export { DEFAULT_AI_MODEL, MAX_AI_SERIES_POINTS, askAI, buildAiHumanPrompt, buildAiPayload, buildAiPrompts, buildAiSystemPrompt, buildCompactAiIndicatorsSnapshot, getDeterministicAiGateContext, getOpenRouterModelKwargs, resetAiRuntimeCache, runAiPrompt, runAiPromptLocal, trimSeriesDeep };
|
|
55
|
+
export { type AiChatMessage, DEFAULT_AI_MODEL, type InvokeAiChatOptions, MAX_AI_SERIES_POINTS, askAI, buildAiHumanPrompt, buildAiPayload, buildAiPrompts, buildAiSystemPrompt, buildCompactAiIndicatorsSnapshot, getDeterministicAiGateContext, getOpenRouterModelKwargs, invokeAiChat, resetAiRuntimeCache, runAiPrompt, runAiPromptLocal, trimSeriesDeep };
|
package/dist/ai.js
CHANGED
|
@@ -40,17 +40,15 @@ __export(ai_exports, {
|
|
|
40
40
|
buildCompactAiIndicatorsSnapshot: () => buildCompactAiIndicatorsSnapshot,
|
|
41
41
|
getDeterministicAiGateContext: () => getDeterministicAiGateContext,
|
|
42
42
|
getOpenRouterModelKwargs: () => getOpenRouterModelKwargs,
|
|
43
|
+
invokeAiChat: () => invokeAiChat,
|
|
43
44
|
resetAiRuntimeCache: () => resetAiRuntimeCache,
|
|
44
45
|
runAiPrompt: () => runAiPrompt,
|
|
45
46
|
runAiPromptLocal: () => runAiPromptLocal,
|
|
46
47
|
trimSeriesDeep: () => trimSeriesDeep
|
|
47
48
|
});
|
|
48
49
|
module.exports = __toCommonJS(ai_exports);
|
|
49
|
-
var
|
|
50
|
-
var import_aiEndpoints = require("@tradejs/core/aiEndpoints");
|
|
51
|
-
var import_aiModels = require("@tradejs/core/aiModels");
|
|
50
|
+
var import_aiLanguages2 = require("@tradejs/core/aiLanguages");
|
|
52
51
|
var import_redis = require("@tradejs/infra/redis");
|
|
53
|
-
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
54
52
|
|
|
55
53
|
// src/aiShared.ts
|
|
56
54
|
var MAX_AI_SERIES_POINTS = 5;
|
|
@@ -654,6 +652,7 @@ var createStrategyRegistryState = () => ({
|
|
|
654
652
|
strategyCreators: /* @__PURE__ */ new Map(),
|
|
655
653
|
strategyManifestsMap: /* @__PURE__ */ new Map(),
|
|
656
654
|
strategyEntriesMap: /* @__PURE__ */ new Map(),
|
|
655
|
+
strategySourcesMap: /* @__PURE__ */ new Map(),
|
|
657
656
|
pluginsLoadPromise: null
|
|
658
657
|
});
|
|
659
658
|
var registryStateByProjectRoot = sharedStrategyRegistry.registryStateByProjectRoot;
|
|
@@ -757,7 +756,149 @@ var postProcessLocalAiAnalysisByStrategy = (signal, analysis, payload = buildAiP
|
|
|
757
756
|
}) ?? strategyAnalysis;
|
|
758
757
|
};
|
|
759
758
|
|
|
759
|
+
// src/aiProvider.ts
|
|
760
|
+
var import_aiEndpoints = require("@tradejs/core/aiEndpoints");
|
|
761
|
+
var import_aiModels = require("@tradejs/core/aiModels");
|
|
762
|
+
var import_aiLanguages = require("@tradejs/core/aiLanguages");
|
|
763
|
+
var import_userSettings = require("@tradejs/infra/userSettings");
|
|
764
|
+
var DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
765
|
+
var userSettingsCache = /* @__PURE__ */ new Map();
|
|
766
|
+
var aiModelCache = /* @__PURE__ */ new Map();
|
|
767
|
+
var normalizeResponseContent = (content) => {
|
|
768
|
+
if (typeof content === "string") return content;
|
|
769
|
+
if (content && typeof content === "object" && !Array.isArray(content)) {
|
|
770
|
+
return content;
|
|
771
|
+
}
|
|
772
|
+
if (Array.isArray(content)) {
|
|
773
|
+
return content.map(
|
|
774
|
+
(part) => typeof part?.text === "string" ? part.text : ""
|
|
775
|
+
).join("\n").trim();
|
|
776
|
+
}
|
|
777
|
+
return String(content ?? "");
|
|
778
|
+
};
|
|
779
|
+
var getAiInvocationError = (error) => {
|
|
780
|
+
const details = error instanceof Error && error.message.trim() ? error.message.trim() : String(error);
|
|
781
|
+
const isEmptyCompletion = error instanceof TypeError && /Cannot read properties of undefined \(reading ['"]message['"]\)/.test(
|
|
782
|
+
details
|
|
783
|
+
);
|
|
784
|
+
const wrapped = new Error(
|
|
785
|
+
isEmptyCompletion ? "AI provider returned an empty chat completion" : `AI model invocation failed: ${details}`
|
|
786
|
+
);
|
|
787
|
+
wrapped.cause = error;
|
|
788
|
+
return wrapped;
|
|
789
|
+
};
|
|
790
|
+
var isEmptyResponseContent = (content) => typeof content === "string" ? content.trim().length === 0 : Object.keys(content).length === 0;
|
|
791
|
+
var getAiModelCacheKey = (userName, modelName, temperature) => `${userName}::${modelName}::${temperature}`;
|
|
792
|
+
var resolveAiModelName = (settings, requestedModelName) => {
|
|
793
|
+
const explicitModelName = requestedModelName?.trim() ?? "";
|
|
794
|
+
if (explicitModelName) return explicitModelName;
|
|
795
|
+
return settings.AI_MODEL?.trim() || DEFAULT_AI_MODEL;
|
|
796
|
+
};
|
|
797
|
+
var getOpenRouterModelKwargs = (apiEndpoint) => {
|
|
798
|
+
const endpoint = String(apiEndpoint ?? "").trim();
|
|
799
|
+
if (!endpoint) return {};
|
|
800
|
+
let hostname = "";
|
|
801
|
+
try {
|
|
802
|
+
hostname = new URL(endpoint).hostname;
|
|
803
|
+
} catch {
|
|
804
|
+
hostname = endpoint;
|
|
805
|
+
}
|
|
806
|
+
return hostname.toLowerCase().includes("openrouter") ? { provider: { ignore: ["azure"] } } : {};
|
|
807
|
+
};
|
|
808
|
+
var getAiUserSettings = async (userName = "root") => {
|
|
809
|
+
let settingsPromise = userSettingsCache.get(userName);
|
|
810
|
+
if (!settingsPromise) {
|
|
811
|
+
settingsPromise = (0, import_userSettings.getUserSettings)(userName).then((settings2) => {
|
|
812
|
+
const endpoint = (0, import_aiEndpoints.normalizeAiEndpoint)(settings2.AI_API_ENDPOINT);
|
|
813
|
+
return {
|
|
814
|
+
...settings2,
|
|
815
|
+
AI_API_ENDPOINT: endpoint,
|
|
816
|
+
AI_MODEL: (0, import_aiModels.normalizeAiModel)(settings2.AI_MODEL, endpoint),
|
|
817
|
+
AI_RESPONSE_LANGUAGE: (0, import_aiLanguages.normalizeAiResponseLanguage)(
|
|
818
|
+
settings2.AI_RESPONSE_LANGUAGE
|
|
819
|
+
)
|
|
820
|
+
};
|
|
821
|
+
});
|
|
822
|
+
settingsPromise.catch(() => userSettingsCache.delete(userName));
|
|
823
|
+
userSettingsCache.set(userName, settingsPromise);
|
|
824
|
+
}
|
|
825
|
+
const settings = await settingsPromise;
|
|
826
|
+
if (!settings.AI_API_KEY || !settings.AI_API_ENDPOINT) {
|
|
827
|
+
throw new Error(`AI settings are incomplete for user ${userName}`);
|
|
828
|
+
}
|
|
829
|
+
return settings;
|
|
830
|
+
};
|
|
831
|
+
var getAiModel = async (userName = "root", requestedModelName, temperature = 0.2) => {
|
|
832
|
+
const settings = await getAiUserSettings(userName);
|
|
833
|
+
const modelName = resolveAiModelName(settings, requestedModelName);
|
|
834
|
+
const cacheKey = getAiModelCacheKey(userName, modelName, temperature);
|
|
835
|
+
let modelPromise = aiModelCache.get(cacheKey);
|
|
836
|
+
if (!modelPromise) {
|
|
837
|
+
modelPromise = import("@langchain/openai").then(({ ChatOpenAI }) => {
|
|
838
|
+
const modelKwargs = getOpenRouterModelKwargs(settings.AI_API_ENDPOINT);
|
|
839
|
+
return new ChatOpenAI({
|
|
840
|
+
temperature,
|
|
841
|
+
modelName,
|
|
842
|
+
apiKey: settings.AI_API_KEY,
|
|
843
|
+
...Object.keys(modelKwargs).length ? { modelKwargs } : {},
|
|
844
|
+
configuration: {
|
|
845
|
+
baseURL: settings.AI_API_ENDPOINT,
|
|
846
|
+
defaultHeaders: {
|
|
847
|
+
"HTTP-Referer": "https://tradejs.dev",
|
|
848
|
+
"X-Title": "Inv"
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
});
|
|
853
|
+
modelPromise.catch(() => aiModelCache.delete(cacheKey));
|
|
854
|
+
aiModelCache.set(cacheKey, modelPromise);
|
|
855
|
+
}
|
|
856
|
+
try {
|
|
857
|
+
return await modelPromise;
|
|
858
|
+
} catch (error) {
|
|
859
|
+
aiModelCache.delete(cacheKey);
|
|
860
|
+
userSettingsCache.delete(userName);
|
|
861
|
+
throw error;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
var resetAiRuntimeCache = () => {
|
|
865
|
+
aiModelCache.clear();
|
|
866
|
+
userSettingsCache.clear();
|
|
867
|
+
};
|
|
868
|
+
var invokeAiChatWithUserMessageEncoding = async ({
|
|
869
|
+
messages,
|
|
870
|
+
userName = "root",
|
|
871
|
+
model,
|
|
872
|
+
temperature = 0.2
|
|
873
|
+
}, resolveUserMessageEncoding) => {
|
|
874
|
+
const [{ HumanMessage, SystemMessage }, aiModel] = await Promise.all([
|
|
875
|
+
import("@langchain/core/messages"),
|
|
876
|
+
getAiModel(userName, model, temperature)
|
|
877
|
+
]);
|
|
878
|
+
const providerMessages = messages.map(
|
|
879
|
+
(message) => message.role === "system" ? new SystemMessage(message.content) : new HumanMessage(
|
|
880
|
+
resolveUserMessageEncoding(message) === "text-block" ? { content: [{ type: "text", text: message.content }] } : message.content
|
|
881
|
+
)
|
|
882
|
+
);
|
|
883
|
+
try {
|
|
884
|
+
const response = await aiModel.invoke(providerMessages);
|
|
885
|
+
const content = normalizeResponseContent(response?.content);
|
|
886
|
+
if (isEmptyResponseContent(content)) {
|
|
887
|
+
throw new Error("AI provider returned an empty chat completion");
|
|
888
|
+
}
|
|
889
|
+
return { content };
|
|
890
|
+
} catch (error) {
|
|
891
|
+
throw getAiInvocationError(error);
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
var invokeAiPromptChat = (options) => invokeAiChatWithUserMessageEncoding(options, () => "text-block");
|
|
895
|
+
var invokeCompatibleAiChat = (options) => invokeAiChatWithUserMessageEncoding(
|
|
896
|
+
options,
|
|
897
|
+
(message) => message.format ?? "plain"
|
|
898
|
+
);
|
|
899
|
+
|
|
760
900
|
// src/ai.ts
|
|
901
|
+
var invokeAiChat = (options) => invokeCompatibleAiChat(options);
|
|
761
902
|
var parseAIResponse = (input) => {
|
|
762
903
|
try {
|
|
763
904
|
if (typeof input === "object" && input !== null) return input;
|
|
@@ -770,18 +911,6 @@ var parseAIResponse = (input) => {
|
|
|
770
911
|
return {};
|
|
771
912
|
}
|
|
772
913
|
};
|
|
773
|
-
var normalizeResponseContent = (content) => {
|
|
774
|
-
if (typeof content === "string" || content && typeof content === "object") {
|
|
775
|
-
if (typeof content !== "object" || !Array.isArray(content)) {
|
|
776
|
-
return content;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
if (Array.isArray(content)) {
|
|
780
|
-
const text = content.map((part) => typeof part?.text === "string" ? part.text : "").join("\n").trim();
|
|
781
|
-
return text;
|
|
782
|
-
}
|
|
783
|
-
return String(content ?? "");
|
|
784
|
-
};
|
|
785
914
|
var normalizeAnalysis = (raw) => {
|
|
786
915
|
const direction = raw?.direction === "LONG" || raw?.direction === "SHORT" ? raw.direction : null;
|
|
787
916
|
const qualityNum = typeof raw?.quality === "number" ? Math.max(1, Math.min(5, Math.round(raw.quality))) : void 0;
|
|
@@ -1015,120 +1144,6 @@ Trade payload:
|
|
|
1015
1144
|
${JSON.stringify(payload)}
|
|
1016
1145
|
${buildAiHumanPromptAddonByStrategy(signal, payload)}
|
|
1017
1146
|
`;
|
|
1018
|
-
var getAiInvocationError = (error) => {
|
|
1019
|
-
const details = error instanceof Error && error.message.trim() ? error.message.trim() : String(error);
|
|
1020
|
-
const isEmptyCompletion = error instanceof TypeError && /Cannot read properties of undefined \(reading ['"]message['"]\)/.test(
|
|
1021
|
-
details
|
|
1022
|
-
);
|
|
1023
|
-
const wrapped = new Error(
|
|
1024
|
-
isEmptyCompletion ? "AI provider returned an empty chat completion" : `AI model invocation failed: ${details}`
|
|
1025
|
-
);
|
|
1026
|
-
wrapped.cause = error;
|
|
1027
|
-
return wrapped;
|
|
1028
|
-
};
|
|
1029
|
-
var isEmptyResponseContent = (content) => typeof content === "string" ? content.trim().length === 0 : Object.keys(content).length === 0;
|
|
1030
|
-
var DEFAULT_AI_MODEL = "openai/gpt-5-mini";
|
|
1031
|
-
var userSettingsCache = /* @__PURE__ */ new Map();
|
|
1032
|
-
var aiModelCache = /* @__PURE__ */ new Map();
|
|
1033
|
-
var getAiModelCacheKey = (userName, modelName) => `${userName}::${modelName}`;
|
|
1034
|
-
var resolveAiModelName = (settings, requestedModelName) => {
|
|
1035
|
-
const explicitModelName = typeof requestedModelName === "string" ? requestedModelName.trim() : "";
|
|
1036
|
-
if (explicitModelName) {
|
|
1037
|
-
return explicitModelName;
|
|
1038
|
-
}
|
|
1039
|
-
const settingsModelName = typeof settings.AI_MODEL === "string" ? settings.AI_MODEL.trim() : "";
|
|
1040
|
-
return settingsModelName || DEFAULT_AI_MODEL;
|
|
1041
|
-
};
|
|
1042
|
-
var getOpenRouterModelKwargs = (apiEndpoint) => {
|
|
1043
|
-
const endpoint = String(apiEndpoint ?? "").trim();
|
|
1044
|
-
if (!endpoint) {
|
|
1045
|
-
return {};
|
|
1046
|
-
}
|
|
1047
|
-
let hostname = "";
|
|
1048
|
-
try {
|
|
1049
|
-
hostname = new URL(endpoint).hostname;
|
|
1050
|
-
} catch {
|
|
1051
|
-
hostname = endpoint;
|
|
1052
|
-
}
|
|
1053
|
-
if (!hostname.toLowerCase().includes("openrouter")) {
|
|
1054
|
-
return {};
|
|
1055
|
-
}
|
|
1056
|
-
return {
|
|
1057
|
-
provider: {
|
|
1058
|
-
ignore: ["azure"]
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
};
|
|
1062
|
-
var getAiSettings = async (userName = "root") => {
|
|
1063
|
-
let settingsPromise = userSettingsCache.get(userName);
|
|
1064
|
-
if (!settingsPromise) {
|
|
1065
|
-
settingsPromise = (0, import_userSettings.getUserSettings)(userName).then((settings2) => {
|
|
1066
|
-
const endpoint = (0, import_aiEndpoints.normalizeAiEndpoint)(settings2.AI_API_ENDPOINT);
|
|
1067
|
-
return {
|
|
1068
|
-
...settings2,
|
|
1069
|
-
AI_API_ENDPOINT: endpoint,
|
|
1070
|
-
AI_MODEL: (0, import_aiModels.normalizeAiModel)(settings2.AI_MODEL, endpoint),
|
|
1071
|
-
AI_RESPONSE_LANGUAGE: (0, import_aiLanguages.normalizeAiResponseLanguage)(
|
|
1072
|
-
settings2.AI_RESPONSE_LANGUAGE
|
|
1073
|
-
)
|
|
1074
|
-
};
|
|
1075
|
-
});
|
|
1076
|
-
settingsPromise.catch(() => {
|
|
1077
|
-
userSettingsCache.delete(userName);
|
|
1078
|
-
});
|
|
1079
|
-
userSettingsCache.set(userName, settingsPromise);
|
|
1080
|
-
}
|
|
1081
|
-
const settings = await settingsPromise;
|
|
1082
|
-
if (!settings.AI_API_KEY || !settings.AI_API_ENDPOINT) {
|
|
1083
|
-
throw new Error(`AI settings are incomplete for user ${userName}`);
|
|
1084
|
-
}
|
|
1085
|
-
return settings;
|
|
1086
|
-
};
|
|
1087
|
-
var createAiModel = async (userName = "root", requestedModelName) => {
|
|
1088
|
-
const settings = await getAiSettings(userName);
|
|
1089
|
-
const modelName = resolveAiModelName(settings, requestedModelName);
|
|
1090
|
-
const cacheKey = getAiModelCacheKey(userName, modelName);
|
|
1091
|
-
let modelPromise = aiModelCache.get(cacheKey);
|
|
1092
|
-
if (!modelPromise) {
|
|
1093
|
-
modelPromise = (async () => {
|
|
1094
|
-
const { ChatOpenAI } = await import("@langchain/openai");
|
|
1095
|
-
const modelKwargs = getOpenRouterModelKwargs(settings.AI_API_ENDPOINT);
|
|
1096
|
-
return new ChatOpenAI({
|
|
1097
|
-
temperature: 0.2,
|
|
1098
|
-
modelName,
|
|
1099
|
-
apiKey: settings.AI_API_KEY,
|
|
1100
|
-
...Object.keys(modelKwargs).length ? { modelKwargs } : {},
|
|
1101
|
-
configuration: {
|
|
1102
|
-
baseURL: settings.AI_API_ENDPOINT,
|
|
1103
|
-
defaultHeaders: {
|
|
1104
|
-
"HTTP-Referer": "https://tradejs.dev",
|
|
1105
|
-
"X-Title": "Inv"
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
});
|
|
1109
|
-
})();
|
|
1110
|
-
modelPromise.catch(() => {
|
|
1111
|
-
aiModelCache.delete(cacheKey);
|
|
1112
|
-
});
|
|
1113
|
-
aiModelCache.set(cacheKey, modelPromise);
|
|
1114
|
-
}
|
|
1115
|
-
return modelPromise;
|
|
1116
|
-
};
|
|
1117
|
-
var getAiModel = async (userName = "root", requestedModelName) => {
|
|
1118
|
-
const settings = await getAiSettings(userName);
|
|
1119
|
-
const resolvedModelName = resolveAiModelName(settings, requestedModelName);
|
|
1120
|
-
try {
|
|
1121
|
-
return await createAiModel(userName, resolvedModelName);
|
|
1122
|
-
} catch (error) {
|
|
1123
|
-
aiModelCache.delete(getAiModelCacheKey(userName, resolvedModelName));
|
|
1124
|
-
userSettingsCache.delete(userName);
|
|
1125
|
-
throw error;
|
|
1126
|
-
}
|
|
1127
|
-
};
|
|
1128
|
-
var resetAiRuntimeCache = () => {
|
|
1129
|
-
aiModelCache.clear();
|
|
1130
|
-
userSettingsCache.clear();
|
|
1131
|
-
};
|
|
1132
1147
|
var buildAiPrompts = (signal) => {
|
|
1133
1148
|
const payload = buildAiPayload(signal);
|
|
1134
1149
|
return {
|
|
@@ -1137,42 +1152,23 @@ var buildAiPrompts = (signal) => {
|
|
|
1137
1152
|
};
|
|
1138
1153
|
};
|
|
1139
1154
|
var runAiPrompt = async ({ systemPrompt, humanPrompt }, options = {}) => {
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
getAiSettings(options.userName)
|
|
1144
|
-
]);
|
|
1145
|
-
const messages = [];
|
|
1146
|
-
const responseLanguage = (0, import_aiLanguages.getAiResponseLanguagePromptName)(
|
|
1147
|
-
settings.AI_RESPONSE_LANGUAGE || import_aiLanguages.DEFAULT_AI_RESPONSE_LANGUAGE
|
|
1148
|
-
);
|
|
1149
|
-
messages.push(new SystemMessage(systemPrompt));
|
|
1150
|
-
messages.push(
|
|
1151
|
-
new SystemMessage(
|
|
1152
|
-
`Write all user-visible text fields in ${responseLanguage}. Keep field names and JSON syntax unchanged.`
|
|
1153
|
-
)
|
|
1154
|
-
);
|
|
1155
|
-
messages.push(
|
|
1156
|
-
new HumanMessage({
|
|
1157
|
-
content: [
|
|
1158
|
-
{
|
|
1159
|
-
type: "text",
|
|
1160
|
-
text: humanPrompt
|
|
1161
|
-
}
|
|
1162
|
-
]
|
|
1163
|
-
})
|
|
1155
|
+
const settings = await getAiUserSettings(options.userName);
|
|
1156
|
+
const responseLanguage = (0, import_aiLanguages2.getAiResponseLanguagePromptName)(
|
|
1157
|
+
settings.AI_RESPONSE_LANGUAGE || import_aiLanguages2.DEFAULT_AI_RESPONSE_LANGUAGE
|
|
1164
1158
|
);
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1159
|
+
const response = await invokeAiPromptChat({
|
|
1160
|
+
userName: options.userName,
|
|
1161
|
+
model: options.model,
|
|
1162
|
+
messages: [
|
|
1163
|
+
{ role: "system", content: systemPrompt },
|
|
1164
|
+
{
|
|
1165
|
+
role: "system",
|
|
1166
|
+
content: `Write all user-visible text fields in ${responseLanguage}. Keep field names and JSON syntax unchanged.`
|
|
1167
|
+
},
|
|
1168
|
+
{ role: "user", content: humanPrompt }
|
|
1169
|
+
]
|
|
1170
|
+
});
|
|
1171
|
+
const parsed = parseAIResponse(response.content);
|
|
1176
1172
|
const normalized = normalizeAnalysis(parsed);
|
|
1177
1173
|
if (!options.signal) {
|
|
1178
1174
|
return normalized;
|
|
@@ -1231,6 +1227,7 @@ var askAI = async (signal, options = {}) => {
|
|
|
1231
1227
|
buildCompactAiIndicatorsSnapshot,
|
|
1232
1228
|
getDeterministicAiGateContext,
|
|
1233
1229
|
getOpenRouterModelKwargs,
|
|
1230
|
+
invokeAiChat,
|
|
1234
1231
|
resetAiRuntimeCache,
|
|
1235
1232
|
runAiPrompt,
|
|
1236
1233
|
runAiPromptLocal,
|
package/dist/ai.mjs
CHANGED
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
buildCompactAiIndicatorsSnapshot,
|
|
10
10
|
getDeterministicAiGateContext,
|
|
11
11
|
getOpenRouterModelKwargs,
|
|
12
|
+
invokeAiChat,
|
|
12
13
|
resetAiRuntimeCache,
|
|
13
14
|
runAiPrompt,
|
|
14
15
|
runAiPromptLocal,
|
|
15
16
|
trimSeriesDeep
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-SEQJ6V6B.mjs";
|
|
18
|
+
import "./chunk-XN7BC7XK.mjs";
|
|
17
19
|
import "./chunk-WS5DYEVZ.mjs";
|
|
18
20
|
import "./chunk-Y6FXYEAI.mjs";
|
|
19
21
|
export {
|
|
@@ -27,6 +29,7 @@ export {
|
|
|
27
29
|
buildCompactAiIndicatorsSnapshot,
|
|
28
30
|
getDeterministicAiGateContext,
|
|
29
31
|
getOpenRouterModelKwargs,
|
|
32
|
+
invokeAiChat,
|
|
30
33
|
resetAiRuntimeCache,
|
|
31
34
|
runAiPrompt,
|
|
32
35
|
runAiPromptLocal,
|