backfill_acp_session_cwd had no production caller, so rows minted before
the column was written stayed unassigned in Desktop until someone ran it by
hand. The manager now runs the idempotent UPDATE once per process on first
DB use (injected or acquired), with a test through create_session().
Also maps the contributor email for attribution.
Adds the contributors/emails mapping for @rain610 (check-attribution) and
the two padding-line-between-statements blank lines eslint --fix wanted in
roster-actions.ts. No behaviour change.
Compare through Path.resolve() so the assertion holds on macOS (/var -> /private/var); drop the
sys.path hack, the no-flag test and the Windows skip stub. Adds the contributor email mapping.
Keeps three invariants across #116156 (@fangliquanflq) and #116292 (@Finn763):
a configured providers.llamacpp entry wins over managed-server detection on the
runtime path; an external llama-server on a local_runtime.detect_ports port is
what /model > Local (switch_model with the picker's provider id) resolves to;
a staged GGUF alone keeps the picker's id resolvable so the runtime seam, not
the provider gate, reports a missing server.
Drops the endpoint.py config auto-load from #116292: both production callers of
resolve_llamacpp_endpoint() now pass the loaded config (#116156), so loading it
again inside the resolver was defense-in-depth. Drops the change-detector test
on the forwarded config object and the redundant negative control.
Docs: local-models page now shows detect_ports and the providers.llamacpp
override for a llama-server the user runs on a fixed port.
Keep canonical plugin profile identity through CLI aliases, separate URL
variables from credentials, and honor matching persisted configuration
across registered aliases. Retain native custom and built-in routing.
Retain real discovery/runtime test provenance from the contributor while
omitting the already absorbed bridge and separately owned transport fix.
Co-authored-by: david-bowiegxw <834563048@qq.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The worker ack file is what the gateway's exists()-then-read loop keys on;
the test drives the production entry point _run_external_worker_payload and
asserts the ack is never observable while its body is still being written
(red on origin/main: O_CREAT made the empty file visible before json.dump),
and that no temp residue is left beside it.
Live probe (real `python -m cron.scheduler --external-worker-file` on a
scratch HERMES_HOME, tight parent-style poller): origin/main 3/3 runs read
an empty ack -> "unreadable acknowledgement"; this head 5/5 read a full ack.
Refs #116164 (form 1), #107184. Salvages #107678 (@keenvc).
Split the single connection row of the gateway's shaped provider-error reply
into three: an interrupted established connection (reset/EOF/RemoteProtocolError),
a refused/unroutable endpoint (the case #86570 wrote the "not running or is
unreachable" wording for), and a cause-free SDK ``APIConnectionError`` that
supports neither diagnosis. A reset says nothing about whether the endpoint is
up, so telling the user to restart a server that just answered sends them to
debug the wrong thing (#116323).
Selectively adapted from Lei-k/hermes-agent#16 (497cc47556b1) via PR #109701,
rebased onto the current reply contract (rate-limit > auth > policy > connection,
every reply names a slash command, no operator jargon).
Add ``resume_thread_id`` to CodexAppServerSession: when set, the first
ensure_started() issues ``thread/resume`` (with the same cwd / personality /
developerInstructions / model params thread/start sends) instead of starting
an empty thread, and verifies codex handed back the requested id. A refused
or mismatched resume raises the typed CodexThreadResumeError once; the next
ensure_started() falls through to ``thread/start`` on the same handshaken
client (initialize now runs once per client, not once per attempt).
Why: the thread id lived in memory only, so every new AIAgent for the same
Hermes session — a later API-server request or the first turn after a
restart — started a fresh codex thread and the model lost its own memory of
the conversation (#100531). The runtime decides the fail-closed policy; this
adapter only speaks the wire contract (verified against codex-cli 0.147.0:
thread/resume{threadId,...} -> result.thread.id; unknown id -> -32600 "no
rollout found"; killed writer -> -32600 "already has an active writer").
Salvaged from #103352 (thread/resume + id cross-fill + mismatch guard).