perchai-cli 2.4.14 → 2.4.15
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/perch.mjs +51 -20
- package/package.json +4 -2
package/dist/perch.mjs
CHANGED
|
@@ -75566,7 +75566,6 @@ var init_payroll = __esm({
|
|
|
75566
75566
|
// lib/perchBusinessTools/index.ts
|
|
75567
75567
|
var init_perchBusinessTools = __esm({
|
|
75568
75568
|
"lib/perchBusinessTools/index.ts"() {
|
|
75569
|
-
"use strict";
|
|
75570
75569
|
init_generateAPAuditPacket();
|
|
75571
75570
|
init_inventoryFolder();
|
|
75572
75571
|
init_loadBusinessTables();
|
|
@@ -213392,11 +213391,14 @@ var init_config2 = __esm({
|
|
|
213392
213391
|
|
|
213393
213392
|
// features/perchTerminal/knowledge/knowledgeApiClient.ts
|
|
213394
213393
|
async function searchKnowledgeViaApi(input, options = {}) {
|
|
213395
|
-
const route = options.route ?? "/api/perch-terminal/knowledge/search";
|
|
213394
|
+
const route = resolveKnowledgeRoute(options.route ?? "/api/perch-terminal/knowledge/search");
|
|
213396
213395
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
213396
|
+
const headers = { "content-type": "application/json" };
|
|
213397
|
+
const token = process.env.PERCH_MODEL_CALL_PROXY_TOKEN?.trim();
|
|
213398
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
213397
213399
|
const response = await fetchImpl(route, {
|
|
213398
213400
|
method: "POST",
|
|
213399
|
-
headers
|
|
213401
|
+
headers,
|
|
213400
213402
|
body: JSON.stringify(input)
|
|
213401
213403
|
});
|
|
213402
213404
|
const payload = await response.json().catch(() => ({}));
|
|
@@ -213408,6 +213410,13 @@ async function searchKnowledgeViaApi(input, options = {}) {
|
|
|
213408
213410
|
}
|
|
213409
213411
|
return payload;
|
|
213410
213412
|
}
|
|
213413
|
+
function resolveKnowledgeRoute(route) {
|
|
213414
|
+
if (!route.startsWith("/")) return route;
|
|
213415
|
+
if (typeof window !== "undefined") return route;
|
|
213416
|
+
const appUrl = process.env.PERCH_MODEL_CALL_PROXY_URL?.trim() || process.env.PERCH_CLI_APP_URL?.trim() || process.env.PERCH_APP_URL?.trim();
|
|
213417
|
+
if (!appUrl) return route;
|
|
213418
|
+
return new URL(route, appUrl).toString();
|
|
213419
|
+
}
|
|
213411
213420
|
var KnowledgeApiClientError;
|
|
213412
213421
|
var init_knowledgeApiClient = __esm({
|
|
213413
213422
|
"features/perchTerminal/knowledge/knowledgeApiClient.ts"() {
|
|
@@ -214630,13 +214639,22 @@ async function computeLiveSignals(store, strategyId, asOf) {
|
|
|
214630
214639
|
}
|
|
214631
214640
|
return out;
|
|
214632
214641
|
}
|
|
214642
|
+
function ledgerFields(result2) {
|
|
214643
|
+
return result2.error ? { ledgerRecorded: result2.recorded, ledgerError: result2.error } : { ledgerRecorded: result2.recorded };
|
|
214644
|
+
}
|
|
214633
214645
|
async function recordLedger(ctx, row) {
|
|
214634
|
-
if (!ctx.supabase)
|
|
214646
|
+
if (!ctx.supabase) {
|
|
214647
|
+
return { recorded: false, error: "supabase_unavailable" };
|
|
214648
|
+
}
|
|
214635
214649
|
try {
|
|
214636
214650
|
const { error } = await ctx.supabase.from("perch_ai_market_backtest_runs").insert(row);
|
|
214637
|
-
return
|
|
214638
|
-
|
|
214639
|
-
|
|
214651
|
+
if (error) return { recorded: false, error: error.message };
|
|
214652
|
+
return { recorded: true };
|
|
214653
|
+
} catch (error) {
|
|
214654
|
+
return {
|
|
214655
|
+
recorded: false,
|
|
214656
|
+
error: error instanceof Error ? error.message : String(error)
|
|
214657
|
+
};
|
|
214640
214658
|
}
|
|
214641
214659
|
}
|
|
214642
214660
|
var NOT_ADVICE, getMarketSignalTool, queryMarketSignalLogTool, explainMarketSignalTool, listMarketStrategiesTool, MAX_PERIOD_DAYS, ISO_DATE, runMarketBacktestTool, getMarketTrackRecordTool, marketDeskTools;
|
|
@@ -214900,7 +214918,8 @@ var init_marketDesk = __esm({
|
|
|
214900
214918
|
holdout_acknowledged: acknowledgeHoldout,
|
|
214901
214919
|
initiator: "tool",
|
|
214902
214920
|
workspace_id: ctx.workspaceId ?? null,
|
|
214903
|
-
thread_id: ctx.threadId ?? null
|
|
214921
|
+
thread_id: ctx.threadId ?? null,
|
|
214922
|
+
user_id: ctx.userId ?? null
|
|
214904
214923
|
};
|
|
214905
214924
|
const wf = args.walkForward && typeof args.walkForward === "object" ? args.walkForward : void 0;
|
|
214906
214925
|
try {
|
|
@@ -214923,10 +214942,10 @@ var init_marketDesk = __esm({
|
|
|
214923
214942
|
paramGrid
|
|
214924
214943
|
});
|
|
214925
214944
|
if (!result3.ok) {
|
|
214926
|
-
await recordLedger(ctx, { ...ledgerBase, status: "failed", error: result3.error, holdout_overlap: false });
|
|
214927
|
-
return { ok: false, errorCode: "walk_forward_failed", message: result3.error };
|
|
214945
|
+
const ledger3 = await recordLedger(ctx, { ...ledgerBase, status: "failed", error: result3.error, holdout_overlap: false });
|
|
214946
|
+
return { ok: false, errorCode: "walk_forward_failed", message: result3.error, ...ledgerFields(ledger3) };
|
|
214928
214947
|
}
|
|
214929
|
-
const
|
|
214948
|
+
const ledger2 = await recordLedger(ctx, {
|
|
214930
214949
|
...ledgerBase,
|
|
214931
214950
|
status: "completed",
|
|
214932
214951
|
holdout_overlap: to >= resolveHoldoutStart(),
|
|
@@ -214951,17 +214970,17 @@ var init_marketDesk = __esm({
|
|
|
214951
214970
|
testMaxDrawdown: round(f.testMetrics.maxDrawdown)
|
|
214952
214971
|
})),
|
|
214953
214972
|
oosMetrics: compactMetrics(result3.oosMetrics),
|
|
214954
|
-
|
|
214973
|
+
...ledgerFields(ledger2),
|
|
214955
214974
|
note: "Out-of-sample (oosMetrics) is the only number that counts; train-window performance is selection, not evidence.",
|
|
214956
214975
|
disclaimer: NOT_ADVICE
|
|
214957
214976
|
};
|
|
214958
214977
|
}
|
|
214959
214978
|
const result2 = await runBacktest(store, backtestCfg);
|
|
214960
214979
|
if (!result2.ok) {
|
|
214961
|
-
await recordLedger(ctx, { ...ledgerBase, status: "failed", error: result2.error, holdout_overlap: false });
|
|
214962
|
-
return { ok: false, errorCode: "backtest_failed", message: result2.error };
|
|
214980
|
+
const ledger2 = await recordLedger(ctx, { ...ledgerBase, status: "failed", error: result2.error, holdout_overlap: false });
|
|
214981
|
+
return { ok: false, errorCode: "backtest_failed", message: result2.error, ...ledgerFields(ledger2) };
|
|
214963
214982
|
}
|
|
214964
|
-
const
|
|
214983
|
+
const ledger = await recordLedger(ctx, {
|
|
214965
214984
|
...ledgerBase,
|
|
214966
214985
|
status: "completed",
|
|
214967
214986
|
holdout_overlap: result2.holdout.overlapped,
|
|
@@ -214990,13 +215009,13 @@ var init_marketDesk = __esm({
|
|
|
214990
215009
|
signalCounts: result2.signalCounts,
|
|
214991
215010
|
equityCurve: downsample(result2.equityCurve, 60).map((p) => ({ date: p.date, equity: round(p.equity, 4) })),
|
|
214992
215011
|
trades: { closed: result2.trades.filter((t) => t.netReturn !== null).length, open: result2.trades.filter((t) => t.exitDate === null && t.netReturn === null).length },
|
|
214993
|
-
|
|
215012
|
+
...ledgerFields(ledger),
|
|
214994
215013
|
note: "Hypothetical backtest with modeled fees/slippage; past simulated performance does not predict future results. Every run (including this one) is recorded in the experiment ledger.",
|
|
214995
215014
|
disclaimer: NOT_ADVICE
|
|
214996
215015
|
};
|
|
214997
215016
|
} catch (error) {
|
|
214998
215017
|
if (error instanceof HoldoutViolationError) {
|
|
214999
|
-
await recordLedger(ctx, {
|
|
215018
|
+
const ledger2 = await recordLedger(ctx, {
|
|
215000
215019
|
...ledgerBase,
|
|
215001
215020
|
status: "failed",
|
|
215002
215021
|
error: "holdout_violation",
|
|
@@ -215007,12 +215026,13 @@ var init_marketDesk = __esm({
|
|
|
215007
215026
|
errorCode: "holdout_violation",
|
|
215008
215027
|
message: error.message,
|
|
215009
215028
|
holdoutStart: error.holdoutStart,
|
|
215010
|
-
hint: "The holdout window is reserved for final evaluation. Re-run with acknowledgeHoldout: true ONLY if the user explicitly wants to spend a holdout look; the run gets flagged in the ledger either way."
|
|
215029
|
+
hint: "The holdout window is reserved for final evaluation. Re-run with acknowledgeHoldout: true ONLY if the user explicitly wants to spend a holdout look; the run gets flagged in the ledger either way.",
|
|
215030
|
+
...ledgerFields(ledger2)
|
|
215011
215031
|
};
|
|
215012
215032
|
}
|
|
215013
215033
|
const message = error instanceof Error ? error.message : String(error);
|
|
215014
|
-
await recordLedger(ctx, { ...ledgerBase, status: "failed", error: message, holdout_overlap: false });
|
|
215015
|
-
return { ok: false, errorCode: "backtest_error", message };
|
|
215034
|
+
const ledger = await recordLedger(ctx, { ...ledgerBase, status: "failed", error: message, holdout_overlap: false });
|
|
215035
|
+
return { ok: false, errorCode: "backtest_error", message, ...ledgerFields(ledger) };
|
|
215016
215036
|
}
|
|
215017
215037
|
}
|
|
215018
215038
|
};
|
|
@@ -215190,11 +215210,22 @@ var init_registry5 = __esm({
|
|
|
215190
215210
|
async function executeRegisteredTool(name, args, ctx) {
|
|
215191
215211
|
const mod = getRegisteredTool(name);
|
|
215192
215212
|
if (!mod) return { handled: false };
|
|
215213
|
+
if (MARKET_DESK_TOOL_NAMES.has(name) && !isMarketDeskEnabled()) {
|
|
215214
|
+
return {
|
|
215215
|
+
handled: true,
|
|
215216
|
+
result: {
|
|
215217
|
+
ok: false,
|
|
215218
|
+
errorCode: "market_desk_disabled",
|
|
215219
|
+
message: "Market Desk tools are disabled. Set PERCH_MARKET_DESK=1 to enable them."
|
|
215220
|
+
}
|
|
215221
|
+
};
|
|
215222
|
+
}
|
|
215193
215223
|
return { handled: true, result: await mod.handler(args, ctx) };
|
|
215194
215224
|
}
|
|
215195
215225
|
var init_executeTool = __esm({
|
|
215196
215226
|
"features/perchTerminal/runtime/toolSystem/executeTool.ts"() {
|
|
215197
215227
|
"use strict";
|
|
215228
|
+
init_marketDeskAccess();
|
|
215198
215229
|
init_registry5();
|
|
215199
215230
|
}
|
|
215200
215231
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "perchai-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.15",
|
|
4
4
|
"description": "Perch AI command-line interface",
|
|
5
5
|
"bin": {
|
|
6
6
|
"perch": "bin/perch"
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"LICENSE"
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@
|
|
15
|
+
"@mozilla/readability": "^0.6.0",
|
|
16
|
+
"@napi-rs/canvas": "^0.1.100",
|
|
17
|
+
"jsdom": "^29.1.1"
|
|
16
18
|
},
|
|
17
19
|
"engines": {
|
|
18
20
|
"node": ">=20"
|