Repository navigation
feat: hermes/omp file-free routing (#535 phases 2+3) + MITM cert strictness fix - #538
Conversation
[bot] 🏷 Reviewing #538 now — checked out |
[bot] 🏷 Review complete — audited the incremental diff ( Pre-flight (re-run on
Security — new absolute-form forward path (src/server.ts:301): verified safe. It returns MITM cert strictness (src/ca.ts): correct. Root omp stale-model bypass (src/agent/pi.ts): correct, well-gated. buildPiEnv / manifest sharing (src/launcher.ts:343): correct. One parseHermesYaml (src/client-config.ts:388): dict form now honors hermes' Two deliberate tradeoffs (both intentional + commented — putting them on the record):
Nits (non-blocking):
Process: stacked on #536 — needs #536 merged first (GitHub retargets to master on base delete). README 👍 from me once #536 lands — subject to acknowledging the two tradeoffs above. |
facf9fd to
8a86fd3
Compare
8a86fd3 to
038cda5
Compare
…ctness fix hermes (#535 phase 2): - launcher: env-only routing — stripInheritedProxy + HTTPS_PROXY=proxy + HERMES_CA_BUNDLE=combined bundle; runs on the REAL ~/.hermes (a user-set HERMES_HOME survives to the child); overlay/HERMES_HOME redirect removed. httpx resolves HTTPS_PROXY for both schemes: https upstreams ride CONNECT + cert MITM, http upstreams ride absolute-form forward-proxy requests the server understands. No identity plugin. - client-config: parseHermesYaml accepts base_url/url/api (hermes priority base_url > url > api) — the canonical form is base_url, old reader matched api only. omp (#535 phase 3): - launcher: buildPiEnv BILI_PROVIDER_REWRITES manifest (shared with pi), PI_CODING_AGENT_DIR stripped from discovery + child, -e dist/agent/omp.js when the plugin is not installed, refusal parity before proxy start. - agent/pi.ts: omp session_start/session_switch repin — omp pins the session Model from a pre-extension snapshot, so registerProvider rewrites never reach agent.state.model and streaming keeps the raw baseUrl (direct fetch, bypasses the proxy). setModel({...model, baseUrl: rewritten}) re-pins it; omp lacks pi's _refreshCurrentModelFromRegistry, this is the client-side equivalent. server: absolute-form forward-proxy requests (GET http://upstream/path via the proxy) — self-host guarded, routed upstream with tunnel semantics. ca: strict OpenSSL 3 (python/httpx) compatibility — leaf certs now carry SKI + AKI (root SKI, explicit bytes) and the root's basicConstraints is critical; mintHostCert extracted for testability. hermes/httpx rejected the old certs with "certificate verify failed: Missing Authority Key Identifier" / "Basic Constraints of CA cert not marked critical" while curl tolerated them.
038cda5 to
94136ff
Compare
Stacked on #536 (phase 1, pi file-free) — merge #536 first; GitHub retargets this PR to master when its base is deleted after merge. Diff below includes only the incremental changes on top of #536.
#535 phases 2+3: hermes + omp join pi in file-free injection (no shadow homes, no overlay dirs, real
~/.hermes/~/.ompuntouched).hermes (phase 2) — env-only routing
stripInheritedProxy+HTTPS_PROXY=<proxy>+HERMES_CA_BUNDLE=<combined bundle>. Runs on the real~/.hermes; a user-setHERMES_HOMEsurvives to the child (custom-home users keep working). All overlay machinery removed.HTTPS_PROXYfor both schemes: https upstreams ride CONNECT + cert MITM, http upstreams ride absolute-form forward-proxy requests (server side added:resolveUpstreamabsolute-form block, self-host guarded).parseHermesYamlnow acceptsbase_url/url/apiwith hermes' own priority (base_url>url>api) — hermes' canonical form isbase_url:; the old reader matchedapi:only.omp (phase 3) — reuses the pi manifest
buildPiEnvBILI_PROVIDER_REWRITESmanifest shared with pi;PI_CODING_AGENT_DIRstripped from discovery + child env;-e dist/agent/omp.jswhen the plugin is not installed; pre-spawn refusal parity before the proxy starts.Modelfrom a pre-extension snapshot —registerProviderrewrites the registry + runtime overrides but never refreshesagent.state.model(omp lacks pi's_refreshCurrentModelFromRegistry), so streaming keeps the rawbaseUrland fetches go direct, bypassing the proxy. Fix: onsession_start/session_switchthe plugin readsctx.modeland callssetModel({...model, baseUrl: rewritten})to re-pin. Verified end-to-end: one-shotomp -pnow showsforward POST → :8197/v1/responsesin the proxy log (was zero forwards before).MITM cert strictness (found by the hermes smoke)
Python/httpx (OpenSSL 3 strict chain verification) rejected our generated certs where curl tolerated them:
certificate verify failed: Missing Authority Key Identifier— leaves had no AKI/SKIBasic Constraints of CA cert not marked critical— root BC not criticalFixed in
src/ca.ts: leaves carry SKI + AKI (= root SKI, explicit bytes), rootbasicConstraintsis critical.mintHostCert()extracted for testability. Note: existing installs regenerate their root CA on next start (10-year self-signed root; path-referenced trust bundles likeHERMES_CA_BUNDLE/NODE_EXTRA_CA_CERTSpick the new one up automatically). Smoke-verified against realopen.bigmodel.cnMITM via hermes + python httpx.Phase 4 (dsh) — deferred
dsh's fetch bypasses proxy env vars for loopback upstreams; recorded on #535 for later.
Pre-flight
npm run typecheckcleannpm test1018/1020 — the 2 fails are the known env-dependent plugin-agent tests (liveBILLION_CONTEXT_PROXYleaks into the test process; pass 32/32 standalone)npm run buildOKforward POST✓; real~/.hermes/config.yaml+~/.omp/agent/*mtimes untouched ✓