@almanak/mcp-server 0.2.8 → 0.2.10

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/tools.js CHANGED
@@ -876,17 +876,14 @@ class PlatformToolHandler {
876
876
  },
877
877
  required: ['agent_id'],
878
878
  },
879
- }, (args) => {
880
- var _a, _b;
881
- return this.fetchAgentLogsToFile({
882
- agentId: args.agent_id,
883
- navigationMode: (_a = args.navigation_mode) !== null && _a !== void 0 ? _a : 'GO_TO_END',
884
- page: (_b = args.page) !== null && _b !== void 0 ? _b : 1,
885
- targetTimestamp: args.target_timestamp,
886
- severity: args.severity,
887
- searchText: args.search_text,
888
- });
889
- });
879
+ }, (args) => { var _a, _b; return this.fetchAgentLogsToFile({
880
+ agentId: args.agent_id,
881
+ navigationMode: (_a = args.navigation_mode) !== null && _a !== void 0 ? _a : 'GO_TO_END',
882
+ page: (_b = args.page) !== null && _b !== void 0 ? _b : 1,
883
+ targetTimestamp: args.target_timestamp,
884
+ severity: args.severity,
885
+ searchText: args.search_text,
886
+ }); });
890
887
  this.register('agents', {
891
888
  name: 'agents_pnl',
892
889
  description: 'Get profit and loss data for an agent including current value, returns, and APY.',
@@ -909,15 +906,12 @@ class PlatformToolHandler {
909
906
  },
910
907
  required: ['agent_id'],
911
908
  },
912
- }, (args) => {
913
- var _a, _b, _c;
914
- return this.client.getAgentTransactions({
915
- agentId: args.agent_id,
916
- page: (_a = args.page) !== null && _a !== void 0 ? _a : 1,
917
- offset: (_b = args.offset) !== null && _b !== void 0 ? _b : 25,
918
- sort: (_c = args.sort) !== null && _c !== void 0 ? _c : 'desc',
919
- });
920
- });
909
+ }, (args) => { var _a, _b, _c; return this.client.getAgentTransactions({
910
+ agentId: args.agent_id,
911
+ page: (_a = args.page) !== null && _a !== void 0 ? _a : 1,
912
+ offset: (_b = args.offset) !== null && _b !== void 0 ? _b : 25,
913
+ sort: (_c = args.sort) !== null && _c !== void 0 ? _c : 'desc',
914
+ }); });
921
915
  this.register('agents', {
922
916
  name: 'agents_sync_status',
923
917
  description: 'Check if a deployed agent is in sync with its linked strategy repository. Returns IN_SYNC, OUT_OF_SYNC, or UNKNOWN.',
@@ -1004,16 +998,13 @@ class PlatformToolHandler {
1004
998
  },
1005
999
  required: ['wallet_id', 'eoa_address', 'chain_id'],
1006
1000
  },
1007
- }, async (args) => {
1008
- var _a;
1009
- return ({
1010
- wallet_id: args.wallet_id,
1011
- eoa_address: args.eoa_address,
1012
- chain_id: args.chain_id,
1013
- chain_name: (_a = args.chain_name) !== null && _a !== void 0 ? _a : '',
1014
- show_widget: true,
1015
- });
1016
- });
1001
+ }, async (args) => { var _a; return ({
1002
+ wallet_id: args.wallet_id,
1003
+ eoa_address: args.eoa_address,
1004
+ chain_id: args.chain_id,
1005
+ chain_name: (_a = args.chain_name) !== null && _a !== void 0 ? _a : '',
1006
+ show_widget: true,
1007
+ }); });
1017
1008
  // ─── Strategy tools ─────────────────────────────────────────
