@jinn-network/client 0.1.1 → 0.1.2-canary.d6e72dfd
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/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +123 -0
- package/README.md +210 -37
- package/deployments/deployment-claim-registry-baseSepolia.json +13 -0
- package/deployments/deployment-jinn-testnet-faucet-baseSepolia-fast.json +15 -0
- package/dist/adapters/claim-registry/abi.d.ts +127 -0
- package/dist/adapters/claim-registry/abi.js +93 -0
- package/dist/adapters/claim-registry/abi.js.map +1 -0
- package/dist/adapters/claim-registry/client.d.ts +89 -0
- package/dist/adapters/claim-registry/client.js +205 -0
- package/dist/adapters/claim-registry/client.js.map +1 -0
- package/dist/adapters/mech/adapter.d.ts +1 -0
- package/dist/adapters/mech/adapter.js +75 -41
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +2 -0
- package/dist/adapters/mech/contracts.js +57 -7
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/ipfs.d.ts +8 -0
- package/dist/adapters/mech/ipfs.js +12 -0
- package/dist/adapters/mech/ipfs.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +20 -46
- package/dist/adapters/mech/types.js +16 -35
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/api/gather-status.d.ts +1 -0
- package/dist/api/gather-status.js +33 -1
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +81 -0
- package/dist/api/portfolio-v0-build.js +141 -0
- package/dist/api/portfolio-v0-build.js.map +1 -0
- package/dist/api/portfolio-v0-doctor.d.ts +37 -0
- package/dist/api/portfolio-v0-doctor.js +123 -0
- package/dist/api/portfolio-v0-doctor.js.map +1 -0
- package/dist/api/rewards-build.js +1 -1
- package/dist/api/rewards-build.js.map +1 -1
- package/dist/api/status-build.d.ts +7 -0
- package/dist/api/status-build.js +1 -0
- package/dist/api/status-build.js.map +1 -1
- package/dist/bin/jinn-mcp.d.ts +0 -12
- package/dist/bin/jinn-mcp.js +5 -14
- package/dist/bin/jinn-mcp.js.map +1 -1
- package/dist/build-meta.json +1 -1
- package/dist/cli/commands/auth.js +115 -25
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/bootstrap.js +1 -0
- package/dist/cli/commands/bootstrap.js.map +1 -1
- package/dist/cli/commands/doctor.js +130 -14
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/fleet-scale.js +1 -0
- package/dist/cli/commands/fleet-scale.js.map +1 -1
- package/dist/cli/commands/fund-requirements.js +2 -0
- package/dist/cli/commands/fund-requirements.js.map +1 -1
- package/dist/cli/commands/intents.d.ts +17 -0
- package/dist/cli/commands/intents.js +489 -0
- package/dist/cli/commands/intents.js.map +1 -0
- package/dist/cli/commands/keys-backup.js +13 -11
- package/dist/cli/commands/keys-backup.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +3 -0
- package/dist/cli/commands/mcp.js +19 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/plugin-install.js +8 -4
- package/dist/cli/commands/plugin-install.js.map +1 -1
- package/dist/cli/commands/quickstart.js +60 -4
- package/dist/cli/commands/quickstart.js.map +1 -1
- package/dist/cli/commands/rewards.js +27 -1
- package/dist/cli/commands/rewards.js.map +1 -1
- package/dist/cli/commands/submit-intent.js +108 -5
- package/dist/cli/commands/submit-intent.js.map +1 -1
- package/dist/cli/commands/version.js +1 -0
- package/dist/cli/commands/version.js.map +1 -1
- package/dist/cli/deployment-digest.js +5 -0
- package/dist/cli/deployment-digest.js.map +1 -1
- package/dist/cli/execution-context.js +1 -0
- package/dist/cli/execution-context.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/intent-registry-access.d.ts +64 -0
- package/dist/cli/intent-registry-access.js +187 -0
- package/dist/cli/intent-registry-access.js.map +1 -0
- package/dist/cli/introspection-context.js +1 -0
- package/dist/cli/introspection-context.js.map +1 -1
- package/dist/cli/password.d.ts +21 -9
- package/dist/cli/password.js +45 -24
- package/dist/cli/password.js.map +1 -1
- package/dist/config.d.ts +110 -8
- package/dist/config.js +41 -12
- package/dist/config.js.map +1 -1
- package/dist/daemon/creator.d.ts +7 -1
- package/dist/daemon/creator.js +38 -3
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +43 -0
- package/dist/daemon/daemon.js +87 -2
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +2 -1
- package/dist/earning/bootstrap.js +72 -4
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +10 -0
- package/dist/earning/contracts.js +24 -0
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/jinn-rewards.d.ts +9 -0
- package/dist/earning/jinn-rewards.js +7 -0
- package/dist/earning/jinn-rewards.js.map +1 -1
- package/dist/intents/prediction-apy-v0-auto.d.ts +11 -0
- package/dist/intents/prediction-apy-v0-auto.js +46 -0
- package/dist/intents/prediction-apy-v0-auto.js.map +1 -0
- package/dist/intents/prediction-apy-v0-template.d.ts +8 -0
- package/dist/intents/prediction-apy-v0-template.js +22 -0
- package/dist/intents/prediction-apy-v0-template.js.map +1 -0
- package/dist/intents/prediction-v0-auto.d.ts +53 -0
- package/dist/intents/prediction-v0-auto.js +84 -0
- package/dist/intents/prediction-v0-auto.js.map +1 -0
- package/dist/intents/prediction-v0-template.d.ts +65 -0
- package/dist/intents/prediction-v0-template.js +125 -0
- package/dist/intents/prediction-v0-template.js.map +1 -0
- package/dist/main.js +149 -1
- package/dist/main.js.map +1 -1
- package/dist/mcp/operator-server.d.ts +1 -1
- package/dist/mcp/operator-server.js +1 -1
- package/dist/preflight/claude-auth.d.ts +12 -1
- package/dist/preflight/claude-auth.js +21 -3
- package/dist/preflight/claude-auth.js.map +1 -1
- package/dist/restorer/engine/canonical-json.d.ts +18 -0
- package/dist/restorer/engine/canonical-json.js +59 -0
- package/dist/restorer/engine/canonical-json.js.map +1 -0
- package/dist/restorer/engine/claim.d.ts +69 -0
- package/dist/restorer/engine/claim.js +104 -0
- package/dist/restorer/engine/claim.js.map +1 -0
- package/dist/restorer/engine/delivery.d.ts +52 -0
- package/dist/restorer/engine/delivery.js +63 -0
- package/dist/restorer/engine/delivery.js.map +1 -0
- package/dist/restorer/engine/engine.d.ts +203 -0
- package/dist/restorer/engine/engine.js +753 -0
- package/dist/restorer/engine/engine.js.map +1 -0
- package/dist/restorer/engine/manifest-assembly.d.ts +67 -0
- package/dist/restorer/engine/manifest-assembly.js +79 -0
- package/dist/restorer/engine/manifest-assembly.js.map +1 -0
- package/dist/restorer/engine/packaging.d.ts +87 -0
- package/dist/restorer/engine/packaging.js +350 -0
- package/dist/restorer/engine/packaging.js.map +1 -0
- package/dist/restorer/engine/persistence.d.ts +170 -0
- package/dist/restorer/engine/persistence.js +381 -0
- package/dist/restorer/engine/persistence.js.map +1 -0
- package/dist/restorer/engine/recovery.d.ts +22 -0
- package/dist/restorer/engine/recovery.js +24 -0
- package/dist/restorer/engine/recovery.js.map +1 -0
- package/dist/restorer/engine/registry.d.ts +62 -0
- package/dist/restorer/engine/registry.js +73 -0
- package/dist/restorer/engine/registry.js.map +1 -0
- package/dist/restorer/engine/signing.d.ts +30 -0
- package/dist/restorer/engine/signing.js +39 -0
- package/dist/restorer/engine/signing.js.map +1 -0
- package/dist/restorer/engine/state.d.ts +42 -0
- package/dist/restorer/engine/state.js +87 -0
- package/dist/restorer/engine/state.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.d.ts +64 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js +96 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/api-wallet.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.d.ts +101 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.js +710 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/index.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.d.ts +137 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js +865 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/mcp-tools.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.d.ts +74 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js +74 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/safety-rails.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.d.ts +97 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js +226 -0
- package/dist/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.d.ts +43 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.js +230 -0
- package/dist/restorer/impls/claude-mcp-prediction/index.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.d.ts +38 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js +135 -0
- package/dist/restorer/impls/claude-mcp-prediction/mcp-tools.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.d.ts +8 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.js +54 -0
- package/dist/restorer/impls/claude-mcp-prediction/prompt.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.d.ts +36 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js +137 -0
- package/dist/restorer/impls/claude-mcp-prediction/session-orchestrator.js.map +1 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.d.ts +82 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.js +6 -0
- package/dist/restorer/impls/claude-mcp-prediction/types.js.map +1 -0
- package/dist/restorer/impls/legacy-claude/index.d.ts +45 -0
- package/dist/restorer/impls/legacy-claude/index.js +71 -0
- package/dist/restorer/impls/legacy-claude/index.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.d.ts +68 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js +117 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.d.ts +49 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js +91 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.d.ts +78 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js +274 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/consistency.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.d.ts +23 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js +49 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.d.ts +25 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js +44 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.d.ts +17 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js +43 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.d.ts +43 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.js +431 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.d.ts +21 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.js +32 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.d.ts +32 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.js +8 -0
- package/dist/restorer/impls/portfolio-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.d.ts +39 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.js +98 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/index.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.d.ts +2 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js +7 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/strategy.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.d.ts +4 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.js +2 -0
- package/dist/restorer/impls/prediction-apy-v0-baseline/types.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +2 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js +7 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.d.ts +39 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js +186 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.d.ts +9 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js +20 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js +2 -0
- package/dist/restorer/impls/prediction-apy-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.d.ts +29 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.js +94 -0
- package/dist/restorer/impls/prediction-v0-baseline/index.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.d.ts +8 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.js +41 -0
- package/dist/restorer/impls/prediction-v0-baseline/strategy.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.js +2 -0
- package/dist/restorer/impls/prediction-v0-baseline/types.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.d.ts +20 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js +66 -0
- package/dist/restorer/impls/prediction-v0-evaluator/canonical-metrics.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.d.ts +9 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js +23 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/availability.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.d.ts +3 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js +13 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/eligibility.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js +93 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.d.ts +5 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js +20 -0
- package/dist/restorer/impls/prediction-v0-evaluator/checks/spec.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.d.ts +33 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.js +208 -0
- package/dist/restorer/impls/prediction-v0-evaluator/index.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.d.ts +8 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.js +15 -0
- package/dist/restorer/impls/prediction-v0-evaluator/score.js.map +1 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.d.ts +7 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.js +2 -0
- package/dist/restorer/impls/prediction-v0-evaluator/types.js.map +1 -0
- package/dist/restorer/types.d.ts +177 -0
- package/dist/restorer/types.js +7 -0
- package/dist/restorer/types.js.map +1 -0
- package/dist/store/store.d.ts +3 -1
- package/dist/store/store.js +3 -0
- package/dist/store/store.js.map +1 -1
- package/dist/types/desired-state.d.ts +53 -0
- package/dist/types/desired-state.js +20 -0
- package/dist/types/desired-state.js.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.js +4 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/portfolio.d.ts +1000 -0
- package/dist/types/portfolio.js +168 -0
- package/dist/types/portfolio.js.map +1 -0
- package/dist/types/prediction-apy.d.ts +919 -0
- package/dist/types/prediction-apy.js +121 -0
- package/dist/types/prediction-apy.js.map +1 -0
- package/dist/types/prediction.d.ts +925 -0
- package/dist/types/prediction.js +140 -0
- package/dist/types/prediction.js.map +1 -0
- package/dist/venues/aave-v3/addresses.d.ts +6 -0
- package/dist/venues/aave-v3/addresses.js +19 -0
- package/dist/venues/aave-v3/addresses.js.map +1 -0
- package/dist/venues/aave-v3/client.d.ts +81 -0
- package/dist/venues/aave-v3/client.js +97 -0
- package/dist/venues/aave-v3/client.js.map +1 -0
- package/dist/venues/chainlink/client.d.ts +99 -0
- package/dist/venues/chainlink/client.js +130 -0
- package/dist/venues/chainlink/client.js.map +1 -0
- package/dist/venues/chainlink/feeds.d.ts +8 -0
- package/dist/venues/chainlink/feeds.js +9 -0
- package/dist/venues/chainlink/feeds.js.map +1 -0
- package/dist/venues/hyperliquid/account-value.d.ts +30 -0
- package/dist/venues/hyperliquid/account-value.js +30 -0
- package/dist/venues/hyperliquid/account-value.js.map +1 -0
- package/dist/venues/hyperliquid/client.d.ts +63 -0
- package/dist/venues/hyperliquid/client.js +135 -0
- package/dist/venues/hyperliquid/client.js.map +1 -0
- package/dist/venues/hyperliquid/grid.d.ts +36 -0
- package/dist/venues/hyperliquid/grid.js +61 -0
- package/dist/venues/hyperliquid/grid.js.map +1 -0
- package/dist/venues/hyperliquid/types.d.ts +81 -0
- package/dist/venues/hyperliquid/types.js +8 -0
- package/dist/venues/hyperliquid/types.js.map +1 -0
- package/dist/withdraw/run-withdraw-plan.js +2 -0
- package/dist/withdraw/run-withdraw-plan.js.map +1 -1
- package/docker-compose.yml +44 -0
- package/package.json +12 -1
- package/skills/jinn-operator/SKILL.md +85 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claude-mcp-prediction — RestorerImpl for prediction.v0 that spawns a single
|
|
3
|
+
* Claude Code session with two MCP tools (read_chainlink_price +
|
|
4
|
+
* submit_prediction) and harvests the model's probability + rationale.
|
|
5
|
+
*
|
|
6
|
+
* Feature-flagged in main.ts via config.restorers.byKind['prediction.v0'];
|
|
7
|
+
* baseline (prediction-v0-baseline) remains the default. Flip once the
|
|
8
|
+
* isolation test (test/restorer/impls/claude-mcp-prediction/isolation.test.ts)
|
|
9
|
+
* is green on ≥3 separate runs.
|
|
10
|
+
*
|
|
11
|
+
* Structure mirrors claude-mcp-hyperliquid, minus trading, API wallet, safety
|
|
12
|
+
* rails, and the session cadence loop. Single-shot only.
|
|
13
|
+
*/
|
|
14
|
+
import { writeFileSync, mkdirSync, existsSync, readFileSync, chmodSync } from 'node:fs';
|
|
15
|
+
import { join, dirname } from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { PredictionV0IntentSchema } from '../../../types/prediction.js';
|
|
18
|
+
import { buildSessionPrompt } from './prompt.js';
|
|
19
|
+
import { spawnSession } from './session-orchestrator.js';
|
|
20
|
+
// ── Impl ──────────────────────────────────────────────────────────────────────
|
|
21
|
+
export class ClaudeMcpPredictionImpl {
|
|
22
|
+
config;
|
|
23
|
+
name = 'claude-mcp-prediction';
|
|
24
|
+
version = '1.0.0';
|
|
25
|
+
constructor(config = {}) {
|
|
26
|
+
this.config = config;
|
|
27
|
+
}
|
|
28
|
+
supports(ctx) {
|
|
29
|
+
return ctx.kind === 'prediction.v0' && ctx.type !== 'evaluation';
|
|
30
|
+
}
|
|
31
|
+
async canAttempt(intent) {
|
|
32
|
+
const parsed = PredictionV0IntentSchema.safeParse(intent);
|
|
33
|
+
if (!parsed.success)
|
|
34
|
+
return { ok: false, reason: `Invalid prediction.v0 intent: ${parsed.error.message}` };
|
|
35
|
+
if (Date.now() > parsed.data.window.endTs)
|
|
36
|
+
return { ok: false, reason: 'window already closed' };
|
|
37
|
+
return { ok: true };
|
|
38
|
+
}
|
|
39
|
+
async run(ctx) {
|
|
40
|
+
const { intent, workingDir, log } = ctx;
|
|
41
|
+
const parsed = PredictionV0IntentSchema.parse(intent);
|
|
42
|
+
const testDeps = this.config._testDeps;
|
|
43
|
+
// Shared submission state. The wrapper-subprocess writes to a JSONL file
|
|
44
|
+
// (submissionLogPath); the orchestrator's isSubmitted poll + our final
|
|
45
|
+
// read pull the record off disk. In test mode, _testDeps.runSession
|
|
46
|
+
// invokes signalSubmit directly to bypass the subprocess.
|
|
47
|
+
const submissionState = {
|
|
48
|
+
probability: null,
|
|
49
|
+
rationale: null,
|
|
50
|
+
submittedAt: null,
|
|
51
|
+
};
|
|
52
|
+
const signalSubmit = (probability, rationale) => {
|
|
53
|
+
submissionState.probability = probability;
|
|
54
|
+
submissionState.rationale = rationale;
|
|
55
|
+
submissionState.submittedAt = Date.now();
|
|
56
|
+
};
|
|
57
|
+
const sessionId = `pred-${Date.now()}`;
|
|
58
|
+
const prompt = buildSessionPrompt(parsed, sessionId);
|
|
59
|
+
// ── Test-mode short-circuit ────────────────────────────────────────────────
|
|
60
|
+
if (testDeps?.runSession) {
|
|
61
|
+
const session = await testDeps.runSession({
|
|
62
|
+
sessionId,
|
|
63
|
+
prompt,
|
|
64
|
+
mcpConfigPath: '<test>',
|
|
65
|
+
workingDir,
|
|
66
|
+
implStateDir: ctx.implStateDir,
|
|
67
|
+
timeoutMs: this.config.sessionMaxMs ?? 180_000,
|
|
68
|
+
signalSubmit,
|
|
69
|
+
});
|
|
70
|
+
return this._finalize(parsed, sessionId, session.transcriptPath, submissionState, session.startedAt, session.endedAt);
|
|
71
|
+
}
|
|
72
|
+
// ── Live path ──────────────────────────────────────────────────────────────
|
|
73
|
+
const mcpDir = join(workingDir, 'mcp');
|
|
74
|
+
mkdirSync(mcpDir, { recursive: true });
|
|
75
|
+
// Per-session submission log. The wrapper appends JSON lines here when
|
|
76
|
+
// submit_prediction is invoked. We tail it to detect the submission.
|
|
77
|
+
const submissionLogPath = join(mcpDir, 'submissions.jsonl');
|
|
78
|
+
writeFileSync(submissionLogPath, '', { encoding: 'utf-8', mode: 0o600 });
|
|
79
|
+
chmodSync(submissionLogPath, 0o600);
|
|
80
|
+
// Write the wrapper script + its config.
|
|
81
|
+
const wrapperPath = join(mcpDir, 'prediction-server.mjs');
|
|
82
|
+
const wrapperConfigPath = join(mcpDir, 'prediction-server-config.json');
|
|
83
|
+
const wrapperConfig = {
|
|
84
|
+
feed: parsed.spec.oracle.feed,
|
|
85
|
+
feedDescription: parsed.spec.oracle.feedDescription,
|
|
86
|
+
venue: parsed.spec.oracle.venue,
|
|
87
|
+
rpcUrl: this.config.rpcUrl ?? this._defaultRpcUrl(parsed.spec.oracle.venue),
|
|
88
|
+
submissionLogPath,
|
|
89
|
+
};
|
|
90
|
+
writeFileSync(wrapperConfigPath, JSON.stringify(wrapperConfig), { encoding: 'utf-8', mode: 0o600 });
|
|
91
|
+
chmodSync(wrapperConfigPath, 0o600);
|
|
92
|
+
_writePredictionMcpServerScript(wrapperPath);
|
|
93
|
+
// MCP config file Claude reads via --mcp-config.
|
|
94
|
+
const mcpConfigPath = join(mcpDir, 'mcp-config.json');
|
|
95
|
+
writeFileSync(mcpConfigPath, JSON.stringify({
|
|
96
|
+
mcpServers: {
|
|
97
|
+
'jinn-prediction': {
|
|
98
|
+
command: process.execPath,
|
|
99
|
+
args: [wrapperPath, wrapperConfigPath],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
}, null, 2));
|
|
103
|
+
// isSubmitted reads the JSONL log; as soon as there's a line, we know
|
|
104
|
+
// the tool fired. We also pull the probability + rationale from it so
|
|
105
|
+
// the cross-process boundary is clean.
|
|
106
|
+
const isSubmitted = () => {
|
|
107
|
+
try {
|
|
108
|
+
const contents = readFileSync(submissionLogPath, 'utf-8');
|
|
109
|
+
const lastLine = contents.trim().split('\n').pop() ?? '';
|
|
110
|
+
if (!lastLine)
|
|
111
|
+
return false;
|
|
112
|
+
const record = JSON.parse(lastLine);
|
|
113
|
+
if (record && typeof record.probability === 'string' && typeof record.rationale === 'string') {
|
|
114
|
+
signalSubmit(record.probability, record.rationale);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
};
|
|
123
|
+
log({ level: 'info', msg: 'claude-mcp-prediction: spawning session', data: { sessionId } });
|
|
124
|
+
const session = await spawnSession(sessionId, prompt, {
|
|
125
|
+
claudePath: this.config.claudePath ?? 'claude',
|
|
126
|
+
...(this.config.claudeModel ? { claudeModel: this.config.claudeModel } : {}),
|
|
127
|
+
mcpConfigPath,
|
|
128
|
+
workingDir,
|
|
129
|
+
abort: ctx.abort,
|
|
130
|
+
log,
|
|
131
|
+
isSubmitted,
|
|
132
|
+
...(this.config.sessionMaxMs !== undefined ? { sessionMaxMs: this.config.sessionMaxMs } : {}),
|
|
133
|
+
});
|
|
134
|
+
// One final read in case isSubmitted's poll raced with session exit.
|
|
135
|
+
if (!submissionState.probability)
|
|
136
|
+
isSubmitted();
|
|
137
|
+
return this._finalize(parsed, sessionId, session.transcriptPath, submissionState, session.startedAt, session.endedAt);
|
|
138
|
+
}
|
|
139
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
140
|
+
_finalize(intent, sessionId, transcriptPath, submission, startedAt, endedAt) {
|
|
141
|
+
if (!submission.probability || !submission.rationale) {
|
|
142
|
+
throw new Error(`claude-mcp-prediction: session ${sessionId} ended without a valid submit_prediction call`);
|
|
143
|
+
}
|
|
144
|
+
const submittedAt = submission.submittedAt ?? Date.now();
|
|
145
|
+
const modelId = `claude-mcp-prediction.${this.config.claudeModel ?? 'default'}.v1`;
|
|
146
|
+
const predictionPath = join(dirname(transcriptPath), '..', '..', 'prediction.json');
|
|
147
|
+
writeFileSync(predictionPath, JSON.stringify({
|
|
148
|
+
probability: submission.probability,
|
|
149
|
+
submittedAt,
|
|
150
|
+
modelId,
|
|
151
|
+
rationale: submission.rationale,
|
|
152
|
+
}, null, 2), { encoding: 'utf-8' });
|
|
153
|
+
return {
|
|
154
|
+
venueRef: { name: 'chainlink' },
|
|
155
|
+
gating: {
|
|
156
|
+
probability: submission.probability,
|
|
157
|
+
submittedAt: String(submittedAt),
|
|
158
|
+
modelId,
|
|
159
|
+
},
|
|
160
|
+
informational: {
|
|
161
|
+
rationale: submission.rationale,
|
|
162
|
+
sessionId,
|
|
163
|
+
transcriptPath,
|
|
164
|
+
feed: intent.spec.oracle.feed,
|
|
165
|
+
venue: intent.spec.oracle.venue,
|
|
166
|
+
sessionDurationMs: endedAt - startedAt,
|
|
167
|
+
},
|
|
168
|
+
artifacts: [
|
|
169
|
+
{ path: 'prediction.json', role: 'prediction_submission' },
|
|
170
|
+
{
|
|
171
|
+
path: transcriptPath,
|
|
172
|
+
role: 'session_transcript',
|
|
173
|
+
metadata: { sessionId, startedAt, endedAt },
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
_defaultRpcUrl(venue) {
|
|
179
|
+
return venue === 'chainlink-base' ? 'https://mainnet.base.org' : 'https://sepolia.base.org';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// ── Wrapper-script writer ─────────────────────────────────────────────────────
|
|
183
|
+
/**
|
|
184
|
+
* Generate a wrapper script that spawns the jinn-prediction MCP server.
|
|
185
|
+
* Follows the same "delegate to compiled mcp-tools.js" pattern as
|
|
186
|
+
* _writeHlMcpServerScript — plain Node loads the wrapper, which imports
|
|
187
|
+
* startMcpServer from the compiled file.
|
|
188
|
+
*/
|
|
189
|
+
export function _writePredictionMcpServerScript(outPath) {
|
|
190
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
191
|
+
// Resolve the COMPILED mcp-tools.js path. The wrapper is spawned by plain
|
|
192
|
+
// Node (not tsx) via --mcp-config, so it must import a .js file. After
|
|
193
|
+
// `yarn build` the compiled artifact lives at dist/.../mcp-tools.js.
|
|
194
|
+
//
|
|
195
|
+
// - Production (running from dist/): __filename is in /.../dist/... → sibling
|
|
196
|
+
// mcp-tools.js exists.
|
|
197
|
+
// - Dev/test (running source via tsx/vitest): __filename is in /.../src/...
|
|
198
|
+
// → rewrite path into /.../dist/... .
|
|
199
|
+
let mcpToolsPath = join(dirname(__filename), 'mcp-tools.js');
|
|
200
|
+
if (!existsSync(mcpToolsPath) && __filename.includes(`${'/'}src${'/'}`)) {
|
|
201
|
+
mcpToolsPath = __filename
|
|
202
|
+
.replace(`${'/'}src${'/'}`, `${'/'}dist${'/'}`)
|
|
203
|
+
.replace(/index\.(ts|js)$/, 'mcp-tools.js');
|
|
204
|
+
}
|
|
205
|
+
if (!existsSync(mcpToolsPath)) {
|
|
206
|
+
throw new Error(`E_DAEMON_MUST_RUN_FROM_DIST: ${mcpToolsPath} does not exist. ` +
|
|
207
|
+
`The claude-mcp-prediction wrapper subprocess loads this compiled artifact. ` +
|
|
208
|
+
`Run \`yarn build\` before starting the daemon or isolation test.`);
|
|
209
|
+
}
|
|
210
|
+
const script = `#!/usr/bin/env node
|
|
211
|
+
// Auto-generated jinn-prediction MCP wrapper — do not edit.
|
|
212
|
+
// Delegates to the compiled mcp-tools module; no business logic in the wrapper.
|
|
213
|
+
// Config (feed address, RPC url, submissionLogPath) is read from argv[2].
|
|
214
|
+
import { readFileSync } from 'node:fs';
|
|
215
|
+
import { startMcpServer } from ${JSON.stringify(mcpToolsPath)};
|
|
216
|
+
|
|
217
|
+
const configPath = process.argv[2];
|
|
218
|
+
if (!configPath) {
|
|
219
|
+
process.stderr.write('Usage: prediction-server.mjs <config-file-path>\\n');
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
224
|
+
await startMcpServer(config);
|
|
225
|
+
`.trim();
|
|
226
|
+
writeFileSync(outPath, script, { encoding: 'utf-8', mode: 0o600 });
|
|
227
|
+
chmodSync(outPath, 0o600);
|
|
228
|
+
}
|
|
229
|
+
export default ClaudeMcpPredictionImpl;
|
|
230
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/restorer/impls/claude-mcp-prediction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAExE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,iFAAiF;AAEjF,MAAM,OAAO,uBAAuB;IAIL;IAHpB,IAAI,GAAG,uBAAuB,CAAC;IAC/B,OAAO,GAAG,OAAO,CAAC;IAE3B,YAA6B,SAAoC,EAAE;QAAtC,WAAM,GAAN,MAAM,CAAgC;IAAG,CAAC;IAEvE,QAAQ,CAAC,GAA0D;QACjE,OAAO,GAAG,CAAC,IAAI,KAAK,eAAe,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,UAAU,CACd,MAAoB;QAEpB,MAAM,MAAM,GAAG,wBAAwB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3G,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QACjG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAuB;QAC/B,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QACxC,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAEvC,yEAAyE;QACzE,uEAAuE;QACvE,oEAAoE;QACpE,0DAA0D;QAC1D,MAAM,eAAe,GAAoB;YACvC,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI;SAClB,CAAC;QAEF,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,SAAiB,EAAQ,EAAE;YACpE,eAAe,CAAC,WAAW,GAAG,WAAW,CAAC;YAC1C,eAAe,CAAC,SAAS,GAAG,SAAS,CAAC;YACtC,eAAe,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3C,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAErD,8EAA8E;QAC9E,IAAI,QAAQ,EAAE,UAAU,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;gBACxC,SAAS;gBACT,MAAM;gBACN,aAAa,EAAE,QAAQ;gBACvB,UAAU;gBACV,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,OAAO;gBAC9C,YAAY;aACb,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,eAAe,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACxH,CAAC;QAED,8EAA8E;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACvC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvC,uEAAuE;QACvE,qEAAqE;QACrE,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;QAC5D,aAAa,CAAC,iBAAiB,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzE,SAAS,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAEpC,yCAAyC;QACzC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;QAC1D,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAAC;QACxE,MAAM,aAAa,GAAG;YACpB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;YAC7B,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe;YACnD,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK;YAC/B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAC3E,iBAAiB;SAClB,CAAC;QACF,aAAa,CAAC,iBAAiB,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,SAAS,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QACpC,+BAA+B,CAAC,WAAW,CAAC,CAAC;QAE7C,iDAAiD;QACjD,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QACtD,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC;YAC1C,UAAU,EAAE;gBACV,iBAAiB,EAAE;oBACjB,OAAO,EAAE,OAAO,CAAC,QAAQ;oBACzB,IAAI,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC;iBACvC;aACF;SACF,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEb,sEAAsE;QACtE,sEAAsE;QACtE,uCAAuC;QACvC,MAAM,WAAW,GAAG,GAAY,EAAE;YAChC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;gBAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBACzD,IAAI,CAAC,QAAQ;oBAAE,OAAO,KAAK,CAAC;gBAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACpC,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC7F,YAAY,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;oBACnD,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,yCAAyC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5F,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE;YACpD,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,QAAQ;YAC9C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,aAAa;YACb,UAAU;YACV,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG;YACH,WAAW;YACX,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9F,CAAC,CAAC;QAEH,qEAAqE;QACrE,IAAI,CAAC,eAAe,CAAC,WAAW;YAAE,WAAW,EAAE,CAAC;QAEhD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,eAAe,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxH,CAAC;IAED,gFAAgF;IAExE,SAAS,CACf,MAAiE,EACjE,SAAiB,EACjB,cAAsB,EACtB,UAA2B,EAC3B,SAAiB,EACjB,OAAe;QAEf,IAAI,CAAC,UAAU,CAAC,WAAW,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CACb,kCAAkC,SAAS,+CAA+C,CAC3F,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACzD,MAAM,OAAO,GAAG,yBAAyB,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,SAAS,KAAK,CAAC;QAEnF,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC;QACpF,aAAa,CACX,cAAc,EACd,IAAI,CAAC,SAAS,CAAC;YACb,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,WAAW;YACX,OAAO;YACP,SAAS,EAAE,UAAU,CAAC,SAAS;SAChC,EAAE,IAAI,EAAE,CAAC,CAAC,EACX,EAAE,QAAQ,EAAE,OAAO,EAAE,CACtB,CAAC;QAEF,OAAO;YACL,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC/B,MAAM,EAAE;gBACN,WAAW,EAAE,UAAU,CAAC,WAAW;gBACnC,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC;gBAChC,OAAO;aACR;YACD,aAAa,EAAE;gBACb,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,SAAS;gBACT,cAAc;gBACd,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI;gBAC7B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK;gBAC/B,iBAAiB,EAAE,OAAO,GAAG,SAAS;aACvC;YACD,SAAS,EAAE;gBACT,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,uBAAuB,EAAE;gBAC1D;oBACE,IAAI,EAAE,cAAc;oBACpB,IAAI,EAAE,oBAAoB;oBAC1B,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE;iBAC5C;aACF;SACF,CAAC;IACJ,CAAC;IAEO,cAAc,CAAC,KAAkD;QACvE,OAAO,KAAK,KAAK,gBAAgB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,0BAA0B,CAAC;IAC9F,CAAC;CACF;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,OAAe;IAC7D,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAElD,0EAA0E;IAC1E,uEAAuE;IACvE,qEAAqE;IACrE,EAAE;IACF,8EAA8E;IAC9E,yBAAyB;IACzB,4EAA4E;IAC5E,wCAAwC;IACxC,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;QACxE,YAAY,GAAG,UAAU;aACtB,OAAO,CAAC,GAAG,GAAG,MAAM,GAAG,EAAE,EAAE,GAAG,GAAG,OAAO,GAAG,EAAE,CAAC;aAC9C,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,gCAAgC,YAAY,mBAAmB;YAC/D,6EAA6E;YAC7E,kEAAkE,CACnE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG;;;;;iCAKgB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;;;;;;;;;;CAU5D,CAAC,IAAI,EAAE,CAAC;IAEP,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACnE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool definitions for claude-mcp-prediction.
|
|
3
|
+
*
|
|
4
|
+
* Two tools, minimal by design:
|
|
5
|
+
* - read_chainlink_price: read-only oracle query. No auth, no side effects.
|
|
6
|
+
* - submit_prediction: terminal tool. Records Claude's decision + ends session.
|
|
7
|
+
*
|
|
8
|
+
* No safety rails, no write-op tracking, no signing. Prediction has no capital
|
|
9
|
+
* surface; the only "write" is `submit_prediction` which writes to the impl's
|
|
10
|
+
* in-memory SubmissionState via onSubmit.
|
|
11
|
+
*
|
|
12
|
+
* Also exports startMcpServer(config): the wrapper-script entrypoint. Mirrors
|
|
13
|
+
* the pattern in claude-mcp-hyperliquid/mcp-tools.ts:1030-1079, minus the HL
|
|
14
|
+
* client + safety setup.
|
|
15
|
+
*/
|
|
16
|
+
import type { PredictionToolDefinition, PredictionToolDeps } from './types.js';
|
|
17
|
+
export declare function buildPredictionTools(deps: PredictionToolDeps): PredictionToolDefinition[];
|
|
18
|
+
/**
|
|
19
|
+
* Config passed into startMcpServer() — serialised as JSON by the impl, written
|
|
20
|
+
* to disk with mode 0o600 alongside the generated wrapper script, and read back
|
|
21
|
+
* by the wrapper when Claude's subprocess launches it via --mcp-config.
|
|
22
|
+
*
|
|
23
|
+
* This lives on-disk (not in memory) because the Claude subprocess spawns the
|
|
24
|
+
* wrapper as a fresh Node process — closures from the daemon don't survive.
|
|
25
|
+
*
|
|
26
|
+
* The wrapper's live submit_prediction handler CANNOT call back into the
|
|
27
|
+
* daemon's onSubmit closure across the process boundary. Instead the wrapper
|
|
28
|
+
* records the submission to `submissionLogPath` (a JSONL file the daemon tails).
|
|
29
|
+
*/
|
|
30
|
+
export interface McpServerConfig {
|
|
31
|
+
feed: `0x${string}`;
|
|
32
|
+
feedDescription: string;
|
|
33
|
+
venue: 'chainlink-base' | 'chainlink-base-sepolia';
|
|
34
|
+
rpcUrl: string;
|
|
35
|
+
/** The daemon tails this file to detect submissions. Created by the daemon. */
|
|
36
|
+
submissionLogPath: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function startMcpServer(config: McpServerConfig): Promise<void>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool definitions for claude-mcp-prediction.
|
|
3
|
+
*
|
|
4
|
+
* Two tools, minimal by design:
|
|
5
|
+
* - read_chainlink_price: read-only oracle query. No auth, no side effects.
|
|
6
|
+
* - submit_prediction: terminal tool. Records Claude's decision + ends session.
|
|
7
|
+
*
|
|
8
|
+
* No safety rails, no write-op tracking, no signing. Prediction has no capital
|
|
9
|
+
* surface; the only "write" is `submit_prediction` which writes to the impl's
|
|
10
|
+
* in-memory SubmissionState via onSubmit.
|
|
11
|
+
*
|
|
12
|
+
* Also exports startMcpServer(config): the wrapper-script entrypoint. Mirrors
|
|
13
|
+
* the pattern in claude-mcp-hyperliquid/mcp-tools.ts:1030-1079, minus the HL
|
|
14
|
+
* client + safety setup.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { createPublicClient, http } from 'viem';
|
|
18
|
+
import { base, baseSepolia } from 'viem/chains';
|
|
19
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
20
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
21
|
+
import { readChainlinkLatest, scaleToDecimal } from '../../../venues/chainlink/client.js';
|
|
22
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
23
|
+
function ok(data) {
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function toolErr(code, message) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{ type: 'text', text: JSON.stringify({ error: true, code, message }) },
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// ── Tool schemas ──────────────────────────────────────────────────────────────
|
|
36
|
+
const ReadChainlinkPriceSchema = z.object({});
|
|
37
|
+
const SubmitPredictionSchema = z.object({
|
|
38
|
+
probability: z
|
|
39
|
+
.number()
|
|
40
|
+
.min(0, 'probability must be ≥ 0')
|
|
41
|
+
.max(1, 'probability must be ≤ 1'),
|
|
42
|
+
rationale: z
|
|
43
|
+
.string()
|
|
44
|
+
.min(1, 'rationale must not be empty')
|
|
45
|
+
.max(2000, 'rationale must be ≤ 2000 characters'),
|
|
46
|
+
});
|
|
47
|
+
// ── Factory ───────────────────────────────────────────────────────────────────
|
|
48
|
+
export function buildPredictionTools(deps) {
|
|
49
|
+
const { feed, feedDescription, venue, publicClient, onSubmit } = deps;
|
|
50
|
+
const readChainlinkPrice = {
|
|
51
|
+
name: 'read_chainlink_price',
|
|
52
|
+
description: 'Read the current Chainlink price for the feed anchored in this prediction intent. Returns the price as a decimal string plus round metadata.',
|
|
53
|
+
schema: ReadChainlinkPriceSchema,
|
|
54
|
+
handler: async () => {
|
|
55
|
+
try {
|
|
56
|
+
const reading = await readChainlinkLatest(feed, publicClient);
|
|
57
|
+
const price = scaleToDecimal(reading.answer, reading.decimals);
|
|
58
|
+
return ok({
|
|
59
|
+
price,
|
|
60
|
+
roundId: String(reading.roundId),
|
|
61
|
+
updatedAt: reading.updatedAt,
|
|
62
|
+
feed,
|
|
63
|
+
feedDescription,
|
|
64
|
+
venue,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
return toolErr('CHAINLINK_READ_FAILED', err instanceof Error ? err.message : String(err));
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const submitPrediction = {
|
|
73
|
+
name: 'submit_prediction',
|
|
74
|
+
description: 'Submit your final prediction. `probability` is your probability (as a decimal number between 0 and 1) that the question resolves YES. `rationale` is a brief one-paragraph explanation of your reasoning. Calling this ends the session; do not call any other tool after it.',
|
|
75
|
+
schema: SubmitPredictionSchema,
|
|
76
|
+
handler: async (rawArgs) => {
|
|
77
|
+
const parsed = SubmitPredictionSchema.safeParse(rawArgs);
|
|
78
|
+
if (!parsed.success) {
|
|
79
|
+
return toolErr('INVALID_ARGS', parsed.error.issues.map(i => i.message).join('; '));
|
|
80
|
+
}
|
|
81
|
+
const { probability, rationale } = parsed.data;
|
|
82
|
+
// Fixed-point string to avoid float drift between tool + manifest.
|
|
83
|
+
const probabilityStr = probability.toFixed(4);
|
|
84
|
+
onSubmit({ probability: probabilityStr, rationale });
|
|
85
|
+
return ok({
|
|
86
|
+
accepted: true,
|
|
87
|
+
probability: probabilityStr,
|
|
88
|
+
note: 'Prediction recorded. The session will terminate shortly after this response reaches Claude.',
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
return [readChainlinkPrice, submitPrediction];
|
|
93
|
+
}
|
|
94
|
+
export async function startMcpServer(config) {
|
|
95
|
+
// Build a publicClient from the chain implied by venue.
|
|
96
|
+
const chain = config.venue === 'chainlink-base' ? base : baseSepolia;
|
|
97
|
+
const publicClient = createPublicClient({
|
|
98
|
+
chain,
|
|
99
|
+
transport: http(config.rpcUrl),
|
|
100
|
+
});
|
|
101
|
+
// The wrapper's onSubmit appends a JSONL record to submissionLogPath.
|
|
102
|
+
// The daemon's orchestrator tails the file and reads the submission from
|
|
103
|
+
// disk. This is the only IPC mechanism that survives the process boundary.
|
|
104
|
+
const { appendFileSync } = await import('node:fs');
|
|
105
|
+
const onSubmit = (submission) => {
|
|
106
|
+
appendFileSync(config.submissionLogPath, JSON.stringify({
|
|
107
|
+
ts: Date.now(),
|
|
108
|
+
probability: submission.probability,
|
|
109
|
+
rationale: submission.rationale,
|
|
110
|
+
}) + '\n', { encoding: 'utf-8' });
|
|
111
|
+
};
|
|
112
|
+
const tools = buildPredictionTools({
|
|
113
|
+
feed: config.feed,
|
|
114
|
+
feedDescription: config.feedDescription,
|
|
115
|
+
venue: config.venue,
|
|
116
|
+
publicClient,
|
|
117
|
+
onSubmit,
|
|
118
|
+
});
|
|
119
|
+
const server = new McpServer({ name: 'jinn-prediction', version: '1.0.0' });
|
|
120
|
+
// Same cast-around-MCP-index-signature pattern as hyperliquid's startMcpServer.
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
122
|
+
const registerTool = server.tool.bind(server);
|
|
123
|
+
for (const tool of tools) {
|
|
124
|
+
const shape = tool.schema.shape ?? {};
|
|
125
|
+
registerTool(tool.name, tool.description, shape, async (args) => tool.handler(args));
|
|
126
|
+
}
|
|
127
|
+
const transport = new StdioServerTransport();
|
|
128
|
+
await server.connect(transport);
|
|
129
|
+
// Keep alive until stdin closes (Claude closes it at session end).
|
|
130
|
+
await new Promise((resolve) => {
|
|
131
|
+
process.stdin.on('close', resolve);
|
|
132
|
+
process.stdin.on('end', resolve);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=mcp-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../../../../src/restorer/impls/claude-mcp-prediction/mcp-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template for claude-mcp-prediction sessions.
|
|
3
|
+
*
|
|
4
|
+
* Kept intentionally static (no branching) so the isolation test has
|
|
5
|
+
* deterministic behavior to assert against.
|
|
6
|
+
*/
|
|
7
|
+
import type { PredictionV0Intent } from '../../../types/prediction.js';
|
|
8
|
+
export declare function buildSessionPrompt(intent: PredictionV0Intent, sessionId: string): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template for claude-mcp-prediction sessions.
|
|
3
|
+
*
|
|
4
|
+
* Kept intentionally static (no branching) so the isolation test has
|
|
5
|
+
* deterministic behavior to assert against.
|
|
6
|
+
*/
|
|
7
|
+
function fmtOperator(op) {
|
|
8
|
+
switch (op) {
|
|
9
|
+
case 'GT': return '>';
|
|
10
|
+
case 'GTE': return '≥';
|
|
11
|
+
case 'LT': return '<';
|
|
12
|
+
case 'LTE': return '≤';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function buildSessionPrompt(intent, sessionId) {
|
|
16
|
+
const { oracle, question } = intent.spec;
|
|
17
|
+
const { window } = intent;
|
|
18
|
+
let questionLine;
|
|
19
|
+
if (question.kind === 'threshold') {
|
|
20
|
+
questionLine = `Will ${oracle.feedDescription} be ${fmtOperator(question.operator)} ${question.threshold} at resolveTs (${new Date(question.resolveTs).toISOString()})?`;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
questionLine = `Will ${oracle.feedDescription} be in [${question.lowerBound}, ${question.upperBound}) at resolveTs (${new Date(question.resolveTs).toISOString()})?`;
|
|
24
|
+
}
|
|
25
|
+
return [
|
|
26
|
+
`Session: ${sessionId}`,
|
|
27
|
+
'',
|
|
28
|
+
'You are evaluating a Jinn prediction intent. Decide the probability that the outcome will be YES and submit it via the submit_prediction tool.',
|
|
29
|
+
'',
|
|
30
|
+
`Question: ${questionLine}`,
|
|
31
|
+
'',
|
|
32
|
+
`Intent window: [${new Date(window.startTs).toISOString()}, ${new Date(window.endTs).toISOString()}]`,
|
|
33
|
+
`Resolution at: ${new Date(question.resolveTs).toISOString()}`,
|
|
34
|
+
`Oracle: Chainlink ${oracle.feedDescription} on ${oracle.venue}`,
|
|
35
|
+
'',
|
|
36
|
+
'You have exactly two tools:',
|
|
37
|
+
'',
|
|
38
|
+
' 1. read_chainlink_price — returns the current oracle price and round metadata. Call this once.',
|
|
39
|
+
' 2. submit_prediction — submit your final probability in [0, 1] with a brief rationale.',
|
|
40
|
+
' Calling this ends the session. Do not call any other tool afterward.',
|
|
41
|
+
'',
|
|
42
|
+
'Approach:',
|
|
43
|
+
' 1. Call read_chainlink_price to see the current price.',
|
|
44
|
+
' 2. Reason briefly about whether the outcome (YES/NO) is likely given the current price and time remaining.',
|
|
45
|
+
' 3. Call submit_prediction with your probability (a decimal between 0 and 1) and a concise rationale.',
|
|
46
|
+
'',
|
|
47
|
+
'Guidelines:',
|
|
48
|
+
' - Be honest. A probability of 0.5 means genuine uncertainty.',
|
|
49
|
+
' - Do not call submit_prediction before calling read_chainlink_price.',
|
|
50
|
+
' - The rationale should reference the price you read.',
|
|
51
|
+
' - Keep the rationale under 2000 characters.',
|
|
52
|
+
].join('\n');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../src/restorer/impls/claude-mcp-prediction/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,SAAS,WAAW,CAAC,EAA+B;IAClD,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,IAAI,CAAC,CAAE,OAAO,GAAG,CAAC;QACvB,KAAK,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC;QACvB,KAAK,IAAI,CAAC,CAAE,OAAO,GAAG,CAAC;QACvB,KAAK,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAA0B,EAAE,SAAiB;IAC9E,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE1B,IAAI,YAAoB,CAAC;IACzB,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAClC,YAAY,GAAG,QAAQ,MAAM,CAAC,eAAe,OAAO,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,SAAS,kBAAkB,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3K,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,QAAQ,MAAM,CAAC,eAAe,WAAW,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,mBAAmB,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC;IACvK,CAAC;IAED,OAAO;QACL,YAAY,SAAS,EAAE;QACvB,EAAE;QACF,gJAAgJ;QAChJ,EAAE;QACF,aAAa,YAAY,EAAE;QAC3B,EAAE;QACF,oBAAoB,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,GAAG;QACtG,mBAAmB,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;QAC/D,6BAA6B,MAAM,CAAC,eAAe,OAAO,MAAM,CAAC,KAAK,EAAE;QACxE,EAAE;QACF,6BAA6B;QAC7B,EAAE;QACF,kGAAkG;QAClG,6FAA6F;QAC7F,kGAAkG;QAClG,EAAE;QACF,WAAW;QACX,0DAA0D;QAC1D,8GAA8G;QAC9G,wGAAwG;QACxG,EAAE;QACF,aAAa;QACb,gEAAgE;QAChE,wEAAwE;QACxE,wDAAwD;QACxD,+CAA+C;KAChD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session orchestrator for claude-mcp-prediction.
|
|
3
|
+
*
|
|
4
|
+
* Single-session (no cadence loop, no market-move triggers). Spawns Claude
|
|
5
|
+
* once with the prediction MCP + prompt, polls a shared "submitted" flag to
|
|
6
|
+
* detect `submit_prediction` tool call, and terminates after a short grace
|
|
7
|
+
* period so Claude's tool response reaches it.
|
|
8
|
+
*
|
|
9
|
+
* Slimmed-down version of:
|
|
10
|
+
* client/src/restorer/impls/claude-mcp-hyperliquid/session-orchestrator.ts:97-209
|
|
11
|
+
*/
|
|
12
|
+
import { spawn } from 'node:child_process';
|
|
13
|
+
import type { SessionResult } from './types.js';
|
|
14
|
+
export interface OrchestratorDeps {
|
|
15
|
+
claudePath: string;
|
|
16
|
+
claudeModel?: string;
|
|
17
|
+
mcpConfigPath: string;
|
|
18
|
+
workingDir: string;
|
|
19
|
+
abort: AbortSignal;
|
|
20
|
+
log: (event: {
|
|
21
|
+
level: 'info' | 'warn' | 'error';
|
|
22
|
+
msg: string;
|
|
23
|
+
data?: unknown;
|
|
24
|
+
}) => void;
|
|
25
|
+
/** Poll callback — returns true once submit_prediction has been invoked. */
|
|
26
|
+
isSubmitted: () => boolean;
|
|
27
|
+
/** Max wall time for the session (ms). Default 3 min. */
|
|
28
|
+
sessionMaxMs?: number;
|
|
29
|
+
/** Interval at which we poll isSubmitted (ms). Default 500. */
|
|
30
|
+
pollIntervalMs?: number;
|
|
31
|
+
/** Grace period after submission before killing Claude (ms). Default 2s. */
|
|
32
|
+
submissionGraceMs?: number;
|
|
33
|
+
/** Injected spawn fn for tests. Defaults to child_process.spawn. */
|
|
34
|
+
_spawnFn?: typeof spawn;
|
|
35
|
+
}
|
|
36
|
+
export declare function spawnSession(sessionId: string, prompt: string, deps: OrchestratorDeps): Promise<SessionResult>;
|