@jinn-network/client 0.1.6 → 0.1.7-canary.205587f0
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/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 -1
- package/dist/adapters/mech/adapter.js +241 -54
- 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 +5 -1
- package/dist/adapters/mech/safe.js +27 -8
- package/dist/adapters/mech/safe.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/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.js +49 -0
- package/dist/api/bootstrap-endpoint.js.map +1 -1
- package/dist/api/codex-doctor-endpoint.d.ts +73 -0
- package/dist/api/codex-doctor-endpoint.js +177 -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 +11 -0
- package/dist/api/gather-status.js +467 -4
- package/dist/api/gather-status.js.map +1 -1
- package/dist/api/hermes-doctor-endpoint.d.ts +117 -0
- package/dist/api/hermes-doctor-endpoint.js +229 -23
- package/dist/api/hermes-doctor-endpoint.js.map +1 -1
- package/dist/api/launcher-status.d.ts +21 -16
- package/dist/api/launcher-status.js +2 -1
- package/dist/api/launcher-status.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 +68 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/setup-endpoints.d.ts +16 -0
- package/dist/api/setup-endpoints.js +78 -4
- 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 +71 -43
- package/dist/api/solvernets-endpoints.js.map +1 -1
- package/dist/api/status-build.d.ts +78 -0
- package/dist/api/status-build.js +74 -18
- package/dist/api/status-build.js.map +1 -1
- 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/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 +24 -9
- package/dist/cli/commands/solver-nets.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 +86 -9
- 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 +3 -1
- package/dist/cli/task-native-readiness.js +28 -6
- package/dist/cli/task-native-readiness.js.map +1 -1
- package/dist/config.d.ts +118 -5
- package/dist/config.js +132 -18
- 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 +19 -0
- package/dist/daemon/daemon.js +68 -1
- 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/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/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/dashboard/assets/index-DMm7Y4f7.css +32 -0
- package/dist/dashboard/assets/index-Dt1RV0Ee.js +330 -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 +142 -3
- package/dist/discovery/http.js.map +1 -1
- package/dist/discovery/onchain.d.ts +5 -0
- package/dist/discovery/onchain.js +407 -15
- package/dist/discovery/onchain.js.map +1 -1
- package/dist/discovery/types.d.ts +45 -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 +10 -0
- package/dist/discovery/with-fallback.js.map +1 -1
- package/dist/earning/bootstrap.d.ts +92 -1
- package/dist/earning/bootstrap.js +203 -63
- 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 +26 -12
- 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 +15 -0
- 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/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 +72 -0
- package/dist/harnesses/engine/engine.js +105 -8
- 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/index.d.ts +9 -0
- package/dist/harnesses/impls/index.js +19 -1
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +3 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.js +49 -0
- package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +41 -4
- package/dist/harnesses/impls/learner/harness.js +114 -2
- package/dist/harnesses/impls/learner/harness.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/types.d.ts +15 -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 +15 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +54 -4
- 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.js +9 -1
- package/dist/harnesses/readiness-registry.js.map +1 -1
- package/dist/main.js +373 -82
- package/dist/main.js.map +1 -1
- package/dist/observability/emit-event.d.ts +1 -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/restart-daemon.d.ts +90 -0
- package/dist/restart-daemon.js +95 -0
- package/dist/restart-daemon.js.map +1 -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.js +43 -3
- package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
- package/dist/solver-nets/registry.d.ts +1 -0
- package/dist/solver-nets/registry.js +1 -1
- 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-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 +65 -0
- package/dist/solver-types/_swe-rebench-v2-validated-pool.js +243 -26
- 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 +45 -20
- package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
- package/dist/solver-types/swe-rebench-v2.d.ts +13 -2
- package/dist/solver-types/swe-rebench-v2.js +233 -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.js +35 -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/store/store.d.ts +15 -0
- package/dist/store/store.js +118 -3
- 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/tx-retry.d.ts +151 -19
- package/dist/tx-retry.js +286 -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 +29 -12
- package/dist/dashboard/assets/index-DOlzFN8a.css +0 -32
- package/dist/dashboard/assets/index-NkZ7CTAT.js +0 -140
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { CLAUDE_CODE_HARNESS } from '../../names.js';
|
|
1
|
+
import { CLAUDE_CODE_HARNESS, CODEX_HARNESS, canonicalHarnessName } from '../../names.js';
|
|
2
2
|
import { resolvePluginRoot } from './plugin-path.js';
|
|
3
3
|
import { harvestOutput } from './harvest.js';
|
|
4
4
|
import { buildClaudeIsReady } from '../../../preflight/claude-auth.js';
|
|
5
|
+
import { probeCodexDoctor } from '../../../api/codex-doctor-endpoint.js';
|
|
6
|
+
import { isLocalCodexBaseUrl } from './adapters/codex-code.js';
|
|
5
7
|
/**
|
|
6
8
|
* `Harness` shell. Bridges the engine's dispatch contract
|
|
7
9
|
* (`await impl.run(ctx)`) into the harness adapter + markdown plugin.
|
|
@@ -16,6 +18,9 @@ export class LearnerHarness {
|
|
|
16
18
|
adapter;
|
|
17
19
|
pluginRoot;
|
|
18
20
|
claudePath;
|
|
21
|
+
codexPath;
|
|
22
|
+
codexBaseUrl;
|
|
23
|
+
codexDoctorTimeoutMs;
|
|
19
24
|
runtimeMode;
|
|
20
25
|
constructor(config) {
|
|
21
26
|
this.adapter = config.adapter;
|
|
@@ -23,12 +28,119 @@ export class LearnerHarness {
|
|
|
23
28
|
this.version = config.version ?? '0.1.0-shim';
|
|
24
29
|
this.pluginRoot = config.pluginRoot ?? resolvePluginRoot();
|
|
25
30
|
this.claudePath = config.claudePath ?? 'claude';
|
|
31
|
+
this.codexPath = config.codexPath;
|
|
32
|
+
this.codexBaseUrl = config.codexBaseUrl;
|
|
33
|
+
this.codexDoctorTimeoutMs = config.codexDoctorTimeoutMs;
|
|
26
34
|
this.runtimeMode = config.runtimeMode ?? 'bare';
|
|
27
35
|
}
|
|
28
|
-
|
|
36
|
+
claudeIsReady = buildClaudeIsReady({
|
|
29
37
|
getClaudePath: () => this.claudePath,
|
|
30
38
|
getContext: () => this.runtimeMode,
|
|
31
39
|
});
|
|
40
|
+
/**
|
|
41
|
+
* Readiness probe.
|
|
42
|
+
*
|
|
43
|
+
* The `LearnerHarness` shell backs two distinct CLIs: claude-code (the
|
|
44
|
+
* default) and Codex (`name === CODEX_HARNESS`). The probe MUST match the
|
|
45
|
+
* CLI actually invoked — delegating the Codex variant to the claude auth
|
|
46
|
+
* probe makes a missing/unconfigured `codex` install look always-ready and
|
|
47
|
+
* burns N/N failed claims (#348, the same-shape bug as #330).
|
|
48
|
+
*
|
|
49
|
+
* - claude-code → `buildClaudeIsReady` (shells `claude auth status`).
|
|
50
|
+
* - Codex → `probeCodexDoctor` (shells `codex --version`, then
|
|
51
|
+
* checks for `OPENAI_API_KEY` / a `codex login` auth file).
|
|
52
|
+
*/
|
|
53
|
+
async isReady(ctx) {
|
|
54
|
+
if (canonicalHarnessName(this.name) === CODEX_HARNESS) {
|
|
55
|
+
return this.codexIsReady();
|
|
56
|
+
}
|
|
57
|
+
return this.claudeIsReady(ctx);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Codex-specific readiness probe. Shells `codex --version` via the shared
|
|
61
|
+
* `probeCodexDoctor` helper (same logic the SPA precheck endpoint uses).
|
|
62
|
+
* Reports:
|
|
63
|
+
* - `installed: false` → binary not on PATH → ready=false with an install
|
|
64
|
+
* nextStep so the operator sees an actionable message instead of N/N
|
|
65
|
+
* failed claims (#348).
|
|
66
|
+
* - `exitCode !== 0` → binary exists but `codex --version` failed →
|
|
67
|
+
* ready=false pointing at the Codex precheck panel.
|
|
68
|
+
* - local `codexBaseUrl` → binary runs and the local sidecar owns auth, so
|
|
69
|
+
* Codex auth is not required.
|
|
70
|
+
* - `authStatus: 'not_configured'` → binary runs but no `OPENAI_API_KEY`
|
|
71
|
+
* and no `codex login` session → ready=false with a sign-in nextStep.
|
|
72
|
+
* - `authStatus: 'expired'` → an `auth.json` is present but its OAuth
|
|
73
|
+
* session has expired (or the file is malformed) → ready=false with a
|
|
74
|
+
* re-login nextStep. Distinct from `not_configured` so a logged-out
|
|
75
|
+
* operator with a leftover file is not treated as ready (#366).
|
|
76
|
+
* - otherwise → ready=true.
|
|
77
|
+
*/
|
|
78
|
+
codexIsReady() {
|
|
79
|
+
const config = {};
|
|
80
|
+
if (this.codexPath !== undefined)
|
|
81
|
+
config.codexPath = this.codexPath;
|
|
82
|
+
if (this.codexDoctorTimeoutMs !== undefined) {
|
|
83
|
+
config.codexDoctorTimeoutMs = this.codexDoctorTimeoutMs;
|
|
84
|
+
}
|
|
85
|
+
const result = probeCodexDoctor(config);
|
|
86
|
+
if (!result.installed) {
|
|
87
|
+
return {
|
|
88
|
+
ready: false,
|
|
89
|
+
reason: 'codex binary not installed',
|
|
90
|
+
nextStep: {
|
|
91
|
+
description: 'Install the Codex CLI — see the Codex precheck panel in the operator dashboard for the install command.',
|
|
92
|
+
url: '/api/codex/doctor',
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (result.exitCode !== 0) {
|
|
97
|
+
const stderr = result.stderr.trim();
|
|
98
|
+
const stdout = result.stdout.trim();
|
|
99
|
+
const detail = stderr.length > 0 ? stderr : stdout;
|
|
100
|
+
return {
|
|
101
|
+
ready: false,
|
|
102
|
+
reason: `codex --version exit ${result.exitCode}${detail ? `: ${detail}` : ''}`,
|
|
103
|
+
nextStep: {
|
|
104
|
+
description: 'Run `codex --version` locally to surface the problem, or open the Codex precheck panel in the operator dashboard.',
|
|
105
|
+
url: '/api/codex/doctor',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (this.codexBaseUrl) {
|
|
110
|
+
if (isLocalCodexBaseUrl(this.codexBaseUrl)) {
|
|
111
|
+
return { ready: true };
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
ready: false,
|
|
115
|
+
reason: 'codex base URL must be local',
|
|
116
|
+
nextStep: {
|
|
117
|
+
description: 'Use a local Codex provider URL such as http://127.0.0.1:11434/v1 or unset JINN_CODEX_BASE_URL.',
|
|
118
|
+
url: '/api/codex/doctor',
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (result.authStatus === 'expired') {
|
|
123
|
+
return {
|
|
124
|
+
ready: false,
|
|
125
|
+
reason: 'codex auth expired',
|
|
126
|
+
nextStep: {
|
|
127
|
+
description: 'Codex sign-in has expired — run `codex login` to refresh the session (or set OPENAI_API_KEY), then re-check the Codex precheck panel in the operator dashboard.',
|
|
128
|
+
url: '/api/codex/doctor',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (result.authStatus !== 'ok') {
|
|
133
|
+
return {
|
|
134
|
+
ready: false,
|
|
135
|
+
reason: 'codex auth not configured',
|
|
136
|
+
nextStep: {
|
|
137
|
+
description: 'Sign in to Codex — set OPENAI_API_KEY or run `codex login`, then re-check the Codex precheck panel in the operator dashboard.',
|
|
138
|
+
url: '/api/codex/doctor',
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return { ready: true };
|
|
143
|
+
}
|
|
32
144
|
supports(spec) {
|
|
33
145
|
if (spec.role === 'evaluation')
|
|
34
146
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/harness.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/harness.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAM1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IAChB,IAAI,CAAS;IACb,OAAO,CAAS;IACR,OAAO,CAAiB;IACxB,UAAU,CAAS;IACnB,UAAU,CAAS;IACnB,SAAS,CAAqB;IAC9B,YAAY,CAAqB;IACjC,oBAAoB,CAAqB;IACzC,WAAW,CAA0C;IAEtE,YAAY,MAA4B;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,mBAAmB,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,YAAY,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,iBAAiB,EAAE,CAAC;QAC3D,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,oBAAoB,CAAC;QACxD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC;IAClD,CAAC;IAEgB,aAAa,GAAG,kBAAkB,CAAC;QAClD,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU;QACpC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW;KACnC,CAAC,CAAC;IAEH;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,OAAO,CACX,GAAiE;QAEjE,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,aAAa,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;QAC7B,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACK,YAAY;QAClB,MAAM,MAAM,GAA0D,EAAE,CAAC;QACzE,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACpE,IAAI,IAAI,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC;QAC1D,CAAC;QACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,4BAA4B;gBACpC,QAAQ,EAAE;oBACR,WAAW,EACT,yGAAyG;oBAC3G,GAAG,EAAE,mBAAmB;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;YACnD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,wBAAwB,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC/E,QAAQ,EAAE;oBACR,WAAW,EACT,mHAAmH;oBACrH,GAAG,EAAE,mBAAmB;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC3C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACzB,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,8BAA8B;gBACtC,QAAQ,EAAE;oBACR,WAAW,EACT,gGAAgG;oBAClG,GAAG,EAAE,mBAAmB;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,oBAAoB;gBAC5B,QAAQ,EAAE;oBACR,WAAW,EACT,iKAAiK;oBACnK,GAAG,EAAE,mBAAmB;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC/B,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,2BAA2B;gBACnC,QAAQ,EAAE;oBACR,WAAW,EACT,+HAA+H;oBACjI,GAAG,EAAE,mBAAmB;iBACzB;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,QAAQ,CAAC,IAAiE;QACxE,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAC7C,uEAAuE;QACvE,2EAA2E;QAC3E,2EAA2E;QAC3E,sDAAsD;QACtD,EAAE;QACF,wEAAwE;QACxE,yEAAyE;QACzE,gEAAgE;QAChE,oEAAoE;QACpE,gEAAgE;QAChE,8EAA8E;QAC9E,0CAA0C;QAC1C,EAAE;QACF,4DAA4D;QAC5D,2EAA2E;QAC3E,sEAAsE;QACtE,sEAAsE;QACtE,kCAAkC;QAClC,IAAI,IAAI,CAAC,UAAU,KAAK,eAAe,IAAI,IAAI,CAAC,UAAU,KAAK,mBAAmB,EAAE,CAAC;YACnF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAmB;QAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAsB;YAChC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU;YAC/B,KAAK,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK;YAC3B,WAAW,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK;YACjC,QAAQ,EAAE,GAAG,CAAC,IAAqC;YACnD,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;YAC/C,aAAa,EAAE,MAAM,CAAC,OAAO;YAC7B,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,YAAY,EAAE,GAAG,CAAC,YAAY,EAAE;YAChC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;QAEF,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1E,OAAO;YACL,GAAG,QAAQ;YACX,QAAQ,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;SACpD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1,14 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolve the learner plugin root from the impl directory's
|
|
3
|
-
* runtime location.
|
|
4
|
-
*
|
|
5
|
-
* Layout assumption: this file lives at
|
|
6
|
-
* <package>/<src-or-dist>/harnesses/impls/learner/plugin-path.{ts,js}
|
|
7
|
-
* and the plugin lives at
|
|
8
|
-
* <package>/plugins/learner/
|
|
9
|
-
*
|
|
10
|
-
* Walks up four directories from this file (impls → harness → src/dist →
|
|
11
|
-
* package root) then descends into plugins/learner/. Verifies the
|
|
12
|
-
* expected layout exists and throws with a clear message if not.
|
|
13
|
-
*/
|
|
14
1
|
export declare function resolvePluginRoot(): string;
|
|
@@ -2,29 +2,49 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
/**
|
|
5
|
-
* Resolve the learner plugin root from the impl directory's
|
|
6
|
-
* runtime location.
|
|
5
|
+
* Resolve the learner plugin root from the impl directory's runtime location.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
* <package
|
|
10
|
-
* and the plugin
|
|
11
|
-
* <package>/plugins/learner/
|
|
7
|
+
* Canonical layout (compiled): this file lives at
|
|
8
|
+
* <package>/dist/harnesses/impls/learner/plugin-path.js
|
|
9
|
+
* and the plugin tree is co-located inside dist/:
|
|
10
|
+
* <package>/dist/plugins/learner/
|
|
12
11
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* The build step copies plugins/learner → dist/plugins/learner so the
|
|
13
|
+
* compiled code and the plugin runtime assets are always version-locked
|
|
14
|
+
* within the same dist/ tree — for published npm installs and source
|
|
15
|
+
* checkouts alike (after `yarn build`).
|
|
16
|
+
*
|
|
17
|
+
* Source-checkout / tsx path (e.g. vitest): this file lives at
|
|
18
|
+
* <package>/src/harnesses/impls/learner/plugin-path.ts
|
|
19
|
+
* Walking up four directories reaches the package root, and the plugin
|
|
20
|
+
* lives at <package>/plugins/learner/.
|
|
21
|
+
*
|
|
22
|
+
* Detection: if the resolved path three levels up ends with `/dist` the
|
|
23
|
+
* runtime is inside a compiled dist tree; otherwise fall back to the
|
|
24
|
+
* package-root layout (four levels up).
|
|
16
25
|
*/
|
|
26
|
+
function requireAsset(pluginRoot, relative, hint) {
|
|
27
|
+
if (!existsSync(join(pluginRoot, relative))) {
|
|
28
|
+
const suffix = hint ? ` — ${hint}` : '';
|
|
29
|
+
throw new Error(`learner plugin at ${pluginRoot} is missing ${relative}${suffix}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
17
32
|
export function resolvePluginRoot() {
|
|
18
33
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
const
|
|
20
|
-
|
|
34
|
+
const threeUp = resolve(here, '..', '..', '..');
|
|
35
|
+
// Compiled dist layout: dist/harnesses/impls/learner → dist/ → dist/plugins/learner
|
|
36
|
+
const isDistTree = threeUp.endsWith('/dist');
|
|
37
|
+
const pluginRoot = isDistTree
|
|
38
|
+
? join(threeUp, 'plugins', 'learner')
|
|
39
|
+
: join(resolve(here, '..', '..', '..', '..'), 'plugins', 'learner');
|
|
21
40
|
if (!existsSync(pluginRoot)) {
|
|
22
41
|
throw new Error(`learner plugin not found at expected path: ${pluginRoot}. ` +
|
|
23
|
-
`Resolved from impl dir: ${here}
|
|
24
|
-
|
|
25
|
-
if (!existsSync(join(pluginRoot, 'skills', 'learn', 'SKILL.md'))) {
|
|
26
|
-
throw new Error(`learner plugin at ${pluginRoot} is missing skills/learn/SKILL.md`);
|
|
42
|
+
`Resolved from impl dir: ${here}. ` +
|
|
43
|
+
`Run \`yarn build\` to copy plugins/learner into dist/plugins/learner.`);
|
|
27
44
|
}
|
|
45
|
+
requireAsset(pluginRoot, 'skills/learn/SKILL.md');
|
|
46
|
+
requireAsset(pluginRoot, 'hooks/session-start', 'plugin assets may be stale or incomplete; rebuild the plugin');
|
|
47
|
+
requireAsset(pluginRoot, 'hooks/hooks.json', 'plugin assets may be stale or incomplete; rebuild the plugin');
|
|
28
48
|
return pluginRoot;
|
|
29
49
|
}
|
|
30
50
|
//# sourceMappingURL=plugin-path.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-path.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/plugin-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC
|
|
1
|
+
{"version":3,"file":"plugin-path.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/plugin-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,YAAY,CAAC,UAAkB,EAAE,QAAgB,EAAE,IAAa;IACvE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,eAAe,QAAQ,GAAG,MAAM,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAEhD,oFAAoF;IACpF,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,UAAU;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAEtE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8CAA8C,UAAU,IAAI;YAC1D,2BAA2B,IAAI,IAAI;YACnC,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,YAAY,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAClD,YAAY,CAAC,UAAU,EAAE,qBAAqB,EAAE,8DAA8D,CAAC,CAAC;IAChH,YAAY,CAAC,UAAU,EAAE,kBAAkB,EAAE,8DAA8D,CAAC,CAAC;IAC7G,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -121,4 +121,19 @@ export interface LearnerHarnessConfig {
|
|
|
121
121
|
* Defaults to 'bare'.
|
|
122
122
|
*/
|
|
123
123
|
runtimeMode?: 'bare' | 'container' | 'docker-compose';
|
|
124
|
+
/**
|
|
125
|
+
* Path to the `codex` executable. Used by `isReady()` when this
|
|
126
|
+
* `LearnerHarness` is the Codex variant (`name === CODEX_HARNESS`) — it is
|
|
127
|
+
* passed to `probeCodexDoctor()`. Defaults to 'codex' (from PATH).
|
|
128
|
+
*/
|
|
129
|
+
codexPath?: string;
|
|
130
|
+
/** Default Codex model when a SolverNet does not specify one. */
|
|
131
|
+
codexModel?: string;
|
|
132
|
+
/** Local OpenAI-compatible Codex provider base URL. */
|
|
133
|
+
codexBaseUrl?: string;
|
|
134
|
+
/**
|
|
135
|
+
* Timeout (ms) for the `codex --version` probe in the Codex variant's
|
|
136
|
+
* `isReady()`. Defaults to 30s.
|
|
137
|
+
*/
|
|
138
|
+
codexDoctorTimeoutMs?: number;
|
|
124
139
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env-gated stub harness for the T2.2 producer/evaluator gate.
|
|
3
|
+
*
|
|
4
|
+
* When JINN_HARNESS_STUB_INSTANCE is set, the canned patch at
|
|
5
|
+
* <fixturesDir>/<instanceMatcher>.patch is returned as a SWE-rebench v2
|
|
6
|
+
* restoration solution. Never calls an LLM; never accepts tasks whose
|
|
7
|
+
* spec.instance_id differs from the configured matcher.
|
|
8
|
+
*
|
|
9
|
+
* PRODUCTION SAFETY — two-env-var requirement.
|
|
10
|
+
* This is a *fake* harness: it produces canned, non-genuine work. If it ever
|
|
11
|
+
* entered a real operator run it would generate fraudulent on-chain activity.
|
|
12
|
+
* To make accidental activation impossible, the factory requires BOTH:
|
|
13
|
+
* JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to
|
|
14
|
+
* JINN_TEST_MODE === '1' — explicit test-mode sentinel
|
|
15
|
+
* If JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not '1', the
|
|
16
|
+
* factory THROWS rather than silently registering the stub. A single stray
|
|
17
|
+
* exported env var in an operator's shell can no longer activate it.
|
|
18
|
+
*
|
|
19
|
+
* Activated by environment variables:
|
|
20
|
+
* JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to (required to activate)
|
|
21
|
+
* JINN_TEST_MODE — must equal '1' (defense-in-depth; required to activate)
|
|
22
|
+
* JINN_HARNESS_STUB_FIXTURES_DIR — dir containing <instanceMatcher>.patch files
|
|
23
|
+
* (default: client/test/release/tier-2/fixtures)
|
|
24
|
+
*/
|
|
25
|
+
import type { Harness, HarnessContext, ReadyStatus, Solution } from '../types.js';
|
|
26
|
+
export interface StubHarnessConfig {
|
|
27
|
+
/** Directory containing <instanceMatcher>.patch files. */
|
|
28
|
+
fixturesDir: string;
|
|
29
|
+
/** The instance ID this stub will accept. Tasks with other instance IDs are rejected. */
|
|
30
|
+
instanceMatcher: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A zero-LLM Harness that returns a canned patch for a specific SWE-rebench v2
|
|
34
|
+
* instance. Intended exclusively for T2.2 release-gate automation.
|
|
35
|
+
*/
|
|
36
|
+
export declare class StubHarness implements Harness {
|
|
37
|
+
readonly name = "harness:stub";
|
|
38
|
+
readonly version = "0.1.0-stub";
|
|
39
|
+
private readonly fixturesDir;
|
|
40
|
+
private readonly instanceMatcher;
|
|
41
|
+
constructor(config: StubHarnessConfig);
|
|
42
|
+
supports(ctx: {
|
|
43
|
+
solverType: string;
|
|
44
|
+
role?: 'restoration' | 'evaluation';
|
|
45
|
+
}): boolean;
|
|
46
|
+
isReady(): Promise<ReadyStatus>;
|
|
47
|
+
run(ctx: HarnessContext): Promise<Solution>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Factory that reads JINN_HARNESS_STUB_INSTANCE and JINN_HARNESS_STUB_FIXTURES_DIR
|
|
51
|
+
* from the environment and returns a configured StubHarness, or null if the env
|
|
52
|
+
* var is absent (allowing the registry to skip registration silently).
|
|
53
|
+
*
|
|
54
|
+
* Defense-in-depth: if JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is
|
|
55
|
+
* not exactly '1', this THROWS rather than returning a harness — a real
|
|
56
|
+
* operator run must never silently pick up the fake stub harness.
|
|
57
|
+
*/
|
|
58
|
+
export declare function maybeCreateStubHarnessFromEnv(): StubHarness | null;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env-gated stub harness for the T2.2 producer/evaluator gate.
|
|
3
|
+
*
|
|
4
|
+
* When JINN_HARNESS_STUB_INSTANCE is set, the canned patch at
|
|
5
|
+
* <fixturesDir>/<instanceMatcher>.patch is returned as a SWE-rebench v2
|
|
6
|
+
* restoration solution. Never calls an LLM; never accepts tasks whose
|
|
7
|
+
* spec.instance_id differs from the configured matcher.
|
|
8
|
+
*
|
|
9
|
+
* PRODUCTION SAFETY — two-env-var requirement.
|
|
10
|
+
* This is a *fake* harness: it produces canned, non-genuine work. If it ever
|
|
11
|
+
* entered a real operator run it would generate fraudulent on-chain activity.
|
|
12
|
+
* To make accidental activation impossible, the factory requires BOTH:
|
|
13
|
+
* JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to
|
|
14
|
+
* JINN_TEST_MODE === '1' — explicit test-mode sentinel
|
|
15
|
+
* If JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not '1', the
|
|
16
|
+
* factory THROWS rather than silently registering the stub. A single stray
|
|
17
|
+
* exported env var in an operator's shell can no longer activate it.
|
|
18
|
+
*
|
|
19
|
+
* Activated by environment variables:
|
|
20
|
+
* JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to (required to activate)
|
|
21
|
+
* JINN_TEST_MODE — must equal '1' (defense-in-depth; required to activate)
|
|
22
|
+
* JINN_HARNESS_STUB_FIXTURES_DIR — dir containing <instanceMatcher>.patch files
|
|
23
|
+
* (default: client/test/release/tier-2/fixtures)
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from 'node:fs/promises';
|
|
26
|
+
import * as path from 'node:path';
|
|
27
|
+
/**
|
|
28
|
+
* A zero-LLM Harness that returns a canned patch for a specific SWE-rebench v2
|
|
29
|
+
* instance. Intended exclusively for T2.2 release-gate automation.
|
|
30
|
+
*/
|
|
31
|
+
export class StubHarness {
|
|
32
|
+
name = 'harness:stub';
|
|
33
|
+
version = '0.1.0-stub';
|
|
34
|
+
fixturesDir;
|
|
35
|
+
instanceMatcher;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.fixturesDir = config.fixturesDir;
|
|
38
|
+
this.instanceMatcher = config.instanceMatcher;
|
|
39
|
+
}
|
|
40
|
+
supports(ctx) {
|
|
41
|
+
if (ctx.role === 'evaluation')
|
|
42
|
+
return false;
|
|
43
|
+
return ctx.solverType === 'swe-rebench-v2.v1';
|
|
44
|
+
}
|
|
45
|
+
async isReady() {
|
|
46
|
+
return { ready: true };
|
|
47
|
+
}
|
|
48
|
+
async run(ctx) {
|
|
49
|
+
const taskInstanceId = ctx.task.spec?.['instance_id'];
|
|
50
|
+
if (taskInstanceId !== this.instanceMatcher) {
|
|
51
|
+
throw new Error(`stub harness: task.spec.instance_id=${String(taskInstanceId)} does not match configured instanceMatcher=${this.instanceMatcher}`);
|
|
52
|
+
}
|
|
53
|
+
const patchPath = path.join(this.fixturesDir, `${this.instanceMatcher}.patch`);
|
|
54
|
+
const patch = await fs.readFile(patchPath, 'utf-8');
|
|
55
|
+
return {
|
|
56
|
+
venueRef: { name: this.name },
|
|
57
|
+
gating: {},
|
|
58
|
+
solutionPayload: {
|
|
59
|
+
schemaVersion: 'swe-rebench-v2-solution.v1',
|
|
60
|
+
patch,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Factory that reads JINN_HARNESS_STUB_INSTANCE and JINN_HARNESS_STUB_FIXTURES_DIR
|
|
67
|
+
* from the environment and returns a configured StubHarness, or null if the env
|
|
68
|
+
* var is absent (allowing the registry to skip registration silently).
|
|
69
|
+
*
|
|
70
|
+
* Defense-in-depth: if JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is
|
|
71
|
+
* not exactly '1', this THROWS rather than returning a harness — a real
|
|
72
|
+
* operator run must never silently pick up the fake stub harness.
|
|
73
|
+
*/
|
|
74
|
+
export function maybeCreateStubHarnessFromEnv() {
|
|
75
|
+
const instanceMatcher = process.env['JINN_HARNESS_STUB_INSTANCE'];
|
|
76
|
+
if (!instanceMatcher)
|
|
77
|
+
return null;
|
|
78
|
+
if (process.env['JINN_TEST_MODE'] !== '1') {
|
|
79
|
+
throw new Error('stub harness must never activate in a real operator run: ' +
|
|
80
|
+
'JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not "1". ' +
|
|
81
|
+
'The stub harness produces canned, non-genuine work and would generate ' +
|
|
82
|
+
'fraudulent on-chain activity. Set JINN_TEST_MODE=1 if this is a Tier 2 ' +
|
|
83
|
+
'test; otherwise unset JINN_HARNESS_STUB_INSTANCE.');
|
|
84
|
+
}
|
|
85
|
+
const fixturesDir = process.env['JINN_HARNESS_STUB_FIXTURES_DIR'] ??
|
|
86
|
+
path.resolve(process.cwd(), 'test', 'release', 'tier-2', 'fixtures');
|
|
87
|
+
return new StubHarness({ instanceMatcher, fixturesDir });
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=stub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stub.js","sourceRoot":"","sources":["../../../src/harnesses/impls/stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAUlC;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,IAAI,GAAG,cAAc,CAAC;IACtB,OAAO,GAAG,YAAY,CAAC;IAEf,WAAW,CAAS;IACpB,eAAe,CAAS;IAEzC,YAAY,MAAyB;QACnC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,GAAgE;QACvE,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAC5C,OAAO,GAAG,CAAC,UAAU,KAAK,mBAAmB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAmB;QAC3B,MAAM,cAAc,GAAI,GAAG,CAAC,IAAI,CAAC,IAA4C,EAAE,CAAC,aAAa,CAAC,CAAC;QAC/F,IAAI,cAAc,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb,uCAAuC,MAAM,CAAC,cAAc,CAAC,8CAA8C,IAAI,CAAC,eAAe,EAAE,CAClI,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,eAAe,QAAQ,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO;YACL,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAC7B,MAAM,EAAE,EAAE;YACV,eAAe,EAAE;gBACf,aAAa,EAAE,4BAA4B;gBAC3C,KAAK;aACN;SACF,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,6BAA6B;IAC3C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAClE,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,2DAA2D;YACzD,mEAAmE;YACnE,wEAAwE;YACxE,yEAAyE;YACzE,mDAAmD,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvE,OAAO,IAAI,WAAW,CAAC,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -37,6 +37,36 @@ export declare class EvalCouldNotGradeError extends Error {
|
|
|
37
37
|
readonly logExcerpt: string;
|
|
38
38
|
constructor(reason: string, logExcerpt?: string);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Thrown by `runEval` when the disk cannot be brought above the eval
|
|
42
|
+
* disk-floor even after a broad prune. A clean abort — the caller stops
|
|
43
|
+
* gracefully; no instance is graded, nothing is marked. Distinct from
|
|
44
|
+
* `EvalCouldNotGradeError`: this is operator-environment, retryable, and must
|
|
45
|
+
* never be turned into a `scorable: false` admission (#476).
|
|
46
|
+
*/
|
|
47
|
+
export declare class InsufficientDiskError extends Error {
|
|
48
|
+
readonly freeBytes: number;
|
|
49
|
+
readonly floorBytes: number;
|
|
50
|
+
constructor(freeBytes: number, floorBytes: number);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Default free-disk floor required before an eval round: 20 GB. A single
|
|
54
|
+
* SWE-rebench eval image was observed to peak transiently at ~12.6 GB, so the
|
|
55
|
+
* floor clears the worst observed instance with real margin. Override with
|
|
56
|
+
* `JINN_EVAL_DISK_FLOOR_GB` on constrained hosts.
|
|
57
|
+
*/
|
|
58
|
+
export declare const DEFAULT_EVAL_DISK_FLOOR_BYTES = 20000000000;
|
|
59
|
+
/** Resolve the disk floor: explicit option > `JINN_EVAL_DISK_FLOOR_GB` env > default. */
|
|
60
|
+
export declare function resolveDiskFloorBytes(opt: number | undefined): number;
|
|
61
|
+
/**
|
|
62
|
+
* Default wall-clock limit for one upstream eval.py invocation: 2 hours. Some
|
|
63
|
+
* linux/amd64 SWE-rebench images can wedge indefinitely under Apple Silicon
|
|
64
|
+
* emulation after a native crash, so the subprocess gets a hard guardrail.
|
|
65
|
+
* Override with `JINN_SWE_REBENCH_EVAL_TIMEOUT_MS`; set `0` to disable.
|
|
66
|
+
*/
|
|
67
|
+
export declare const DEFAULT_EVAL_TIMEOUT_MS: number;
|
|
68
|
+
/** Resolve the eval timeout: explicit option > env > default. */
|
|
69
|
+
export declare function resolveEvalTimeoutMs(opt: number | undefined): number;
|
|
40
70
|
export interface PythonEvalRunnerOptions {
|
|
41
71
|
/** Path to the cloned SWE-rebench-V2 repo (cached locally). */
|
|
42
72
|
upstreamRepoDir: string;
|
|
@@ -45,66 +75,55 @@ export interface PythonEvalRunnerOptions {
|
|
|
45
75
|
/** Workers for parallel eval (defaults to 1; we run one task at a time). */
|
|
46
76
|
maxWorkers?: number;
|
|
47
77
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* The leaderboard pool has hundreds of unique instances at ~3 GB/image, so
|
|
54
|
-
* an unbounded cache fills operator disks in days (jinn-mono-uy6v.11).
|
|
78
|
+
* Removes a completed round's entire Docker footprint — the round's image,
|
|
79
|
+
* stopped containers, and build cache — so eval disk usage never
|
|
80
|
+
* accumulates across instances (#476). Called once per `runEval`, in a
|
|
81
|
+
* `finally`, even when the eval threw.
|
|
55
82
|
*
|
|
56
|
-
*
|
|
57
|
-
* `
|
|
83
|
+
* Defaults to {@link defaultPruneRound}. Implementations MUST NOT throw —
|
|
84
|
+
* `runEval` guards defensively, but cleanup failures should be swallowed
|
|
85
|
+
* (logged elsewhere if desired) so a flaky `docker` never escapes `runEval`.
|
|
58
86
|
*/
|
|
59
|
-
|
|
87
|
+
pruneRound?: (image: string) => Promise<void>;
|
|
60
88
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* elsewhere if desired) so a missing/failed `docker rmi` never escapes
|
|
69
|
-
* `runEval`. The runner enforces this defensively too.
|
|
89
|
+
* Resolves the eval image digest while the image is still local, before
|
|
90
|
+
* per-round pruning removes it. Defaults to `docker image inspect`.
|
|
91
|
+
*/
|
|
92
|
+
resolveImageDigest?: (image: string) => Promise<string | null>;
|
|
93
|
+
/**
|
|
94
|
+
* Required free disk (bytes) before an eval round starts. Explicit value >
|
|
95
|
+
* `JINN_EVAL_DISK_FLOOR_GB` env > {@link DEFAULT_EVAL_DISK_FLOOR_BYTES}.
|
|
70
96
|
*/
|
|
71
|
-
|
|
97
|
+
diskFloorBytes?: number;
|
|
98
|
+
/** Probe of free disk (bytes). Defaults to a `statfs` on the temp dir. */
|
|
99
|
+
freeDiskBytes?: () => Promise<number>;
|
|
100
|
+
/**
|
|
101
|
+
* Broad reclaim invoked when free disk is below the floor. Defaults to
|
|
102
|
+
* `docker system prune -f`. MUST NOT throw.
|
|
103
|
+
*/
|
|
104
|
+
systemPrune?: () => Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Wall-clock timeout (ms) for one upstream eval.py invocation. Explicit value
|
|
107
|
+
* > `JINN_SWE_REBENCH_EVAL_TIMEOUT_MS` env > {@link DEFAULT_EVAL_TIMEOUT_MS}.
|
|
108
|
+
* Set to 0 to disable.
|
|
109
|
+
*/
|
|
110
|
+
evalTimeoutMs?: number;
|
|
72
111
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Default cap on the per-instance Docker image cache when no explicit
|
|
75
|
-
* `imageCacheMax` and no `JINN_EVAL_IMAGE_CACHE_MAX` env var are configured.
|
|
76
|
-
*
|
|
77
|
-
* 20 images × ~3 GB/image ≈ 60 GB working set — small enough that even a
|
|
78
|
-
* 256 GB disk has headroom, large enough that the steady-state loop on a
|
|
79
|
-
* frequently-repeating subset of the pool rarely re-pulls.
|
|
80
|
-
*/
|
|
81
|
-
export declare const DEFAULT_EVAL_IMAGE_CACHE_MAX = 20;
|
|
82
|
-
export declare function resolveImageCacheMax(opt: number | undefined): number;
|
|
83
112
|
export declare function matchInfraSignature(log: string): string | null;
|
|
84
113
|
export declare class PythonEvalRunner implements EvalRunner {
|
|
85
114
|
private readonly opts;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
private readonly imageLru;
|
|
93
|
-
private readonly imageCacheMax;
|
|
94
|
-
private readonly cleanupImage;
|
|
115
|
+
private readonly pruneRound;
|
|
116
|
+
private readonly diskFloorBytes;
|
|
117
|
+
private readonly freeDiskBytes;
|
|
118
|
+
private readonly systemPrune;
|
|
119
|
+
private readonly resolveImageDigest;
|
|
120
|
+
private readonly evalTimeoutMs;
|
|
95
121
|
constructor(opts: PythonEvalRunnerOptions);
|
|
96
|
-
runEval(args: Parameters<EvalRunner['runEval']>[0]): ReturnType<EvalRunner['runEval']>;
|
|
97
122
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* {@link cleanupImage}. Eviction failures are swallowed so a flaky
|
|
101
|
-
* `docker rmi` cannot escape `runEval`.
|
|
102
|
-
*
|
|
103
|
-
* The cap is enforced after the just-used image is inserted: the
|
|
104
|
-
* just-evaluated image is the *most* recent, so repeat-evals of recently
|
|
105
|
-
* used instances never re-pull. Only when more than N distinct images have
|
|
106
|
-
* been used does the oldest get rmi'd.
|
|
123
|
+
* Ensure enough free disk for an eval round. Below the floor → broad prune →
|
|
124
|
+
* re-probe; still below → `InsufficientDiskError` (clean abort). (#476)
|
|
107
125
|
*/
|
|
108
|
-
private
|
|
126
|
+
private ensureDiskHeadroom;
|
|
127
|
+
runEval(args: Parameters<EvalRunner['runEval']>[0]): ReturnType<EvalRunner['runEval']>;
|
|
109
128
|
private runEvalImpl;
|
|
110
129
|
}
|