feat(grid): Windows node hosts named personas via external serving endpoint (K3) - #2058
Open
joelteply wants to merge 4 commits into
Open
feat(grid): Windows node hosts named personas via external serving endpoint (K3)#2058joelteply wants to merge 4 commits into
joelteply wants to merge 4 commits into
Conversation
…coding 8GB The MEMGUARD memory-guard task hardcoded system_ram_mb=8192 on Windows (the non-macos/linux cfg branch), so its self-kill limit was a fixed 6553MB (80% of a bogus 8GB) on EVERY Windows box regardless of actual RAM. On BigMama (RTX 5090, 64GB) that meant the substrate would std::process::exit(1) the instant RSS passed 6.5GB — normal once the serving model + embedding runtime load — silently taking the node (and its hosted personas' grid beacons) down minutes after boot. Use sysinfo (the crate's existing cross-platform RAM source, already the system_resources backbone) to read real physical RAM. Verified live on BigMama: the guard now logs system=64914MB instead of 8192MB. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc
…dpoint (lane-source-agnostic) Persona hosting was gated on a decode-ready LOCAL GPU serving lane (await_ready_serving on the serving daemon's ServingSnapshot). On a node whose GPU is already fully occupied by another engine (BigMama: the K3 llama-server owns the 5090), continuum-core could never stand up its own lane, so it hosted ZERO personas and their grid presence went stale — even though a perfectly good OpenAI-compatible endpoint was running right there. Make the hosting gate lane-source-agnostic (the misfit / grid design: a persona is served by whatever endpoint is available — this node's GPU, a co-located engine, or later a grid peer). When LLAMA_SERVER_BASE_URL pins an external endpoint: - await_ready_serving() short-circuits to probe_external_serving(), which reachability-checks the endpoint (/health 200 + /props n_ctx window + /v1/models model) and synthesizes the ready ServingSnapshot personas bind against (base_url = the pinned endpoint). ONE change: both the persona-host gate AND the adapter factory call await_ready_serving, so the whole path becomes source-agnostic. - the persona-host gate enters the ready-check on an external pin even when the LOCAL plan does not fit_on_gpu (there is no local lane). - the serving daemon's reconcile_to_plan early-returns on an external pin so it never spawns/reclaims a local llama-server that would fight the pinned endpoint for its port. The adopt bar for a DELIBERATELY-pinned endpoint is reachability, not the local-lane decode_smoke_ok (5+ tokens in 75s) — that doubles as a speed test a legitimately slow endpoint (a CPU-offloaded MoE at <0.05 tok/s, or a distant grid peer) fails despite decoding fine, and a client-timeout does not cancel the server-side generation so a probe storm monopolizes the slot. A genuine wedge (every turn 500s) surfaces LOUD on the persona's first real turn, not silently faked. Verified live on BigMama: with LLAMA_SERVER_BASE_URL=http://127.0.0.1:8090/v1 (the K3 engine), 'external serving endpoint adopted as the persona lane', persona bootstrap 'Alive heartbeat pump started', and the persona shows FRESH on 'airc network' where it had been stale for 21h. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc
…ot to SERVING_STATE Follow-up to the lane-source-agnostic hosting change. Making the serving daemon merely SKIP its reconcile on an external pin left SERVING_STATE empty (ready=false, active=<none>). That broke the OpenAI adapter's pre-generate model-guard (openai_adapter.rs:1918, reads current_serving() == SERVING_STATE directly, NOT await_ready_serving): every persona turn died with 'model <K3> is not the active served model (serving: <none>, ready: false) — refusing to generate against an unguaranteed model'. Now, on an external pin, the daemon ADOPTS the endpoint: it publishes the probed external ServingSnapshot (ready=true, active_model=the endpoint's resident model, served window from its /props) to SERVING_STATE via serving_tx, while still spawning NO local lane. So current_serving() and await_ready_serving both report the ready external lane, and the guard passes. Trust once-ready; re-probe only while not-yet-ready. Verified live on BigMama with the K3 endpoint pinned: after the daemon's adopt+publish, guard refusals drop to ZERO and persona turns proceed to build prompts and dispatch to K3 (the remaining refusals are the correct per-slot-window guard — K3's 2048 n_ctx vs a ~2269-token persona prompt — and K3's <0.05 tok/s speed, both K3-side, not the hosting path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc
… on the heartbeat cadence
Hosted personas rendered as UNNAMED roster rows in the M5 desktop
(peer-<uuid> + default robot glyph). continuum-core called
publish_identity(), which seeds ONLY the agent-name floor — role, bio,
avatar, and kind never reached the wire, and the one-shot emit at attach
was missed by any peer that joined the room later (M5 reconnecting), so
even the name didn't propagate reliably.
A hosted persona can't run `airc identity set` herself, so continuum-core
now publishes her card on her behalf:
- persona_identity_card(&PersonaCard) maps her durable seed identity to
an airc Identity: name, pronouns (from gender), role (RoleId), bio
(from the open profile), and integrations{continuum_persona_id,
continuum_kind=persona, avatar_vrm}. The avatar rides integrations
exactly as M5's roster fold expects; kind=persona also rides the Alive
heartbeat's runtime tag.
- bootstrap reads the seed (citizens/personas/<name>/seed.json, one dir
up from the airc home) and set_local_identity_card()s the full card
(persists + broadcasts). WARN-and-continue → name-floor publish on a
seed-read miss, so she is at least named.
- a new identity_republish task re-emits the card every
DEFAULT_HEARTBEAT_INTERVAL so a LATE-joining peer is grounded within a
heartbeat window. Handle held for the persona's lifetime, aborted on
drop like the heartbeat pump.
Verified live on BigMama: `airc whois <peer>` now shows Kimi/Sahar with
name + pronouns=she/her + role=helper + bio + integrations{avatar_vrm,
continuum_kind=persona} — was name-only before.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BigMama grid-serving work: get a Windows node hosting named personas on the grid, served by an already-running external engine. Four commits, all validated live on BigMama (RTX 5090, native windows-msvc) and clean-rebased onto canary.
Commits
fix(ipc/windows): detect real RAM in the memory guard — the MEMGUARD self-kill limit hardcodedsystem_ram_mb=8192on Windows → a fixed 6.5 GB RSS cap on every Windows box regardless of actual RAM, so the substrateexit(1)d minutes after boot. Now reads real RAM via sysinfo. Verified: guard logssystem=64914MBon BigMama.feat(serving): host personas against an external OpenAI-compatible endpoint (lane-source-agnostic) — persona hosting was gated on a decode-ready local GPU serving lane. On a node whose GPU is already fully occupied by another engine (BigMama: the K3 llama-server owns the 5090), continuum-core could never stand up its own lane → 0 personas hosted → grid presence went stale. WhenLLAMA_SERVER_BASE_URLpins an external endpoint,await_ready_servingshort-circuits toprobe_external_serving(reachability gate:/health+/propsn_ctx +/v1/models), the persona-host gate enters on the pin even without a local plan, and the serving daemon reconcile early-returns so it never fights the endpoint for its port. The misfit/grid design: a persona is served by whatever endpoint is available.fix(serving): daemon publishes the adopted external endpoint's snapshot to SERVING_STATE — the OpenAI adapter's pre-generate model-guard readscurrent_serving()(SERVING_STATE) directly, so merely skipping reconcile left it empty and every turn died with "model is not the active served model". The daemon now publishes the probed externalServingSnapshot(ready + resident model +/propswindow) while spawning no local lane. Verified: guard refusals → 0; persona turns reach the K3 dispatch.feat(persona/airc): publish each hosted persona's FULL identity card, on the heartbeat cadence — hosted personas rendered UNNAMED (peer-<uuid>+ default glyph) in the M5 desktop roster becausepublish_identity()seeds only the name floor. continuum-core now publishes the full card on the persona's behalf — name + pronouns + role + bio +integrations{continuum_persona_id, continuum_kind=persona, avatar_vrm}— sourced from her durablePersonaCard(seed), re-emitted every heartbeat interval so late-joining peers are grounded. Verified:airc whois <peer>shows Kimi/Sahar with name + role=helper + bio + avatar (was name-only).Live validation (BigMama)
#cambriantech.:8090) adopted as the persona lane → Kimi + Sahar host + beacon LIVE.airc whois e2f0e022/df72dbf2→ full named cards.Remaining (K3-side, not this PR): K3's 2048 ctx window < persona prompt, and K3's <0.05 tok/s speed gate an actual completed response; both resolve when K3 gets a larger window + its slot-cache/speed fix.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Q4NU4VNiELPQfBpCacDZGc