1018
1009
  this.register('strategies', {
1019
1010
  name: 'strategies_token_funding',
@@ -1040,23 +1031,25 @@ class PlatformToolHandler {
1040
1031
  },
1041
1032
  required: ['tokens'],
1042
1033
  },
1043
- }, async (args) => {
1044
- var _a, _b;
1045
- return ({
1046
- tokens: (_a = args.tokens) !== null && _a !== void 0 ? _a : [],
1047
- prompt: (_b = args.prompt) !== null && _b !== void 0 ? _b : 'How much (in USD) do you want to allocate per token?',
1048
- show_widget: true,
1049
- });
1050
- });
1034
+ }, async (args) => { var _a, _b; return ({
1035
+ tokens: (_a = args.tokens) !== null && _a !== void 0 ? _a : [],
1036
+ prompt: (_b = args.prompt) !== null && _b !== void 0 ? _b : 'How much (in USD) do you want to allocate per token?',
1037
+ show_widget: true,
1038
+ }); });
1051
1039
  this.register('strategies', {
1052
1040
  name: 'strategies_spec',
1053
- description: "Show the user an editable Strategy Spec panel to review and approve the strategy's risk posture BEFORE building. Call early — after confirming protocol support, before scaffolding. Pass plainSummary (one-line plain-language money-at-risk), fields (the few user-facing posture choices, each {key,label,description,value,unit}), the full content (the SPEC.json values), optional presets (conservative/balanced/aggressive content variants), and show_widget=true. content must include an `exit` object stating what stop/teardown does (close actions, asset policy), and fields must include an `exit.*` entry so the user sees it. If user constraints conflict with a clean exit, surface the resolution here rather than deciding silently. Give each field the unit that matches its meaning (see fields[].unit): a plain percentage such as an LP range width is `pct`, never `pct_of_balance`. Execution pauses; the user reviews/edits, then the reply is a fenced ```json``` block `{action, content}` — use the returned `content` as the approved build contract (the full SPEC values with the user's edits applied). Surface only genuine posture choices the strategy actually consults — keep safety internals in config.json.",
1041
+ description: "Show the user an editable Strategy Spec panel to review and approve the strategy's risk posture BEFORE building. Call early — after confirming protocol support, before scaffolding. Pass plainSummary (one-line plain-language money-at-risk), fields (the few user-facing posture choices, each {key,label,description,value,unit}), the full content (the SPEC.json values), optional presets (conservative/balanced/aggressive content variants), and show_widget=true. content must include an `exit` object stating what stop/teardown does (close actions, asset policy), and fields must include an `exit.*` entry so the user sees it. If user constraints conflict with a clean exit, surface the resolution here rather than deciding silently. Give each field the unit that matches its meaning (see fields[].unit): a plain percentage such as an LP range width is `pct`, never `pct_of_balance`. Execution pauses; the user reviews/edits, then the reply is a fenced ```json``` block `{action, content}` — use the returned `content` as the approved build contract (the full SPEC values with the user's edits applied). If the reply's action is `revise` it also carries `note` (a change the user asked for) and is NOT an approval: apply the note to `content` (keep fields, `behavior` and `exit` consistent), say in one line what changed or what cannot be done and the closest option, then call strategies_spec again for approval. Surface only genuine posture choices the strategy actually consults — keep safety internals in config.json.",
1054
1042
  inputSchema: {
1055
1043
  type: 'object',
1056
1044
  properties: {
1057
1045
  widgetId: { type: 'string', description: 'Widget identifier (default: "spec").' },
1058
1046
  plainSummary: { type: 'string', description: 'One-line plain-language summary of what the strategy does and risks.' },
1059
- content: { type: 'object', description: 'The SPEC.json values (the build contract).' },
1047
+ content: {
1048
+ type: 'object',
1049
+ description: 'The SPEC.json values (the build contract). Optional `behavior`: an array of 3–6 plain-language ' +
1050
+ 'trigger → action lines (entry, while a position is held, missing data, stop), shown read-only ' +
1051
+ 'under the fields as "How it behaves".',
1052
+ },
1060
1053
  fields: {
1061
1054
  type: 'array',
1062
1055
  description: 'User-facing posture fields to render. Each references a key in content.',
@@ -1600,9 +1593,9 @@ class PlatformToolHandler {
1600
1593
  name: 'run_test',
1601
1594
  description: 'Run the SDK test ladder against a strategy workspace and return per-step ' +
1602
1595
  'pass/fail with logs. SDK v2 workspaces (config.json) execute (1) Python import smoke, ' +
1603
- '(2) pytest tests/, (3) almanak strat run --network anvil --once, (4) almanak strat test ' +
1604
- 'lifecycle with optional force-action sequence + teardown. Steps 1+2 are ' +
1605
- 'fail-fast; steps 3+4 share a per-call gateway from the test-controller ' +
1596
+ '(2) python -m pytest tests/, (3) almanak strat run --network anvil --once, (4) almanak strat test ' +
1597
+ 'lifecycle with optional force-action sequence + teardown. Step 1 is fail-fast; a unit ' +
1598
+ 'failure still runs steps 3+4 and fails all_passed. Steps 3+4 share a per-call gateway from the test-controller ' +
1606
1599
  'sidecar. The lifecycle step\'s JSON summary is parsed and returned on ' +
1607
1600
  'steps[3].summary. SDK v3 workspaces (config.yaml) execute (1) almanak check --json ' +
1608
1601
  '(its document is returned on steps[0].summary) and (2) pytest tests/; the on-chain ' +
@@ -1683,19 +1676,20 @@ class PlatformToolHandler {
1683
1676
  * turn into a widget (the error card auto-resolves the gate immediately).
1684
1677
  */
1685
1678
  async runBacktest(args) {
1686
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
1687
- const strategyLinkId = String((_a = args.strategy_link_id) !== null && _a !== void 0 ? _a : '').trim();
1688
- const startTime = String((_b = args.start_time) !== null && _b !== void 0 ? _b : '').trim();
1679
+ var _a;
1680
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
1681
+ const strategyLinkId = String((_b = args.strategy_link_id) !== null && _b !== void 0 ? _b : '').trim();
1682
+ const startTime = String((_c = args.start_time) !== null && _c !== void 0 ? _c : '').trim();
1689
1683
  // required[] only checks presence — an empty/whitespace id would call
1690
1684
  // getStrategy('') → GET /github/strategies/ (the list route). Fail early.
1691
1685
  if (!strategyLinkId) {
1692
1686
  return {
1693
1687
  statusCode: 400,
1694
1688
  error: 'strategy_link_id is required — pass the linked strategy id (from strategies_list or the strategies_export_workspace result).',
1695
- backtest_config: { start_time: startTime, end_time: String((_c = args.end_time) !== null && _c !== void 0 ? _c : '').trim(), include_gas_costs: args.include_gas_costs !== false },
1689
+ backtest_config: { start_time: startTime, end_time: String((_d = args.end_time) !== null && _d !== void 0 ? _d : '').trim(), include_gas_costs: args.include_gas_costs !== false },
1696
1690
  };
1697
1691
  }
1698
- const endTime = String((_d = args.end_time) !== null && _d !== void 0 ? _d : '').trim();
1692
+ const endTime = String((_e = args.end_time) !== null && _e !== void 0 ? _e : '').trim();
1699
1693
  const includeGasCosts = args.include_gas_costs !== false;
1700
1694
  const backtestConfig = { start_time: startTime, end_time: endTime, include_gas_costs: includeGasCosts };
1701
1695
  const fail = (statusCode, error, extra) => ({
@@ -1728,7 +1722,7 @@ class PlatformToolHandler {
1728
1722
  try {
1729
1723
  const strategyRes = await this.client.getStrategy(strategyLinkId);
1730
1724
  if ((strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.valid) === false || !(strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.data)) {
1731
- return fail((_e = strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.statusCode) !== null && _e !== void 0 ? _e : 404, (_g = (_f = strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.message) !== null && _f !== void 0 ? _f : strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.error) !== null && _g !== void 0 ? _g : 'Strategy not found');
1725
+ return fail((_f = strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.statusCode) !== null && _f !== void 0 ? _f : 404, (_h = (_g = strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.message) !== null && _g !== void 0 ? _g : strategyRes === null || strategyRes === void 0 ? void 0 : strategyRes.error) !== null && _h !== void 0 ? _h : 'Strategy not found');
1732
1726
  }
1733
1727
  const strategy = strategyRes.data;
1734
1728
  // The stored framework_version is authoritative for which runner family serves the strategy.
@@ -1743,7 +1737,7 @@ class PlatformToolHandler {
1743
1737
  return await this.runV3Backtest(args, strategyLinkId, strategy);
1744
1738
  }
1745
1739
  if (sessionIsV3) {
1746
- return fail(400, `The strategy link is stored as SDK ${String((_h = strategy.framework_version) !== null && _h !== void 0 ? _h : 'v2').toLowerCase()}, but this chat session ` +
1740
+ return fail(400, `The strategy link is stored as SDK ${String((_j = strategy.framework_version) !== null && _j !== void 0 ? _j : 'v2').toLowerCase()}, but this chat session ` +
1747
1741
  'runs the SDK v3 lane. The stored generation decides which backtest runs, and the two disagree, so nothing was ' +
1748
1742
  'submitted. Do not add SDK v2 window inputs; tell the user the strategy link is not recognised as SDK v3 ' +
1749
1743
  '(its repository must resolve almanak 3.x and carry strategy.py and config.yaml at the root).', { errorCode: 'SDK_GENERATION_MISMATCH' });
@@ -1778,19 +1772,19 @@ class PlatformToolHandler {
1778
1772
  const refType = explicitSha ? 'commit' : 'branch';
1779
1773
  const refConfigRes = await this.client.getStrategyRefConfig(strategyLinkId, ref, refType);
1780
1774
  if ((refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.valid) === false || !(refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.data)) {
1781
- const baseError = (_k = (_j = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.message) !== null && _j !== void 0 ? _j : refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.error) !== null && _k !== void 0 ? _k : `Could not resolve ref "${ref}" for the linked strategy repository.`;
1775
+ const baseError = (_l = (_k = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.message) !== null && _k !== void 0 ? _k : refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.error) !== null && _l !== void 0 ? _l : `Could not resolve ref "${ref}" for the linked strategy repository.`;
1782
1776
  const recoveryGuidance = explicitSha
1783
1777
  ? ` Omit commit_sha only if the user explicitly approves running the latest commit on ${defaultBranch}; ` +
1784
1778
  'do not retry with different code automatically.'
1785
1779
  : '';
1786
- return fail((_l = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.statusCode) !== null && _l !== void 0 ? _l : 400, `${baseError}${recoveryGuidance}`, {
1787
- errorCode: (_m = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.errorCode) !== null && _m !== void 0 ? _m : 'INTERNAL_ERROR',
1780
+ return fail((_m = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.statusCode) !== null && _m !== void 0 ? _m : 400, `${baseError}${recoveryGuidance}`, {
1781
+ errorCode: (_o = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.errorCode) !== null && _o !== void 0 ? _o : 'INTERNAL_ERROR',
1788
1782
  retryable: (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.retryable) === true,
1789
1783
  ...recoveryContext,
1790
1784
  });
1791
1785
  }
1792
1786
  const refConfig = refConfigRes.data;
1793
- const commitSha = (_o = refConfig.github_commit_sha) !== null && _o !== void 0 ? _o : '';
1787
+ const commitSha = (_p = refConfig.github_commit_sha) !== null && _p !== void 0 ? _p : '';
1794
1788
  if (!FULL_COMMIT_SHA_RE.test(commitSha)) {
1795
1789
  return fail(400, `Could not resolve "${ref}" to a full commit SHA — has the strategy been pushed to its repository?`, {
1796
1790
  errorCode: 'COMMIT_UNRESOLVED',
@@ -1801,13 +1795,13 @@ class PlatformToolHandler {
1801
1795
  // /ref-config — pin it to the resolved commit so it matches the config.
1802
1796
  const refMetaRes = await this.client.getStrategyRefMetadata(strategyLinkId, commitSha);
1803
1797
  if ((refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.valid) === false || !(refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.data)) {
1804
- return fail((_p = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.statusCode) !== null && _p !== void 0 ? _p : 400, (_r = (_q = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.message) !== null && _q !== void 0 ? _q : refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.error) !== null && _r !== void 0 ? _r : 'Could not load strategy ref metadata');
1798
+ return fail((_q = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.statusCode) !== null && _q !== void 0 ? _q : 400, (_s = (_r = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.message) !== null && _r !== void 0 ? _r : refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.error) !== null && _s !== void 0 ? _s : 'Could not load strategy ref metadata');
1805
1799
  }
1806
- const sdkVersion = (_s = refMetaRes.data.almanak_sdk_version) !== null && _s !== void 0 ? _s : null;
1800
+ const sdkVersion = (_t = refMetaRes.data.almanak_sdk_version) !== null && _t !== void 0 ? _t : null;
1807
1801
  if (!sdkVersion) {
1808
1802
  return fail(400, 'Could not detect the Almanak SDK version from pyproject.toml at the selected commit.');
1809
1803
  }
1810
- if (((_u = (_t = parseSdkVersion(sdkVersion)) === null || _t === void 0 ? void 0 : _t.major) !== null && _u !== void 0 ? _u : 0) >= 3) {
1804
+ if (((_u = (_a = parseSdkVersion(sdkVersion)) === null || _a === void 0 ? void 0 : _a.major) !== null && _u !== void 0 ? _u : 0) >= 3) {
1811
1805
  // The backend refuses a v3 SDK against a V2 record; say why instead of submitting the v2 shape.
1812
1806
  return fail(400, `Commit ${commitSha.slice(0, 7)} resolves almanak ${sdkVersion} (SDK v3), but the strategy link is stored as SDK v2. ` +
1813
1807
  'The generations disagree, so nothing was submitted; SDK v2 window inputs cannot backtest an SDK v3 repository.', { errorCode: 'SDK_GENERATION_MISMATCH', commit_sha: commitSha, sdk_version: sdkVersion });
@@ -1857,7 +1851,8 @@ class PlatformToolHandler {
1857
1851
  * throws and every path returns a widget-renderable shape.
1858
1852
  */
1859
1853
  async runV3Backtest(args, strategyLinkId, strategy) {
1860
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
1854
+ var _a, _b, _c;
1855
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
1861
1856
  const strategyName = (typeof strategy.display_name === 'string' && strategy.display_name) ||
1862
1857
  (typeof strategy.github_repo_name === 'string' && strategy.github_repo_name) ||
1863
1858
  null;
@@ -1906,18 +1901,18 @@ class PlatformToolHandler {
1906
1901
  const recoveryContext = { requestedCommit: explicitSha || null, linkedRepo, defaultBranch };
1907
1902
  try {
1908
1903
  const refConfigRes = await this.client.getStrategyRefConfig(strategyLinkId, ref, refType);
1909
- const commitSha = (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.valid) === false ? '' : String((_b = (_a = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.data) === null || _a === void 0 ? void 0 : _a.github_commit_sha) !== null && _b !== void 0 ? _b : '');
1904
+ const commitSha = (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.valid) === false ? '' : String((_d = (_a = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.data) === null || _a === void 0 ? void 0 : _a.github_commit_sha) !== null && _d !== void 0 ? _d : '');
1910
1905
  if (!FULL_COMMIT_SHA_RE.test(commitSha)) {
1911
- const baseError = (_d = (_c = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.message) !== null && _c !== void 0 ? _c : refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.error) !== null && _d !== void 0 ? _d : `Could not resolve ${refType} "${ref}" in the linked strategy repository.`;
1906
+ const baseError = (_f = (_e = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.message) !== null && _e !== void 0 ? _e : refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.error) !== null && _f !== void 0 ? _f : `Could not resolve ${refType} "${ref}" in the linked strategy repository.`;
1912
1907
  // Push advice fits only a ref the repository does not have; access and availability errors keep their own text.
1913
- const errorCode = (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.valid) === false ? ((_e = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.errorCode) !== null && _e !== void 0 ? _e : 'INTERNAL_ERROR') : 'COMMIT_UNRESOLVED';
1908
+ const errorCode = (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.valid) === false ? ((_g = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.errorCode) !== null && _g !== void 0 ? _g : 'INTERNAL_ERROR') : 'COMMIT_UNRESOLVED';
1914
1909
  const guidance = errorCode !== 'COMMIT_UNRESOLVED'
1915
1910
  ? ''
1916
1911
  : explicitSha
1917
1912
  ? ` Only pushed commits can be backtested: make sure the commit is pushed to ${linkedRepo !== null && linkedRepo !== void 0 ? linkedRepo : 'the linked repository'} ` +
1918
1913
  '(git push, then git rev-parse HEAD) and call again with that SHA. Do not switch to a different commit without the user.'
1919
1914
  : ` Push the branch to ${linkedRepo !== null && linkedRepo !== void 0 ? linkedRepo : 'the linked repository'} first.`;
1920
- return fail((_f = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.statusCode) !== null && _f !== void 0 ? _f : 400, `${baseError}${guidance}`, {
1915
+ return fail((_h = refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.statusCode) !== null && _h !== void 0 ? _h : 400, `${baseError}${guidance}`, {
1921
1916
  errorCode,
1922
1917
  retryable: (refConfigRes === null || refConfigRes === void 0 ? void 0 : refConfigRes.retryable) === true,
1923
1918
  ...recoveryContext,
@@ -1926,7 +1921,7 @@ class PlatformToolHandler {
1926
1921
  context.commit_sha = commitSha;
1927
1922
  const refMetaRes = await this.client.getStrategyRefMetadata(strategyLinkId, commitSha);
1928
1923
  if ((refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.valid) === false || !(refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.data)) {
1929
- return fail((_g = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.statusCode) !== null && _g !== void 0 ? _g : 400, (_j = (_h = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.message) !== null && _h !== void 0 ? _h : refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.error) !== null && _j !== void 0 ? _j : 'Could not load strategy ref metadata');
1924
+ return fail((_j = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.statusCode) !== null && _j !== void 0 ? _j : 400, (_l = (_k = refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.message) !== null && _k !== void 0 ? _k : refMetaRes === null || refMetaRes === void 0 ? void 0 : refMetaRes.error) !== null && _l !== void 0 ? _l : 'Could not load strategy ref metadata');
1930
1925
  }
1931
1926
  const meta = refMetaRes.data;
1932
1927
  const sdkVersion = typeof meta.almanak_sdk_version === 'string' ? meta.almanak_sdk_version : '';
@@ -1936,7 +1931,7 @@ class PlatformToolHandler {
1936
1931
  });
1937
1932
  }
1938
1933
  context.sdk_version = sdkVersion;
1939
- if (((_l = (_k = parseSdkVersion(sdkVersion)) === null || _k === void 0 ? void 0 : _k.major) !== null && _l !== void 0 ? _l : 0) < 3 || !isSdkVersionBacktestable(sdkVersion, backtest_v3_1.MIN_BACKTEST_SDK_VERSION_V3)) {
1934
+ if (((_m = (_b = parseSdkVersion(sdkVersion)) === null || _b === void 0 ? void 0 : _b.major) !== null && _m !== void 0 ? _m : 0) < 3 || !isSdkVersionBacktestable(sdkVersion, backtest_v3_1.MIN_BACKTEST_SDK_VERSION_V3)) {
1940
1935
  return fail(400, `Hosted SDK v3 backtests need almanak ${backtest_v3_1.MIN_BACKTEST_SDK_VERSION_V3} or newer; commit ${commitSha.slice(0, 7)} resolves ` +
1941
1936
  `${sdkVersion}. Update the almanak pin (uv.lock / pyproject.toml), commit, push and re-run.`, { errorCode: 'V3_BACKTEST_INPUT_INVALID' });
1942
1937
  }
@@ -1967,7 +1962,7 @@ class PlatformToolHandler {
1967
1962
  // The file must exist at the commit; its contents are validated by the runner's pinned SDK, not here.
1968
1963
  if (committed[backtestPath] === undefined) {
1969
1964
  const fileRes = await this.client.getStrategyFileContent(strategyLinkId, backtestPath, commitSha);
1970
- const file = (fileRes === null || fileRes === void 0 ? void 0 : fileRes.valid) === false ? null : (_m = fileRes === null || fileRes === void 0 ? void 0 : fileRes.data) === null || _m === void 0 ? void 0 : _m.file;
1965
+ const file = (fileRes === null || fileRes === void 0 ? void 0 : fileRes.valid) === false ? null : (_c = fileRes === null || fileRes === void 0 ? void 0 : fileRes.data) === null || _c === void 0 ? void 0 : _c.file;
1971
1966
  const lookupError = (fileRes === null || fileRes === void 0 ? void 0 : fileRes.valid) === false ? String((_p = (_o = fileRes === null || fileRes === void 0 ? void 0 : fileRes.message) !== null && _o !== void 0 ? _o : fileRes === null || fileRes === void 0 ? void 0 : fileRes.error) !== null && _p !== void 0 ? _p : '') : '';
1972
1967
  if (file && typeof file.content !== 'string') {
1973
1968
  // The preview refuses some present files (build/dist/venv paths, directories, oversized files) with a reason.
@@ -2021,7 +2016,8 @@ class PlatformToolHandler {
2021
2016
  * path returned — equity curves and per-trade detail are read on demand.
2022
2017
  */
2023
2018
  async getBacktestResults(args) {
2024
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
2019
+ var _a, _b;
2020
+ var _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
2025
2021
  const backtestId = typeof args.backtest_id === 'string' ? args.backtest_id.trim() : '';
2026
2022
  if (!backtestId) {
2027
2023
  return {
@@ -2034,30 +2030,30 @@ class PlatformToolHandler {
2034
2030
  run = await this.client.getBacktest(backtestId);
2035
2031
  }
2036
2032
  catch (err) {
2037
- return { statusCode: 502, error: `Backtest lookup failed: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : String(err)}` };
2033
+ return { statusCode: 502, error: `Backtest lookup failed: ${(_c = err === null || err === void 0 ? void 0 : err.message) !== null && _c !== void 0 ? _c : String(err)}` };
2038
2034
  }
2039
2035
  if (!run || run.valid === false) {
2040
2036
  return {
2041
- statusCode: (_b = run === null || run === void 0 ? void 0 : run.statusCode) !== null && _b !== void 0 ? _b : 404,
2042
- error: (_c = run === null || run === void 0 ? void 0 : run.error) !== null && _c !== void 0 ? _c : 'Backtest run not found',
2037
+ statusCode: (_d = run === null || run === void 0 ? void 0 : run.statusCode) !== null && _d !== void 0 ? _d : 404,
2038
+ error: (_e = run === null || run === void 0 ? void 0 : run.error) !== null && _e !== void 0 ? _e : 'Backtest run not found',
2043
2039
  backtest_id: backtestId,
2044
2040
  };
2045
2041
  }
2046
2042
  if ((0, backtest_v3_1.isV3BacktestRun)(run)) {
2047
2043
  return this.getV3BacktestResults(backtestId, run);
2048
2044
  }
2049
- const summaryVerdict = summarizeRunValidity((_d = run.result_summary) === null || _d === void 0 ? void 0 : _d.run_validity);
2045
+ const summaryVerdict = summarizeRunValidity((_a = run.result_summary) === null || _a === void 0 ? void 0 : _a.run_validity);
2050
2046
  const base = {
2051
- backtest_id: (_e = run.id) !== null && _e !== void 0 ? _e : backtestId,
2047
+ backtest_id: (_f = run.id) !== null && _f !== void 0 ? _f : backtestId,
2052
2048
  status: run.status,
2053
- created_at: (_f = run.created_at) !== null && _f !== void 0 ? _f : null,
2054
- completed_at: (_g = run.completed_at) !== null && _g !== void 0 ? _g : null,
2055
- strategy_link_id: (_h = run.github_strategy_link_id) !== null && _h !== void 0 ? _h : null,
2056
- commit_sha: (_j = run.commit_sha) !== null && _j !== void 0 ? _j : null,
2057
- sdk_version: (_k = run.sdk_version) !== null && _k !== void 0 ? _k : null,
2058
- result_summary: (_l = run.result_summary) !== null && _l !== void 0 ? _l : null,
2049
+ created_at: (_g = run.created_at) !== null && _g !== void 0 ? _g : null,
2050
+ completed_at: (_h = run.completed_at) !== null && _h !== void 0 ? _h : null,
2051
+ strategy_link_id: (_j = run.github_strategy_link_id) !== null && _j !== void 0 ? _j : null,
2052
+ commit_sha: (_k = run.commit_sha) !== null && _k !== void 0 ? _k : null,
2053
+ sdk_version: (_l = run.sdk_version) !== null && _l !== void 0 ? _l : null,
2054
+ result_summary: (_m = run.result_summary) !== null && _m !== void 0 ? _m : null,
2059
2055
  run_validity: summaryVerdict,
2060
- error_message: (_m = run.error_message) !== null && _m !== void 0 ? _m : null,
2056
+ error_message: (_o = run.error_message) !== null && _o !== void 0 ? _o : null,
2061
2057
  };
2062
2058
  if (run.status !== 'COMPLETED') {
2063
2059
  let hint;
@@ -2086,24 +2082,24 @@ class PlatformToolHandler {
2086
2082
  doc = await this.client.getBacktestResult(backtestId);
2087
2083
  }
2088
2084
  catch (err) {
2089
- return { ...base, result_fetch_error: `Result fetch failed: ${(_o = err === null || err === void 0 ? void 0 : err.message) !== null && _o !== void 0 ? _o : String(err)}` };
2085
+ return { ...base, result_fetch_error: `Result fetch failed: ${(_p = err === null || err === void 0 ? void 0 : err.message) !== null && _p !== void 0 ? _p : String(err)}` };
2090
2086
  }
2091
2087
  if (!doc || doc.valid === false) {
2092
- return { ...base, result_fetch_error: (_p = doc === null || doc === void 0 ? void 0 : doc.error) !== null && _p !== void 0 ? _p : 'Backtest result not found' };
2088
+ return { ...base, result_fetch_error: (_q = doc === null || doc === void 0 ? void 0 : doc.error) !== null && _q !== void 0 ? _q : 'Backtest result not found' };
2093
2089
  }
2094
2090
  // Compute the compact inline fields BEFORE artifact persistence, so a
2095
2091
  // failed write degrades to summaries-without-a-file instead of losing
2096
2092
  // the whole (successful) lookup.
2097
- const result = (_q = doc.result) !== null && _q !== void 0 ? _q : {};
2093
+ const result = (_r = doc.result) !== null && _r !== void 0 ? _r : {};
2098
2094
  const trades = Array.isArray(result.trades) ? result.trades : [];
2099
- const decisionSummary = (_r = result.decision_summary) !== null && _r !== void 0 ? _r : null;
2100
- const runValidity = (_s = summarizeRunValidity(result.run_validity)) !== null && _s !== void 0 ? _s : summaryVerdict;
2095
+ const decisionSummary = (_s = result.decision_summary) !== null && _s !== void 0 ? _s : null;
2096
+ const runValidity = (_t = summarizeRunValidity(result.run_validity)) !== null && _t !== void 0 ? _t : summaryVerdict;
2101
2097
  const inline = {
2102
2098
  ...base,
2103
2099
  run_validity: runValidity,
2104
2100
  decision_summary: decisionSummary,
2105
- decision_input_failures: (_t = result.decision_input_failures) !== null && _t !== void 0 ? _t : [],
2106
- data_manifest_summary: (_v = (_u = result.data_manifest) === null || _u === void 0 ? void 0 : _u.summary) !== null && _v !== void 0 ? _v : null,
2101
+ decision_input_failures: (_u = result.decision_input_failures) !== null && _u !== void 0 ? _u : [],
2102
+ data_manifest_summary: (_v = (_b = result.data_manifest) === null || _b === void 0 ? void 0 : _b.summary) !== null && _v !== void 0 ? _v : null,
2107
2103
  trades_count: trades.length,
2108
2104
  };
2109
2105
  const passiveHint = (runValidity === null || runValidity === void 0 ? void 0 : runValidity.passive_only) === true