@tradejs/node 3.1.29-beta.282 → 3.1.29-beta.283
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/diagnostics.d.mts +54 -1
- package/dist/diagnostics.d.ts +54 -1
- package/dist/diagnostics.js +199 -32
- package/dist/diagnostics.mjs +167 -4
- package/dist/mcp.d.mts +2 -2
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +4 -1
- package/dist/mcp.mjs +4 -1
- package/package.json +5 -5
package/dist/diagnostics.d.mts
CHANGED
|
@@ -179,4 +179,57 @@ declare const verifyRuntimeFeedbackReplaySource: ({ bundleDir, runtimeEvidenceBu
|
|
|
179
179
|
runtimeEvidence: VerifiedRuntimeEvidenceBundle;
|
|
180
180
|
}>;
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
/** Version of the complete feedback read contract, independent of package versions. */
|
|
183
|
+
declare const MCP_FEEDBACK_CONTRACT: {
|
|
184
|
+
readonly version: 1;
|
|
185
|
+
readonly hostProtocolVersion: 2;
|
|
186
|
+
readonly replayQueue: {
|
|
187
|
+
readonly waitingStates: readonly ["waiting_resources", "waiting_executor"];
|
|
188
|
+
readonly automaticFailedRetries: false;
|
|
189
|
+
};
|
|
190
|
+
readonly artifactEncoding: "base64";
|
|
191
|
+
readonly maximumChunkBytes: 48000;
|
|
192
|
+
readonly artifactFiles: readonly ["payload", "manifest.json", ".complete", "replay.log"];
|
|
193
|
+
readonly requiredTools: readonly ["tradejs_info", "diagnostics_list_reports", "diagnostics_get_report", "artifact_get", "job_get", "job_get_logs"];
|
|
194
|
+
};
|
|
195
|
+
type McpToolDescription = {
|
|
196
|
+
name: string;
|
|
197
|
+
inputSchema: {
|
|
198
|
+
properties?: Record<string, unknown>;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
/** Check the actual client's tools/list, not only what the server advertises. */
|
|
202
|
+
declare const assertMcpFeedbackContract: (version: unknown, tools: McpToolDescription[]) => void;
|
|
203
|
+
|
|
204
|
+
type McpArtifactFile = 'payload' | 'manifest.json' | '.complete' | 'replay.log';
|
|
205
|
+
type McpBundleDescriptor = {
|
|
206
|
+
id: string;
|
|
207
|
+
kind: 'runtime-evidence' | 'runtime-feedback-replay';
|
|
208
|
+
files: {
|
|
209
|
+
file: McpArtifactFile;
|
|
210
|
+
bytes: number;
|
|
211
|
+
sha256: string;
|
|
212
|
+
available: boolean;
|
|
213
|
+
}[];
|
|
214
|
+
};
|
|
215
|
+
declare class McpReadTransportError extends Error {
|
|
216
|
+
readonly retryAfterMs?: number | undefined;
|
|
217
|
+
constructor(message: string, retryAfterMs?: number | undefined);
|
|
218
|
+
}
|
|
219
|
+
type ChunkRequest = {
|
|
220
|
+
artifactId: string;
|
|
221
|
+
file: McpArtifactFile;
|
|
222
|
+
offset: number;
|
|
223
|
+
length: number;
|
|
224
|
+
};
|
|
225
|
+
/** The caller owns the authenticated MCP connection. This function only reads artifacts. */
|
|
226
|
+
declare const downloadMcpBundle: ({ descriptor, root, contractVersion, tools, readChunk, wait, }: {
|
|
227
|
+
descriptor: McpBundleDescriptor;
|
|
228
|
+
root: string;
|
|
229
|
+
contractVersion: unknown;
|
|
230
|
+
tools: McpToolDescription[];
|
|
231
|
+
readChunk: (request: ChunkRequest) => Promise<unknown>;
|
|
232
|
+
wait?: (ms: number) => Promise<unknown>;
|
|
233
|
+
}) => Promise<VerifiedRuntimeEvidenceBundle | VerifiedRuntimeFeedbackReplayBundle>;
|
|
234
|
+
|
|
235
|
+
export { MCP_FEEDBACK_CONTRACT, type McpArtifactFile, type McpBundleDescriptor, McpReadTransportError, type McpToolDescription, RUNTIME_EVIDENCE_COMPLETE_FILE, RUNTIME_EVIDENCE_MANIFEST_FILE, RUNTIME_EVIDENCE_PAYLOAD_FILE, RUNTIME_FEEDBACK_COMPLETE_FILE, RUNTIME_FEEDBACK_LOG_FILE, RUNTIME_FEEDBACK_MANIFEST_FILE, RUNTIME_FEEDBACK_REPLAY_FILE, type RuntimeEvidenceArtifactManifest, type RuntimeEvidenceDeploymentSnapshot, type RuntimeEvidenceProducer, type RuntimeEvidenceStrategySnapshot, type RuntimeFeedbackReplayManifest, type VerifiedRuntimeEvidenceBundle, type VerifiedRuntimeFeedbackReplayBundle, activeRuntimeEvidenceStrategies, assertCurrentRuntimeEvidenceArtifact, assertMcpFeedbackContract, discoverRuntimeEvidenceBundles, discoverRuntimeFeedbackReplayBundles, downloadMcpBundle, parseRuntimeEvidenceDeploymentSnapshot, parseRuntimeEvidenceProducer, publishRuntimeEvidenceBundle, resolveRuntimeEvidenceDeploymentSnapshot, resolveRuntimeEvidenceProducer, resolveRuntimeEvidenceTickerUniverse, runtimeDeploymentFromEvidence, runtimeLineageMatchesStrategySnapshot, sealRuntimeFeedbackReplayBundle, verifyRuntimeEvidenceBundle, verifyRuntimeFeedbackReplayBundle, verifyRuntimeFeedbackReplaySource };
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -179,4 +179,57 @@ declare const verifyRuntimeFeedbackReplaySource: ({ bundleDir, runtimeEvidenceBu
|
|
|
179
179
|
runtimeEvidence: VerifiedRuntimeEvidenceBundle;
|
|
180
180
|
}>;
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
/** Version of the complete feedback read contract, independent of package versions. */
|
|
183
|
+
declare const MCP_FEEDBACK_CONTRACT: {
|
|
184
|
+
readonly version: 1;
|
|
185
|
+
readonly hostProtocolVersion: 2;
|
|
186
|
+
readonly replayQueue: {
|
|
187
|
+
readonly waitingStates: readonly ["waiting_resources", "waiting_executor"];
|
|
188
|
+
readonly automaticFailedRetries: false;
|
|
189
|
+
};
|
|
190
|
+
readonly artifactEncoding: "base64";
|
|
191
|
+
readonly maximumChunkBytes: 48000;
|
|
192
|
+
readonly artifactFiles: readonly ["payload", "manifest.json", ".complete", "replay.log"];
|
|
193
|
+
readonly requiredTools: readonly ["tradejs_info", "diagnostics_list_reports", "diagnostics_get_report", "artifact_get", "job_get", "job_get_logs"];
|
|
194
|
+
};
|
|
195
|
+
type McpToolDescription = {
|
|
196
|
+
name: string;
|
|
197
|
+
inputSchema: {
|
|
198
|
+
properties?: Record<string, unknown>;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
/** Check the actual client's tools/list, not only what the server advertises. */
|
|
202
|
+
declare const assertMcpFeedbackContract: (version: unknown, tools: McpToolDescription[]) => void;
|
|
203
|
+
|
|
204
|
+
type McpArtifactFile = 'payload' | 'manifest.json' | '.complete' | 'replay.log';
|
|
205
|
+
type McpBundleDescriptor = {
|
|
206
|
+
id: string;
|
|
207
|
+
kind: 'runtime-evidence' | 'runtime-feedback-replay';
|
|
208
|
+
files: {
|
|
209
|
+
file: McpArtifactFile;
|
|
210
|
+
bytes: number;
|
|
211
|
+
sha256: string;
|
|
212
|
+
available: boolean;
|
|
213
|
+
}[];
|
|
214
|
+
};
|
|
215
|
+
declare class McpReadTransportError extends Error {
|
|
216
|
+
readonly retryAfterMs?: number | undefined;
|
|
217
|
+
constructor(message: string, retryAfterMs?: number | undefined);
|
|
218
|
+
}
|
|
219
|
+
type ChunkRequest = {
|
|
220
|
+
artifactId: string;
|
|
221
|
+
file: McpArtifactFile;
|
|
222
|
+
offset: number;
|
|
223
|
+
length: number;
|
|
224
|
+
};
|
|
225
|
+
/** The caller owns the authenticated MCP connection. This function only reads artifacts. */
|
|
226
|
+
declare const downloadMcpBundle: ({ descriptor, root, contractVersion, tools, readChunk, wait, }: {
|
|
227
|
+
descriptor: McpBundleDescriptor;
|
|
228
|
+
root: string;
|
|
229
|
+
contractVersion: unknown;
|
|
230
|
+
tools: McpToolDescription[];
|
|
231
|
+
readChunk: (request: ChunkRequest) => Promise<unknown>;
|
|
232
|
+
wait?: (ms: number) => Promise<unknown>;
|
|
233
|
+
}) => Promise<VerifiedRuntimeEvidenceBundle | VerifiedRuntimeFeedbackReplayBundle>;
|
|
234
|
+
|
|
235
|
+
export { MCP_FEEDBACK_CONTRACT, type McpArtifactFile, type McpBundleDescriptor, McpReadTransportError, type McpToolDescription, RUNTIME_EVIDENCE_COMPLETE_FILE, RUNTIME_EVIDENCE_MANIFEST_FILE, RUNTIME_EVIDENCE_PAYLOAD_FILE, RUNTIME_FEEDBACK_COMPLETE_FILE, RUNTIME_FEEDBACK_LOG_FILE, RUNTIME_FEEDBACK_MANIFEST_FILE, RUNTIME_FEEDBACK_REPLAY_FILE, type RuntimeEvidenceArtifactManifest, type RuntimeEvidenceDeploymentSnapshot, type RuntimeEvidenceProducer, type RuntimeEvidenceStrategySnapshot, type RuntimeFeedbackReplayManifest, type VerifiedRuntimeEvidenceBundle, type VerifiedRuntimeFeedbackReplayBundle, activeRuntimeEvidenceStrategies, assertCurrentRuntimeEvidenceArtifact, assertMcpFeedbackContract, discoverRuntimeEvidenceBundles, discoverRuntimeFeedbackReplayBundles, downloadMcpBundle, parseRuntimeEvidenceDeploymentSnapshot, parseRuntimeEvidenceProducer, publishRuntimeEvidenceBundle, resolveRuntimeEvidenceDeploymentSnapshot, resolveRuntimeEvidenceProducer, resolveRuntimeEvidenceTickerUniverse, runtimeDeploymentFromEvidence, runtimeLineageMatchesStrategySnapshot, sealRuntimeFeedbackReplayBundle, verifyRuntimeEvidenceBundle, verifyRuntimeFeedbackReplayBundle, verifyRuntimeFeedbackReplaySource };
|
package/dist/diagnostics.js
CHANGED
|
@@ -43,7 +43,7 @@ var init_jevInput = __esm({
|
|
|
43
43
|
import_data = require("@tradejs/core/data");
|
|
44
44
|
import_jev = require("@tradejs/core/jev");
|
|
45
45
|
object = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
46
|
-
at = (value, ...
|
|
46
|
+
at = (value, ...path8) => path8.reduce((current, key) => object(current)[key], value);
|
|
47
47
|
finite = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
48
48
|
fact = (value) => {
|
|
49
49
|
if (value == null || typeof value === "boolean") return value ?? null;
|
|
@@ -453,25 +453,25 @@ var init_jevTraining = __esm({
|
|
|
453
453
|
"Jev training is bounded to 20000 rows; select a frozen sample first"
|
|
454
454
|
);
|
|
455
455
|
for (const row of rows) {
|
|
456
|
-
const
|
|
457
|
-
if (row?.schema !== "tradejs-jev-study/v4" || !row.signalId ||
|
|
458
|
-
inputHash:
|
|
459
|
-
questionsHash:
|
|
460
|
-
provider:
|
|
456
|
+
const record2 = row?.record;
|
|
457
|
+
if (row?.schema !== "tradejs-jev-study/v4" || !row.signalId || record2?.schema !== "tradejs-jev-record/v4" || record2.input?.schema !== "tradejs-jev-input/v4" || record2.input.questionSet !== import_jev2.JEV_QUESTION_SET || !Number.isFinite(record2.input.timestamp) || record2.inputHash !== (0, import_jev3.jevHash)(record2.input) || record2.questionsHash !== (0, import_jev3.jevHash)(questionsForJevInput(record2.input)) || record2.id !== (0, import_jev3.jevHash)({
|
|
458
|
+
inputHash: record2.inputHash,
|
|
459
|
+
questionsHash: record2.questionsHash,
|
|
460
|
+
provider: record2.provider
|
|
461
461
|
}))
|
|
462
462
|
throw new Error("Invalid Jev study provenance");
|
|
463
|
-
(0, import_jev3.validateJevResponse)(
|
|
463
|
+
(0, import_jev3.validateJevResponse)(record2.response, record2.input.questions);
|
|
464
464
|
for (const dimension of import_jev2.JEV_DIMENSIONS) {
|
|
465
|
-
const expected =
|
|
466
|
-
if (
|
|
465
|
+
const expected = record2.input.questions.includes(dimension) ? record2.response.answers[dimension].score / (0, import_jev3.jevScoreMaximum)(dimension) : null;
|
|
466
|
+
if (record2.scores[dimension] !== expected)
|
|
467
467
|
throw new Error("Jev study scores do not match the teacher response");
|
|
468
468
|
}
|
|
469
469
|
if (row.profit != null && !Number.isFinite(row.profit))
|
|
470
470
|
throw new Error("Invalid study outcome");
|
|
471
|
-
const prior = unique.get(
|
|
472
|
-
if (prior && (prior.record.id !==
|
|
471
|
+
const prior = unique.get(record2.inputHash);
|
|
472
|
+
if (prior && (prior.record.id !== record2.id || prior.profit !== row.profit || (0, import_jev3.jevHash)(prior.record.response) !== (0, import_jev3.jevHash)(record2.response)))
|
|
473
473
|
throw new Error("Conflicting duplicated Jev sample");
|
|
474
|
-
unique.set(
|
|
474
|
+
unique.set(record2.inputHash, row);
|
|
475
475
|
}
|
|
476
476
|
const ordered = [...unique.values()].sort(
|
|
477
477
|
(a, b) => a.record.input.timestamp - b.record.input.timestamp || a.record.id.localeCompare(b.record.id)
|
|
@@ -777,6 +777,8 @@ var init_jevTraining = __esm({
|
|
|
777
777
|
// src/diagnostics.ts
|
|
778
778
|
var diagnostics_exports = {};
|
|
779
779
|
__export(diagnostics_exports, {
|
|
780
|
+
MCP_FEEDBACK_CONTRACT: () => MCP_FEEDBACK_CONTRACT,
|
|
781
|
+
McpReadTransportError: () => McpReadTransportError,
|
|
780
782
|
RUNTIME_EVIDENCE_COMPLETE_FILE: () => RUNTIME_EVIDENCE_COMPLETE_FILE,
|
|
781
783
|
RUNTIME_EVIDENCE_MANIFEST_FILE: () => RUNTIME_EVIDENCE_MANIFEST_FILE,
|
|
782
784
|
RUNTIME_EVIDENCE_PAYLOAD_FILE: () => RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
@@ -786,8 +788,10 @@ __export(diagnostics_exports, {
|
|
|
786
788
|
RUNTIME_FEEDBACK_REPLAY_FILE: () => RUNTIME_FEEDBACK_REPLAY_FILE,
|
|
787
789
|
activeRuntimeEvidenceStrategies: () => activeRuntimeEvidenceStrategies,
|
|
788
790
|
assertCurrentRuntimeEvidenceArtifact: () => assertCurrentRuntimeEvidenceArtifact,
|
|
791
|
+
assertMcpFeedbackContract: () => assertMcpFeedbackContract,
|
|
789
792
|
discoverRuntimeEvidenceBundles: () => discoverRuntimeEvidenceBundles,
|
|
790
793
|
discoverRuntimeFeedbackReplayBundles: () => discoverRuntimeFeedbackReplayBundles,
|
|
794
|
+
downloadMcpBundle: () => downloadMcpBundle,
|
|
791
795
|
parseRuntimeEvidenceDeploymentSnapshot: () => parseRuntimeEvidenceDeploymentSnapshot,
|
|
792
796
|
parseRuntimeEvidenceProducer: () => parseRuntimeEvidenceProducer,
|
|
793
797
|
publishRuntimeEvidenceBundle: () => publishRuntimeEvidenceBundle,
|
|
@@ -982,24 +986,24 @@ var evaluateJevInput = async ({
|
|
|
982
986
|
promise = getRecord();
|
|
983
987
|
pending.set(pendingKey, promise);
|
|
984
988
|
}
|
|
985
|
-
let
|
|
989
|
+
let record2;
|
|
986
990
|
try {
|
|
987
|
-
|
|
991
|
+
record2 = await promise;
|
|
988
992
|
} finally {
|
|
989
993
|
pending.delete(pendingKey);
|
|
990
994
|
}
|
|
991
995
|
return {
|
|
992
|
-
record,
|
|
996
|
+
record: record2,
|
|
993
997
|
assessment: {
|
|
994
998
|
...base,
|
|
995
999
|
status: "available",
|
|
996
1000
|
recordId: id,
|
|
997
|
-
model:
|
|
998
|
-
scores:
|
|
1001
|
+
model: record2.response.model,
|
|
1002
|
+
scores: record2.scores,
|
|
999
1003
|
confidence: Object.fromEntries(
|
|
1000
1004
|
import_jev4.JEV_DIMENSIONS.map((key) => [
|
|
1001
1005
|
key,
|
|
1002
|
-
|
|
1006
|
+
record2.response.answers[key]?.confidence ?? null
|
|
1003
1007
|
])
|
|
1004
1008
|
)
|
|
1005
1009
|
}
|
|
@@ -2922,7 +2926,7 @@ var recordRuntimeTradeOpen = async (params) => {
|
|
|
2922
2926
|
if (!userName) {
|
|
2923
2927
|
return null;
|
|
2924
2928
|
}
|
|
2925
|
-
const
|
|
2929
|
+
const record2 = {
|
|
2926
2930
|
...params,
|
|
2927
2931
|
entryCount: 1,
|
|
2928
2932
|
lastEntryPrice: params.entryPrice,
|
|
@@ -2936,33 +2940,33 @@ var recordRuntimeTradeOpen = async (params) => {
|
|
|
2936
2940
|
exitTimestamp: null,
|
|
2937
2941
|
lastSyncedAt: now()
|
|
2938
2942
|
};
|
|
2939
|
-
const dayKey = (0, import_time.getRuntimeStorageDayKey)(
|
|
2940
|
-
const runtimeScopeId =
|
|
2943
|
+
const dayKey = (0, import_time.getRuntimeStorageDayKey)(record2.entryTimestamp);
|
|
2944
|
+
const runtimeScopeId = record2.deploymentId ?? record2.accountId;
|
|
2941
2945
|
try {
|
|
2942
2946
|
await Promise.all([
|
|
2943
|
-
(0, import_redis2.setData)(import_redis2.redisKeys.runtimeTrade(userName,
|
|
2947
|
+
(0, import_redis2.setData)(import_redis2.redisKeys.runtimeTrade(userName, record2.orderId), record2, {
|
|
2944
2948
|
expire: 0
|
|
2945
2949
|
}),
|
|
2946
2950
|
(0, import_redis2.setHashJsonField)(
|
|
2947
2951
|
import_redis2.redisKeys.runtimeTradeBucket(userName, dayKey),
|
|
2948
|
-
|
|
2949
|
-
|
|
2952
|
+
record2.orderId,
|
|
2953
|
+
record2,
|
|
2950
2954
|
{ expire: 0 }
|
|
2951
2955
|
),
|
|
2952
2956
|
(0, import_redis2.setData)(
|
|
2953
|
-
import_redis2.redisKeys.runtimeActiveTrade(userName,
|
|
2954
|
-
{ orderId:
|
|
2957
|
+
import_redis2.redisKeys.runtimeActiveTrade(userName, record2.symbol, runtimeScopeId),
|
|
2958
|
+
{ orderId: record2.orderId },
|
|
2955
2959
|
{ expire: 0 }
|
|
2956
2960
|
)
|
|
2957
2961
|
]);
|
|
2958
2962
|
} catch (error) {
|
|
2959
2963
|
import_logger2.logger.error(
|
|
2960
2964
|
"runtime trade open journal failed: %s %s",
|
|
2961
|
-
|
|
2965
|
+
record2.symbol,
|
|
2962
2966
|
error?.message || String(error)
|
|
2963
2967
|
);
|
|
2964
2968
|
}
|
|
2965
|
-
return
|
|
2969
|
+
return record2;
|
|
2966
2970
|
};
|
|
2967
2971
|
var recordRuntimeTradeIncrease = async (params) => {
|
|
2968
2972
|
const {
|
|
@@ -8287,10 +8291,10 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
|
8287
8291
|
};
|
|
8288
8292
|
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
8289
8293
|
var unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
8290
|
-
const
|
|
8291
|
-
const nested =
|
|
8292
|
-
return nested ??
|
|
8293
|
-
}).filter((
|
|
8294
|
+
const record2 = isRecord2(candidate) ? candidate : null;
|
|
8295
|
+
const nested = record2 && isRecord2(record2[field]) ? record2[field] : null;
|
|
8296
|
+
return nested ?? record2;
|
|
8297
|
+
}).filter((record2) => record2 != null);
|
|
8294
8298
|
var assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
8295
8299
|
if (!isRecord2(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
8296
8300
|
throw new Error("Invalid runtime evidence artifact");
|
|
@@ -9032,8 +9036,169 @@ var verifyRuntimeFeedbackReplaySource = async ({
|
|
|
9032
9036
|
});
|
|
9033
9037
|
return { feedback, runtimeEvidence };
|
|
9034
9038
|
};
|
|
9039
|
+
|
|
9040
|
+
// src/diagnostics/mcpFeedbackContract.ts
|
|
9041
|
+
var MCP_FEEDBACK_CONTRACT = {
|
|
9042
|
+
version: 1,
|
|
9043
|
+
hostProtocolVersion: 2,
|
|
9044
|
+
replayQueue: {
|
|
9045
|
+
waitingStates: ["waiting_resources", "waiting_executor"],
|
|
9046
|
+
automaticFailedRetries: false
|
|
9047
|
+
},
|
|
9048
|
+
artifactEncoding: "base64",
|
|
9049
|
+
maximumChunkBytes: 48e3,
|
|
9050
|
+
artifactFiles: ["payload", "manifest.json", ".complete", "replay.log"],
|
|
9051
|
+
requiredTools: [
|
|
9052
|
+
"tradejs_info",
|
|
9053
|
+
"diagnostics_list_reports",
|
|
9054
|
+
"diagnostics_get_report",
|
|
9055
|
+
"artifact_get",
|
|
9056
|
+
"job_get",
|
|
9057
|
+
"job_get_logs"
|
|
9058
|
+
]
|
|
9059
|
+
};
|
|
9060
|
+
var assertMcpFeedbackContract = (version, tools) => {
|
|
9061
|
+
if (version !== MCP_FEEDBACK_CONTRACT.version)
|
|
9062
|
+
throw new Error("MCP feedback contract version mismatch");
|
|
9063
|
+
for (const name of MCP_FEEDBACK_CONTRACT.requiredTools)
|
|
9064
|
+
if (!tools.some((tool) => tool.name === name))
|
|
9065
|
+
throw new Error(`MCP feedback requires tool ${name}`);
|
|
9066
|
+
const properties = tools.find((tool) => tool.name === "artifact_get")?.inputSchema.properties;
|
|
9067
|
+
if (!properties || !("file" in properties))
|
|
9068
|
+
throw new Error(
|
|
9069
|
+
"MCP feedback requires artifact_get.file; refresh the client tool schema"
|
|
9070
|
+
);
|
|
9071
|
+
};
|
|
9072
|
+
|
|
9073
|
+
// src/diagnostics/mcpBundleDownload.ts
|
|
9074
|
+
var import_node_crypto8 = require("crypto");
|
|
9075
|
+
var import_promises6 = __toESM(require("fs/promises"));
|
|
9076
|
+
var import_node_path6 = __toESM(require("path"));
|
|
9077
|
+
var McpReadTransportError = class extends Error {
|
|
9078
|
+
constructor(message, retryAfterMs) {
|
|
9079
|
+
super(message);
|
|
9080
|
+
this.retryAfterMs = retryAfterMs;
|
|
9081
|
+
}
|
|
9082
|
+
};
|
|
9083
|
+
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
9084
|
+
var digest = (bytes) => (0, import_node_crypto8.createHash)("sha256").update(bytes).digest("hex");
|
|
9085
|
+
var exists = async (file) => import_promises6.default.lstat(file).catch((error) => {
|
|
9086
|
+
if (error.code === "ENOENT") return void 0;
|
|
9087
|
+
throw error;
|
|
9088
|
+
});
|
|
9089
|
+
var checkFile = async (file) => {
|
|
9090
|
+
const stat = await exists(file);
|
|
9091
|
+
if (stat && (!stat.isFile() || stat.isSymbolicLink()))
|
|
9092
|
+
throw new Error("Invalid local bundle file");
|
|
9093
|
+
return stat;
|
|
9094
|
+
};
|
|
9095
|
+
var downloadMcpBundle = async ({
|
|
9096
|
+
descriptor,
|
|
9097
|
+
root,
|
|
9098
|
+
contractVersion,
|
|
9099
|
+
tools,
|
|
9100
|
+
readChunk,
|
|
9101
|
+
wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
9102
|
+
}) => {
|
|
9103
|
+
assertMcpFeedbackContract(contractVersion, tools);
|
|
9104
|
+
if (!/^[a-f0-9]{64}$/.test(descriptor.id))
|
|
9105
|
+
throw new Error("Invalid artifact identity");
|
|
9106
|
+
const required = ["payload", "manifest.json", ".complete"];
|
|
9107
|
+
if (descriptor.kind === "runtime-feedback-replay")
|
|
9108
|
+
required.push("replay.log");
|
|
9109
|
+
for (const name of required) {
|
|
9110
|
+
const matches = descriptor.files.filter((f) => f.file === name);
|
|
9111
|
+
if (matches.length !== 1 || !matches[0].available || !Number.isSafeInteger(matches[0].bytes) || matches[0].bytes < 0 || !/^[a-f0-9]{64}$/.test(matches[0].sha256))
|
|
9112
|
+
throw new Error(`Incomplete bundle descriptor: ${name}`);
|
|
9113
|
+
}
|
|
9114
|
+
const bundleDir = import_node_path6.default.join(root, descriptor.id);
|
|
9115
|
+
await import_promises6.default.mkdir(bundleDir, { recursive: true });
|
|
9116
|
+
const dir = await import_promises6.default.lstat(bundleDir);
|
|
9117
|
+
if (dir.isSymbolicLink()) throw new Error("Invalid bundle directory");
|
|
9118
|
+
const lock = import_node_path6.default.join(bundleDir, ".download-lock");
|
|
9119
|
+
await import_promises6.default.mkdir(lock);
|
|
9120
|
+
try {
|
|
9121
|
+
for (const name of [
|
|
9122
|
+
...required.filter((f) => f !== ".complete"),
|
|
9123
|
+
".complete"
|
|
9124
|
+
]) {
|
|
9125
|
+
const expected = descriptor.files.find((f) => f.file === name);
|
|
9126
|
+
if (!expected) throw new Error("Missing bundle file");
|
|
9127
|
+
const filename = name === "payload" ? descriptor.kind === "runtime-evidence" ? "runtime-evidence.json" : "replay-runtime-evidence.json" : name;
|
|
9128
|
+
const target = import_node_path6.default.join(bundleDir, filename);
|
|
9129
|
+
const verified = await checkFile(target);
|
|
9130
|
+
if (verified) {
|
|
9131
|
+
if (verified.size !== expected.bytes || digest(await import_promises6.default.readFile(target)) !== expected.sha256)
|
|
9132
|
+
throw new Error("Local bundle checksum mismatch");
|
|
9133
|
+
continue;
|
|
9134
|
+
}
|
|
9135
|
+
const partial = target + ".part";
|
|
9136
|
+
const checkpoint = partial + ".json";
|
|
9137
|
+
const identity = JSON.stringify({
|
|
9138
|
+
artifactId: descriptor.id,
|
|
9139
|
+
file: name,
|
|
9140
|
+
bytes: expected.bytes,
|
|
9141
|
+
sha256: expected.sha256
|
|
9142
|
+
});
|
|
9143
|
+
await checkFile(checkpoint);
|
|
9144
|
+
const stat = await checkFile(partial);
|
|
9145
|
+
if (stat) {
|
|
9146
|
+
if (await import_promises6.default.readFile(checkpoint, "utf8") !== identity || stat.size > expected.bytes)
|
|
9147
|
+
throw new Error("Artifact changed during download");
|
|
9148
|
+
} else {
|
|
9149
|
+
if (await checkFile(checkpoint)) {
|
|
9150
|
+
if (await import_promises6.default.readFile(checkpoint, "utf8") !== identity)
|
|
9151
|
+
throw new Error("Artifact changed during download");
|
|
9152
|
+
} else await import_promises6.default.writeFile(checkpoint, identity, { flag: "wx" });
|
|
9153
|
+
}
|
|
9154
|
+
let offset = stat?.size ?? 0;
|
|
9155
|
+
if (!stat) await import_promises6.default.writeFile(partial, Buffer.alloc(0), { flag: "wx" });
|
|
9156
|
+
while (offset < expected.bytes) {
|
|
9157
|
+
const request = {
|
|
9158
|
+
artifactId: descriptor.id,
|
|
9159
|
+
file: name,
|
|
9160
|
+
offset,
|
|
9161
|
+
length: MCP_FEEDBACK_CONTRACT.maximumChunkBytes
|
|
9162
|
+
};
|
|
9163
|
+
let response;
|
|
9164
|
+
for (let attempt = 0; ; attempt++) {
|
|
9165
|
+
try {
|
|
9166
|
+
response = await readChunk(request);
|
|
9167
|
+
break;
|
|
9168
|
+
} catch (error) {
|
|
9169
|
+
if (!(error instanceof McpReadTransportError) || attempt >= 3)
|
|
9170
|
+
throw error;
|
|
9171
|
+
await wait(
|
|
9172
|
+
Math.max([2e3, 5e3, 1e4][attempt], error.retryAfterMs ?? 0)
|
|
9173
|
+
);
|
|
9174
|
+
}
|
|
9175
|
+
}
|
|
9176
|
+
if (!record(response) || response.id !== descriptor.id || response.file !== name || response.offset !== offset || response.bytes !== expected.bytes || response.sha256 !== expected.sha256 || response.encoding !== "base64" || typeof response.data !== "string" || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(
|
|
9177
|
+
response.data
|
|
9178
|
+
))
|
|
9179
|
+
throw new Error("Invalid artifact chunk identity");
|
|
9180
|
+
const bytes = Buffer.from(response.data, "base64");
|
|
9181
|
+
const next = offset + bytes.length;
|
|
9182
|
+
if (!bytes.length || bytes.length > request.length || next > expected.bytes || response.nextOffset !== (next === expected.bytes ? null : next))
|
|
9183
|
+
throw new Error("Invalid artifact chunk range");
|
|
9184
|
+
await import_promises6.default.appendFile(partial, bytes);
|
|
9185
|
+
offset = next;
|
|
9186
|
+
}
|
|
9187
|
+
if (digest(await import_promises6.default.readFile(partial)) !== expected.sha256)
|
|
9188
|
+
throw new Error("Downloaded bundle checksum mismatch");
|
|
9189
|
+
await import_promises6.default.rename(partial, target);
|
|
9190
|
+
await import_promises6.default.unlink(checkpoint);
|
|
9191
|
+
}
|
|
9192
|
+
const bundle = descriptor.kind === "runtime-evidence" ? await verifyRuntimeEvidenceBundle(bundleDir) : await verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
9193
|
+
return bundle;
|
|
9194
|
+
} finally {
|
|
9195
|
+
await import_promises6.default.rmdir(lock);
|
|
9196
|
+
}
|
|
9197
|
+
};
|
|
9035
9198
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9036
9199
|
0 && (module.exports = {
|
|
9200
|
+
MCP_FEEDBACK_CONTRACT,
|
|
9201
|
+
McpReadTransportError,
|
|
9037
9202
|
RUNTIME_EVIDENCE_COMPLETE_FILE,
|
|
9038
9203
|
RUNTIME_EVIDENCE_MANIFEST_FILE,
|
|
9039
9204
|
RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
@@ -9043,8 +9208,10 @@ var verifyRuntimeFeedbackReplaySource = async ({
|
|
|
9043
9208
|
RUNTIME_FEEDBACK_REPLAY_FILE,
|
|
9044
9209
|
activeRuntimeEvidenceStrategies,
|
|
9045
9210
|
assertCurrentRuntimeEvidenceArtifact,
|
|
9211
|
+
assertMcpFeedbackContract,
|
|
9046
9212
|
discoverRuntimeEvidenceBundles,
|
|
9047
9213
|
discoverRuntimeFeedbackReplayBundles,
|
|
9214
|
+
downloadMcpBundle,
|
|
9048
9215
|
parseRuntimeEvidenceDeploymentSnapshot,
|
|
9049
9216
|
parseRuntimeEvidenceProducer,
|
|
9050
9217
|
publishRuntimeEvidenceBundle,
|
package/dist/diagnostics.mjs
CHANGED
|
@@ -95,10 +95,10 @@ var parseRuntimeEvidenceDeploymentSnapshot = (value) => {
|
|
|
95
95
|
};
|
|
96
96
|
var activeRuntimeEvidenceStrategies = (deployment) => deployment.enabled ? deployment.strategies.filter((strategy) => strategy.enabled) : [];
|
|
97
97
|
var unwrapRuntimeEvidenceRows = (value, field) => (Array.isArray(value) ? value : []).map((candidate) => {
|
|
98
|
-
const
|
|
99
|
-
const nested =
|
|
100
|
-
return nested ??
|
|
101
|
-
}).filter((
|
|
98
|
+
const record2 = isRecord(candidate) ? candidate : null;
|
|
99
|
+
const nested = record2 && isRecord(record2[field]) ? record2[field] : null;
|
|
100
|
+
return nested ?? record2;
|
|
101
|
+
}).filter((record2) => record2 != null);
|
|
102
102
|
var assertCurrentRuntimeEvidenceArtifact = (artifact) => {
|
|
103
103
|
if (!isRecord(artifact) || artifact.reportType !== "runtime-evidence") {
|
|
104
104
|
throw new Error("Invalid runtime evidence artifact");
|
|
@@ -840,7 +840,168 @@ var verifyRuntimeFeedbackReplaySource = async ({
|
|
|
840
840
|
});
|
|
841
841
|
return { feedback, runtimeEvidence };
|
|
842
842
|
};
|
|
843
|
+
|
|
844
|
+
// src/diagnostics/mcpFeedbackContract.ts
|
|
845
|
+
var MCP_FEEDBACK_CONTRACT = {
|
|
846
|
+
version: 1,
|
|
847
|
+
hostProtocolVersion: 2,
|
|
848
|
+
replayQueue: {
|
|
849
|
+
waitingStates: ["waiting_resources", "waiting_executor"],
|
|
850
|
+
automaticFailedRetries: false
|
|
851
|
+
},
|
|
852
|
+
artifactEncoding: "base64",
|
|
853
|
+
maximumChunkBytes: 48e3,
|
|
854
|
+
artifactFiles: ["payload", "manifest.json", ".complete", "replay.log"],
|
|
855
|
+
requiredTools: [
|
|
856
|
+
"tradejs_info",
|
|
857
|
+
"diagnostics_list_reports",
|
|
858
|
+
"diagnostics_get_report",
|
|
859
|
+
"artifact_get",
|
|
860
|
+
"job_get",
|
|
861
|
+
"job_get_logs"
|
|
862
|
+
]
|
|
863
|
+
};
|
|
864
|
+
var assertMcpFeedbackContract = (version, tools) => {
|
|
865
|
+
if (version !== MCP_FEEDBACK_CONTRACT.version)
|
|
866
|
+
throw new Error("MCP feedback contract version mismatch");
|
|
867
|
+
for (const name of MCP_FEEDBACK_CONTRACT.requiredTools)
|
|
868
|
+
if (!tools.some((tool) => tool.name === name))
|
|
869
|
+
throw new Error(`MCP feedback requires tool ${name}`);
|
|
870
|
+
const properties = tools.find((tool) => tool.name === "artifact_get")?.inputSchema.properties;
|
|
871
|
+
if (!properties || !("file" in properties))
|
|
872
|
+
throw new Error(
|
|
873
|
+
"MCP feedback requires artifact_get.file; refresh the client tool schema"
|
|
874
|
+
);
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
// src/diagnostics/mcpBundleDownload.ts
|
|
878
|
+
import { createHash as createHash4 } from "crypto";
|
|
879
|
+
import fs4 from "fs/promises";
|
|
880
|
+
import path4 from "path";
|
|
881
|
+
var McpReadTransportError = class extends Error {
|
|
882
|
+
constructor(message, retryAfterMs) {
|
|
883
|
+
super(message);
|
|
884
|
+
this.retryAfterMs = retryAfterMs;
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
var record = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
888
|
+
var digest = (bytes) => createHash4("sha256").update(bytes).digest("hex");
|
|
889
|
+
var exists = async (file) => fs4.lstat(file).catch((error) => {
|
|
890
|
+
if (error.code === "ENOENT") return void 0;
|
|
891
|
+
throw error;
|
|
892
|
+
});
|
|
893
|
+
var checkFile = async (file) => {
|
|
894
|
+
const stat = await exists(file);
|
|
895
|
+
if (stat && (!stat.isFile() || stat.isSymbolicLink()))
|
|
896
|
+
throw new Error("Invalid local bundle file");
|
|
897
|
+
return stat;
|
|
898
|
+
};
|
|
899
|
+
var downloadMcpBundle = async ({
|
|
900
|
+
descriptor,
|
|
901
|
+
root,
|
|
902
|
+
contractVersion,
|
|
903
|
+
tools,
|
|
904
|
+
readChunk,
|
|
905
|
+
wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
906
|
+
}) => {
|
|
907
|
+
assertMcpFeedbackContract(contractVersion, tools);
|
|
908
|
+
if (!/^[a-f0-9]{64}$/.test(descriptor.id))
|
|
909
|
+
throw new Error("Invalid artifact identity");
|
|
910
|
+
const required = ["payload", "manifest.json", ".complete"];
|
|
911
|
+
if (descriptor.kind === "runtime-feedback-replay")
|
|
912
|
+
required.push("replay.log");
|
|
913
|
+
for (const name of required) {
|
|
914
|
+
const matches = descriptor.files.filter((f) => f.file === name);
|
|
915
|
+
if (matches.length !== 1 || !matches[0].available || !Number.isSafeInteger(matches[0].bytes) || matches[0].bytes < 0 || !/^[a-f0-9]{64}$/.test(matches[0].sha256))
|
|
916
|
+
throw new Error(`Incomplete bundle descriptor: ${name}`);
|
|
917
|
+
}
|
|
918
|
+
const bundleDir = path4.join(root, descriptor.id);
|
|
919
|
+
await fs4.mkdir(bundleDir, { recursive: true });
|
|
920
|
+
const dir = await fs4.lstat(bundleDir);
|
|
921
|
+
if (dir.isSymbolicLink()) throw new Error("Invalid bundle directory");
|
|
922
|
+
const lock = path4.join(bundleDir, ".download-lock");
|
|
923
|
+
await fs4.mkdir(lock);
|
|
924
|
+
try {
|
|
925
|
+
for (const name of [
|
|
926
|
+
...required.filter((f) => f !== ".complete"),
|
|
927
|
+
".complete"
|
|
928
|
+
]) {
|
|
929
|
+
const expected = descriptor.files.find((f) => f.file === name);
|
|
930
|
+
if (!expected) throw new Error("Missing bundle file");
|
|
931
|
+
const filename = name === "payload" ? descriptor.kind === "runtime-evidence" ? "runtime-evidence.json" : "replay-runtime-evidence.json" : name;
|
|
932
|
+
const target = path4.join(bundleDir, filename);
|
|
933
|
+
const verified = await checkFile(target);
|
|
934
|
+
if (verified) {
|
|
935
|
+
if (verified.size !== expected.bytes || digest(await fs4.readFile(target)) !== expected.sha256)
|
|
936
|
+
throw new Error("Local bundle checksum mismatch");
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
const partial = target + ".part";
|
|
940
|
+
const checkpoint = partial + ".json";
|
|
941
|
+
const identity = JSON.stringify({
|
|
942
|
+
artifactId: descriptor.id,
|
|
943
|
+
file: name,
|
|
944
|
+
bytes: expected.bytes,
|
|
945
|
+
sha256: expected.sha256
|
|
946
|
+
});
|
|
947
|
+
await checkFile(checkpoint);
|
|
948
|
+
const stat = await checkFile(partial);
|
|
949
|
+
if (stat) {
|
|
950
|
+
if (await fs4.readFile(checkpoint, "utf8") !== identity || stat.size > expected.bytes)
|
|
951
|
+
throw new Error("Artifact changed during download");
|
|
952
|
+
} else {
|
|
953
|
+
if (await checkFile(checkpoint)) {
|
|
954
|
+
if (await fs4.readFile(checkpoint, "utf8") !== identity)
|
|
955
|
+
throw new Error("Artifact changed during download");
|
|
956
|
+
} else await fs4.writeFile(checkpoint, identity, { flag: "wx" });
|
|
957
|
+
}
|
|
958
|
+
let offset = stat?.size ?? 0;
|
|
959
|
+
if (!stat) await fs4.writeFile(partial, Buffer.alloc(0), { flag: "wx" });
|
|
960
|
+
while (offset < expected.bytes) {
|
|
961
|
+
const request = {
|
|
962
|
+
artifactId: descriptor.id,
|
|
963
|
+
file: name,
|
|
964
|
+
offset,
|
|
965
|
+
length: MCP_FEEDBACK_CONTRACT.maximumChunkBytes
|
|
966
|
+
};
|
|
967
|
+
let response;
|
|
968
|
+
for (let attempt = 0; ; attempt++) {
|
|
969
|
+
try {
|
|
970
|
+
response = await readChunk(request);
|
|
971
|
+
break;
|
|
972
|
+
} catch (error) {
|
|
973
|
+
if (!(error instanceof McpReadTransportError) || attempt >= 3)
|
|
974
|
+
throw error;
|
|
975
|
+
await wait(
|
|
976
|
+
Math.max([2e3, 5e3, 1e4][attempt], error.retryAfterMs ?? 0)
|
|
977
|
+
);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
if (!record(response) || response.id !== descriptor.id || response.file !== name || response.offset !== offset || response.bytes !== expected.bytes || response.sha256 !== expected.sha256 || response.encoding !== "base64" || typeof response.data !== "string" || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(
|
|
981
|
+
response.data
|
|
982
|
+
))
|
|
983
|
+
throw new Error("Invalid artifact chunk identity");
|
|
984
|
+
const bytes = Buffer.from(response.data, "base64");
|
|
985
|
+
const next = offset + bytes.length;
|
|
986
|
+
if (!bytes.length || bytes.length > request.length || next > expected.bytes || response.nextOffset !== (next === expected.bytes ? null : next))
|
|
987
|
+
throw new Error("Invalid artifact chunk range");
|
|
988
|
+
await fs4.appendFile(partial, bytes);
|
|
989
|
+
offset = next;
|
|
990
|
+
}
|
|
991
|
+
if (digest(await fs4.readFile(partial)) !== expected.sha256)
|
|
992
|
+
throw new Error("Downloaded bundle checksum mismatch");
|
|
993
|
+
await fs4.rename(partial, target);
|
|
994
|
+
await fs4.unlink(checkpoint);
|
|
995
|
+
}
|
|
996
|
+
const bundle = descriptor.kind === "runtime-evidence" ? await verifyRuntimeEvidenceBundle(bundleDir) : await verifyRuntimeFeedbackReplayBundle(bundleDir);
|
|
997
|
+
return bundle;
|
|
998
|
+
} finally {
|
|
999
|
+
await fs4.rmdir(lock);
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
843
1002
|
export {
|
|
1003
|
+
MCP_FEEDBACK_CONTRACT,
|
|
1004
|
+
McpReadTransportError,
|
|
844
1005
|
RUNTIME_EVIDENCE_COMPLETE_FILE,
|
|
845
1006
|
RUNTIME_EVIDENCE_MANIFEST_FILE,
|
|
846
1007
|
RUNTIME_EVIDENCE_PAYLOAD_FILE,
|
|
@@ -850,8 +1011,10 @@ export {
|
|
|
850
1011
|
RUNTIME_FEEDBACK_REPLAY_FILE,
|
|
851
1012
|
activeRuntimeEvidenceStrategies,
|
|
852
1013
|
assertCurrentRuntimeEvidenceArtifact,
|
|
1014
|
+
assertMcpFeedbackContract,
|
|
853
1015
|
discoverRuntimeEvidenceBundles,
|
|
854
1016
|
discoverRuntimeFeedbackReplayBundles,
|
|
1017
|
+
downloadMcpBundle,
|
|
855
1018
|
parseRuntimeEvidenceDeploymentSnapshot,
|
|
856
1019
|
parseRuntimeEvidenceProducer,
|
|
857
1020
|
publishRuntimeEvidenceBundle,
|
package/dist/mcp.d.mts
CHANGED
|
@@ -12,7 +12,7 @@ declare const redactMcpJobLog: (line: string) => string;
|
|
|
12
12
|
/** Offsets refer to the retained worker tail, which may shift while running. */
|
|
13
13
|
declare const readMcpJobLogs: (principal: McpPrincipal, id: string, offset?: number, limit?: number) => Promise<{
|
|
14
14
|
jobId: string;
|
|
15
|
-
status: "completed" | "failed" | "
|
|
15
|
+
status: "running" | "completed" | "failed" | "queued" | "waiting_resources" | "waiting_executor" | "cancelled";
|
|
16
16
|
updatedAt: number;
|
|
17
17
|
offset: number;
|
|
18
18
|
nextOffset: number | null;
|
|
@@ -30,7 +30,7 @@ declare const publicMcpJob: (job: McpJob) => {
|
|
|
30
30
|
userName: string;
|
|
31
31
|
clientId: string;
|
|
32
32
|
kind: "backtest" | "runtime-evidence" | "runtime-feedback-replay";
|
|
33
|
-
status: "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
33
|
+
status: "queued" | "waiting_resources" | "waiting_executor" | "running" | "completed" | "failed" | "cancelled";
|
|
34
34
|
createdAt: number;
|
|
35
35
|
updatedAt: number;
|
|
36
36
|
startedAt?: number;
|
package/dist/mcp.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare const redactMcpJobLog: (line: string) => string;
|
|
|
12
12
|
/** Offsets refer to the retained worker tail, which may shift while running. */
|
|
13
13
|
declare const readMcpJobLogs: (principal: McpPrincipal, id: string, offset?: number, limit?: number) => Promise<{
|
|
14
14
|
jobId: string;
|
|
15
|
-
status: "completed" | "failed" | "
|
|
15
|
+
status: "running" | "completed" | "failed" | "queued" | "waiting_resources" | "waiting_executor" | "cancelled";
|
|
16
16
|
updatedAt: number;
|
|
17
17
|
offset: number;
|
|
18
18
|
nextOffset: number | null;
|
|
@@ -30,7 +30,7 @@ declare const publicMcpJob: (job: McpJob) => {
|
|
|
30
30
|
userName: string;
|
|
31
31
|
clientId: string;
|
|
32
32
|
kind: "backtest" | "runtime-evidence" | "runtime-feedback-replay";
|
|
33
|
-
status: "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
33
|
+
status: "queued" | "waiting_resources" | "waiting_executor" | "running" | "completed" | "failed" | "cancelled";
|
|
34
34
|
createdAt: number;
|
|
35
35
|
updatedAt: number;
|
|
36
36
|
startedAt?: number;
|
package/dist/mcp.js
CHANGED
|
@@ -8912,7 +8912,10 @@ var cancelMcpJob = async (principal, id) => {
|
|
|
8912
8912
|
const job = await readMcpJob(principal.userName, id);
|
|
8913
8913
|
if (job.clientId !== principal.clientId)
|
|
8914
8914
|
throw new Error("Only the submitting client can cancel this job");
|
|
8915
|
-
if (!["queued", "running"].includes(
|
|
8915
|
+
if (!["queued", "waiting_resources", "waiting_executor", "running"].includes(
|
|
8916
|
+
job.status
|
|
8917
|
+
))
|
|
8918
|
+
return job;
|
|
8916
8919
|
const next = {
|
|
8917
8920
|
...job,
|
|
8918
8921
|
cancelRequested: true,
|
package/dist/mcp.mjs
CHANGED
|
@@ -236,7 +236,10 @@ var cancelMcpJob = async (principal, id) => {
|
|
|
236
236
|
const job = await readMcpJob(principal.userName, id);
|
|
237
237
|
if (job.clientId !== principal.clientId)
|
|
238
238
|
throw new Error("Only the submitting client can cancel this job");
|
|
239
|
-
if (!["queued", "running"].includes(
|
|
239
|
+
if (!["queued", "waiting_resources", "waiting_executor", "running"].includes(
|
|
240
|
+
job.status
|
|
241
|
+
))
|
|
242
|
+
return job;
|
|
240
243
|
const next = {
|
|
241
244
|
...job,
|
|
242
245
|
cancelRequested: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/node",
|
|
3
|
-
"version": "3.1.29-beta.
|
|
3
|
+
"version": "3.1.29-beta.283",
|
|
4
4
|
"description": "Node-only runtime for the TradeJS TypeScript framework: strategies, backtests, Pine strategy loading, and plugin registries.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -105,9 +105,9 @@
|
|
|
105
105
|
"dependencies": {
|
|
106
106
|
"@langchain/core": "^1.2.3",
|
|
107
107
|
"@langchain/openai": "^1.5.5",
|
|
108
|
-
"@tradejs/core": "^3.1.29-beta.
|
|
109
|
-
"@tradejs/infra": "^3.1.29-beta.
|
|
110
|
-
"@tradejs/types": "^3.1.29-beta.
|
|
108
|
+
"@tradejs/core": "^3.1.29-beta.283",
|
|
109
|
+
"@tradejs/infra": "^3.1.29-beta.283",
|
|
110
|
+
"@tradejs/types": "^3.1.29-beta.283",
|
|
111
111
|
"@types/node": "^24",
|
|
112
112
|
"chalk": "4.1.2",
|
|
113
113
|
"ioredis": "5.11.1",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"typescript": "^5.9"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
123
|
-
"@tradejs/indicators": "^3.1.29-beta.
|
|
123
|
+
"@tradejs/indicators": "^3.1.29-beta.283",
|
|
124
124
|
"@tradejs/strategy-adaptive-momentum-ribbon": "3.0.5",
|
|
125
125
|
"@tradejs/strategy-hyperliquid-consensus": "3.0.5",
|
|
126
126
|
"@tradejs/strategy-kit": "3.0.6",
|