@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
|
@@ -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 { SafeInnerRevertError, formatDecodedRevert, 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,41 @@ 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
|
+
* Bound the number of consecutive transient/uncaught failures for a single
|
|
36
|
+
* pending evaluation solution. Once exceeded, the solution is pruned from
|
|
37
|
+
* `pendingEvaluationSolutions` to stop unbounded log spam (#645). At default
|
|
38
|
+
* pollIntervalMs=5000, twenty cycles ≈ 100 s — comfortably above a normal
|
|
39
|
+
* transient RPC outage window, well below "spamming the log forever".
|
|
40
|
+
*
|
|
41
|
+
* The signal-driven prunes (terminal claimability, `null` delivery-envelope
|
|
42
|
+
* CID per #553, !isDiscoveryTaskAllowed) still fire on their own conditions;
|
|
43
|
+
* this counter is the backstop for failure modes that don't surface a clean
|
|
44
|
+
* terminal signal.
|
|
45
|
+
*/
|
|
46
|
+
const MAX_EVALUATION_RETRY_ATTEMPTS = 20;
|
|
47
|
+
/**
|
|
48
|
+
* Decide whether a `canClaimEvaluation` failure means the opportunity can NEVER
|
|
49
|
+
* become claimable (terminal, prune it) versus one that could still clear later
|
|
50
|
+
* (transient, keep retrying).
|
|
51
|
+
*
|
|
52
|
+
* Classification is done on the *structured* `revertName` decoded straight from
|
|
53
|
+
* the inner revert data — not by regex-unformatting the operator-facing `reason`
|
|
54
|
+
* string. The format→regex round-trip was fragile: an arg value containing a
|
|
55
|
+
* `(` corrupted the strip, and the `flattenErrorMessage` fallback produced
|
|
56
|
+
* arbitrary text the regex mangled, silently mis-classifying opportunities.
|
|
57
|
+
*
|
|
58
|
+
* A false-keep (re-checking a dead opportunity) only costs one more RPC; a
|
|
59
|
+
* false-prune (dropping a still-claimable opportunity) loses real work — so
|
|
60
|
+
* when in doubt we keep. Anything without a known non-recoverable revert name
|
|
61
|
+
* is treated as transient.
|
|
62
|
+
*/
|
|
63
|
+
function isTerminalEvaluationReason(revertName) {
|
|
64
|
+
return isNonRecoverableInnerRevert(revertName);
|
|
65
|
+
}
|
|
19
66
|
const DEFAULT_ROUTER_LOG_CHUNK_BLOCKS = 9999n;
|
|
20
67
|
/**
|
|
21
68
|
* Floor block for the on-chain TaskCreated backlog scan, per chain.
|
|
@@ -81,8 +128,18 @@ export class MechAdapter {
|
|
|
81
128
|
deliveryBlockCursor = 0n;
|
|
82
129
|
pendingEvaluations = new Map();
|
|
83
130
|
observedTasks = new Map();
|
|
131
|
+
/**
|
|
132
|
+
* Read-through cache for `restorationAnnouncementForTaskId` — the restoration
|
|
133
|
+
* task body looked up *while building an evaluation opportunity*. Kept
|
|
134
|
+
* SEPARATE from `observedTasks` (the `watchForTasks` discovery dedup set) on
|
|
135
|
+
* purpose: writing the restoration body into `observedTasks` made the
|
|
136
|
+
* TaskCreated scan skip that taskId as a *restoration* opportunity just
|
|
137
|
+
* because the daemon had built an *evaluation* opportunity for someone
|
|
138
|
+
* else's attempt on it. That blocked the creator's own daemon from claiming
|
|
139
|
+
* its own attempt on a multi-attempt (`maxClaims > 1`) task it posted.
|
|
140
|
+
*/
|
|
141
|
+
restorationBodyCache = new Map();
|
|
84
142
|
requestKinds = new Map();
|
|
85
|
-
claimedRestorationTaskIds = new Set();
|
|
86
143
|
evaluationOpportunities = new Map();
|
|
87
144
|
pendingEvaluationSolutions = new Map();
|
|
88
145
|
// Original Tasks keyed by request ID (restoration and evaluation)
|
|
@@ -104,7 +161,7 @@ export class MechAdapter {
|
|
|
104
161
|
formatRpcError(message, {
|
|
105
162
|
operation: 'getBlockNumber',
|
|
106
163
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
107
|
-
rpcUrl: this.config.rpcUrl,
|
|
164
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
108
165
|
}));
|
|
109
166
|
},
|
|
110
167
|
});
|
|
@@ -214,6 +271,13 @@ export class MechAdapter {
|
|
|
214
271
|
? item.transactionHash
|
|
215
272
|
: undefined,
|
|
216
273
|
blockNumber: typeof item.blockNumber === 'number' ? item.blockNumber : undefined,
|
|
274
|
+
// #645: clamp to a non-negative integer. A tampered or corrupted
|
|
275
|
+
// store row carrying a negative or fractional failedAttempts could
|
|
276
|
+
// otherwise underflow the prune budget (e.g. -1_000_000_000 would
|
|
277
|
+
// defeat the bound for ~10^9 cycles).
|
|
278
|
+
failedAttempts: typeof item.failedAttempts === 'number' && Number.isFinite(item.failedAttempts)
|
|
279
|
+
? Math.max(0, Math.floor(item.failedAttempts))
|
|
280
|
+
: 0,
|
|
217
281
|
};
|
|
218
282
|
this.pendingEvaluationSolutions.set(solution.requestId, solution);
|
|
219
283
|
}
|
|
@@ -236,6 +300,90 @@ export class MechAdapter {
|
|
|
236
300
|
return;
|
|
237
301
|
this.persistPendingEvaluationSolutions();
|
|
238
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Increment the per-solution failure counter and prune when it exceeds the
|
|
305
|
+
* MAX_EVALUATION_RETRY_ATTEMPTS budget. Persistence runs on every increment
|
|
306
|
+
* so a crash mid-cycle does not lose the count (and let a wedge resume
|
|
307
|
+
* log-spamming after a restart).
|
|
308
|
+
*
|
|
309
|
+
* Call sites: ONLY the two paths that fail to make progress on this specific
|
|
310
|
+
* solution — the transient `canClaimEvaluation` branch in
|
|
311
|
+
* evaluationAnnouncementForSolution, and the `catch (err)` arm of
|
|
312
|
+
* retryPendingEvaluationSolutions. Do NOT call from the signal-driven prune
|
|
313
|
+
* paths (terminal claimability, null delivery-envelope CID,
|
|
314
|
+
* !isDiscoveryTaskAllowed) — those already prune cleanly.
|
|
315
|
+
*
|
|
316
|
+
* Returns true when the solution was pruned (caller should stop work on it).
|
|
317
|
+
*/
|
|
318
|
+
recordEvaluationFailureAndMaybePrune(solution) {
|
|
319
|
+
const next = (solution.failedAttempts ?? 0) + 1;
|
|
320
|
+
solution.failedAttempts = next;
|
|
321
|
+
if (next > MAX_EVALUATION_RETRY_ATTEMPTS) {
|
|
322
|
+
console.log(`[mech] pruning evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ` +
|
|
323
|
+
`exceeded retry budget (${MAX_EVALUATION_RETRY_ATTEMPTS}) — pruned`);
|
|
324
|
+
this.forgetPendingEvaluationSolution(solution.requestId);
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
this.persistPendingEvaluationSolutions();
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
/** Prune terminal evaluation state so the poll loop stops retrying (#512). */
|
|
331
|
+
pruneTerminalEvaluationOpportunity(params) {
|
|
332
|
+
const { opportunityId, solutionRequestId, reason } = params;
|
|
333
|
+
const target = opportunityId ?? solutionRequestId ?? 'unknown';
|
|
334
|
+
console.log(`[mech] pruning evaluation opportunity ${target}: ${reason} (terminal — pruned)`);
|
|
335
|
+
if (opportunityId) {
|
|
336
|
+
this.evaluationOpportunities.delete(opportunityId);
|
|
337
|
+
this.observedTasks.delete(opportunityId);
|
|
338
|
+
}
|
|
339
|
+
if (solutionRequestId) {
|
|
340
|
+
this.forgetPendingEvaluationSolution(solutionRequestId);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
async claimEvaluationWithTerminalPrune(opportunityId, evaluationOpportunity, evaluationTaskCidDigest) {
|
|
344
|
+
try {
|
|
345
|
+
return await this.claimEvaluation(evaluationOpportunity.taskId, evaluationOpportunity.attemptIndex, evaluationTaskCidDigest);
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
if (err instanceof SafeInnerRevertError && isNonRecoverableInnerRevert(err.decodedName)) {
|
|
349
|
+
this.pruneTerminalEvaluationOpportunity({
|
|
350
|
+
opportunityId,
|
|
351
|
+
solutionRequestId: evaluationOpportunity.task.restorationRequestId,
|
|
352
|
+
reason: formatDecodedRevert(err.decodedName, err.decodedArgs),
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
throw err;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
clearPendingDeliveryRecoveryState(requestId) {
|
|
359
|
+
this.originalStates.delete(requestId);
|
|
360
|
+
this.pendingEvaluations.delete(requestId);
|
|
361
|
+
this.requestKinds.delete(requestId);
|
|
362
|
+
}
|
|
363
|
+
recoveryDeliveryExpirySeconds(requestId) {
|
|
364
|
+
const task = this.originalStates.get(requestId) ?? this.pendingEvaluations.get(requestId);
|
|
365
|
+
const claimPolicy = task?.claimPolicy ?? DEFAULT_MECH_CLAIM_POLICY;
|
|
366
|
+
const normalizeTsToSeconds = (value) => {
|
|
367
|
+
if (value == null)
|
|
368
|
+
return undefined;
|
|
369
|
+
return value > 10_000_000_000 ? Math.floor(value / 1000) : value;
|
|
370
|
+
};
|
|
371
|
+
const submissionDeadlineSeconds = normalizeTsToSeconds(claimPolicy.submissionDeadlineTs);
|
|
372
|
+
if (submissionDeadlineSeconds != null)
|
|
373
|
+
return submissionDeadlineSeconds;
|
|
374
|
+
const claimWindowEndSeconds = normalizeTsToSeconds(claimPolicy.claimWindowEndTs ?? task?.window?.endTs);
|
|
375
|
+
if (claimWindowEndSeconds == null)
|
|
376
|
+
return undefined;
|
|
377
|
+
return claimWindowEndSeconds + claimPolicy.claimLeaseTtlSeconds;
|
|
378
|
+
}
|
|
379
|
+
shouldSkipExpiredRecoveryDelivery(requestId, currentChainTimestampSeconds, recoveryExpirySeconds) {
|
|
380
|
+
if (currentChainTimestampSeconds <= recoveryExpirySeconds)
|
|
381
|
+
return false;
|
|
382
|
+
console.error(`[mech] skipping recovery delivery for ${requestId}: ` +
|
|
383
|
+
`submission deadline expired at ${new Date(recoveryExpirySeconds * 1000).toISOString()}`);
|
|
384
|
+
this.clearPendingDeliveryRecoveryState(requestId);
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
239
387
|
async postTask(state) {
|
|
240
388
|
const restorationState = {
|
|
241
389
|
...state,
|
|
@@ -264,18 +412,21 @@ export class MechAdapter {
|
|
|
264
412
|
const manifestDigest = keccak256(toBytes(signedTask.solverNetManifestCid));
|
|
265
413
|
const policy = this.contractPolicyForTask(restorationState);
|
|
266
414
|
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
|
-
|
|
415
|
+
// Deliberately do NOT seed `observedTasks` with the task we just posted.
|
|
416
|
+
// `observedTasks` is the dedup set for `watchForTasks`: the on-chain
|
|
417
|
+
// TaskCreated scan skips any taskId already in it (so a task is announced
|
|
418
|
+
// to the engine-watcher at most once). Seeding it here marked the
|
|
419
|
+
// creator's own task as "already announced" before it was ever yielded —
|
|
420
|
+
// which permanently prevented the *creator's own daemon* from discovering,
|
|
421
|
+
// claiming, and solving a task it posted. On a multi-attempt task
|
|
422
|
+
// (`maxClaims > 1`) the creator running the solver role is legitimate
|
|
423
|
+
// (the protocol forbids only self-*evaluation*, and that on a per-attempt
|
|
424
|
+
// basis), and on testnet it is the intended single-operator dogfood path
|
|
425
|
+
// — post → claim → solve → grade → settle from one daemon. The dedup is
|
|
426
|
+
// still correct: it now keys only on tasks `watchForTasks` actually
|
|
427
|
+
// yielded. `restorationAnnouncementForTaskId` re-hydrates from chain/IPFS
|
|
428
|
+
// on a cache miss, so dropping the pre-seed costs at most one redundant
|
|
429
|
+
// fetch if the creator later claims its own task.
|
|
279
430
|
return {
|
|
280
431
|
taskId: taskSubmission.taskId,
|
|
281
432
|
taskCid: restorationTaskCid,
|
|
@@ -348,7 +499,14 @@ export class MechAdapter {
|
|
|
348
499
|
maxClaimsPerOperator: claimPolicy.maxClaimsPerOperator,
|
|
349
500
|
policyHook: (claimPolicy.policyHook ?? zeroAddress),
|
|
350
501
|
evaluationPolicy: {
|
|
351
|
-
requiredVerdicts
|
|
502
|
+
// `requiredVerdicts` defaults to 1 but is overridable via the task's
|
|
503
|
+
// claim policy. A value > 1 opens additional verdict claim slots per
|
|
504
|
+
// attempt; combined with the per-evaluator cap below (1), it
|
|
505
|
+
// guarantees an honest evaluator can still claim and deliver a slot
|
|
506
|
+
// even when other evaluators have squatted some — the structural fix
|
|
507
|
+
// for a shared/adversarial testnet where a non-delivering claimer
|
|
508
|
+
// would otherwise permanently lock a single-slot attempt.
|
|
509
|
+
requiredVerdicts: claimPolicy.requiredVerdicts ?? 1,
|
|
352
510
|
passThreshold: 1,
|
|
353
511
|
evaluationDeadline: submissionDeadline + BigInt(claimPolicy.claimLeaseTtlSeconds),
|
|
354
512
|
maxVerdictsPerEvaluator: 1,
|
|
@@ -381,7 +539,11 @@ export class MechAdapter {
|
|
|
381
539
|
};
|
|
382
540
|
}
|
|
383
541
|
async restorationAnnouncementForTaskId(taskId) {
|
|
384
|
-
|
|
542
|
+
// Read-through `restorationBodyCache` — NOT `observedTasks`. This helper is
|
|
543
|
+
// an evaluation-path lookup of a task's restoration body; caching it into
|
|
544
|
+
// the `watchForTasks` discovery dedup set would suppress the creator's own
|
|
545
|
+
// restoration-claim discovery for the same taskId (see field comment).
|
|
546
|
+
const cached = this.restorationBodyCache.get(taskId) ?? this.observedTasks.get(taskId);
|
|
385
547
|
if (cached)
|
|
386
548
|
return cached;
|
|
387
549
|
const taskCidDigest = await getTaskCidDigest(this.publicClient, this.config.routerAddress, taskId);
|
|
@@ -394,7 +556,7 @@ export class MechAdapter {
|
|
|
394
556
|
task,
|
|
395
557
|
taskCid,
|
|
396
558
|
};
|
|
397
|
-
this.
|
|
559
|
+
this.restorationBodyCache.set(taskId, announcement);
|
|
398
560
|
return announcement;
|
|
399
561
|
}
|
|
400
562
|
async restorationAnnouncementFromDigest(params) {
|
|
@@ -440,8 +602,6 @@ export class MechAdapter {
|
|
|
440
602
|
for (const candidate of candidates) {
|
|
441
603
|
if (!this.isDiscoveryTaskAllowed(candidate.taskId))
|
|
442
604
|
continue;
|
|
443
|
-
if (this.claimedRestorationTaskIds.has(candidate.taskId))
|
|
444
|
-
continue;
|
|
445
605
|
// gh #300 ghost-task floor — same floor as the on-chain TaskCreated
|
|
446
606
|
// backlog scan, applied to the DiscoveryAPI path too. Without this,
|
|
447
607
|
// the Ponder indexer (or onchain floor's listClaimableTasks) returns
|
|
@@ -465,19 +625,40 @@ export class MechAdapter {
|
|
|
465
625
|
continue;
|
|
466
626
|
}
|
|
467
627
|
try {
|
|
628
|
+
// Yield every hydrated candidate per cycle rather than returning after
|
|
629
|
+
// the first. The engine-watcher (daemon._runEngineWatcherLoop) is the
|
|
630
|
+
// single point of skip-state truth — when its in-flight admission gate
|
|
631
|
+
// fast-skips a candidate (~30s TTL), that skip state never flows back
|
|
632
|
+
// into the adapter's iteration cursor. Yielding only the first
|
|
633
|
+
// candidate per cycle meant a fast-skipped slot starved every
|
|
634
|
+
// subsequent candidate in the round-robin (`fc05f686`) ordering for
|
|
635
|
+
// the duration of the TTL. By driving the full candidate list per
|
|
636
|
+
// cycle we let the engine apply its gate to each one, preserving the
|
|
637
|
+
// round-robin fairness across joined SolverNets. See task 212 live
|
|
638
|
+
// verification in the fix's commit body.
|
|
468
639
|
yield await this.restorationAnnouncementFromDigest({
|
|
469
640
|
taskId: candidate.taskId,
|
|
470
641
|
taskCidDigest: candidate.taskCidDigest,
|
|
471
642
|
transactionHash: candidate.createdAtTx,
|
|
472
643
|
blockNumber: candidate.createdAtBlock,
|
|
473
644
|
});
|
|
474
|
-
return;
|
|
475
645
|
}
|
|
476
646
|
catch (err) {
|
|
477
647
|
console.error(`[mech] failed to hydrate subgraph task ${candidate.taskId}:`, err instanceof Error ? err.message : err);
|
|
478
648
|
}
|
|
479
649
|
}
|
|
480
650
|
}
|
|
651
|
+
/**
|
|
652
|
+
* Look up the Deliver-event envelope CID for a pending evaluation solution.
|
|
653
|
+
*
|
|
654
|
+
* Returns `null` when the Deliver event is not present in the configured
|
|
655
|
+
* lookback window. This is a terminal signal for the caller — re-running the
|
|
656
|
+
* same lookup later is deterministically futile when `solution.blockNumber`
|
|
657
|
+
* is set (toBlock is fixed at the SolutionDeliveryClaimed block), and is
|
|
658
|
+
* monotonically less likely to find the event when toBlock follows chain head
|
|
659
|
+
* (the window slides forward, away from any older Deliver event). Callers
|
|
660
|
+
* should prune the pending solution on `null` rather than retry — see #553.
|
|
661
|
+
*/
|
|
481
662
|
async deliveryEnvelopeCidForSolution(solution) {
|
|
482
663
|
const deliveryMech = await getMarketplaceRequestDeliveryMech(this.publicClient, this.config.mechMarketplaceAddress, solution.requestId);
|
|
483
664
|
const toBlock = solution.blockNumber != null
|
|
@@ -488,8 +669,7 @@ export class MechAdapter {
|
|
|
488
669
|
const fromBlock = toBlock > lookback ? toBlock - lookback : 0n;
|
|
489
670
|
const deliveryDataHex = await findLatestDeliveryDataHexForRequest(this.publicClient, deliveryMech, solution.requestId, fromBlock, toBlock);
|
|
490
671
|
if (!deliveryDataHex) {
|
|
491
|
-
|
|
492
|
-
`between blocks ${fromBlock} and ${toBlock}`);
|
|
672
|
+
return null;
|
|
493
673
|
}
|
|
494
674
|
const digest = deliveryDataHex.startsWith('0x') ? deliveryDataHex.slice(2) : deliveryDataHex;
|
|
495
675
|
return `f01551220${digest}`;
|
|
@@ -500,14 +680,43 @@ export class MechAdapter {
|
|
|
500
680
|
this.forgetPendingEvaluationSolution(solution.requestId);
|
|
501
681
|
return undefined;
|
|
502
682
|
}
|
|
503
|
-
|
|
683
|
+
// Cheap claimability gate FIRST — before the restoration lookup + IPFS
|
|
684
|
+
// fetch. A backlog of terminal opportunities (finalized / evaluation
|
|
685
|
+
// deadline passed / max verdicts reached) must not pay the expensive
|
|
686
|
+
// restoration-announcement cost on every poll cycle. Terminal reasons are
|
|
687
|
+
// pruned from the working set so the loop never re-scans on-chain history;
|
|
688
|
+
// transient reasons are left in place to be retried next cycle.
|
|
504
689
|
const claimable = await canClaimEvaluation(this.publicClient, this.config.safeAddress, this.config.routerAddress, solution.taskId, solution.attemptIndex, this.config.mechContractAddress);
|
|
505
690
|
if (!claimable.ok) {
|
|
506
|
-
|
|
507
|
-
|
|
691
|
+
const terminal = isTerminalEvaluationReason(claimable.revertName);
|
|
692
|
+
console.log(`[mech] skipping evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ${claimable.reason}` +
|
|
693
|
+
(terminal ? ' (terminal — pruned)' : ' (transient — will retry)'));
|
|
694
|
+
if (terminal) {
|
|
695
|
+
this.pruneTerminalEvaluationOpportunity({
|
|
696
|
+
solutionRequestId: solution.requestId,
|
|
697
|
+
reason: claimable.reason,
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
// #645 backstop: bound retries on transient/unclassified claimability
|
|
702
|
+
// failures so a wedged opportunity can't log-spam forever.
|
|
703
|
+
this.recordEvaluationFailureAndMaybePrune(solution);
|
|
704
|
+
}
|
|
508
705
|
return undefined;
|
|
509
706
|
}
|
|
707
|
+
const restoration = await this.restorationAnnouncementForTaskId(solution.taskId);
|
|
510
708
|
const solutionEnvelopeCid = await this.deliveryEnvelopeCidForSolution(solution);
|
|
709
|
+
if (solutionEnvelopeCid == null) {
|
|
710
|
+
// #553: Deliver event is not within the configured lookback window. A
|
|
711
|
+
// retry with the same toBlock cannot reach an older event, so this is
|
|
712
|
+
// terminal — prune so the loop never re-pays the canClaimEvaluation +
|
|
713
|
+
// restoration lookup cost on a deterministically-failing opportunity.
|
|
714
|
+
this.pruneTerminalEvaluationOpportunity({
|
|
715
|
+
solutionRequestId: solution.requestId,
|
|
716
|
+
reason: `no Deliver event found within configured lookback for task ${solution.taskId}/${solution.attemptIndex}`,
|
|
717
|
+
});
|
|
718
|
+
return undefined;
|
|
719
|
+
}
|
|
511
720
|
const resultPayload = await fetchFromIpfs(this.config.ipfsGatewayUrl, solutionEnvelopeCid);
|
|
512
721
|
const resultData = resultPayload.data ?? JSON.stringify(resultPayload);
|
|
513
722
|
const evaluationTask = this.buildEvaluationTask({
|
|
@@ -532,21 +741,39 @@ export class MechAdapter {
|
|
|
532
741
|
task: evaluationTask,
|
|
533
742
|
});
|
|
534
743
|
this.observedTasks.set(opportunityId, announcement);
|
|
744
|
+
// #645: a successful announcement means the candidate has made progress;
|
|
745
|
+
// reset the transient-failure counter so that subsequent transient errors
|
|
746
|
+
// (e.g. IPFS hiccups in the announce → claim window) don't accumulate
|
|
747
|
+
// across the candidate's lifetime and silently false-prune legitimate work.
|
|
748
|
+
if (solution.failedAttempts) {
|
|
749
|
+
solution.failedAttempts = 0;
|
|
750
|
+
this.persistPendingEvaluationSolutions();
|
|
751
|
+
}
|
|
535
752
|
return announcement;
|
|
536
753
|
}
|
|
537
754
|
async *retryPendingEvaluationSolutions() {
|
|
755
|
+
let processed = 0;
|
|
538
756
|
for (const [requestId, solution] of Array.from(this.pendingEvaluationSolutions)) {
|
|
757
|
+
// Yield to the event loop periodically so a large backlog of pending
|
|
758
|
+
// evaluation solutions can't starve the HTTP API mid-cycle.
|
|
759
|
+
if (processed > 0 && processed % EVALUATION_RETRY_YIELD_EVERY === 0) {
|
|
760
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
761
|
+
}
|
|
762
|
+
processed++;
|
|
539
763
|
try {
|
|
540
764
|
const announcement = await this.evaluationAnnouncementForSolution(solution);
|
|
541
765
|
if (announcement) {
|
|
542
766
|
yield announcement;
|
|
543
767
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
768
|
+
// No announcement does NOT mean "forget" — pruning is owned by
|
|
769
|
+
// evaluationAnnouncementForSolution, which only removes terminal cases.
|
|
547
770
|
}
|
|
548
771
|
catch (err) {
|
|
549
772
|
console.error(`[mech] evaluation opportunity retry failed for ${requestId}:`, err);
|
|
773
|
+
// #645 backstop: bound retries on any uncaught failure so a wedged
|
|
774
|
+
// requestId (e.g. an RPC failure path that re-throws every cycle)
|
|
775
|
+
// can't log-spam forever.
|
|
776
|
+
this.recordEvaluationFailureAndMaybePrune(solution);
|
|
550
777
|
}
|
|
551
778
|
}
|
|
552
779
|
}
|
|
@@ -576,7 +803,7 @@ export class MechAdapter {
|
|
|
576
803
|
for (const { taskId, taskCidDigest, manifestDigest, transactionHash, blockNumber } of createdTasks) {
|
|
577
804
|
if (!this.isDiscoveryTaskAllowed(taskId))
|
|
578
805
|
continue;
|
|
579
|
-
if (this.
|
|
806
|
+
if (this.observedTasks.has(taskId))
|
|
580
807
|
continue;
|
|
581
808
|
if (joinedManifestDigests.size > 0 && !joinedManifestDigests.has(manifestDigest.toLowerCase()))
|
|
582
809
|
continue;
|
|
@@ -605,7 +832,7 @@ export class MechAdapter {
|
|
|
605
832
|
console.error('[mech] Error polling for tasks:', formatRpcError(err, {
|
|
606
833
|
operation: 'pollTaskCreated',
|
|
607
834
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
608
|
-
rpcUrl: this.config.rpcUrl,
|
|
835
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
609
836
|
contract: this.config.routerAddress,
|
|
610
837
|
fromBlock: this.requestBlockCursor + 1n,
|
|
611
838
|
}));
|
|
@@ -619,7 +846,7 @@ export class MechAdapter {
|
|
|
619
846
|
const signedEvaluationTask = await this.signTaskDocument(evaluationOpportunity.task);
|
|
620
847
|
const evaluationCid = await uploadToIpfs(this.config.ipfsRegistryUrl, signedEvaluationTask);
|
|
621
848
|
const evaluationTaskCidDigest = cidToDigestHex(evaluationCid);
|
|
622
|
-
const claimed = await this.
|
|
849
|
+
const claimed = await this.claimEvaluationWithTerminalPrune(taskId, evaluationOpportunity, evaluationTaskCidDigest);
|
|
623
850
|
this.pendingEvaluations.set(claimed.requestId, evaluationOpportunity.task);
|
|
624
851
|
this.originalStates.set(claimed.requestId, evaluationOpportunity.task);
|
|
625
852
|
this.requestKinds.set(claimed.requestId, 'verdict');
|
|
@@ -644,7 +871,6 @@ export class MechAdapter {
|
|
|
644
871
|
}
|
|
645
872
|
const claimed = await claimTaskOnchain(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, taskId, this.config.mechContractAddress, this.config.evictionRecovery);
|
|
646
873
|
const task = announcement.task;
|
|
647
|
-
this.claimedRestorationTaskIds.add(claimed.taskId);
|
|
648
874
|
this.pendingEvaluations.set(claimed.requestId, task);
|
|
649
875
|
this.originalStates.set(claimed.requestId, { ...task, role: task.role ?? 'restoration' });
|
|
650
876
|
this.requestKinds.set(claimed.requestId, 'solution');
|
|
@@ -676,9 +902,13 @@ export class MechAdapter {
|
|
|
676
902
|
async submitVerdictDelivery(requestId, verdictDigest, verdictCode) {
|
|
677
903
|
await claimDelivery(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, requestId, { variant: 'v3', kind: 'verdict', evidenceHash: verdictDigest, verdictCode }, this.config.evictionRecovery);
|
|
678
904
|
}
|
|
679
|
-
async
|
|
905
|
+
async deliveryClaimForDelivery(requestId, deliveryDataHex) {
|
|
906
|
+
const fallbackKind = this.requestKinds.get(requestId) ?? 'solution';
|
|
680
907
|
if (this.config.routerClaimDeliveryVariant !== 'v2' && this.config.routerClaimDeliveryVariant !== 'v3') {
|
|
681
|
-
return
|
|
908
|
+
return {
|
|
909
|
+
evidenceHash: undefined,
|
|
910
|
+
kind: fallbackKind,
|
|
911
|
+
};
|
|
682
912
|
}
|
|
683
913
|
const deliveryDigest = deliveryDataHex.startsWith('0x')
|
|
684
914
|
? deliveryDataHex.slice(2)
|
|
@@ -686,11 +916,6 @@ export class MechAdapter {
|
|
|
686
916
|
const envelopeCid = `f01551220${deliveryDigest}`;
|
|
687
917
|
const rawEnvelope = await fetchSignedEnvelopeFromIpfs(this.config.ipfsGatewayUrl, envelopeCid);
|
|
688
918
|
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
919
|
const rawSigned = rawEnvelope;
|
|
695
920
|
const { signature: _rawSignature, ...unsignedBody } = rawSigned;
|
|
696
921
|
const signature = parsed.signature;
|
|
@@ -699,22 +924,36 @@ export class MechAdapter {
|
|
|
699
924
|
if (recomputed !== signature.hash) {
|
|
700
925
|
throw new Error(`recomputed hash ${recomputed} !== envelope.signature.hash ${signature.hash}`);
|
|
701
926
|
}
|
|
702
|
-
|
|
927
|
+
const role = normalizeEnvelopeRole(parsed.role);
|
|
928
|
+
if (role === 'capture') {
|
|
929
|
+
throw new Error(`unsupported delivery envelope role=capture for requestId ${requestId}`);
|
|
930
|
+
}
|
|
931
|
+
const kind = role === 'verdict' ? 'verdict' : 'solution';
|
|
932
|
+
const payload = rawSigned['payload'];
|
|
933
|
+
const rawVerdict = payload != null && typeof payload === 'object'
|
|
934
|
+
? payload['verdict']
|
|
935
|
+
: undefined;
|
|
936
|
+
return {
|
|
937
|
+
evidenceHash: recomputed,
|
|
938
|
+
kind,
|
|
939
|
+
verdictCode: kind === 'verdict' ? verdictCodeFromValue(rawVerdict) : undefined,
|
|
940
|
+
};
|
|
703
941
|
}
|
|
704
942
|
async ensureDeliveryClaimed(requestId, deliveryDataHex) {
|
|
705
|
-
let
|
|
943
|
+
let claimOptions;
|
|
706
944
|
try {
|
|
707
|
-
|
|
945
|
+
claimOptions = await this.deliveryClaimForDelivery(requestId, deliveryDataHex);
|
|
708
946
|
}
|
|
709
947
|
catch (err) {
|
|
710
|
-
console.error(`[mech]
|
|
948
|
+
console.error(`[mech] delivery claim metadata derivation failed for ${requestId} — skipping claim, will retry on next loop:`, err);
|
|
711
949
|
return 'retry';
|
|
712
950
|
}
|
|
713
951
|
try {
|
|
714
952
|
await claimDelivery(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, requestId, {
|
|
715
953
|
variant: this.config.routerClaimDeliveryVariant,
|
|
716
|
-
kind:
|
|
717
|
-
evidenceHash,
|
|
954
|
+
kind: claimOptions.kind,
|
|
955
|
+
evidenceHash: claimOptions.evidenceHash,
|
|
956
|
+
verdictCode: claimOptions.verdictCode,
|
|
718
957
|
}, this.config.evictionRecovery);
|
|
719
958
|
return 'claimed';
|
|
720
959
|
}
|
|
@@ -728,22 +967,66 @@ export class MechAdapter {
|
|
|
728
967
|
return 'already-claimed';
|
|
729
968
|
}
|
|
730
969
|
console.error(`[mech] claimDelivery failed for ${requestId}:`, err);
|
|
970
|
+
// Paired SSE signal for the operator-app `claim_failed` notification
|
|
971
|
+
// (OPERATOR-APP-SPEC §2.10). The early-return branches above
|
|
972
|
+
// (`skipped` / `already-claimed`) are not failures and intentionally do not emit.
|
|
973
|
+
emitStructured({
|
|
974
|
+
kind: 'intent',
|
|
975
|
+
message: 'Delivery claim failed',
|
|
976
|
+
requestId,
|
|
977
|
+
errorCode: 'claim_failed',
|
|
978
|
+
details: {
|
|
979
|
+
kind: claimOptions.kind,
|
|
980
|
+
source: 'mech.claimDelivery',
|
|
981
|
+
error: message,
|
|
982
|
+
},
|
|
983
|
+
});
|
|
731
984
|
return 'retry';
|
|
732
985
|
}
|
|
733
986
|
}
|
|
987
|
+
/**
|
|
988
|
+
* Paginate `getLogs` over `[deliveryBlockCursor+1, currentBlock]` chunked by
|
|
989
|
+
* `DEFAULT_ROUTER_LOG_CHUNK_BLOCKS` to honor RPC provider block-range limits
|
|
990
|
+
* (Tenderly base-sepolia caps at 100k; sepolia.base.org ~1k). Advances +
|
|
991
|
+
* persists `deliveryBlockCursor` per chunk so a mid-scan RPC failure on a
|
|
992
|
+
* later chunk does not strand the cursor at the pre-poll value (#552).
|
|
993
|
+
*
|
|
994
|
+
* Yields each chunk's decoded Deliver entries so the consumer can process
|
|
995
|
+
* them with the live "current block" context (needed for the recovery-
|
|
996
|
+
* delivery timestamp cache).
|
|
997
|
+
*/
|
|
998
|
+
async *scanDeliveryLogChunks(currentBlock) {
|
|
999
|
+
while (currentBlock > this.deliveryBlockCursor) {
|
|
1000
|
+
const chunkStart = this.deliveryBlockCursor + 1n;
|
|
1001
|
+
const chunkEnd = chunkStart + DEFAULT_ROUTER_LOG_CHUNK_BLOCKS > currentBlock
|
|
1002
|
+
? currentBlock
|
|
1003
|
+
: chunkStart + DEFAULT_ROUTER_LOG_CHUNK_BLOCKS;
|
|
1004
|
+
const logs = await this.publicClient.getLogs({
|
|
1005
|
+
address: this.config.mechContractAddress,
|
|
1006
|
+
fromBlock: chunkStart,
|
|
1007
|
+
toBlock: chunkEnd,
|
|
1008
|
+
});
|
|
1009
|
+
// Advance + persist BEFORE yielding so partial progress is durable even
|
|
1010
|
+
// if a downstream throw escapes back through the for-await consumer.
|
|
1011
|
+
this.deliveryBlockCursor = chunkEnd;
|
|
1012
|
+
if (this.store) {
|
|
1013
|
+
this.store.setLastProcessedBlock(this.deliveryBlockCursor);
|
|
1014
|
+
}
|
|
1015
|
+
yield decodeDeliverLogs(logs);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
734
1018
|
async *watchForDeliveries() {
|
|
735
1019
|
while (!this.stopped) {
|
|
736
1020
|
try {
|
|
737
1021
|
const currentBlock = await this.publicClient.getBlockNumber();
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const
|
|
746
|
-
for (const { requestId, deliveryDataHex, mechAddress } of decoded) {
|
|
1022
|
+
// Caches scoped to the whole poll iteration: the "current block"
|
|
1023
|
+
// reference does not change across chunks.
|
|
1024
|
+
const blockTimestampSecondsByNumber = new Map();
|
|
1025
|
+
let currentBlockTimestampSeconds;
|
|
1026
|
+
for await (const decoded of this.scanDeliveryLogChunks(currentBlock)) {
|
|
1027
|
+
if (this.stopped)
|
|
1028
|
+
break;
|
|
1029
|
+
for (const { requestId, deliveryDataHex, mechAddress, blockNumber } of decoded) {
|
|
747
1030
|
// Two concerns, independent:
|
|
748
1031
|
// (a) Did this Safe DELIVER this? → claim it (counter credit goes to msg.sender)
|
|
749
1032
|
// The Deliver event's mechAddress is mechServiceMultisig (the Safe that owns
|
|
@@ -753,6 +1036,30 @@ export class MechAdapter {
|
|
|
753
1036
|
const iCreatedRestoration = this.pendingEvaluations.has(requestId);
|
|
754
1037
|
if (!iDelivered && !iCreatedRestoration)
|
|
755
1038
|
continue;
|
|
1039
|
+
if (iCreatedRestoration) {
|
|
1040
|
+
const recoveryExpirySeconds = this.recoveryDeliveryExpirySeconds(requestId);
|
|
1041
|
+
if (recoveryExpirySeconds != null) {
|
|
1042
|
+
let deliveryTimestampSeconds;
|
|
1043
|
+
if (blockNumber != null) {
|
|
1044
|
+
deliveryTimestampSeconds = blockTimestampSecondsByNumber.get(blockNumber);
|
|
1045
|
+
if (deliveryTimestampSeconds == null) {
|
|
1046
|
+
const deliveryBlockData = await this.publicClient.getBlock({ blockNumber });
|
|
1047
|
+
deliveryTimestampSeconds = Number(deliveryBlockData.timestamp);
|
|
1048
|
+
blockTimestampSecondsByNumber.set(blockNumber, deliveryTimestampSeconds);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
else {
|
|
1052
|
+
if (currentBlockTimestampSeconds == null) {
|
|
1053
|
+
const currentBlockData = await this.publicClient.getBlock({ blockNumber: currentBlock });
|
|
1054
|
+
currentBlockTimestampSeconds = Number(currentBlockData.timestamp);
|
|
1055
|
+
}
|
|
1056
|
+
deliveryTimestampSeconds = currentBlockTimestampSeconds;
|
|
1057
|
+
}
|
|
1058
|
+
if (this.shouldSkipExpiredRecoveryDelivery(requestId, deliveryTimestampSeconds, recoveryExpirySeconds)) {
|
|
1059
|
+
continue;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
756
1063
|
// (a) Deliverer-side claim path: if this Safe delivered the request,
|
|
757
1064
|
// claim it first so router counters credit the deliverer.
|
|
758
1065
|
let deliveryClaimStatus;
|
|
@@ -788,9 +1095,7 @@ export class MechAdapter {
|
|
|
788
1095
|
deliveryMechAddress: mechAddress,
|
|
789
1096
|
};
|
|
790
1097
|
// Clean up after yielding
|
|
791
|
-
this.
|
|
792
|
-
this.pendingEvaluations.delete(requestId);
|
|
793
|
-
this.requestKinds.delete(requestId);
|
|
1098
|
+
this.clearPendingDeliveryRecoveryState(requestId);
|
|
794
1099
|
}
|
|
795
1100
|
catch (err) {
|
|
796
1101
|
console.error(`[mech] Failed to parse delivery ${requestId}:`, err);
|
|
@@ -802,15 +1107,13 @@ export class MechAdapter {
|
|
|
802
1107
|
console.error('[mech] Error polling for deliveries:', formatRpcError(err, {
|
|
803
1108
|
operation: 'pollDeliveries',
|
|
804
1109
|
chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
|
|
805
|
-
rpcUrl: this.config.rpcUrl,
|
|
1110
|
+
rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
|
|
806
1111
|
contract: this.config.mechContractAddress,
|
|
807
1112
|
fromBlock: this.deliveryBlockCursor + 1n,
|
|
808
1113
|
}));
|
|
809
1114
|
}
|
|
810
|
-
//
|
|
811
|
-
|
|
812
|
-
this.store.setLastProcessedBlock(this.deliveryBlockCursor);
|
|
813
|
-
}
|
|
1115
|
+
// Cursor persistence is per-chunk inside the loop above (#552). A poll
|
|
1116
|
+
// that did no chunked work has no progress to persist.
|
|
814
1117
|
await new Promise(r => setTimeout(r, this.config.pollIntervalMs));
|
|
815
1118
|
}
|
|
816
1119
|
}
|