@jinn-network/client 0.1.6 → 0.1.7-canary.0a586ca9
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 +33 -0
- package/README.md +67 -1
- package/deployments/deployment-jinn-mvi-l1-sepolia-fast.json +23 -4
- package/deployments/deployment-jinn-mvi-l1-sepolia.json +23 -4
- package/deployments/deployment-jinn-mvi-l2-baseSepolia.json +5 -4
- package/dist/adapters/mech/adapter.d.ts +57 -2
- package/dist/adapters/mech/adapter.js +366 -63
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +17 -4
- package/dist/adapters/mech/contracts.js +19 -4
- package/dist/adapters/mech/contracts.js.map +1 -1
- package/dist/adapters/mech/safe-revert.d.ts +20 -0
- package/dist/adapters/mech/safe-revert.js +12 -4
- package/dist/adapters/mech/safe-revert.js.map +1 -1
- package/dist/adapters/mech/safe.d.ts +6 -2
- package/dist/adapters/mech/safe.js +32 -11
- package/dist/adapters/mech/safe.js.map +1 -1
- package/dist/adapters/mech/types.d.ts +6 -1
- package/dist/adapters/mech/types.js.map +1 -1
- package/dist/adapters/mech/verdict-code.d.ts +1 -0
- package/dist/adapters/mech/verdict-code.js +18 -0
- package/dist/adapters/mech/verdict-code.js.map +1 -1
- package/dist/agent/operator-claude.js +8 -0
- package/dist/agent/operator-claude.js.map +1 -1
- package/dist/api/activity-events-endpoint.d.ts +14 -0
- package/dist/api/activity-events-endpoint.js +59 -0
- package/dist/api/activity-events-endpoint.js.map +1 -0
- package/dist/api/admin-endpoint.d.ts +15 -3
- package/dist/api/admin-endpoint.js +24 -2
- package/dist/api/admin-endpoint.js.map +1 -1
- package/dist/api/bootstrap-endpoint.d.ts +1 -2
- package/dist/api/bootstrap-endpoint.js +85 -18
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/codex-doctor-endpoint.d.ts +90 -0
- package/dist/api/codex-doctor-endpoint.js +296 -0
- package/dist/api/codex-doctor-endpoint.js.map +1 -0
- package/dist/api/discovery-endpoint.d.ts +1 -0
- package/dist/api/discovery-endpoint.js +26 -0
- package/dist/api/discovery-endpoint.js.map +1 -1
- package/dist/api/fleet-build.d.ts +1 -0
- package/dist/api/fleet-build.js +2 -1
- package/dist/api/fleet-build.js.map +1 -1
- package/dist/api/gather-status.d.ts +37 -0
- package/dist/api/gather-status.js +572 -19
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +128 -3
- package/dist/api/hermes-doctor-endpoint.js +265 -22
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/launcher-status.d.ts +24 -17
- package/dist/api/launcher-status.js +13 -11
- package/dist/api/launcher-status.js.map +1 -1
- package/dist/api/launcher-tasks.d.ts +1 -1
- package/dist/api/launcher-tasks.js +12 -8
- package/dist/api/launcher-tasks.js.map +1 -1
- package/dist/api/operator-artifacts-endpoint.js +73 -6
- package/dist/api/operator-artifacts-endpoint.js.map +1 -1
- package/dist/api/portfolio-v0-build.d.ts +10 -0
- package/dist/api/portfolio-v0-build.js +24 -5
- package/dist/api/portfolio-v0-build.js.map +1 -1
- package/dist/api/prediction-v1-build.d.ts +10 -0
- package/dist/api/prediction-v1-build.js +7 -1
- package/dist/api/prediction-v1-build.js.map +1 -1
- package/dist/api/server.d.ts +31 -1
- package/dist/api/server.js +95 -2
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +7 -0
- package/dist/api/setup-endpoints.js +67 -135
- package/dist/api/setup-endpoints.js.map +1 -1
- package/dist/api/setup-retry-endpoint.d.ts +19 -0
- package/dist/api/setup-retry-endpoint.js +32 -0
- package/dist/api/setup-retry-endpoint.js.map +1 -0
- package/dist/api/solvernets-endpoints.d.ts +8 -0
- package/dist/api/solvernets-endpoints.js +100 -105
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +167 -2
- package/dist/api/status-build.js +118 -27
- package/dist/api/status-build.js.map +1 -1
- package/dist/api/status-harness-rollup.d.ts +35 -0
- package/dist/api/status-harness-rollup.js +45 -0
- package/dist/api/status-harness-rollup.js.map +1 -0
- package/dist/api/task-run-routing.d.ts +7 -0
- package/dist/api/task-run-routing.js +12 -0
- package/dist/api/task-run-routing.js.map +1 -0
- package/dist/api/task-runs-build.d.ts +21 -0
- package/dist/api/task-runs-build.js +14 -1
- package/dist/api/task-runs-build.js.map +1 -1
- package/dist/build-info.json +4 -4
- package/dist/build-meta.json +1 -1
- package/dist/captures/live-publisher.js +24 -4
- package/dist/captures/live-publisher.js.map +1 -1
- package/dist/captures/publish.d.ts +1 -1
- package/dist/chain-read-errors.d.ts +22 -0
- package/dist/chain-read-errors.js +41 -1
- package/dist/chain-read-errors.js.map +1 -1
- package/dist/cli/commands/auth.js +1 -1
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
- package/dist/cli/commands/codedigest-revert-check.js +249 -0
- package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
- package/dist/cli/commands/create.js +3 -2
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +2 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/rewards.js +11 -7
- package/dist/cli/commands/rewards.js.map +1 -1
- package/dist/cli/commands/solver-nets.d.ts +1 -0
- package/dist/cli/commands/solver-nets.js +179 -16
- package/dist/cli/commands/solver-nets.js.map +1 -1
- package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
- package/dist/cli/commands/solver-plugins-block.js +118 -0
- package/dist/cli/commands/solver-plugins-block.js.map +1 -0
- package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
- package/dist/cli/commands/solver-plugins-feedback.js +262 -0
- package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
- package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
- package/dist/cli/commands/solver-plugins-read.js +259 -0
- package/dist/cli/commands/solver-plugins-read.js.map +1 -0
- package/dist/cli/commands/solver-plugins.d.ts +35 -0
- package/dist/cli/commands/solver-plugins.js +399 -2
- package/dist/cli/commands/solver-plugins.js.map +1 -1
- package/dist/cli/commands/status.js +1 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tasks.js +101 -11
- package/dist/cli/commands/tasks.js.map +1 -1
- package/dist/cli/commands/update.d.ts +10 -0
- package/dist/cli/commands/update.js +36 -0
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/introspection-context.js +5 -0
- package/dist/cli/introspection-context.js.map +1 -1
- package/dist/cli/task-native-readiness.d.ts +10 -1
- package/dist/cli/task-native-readiness.js +30 -6
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +287 -235
- package/dist/config.js +318 -114
- package/dist/config.js.map +1 -1
- package/dist/daemon/checkpoint-loop.d.ts +48 -0
- package/dist/daemon/checkpoint-loop.js +76 -0
- package/dist/daemon/checkpoint-loop.js.map +1 -0
- package/dist/daemon/creator.d.ts +1 -1
- package/dist/daemon/creator.js +20 -3
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +22 -0
- package/dist/daemon/daemon.js +174 -31
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/daemon/eviction-loop.d.ts +40 -0
- package/dist/daemon/eviction-loop.js +67 -0
- package/dist/daemon/eviction-loop.js.map +1 -0
- package/dist/daemon/gate-logger.d.ts +9 -0
- package/dist/daemon/gate-logger.js +2 -0
- package/dist/daemon/gate-logger.js.map +1 -0
- package/dist/daemon/jinn-claim-loop-wiring.d.ts +33 -0
- package/dist/daemon/jinn-claim-loop-wiring.js +40 -0
- package/dist/daemon/jinn-claim-loop-wiring.js.map +1 -0
- package/dist/daemon/jinn-claim-loop.d.ts +24 -17
- package/dist/daemon/jinn-claim-loop.js +77 -23
- package/dist/daemon/jinn-claim-loop.js.map +1 -1
- package/dist/daemon/readiness-gate.d.ts +1 -4
- package/dist/daemon/readiness-gate.js.map +1 -1
- package/dist/daemon/skip-log-dedup.d.ts +69 -0
- package/dist/daemon/skip-log-dedup.js +106 -0
- package/dist/daemon/skip-log-dedup.js.map +1 -0
- package/dist/daemon/spend-cap-gate.d.ts +40 -0
- package/dist/daemon/spend-cap-gate.js +46 -0
- package/dist/daemon/spend-cap-gate.js.map +1 -0
- package/dist/dashboard/assets/index-BNs_ewI6.js +345 -0
- package/dist/dashboard/assets/index-C4huIsUW.css +32 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/discovery/factory.d.ts +17 -5
- package/dist/discovery/factory.js +46 -18
- package/dist/discovery/factory.js.map +1 -1
- package/dist/discovery/http.js +469 -3
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.d.ts +5 -0
- package/dist/discovery/onchain.js +448 -18
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +174 -1
- package/dist/discovery/types.js +8 -10
- package/dist/discovery/types.js.map +1 -1
- package/dist/discovery/with-fallback.d.ts +7 -0
- package/dist/discovery/with-fallback.js +37 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +100 -4
- package/dist/earning/bootstrap.js +239 -76
- package/dist/earning/bootstrap.js.map +1 -1
- package/dist/earning/contracts.d.ts +14 -0
- package/dist/earning/contracts.js +17 -5
- package/dist/earning/contracts.js.map +1 -1
- package/dist/earning/funding-plan.js +27 -18
- package/dist/earning/funding-plan.js.map +1 -1
- package/dist/earning/jinn-rewards.d.ts +46 -0
- package/dist/earning/jinn-rewards.js +32 -0
- package/dist/earning/jinn-rewards.js.map +1 -1
- package/dist/earning/safe-adapter.d.ts +2 -0
- package/dist/earning/safe-adapter.js +37 -11
- package/dist/earning/safe-adapter.js.map +1 -1
- package/dist/earning/store.d.ts +8 -0
- package/dist/earning/store.js.map +1 -1
- package/dist/earning/testnet-setup-migration.d.ts +12 -0
- package/dist/earning/testnet-setup-migration.js +27 -1
- package/dist/earning/testnet-setup-migration.js.map +1 -1
- package/dist/earning/types.d.ts +21 -6
- package/dist/earning/viem-clients.d.ts +11 -4
- package/dist/earning/viem-clients.js +14 -5
- package/dist/earning/viem-clients.js.map +1 -1
- package/dist/erc8004/identity.d.ts +19 -3
- package/dist/erc8004/identity.js +21 -6
- package/dist/erc8004/identity.js.map +1 -1
- package/dist/erc8004/index.d.ts +1 -1
- package/dist/erc8004/index.js.map +1 -1
- package/dist/erc8004/reputation.d.ts +8 -0
- package/dist/erc8004/reputation.js +22 -3
- package/dist/erc8004/reputation.js.map +1 -1
- package/dist/events/types.d.ts +2 -2
- package/dist/harnesses/cost-estimates.d.ts +124 -0
- package/dist/harnesses/cost-estimates.js +265 -0
- package/dist/harnesses/cost-estimates.js.map +1 -0
- package/dist/harnesses/engine/engine.d.ts +78 -0
- package/dist/harnesses/engine/engine.js +153 -11
- package/dist/harnesses/engine/engine.js.map +1 -1
- package/dist/harnesses/engine/persistence.d.ts +51 -1
- package/dist/harnesses/engine/persistence.js +118 -5
- package/dist/harnesses/engine/persistence.js.map +1 -1
- package/dist/harnesses/engine/work-dir-reaper.d.ts +65 -0
- package/dist/harnesses/engine/work-dir-reaper.js +100 -0
- package/dist/harnesses/engine/work-dir-reaper.js.map +1 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js +40 -0
- package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +20 -0
- package/dist/harnesses/impls/hermes-agent/bootstrap.js +44 -8
- package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
- package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
- package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/harness.d.ts +59 -1
- package/dist/harnesses/impls/hermes-agent/harness.js +104 -0
- package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
- package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
- package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
- package/dist/harnesses/impls/index.d.ts +7 -0
- package/dist/harnesses/impls/index.js +16 -1
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +47 -4
- package/dist/harnesses/impls/learner/harness.js +105 -2
- package/dist/harnesses/impls/learner/harness.js.map +1 -1
- package/dist/harnesses/impls/learner/harvest.d.ts +1 -1
- package/dist/harnesses/impls/learner/harvest.js +23 -5
- package/dist/harnesses/impls/learner/harvest.js.map +1 -1
- package/dist/harnesses/impls/learner/plugin-path.d.ts +0 -13
- package/dist/harnesses/impls/learner/plugin-path.js +35 -15
- package/dist/harnesses/impls/learner/plugin-path.js.map +1 -1
- package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
- package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
- package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
- package/dist/harnesses/impls/learner/types.d.ts +11 -0
- package/dist/harnesses/impls/stub.d.ts +58 -0
- package/dist/harnesses/impls/stub.js +89 -0
- package/dist/harnesses/impls/stub.js.map +1 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +69 -50
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +199 -94
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.d.ts +12 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +121 -7
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +88 -4
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +143 -22
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.d.ts +6 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js.map +1 -1
- package/dist/harnesses/readiness-registry.d.ts +7 -0
- package/dist/harnesses/readiness-registry.js +18 -1
- package/dist/harnesses/readiness-registry.js.map +1 -1
- package/dist/learner/revert-decision.d.ts +59 -0
- package/dist/learner/revert-decision.js +53 -0
- package/dist/learner/revert-decision.js.map +1 -0
- package/dist/learner/revert-stats.d.ts +24 -0
- package/dist/learner/revert-stats.js +44 -0
- package/dist/learner/revert-stats.js.map +1 -0
- package/dist/main.js +470 -142
- package/dist/main.js.map +1 -1
- package/dist/mcp/get-codedigest-reward.d.ts +13 -0
- package/dist/mcp/get-codedigest-reward.js +23 -0
- package/dist/mcp/get-codedigest-reward.js.map +1 -0
- package/dist/mcp/server.js +23 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/observability/emit-event.d.ts +3 -2
- package/dist/observability/emit-event.js +22 -1
- package/dist/observability/emit-event.js.map +1 -1
- package/dist/operator-errors.d.ts +7 -0
- package/dist/operator-errors.js +13 -1
- package/dist/operator-errors.js.map +1 -1
- package/dist/plugins/learner/.claude-plugin/plugin.json +9 -0
- package/dist/plugins/learner/.codex-plugin/plugin.json +39 -0
- package/dist/plugins/learner/AGENTS.md +40 -0
- package/dist/plugins/learner/CLAUDE.md +33 -0
- package/dist/plugins/learner/README.md +59 -0
- package/dist/plugins/learner/hooks/hooks.json +16 -0
- package/dist/plugins/learner/hooks/session-start +38 -0
- package/dist/plugins/learner/skills/learn/SKILL.md +412 -0
- package/dist/plugins/learner/skills/learn/analyst-prompt.md +68 -0
- package/dist/plugins/learner/skills/learn/consolidator-prompt.md +111 -0
- package/dist/plugins/learner/skills/learn/explorer-prompt.md +53 -0
- package/dist/plugins/learner/skills/learn/planner-prompt.md +87 -0
- package/dist/plugins/learner/skills/learn/promoter-prompt.md +184 -0
- package/dist/plugins/learner/skills/learn/step-worker-prompt.md +47 -0
- package/dist/plugins/learner/skills/learn/strategist-prompt.md +85 -0
- package/dist/preflight/pidfile-liveness.d.ts +44 -0
- package/dist/preflight/pidfile-liveness.js +103 -0
- package/dist/preflight/pidfile-liveness.js.map +1 -0
- package/dist/preflight/rpc-network.d.ts +40 -0
- package/dist/preflight/rpc-network.js +67 -1
- package/dist/preflight/rpc-network.js.map +1 -1
- package/dist/restart-daemon.d.ts +90 -0
- package/dist/restart-daemon.js +95 -0
- package/dist/restart-daemon.js.map +1 -0
- package/dist/rpc/transport.d.ts +109 -0
- package/dist/rpc/transport.js +220 -0
- package/dist/rpc/transport.js.map +1 -0
- package/dist/scripts/donation-consumption-acceptance.js +7 -28
- package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
- package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
- package/dist/setup/halt-mode.d.ts +14 -0
- package/dist/setup/halt-mode.js +17 -0
- package/dist/setup/halt-mode.js.map +1 -0
- package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
- package/dist/solver-nets/prediction-operator-ux.js +90 -47
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +20 -1
- package/dist/solver-nets/registry.js +38 -25
- package/dist/solver-nets/registry.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-pool-cache.d.ts +58 -0
- package/dist/solver-types/_swe-rebench-v2-pool-cache.js +87 -0
- package/dist/solver-types/_swe-rebench-v2-pool-cache.js.map +1 -0
- package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
- package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
- package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-state.d.ts +15 -0
- package/dist/solver-types/_swe-rebench-v2-state.js +19 -0
- package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-substrate.d.ts +1 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js +10 -0
- package/dist/solver-types/_swe-rebench-v2-substrate.js.map +1 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +145 -2
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +482 -44
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +38 -14
- package/dist/solver-types/swe-rebench-v2-auto.js +87 -28
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +19 -2
- package/dist/solver-types/swe-rebench-v2.js +351 -96
- package/dist/solver-types/swe-rebench-v2.js.map +1 -1
- package/dist/solvernets/daemon-init.d.ts +10 -2
- package/dist/solvernets/daemon-init.js +22 -2
- package/dist/solvernets/daemon-init.js.map +1 -1
- package/dist/solvernets/launched-record-dispatcher.d.ts +4 -0
- package/dist/solvernets/launched-record-dispatcher.js +41 -7
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/solvernets/registry-client-erc8004.js +11 -0
- package/dist/solvernets/registry-client-erc8004.js.map +1 -1
- package/dist/solvernets/store.d.ts +7 -2
- package/dist/solvernets/store.js +1 -0
- package/dist/solvernets/store.js.map +1 -1
- package/dist/spend/cost-surface-status.d.ts +10 -0
- package/dist/spend/cost-surface-status.js +22 -0
- package/dist/spend/cost-surface-status.js.map +1 -0
- package/dist/spend/credential.d.ts +8 -0
- package/dist/spend/credential.js +30 -0
- package/dist/spend/credential.js.map +1 -0
- package/dist/spend/daemon-config.d.ts +13 -0
- package/dist/spend/daemon-config.js +24 -0
- package/dist/spend/daemon-config.js.map +1 -0
- package/dist/spend/pricing.d.ts +16 -0
- package/dist/spend/pricing.js +26 -0
- package/dist/spend/pricing.js.map +1 -0
- package/dist/spend/record.d.ts +13 -0
- package/dist/spend/record.js +30 -0
- package/dist/spend/record.js.map +1 -0
- package/dist/spend/usage.d.ts +27 -0
- package/dist/spend/usage.js +113 -0
- package/dist/spend/usage.js.map +1 -0
- package/dist/store/store.d.ts +61 -0
- package/dist/store/store.js +302 -7
- package/dist/store/store.js.map +1 -1
- package/dist/tasks/sources.d.ts +18 -1
- package/dist/tasks/sources.js +33 -5
- package/dist/tasks/sources.js.map +1 -1
- package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
- package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
- package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
- package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
- package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
- package/dist/trajectory/transcript-session-dirs.js +85 -0
- package/dist/trajectory/transcript-session-dirs.js.map +1 -0
- package/dist/trajectory/transcript-watcher.d.ts +20 -1
- package/dist/trajectory/transcript-watcher.js +98 -32
- package/dist/trajectory/transcript-watcher.js.map +1 -1
- package/dist/tx-retry.d.ts +166 -19
- package/dist/tx-retry.js +310 -32
- package/dist/tx-retry.js.map +1 -1
- package/dist/types/payloads/portfolio-v0.d.ts +3 -3
- package/dist/types/payloads/prediction-apy-v0.d.ts +8 -8
- package/dist/types/payloads/prediction-v0.d.ts +17 -17
- package/dist/types/task-document.d.ts +392 -0
- package/dist/types/task-document.js +10 -0
- package/dist/types/task-document.js.map +1 -1
- package/dist/types/task.d.ts +28 -0
- package/dist/util/extract-tx-hash.d.ts +14 -0
- package/dist/util/extract-tx-hash.js +19 -0
- package/dist/util/extract-tx-hash.js.map +1 -0
- package/dist/vendor/@jinn-network/sdk/dist/contracts.js +1 -1
- package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.d.ts +3 -0
- package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.js +1 -0
- package/package.json +37 -13
- package/plugins/learner/skills/learn/consolidator-prompt.md +18 -1
- package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
- package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
- package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
- package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
- package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
- package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
- package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
- package/plugins/swe-rebench-v2-runtime/README.md +6 -6
- package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
- package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +69 -0
- package/dist/dashboard/assets/index-DOlzFN8a.css +0 -32
- package/dist/dashboard/assets/index-NkZ7CTAT.js +0 -140
- package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
- package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
package/dist/main.js
CHANGED
|
@@ -26,7 +26,8 @@ import { dirname, join } from 'node:path';
|
|
|
26
26
|
import { fileURLToPath } from 'node:url';
|
|
27
27
|
import { loadConfig, getConfigPathFromArgs, DEFAULT_CONFIG_PATH } from './config.js';
|
|
28
28
|
import { Store } from './store/store.js';
|
|
29
|
-
import { startApiServer } from './api/server.js';
|
|
29
|
+
import { startApiServer, isEmbeddedAgentEnabled } from './api/server.js';
|
|
30
|
+
import { setDefaultTxSubmissionLedger } from './tx-retry.js';
|
|
30
31
|
// addHarnessReadinessRoutes is wired through startApiServer's holder ref now
|
|
31
32
|
// (jinn-mono-u34i). No direct import needed.
|
|
32
33
|
import { CapturePublishUnavailableError } from './api/captures.js';
|
|
@@ -36,10 +37,12 @@ import { hashImplStateDir } from './harnesses/freeze.js';
|
|
|
36
37
|
import { readModeState } from './harnesses/mode-state.js';
|
|
37
38
|
import { attachAgentWs, updateAgentClaudePath } from './agent/agent-ws.js';
|
|
38
39
|
import { createSetupModeController } from './setup-mode.js';
|
|
40
|
+
import { requestDaemonRestart } from './restart-daemon.js';
|
|
39
41
|
import { buildEnvelope, emitEnvelope } from './errors/envelope.js';
|
|
40
42
|
import { clearBootstrapError, persistBootstrapError, } from './errors/persisted-bootstrap-error.js';
|
|
41
43
|
import { emitStructured } from './events/emitter.js';
|
|
42
|
-
import {
|
|
44
|
+
import { applyPidfileLivenessGate } from './preflight/pidfile-liveness.js';
|
|
45
|
+
import { FleetBootstrapper, recoverEvictedService as recoverEvictedServiceFn } from './earning/bootstrap.js';
|
|
43
46
|
import { DEFAULT_TESTNET_ARTIFACTS, applyChainGasOverrides, getChainConfig, loadJinnMviConfig } from './earning/contracts.js';
|
|
44
47
|
import { runLegacyAgentIdMigration } from './earning/migrate-agent-id.js';
|
|
45
48
|
import { FleetStateStore } from './earning/store.js';
|
|
@@ -48,6 +51,8 @@ import { decryptMnemonic, deriveMasterSigner, walletPrivateKeyAtIndex } from './
|
|
|
48
51
|
import { MechAdapter } from './adapters/mech/adapter.js';
|
|
49
52
|
import { ClaudeRunner } from './runner/claude.js';
|
|
50
53
|
import { Daemon } from './daemon/daemon.js';
|
|
54
|
+
import { buildSpendCapConfig } from './spend/daemon-config.js';
|
|
55
|
+
import { buildJinnClaimLoopConfig, shouldWireJinnClaimL1Signer, } from './daemon/jinn-claim-loop-wiring.js';
|
|
51
56
|
import { createJinnPublicClient, createJinnWalletClient, createJinnL1PublicClient, createJinnL1WalletClient } from './earning/viem-clients.js';
|
|
52
57
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
53
58
|
import { getAddress } from 'viem';
|
|
@@ -56,9 +61,10 @@ import { joinedSolverNetsViewFromConfig } from './harnesses/engine/engine.js';
|
|
|
56
61
|
import { buildHarnesses } from './harnesses/impls/index.js';
|
|
57
62
|
import { loadExternalImpl } from './harnesses/external-impls/index.js';
|
|
58
63
|
import { CLAUDE_CODE_HARNESS, CODEX_HARNESS, HERMES_AGENT_HARNESS, harnessStateDirName } from './harnesses/names.js';
|
|
64
|
+
import { resolveContractFromSolverNetId } from './solvernets/launched-record-dispatcher.js';
|
|
59
65
|
import { HarnessReadinessRegistry } from './harnesses/readiness-registry.js';
|
|
60
66
|
import { createClients } from './adapters/mech/safe.js';
|
|
61
|
-
import { loadSolverNets } from './solver-nets/registry.js';
|
|
67
|
+
import { findJoinedByName, loadSolverNets, solverTypeFromJoinedContract, } from './solver-nets/registry.js';
|
|
62
68
|
import { createCorpus } from './corpus/index.js';
|
|
63
69
|
import { DEFAULT_EXECUTION_DISCOVERY_FROM_BLOCK } from './corpus/onchain-query.js';
|
|
64
70
|
import { CapturesStore } from './store/captures.js';
|
|
@@ -74,12 +80,15 @@ import { ClaudeCodeJsonlParser } from './trajectory/transcript-parsers/claude-co
|
|
|
74
80
|
import { CodexSessionParser } from './trajectory/transcript-parsers/codex-session.js';
|
|
75
81
|
import { GeminiSessionParser } from './trajectory/transcript-parsers/gemini-session.js';
|
|
76
82
|
import { CursorSqliteParser } from './trajectory/transcript-parsers/cursor-sqlite.js';
|
|
83
|
+
import { startTranscriptWatcher, } from './trajectory/transcript-watcher.js';
|
|
84
|
+
import { defaultTranscriptWatchDirectories } from './trajectory/transcript-session-dirs.js';
|
|
77
85
|
import { buildInfo } from './build-info.js';
|
|
78
86
|
import { BASE_FEEDS } from './venues/chainlink/feeds.js';
|
|
79
|
-
import { GeneratedTaskSource, StaticConfiguredTaskSource } from './tasks/sources.js';
|
|
80
|
-
import { checkRpcNetwork, logRpcLocalDevToStderr, rpcNetworkFailureHint } from './preflight/rpc-network.js';
|
|
87
|
+
import { GeneratedTaskSource, StaticConfiguredTaskSource, filterBindableTasks } from './tasks/sources.js';
|
|
88
|
+
import { checkRpcNetwork, logRpcLocalDevToStderr, probeFallbackChain, rpcNetworkFailureHint, summarizeFallbackChain, } from './preflight/rpc-network.js';
|
|
81
89
|
import { apiPortFailureMessage, checkApiPortAvailable } from './preflight/api-port.js';
|
|
82
90
|
import { openBrowser } from './cli/open-browser.js';
|
|
91
|
+
import { keepSetupUiOnBootstrapError } from './setup/halt-mode.js';
|
|
83
92
|
if (process.env['JINN_LOAD_DEV_ENV'] === '1' || process.env['NODE_ENV'] === 'development') {
|
|
84
93
|
dotenvConfig({ path: join(dirname(fileURLToPath(import.meta.url)), '..', '.env') });
|
|
85
94
|
}
|
|
@@ -132,8 +141,19 @@ const config = loadConfig(CONFIG_PATH);
|
|
|
132
141
|
if (config.network === 'mainnet' && process.env['JINN_ENABLE_MAINNET'] !== '1') {
|
|
133
142
|
console.warn('[main] Mainnet is disabled before launch; using testnet defaults.');
|
|
134
143
|
config.network = 'testnet';
|
|
135
|
-
config.rpcUrl = 'https://base-sepolia.
|
|
144
|
+
config.rpcUrl = 'https://base-sepolia-rpc.publicnode.com';
|
|
136
145
|
}
|
|
146
|
+
// Issue #326: the embedded Claude agent chat surface (right rail + onboarding
|
|
147
|
+
// "Ask Claude" panel + /api/agent/ws bridge) is hidden by default while its
|
|
148
|
+
// action-authority / plugin-scope shape is still in design. Set
|
|
149
|
+
// `JINN_ENABLE_EMBEDDED_AGENT=1` to re-enable it for development. This does
|
|
150
|
+
// NOT affect Claude-Code-as-a-solver-harness — that path is independent.
|
|
151
|
+
//
|
|
152
|
+
// Issue #367: the SPA reads this flag via the injected `window.__JINN_FEATURES__`
|
|
153
|
+
// (`resolveFeatureFlags` in api/server.ts) like every other operator-app flag.
|
|
154
|
+
// This `embeddedAgentEnabled` const is the daemon-side consumer only — it gates
|
|
155
|
+
// whether the `/api/agent/ws` bridge is mounted below.
|
|
156
|
+
const embeddedAgentEnabled = isEmbeddedAgentEnabled();
|
|
137
157
|
let activeClaudePath = config.claudePath ?? 'claude';
|
|
138
158
|
const selectClaudePath = (claudePath) => {
|
|
139
159
|
activeClaudePath = claudePath;
|
|
@@ -187,25 +207,15 @@ class EnsurePendingCaptureProcessor {
|
|
|
187
207
|
onStart() { }
|
|
188
208
|
onEnd(span) {
|
|
189
209
|
const sessionId = stringAttribute(span.attributes['jinn.session.id']);
|
|
190
|
-
if (!sessionId
|
|
210
|
+
if (!sessionId)
|
|
191
211
|
return;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
spanCount: 0,
|
|
200
|
-
durationMs: 0,
|
|
201
|
-
redactedSpanCount: 0,
|
|
202
|
-
...repoMetadataFromSpan(span),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
catch (err) {
|
|
206
|
-
if (!this.captures.getBySession(sessionId))
|
|
207
|
-
throw err;
|
|
208
|
-
}
|
|
212
|
+
ensurePendingCapture(this.captures, {
|
|
213
|
+
sessionId,
|
|
214
|
+
capturedAt: hrTimeToIso(span.startTime),
|
|
215
|
+
tool: inferCaptureTool(span),
|
|
216
|
+
capturePath: inferCapturePath(span),
|
|
217
|
+
...repoMetadataFromSpan(span),
|
|
218
|
+
});
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
function stringAttribute(value) {
|
|
@@ -220,6 +230,11 @@ function inferCaptureTool(span) {
|
|
|
220
230
|
?? stringAttribute(span.resource.attributes['service.name'])
|
|
221
231
|
?? 'otel';
|
|
222
232
|
}
|
|
233
|
+
function inferCapturePath(span) {
|
|
234
|
+
if (stringAttribute(span.attributes['transcript.tool']))
|
|
235
|
+
return 'B';
|
|
236
|
+
return 'A';
|
|
237
|
+
}
|
|
223
238
|
function repoMetadataFromSpan(span) {
|
|
224
239
|
const attrs = span.attributes;
|
|
225
240
|
const repoRemoteUrl = stringAttribute(attrs['repo.remote_url'])
|
|
@@ -249,28 +264,35 @@ function parserForStopHookTool(tool) {
|
|
|
249
264
|
}
|
|
250
265
|
}
|
|
251
266
|
}
|
|
252
|
-
function
|
|
253
|
-
if (captures.getBySession(
|
|
267
|
+
function ensurePendingCapture(captures, params) {
|
|
268
|
+
if (captures.getBySession(params.sessionId))
|
|
254
269
|
return;
|
|
255
270
|
try {
|
|
256
271
|
captures.savePending({
|
|
257
|
-
sessionId:
|
|
258
|
-
capturedAt:
|
|
259
|
-
originatingTool: { name:
|
|
260
|
-
capturePath:
|
|
272
|
+
sessionId: params.sessionId,
|
|
273
|
+
capturedAt: params.capturedAt,
|
|
274
|
+
originatingTool: { name: params.tool },
|
|
275
|
+
capturePath: params.capturePath,
|
|
261
276
|
status: 'pending',
|
|
262
277
|
spanCount: 0,
|
|
263
278
|
durationMs: 0,
|
|
264
279
|
redactedSpanCount: 0,
|
|
280
|
+
...(params.repoRemoteUrl ? { repoRemoteUrl: params.repoRemoteUrl } : {}),
|
|
281
|
+
...(params.repoCommitHash ? { repoCommitHash: params.repoCommitHash } : {}),
|
|
265
282
|
});
|
|
266
283
|
}
|
|
267
284
|
catch (err) {
|
|
268
|
-
if (!captures.getBySession(
|
|
285
|
+
if (!captures.getBySession(params.sessionId))
|
|
269
286
|
throw err;
|
|
270
287
|
}
|
|
271
288
|
}
|
|
272
289
|
async function ingestStopHookCapture(captures, receiver, payload) {
|
|
273
|
-
|
|
290
|
+
ensurePendingCapture(captures, {
|
|
291
|
+
sessionId: payload.sessionId,
|
|
292
|
+
capturedAt: payload.stoppedAt,
|
|
293
|
+
tool: payload.tool,
|
|
294
|
+
capturePath: 'D',
|
|
295
|
+
});
|
|
274
296
|
if (!payload.transcriptPath)
|
|
275
297
|
return;
|
|
276
298
|
if (!receiver) {
|
|
@@ -484,11 +506,17 @@ async function bootstrap() {
|
|
|
484
506
|
hint: 'Fund the listed address and re-run this command.',
|
|
485
507
|
exampleCli: 'jinn fund-requirements --json',
|
|
486
508
|
details: {
|
|
487
|
-
|
|
509
|
+
// jinn-mono-hjex.6: structured envelope so SPA can render the
|
|
510
|
+
// specific address + amount instead of a prose disjunction.
|
|
511
|
+
category: 'insufficient_funds',
|
|
512
|
+
step: 'awaiting_funding',
|
|
488
513
|
address: result.funding.master_address,
|
|
514
|
+
requiredWei: result.funding.eth_required,
|
|
515
|
+
haveWei: result.funding.eth_balance,
|
|
516
|
+
// Legacy aliases kept for any external consumers that read these.
|
|
517
|
+
role: 'master',
|
|
489
518
|
asset: 'native',
|
|
490
519
|
needWei: result.funding.eth_required,
|
|
491
|
-
haveWei: result.funding.eth_balance,
|
|
492
520
|
},
|
|
493
521
|
});
|
|
494
522
|
}
|
|
@@ -503,11 +531,17 @@ async function bootstrap() {
|
|
|
503
531
|
hint: 'Bootstrap failed before the fleet reached a runnable state.',
|
|
504
532
|
details: {
|
|
505
533
|
cause: result.message,
|
|
534
|
+
// jinn-mono-hjex.6: propagate structured category from the bootstrapper
|
|
535
|
+
// so the SPA can render category-specific UI (e.g. funding shortfall).
|
|
536
|
+
...(result.errorCategory !== undefined ? { category: result.errorCategory } : {}),
|
|
506
537
|
// Preserve the raw underlying error so a misclassified summary can
|
|
507
538
|
// be diagnosed without re-running with JINN_DEBUG. See jinn-mono-jz9f.
|
|
508
539
|
...(result.rawErrorMessage && result.rawErrorMessage !== result.message
|
|
509
540
|
? { rawErrorMessage: result.rawErrorMessage }
|
|
510
541
|
: {}),
|
|
542
|
+
// jinn-mono-hjex reviewer fix: propagate tx hash so the SPA can render
|
|
543
|
+
// a block-explorer link for failed on-chain revert transactions.
|
|
544
|
+
...(result.txHash != null ? { txHash: result.txHash } : {}),
|
|
511
545
|
},
|
|
512
546
|
});
|
|
513
547
|
}
|
|
@@ -592,7 +626,9 @@ class SetupBootstrapHalted extends Error {
|
|
|
592
626
|
this.name = 'SetupBootstrapHalted';
|
|
593
627
|
}
|
|
594
628
|
}
|
|
595
|
-
|
|
629
|
+
// hjex.6: gate for the halt-and-resume loop. Lives in ./setup/halt-mode.ts
|
|
630
|
+
// so it can be unit-tested without dragging main.ts's top-level side
|
|
631
|
+
// effects (password resolution, config load) into the test.
|
|
596
632
|
// ── Main ────────────────────────────────────────────────────────────────────
|
|
597
633
|
/**
|
|
598
634
|
* --json-progress: emit NDJSON progress envelopes on stdout during long
|
|
@@ -651,6 +687,15 @@ export async function main() {
|
|
|
651
687
|
else {
|
|
652
688
|
logRpcLocalDevToStderr(rpcPreflight);
|
|
653
689
|
}
|
|
690
|
+
// Boot-time RPC fallback-chain probe (issue #592, AC7 + AC9). Log-only —
|
|
691
|
+
// per-slot 429s/5xx never gate startup. checkRpcNetwork above already
|
|
692
|
+
// fail-loud on chain-id mismatch against the head provider.
|
|
693
|
+
await probeFallbackChain(config.rpcUrls, config.network, 'L2');
|
|
694
|
+
console.error(summarizeFallbackChain('L2', config.rpcUrls));
|
|
695
|
+
if (config.jinnClaimLoopEnabled && config.ethereumRpcUrls) {
|
|
696
|
+
await probeFallbackChain(config.ethereumRpcUrls, config.network, 'L1');
|
|
697
|
+
console.error(summarizeFallbackChain('L1', config.ethereumRpcUrls));
|
|
698
|
+
}
|
|
654
699
|
const portPreflight = await checkApiPortAvailable(config.apiPort);
|
|
655
700
|
if (!portPreflight.ok) {
|
|
656
701
|
emitEnvelope({
|
|
@@ -679,6 +724,7 @@ export async function main() {
|
|
|
679
724
|
// /v1/bootstrap + /v1/events + /v1/status here. The same Store instance is
|
|
680
725
|
// later passed into Daemon so we don't double-open the SQLite file.
|
|
681
726
|
const sharedStore = new Store(config.dbPath);
|
|
727
|
+
setDefaultTxSubmissionLedger(sharedStore);
|
|
682
728
|
const capturesStore = new CapturesStore(sharedStore);
|
|
683
729
|
let captureReceiver;
|
|
684
730
|
try {
|
|
@@ -703,11 +749,56 @@ export async function main() {
|
|
|
703
749
|
console.warn('[main] Capture OTLP receiver disabled; path-A telemetry capture unavailable: ' +
|
|
704
750
|
`${err instanceof Error ? err.message : String(err)}`);
|
|
705
751
|
}
|
|
752
|
+
let transcriptWatcher;
|
|
753
|
+
let pathBSyntheticSpanProvider;
|
|
754
|
+
const closePathBTranscriptWatcher = async () => {
|
|
755
|
+
const watcher = transcriptWatcher;
|
|
756
|
+
const provider = pathBSyntheticSpanProvider;
|
|
757
|
+
transcriptWatcher = undefined;
|
|
758
|
+
pathBSyntheticSpanProvider = undefined;
|
|
759
|
+
await Promise.all([
|
|
760
|
+
watcher?.shutdown().catch(() => undefined),
|
|
761
|
+
provider?.shutdown().catch(() => undefined),
|
|
762
|
+
]);
|
|
763
|
+
};
|
|
706
764
|
const closeCaptureReceiver = async () => {
|
|
765
|
+
await closePathBTranscriptWatcher();
|
|
707
766
|
const receiver = captureReceiver;
|
|
708
767
|
captureReceiver = undefined;
|
|
709
768
|
await receiver?.shutdown().catch(() => undefined);
|
|
710
769
|
};
|
|
770
|
+
if (captureReceiver) {
|
|
771
|
+
try {
|
|
772
|
+
const watchDirectories = defaultTranscriptWatchDirectories();
|
|
773
|
+
if (watchDirectories.length > 0) {
|
|
774
|
+
pathBSyntheticSpanProvider = startSyntheticSpanProvider({
|
|
775
|
+
otlpHttpEndpoint: `http://127.0.0.1:${captureReceiver.httpPort}/v1/traces`,
|
|
776
|
+
});
|
|
777
|
+
transcriptWatcher = await startTranscriptWatcher({
|
|
778
|
+
directories: watchDirectories,
|
|
779
|
+
onEvent: (envelope) => {
|
|
780
|
+
ensurePendingCapture(capturesStore, {
|
|
781
|
+
sessionId: envelope.sessionId,
|
|
782
|
+
capturedAt: new Date().toISOString(),
|
|
783
|
+
tool: envelope.tool,
|
|
784
|
+
capturePath: 'B',
|
|
785
|
+
});
|
|
786
|
+
emitSyntheticSpan(pathBSyntheticSpanProvider, envelope);
|
|
787
|
+
},
|
|
788
|
+
});
|
|
789
|
+
console.log('[main] Path-B transcript watcher started for ' +
|
|
790
|
+
watchDirectories.map((d) => `${d.tool}@${d.directory}`).join(', '));
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
console.log('[main] Path-B transcript watcher skipped — no Codex/Claude session directories on disk yet');
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
catch (err) {
|
|
797
|
+
await closePathBTranscriptWatcher();
|
|
798
|
+
console.warn('[main] Path-B transcript watcher disabled: ' +
|
|
799
|
+
`${err instanceof Error ? err.message : String(err)}`);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
711
802
|
const capturePublishRef = { current: undefined };
|
|
712
803
|
const earningStateStore = new FleetStateStore(config.earningDir);
|
|
713
804
|
const initialFleet = await earningStateStore.tryLoadExisting();
|
|
@@ -759,6 +850,13 @@ export async function main() {
|
|
|
759
850
|
// builder-artifacts. Holder ref lets the routes register eagerly and
|
|
760
851
|
// start returning real data the moment main.ts assigns holder.current.
|
|
761
852
|
const discoveryApiHolder = { current: undefined };
|
|
853
|
+
// hjex.6: retry signal for the bootstrap halt-and-resume loop.
|
|
854
|
+
// When a SetupBootstrapHalted is caught (fatal non-funding error or funding
|
|
855
|
+
// timeout), main() waits on this promise instead of returning, so the setup
|
|
856
|
+
// API stays alive and the operator can click Retry in the SPA.
|
|
857
|
+
// The retry endpoint resolves this promise to trigger a re-run.
|
|
858
|
+
let retryBootstrapResolve = null;
|
|
859
|
+
let retryBootstrapReject = null;
|
|
762
860
|
let setupApiServer;
|
|
763
861
|
try {
|
|
764
862
|
setupApiServer = await startApiServer({
|
|
@@ -772,11 +870,30 @@ export async function main() {
|
|
|
772
870
|
hermesPath: config.hermesPath,
|
|
773
871
|
hermesDoctorTimeoutMs: config.hermesDoctorTimeoutMs,
|
|
774
872
|
},
|
|
873
|
+
codexDoctor: {
|
|
874
|
+
codexPath: config.codexPath,
|
|
875
|
+
codexDoctorTimeoutMs: config.codexDoctorTimeoutMs,
|
|
876
|
+
},
|
|
775
877
|
admin: {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
878
|
+
// jinn-mono #289: in interactive mode (the dashboard SPA case),
|
|
879
|
+
// spawn a detached replacement before exiting so the panel reconnects
|
|
880
|
+
// to a live daemon instead of seeing a 502 + terminal prompt. In
|
|
881
|
+
// headless mode (`JINN_NO_UI=1`), exit without respawning so the
|
|
882
|
+
// supervisor / systemd / docker entrypoint decides what to do.
|
|
883
|
+
// Stop: pure exit, never respawn. The operator clicked Stop; they
|
|
884
|
+
// want the daemon down until they explicitly start it again.
|
|
885
|
+
onStopRequested: () => process.exit(0),
|
|
886
|
+
onRestartRequested: (opts) => requestDaemonRestart({
|
|
887
|
+
forceRespawn: opts.forceRespawn,
|
|
888
|
+
// jinn-mono #561: close the API + OTLP listeners before the
|
|
889
|
+
// replacement spawns, so the child binds without an
|
|
890
|
+
// EADDRINUSE race. Errors are swallowed inside
|
|
891
|
+
// requestDaemonRestart so the operator is never stranded.
|
|
892
|
+
preSpawnCleanup: async () => {
|
|
893
|
+
await setupApiServer.close().catch(() => undefined);
|
|
894
|
+
await closeCaptureReceiver();
|
|
895
|
+
},
|
|
896
|
+
}),
|
|
780
897
|
},
|
|
781
898
|
harnessStatus: {
|
|
782
899
|
getStatus: async () => {
|
|
@@ -830,7 +947,6 @@ export async function main() {
|
|
|
830
947
|
configReader: () => ({
|
|
831
948
|
rpcUrl: config.rpcUrl,
|
|
832
949
|
defaultRpcUrl: CHAIN_CONFIG.rpcUrl,
|
|
833
|
-
solverNets: config.solverNets,
|
|
834
950
|
joinedSolverNets: config.joinedSolverNets,
|
|
835
951
|
}),
|
|
836
952
|
},
|
|
@@ -953,19 +1069,42 @@ export async function main() {
|
|
|
953
1069
|
configPath: CONFIG_PATH ?? DEFAULT_CONFIG_PATH,
|
|
954
1070
|
defaultRpcUrlForChain: () => CHAIN_CONFIG.rpcUrl,
|
|
955
1071
|
onClaudePathSelected: selectClaudePath,
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1072
|
+
// Issue #421 retired the legacy `solverNets` write target. Setup
|
|
1073
|
+
// endpoints no longer call back into the daemon to mutate operator
|
|
1074
|
+
// SolverNet config; the canonical join flow is
|
|
1075
|
+
// `POST /v1/operator/join/:cid`, which mutates
|
|
1076
|
+
// `config.joinedSolverNets` directly via its own write path.
|
|
1077
|
+
// The cache-invalidation hook is no longer needed here.
|
|
1078
|
+
onSolverNetsUpdated: () => {
|
|
963
1079
|
invalidatePredictionOperatorStatusCache(config);
|
|
964
1080
|
},
|
|
1081
|
+
// hjex.6: re-trigger the bootstrap state machine from the SPA Retry button.
|
|
1082
|
+
// Resolves the halt-and-resume promise; main() will loop back and call
|
|
1083
|
+
// bootstrap() again. Rejects if the daemon is not currently halted.
|
|
1084
|
+
retryBootstrap: () => {
|
|
1085
|
+
return new Promise((resolve, reject) => {
|
|
1086
|
+
if (!retryBootstrapResolve) {
|
|
1087
|
+
reject(new Error('daemon_not_halted'));
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
const prevResolve = retryBootstrapResolve;
|
|
1091
|
+
// The resolve will unblock the main loop's await. When bootstrap
|
|
1092
|
+
// completes (success or new halt), the caller receives the result
|
|
1093
|
+
// via the /v1/bootstrap polling endpoint.
|
|
1094
|
+
prevResolve();
|
|
1095
|
+
resolve();
|
|
1096
|
+
});
|
|
1097
|
+
},
|
|
965
1098
|
},
|
|
966
1099
|
status: {
|
|
967
1100
|
earningDir: config.earningDir,
|
|
968
1101
|
rpcUrl: config.rpcUrl,
|
|
1102
|
+
// tJINN identity comes from the bundled JINN MVI L1 artifact
|
|
1103
|
+
// (`JINN_MVI_CONFIG`) — one source of truth. The Sepolia RPC endpoint
|
|
1104
|
+
// is read from `config.ethereumRpcUrl` via the threaded `config`.
|
|
1105
|
+
tjinnTokenAddress: JINN_MVI_CONFIG.jinn,
|
|
1106
|
+
tjinnChainId: JINN_MVI_CONFIG.l1ChainId,
|
|
1107
|
+
tjinnDistributorAddress: JINN_MVI_CONFIG.distributor,
|
|
969
1108
|
network: config.network,
|
|
970
1109
|
pollIntervalMs: config.pollIntervalMs,
|
|
971
1110
|
masterEthDailyEstimateWei: config.masterEthDailyEstimateWei,
|
|
@@ -1000,29 +1139,30 @@ export async function main() {
|
|
|
1000
1139
|
// TODO(jinn-mono launcher Task 8): real `getReservedBudgetWei`
|
|
1001
1140
|
// (sum of unconsumed claim payments across open Tasks).
|
|
1002
1141
|
launcher: {
|
|
1003
|
-
getConfig: () => ({
|
|
1142
|
+
getConfig: () => ({ joinedSolverNets: config.joinedSolverNets }),
|
|
1004
1143
|
configPath: CONFIG_PATH ?? DEFAULT_CONFIG_PATH,
|
|
1005
|
-
//
|
|
1006
|
-
//
|
|
1007
|
-
//
|
|
1008
|
-
|
|
1009
|
-
onSolverNetsUpdated: (solverNets) => {
|
|
1010
|
-
config.solverNets = solverNets;
|
|
1144
|
+
// Issue #421 retired the legacy `solverNets` write target. The hook
|
|
1145
|
+
// only needs to invalidate the prediction-operator status cache when
|
|
1146
|
+
// operator mode mutates joinedSolverNets via setup endpoints.
|
|
1147
|
+
onSolverNetsUpdated: () => {
|
|
1011
1148
|
invalidatePredictionOperatorStatusCache(config);
|
|
1012
1149
|
},
|
|
1013
1150
|
getGeneratorState: (netName) => {
|
|
1014
1151
|
if (netName === 'prediction') {
|
|
1015
1152
|
return predictionGeneratorRef?.getState();
|
|
1016
1153
|
}
|
|
1017
|
-
const
|
|
1154
|
+
const joined = findJoinedByName(config.joinedSolverNets, netName);
|
|
1155
|
+
const solverType = joined ? solverTypeFromJoinedContract(joined) : undefined;
|
|
1018
1156
|
if (!solverType)
|
|
1019
1157
|
return undefined;
|
|
1020
1158
|
return launchedGeneratorStateBySolverType.get(solverType)?.();
|
|
1021
1159
|
},
|
|
1022
1160
|
getOpenTaskCount: (netName) => {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1161
|
+
if (!safeAddressForLauncher)
|
|
1162
|
+
return 0;
|
|
1163
|
+
const joined = findJoinedByName(config.joinedSolverNets, netName);
|
|
1164
|
+
const solverType = joined ? solverTypeFromJoinedContract(joined) : undefined;
|
|
1165
|
+
if (!solverType)
|
|
1026
1166
|
return 0;
|
|
1027
1167
|
return sharedStore.countPostedTasksByCreatorAndSolverType({
|
|
1028
1168
|
creatorSafeAddress: safeAddressForLauncher,
|
|
@@ -1114,30 +1254,41 @@ export async function main() {
|
|
|
1114
1254
|
// can attach to a long-lived embedded `claude` subprocess. The embedded
|
|
1115
1255
|
// session reads MCP config we materialise to disk so it can reach the
|
|
1116
1256
|
// operator MCP server (`jinn mcp`) for tool calls.
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1257
|
+
//
|
|
1258
|
+
// Issue #326: the embedded agent chat surface is hidden by default. The WS
|
|
1259
|
+
// bridge mounts only when `JINN_ENABLE_EMBEDDED_AGENT=1` so the dev-time
|
|
1260
|
+
// path stays end-to-end; with the flag off there is no /api/agent/ws route
|
|
1261
|
+
// and the SPA never renders the chat panel. Claude-Code-as-solver-harness
|
|
1262
|
+
// is independent of this bridge and unaffected.
|
|
1263
|
+
if (embeddedAgentEnabled) {
|
|
1264
|
+
const operatorMcpConfigPath = join(homedir(), '.jinn-client', 'operator-mcp-config.json');
|
|
1265
|
+
try {
|
|
1266
|
+
mkdirSync(dirname(operatorMcpConfigPath), { recursive: true });
|
|
1267
|
+
writeFileSyncMain(operatorMcpConfigPath, JSON.stringify({
|
|
1268
|
+
mcpServers: {
|
|
1269
|
+
'jinn-operator': {
|
|
1270
|
+
command: 'jinn',
|
|
1271
|
+
args: ['mcp'],
|
|
1272
|
+
},
|
|
1125
1273
|
},
|
|
1126
|
-
},
|
|
1127
|
-
}
|
|
1274
|
+
}, null, 2));
|
|
1275
|
+
}
|
|
1276
|
+
catch (err) {
|
|
1277
|
+
console.warn(`[main] Failed to write operator MCP config at ${operatorMcpConfigPath}: ` +
|
|
1278
|
+
(err instanceof Error ? err.message : String(err)));
|
|
1279
|
+
}
|
|
1280
|
+
attachAgentWs({
|
|
1281
|
+
httpServer: setupApiServer.server,
|
|
1282
|
+
uiToken,
|
|
1283
|
+
claudePath: activeClaudePath,
|
|
1284
|
+
cwd: process.cwd(),
|
|
1285
|
+
mcpConfigPath: operatorMcpConfigPath,
|
|
1286
|
+
});
|
|
1287
|
+
console.log(`[main] Agent WS bridge mounted at ws://127.0.0.1:${setupApiServer.port}/api/agent/ws`);
|
|
1128
1288
|
}
|
|
1129
|
-
|
|
1130
|
-
console.
|
|
1131
|
-
(err instanceof Error ? err.message : String(err)));
|
|
1289
|
+
else {
|
|
1290
|
+
console.log('[main] Embedded agent surface disabled (set JINN_ENABLE_EMBEDDED_AGENT=1 to enable).');
|
|
1132
1291
|
}
|
|
1133
|
-
attachAgentWs({
|
|
1134
|
-
httpServer: setupApiServer.server,
|
|
1135
|
-
uiToken,
|
|
1136
|
-
claudePath: activeClaudePath,
|
|
1137
|
-
cwd: process.cwd(),
|
|
1138
|
-
mcpConfigPath: operatorMcpConfigPath,
|
|
1139
|
-
});
|
|
1140
|
-
console.log(`[main] Agent WS bridge mounted at ws://127.0.0.1:${setupApiServer.port}/api/agent/ws`);
|
|
1141
1292
|
// ── Init-if-missing ──────────────────────────────────────────────────────
|
|
1142
1293
|
// If the keystore is missing but we have a password, run `jinn init` now so
|
|
1143
1294
|
// bootstrap has something to decrypt. Idempotent: init is a no-op when the
|
|
@@ -1178,30 +1329,96 @@ export async function main() {
|
|
|
1178
1329
|
// keystore is on disk and we're transitioning into bootstrap.
|
|
1179
1330
|
setupController.refresh({ keystoreExists: true, allComplete: false });
|
|
1180
1331
|
}
|
|
1332
|
+
// hjex.6: halt-and-resume loop for bootstrap retries.
|
|
1333
|
+
// When failBootstrap() throws SetupBootstrapHalted, we wait for the operator
|
|
1334
|
+
// to click Retry in the SPA (which resolves retryBootstrapResolve) rather
|
|
1335
|
+
// than returning and exiting. On each retry, we loop back and call bootstrap()
|
|
1336
|
+
// again. bootstrap() is idempotent — completed steps are no-ops.
|
|
1181
1337
|
let bootstrapResult;
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1338
|
+
// eslint-disable-next-line no-constant-condition
|
|
1339
|
+
while (true) {
|
|
1340
|
+
try {
|
|
1341
|
+
bootstrapResult = await bootstrap();
|
|
1342
|
+
break; // success — exit the retry loop
|
|
1343
|
+
}
|
|
1344
|
+
catch (err) {
|
|
1345
|
+
if (err instanceof SetupBootstrapHalted) {
|
|
1346
|
+
// Install the retry signal so the endpoint can unblock us.
|
|
1347
|
+
const retrySignal = new Promise((resolve, reject) => {
|
|
1348
|
+
retryBootstrapResolve = resolve;
|
|
1349
|
+
retryBootstrapReject = reject;
|
|
1350
|
+
});
|
|
1351
|
+
console.log('[main] Bootstrap halted. Waiting for retry signal from the dashboard...');
|
|
1352
|
+
// hjex.6: Auto-resume funding poller.
|
|
1353
|
+
// When the halt is a funding shortfall, poll the master EOA balance
|
|
1354
|
+
// every JINN_FUNDING_POLL_INTERVAL_MS (default 15s). When the balance
|
|
1355
|
+
// meets or exceeds the required amount, auto-signal the retry loop.
|
|
1356
|
+
// Only runs while the halt signal is pending; stops on any signal.
|
|
1357
|
+
let fundingPollHandle = null;
|
|
1358
|
+
const isHaltedOnFunding = err.envelope.code === 'funding_required';
|
|
1359
|
+
const haltDetails = err.envelope.details;
|
|
1360
|
+
const haltAddress = typeof haltDetails?.['address'] === 'string'
|
|
1361
|
+
? haltDetails['address']
|
|
1362
|
+
: null;
|
|
1363
|
+
const haltRequired = typeof haltDetails?.['requiredWei'] === 'string'
|
|
1364
|
+
? BigInt(haltDetails['requiredWei'])
|
|
1365
|
+
: typeof haltDetails?.['needWei'] === 'string'
|
|
1366
|
+
? BigInt(haltDetails['needWei'])
|
|
1367
|
+
: null;
|
|
1368
|
+
const fundingPollIntervalMs = (() => {
|
|
1369
|
+
const raw = process.env['JINN_FUNDING_POLL_INTERVAL_MS'];
|
|
1370
|
+
if (!raw)
|
|
1371
|
+
return 15_000;
|
|
1372
|
+
const n = Number.parseInt(raw, 10);
|
|
1373
|
+
return Number.isFinite(n) && n > 0 ? n : 15_000;
|
|
1374
|
+
})();
|
|
1375
|
+
if (isHaltedOnFunding && haltAddress && haltRequired !== null) {
|
|
1376
|
+
const publicClient = createJinnPublicClient(config.rpcUrls, NETWORK_CHAIN);
|
|
1377
|
+
const schedulePoll = () => {
|
|
1378
|
+
fundingPollHandle = setTimeout(async () => {
|
|
1379
|
+
// Guard: if the signal was already fired, stop polling.
|
|
1380
|
+
if (!retryBootstrapResolve)
|
|
1381
|
+
return;
|
|
1382
|
+
try {
|
|
1383
|
+
const balance = await publicClient.getBalance({ address: haltAddress });
|
|
1384
|
+
if (balance >= haltRequired) {
|
|
1385
|
+
console.log(`[main] Funding shortfall cleared (have ${balance}, required ${haltRequired}). ` +
|
|
1386
|
+
`Auto-resuming bootstrap...`);
|
|
1387
|
+
retryBootstrapResolve?.();
|
|
1388
|
+
return; // don't schedule the next poll
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
catch (pollErr) {
|
|
1392
|
+
// Balance read failed — not fatal, just skip this tick.
|
|
1393
|
+
const msg = pollErr instanceof Error ? pollErr.message : String(pollErr);
|
|
1394
|
+
console.log(`[main] Funding poller balance read failed (will retry): ${msg}`);
|
|
1395
|
+
}
|
|
1396
|
+
schedulePoll(); // reschedule
|
|
1397
|
+
}, fundingPollIntervalMs);
|
|
1398
|
+
};
|
|
1399
|
+
schedulePoll();
|
|
1400
|
+
}
|
|
1401
|
+
try {
|
|
1402
|
+
await retrySignal;
|
|
1403
|
+
}
|
|
1404
|
+
finally {
|
|
1405
|
+
retryBootstrapResolve = null;
|
|
1406
|
+
retryBootstrapReject = null;
|
|
1407
|
+
if (fundingPollHandle !== null) {
|
|
1408
|
+
clearTimeout(fundingPollHandle);
|
|
1409
|
+
fundingPollHandle = null;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
console.log('[main] Retry triggered — re-running bootstrap...');
|
|
1413
|
+
continue; // loop back to the bootstrap() call
|
|
1414
|
+
}
|
|
1415
|
+
// If bootstrap throws an unexpected error (vs. SetupBootstrapHalted),
|
|
1416
|
+
// tear down the API we just started so we don't leave a dangling listener.
|
|
1417
|
+
await setupApiServer.close().catch(() => undefined);
|
|
1418
|
+
await closeCaptureReceiver();
|
|
1419
|
+
sharedStore.close();
|
|
1420
|
+
throw err;
|
|
1198
1421
|
}
|
|
1199
|
-
// If bootstrap throws (vs. emitEnvelope-exits), tear down the API we
|
|
1200
|
-
// just started so we don't leave a dangling listener on the port.
|
|
1201
|
-
await setupApiServer.close().catch(() => undefined);
|
|
1202
|
-
await closeCaptureReceiver();
|
|
1203
|
-
sharedStore.close();
|
|
1204
|
-
throw err;
|
|
1205
1422
|
}
|
|
1206
1423
|
// Bootstrap completed — flip the controller into 'running' so any waiters
|
|
1207
1424
|
// (future loops gated on this) unblock.
|
|
@@ -1254,9 +1471,9 @@ export async function main() {
|
|
|
1254
1471
|
const earningStore = new FleetStateStore(config.earningDir);
|
|
1255
1472
|
const mnemonicForMaster = await decryptMnemonic(await earningStore.loadMnemonicKeystore(), PASSWORD);
|
|
1256
1473
|
const masterAccount = deriveMasterSigner(mnemonicForMaster);
|
|
1257
|
-
const publicClient = createJinnPublicClient(config.
|
|
1474
|
+
const publicClient = createJinnPublicClient(config.rpcUrls, NETWORK_CHAIN);
|
|
1258
1475
|
publicClientForLauncher = publicClient;
|
|
1259
|
-
const masterWallet = createJinnWalletClient(config.
|
|
1476
|
+
const masterWallet = createJinnWalletClient(config.rpcUrls, NETWORK_CHAIN, masterAccount);
|
|
1260
1477
|
const evictionRecovery = config.stakingMode === 'standard' &&
|
|
1261
1478
|
serviceId !== null &&
|
|
1262
1479
|
stakingAddress &&
|
|
@@ -1315,7 +1532,7 @@ export async function main() {
|
|
|
1315
1532
|
// the /build page rendered "Discovery unavailable" permanently.
|
|
1316
1533
|
discoveryApiHolder.current = sharedDiscoveryApi;
|
|
1317
1534
|
const adapter = new MechAdapter({
|
|
1318
|
-
rpcUrl: config.
|
|
1535
|
+
rpcUrl: config.rpcUrls,
|
|
1319
1536
|
mechMarketplaceAddress: MARKETPLACE_ADDRESS,
|
|
1320
1537
|
routerAddress: ROUTER_ADDRESS,
|
|
1321
1538
|
mechContractAddress: mechAddress,
|
|
@@ -1331,12 +1548,18 @@ export async function main() {
|
|
|
1331
1548
|
? {
|
|
1332
1549
|
discoveryApi: sharedDiscoveryApi,
|
|
1333
1550
|
solverNetManifestCids: taskDiscoveryManifestCids,
|
|
1334
|
-
// No explicit `onchainFromBlock` — let `MechAdapter`'s
|
|
1551
|
+
// No explicit `onchainFromBlock` by default — let `MechAdapter`'s
|
|
1335
1552
|
// `DEFAULT_TASK_DISCOVERY_FROM_BLOCK` per-chain default flow
|
|
1336
1553
|
// through. Hardcoding here shadowed the adapter's default and
|
|
1337
1554
|
// re-introduced the ghost-task floor every release; removing the
|
|
1338
1555
|
// shadow makes `adapter.ts` the single source of truth. See gh
|
|
1339
|
-
// #300.
|
|
1556
|
+
// #300. An operator MAY opt in to a recent floor via
|
|
1557
|
+
// `taskDiscoveryOnchainFromBlock` to bound the canonical getLogs
|
|
1558
|
+
// scan (which otherwise parses a large history on the main thread
|
|
1559
|
+
// and can stall the loop) and lean on the indexer DiscoveryAPI.
|
|
1560
|
+
...(config.taskDiscoveryOnchainFromBlock !== undefined
|
|
1561
|
+
? { onchainFromBlock: config.taskDiscoveryOnchainFromBlock }
|
|
1562
|
+
: {}),
|
|
1340
1563
|
...(config.taskDiscoveryAllowedTaskIds?.length
|
|
1341
1564
|
? { allowedTaskIds: config.taskDiscoveryAllowedTaskIds }
|
|
1342
1565
|
: {}),
|
|
@@ -1353,26 +1576,52 @@ export async function main() {
|
|
|
1353
1576
|
const agentChainContracts = agentChain.contracts;
|
|
1354
1577
|
const optimismPortalAddress = agentChainContracts?.portal?.[l1Chain.id]?.address;
|
|
1355
1578
|
const disputeGameFactoryAddress = agentChainContracts?.disputeGameFactory?.[l1Chain.id]?.address;
|
|
1356
|
-
const l2ProofClient = config.
|
|
1357
|
-
? createJinnPublicClient(config.
|
|
1579
|
+
const l2ProofClient = config.l2ProofRpcUrls
|
|
1580
|
+
? createJinnPublicClient(config.l2ProofRpcUrls, NETWORK_CHAIN)
|
|
1358
1581
|
: undefined;
|
|
1359
|
-
const agentClients = createClients(config.
|
|
1582
|
+
const agentClients = createClients(config.rpcUrls, agentPrivateKey, agentChain);
|
|
1360
1583
|
// ── L1 (Sepolia / Ethereum mainnet) clients for cross-chain JINN claim loop ──
|
|
1361
1584
|
// Uses the agent EOA because MockMessenger.owner is the agent on testnet.
|
|
1362
1585
|
// Same key as L2; only the chain differs.
|
|
1363
|
-
const
|
|
1586
|
+
const shouldWireJinnClaimL1 = shouldWireJinnClaimL1Signer({
|
|
1587
|
+
enabled: config.jinnClaimLoopEnabled,
|
|
1588
|
+
intervalMs: config.jinnClaimLoopIntervalMs,
|
|
1589
|
+
submissionMode: config.jinnClaimSubmissionMode,
|
|
1590
|
+
distributorAddress: JINN_MVI_CONFIG.distributor,
|
|
1591
|
+
ethereumRpcUrl: config.ethereumRpcUrl,
|
|
1592
|
+
});
|
|
1593
|
+
const l1ClientsForJinnClaim = shouldWireJinnClaimL1 && config.ethereumRpcUrls
|
|
1364
1594
|
? {
|
|
1365
|
-
public: createJinnL1PublicClient(config.
|
|
1366
|
-
wallet: createJinnL1WalletClient(config.
|
|
1595
|
+
public: createJinnL1PublicClient(config.ethereumRpcUrls, config.jinnL1Network),
|
|
1596
|
+
wallet: createJinnL1WalletClient(config.ethereumRpcUrls, config.jinnL1Network, privateKeyToAccount(agentPrivateKey)),
|
|
1367
1597
|
}
|
|
1368
1598
|
: undefined;
|
|
1369
|
-
|
|
1370
|
-
|
|
1599
|
+
const jinnClaimLoopConfig = buildJinnClaimLoopConfig({
|
|
1600
|
+
enabled: config.jinnClaimLoopEnabled,
|
|
1601
|
+
intervalMs: config.jinnClaimLoopIntervalMs,
|
|
1602
|
+
submissionMode: config.jinnClaimSubmissionMode,
|
|
1603
|
+
messengerMode: JINN_CLAIM_MESSENGER_MODE,
|
|
1604
|
+
mvi: JINN_MVI_CONFIG,
|
|
1605
|
+
l2Client: agentClients.publicClient,
|
|
1606
|
+
l2ProofClient,
|
|
1607
|
+
l2Wallet: agentClients.walletClient,
|
|
1608
|
+
l1Clients: l1ClientsForJinnClaim,
|
|
1609
|
+
store: earningStore,
|
|
1610
|
+
chain: NETWORK_CHAIN,
|
|
1611
|
+
optimismPortalAddress,
|
|
1612
|
+
disputeGameFactoryAddress,
|
|
1613
|
+
});
|
|
1614
|
+
if (jinnClaimLoopConfig) {
|
|
1615
|
+
console.log(`[main] JinnClaimLoop: enabled (submission=${config.jinnClaimSubmissionMode}, ` +
|
|
1616
|
+
`mode=${JINN_CLAIM_MESSENGER_MODE}, ` +
|
|
1371
1617
|
`interval=${config.jinnClaimLoopIntervalMs}ms, distributor=${JINN_MVI_CONFIG.distributor}, ` +
|
|
1372
1618
|
`emitter=${JINN_MVI_CONFIG.claimEmitter})`);
|
|
1373
1619
|
}
|
|
1620
|
+
else if (!config.jinnClaimLoopEnabled) {
|
|
1621
|
+
console.log('[main] JinnClaimLoop: disabled (jinnClaimLoopEnabled=false)');
|
|
1622
|
+
}
|
|
1374
1623
|
else {
|
|
1375
|
-
console.log(`[main] JinnClaimLoop: disabled (
|
|
1624
|
+
console.log(`[main] JinnClaimLoop: disabled (missing claim-loop artifacts, interval disabled, or L1 submit wiring)`);
|
|
1376
1625
|
}
|
|
1377
1626
|
// ── Harness registry ─────────────────────────────────────────────────────────
|
|
1378
1627
|
const solverNetRegistry = await loadSolverNets(config);
|
|
@@ -1464,6 +1713,9 @@ export async function main() {
|
|
|
1464
1713
|
hermesPath: config.hermesPath,
|
|
1465
1714
|
hermesModel: config.hermesModel,
|
|
1466
1715
|
hermesProvider: config.hermesProvider,
|
|
1716
|
+
hermesDoctorTimeoutMs: config.hermesDoctorTimeoutMs,
|
|
1717
|
+
codexPath: config.codexPath,
|
|
1718
|
+
codexDoctorTimeoutMs: config.codexDoctorTimeoutMs,
|
|
1467
1719
|
})) {
|
|
1468
1720
|
implRegistry.register(impl);
|
|
1469
1721
|
}
|
|
@@ -1733,11 +1985,19 @@ export async function main() {
|
|
|
1733
1985
|
if (!safeAddressForLauncher) {
|
|
1734
1986
|
throw new Error('[main] safeAddressForLauncher missing at SolverNet endpoints registration');
|
|
1735
1987
|
}
|
|
1988
|
+
const getGeneratorState = (solverNetId) => {
|
|
1989
|
+
const entry = pendingGeneratorsRef.current.find((g) => g.recordRef.current.solverNetId === solverNetId);
|
|
1990
|
+
const resolved = resolveContractFromSolverNetId(entry?.recordRef.current.solverNetId ?? solverNetId);
|
|
1991
|
+
if (!resolved)
|
|
1992
|
+
return undefined;
|
|
1993
|
+
return launchedGeneratorStateBySolverType.get(resolved.solverType)?.();
|
|
1994
|
+
};
|
|
1736
1995
|
solverNetEndpointsDepsHolder.current = {
|
|
1737
1996
|
store: solverNetStore,
|
|
1738
1997
|
launch: {
|
|
1739
1998
|
launchAction,
|
|
1740
1999
|
lifecycleTransition,
|
|
2000
|
+
getGeneratorState,
|
|
1741
2001
|
pendingGenerators: pendingGeneratorsRef,
|
|
1742
2002
|
signer: launcherSigner,
|
|
1743
2003
|
network: 'base-sepolia',
|
|
@@ -1794,6 +2054,7 @@ export async function main() {
|
|
|
1794
2054
|
agentEoa: agentEoaAddress,
|
|
1795
2055
|
safeAddress,
|
|
1796
2056
|
agentPrivateKey,
|
|
2057
|
+
...(sharedDiscoveryApi ? { discoveryApi: sharedDiscoveryApi } : {}),
|
|
1797
2058
|
},
|
|
1798
2059
|
logger: {
|
|
1799
2060
|
info: (message) => console.log(message),
|
|
@@ -1812,9 +2073,23 @@ export async function main() {
|
|
|
1812
2073
|
if (config.network === 'mainnet' && !autoTasksDisabled && BASE_FEEDS['ETH / USD']) {
|
|
1813
2074
|
// Mainnet auto-task opt-in only; default is OFF. Reserved for a future flag.
|
|
1814
2075
|
}
|
|
2076
|
+
// filterBindableTasks (issue #415): drop config-level tasks[] entries without
|
|
2077
|
+
// solverNetManifestCid before they enter the creator loop. Such entries would
|
|
2078
|
+
// throw a PermanentError on every attempt and retry every 30 min indefinitely.
|
|
2079
|
+
const bindableConfigTasks = filterBindableTasks(config.tasks);
|
|
1815
2080
|
const taskSources = [
|
|
1816
|
-
new StaticConfiguredTaskSource(
|
|
1817
|
-
...launchedRecordGenerators.map(({ solverType, generator }, idx) => new GeneratedTaskSource(`launched:${solverType}:${idx}`, generator
|
|
2081
|
+
new StaticConfiguredTaskSource(bindableConfigTasks),
|
|
2082
|
+
...launchedRecordGenerators.map(({ solverType, generator }, idx) => new GeneratedTaskSource(`launched:${solverType}:${idx}`, generator, {
|
|
2083
|
+
bucketKeyForTask: (task) => {
|
|
2084
|
+
if (task.solverType !== 'swe-rebench-v2.v1')
|
|
2085
|
+
return undefined;
|
|
2086
|
+
const instanceId = task.spec?.['instance_id'];
|
|
2087
|
+
const postedCount = task.eligibility?.['posted_count_after_record'];
|
|
2088
|
+
if (typeof instanceId !== 'string' || typeof postedCount !== 'number')
|
|
2089
|
+
return undefined;
|
|
2090
|
+
return `swe-rebench-v2:${instanceId}:${postedCount}`;
|
|
2091
|
+
},
|
|
2092
|
+
})),
|
|
1818
2093
|
];
|
|
1819
2094
|
// ── Corpus (daemon-side, jinn-mono-vy37.1.6) ─────────────────────────────
|
|
1820
2095
|
//
|
|
@@ -1847,6 +2122,7 @@ export async function main() {
|
|
|
1847
2122
|
console.warn('[main] Corpus disabled (no DiscoveryAPI or on-chain identity registry); ' +
|
|
1848
2123
|
'MCP record lookup and artifact acquisition network branches will be unavailable.');
|
|
1849
2124
|
}
|
|
2125
|
+
const spendCap = buildSpendCapConfig(config, process.env);
|
|
1850
2126
|
const daemon = new Daemon({
|
|
1851
2127
|
adapter,
|
|
1852
2128
|
runner,
|
|
@@ -1863,9 +2139,21 @@ export async function main() {
|
|
|
1863
2139
|
creatorSafeAddress: safeAddress,
|
|
1864
2140
|
corpusFactory,
|
|
1865
2141
|
harnessReadinessRegistry,
|
|
2142
|
+
spendCap,
|
|
1866
2143
|
status: {
|
|
1867
2144
|
earningDir: config.earningDir,
|
|
1868
2145
|
rpcUrl: config.rpcUrl,
|
|
2146
|
+
// tJINN identity comes from the bundled JINN MVI L1 artifact
|
|
2147
|
+
// (`JINN_MVI_CONFIG`) — one source of truth. The Sepolia RPC endpoint
|
|
2148
|
+
// is read from `config.ethereumRpcUrl` via the threaded `config`.
|
|
2149
|
+
tjinnTokenAddress: JINN_MVI_CONFIG.jinn,
|
|
2150
|
+
tjinnChainId: JINN_MVI_CONFIG.l1ChainId,
|
|
2151
|
+
tjinnDistributorAddress: JINN_MVI_CONFIG.distributor,
|
|
2152
|
+
// stOLAS L2 distributor — mirrors `CHAIN_CONFIG.distributorAddress`
|
|
2153
|
+
// used to gate the EvictionLoop (issue #651). Threaded through so the
|
|
2154
|
+
// SPA's autoRestake predicate keys off the same on-chain artifact as
|
|
2155
|
+
// the daemon's `evictionCheck` predicate (~line 2520 below).
|
|
2156
|
+
stOlasDistributorAddress: CHAIN_CONFIG.distributorAddress,
|
|
1869
2157
|
network: config.network,
|
|
1870
2158
|
pollIntervalMs: config.pollIntervalMs,
|
|
1871
2159
|
masterEthDailyEstimateWei: config.masterEthDailyEstimateWei,
|
|
@@ -1877,6 +2165,7 @@ export async function main() {
|
|
|
1877
2165
|
engine: config.engine,
|
|
1878
2166
|
config,
|
|
1879
2167
|
configPath: CONFIG_PATH ?? DEFAULT_CONFIG_PATH,
|
|
2168
|
+
spendCaps: spendCap?.caps,
|
|
1880
2169
|
},
|
|
1881
2170
|
rewardClaim: config.rewardClaimIntervalMs > 0
|
|
1882
2171
|
? {
|
|
@@ -1888,28 +2177,7 @@ export async function main() {
|
|
|
1888
2177
|
distributorAddress: CHAIN_CONFIG.distributorAddress,
|
|
1889
2178
|
}
|
|
1890
2179
|
: undefined,
|
|
1891
|
-
jinnClaim:
|
|
1892
|
-
JINN_MVI_CONFIG.claimEmitter &&
|
|
1893
|
-
JINN_MVI_CONFIG.messenger &&
|
|
1894
|
-
JINN_MVI_CONFIG.distributor &&
|
|
1895
|
-
config.jinnClaimLoopIntervalMs > 0
|
|
1896
|
-
? {
|
|
1897
|
-
intervalMs: config.jinnClaimLoopIntervalMs,
|
|
1898
|
-
l2Client: agentClients.publicClient,
|
|
1899
|
-
l2ProofClient,
|
|
1900
|
-
l2Wallet: agentClients.walletClient,
|
|
1901
|
-
l1Client: l1ClientsForJinnClaim.public,
|
|
1902
|
-
l1Wallet: l1ClientsForJinnClaim.wallet,
|
|
1903
|
-
store: earningStore,
|
|
1904
|
-
chain: NETWORK_CHAIN,
|
|
1905
|
-
claimEmitterAddress: JINN_MVI_CONFIG.claimEmitter,
|
|
1906
|
-
distributorAddress: JINN_MVI_CONFIG.distributor,
|
|
1907
|
-
messengerAddress: JINN_MVI_CONFIG.messenger,
|
|
1908
|
-
messengerMode: JINN_CLAIM_MESSENGER_MODE,
|
|
1909
|
-
optimismPortalAddress,
|
|
1910
|
-
disputeGameFactoryAddress,
|
|
1911
|
-
}
|
|
1912
|
-
: undefined,
|
|
2180
|
+
jinnClaim: jinnClaimLoopConfig,
|
|
1913
2181
|
restorationEngine: {
|
|
1914
2182
|
paths: {
|
|
1915
2183
|
workingDirRoot: config.engine.workingDirRoot,
|
|
@@ -1954,11 +2222,71 @@ export async function main() {
|
|
|
1954
2222
|
safeTopupTarget: CHAIN_CONFIG.minSafeEth,
|
|
1955
2223
|
}
|
|
1956
2224
|
: undefined,
|
|
2225
|
+
// Eviction-check loop — only in standard staking mode (requires distributorAddress).
|
|
2226
|
+
// Running mode only: setup-halted daemons must not try to restake services that
|
|
2227
|
+
// haven't been staked yet (hjex.3).
|
|
2228
|
+
evictionCheck: config.evictionCheckIntervalMs > 0 &&
|
|
2229
|
+
config.stakingMode === 'standard' &&
|
|
2230
|
+
CHAIN_CONFIG.distributorAddress
|
|
2231
|
+
? {
|
|
2232
|
+
intervalMs: config.evictionCheckIntervalMs,
|
|
2233
|
+
store: earningStore,
|
|
2234
|
+
chain: NETWORK_CHAIN,
|
|
2235
|
+
readContract: (opts) => publicClient.readContract(opts),
|
|
2236
|
+
recoverEvictedService: async (svc) => {
|
|
2237
|
+
if (!svc.service_id || !svc.staking_address)
|
|
2238
|
+
return;
|
|
2239
|
+
await recoverEvictedServiceFn({
|
|
2240
|
+
serviceDisplayIndex: Math.max(0, svc.index - 1),
|
|
2241
|
+
serviceId: svc.service_id,
|
|
2242
|
+
stakingAddress: svc.staking_address,
|
|
2243
|
+
distributorAddress: CHAIN_CONFIG.distributorAddress,
|
|
2244
|
+
rpcUrl: config.rpcUrl,
|
|
2245
|
+
chain: NETWORK_CHAIN,
|
|
2246
|
+
mnemonic: mnemonicForMaster,
|
|
2247
|
+
});
|
|
2248
|
+
},
|
|
2249
|
+
}
|
|
2250
|
+
: undefined,
|
|
2251
|
+
// Checkpoint loop — proactively advances `tsCheckpoint` on each staked
|
|
2252
|
+
// proxy so the activity-rate window stays narrow (issue #505).
|
|
2253
|
+
// `checkpoint()` is permissionless; master EOA pays gas. No-op for
|
|
2254
|
+
// non-standard staking modes.
|
|
2255
|
+
checkpoint: config.checkpointIntervalMs > 0 && config.stakingMode === 'standard'
|
|
2256
|
+
? {
|
|
2257
|
+
intervalMs: config.checkpointIntervalMs,
|
|
2258
|
+
store: earningStore,
|
|
2259
|
+
chain: NETWORK_CHAIN,
|
|
2260
|
+
writeCheckpoint: async ({ stakingProxy }) => {
|
|
2261
|
+
const txHash = await masterWallet.writeContract({
|
|
2262
|
+
address: stakingProxy,
|
|
2263
|
+
abi: [
|
|
2264
|
+
{
|
|
2265
|
+
type: 'function',
|
|
2266
|
+
name: 'checkpoint',
|
|
2267
|
+
stateMutability: 'nonpayable',
|
|
2268
|
+
inputs: [],
|
|
2269
|
+
outputs: [],
|
|
2270
|
+
},
|
|
2271
|
+
],
|
|
2272
|
+
functionName: 'checkpoint',
|
|
2273
|
+
account: masterAccount,
|
|
2274
|
+
chain: null,
|
|
2275
|
+
});
|
|
2276
|
+
return { txHash };
|
|
2277
|
+
},
|
|
2278
|
+
}
|
|
2279
|
+
: undefined,
|
|
1957
2280
|
});
|
|
1958
|
-
// Write pidfile so `jinn stop` can find us.
|
|
2281
|
+
// Write pidfile so `jinn stop` can find us. First, refuse the run if another
|
|
2282
|
+
// daemon already owns this earning directory — see issue #649. The gate
|
|
2283
|
+
// handles all three branches (refuse-and-exit, unlink-stale-and-continue,
|
|
2284
|
+
// proceed); the writeFileSync below MUST stay outside the helper so the
|
|
2285
|
+
// "// DO NOT add store mutations above this line — see #649" invariant is
|
|
2286
|
+
// visible right here at the call site.
|
|
1959
2287
|
const pidPath = join(config.earningDir, 'daemon.pid');
|
|
1960
|
-
|
|
1961
|
-
|
|
2288
|
+
applyPidfileLivenessGate(pidPath);
|
|
2289
|
+
writeFileSyncMain(pidPath, String(process.pid) + '\n', 'utf-8');
|
|
1962
2290
|
const removePidfile = () => {
|
|
1963
2291
|
try {
|
|
1964
2292
|
unlinkSync(pidPath);
|