@jinn-network/client 0.1.6 → 0.1.7
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 +400 -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 +72 -0
- package/dist/api/status-build.js +73 -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 +106 -5
- package/dist/config.js +97 -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-BUlE8F3Y.js +330 -0
- package/dist/dashboard/assets/index-blqc7eqq.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 +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 +7 -0
- package/dist/harnesses/impls/index.js +16 -1
- package/dist/harnesses/impls/index.js.map +1 -1
- package/dist/harnesses/impls/learner/harness.d.ts +38 -4
- package/dist/harnesses/impls/learner/harness.js +96 -2
- package/dist/harnesses/impls/learner/harness.js.map +1 -1
- package/dist/harnesses/impls/learner/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 +11 -0
- package/dist/harnesses/impls/stub.d.ts +58 -0
- package/dist/harnesses/impls/stub.js +89 -0
- package/dist/harnesses/impls/stub.js.map +1 -0
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +69 -50
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +178 -93
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.d.ts +12 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +121 -7
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
- package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +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 +371 -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
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
* `installed: false` means the binary was not found (ENOENT or equivalent).
|
|
12
12
|
* `exitCode !== 0` (with `installed: true`) means the binary exists but
|
|
13
13
|
* reports a config problem.
|
|
14
|
+
*
|
|
15
|
+
* The probe logic is exported as `probeHermesDoctor` so the Hermes harness
|
|
16
|
+
* can reuse it from `isReady()` — same source of truth for the SPA
|
|
17
|
+
* precheck panel and the daemon's claim-readiness gate (#330).
|
|
14
18
|
*/
|
|
15
19
|
import type { Hono } from 'hono';
|
|
16
20
|
export interface HermesDoctorResponse {
|
|
@@ -23,4 +27,117 @@ export interface HermesDoctorConfig {
|
|
|
23
27
|
hermesPath?: string;
|
|
24
28
|
hermesDoctorTimeoutMs?: number;
|
|
25
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Synchronously runs `hermes doctor` and classifies the result. Pure (no
|
|
32
|
+
* Hono dependency) so the harness layer can call it without pulling the API
|
|
33
|
+
* server in.
|
|
34
|
+
*/
|
|
35
|
+
export declare function probeHermesDoctor(config?: HermesDoctorConfig): HermesDoctorResponse;
|
|
36
|
+
/**
|
|
37
|
+
* Result of probing a single Hermes model provider's auth state.
|
|
38
|
+
*/
|
|
39
|
+
export interface HermesAuthStatus {
|
|
40
|
+
/** Provider name probed, e.g. `openrouter`. */
|
|
41
|
+
provider: string;
|
|
42
|
+
/** True only when the provider has a usable credential. */
|
|
43
|
+
authed: boolean;
|
|
44
|
+
/** Raw `hermes auth list <provider>` stdout (trimmed, truncated). */
|
|
45
|
+
raw: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Synchronously runs `hermes auth list <provider>` and classifies whether the
|
|
49
|
+
* provider has a usable credential (API-key OR OAuth) in Hermes's credential
|
|
50
|
+
* pool.
|
|
51
|
+
*
|
|
52
|
+
* WHY `auth list`, not `auth status`: `hermes auth status <provider>` only
|
|
53
|
+
* reflects interactive-OAuth-login state (the `providers` block in
|
|
54
|
+
* `~/.hermes/auth.json`). It prints `<provider>: logged out` whenever there
|
|
55
|
+
* is no OAuth session — even when an API-key credential is present and
|
|
56
|
+
* working. An operator who authenticated to OpenRouter the normal way
|
|
57
|
+
* (`OPENROUTER_API_KEY` env var, or `hermes auth add`) would be wrongly
|
|
58
|
+
* reported not-ready and gated out of every claim. `hermes auth list` reads
|
|
59
|
+
* the `credential_pool`, so it sees api_key credentials too.
|
|
60
|
+
*
|
|
61
|
+
* Parsing (`auth list <provider>` output, see `auth_list_command` in
|
|
62
|
+
* hermes_cli/auth_commands.py):
|
|
63
|
+
* - empty stdout → no credential of any kind → not authed
|
|
64
|
+
* - a `<provider> (N credentials):` header followed by ` #<idx> ...` lines,
|
|
65
|
+
* one per pooled credential → authed iff at least one line is *usable*
|
|
66
|
+
* (not exhausted with a wait window still open, not a hard auth failure)
|
|
67
|
+
* - ENOENT / spawn error → not authed (binary not on PATH)
|
|
68
|
+
*
|
|
69
|
+
* `hermes auth list` exits 0 in all of these cases; the signal is entirely in
|
|
70
|
+
* stdout. Pure (no Hono dependency) so the harness layer can call it without
|
|
71
|
+
* pulling the API server in. This is the third readiness gate for Hermes:
|
|
72
|
+
* `hermes doctor` exits 0 even when every provider is logged out (it treats
|
|
73
|
+
* missing providers as warnings), so the harness must probe auth directly.
|
|
74
|
+
*/
|
|
75
|
+
export declare function probeHermesAuthStatus(provider: string, config?: HermesDoctorConfig): HermesAuthStatus;
|
|
26
76
|
export declare function addHermesDoctorRoutes(app: Hono, config?: HermesDoctorConfig): void;
|
|
77
|
+
/**
|
|
78
|
+
* Result of probing OpenRouter's `/api/v1/key` endpoint for spendable credit.
|
|
79
|
+
*
|
|
80
|
+
* `state` is the verdict we feed into readiness:
|
|
81
|
+
* - `ok` → remaining credit is at or above the floor → ready
|
|
82
|
+
* - `exhausted` → remaining credit is below the floor → NOT ready (clear
|
|
83
|
+
* actionable signal: operator must top up)
|
|
84
|
+
* - `unknown` → couldn't determine — network error, non-200, malformed
|
|
85
|
+
* JSON, missing API key. Readiness MUST treat this as
|
|
86
|
+
* fail-safe (ready=true) so a transient OpenRouter outage
|
|
87
|
+
* does not shut every operator down (#332 / production
|
|
88
|
+
* bug 2026-05-23: false-positive ready when credit
|
|
89
|
+
* exhausted, but we explicitly do NOT want the inverse
|
|
90
|
+
* false-negative).
|
|
91
|
+
*
|
|
92
|
+
* `remainingUsd` and `floorUsd` are populated when known (state=`ok` or
|
|
93
|
+
* `exhausted`) so the readiness `nextStep` can show the operator how short
|
|
94
|
+
* they are. `raw` carries the truncated response body for diagnostics.
|
|
95
|
+
*/
|
|
96
|
+
export interface OpenRouterCreditStatus {
|
|
97
|
+
state: 'ok' | 'exhausted' | 'unknown';
|
|
98
|
+
remainingUsd?: number;
|
|
99
|
+
limitUsd?: number | null;
|
|
100
|
+
usageUsd?: number;
|
|
101
|
+
floorUsd: number;
|
|
102
|
+
reason?: string;
|
|
103
|
+
raw?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface OpenRouterCreditConfig {
|
|
106
|
+
/**
|
|
107
|
+
* Per-task credit floor in USD. The default is generous enough to cover a
|
|
108
|
+
* single SWE-rebench solve with `max_tokens=32000` against the priciest
|
|
109
|
+
* frontier models at typical 2026 OpenRouter rates ($3-$5 / Mtok output =
|
|
110
|
+
* $0.10-$0.16 per solve), with headroom for input-token cost and the
|
|
111
|
+
* occasional retry. Tune via the env override below if a SolverNet pins
|
|
112
|
+
* a different model class.
|
|
113
|
+
*/
|
|
114
|
+
floorUsd?: number;
|
|
115
|
+
/** Override the OpenRouter API key (defaults to `process.env.OPENROUTER_API_KEY`). */
|
|
116
|
+
apiKey?: string;
|
|
117
|
+
/** Inject a custom fetch for tests; defaults to global `fetch`. */
|
|
118
|
+
fetchFn?: typeof fetch;
|
|
119
|
+
/** HTTP timeout in ms. Defaults to 5s — readiness probes must not stall the daemon. */
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
}
|
|
122
|
+
export declare const DEFAULT_OPENROUTER_CREDIT_FLOOR_USD: number;
|
|
123
|
+
/**
|
|
124
|
+
* Probes `GET https://openrouter.ai/api/v1/key` to determine whether the
|
|
125
|
+
* operator's OpenRouter credential has spendable credit above the per-task
|
|
126
|
+
* floor.
|
|
127
|
+
*
|
|
128
|
+
* WHY this gate exists (production bug, 2026-05-23): the existing readiness
|
|
129
|
+
* gates — `hermes doctor` + `hermes auth list openrouter` — verify that a
|
|
130
|
+
* credential is *present* and pool-healthy, but say nothing about whether
|
|
131
|
+
* the credential's *credit balance* is sufficient to run a task. On
|
|
132
|
+
* 2026-05-23 every solve attempt for the day returned `HTTP 402` from
|
|
133
|
+
* OpenRouter ("This request requires more credits, or fewer max_tokens.")
|
|
134
|
+
* while readiness reported ready=true — the harness silently burned 12
|
|
135
|
+
* sessions. This probe closes that gap.
|
|
136
|
+
*
|
|
137
|
+
* Fail-safe philosophy: a clearly-confirmed insufficient-credit signal flips
|
|
138
|
+
* `ready=false`; anything ambiguous (network failure, non-200, missing key)
|
|
139
|
+
* returns `state=unknown` so the caller treats the harness as ready. The
|
|
140
|
+
* inverse false-negative — shutting every operator down because OpenRouter
|
|
141
|
+
* is transiently down — is worse than the original bug.
|
|
142
|
+
*/
|
|
143
|
+
export declare function probeOpenRouterCredit(config?: OpenRouterCreditConfig): Promise<OpenRouterCreditStatus>;
|
|
@@ -1,29 +1,235 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Shared `hermes <args>` spawn scaffolding for both probes: resolves the binary
|
|
4
|
+
* and timeout from config, runs `spawnSync`, and extracts the spawn-error code.
|
|
5
|
+
* Each probe applies its own classification/parsing to the returned result.
|
|
6
|
+
*/
|
|
7
|
+
function runHermes(args, config) {
|
|
8
|
+
const hermesBin = config.hermesPath ?? 'hermes';
|
|
9
|
+
const timeoutMs = config.hermesDoctorTimeoutMs ?? 30_000;
|
|
10
|
+
const result = spawnSync(hermesBin, args, {
|
|
11
|
+
timeout: timeoutMs,
|
|
12
|
+
encoding: 'utf8',
|
|
13
|
+
});
|
|
14
|
+
const errorCode = result.error?.code;
|
|
15
|
+
return { result, errorCode };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Synchronously runs `hermes doctor` and classifies the result. Pure (no
|
|
19
|
+
* Hono dependency) so the harness layer can call it without pulling the API
|
|
20
|
+
* server in.
|
|
21
|
+
*/
|
|
22
|
+
export function probeHermesDoctor(config = {}) {
|
|
23
|
+
const { result, errorCode } = runHermes(['doctor'], config);
|
|
24
|
+
// installed=true means we found the binary on disk. ENOENT is the only
|
|
25
|
+
// definitive not-installed signal. Other errors (EACCES = wrong
|
|
26
|
+
// permissions; ETIMEDOUT = ran but didn't finish in time) indicate the
|
|
27
|
+
// binary exists but couldn't be exercised cleanly — surface those as
|
|
28
|
+
// config-issue, not missing.
|
|
29
|
+
const notFound = errorCode === 'ENOENT';
|
|
30
|
+
const installed = !notFound && (result.status !== null
|
|
31
|
+
|| result.signal !== null
|
|
32
|
+
|| (errorCode != null && errorCode !== 'ENOENT'));
|
|
33
|
+
return {
|
|
34
|
+
installed,
|
|
35
|
+
exitCode: result.status,
|
|
36
|
+
stdout: (result.stdout ?? '').slice(0, 4000),
|
|
37
|
+
stderr: (result.stderr ?? '').slice(0, 4000),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detects whether a single `hermes auth list` credential line is currently
|
|
42
|
+
* *unusable* — i.e. the credential pool has flagged it exhausted with retry
|
|
43
|
+
* time still on the clock, or marked it as a hard auth failure.
|
|
44
|
+
*
|
|
45
|
+
* `hermes auth list` annotates exhausted entries via
|
|
46
|
+
* `_format_exhausted_status` (hermes_cli/auth_commands.py). The annotation
|
|
47
|
+
* forms we treat as still-usable:
|
|
48
|
+
* - no annotation at all → healthy credential
|
|
49
|
+
* - `... (ready to retry)` → exhaustion window has elapsed; usable
|
|
50
|
+
* The forms we treat as unusable:
|
|
51
|
+
* - `... rate-limited ... (12m 3s left)` / `... exhausted ... (1h 4m left)`
|
|
52
|
+
* - `... auth failed ... (re-auth may be required)`
|
|
53
|
+
*
|
|
54
|
+
* A line that carries an exhaustion keyword but no `(ready to retry)` and no
|
|
55
|
+
* `re-auth` hint (e.g. exhausted with a wait window still open) is unusable.
|
|
56
|
+
*/
|
|
57
|
+
function isCredentialLineUnusable(line) {
|
|
58
|
+
// `(ready to retry)` means the exhaustion window has elapsed — usable.
|
|
59
|
+
if (/\(ready to retry\)/i.test(line))
|
|
60
|
+
return false;
|
|
61
|
+
// A hard auth failure or any still-open exhaustion window → unusable.
|
|
62
|
+
return /\bauth failed\b|\(re-auth may be required\)|\brate-limited\b|\bexhausted\b/i.test(line);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Synchronously runs `hermes auth list <provider>` and classifies whether the
|
|
66
|
+
* provider has a usable credential (API-key OR OAuth) in Hermes's credential
|
|
67
|
+
* pool.
|
|
68
|
+
*
|
|
69
|
+
* WHY `auth list`, not `auth status`: `hermes auth status <provider>` only
|
|
70
|
+
* reflects interactive-OAuth-login state (the `providers` block in
|
|
71
|
+
* `~/.hermes/auth.json`). It prints `<provider>: logged out` whenever there
|
|
72
|
+
* is no OAuth session — even when an API-key credential is present and
|
|
73
|
+
* working. An operator who authenticated to OpenRouter the normal way
|
|
74
|
+
* (`OPENROUTER_API_KEY` env var, or `hermes auth add`) would be wrongly
|
|
75
|
+
* reported not-ready and gated out of every claim. `hermes auth list` reads
|
|
76
|
+
* the `credential_pool`, so it sees api_key credentials too.
|
|
77
|
+
*
|
|
78
|
+
* Parsing (`auth list <provider>` output, see `auth_list_command` in
|
|
79
|
+
* hermes_cli/auth_commands.py):
|
|
80
|
+
* - empty stdout → no credential of any kind → not authed
|
|
81
|
+
* - a `<provider> (N credentials):` header followed by ` #<idx> ...` lines,
|
|
82
|
+
* one per pooled credential → authed iff at least one line is *usable*
|
|
83
|
+
* (not exhausted with a wait window still open, not a hard auth failure)
|
|
84
|
+
* - ENOENT / spawn error → not authed (binary not on PATH)
|
|
85
|
+
*
|
|
86
|
+
* `hermes auth list` exits 0 in all of these cases; the signal is entirely in
|
|
87
|
+
* stdout. Pure (no Hono dependency) so the harness layer can call it without
|
|
88
|
+
* pulling the API server in. This is the third readiness gate for Hermes:
|
|
89
|
+
* `hermes doctor` exits 0 even when every provider is logged out (it treats
|
|
90
|
+
* missing providers as warnings), so the harness must probe auth directly.
|
|
91
|
+
*/
|
|
92
|
+
export function probeHermesAuthStatus(provider, config = {}) {
|
|
93
|
+
const { result, errorCode } = runHermes(['auth', 'list', provider], config);
|
|
94
|
+
const raw = (result.stdout ?? '').trim().slice(0, 4000);
|
|
95
|
+
// Binary not found, or any other spawn error, or no output → not authed.
|
|
96
|
+
// Empty stdout means `auth_list_command` skipped the provider section
|
|
97
|
+
// because the credential pool has zero entries for it.
|
|
98
|
+
if (errorCode != null || raw.length === 0) {
|
|
99
|
+
return { provider, authed: false, raw };
|
|
100
|
+
}
|
|
101
|
+
// Credential lines are the ` #<idx> ...` rows under the provider header.
|
|
102
|
+
// A provider is usable when at least one of its pooled credentials is not
|
|
103
|
+
// currently exhausted / hard-failed.
|
|
104
|
+
const credentialLines = raw
|
|
105
|
+
.split('\n')
|
|
106
|
+
.filter((line) => /^\s*#\d+\b/.test(line));
|
|
107
|
+
if (credentialLines.length === 0) {
|
|
108
|
+
// Header present but no credential rows parsed — treat as not authed
|
|
109
|
+
// rather than guess.
|
|
110
|
+
return { provider, authed: false, raw };
|
|
111
|
+
}
|
|
112
|
+
const hasUsableCredential = credentialLines.some((line) => !isCredentialLineUnusable(line));
|
|
113
|
+
return { provider, authed: hasUsableCredential, raw };
|
|
114
|
+
}
|
|
2
115
|
export function addHermesDoctorRoutes(app, config = {}) {
|
|
3
116
|
app.get('/api/hermes/doctor', (c) => {
|
|
4
|
-
|
|
5
|
-
const timeoutMs = config.hermesDoctorTimeoutMs ?? 30_000;
|
|
6
|
-
const result = spawnSync(hermesBin, ['doctor'], {
|
|
7
|
-
timeout: timeoutMs,
|
|
8
|
-
encoding: 'utf8',
|
|
9
|
-
});
|
|
10
|
-
const errorCode = result.error?.code;
|
|
11
|
-
// installed=true means we found the binary on disk. ENOENT is the only
|
|
12
|
-
// definitive not-installed signal. Other errors (EACCES = wrong
|
|
13
|
-
// permissions; ETIMEDOUT = ran but didn't finish in time) indicate the
|
|
14
|
-
// binary exists but couldn't be exercised cleanly — surface those as
|
|
15
|
-
// config-issue, not missing.
|
|
16
|
-
const notFound = errorCode === 'ENOENT';
|
|
17
|
-
const installed = !notFound && (result.status !== null
|
|
18
|
-
|| result.signal !== null
|
|
19
|
-
|| (errorCode != null && errorCode !== 'ENOENT'));
|
|
20
|
-
const body = {
|
|
21
|
-
installed,
|
|
22
|
-
exitCode: result.status,
|
|
23
|
-
stdout: (result.stdout ?? '').slice(0, 4000),
|
|
24
|
-
stderr: (result.stderr ?? '').slice(0, 4000),
|
|
25
|
-
};
|
|
26
|
-
return c.json(body);
|
|
117
|
+
return c.json(probeHermesDoctor(config));
|
|
27
118
|
});
|
|
28
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Default per-task credit floor (USD). See {@link OpenRouterCreditConfig}.
|
|
122
|
+
*
|
|
123
|
+
* Sized to comfortably cover one solve on a cheap routed model (e.g.
|
|
124
|
+
* `deepseek/deepseek-v4-flash` — typical solve costs ~$0.01-0.02 with the
|
|
125
|
+
* `JINN_HERMES_MAX_TOKENS_CAP` of 32000). An operator using a premium model
|
|
126
|
+
* (Sonnet, GPT-5) should override via the `JINN_HERMES_CREDIT_FLOOR_USD`
|
|
127
|
+
* env var (or pass `floorUsd` explicitly).
|
|
128
|
+
*
|
|
129
|
+
* History: a too-conservative initial default of $0.50 — sized for Sonnet —
|
|
130
|
+
* silently gated out deepseek operators with $0.43 remaining (enough for
|
|
131
|
+
* ~25 solves) on 2026-05-23. The right size is the cost of *one* task with
|
|
132
|
+
* comfortable headroom, not a Sonnet-class reserve.
|
|
133
|
+
*/
|
|
134
|
+
const DEFAULT_OPENROUTER_CREDIT_FLOOR_USD_FALLBACK = 0.02;
|
|
135
|
+
const envFloor = process.env['JINN_HERMES_CREDIT_FLOOR_USD'];
|
|
136
|
+
const envFloorParsed = envFloor !== undefined ? Number(envFloor) : NaN;
|
|
137
|
+
export const DEFAULT_OPENROUTER_CREDIT_FLOOR_USD = Number.isFinite(envFloorParsed) && envFloorParsed > 0
|
|
138
|
+
? envFloorParsed
|
|
139
|
+
: DEFAULT_OPENROUTER_CREDIT_FLOOR_USD_FALLBACK;
|
|
140
|
+
/**
|
|
141
|
+
* Probes `GET https://openrouter.ai/api/v1/key` to determine whether the
|
|
142
|
+
* operator's OpenRouter credential has spendable credit above the per-task
|
|
143
|
+
* floor.
|
|
144
|
+
*
|
|
145
|
+
* WHY this gate exists (production bug, 2026-05-23): the existing readiness
|
|
146
|
+
* gates — `hermes doctor` + `hermes auth list openrouter` — verify that a
|
|
147
|
+
* credential is *present* and pool-healthy, but say nothing about whether
|
|
148
|
+
* the credential's *credit balance* is sufficient to run a task. On
|
|
149
|
+
* 2026-05-23 every solve attempt for the day returned `HTTP 402` from
|
|
150
|
+
* OpenRouter ("This request requires more credits, or fewer max_tokens.")
|
|
151
|
+
* while readiness reported ready=true — the harness silently burned 12
|
|
152
|
+
* sessions. This probe closes that gap.
|
|
153
|
+
*
|
|
154
|
+
* Fail-safe philosophy: a clearly-confirmed insufficient-credit signal flips
|
|
155
|
+
* `ready=false`; anything ambiguous (network failure, non-200, missing key)
|
|
156
|
+
* returns `state=unknown` so the caller treats the harness as ready. The
|
|
157
|
+
* inverse false-negative — shutting every operator down because OpenRouter
|
|
158
|
+
* is transiently down — is worse than the original bug.
|
|
159
|
+
*/
|
|
160
|
+
export async function probeOpenRouterCredit(config = {}) {
|
|
161
|
+
const floorUsd = config.floorUsd ?? DEFAULT_OPENROUTER_CREDIT_FLOOR_USD;
|
|
162
|
+
const apiKey = config.apiKey ?? process.env['OPENROUTER_API_KEY'];
|
|
163
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
164
|
+
const timeoutMs = config.timeoutMs ?? 5_000;
|
|
165
|
+
// No API key → unknown (fail-safe). The auth-list gate would have caught
|
|
166
|
+
// a missing credential already; if we somehow get here without one, do
|
|
167
|
+
// not flip the operator into not-ready on a probe we can't even run.
|
|
168
|
+
if (!apiKey) {
|
|
169
|
+
return { state: 'unknown', floorUsd, reason: 'OPENROUTER_API_KEY not set' };
|
|
170
|
+
}
|
|
171
|
+
const controller = new AbortController();
|
|
172
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
173
|
+
try {
|
|
174
|
+
const response = await fetchFn('https://openrouter.ai/api/v1/key', {
|
|
175
|
+
method: 'GET',
|
|
176
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
177
|
+
signal: controller.signal,
|
|
178
|
+
});
|
|
179
|
+
if (!response.ok) {
|
|
180
|
+
// Non-200 (including 401/403/5xx) — unknown, not exhausted. A 401
|
|
181
|
+
// would imply the credential is broken, but the auth-list gate
|
|
182
|
+
// already covered presence; treating an auth-broken state here as
|
|
183
|
+
// "exhausted" would mis-classify it. Fail-safe to unknown.
|
|
184
|
+
const raw = await safeReadResponse(response);
|
|
185
|
+
return {
|
|
186
|
+
state: 'unknown',
|
|
187
|
+
floorUsd,
|
|
188
|
+
reason: `OpenRouter /api/v1/key returned HTTP ${response.status}`,
|
|
189
|
+
raw,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const body = (await response.json());
|
|
193
|
+
const data = body?.data;
|
|
194
|
+
if (!data || typeof data !== 'object') {
|
|
195
|
+
return { state: 'unknown', floorUsd, reason: 'OpenRouter /api/v1/key returned malformed body' };
|
|
196
|
+
}
|
|
197
|
+
const usageUsd = typeof data.usage === 'number' ? data.usage : 0;
|
|
198
|
+
// `limit` can be `null` for unlimited keys — treat that as plenty of credit.
|
|
199
|
+
// `undefined` means the field was absent from the response body, which is
|
|
200
|
+
// ambiguous (API schema drift?) — return `unknown` so a future shape
|
|
201
|
+
// change does not silently pass readiness.
|
|
202
|
+
if (data.limit === null) {
|
|
203
|
+
return { state: 'ok', floorUsd, limitUsd: null, usageUsd };
|
|
204
|
+
}
|
|
205
|
+
if (data.limit === undefined) {
|
|
206
|
+
return { state: 'unknown', floorUsd, reason: 'OpenRouter /api/v1/key response missing `data.limit`' };
|
|
207
|
+
}
|
|
208
|
+
const limitUsd = data.limit;
|
|
209
|
+
// Prefer the API's `data.limit_remaining` (authoritative for the current
|
|
210
|
+
// billing window when the key has a periodic reset) over `limit - usage`
|
|
211
|
+
// (which is all-time and underestimates remaining credit on resetting
|
|
212
|
+
// keys). Fall back to the subtraction when `limit_remaining` is absent.
|
|
213
|
+
const remainingUsd = typeof data.limit_remaining === 'number' ? data.limit_remaining : limitUsd - usageUsd;
|
|
214
|
+
const state = remainingUsd >= floorUsd ? 'ok' : 'exhausted';
|
|
215
|
+
return { state, floorUsd, remainingUsd, limitUsd, usageUsd };
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
// Network error, timeout, abort, JSON parse failure — unknown (fail-safe).
|
|
219
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
220
|
+
return { state: 'unknown', floorUsd, reason };
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
clearTimeout(timer);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
async function safeReadResponse(response) {
|
|
227
|
+
try {
|
|
228
|
+
const text = await response.text();
|
|
229
|
+
return text.slice(0, 4000);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
return '';
|
|
233
|
+
}
|
|
234
|
+
}
|
|
29
235
|
//# sourceMappingURL=hermes-doctor-endpoint.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermes-doctor-endpoint.js","sourceRoot":"","sources":["../../src/api/hermes-doctor-endpoint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hermes-doctor-endpoint.js","sourceRoot":"","sources":["../../src/api/hermes-doctor-endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* spec/2026-05-05-solvernet-creation-and-launch.md dropped that enum value);
|
|
9
9
|
* the launched-record subsystem owns that signal now.
|
|
10
10
|
*
|
|
11
|
-
* Stale-poll detection is computed here
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Stale-poll detection is computed here when a generator reports a cadence:
|
|
12
|
+
* a poll is stale when the wall clock has advanced past `lastPollAt + 2 *
|
|
13
|
+
* cadenceMs`. Fill-the-pool generators may omit cadence and are never marked
|
|
14
|
+
* stale by this generic status surface.
|
|
15
15
|
*
|
|
16
16
|
* The deps shape is intentionally narrow — every external surface is a
|
|
17
17
|
* function so tests can inject deterministic state without standing up the
|
|
@@ -23,18 +23,27 @@ import type { JinnConfig } from '../config.js';
|
|
|
23
23
|
export interface LauncherStatusGeneratorView {
|
|
24
24
|
state: 'active' | 'paused' | 'errored';
|
|
25
25
|
lastPollAt?: string;
|
|
26
|
-
lastPollSummary?:
|
|
27
|
-
evaluated: number;
|
|
28
|
-
posted: number;
|
|
29
|
-
skipped: number;
|
|
30
|
-
};
|
|
26
|
+
lastPollSummary?: LauncherGeneratorPollSummary;
|
|
31
27
|
lastError?: {
|
|
32
28
|
message: string;
|
|
33
29
|
at: string;
|
|
34
30
|
};
|
|
35
|
-
cadenceMs
|
|
31
|
+
cadenceMs?: number;
|
|
36
32
|
stale: boolean;
|
|
37
33
|
}
|
|
34
|
+
export type LauncherGeneratorPollSummary = {
|
|
35
|
+
evaluated: number;
|
|
36
|
+
posted: number;
|
|
37
|
+
skipped: number;
|
|
38
|
+
} | {
|
|
39
|
+
poolSize: number;
|
|
40
|
+
posted: number;
|
|
41
|
+
unposted: number;
|
|
42
|
+
live: number;
|
|
43
|
+
repostable: number;
|
|
44
|
+
saturated: number;
|
|
45
|
+
abandoned: number;
|
|
46
|
+
};
|
|
38
47
|
export interface LauncherStatusBudgetView {
|
|
39
48
|
safeAddress: string;
|
|
40
49
|
safeBalanceWei: string;
|
|
@@ -60,16 +69,12 @@ export interface LauncherStatusResponse {
|
|
|
60
69
|
*/
|
|
61
70
|
export interface LauncherGeneratorStateSnapshot {
|
|
62
71
|
lastPollAt?: string;
|
|
63
|
-
lastPollSummary?:
|
|
64
|
-
evaluated: number;
|
|
65
|
-
posted: number;
|
|
66
|
-
skipped: number;
|
|
67
|
-
};
|
|
72
|
+
lastPollSummary?: LauncherGeneratorPollSummary;
|
|
68
73
|
lastError?: {
|
|
69
74
|
message: string;
|
|
70
75
|
at: string;
|
|
71
76
|
};
|
|
72
|
-
cadenceMs
|
|
77
|
+
cadenceMs?: number;
|
|
73
78
|
}
|
|
74
79
|
export interface GatherLauncherStatusDeps {
|
|
75
80
|
config: Pick<JinnConfig, 'solverNets'>;
|
|
@@ -52,9 +52,10 @@ export async function gatherLauncherStatus(deps) {
|
|
|
52
52
|
]);
|
|
53
53
|
const generator = {
|
|
54
54
|
state: generatorState,
|
|
55
|
-
cadenceMs: snapshot?.cadenceMs ?? 0,
|
|
56
55
|
stale,
|
|
57
56
|
};
|
|
57
|
+
if (snapshot?.cadenceMs !== undefined)
|
|
58
|
+
generator.cadenceMs = snapshot.cadenceMs;
|
|
58
59
|
if (snapshot?.lastPollAt)
|
|
59
60
|
generator.lastPollAt = snapshot.lastPollAt;
|
|
60
61
|
if (snapshot?.lastPollSummary)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launcher-status.js","sourceRoot":"","sources":["../../src/api/launcher-status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"launcher-status.js","sourceRoot":"","sources":["../../src/api/launcher-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -64,7 +64,17 @@ export interface PortfolioV0Status {
|
|
|
64
64
|
totals: {
|
|
65
65
|
/** Tasks that reached terminal success and delivered their result. */
|
|
66
66
|
delivered: number;
|
|
67
|
+
/**
|
|
68
|
+
* Sum of `settledFailed` and `localErrors`. Retained for callers that
|
|
69
|
+
* still want a single failure count; new surfaces should prefer the
|
|
70
|
+
* split fields to distinguish on-chain settled fails from local
|
|
71
|
+
* engine errors.
|
|
72
|
+
*/
|
|
67
73
|
failed: number;
|
|
74
|
+
/** FAILED runs whose delivery tx landed on-chain (settled failure). */
|
|
75
|
+
settledFailed: number;
|
|
76
|
+
/** FAILED runs that never reached the marketplace (local engine error). */
|
|
77
|
+
localErrors: number;
|
|
68
78
|
active: number;
|
|
69
79
|
};
|
|
70
80
|
/** Tasks currently being processed (not in a terminal state). */
|
|
@@ -12,6 +12,7 @@ import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
|
12
12
|
import { homedir } from 'node:os';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { TaskRunPersistence } from '../harnesses/engine/persistence.js';
|
|
15
|
+
import { taskRunRoutingKey } from './task-run-routing.js';
|
|
15
16
|
/** Default per-task engine work root; kept in sync with `config.engine.workingDirRoot`. */
|
|
16
17
|
export const DEFAULT_ENGINE_WORKING_DIR_ROOT = join(homedir(), '.jinn-client', 'engine', 'work');
|
|
17
18
|
const RECENT_CLAUDE_OUTCOMES_LIMIT = 10;
|
|
@@ -52,16 +53,25 @@ function toVerdict(task) {
|
|
|
52
53
|
*/
|
|
53
54
|
export function gatherPortfolioV0Status(store, workingDirRoot = DEFAULT_ENGINE_WORKING_DIR_ROOT) {
|
|
54
55
|
const persistence = new TaskRunPersistence(store.db);
|
|
55
|
-
//
|
|
56
|
-
|
|
56
|
+
// portfolio.v0 is a solver-specific status payload — filter task_runs by
|
|
57
|
+
// the daemon's internal routing key so other SolverNets' runs don't leak
|
|
58
|
+
// into these counters (jinn-mono-0t6p) while historical rows can still be
|
|
59
|
+
// classified from canonical `contractId` / `contractVersion` or the legacy
|
|
60
|
+
// `task_payload.solverType` alias.
|
|
61
|
+
const inFlight = persistence.getInFlight().filter(isPortfolioV0Run);
|
|
62
|
+
const complete = persistence.getByState('COMPLETE').filter(isPortfolioV0Run);
|
|
63
|
+
const failed = persistence.getByState('FAILED').filter(isPortfolioV0Run);
|
|
64
|
+
const inFlightSummaries = inFlight.map(toInFlightTask);
|
|
57
65
|
// Recent verdicts: last N COMPLETE + FAILED task runs combined, newest first
|
|
58
|
-
const complete = persistence.getByState('COMPLETE');
|
|
59
|
-
const failed = persistence.getByState('FAILED');
|
|
60
66
|
const allTerminal = [...complete, ...failed].sort((a, b) => b.stateUpdatedAt - a.stateUpdatedAt);
|
|
61
67
|
const recentVerdicts = allTerminal.slice(0, RECENT_VERDICTS_LIMIT).map(toVerdict);
|
|
68
|
+
const settledFailed = failed.filter((task) => task.deliveryTxHash !== null);
|
|
69
|
+
const localErrors = failed.filter((task) => task.deliveryTxHash === null);
|
|
62
70
|
const totals = {
|
|
63
71
|
delivered: complete.length,
|
|
64
72
|
failed: failed.length,
|
|
73
|
+
settledFailed: settledFailed.length,
|
|
74
|
+
localErrors: localErrors.length,
|
|
65
75
|
active: inFlight.length,
|
|
66
76
|
};
|
|
67
77
|
// Recent system_snapshot artifacts (tagged with 'system_snapshot')
|
|
@@ -84,7 +94,16 @@ export function gatherPortfolioV0Status(store, workingDirRoot = DEFAULT_ENGINE_W
|
|
|
84
94
|
recentSnapshots = [];
|
|
85
95
|
}
|
|
86
96
|
const recentClaudeOutcomes = gatherRecentClaudeOutcomes(workingDirRoot);
|
|
87
|
-
return {
|
|
97
|
+
return {
|
|
98
|
+
totals,
|
|
99
|
+
inFlight: inFlightSummaries,
|
|
100
|
+
recentVerdicts,
|
|
101
|
+
recentSnapshots,
|
|
102
|
+
recentClaudeOutcomes,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function isPortfolioV0Run(run) {
|
|
106
|
+
return taskRunRoutingKey(run) === 'portfolio.v0';
|
|
88
107
|
}
|
|
89
108
|
/**
|
|
90
109
|
* Scan session outcome files: each task dir under `workingDirRoot` may contain
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portfolio-v0-build.js","sourceRoot":"","sources":["../../src/api/portfolio-v0-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"portfolio-v0-build.js","sourceRoot":"","sources":["../../src/api/portfolio-v0-build.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ export interface PredictionV1TaskRunSummary {
|
|
|
34
34
|
implName: string | null;
|
|
35
35
|
windowStartTs: number;
|
|
36
36
|
windowEndTs: number;
|
|
37
|
+
runStartedAt: number | null;
|
|
37
38
|
stateUpdatedAt: number;
|
|
38
39
|
manifestCid: string | null;
|
|
39
40
|
deliveryTxHash: string | null;
|
|
@@ -47,7 +48,16 @@ export interface PredictionV1Status {
|
|
|
47
48
|
activeTaskRuns: number;
|
|
48
49
|
solutions: number;
|
|
49
50
|
verdicts: number;
|
|
51
|
+
/**
|
|
52
|
+
* Sum of `settledFailed` and `localErrors`. Retained for callers that
|
|
53
|
+
* still want the rolled-up count; new surfaces should prefer the split
|
|
54
|
+
* fields to align with the public explorer.
|
|
55
|
+
*/
|
|
50
56
|
failed: number;
|
|
57
|
+
/** FAILED runs whose delivery tx landed on-chain (settled failure). */
|
|
58
|
+
settledFailed: number;
|
|
59
|
+
/** FAILED runs that never reached the marketplace (local engine error). */
|
|
60
|
+
localErrors: number;
|
|
51
61
|
};
|
|
52
62
|
latest: {
|
|
53
63
|
taskAt: number | null;
|