@jinn-network/client 0.1.6 → 0.1.7-canary.08ebd916
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 +38 -2
- package/dist/adapters/mech/adapter.js +269 -62
- package/dist/adapters/mech/adapter.js.map +1 -1
- package/dist/adapters/mech/contracts.d.ts +17 -4
- package/dist/adapters/mech/contracts.js +8 -2
- 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 +25 -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 +16 -0
- package/dist/api/setup-endpoints.js +89 -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 +99 -60
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +168 -2
- package/dist/api/status-build.js +116 -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 +10 -0
- package/dist/chain-read-errors.js +15 -0
- 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/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.js +101 -15
- 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/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 +273 -235
- package/dist/config.js +305 -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 +7 -3
- package/dist/daemon/creator.js.map +1 -1
- package/dist/daemon/daemon.d.ts +22 -0
- package/dist/daemon/daemon.js +156 -23
- 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-C4huIsUW.css +32 -0
- package/dist/dashboard/assets/index-DkTglWXU.js +345 -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 +216 -3
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.d.ts +5 -0
- package/dist/discovery/onchain.js +418 -15
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +75 -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 +20 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +100 -4
- package/dist/earning/bootstrap.js +221 -74
- 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 +145 -0
- package/dist/harnesses/cost-estimates.js +297 -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 +40 -6
- package/dist/harnesses/impls/hermes-agent/bootstrap.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 +38 -4
- package/dist/harnesses/impls/learner/harness.js +96 -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 +178 -93
- 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/main.js +419 -111
- package/dist/main.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 +94 -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 +113 -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/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/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-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 +94 -1
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +305 -39
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2-auto.d.ts +22 -7
- package/dist/solver-types/swe-rebench-v2-auto.js +57 -20
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +18 -2
- package/dist/solver-types/swe-rebench-v2.js +310 -94
- 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 +44 -7
- package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
- package/dist/solvernets/store.d.ts +5 -0
- package/dist/solvernets/store.js +1 -0
- package/dist/solvernets/store.js.map +1 -1
- 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/types.d.ts +8 -8
- 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/prediction-apy-v0.d.ts +5 -5
- package/dist/types/payloads/prediction-v0.d.ts +5 -5
- 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 +36 -13
- 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
|
@@ -4,11 +4,23 @@ import { privateKeyToAccount } from 'viem/accounts';
|
|
|
4
4
|
import { base, baseSepolia } from 'viem/chains';
|
|
5
5
|
import { PermanentError, parseTask } from '../../types/index.js';
|
|
6
6
|
import { createClients } from './safe.js';
|
|
7
|
+
/**
|
|
8
|
+
* Coalesce a string-or-array RPC input down to the head URL for display in
|
|
9
|
+
* error contexts (`formatRpcError` expects a single host). The adapter
|
|
10
|
+
* accepts the full fallback chain at the type level; this helper exists so
|
|
11
|
+
* the error-formatting call sites can keep their old signature.
|
|
12
|
+
*/
|
|
13
|
+
function rpcUrlForDisplay(rpcUrl) {
|
|
14
|
+
return Array.isArray(rpcUrl) ? rpcUrl[0] : rpcUrl;
|
|
15
|
+
}
|
|
7
16
|
import { buildResultPayload, uploadToIpfs, cidToDigestHex, fetchFromIpfs, fetchSignedTaskFromIpfs, fetchSignedEnvelopeFromIpfs, } from './ipfs.js';
|
|
8
17
|
import { canonicalJson } from '../../harnesses/engine/canonical-json.js';
|
|
9
|
-
import { SignedEnvelopeSchema } from '../../types/envelope.js';
|
|
18
|
+
import { normalizeEnvelopeRole, SignedEnvelopeSchema } from '../../types/envelope.js';
|
|
10
19
|
import { submitTask, claimTask as claimTaskOnchain, claimEvaluation as claimEvaluationOnchain, claimDelivery, getMechDeliveryRate, getTimeoutBounds, decodeTaskCreatedLogs, decodeSolutionDeliveryClaimedLogs, decodeDeliverLogs, findLatestDeliveryDataHexForRequest, getMarketplaceRequestDeliveryMech, getTaskCidDigest, callDeliverToMarketplace, canClaimTask, canClaimEvaluation, } from './contracts.js';
|
|
20
|
+
import { isNonRecoverableInnerRevert } from './safe-revert.js';
|
|
21
|
+
import { verdictCodeFromValue } from './verdict-code.js';
|
|
11
22
|
import { manifestDigestForCid } from './digest.js';
|
|
23
|
+
import { emitStructured } from '../../events/emitter.js';
|
|
12
24
|
import { withRecoverableRetry } from '../../tx-retry.js';
|
|
13
25
|
import { formatRpcError } from '../../rpc-error-context.js';
|
|
14
26
|
import { SOLUTION_ENVELOPE_CID_CONTEXT_KEY, SOLUTION_TASK_CID_CONTEXT_KEY, RESTORATION_TASK_CID_CONTEXT_KEY, } from '../../harnesses/impls/evaluation-context.js';
|
|
@@ -16,6 +28,28 @@ import { signTaskV1 } from '../../tasks/signing.js';
|
|
|
16
28
|
const ROUTER_REQUEST_CURSOR_CONFIG_KEY = 'mech_router_request_block_cursor_v1';
|
|
17
29
|
const PENDING_EVALUATION_SOLUTIONS_CONFIG_KEY = 'mech_pending_evaluation_solutions_v1';
|
|
18
30
|
const DEFAULT_MECH_DELIVER_BACKFILL_LOOKBACK_BLOCKS = 100000n;
|
|
31
|
+
/** Yield to the event loop every N evaluation opportunities so a large retry
|
|
32
|
+
* backlog can't starve the HTTP API mid-cycle. */
|
|
33
|
+
const EVALUATION_RETRY_YIELD_EVERY = 10;
|
|
34
|
+
/**
|
|
35
|
+
* Decide whether a `canClaimEvaluation` failure means the opportunity can NEVER
|
|
36
|
+
* become claimable (terminal, prune it) versus one that could still clear later
|
|
37
|
+
* (transient, keep retrying).
|
|
38
|
+
*
|
|
39
|
+
* Classification is done on the *structured* `revertName` decoded straight from
|
|
40
|
+
* the inner revert data — not by regex-unformatting the operator-facing `reason`
|
|
41
|
+
* string. The format→regex round-trip was fragile: an arg value containing a
|
|
42
|
+
* `(` corrupted the strip, and the `flattenErrorMessage` fallback produced
|
|
43
|
+
* arbitrary text the regex mangled, silently mis-classifying opportunities.
|
|
44
|
+
*
|
|
45
|
+
* A false-keep (re-checking a dead opportunity) only costs one more RPC; a
|
|
46
|
+
* false-prune (dropping a still-claimable opportunity) loses real work — so
|
|
47
|
+
* when in doubt we keep. Anything without a known non-recoverable revert name
|
|
48
|
+
* is treated as transient.
|
|
49
|
+
*/
|
|
50
|
+
function isTerminalEvaluationReason(revertName) {
|
|
51
|
+
return isNonRecoverableInnerRevert(revertName);
|
|
52
|
+
}
|
|
19
53
|
const DEFAULT_ROUTER_LOG_CHUNK_BLOCKS = 9999n;
|
|
20
54
|
/**
|
|
21
55
|
* Floor block for the on-chain TaskCreated backlog scan, per chain.
|
|
@@ -81,8 +115,18 @@ export class MechAdapter {
|
|
|
81
115
|
deliveryBlockCursor = 0n;
|
|
82
116
|
pendingEvaluations = new Map();
|
|
83
117
|
observedTasks = new Map();
|
|
118
|
+
/**
|
|
119
|
+
* Read-through cache for `restorationAnnouncementForTaskId` — the restoration
|
|
120
|
+
* task body looked up *while building an evaluation opportunity*. Kept
|
|
121
|
+
* SEPARATE from `observedTasks` (the `watchForTasks` discovery dedup set) on
|
|
122
|
+
* purpose: writing the restoration body into `observedTasks` made the
|
|
123
|
+
* TaskCreated scan skip that taskId as a *restoration* opportunity just
|
|
124
|
+
* because the daemon had built an *evaluation* opportunity for someone
|
|
125
|
+
* else's attempt on it. That blocked the creator's own daemon from claiming
|
|
126
|
+
* its own attempt on a multi-attempt (`maxClaims > 1`) task it posted.
|
|
127
|
+
*/
|
|
128
|
+
restorationBodyCache = new Map();
|
|
84
129
|
requestKinds = new Map();
|
|
85
|
-
claimedRestorationTaskIds = new Set();
|
|
86
130
|
evaluationOpportunities = new Map();
|
|
87
131
|
pendingEvaluationSolutions = new Map();
|
|
88
132
|
// Original Tasks keyed by request ID (restoration and evaluation)
|
|
@@ -104,7 +148,7 @@ export class MechAdapter {
|
|
|
104
148
|
formatRpcError(message, {
|
|
105
149
|
operation: 'getBlockNumber',
|
|
106
150
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
107
|
-
rpcUrl: this.config.rpcUrl,
|
|
151
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
108
152
|
}));
|
|
109
153
|
},
|
|
110
154
|
});
|
|
@@ -236,6 +280,35 @@ export class MechAdapter {
|
|
|
236
280
|
return;
|
|
237
281
|
this.persistPendingEvaluationSolutions();
|
|
238
282
|
}
|
|
283
|
+
clearPendingDeliveryRecoveryState(requestId) {
|
|
284
|
+
this.originalStates.delete(requestId);
|
|
285
|
+
this.pendingEvaluations.delete(requestId);
|
|
286
|
+
this.requestKinds.delete(requestId);
|
|
287
|
+
}
|
|
288
|
+
recoveryDeliveryExpirySeconds(requestId) {
|
|
289
|
+
const task = this.originalStates.get(requestId) ?? this.pendingEvaluations.get(requestId);
|
|
290
|
+
const claimPolicy = task?.claimPolicy ?? DEFAULT_MECH_CLAIM_POLICY;
|
|
291
|
+
const normalizeTsToSeconds = (value) => {
|
|
292
|
+
if (value == null)
|
|
293
|
+
return undefined;
|
|
294
|
+
return value > 10_000_000_000 ? Math.floor(value / 1000) : value;
|
|
295
|
+
};
|
|
296
|
+
const submissionDeadlineSeconds = normalizeTsToSeconds(claimPolicy.submissionDeadlineTs);
|
|
297
|
+
if (submissionDeadlineSeconds != null)
|
|
298
|
+
return submissionDeadlineSeconds;
|
|
299
|
+
const claimWindowEndSeconds = normalizeTsToSeconds(claimPolicy.claimWindowEndTs ?? task?.window?.endTs);
|
|
300
|
+
if (claimWindowEndSeconds == null)
|
|
301
|
+
return undefined;
|
|
302
|
+
return claimWindowEndSeconds + claimPolicy.claimLeaseTtlSeconds;
|
|
303
|
+
}
|
|
304
|
+
shouldSkipExpiredRecoveryDelivery(requestId, currentChainTimestampSeconds, recoveryExpirySeconds) {
|
|
305
|
+
if (currentChainTimestampSeconds <= recoveryExpirySeconds)
|
|
306
|
+
return false;
|
|
307
|
+
console.error(`[mech] skipping recovery delivery for ${requestId}: ` +
|
|
308
|
+
`submission deadline expired at ${new Date(recoveryExpirySeconds * 1000).toISOString()}`);
|
|
309
|
+
this.clearPendingDeliveryRecoveryState(requestId);
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
239
312
|
async postTask(state) {
|
|
240
313
|
const restorationState = {
|
|
241
314
|
...state,
|
|
@@ -264,18 +337,21 @@ export class MechAdapter {
|
|
|
264
337
|
const manifestDigest = keccak256(toBytes(signedTask.solverNetManifestCid));
|
|
265
338
|
const policy = this.contractPolicyForTask(restorationState);
|
|
266
339
|
const taskSubmission = await submitTask(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, restorationDataHex, manifestDigest, policy, deliveryRate, deliveryRate, maxTimeout, this.config.evictionRecovery);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
340
|
+
// Deliberately do NOT seed `observedTasks` with the task we just posted.
|
|
341
|
+
// `observedTasks` is the dedup set for `watchForTasks`: the on-chain
|
|
342
|
+
// TaskCreated scan skips any taskId already in it (so a task is announced
|
|
343
|
+
// to the engine-watcher at most once). Seeding it here marked the
|
|
344
|
+
// creator's own task as "already announced" before it was ever yielded —
|
|
345
|
+
// which permanently prevented the *creator's own daemon* from discovering,
|
|
346
|
+
// claiming, and solving a task it posted. On a multi-attempt task
|
|
347
|
+
// (`maxClaims > 1`) the creator running the solver role is legitimate
|
|
348
|
+
// (the protocol forbids only self-*evaluation*, and that on a per-attempt
|
|
349
|
+
// basis), and on testnet it is the intended single-operator dogfood path
|
|
350
|
+
// — post → claim → solve → grade → settle from one daemon. The dedup is
|
|
351
|
+
// still correct: it now keys only on tasks `watchForTasks` actually
|
|
352
|
+
// yielded. `restorationAnnouncementForTaskId` re-hydrates from chain/IPFS
|
|
353
|
+
// on a cache miss, so dropping the pre-seed costs at most one redundant
|
|
354
|
+
// fetch if the creator later claims its own task.
|
|
279
355
|
return {
|
|
280
356
|
taskId: taskSubmission.taskId,
|
|
281
357
|
taskCid: restorationTaskCid,
|
|
@@ -348,7 +424,14 @@ export class MechAdapter {
|
|
|
348
424
|
maxClaimsPerOperator: claimPolicy.maxClaimsPerOperator,
|
|
349
425
|
policyHook: (claimPolicy.policyHook ?? zeroAddress),
|
|
350
426
|
evaluationPolicy: {
|
|
351
|
-
requiredVerdicts
|
|
427
|
+
// `requiredVerdicts` defaults to 1 but is overridable via the task's
|
|
428
|
+
// claim policy. A value > 1 opens additional verdict claim slots per
|
|
429
|
+
// attempt; combined with the per-evaluator cap below (1), it
|
|
430
|
+
// guarantees an honest evaluator can still claim and deliver a slot
|
|
431
|
+
// even when other evaluators have squatted some — the structural fix
|
|
432
|
+
// for a shared/adversarial testnet where a non-delivering claimer
|
|
433
|
+
// would otherwise permanently lock a single-slot attempt.
|
|
434
|
+
requiredVerdicts: claimPolicy.requiredVerdicts ?? 1,
|
|
352
435
|
passThreshold: 1,
|
|
353
436
|
evaluationDeadline: submissionDeadline + BigInt(claimPolicy.claimLeaseTtlSeconds),
|
|
354
437
|
maxVerdictsPerEvaluator: 1,
|
|
@@ -381,7 +464,11 @@ export class MechAdapter {
|
|
|
381
464
|
};
|
|
382
465
|
}
|
|
383
466
|
async restorationAnnouncementForTaskId(taskId) {
|
|
384
|
-
|
|
467
|
+
// Read-through `restorationBodyCache` — NOT `observedTasks`. This helper is
|
|
468
|
+
// an evaluation-path lookup of a task's restoration body; caching it into
|
|
469
|
+
// the `watchForTasks` discovery dedup set would suppress the creator's own
|
|
470
|
+
// restoration-claim discovery for the same taskId (see field comment).
|
|
471
|
+
const cached = this.restorationBodyCache.get(taskId) ?? this.observedTasks.get(taskId);
|
|
385
472
|
if (cached)
|
|
386
473
|
return cached;
|
|
387
474
|
const taskCidDigest = await getTaskCidDigest(this.publicClient, this.config.routerAddress, taskId);
|
|
@@ -394,7 +481,7 @@ export class MechAdapter {
|
|
|
394
481
|
task,
|
|
395
482
|
taskCid,
|
|
396
483
|
};
|
|
397
|
-
this.
|
|
484
|
+
this.restorationBodyCache.set(taskId, announcement);
|
|
398
485
|
return announcement;
|
|
399
486
|
}
|
|
400
487
|
async restorationAnnouncementFromDigest(params) {
|
|
@@ -440,8 +527,6 @@ export class MechAdapter {
|
|
|
440
527
|
for (const candidate of candidates) {
|
|
441
528
|
if (!this.isDiscoveryTaskAllowed(candidate.taskId))
|
|
442
529
|
continue;
|
|
443
|
-
if (this.claimedRestorationTaskIds.has(candidate.taskId))
|
|
444
|
-
continue;
|
|
445
530
|
// gh #300 ghost-task floor — same floor as the on-chain TaskCreated
|
|
446
531
|
// backlog scan, applied to the DiscoveryAPI path too. Without this,
|
|
447
532
|
// the Ponder indexer (or onchain floor's listClaimableTasks) returns
|
|
@@ -465,19 +550,40 @@ export class MechAdapter {
|
|
|
465
550
|
continue;
|
|
466
551
|
}
|
|
467
552
|
try {
|
|
553
|
+
// Yield every hydrated candidate per cycle rather than returning after
|
|
554
|
+
// the first. The engine-watcher (daemon._runEngineWatcherLoop) is the
|
|
555
|
+
// single point of skip-state truth — when its in-flight admission gate
|
|
556
|
+
// fast-skips a candidate (~30s TTL), that skip state never flows back
|
|
557
|
+
// into the adapter's iteration cursor. Yielding only the first
|
|
558
|
+
// candidate per cycle meant a fast-skipped slot starved every
|
|
559
|
+
// subsequent candidate in the round-robin (`fc05f686`) ordering for
|
|
560
|
+
// the duration of the TTL. By driving the full candidate list per
|
|
561
|
+
// cycle we let the engine apply its gate to each one, preserving the
|
|
562
|
+
// round-robin fairness across joined SolverNets. See task 212 live
|
|
563
|
+
// verification in the fix's commit body.
|
|
468
564
|
yield await this.restorationAnnouncementFromDigest({
|
|
469
565
|
taskId: candidate.taskId,
|
|
470
566
|
taskCidDigest: candidate.taskCidDigest,
|
|
471
567
|
transactionHash: candidate.createdAtTx,
|
|
472
568
|
blockNumber: candidate.createdAtBlock,
|
|
473
569
|
});
|
|
474
|
-
return;
|
|
475
570
|
}
|
|
476
571
|
catch (err) {
|
|
477
572
|
console.error(`[mech] failed to hydrate subgraph task ${candidate.taskId}:`, err instanceof Error ? err.message : err);
|
|
478
573
|
}
|
|
479
574
|
}
|
|
480
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Look up the Deliver-event envelope CID for a pending evaluation solution.
|
|
578
|
+
*
|
|
579
|
+
* Returns `null` when the Deliver event is not present in the configured
|
|
580
|
+
* lookback window. This is a terminal signal for the caller — re-running the
|
|
581
|
+
* same lookup later is deterministically futile when `solution.blockNumber`
|
|
582
|
+
* is set (toBlock is fixed at the SolutionDeliveryClaimed block), and is
|
|
583
|
+
* monotonically less likely to find the event when toBlock follows chain head
|
|
584
|
+
* (the window slides forward, away from any older Deliver event). Callers
|
|
585
|
+
* should prune the pending solution on `null` rather than retry — see #553.
|
|
586
|
+
*/
|
|
481
587
|
async deliveryEnvelopeCidForSolution(solution) {
|
|
482
588
|
const deliveryMech = await getMarketplaceRequestDeliveryMech(this.publicClient, this.config.mechMarketplaceAddress, solution.requestId);
|
|
483
589
|
const toBlock = solution.blockNumber != null
|
|
@@ -488,8 +594,7 @@ export class MechAdapter {
|
|
|
488
594
|
const fromBlock = toBlock > lookback ? toBlock - lookback : 0n;
|
|
489
595
|
const deliveryDataHex = await findLatestDeliveryDataHexForRequest(this.publicClient, deliveryMech, solution.requestId, fromBlock, toBlock);
|
|
490
596
|
if (!deliveryDataHex) {
|
|
491
|
-
|
|
492
|
-
`between blocks ${fromBlock} and ${toBlock}`);
|
|
597
|
+
return null;
|
|
493
598
|
}
|
|
494
599
|
const digest = deliveryDataHex.startsWith('0x') ? deliveryDataHex.slice(2) : deliveryDataHex;
|
|
495
600
|
return `f01551220${digest}`;
|
|
@@ -500,14 +605,34 @@ export class MechAdapter {
|
|
|
500
605
|
this.forgetPendingEvaluationSolution(solution.requestId);
|
|
501
606
|
return undefined;
|
|
502
607
|
}
|
|
503
|
-
|
|
608
|
+
// Cheap claimability gate FIRST — before the restoration lookup + IPFS
|
|
609
|
+
// fetch. A backlog of terminal opportunities (finalized / evaluation
|
|
610
|
+
// deadline passed / max verdicts reached) must not pay the expensive
|
|
611
|
+
// restoration-announcement cost on every poll cycle. Terminal reasons are
|
|
612
|
+
// pruned from the working set so the loop never re-scans on-chain history;
|
|
613
|
+
// transient reasons are left in place to be retried next cycle.
|
|
504
614
|
const claimable = await canClaimEvaluation(this.publicClient, this.config.safeAddress, this.config.routerAddress, solution.taskId, solution.attemptIndex, this.config.mechContractAddress);
|
|
505
615
|
if (!claimable.ok) {
|
|
506
|
-
|
|
507
|
-
|
|
616
|
+
const terminal = isTerminalEvaluationReason(claimable.revertName);
|
|
617
|
+
console.log(`[mech] skipping evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ${claimable.reason}` +
|
|
618
|
+
(terminal ? ' (terminal — pruned)' : ' (transient — will retry)'));
|
|
619
|
+
if (terminal) {
|
|
620
|
+
this.forgetPendingEvaluationSolution(solution.requestId);
|
|
621
|
+
}
|
|
508
622
|
return undefined;
|
|
509
623
|
}
|
|
624
|
+
const restoration = await this.restorationAnnouncementForTaskId(solution.taskId);
|
|
510
625
|
const solutionEnvelopeCid = await this.deliveryEnvelopeCidForSolution(solution);
|
|
626
|
+
if (solutionEnvelopeCid == null) {
|
|
627
|
+
// #553: Deliver event is not within the configured lookback window. A
|
|
628
|
+
// retry with the same toBlock cannot reach an older event, so this is
|
|
629
|
+
// terminal — prune so the loop never re-pays the canClaimEvaluation +
|
|
630
|
+
// restoration lookup cost on a deterministically-failing opportunity.
|
|
631
|
+
console.log(`[mech] pruning evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ` +
|
|
632
|
+
`no Deliver event found within configured lookback (terminal — pruned)`);
|
|
633
|
+
this.forgetPendingEvaluationSolution(solution.requestId);
|
|
634
|
+
return undefined;
|
|
635
|
+
}
|
|
511
636
|
const resultPayload = await fetchFromIpfs(this.config.ipfsGatewayUrl, solutionEnvelopeCid);
|
|
512
637
|
const resultData = resultPayload.data ?? JSON.stringify(resultPayload);
|
|
513
638
|
const evaluationTask = this.buildEvaluationTask({
|
|
@@ -535,15 +660,21 @@ export class MechAdapter {
|
|
|
535
660
|
return announcement;
|
|
536
661
|
}
|
|
537
662
|
async *retryPendingEvaluationSolutions() {
|
|
663
|
+
let processed = 0;
|
|
538
664
|
for (const [requestId, solution] of Array.from(this.pendingEvaluationSolutions)) {
|
|
665
|
+
// Yield to the event loop periodically so a large backlog of pending
|
|
666
|
+
// evaluation solutions can't starve the HTTP API mid-cycle.
|
|
667
|
+
if (processed > 0 && processed % EVALUATION_RETRY_YIELD_EVERY === 0) {
|
|
668
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
669
|
+
}
|
|
670
|
+
processed++;
|
|
539
671
|
try {
|
|
540
672
|
const announcement = await this.evaluationAnnouncementForSolution(solution);
|
|
541
673
|
if (announcement) {
|
|
542
674
|
yield announcement;
|
|
543
675
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
676
|
+
// No announcement does NOT mean "forget" — pruning is owned by
|
|
677
|
+
// evaluationAnnouncementForSolution, which only removes terminal cases.
|
|
547
678
|
}
|
|
548
679
|
catch (err) {
|
|
549
680
|
console.error(`[mech] evaluation opportunity retry failed for ${requestId}:`, err);
|
|
@@ -576,7 +707,7 @@ export class MechAdapter {
|
|
|
576
707
|
for (const { taskId, taskCidDigest, manifestDigest, transactionHash, blockNumber } of createdTasks) {
|
|
577
708
|
if (!this.isDiscoveryTaskAllowed(taskId))
|
|
578
709
|
continue;
|
|
579
|
-
if (this.
|
|
710
|
+
if (this.observedTasks.has(taskId))
|
|
580
711
|
continue;
|
|
581
712
|
if (joinedManifestDigests.size > 0 && !joinedManifestDigests.has(manifestDigest.toLowerCase()))
|
|
582
713
|
continue;
|
|
@@ -605,7 +736,7 @@ export class MechAdapter {
|
|
|
605
736
|
console.error('[mech] Error polling for tasks:', formatRpcError(err, {
|
|
606
737
|
operation: 'pollTaskCreated',
|
|
607
738
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
608
|
-
rpcUrl: this.config.rpcUrl,
|
|
739
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
609
740
|
contract: this.config.routerAddress,
|
|
610
741
|
fromBlock: this.requestBlockCursor + 1n,
|
|
611
742
|
}));
|
|
@@ -644,7 +775,6 @@ export class MechAdapter {
|
|
|
644
775
|
}
|
|
645
776
|
const claimed = await claimTaskOnchain(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, taskId, this.config.mechContractAddress, this.config.evictionRecovery);
|
|
646
777
|
const task = announcement.task;
|
|
647
|
-
this.claimedRestorationTaskIds.add(claimed.taskId);
|
|
648
778
|
this.pendingEvaluations.set(claimed.requestId, task);
|
|
649
779
|
this.originalStates.set(claimed.requestId, { ...task, role: task.role ?? 'restoration' });
|
|
650
780
|
this.requestKinds.set(claimed.requestId, 'solution');
|
|
@@ -676,9 +806,13 @@ export class MechAdapter {
|
|
|
676
806
|
async submitVerdictDelivery(requestId, verdictDigest, verdictCode) {
|
|
677
807
|
await claimDelivery(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, requestId, { variant: 'v3', kind: 'verdict', evidenceHash: verdictDigest, verdictCode }, this.config.evictionRecovery);
|
|
678
808
|
}
|
|
679
|
-
async
|
|
809
|
+
async deliveryClaimForDelivery(requestId, deliveryDataHex) {
|
|
810
|
+
const fallbackKind = this.requestKinds.get(requestId) ?? 'solution';
|
|
680
811
|
if (this.config.routerClaimDeliveryVariant !== 'v2' && this.config.routerClaimDeliveryVariant !== 'v3') {
|
|
681
|
-
return
|
|
812
|
+
return {
|
|
813
|
+
evidenceHash: undefined,
|
|
814
|
+
kind: fallbackKind,
|
|
815
|
+
};
|
|
682
816
|
}
|
|
683
817
|
const deliveryDigest = deliveryDataHex.startsWith('0x')
|
|
684
818
|
? deliveryDataHex.slice(2)
|
|
@@ -686,11 +820,6 @@ export class MechAdapter {
|
|
|
686
820
|
const envelopeCid = `f01551220${deliveryDigest}`;
|
|
687
821
|
const rawEnvelope = await fetchSignedEnvelopeFromIpfs(this.config.ipfsGatewayUrl, envelopeCid);
|
|
688
822
|
const parsed = SignedEnvelopeSchema.parse(rawEnvelope);
|
|
689
|
-
// Strip signature to recompute the hash over the unsigned body.
|
|
690
|
-
//
|
|
691
|
-
// Important: compute over the fetched wire object, not over the parsed
|
|
692
|
-
// schema result. The schema normalizes some nested objects and may strip
|
|
693
|
-
// extension metadata that was present when the envelope was signed.
|
|
694
823
|
const rawSigned = rawEnvelope;
|
|
695
824
|
const { signature: _rawSignature, ...unsignedBody } = rawSigned;
|
|
696
825
|
const signature = parsed.signature;
|
|
@@ -699,22 +828,36 @@ export class MechAdapter {
|
|
|
699
828
|
if (recomputed !== signature.hash) {
|
|
700
829
|
throw new Error(`recomputed hash ${recomputed} !== envelope.signature.hash ${signature.hash}`);
|
|
701
830
|
}
|
|
702
|
-
|
|
831
|
+
const role = normalizeEnvelopeRole(parsed.role);
|
|
832
|
+
if (role === 'capture') {
|
|
833
|
+
throw new Error(`unsupported delivery envelope role=capture for requestId ${requestId}`);
|
|
834
|
+
}
|
|
835
|
+
const kind = role === 'verdict' ? 'verdict' : 'solution';
|
|
836
|
+
const payload = rawSigned['payload'];
|
|
837
|
+
const rawVerdict = payload != null && typeof payload === 'object'
|
|
838
|
+
? payload['verdict']
|
|
839
|
+
: undefined;
|
|
840
|
+
return {
|
|
841
|
+
evidenceHash: recomputed,
|
|
842
|
+
kind,
|
|
843
|
+
verdictCode: kind === 'verdict' ? verdictCodeFromValue(rawVerdict) : undefined,
|
|
844
|
+
};
|
|
703
845
|
}
|
|
704
846
|
async ensureDeliveryClaimed(requestId, deliveryDataHex) {
|
|
705
|
-
let
|
|
847
|
+
let claimOptions;
|
|
706
848
|
try {
|
|
707
|
-
|
|
849
|
+
claimOptions = await this.deliveryClaimForDelivery(requestId, deliveryDataHex);
|
|
708
850
|
}
|
|
709
851
|
catch (err) {
|
|
710
|
-
console.error(`[mech]
|
|
852
|
+
console.error(`[mech] delivery claim metadata derivation failed for ${requestId} — skipping claim, will retry on next loop:`, err);
|
|
711
853
|
return 'retry';
|
|
712
854
|
}
|
|
713
855
|
try {
|
|
714
856
|
await claimDelivery(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, requestId, {
|
|
715
857
|
variant: this.config.routerClaimDeliveryVariant,
|
|
716
|
-
kind:
|
|
717
|
-
evidenceHash,
|
|
858
|
+
kind: claimOptions.kind,
|
|
859
|
+
evidenceHash: claimOptions.evidenceHash,
|
|
860
|
+
verdictCode: claimOptions.verdictCode,
|
|
718
861
|
}, this.config.evictionRecovery);
|
|
719
862
|
return 'claimed';
|
|
720
863
|
}
|
|
@@ -728,22 +871,66 @@ export class MechAdapter {
|
|
|
728
871
|
return 'already-claimed';
|
|
729
872
|
}
|
|
730
873
|
console.error(`[mech] claimDelivery failed for ${requestId}:`, err);
|
|
874
|
+
// Paired SSE signal for the operator-app `claim_failed` notification
|
|
875
|
+
// (OPERATOR-APP-SPEC §2.10). The early-return branches above
|
|
876
|
+
// (`skipped` / `already-claimed`) are not failures and intentionally do not emit.
|
|
877
|
+
emitStructured({
|
|
878
|
+
kind: 'intent',
|
|
879
|
+
message: 'Delivery claim failed',
|
|
880
|
+
requestId,
|
|
881
|
+
errorCode: 'claim_failed',
|
|
882
|
+
details: {
|
|
883
|
+
kind: claimOptions.kind,
|
|
884
|
+
source: 'mech.claimDelivery',
|
|
885
|
+
error: message,
|
|
886
|
+
},
|
|
887
|
+
});
|
|
731
888
|
return 'retry';
|
|
732
889
|
}
|
|
733
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Paginate `getLogs` over `[deliveryBlockCursor+1, currentBlock]` chunked by
|
|
893
|
+
* `DEFAULT_ROUTER_LOG_CHUNK_BLOCKS` to honor RPC provider block-range limits
|
|
894
|
+
* (Tenderly base-sepolia caps at 100k; sepolia.base.org ~1k). Advances +
|
|
895
|
+
* persists `deliveryBlockCursor` per chunk so a mid-scan RPC failure on a
|
|
896
|
+
* later chunk does not strand the cursor at the pre-poll value (#552).
|
|
897
|
+
*
|
|
898
|
+
* Yields each chunk's decoded Deliver entries so the consumer can process
|
|
899
|
+
* them with the live "current block" context (needed for the recovery-
|
|
900
|
+
* delivery timestamp cache).
|
|
901
|
+
*/
|
|
902
|
+
async *scanDeliveryLogChunks(currentBlock) {
|
|
903
|
+
while (currentBlock > this.deliveryBlockCursor) {
|
|
904
|
+
const chunkStart = this.deliveryBlockCursor + 1n;
|
|
905
|
+
const chunkEnd = chunkStart + DEFAULT_ROUTER_LOG_CHUNK_BLOCKS > currentBlock
|
|
906
|
+
? currentBlock
|
|
907
|
+
: chunkStart + DEFAULT_ROUTER_LOG_CHUNK_BLOCKS;
|
|
908
|
+
const logs = await this.publicClient.getLogs({
|
|
909
|
+
address: this.config.mechContractAddress,
|
|
910
|
+
fromBlock: chunkStart,
|
|
911
|
+
toBlock: chunkEnd,
|
|
912
|
+
});
|
|
913
|
+
// Advance + persist BEFORE yielding so partial progress is durable even
|
|
914
|
+
// if a downstream throw escapes back through the for-await consumer.
|
|
915
|
+
this.deliveryBlockCursor = chunkEnd;
|
|
916
|
+
if (this.store) {
|
|
917
|
+
this.store.setLastProcessedBlock(this.deliveryBlockCursor);
|
|
918
|
+
}
|
|
919
|
+
yield decodeDeliverLogs(logs);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
734
922
|
async *watchForDeliveries() {
|
|
735
923
|
while (!this.stopped) {
|
|
736
924
|
try {
|
|
737
925
|
const currentBlock = await this.publicClient.getBlockNumber();
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const
|
|
746
|
-
for (const { requestId, deliveryDataHex, mechAddress } of decoded) {
|
|
926
|
+
// Caches scoped to the whole poll iteration: the "current block"
|
|
927
|
+
// reference does not change across chunks.
|
|
928
|
+
const blockTimestampSecondsByNumber = new Map();
|
|
929
|
+
let currentBlockTimestampSeconds;
|
|
930
|
+
for await (const decoded of this.scanDeliveryLogChunks(currentBlock)) {
|
|
931
|
+
if (this.stopped)
|
|
932
|
+
break;
|
|
933
|
+
for (const { requestId, deliveryDataHex, mechAddress, blockNumber } of decoded) {
|
|
747
934
|
// Two concerns, independent:
|
|
748
935
|
// (a) Did this Safe DELIVER this? → claim it (counter credit goes to msg.sender)
|
|
749
936
|
// The Deliver event's mechAddress is mechServiceMultisig (the Safe that owns
|
|
@@ -753,6 +940,30 @@ export class MechAdapter {
|
|
|
753
940
|
const iCreatedRestoration = this.pendingEvaluations.has(requestId);
|
|
754
941
|
if (!iDelivered && !iCreatedRestoration)
|
|
755
942
|
continue;
|
|
943
|
+
if (iCreatedRestoration) {
|
|
944
|
+
const recoveryExpirySeconds = this.recoveryDeliveryExpirySeconds(requestId);
|
|
945
|
+
if (recoveryExpirySeconds != null) {
|
|
946
|
+
let deliveryTimestampSeconds;
|
|
947
|
+
if (blockNumber != null) {
|
|
948
|
+
deliveryTimestampSeconds = blockTimestampSecondsByNumber.get(blockNumber);
|
|
949
|
+
if (deliveryTimestampSeconds == null) {
|
|
950
|
+
const deliveryBlockData = await this.publicClient.getBlock({ blockNumber });
|
|
951
|
+
deliveryTimestampSeconds = Number(deliveryBlockData.timestamp);
|
|
952
|
+
blockTimestampSecondsByNumber.set(blockNumber, deliveryTimestampSeconds);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
if (currentBlockTimestampSeconds == null) {
|
|
957
|
+
const currentBlockData = await this.publicClient.getBlock({ blockNumber: currentBlock });
|
|
958
|
+
currentBlockTimestampSeconds = Number(currentBlockData.timestamp);
|
|
959
|
+
}
|
|
960
|
+
deliveryTimestampSeconds = currentBlockTimestampSeconds;
|
|
961
|
+
}
|
|
962
|
+
if (this.shouldSkipExpiredRecoveryDelivery(requestId, deliveryTimestampSeconds, recoveryExpirySeconds)) {
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
}
|
|
756
967
|
// (a) Deliverer-side claim path: if this Safe delivered the request,
|
|
757
968
|
// claim it first so router counters credit the deliverer.
|
|
758
969
|
let deliveryClaimStatus;
|
|
@@ -788,9 +999,7 @@ export class MechAdapter {
|
|
|
788
999
|
deliveryMechAddress: mechAddress,
|
|
789
1000
|
};
|
|
790
1001
|
// Clean up after yielding
|
|
791
|
-
this.
|
|
792
|
-
this.pendingEvaluations.delete(requestId);
|
|
793
|
-
this.requestKinds.delete(requestId);
|
|
1002
|
+
this.clearPendingDeliveryRecoveryState(requestId);
|
|
794
1003
|
}
|
|
795
1004
|
catch (err) {
|
|
796
1005
|
console.error(`[mech] Failed to parse delivery ${requestId}:`, err);
|
|
@@ -802,15 +1011,13 @@ export class MechAdapter {
|
|
|
802
1011
|
console.error('[mech] Error polling for deliveries:', formatRpcError(err, {
|
|
803
1012
|
operation: 'pollDeliveries',
|
|
804
1013
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
805
|
-
rpcUrl: this.config.rpcUrl,
|
|
1014
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
806
1015
|
contract: this.config.mechContractAddress,
|
|
807
1016
|
fromBlock: this.deliveryBlockCursor + 1n,
|
|
808
1017
|
}));
|
|
809
1018
|
}
|
|
810
|
-
//
|
|
811
|
-
|
|
812
|
-
this.store.setLastProcessedBlock(this.deliveryBlockCursor);
|
|
813
|
-
}
|
|
1019
|
+
// Cursor persistence is per-chunk inside the loop above (#552). A poll
|
|
1020
|
+
// that did no chunked work has no progress to persist.
|
|
814
1021
|
await new Promise(r => setTimeout(r, this.config.pollIntervalMs));
|
|
815
1022
|
}
|
|
816
1023
|
}
|