Skip to content

fix(ios/local-inference): #11841 keep-awake + first-run download-trigger, plus accumulated worktree residuals - #12085

Closed
lalalune wants to merge 42 commits into
developfrom
feat/multi-account-login-verification
Closed

lalalune wants to merge 42 commits into
developfrom
feat/multi-account-login-verification

Conversation

@lalalune

@lalalune lalalune commented Jul 3, 2026

Copy link
Copy Markdown
Member

Accumulated worktree residuals from the shared swarm branch (its prior PR #11731 already merged; this batches the 42 commits since). Grouped by thread below. CI is the gate; individual threads are self-contained fixes.

Headline: iOS on-device model download (#11841)

  • keep-awake during download — reference-counted keep_awake_set that holds the iOS idle timer open while a model download is active, so auto-lock can't suspend the in-process transfer. Wired on both engine paths: the JSContext compat bridge and the full-Bun host_call dispatch (FullBunEngineHost), with the JavaScriptCore-free core split so it compiles into the full-Bun target. Verified on-device: BUILD SUCCEEDED + installed on an iPhone 16 Pro Max running the full-Bun engine; the host_call path is live (host call method=…). Downloader unit tests 20/20.
  • first-run download-trigger bug — picking "On this device (recommended)" set localInference=cloud-inference because the inference-step parser's cloud regex matched the word "recommended", so the local model download was never requested. Removed "recommended" from the cloud signal (cloud still matches on cloud/eliza cloud/online); added a regression test (first-run 22/22).
  • BootCaptureUITests — added holdForLocalModelDownload (opt-in ELIZA_LOCAL_MODEL_DOWNLOAD_WAIT_SECONDS) so the local-onboarding capture keeps the app alive through the fire-and-forget download instead of tearing it down; harness knob added.

Other threads (self-contained)

  • ci — path-gate / workflow fixes.
  • core / prompts / orchestrator — extractFirstSentence abbreviation edge, action-description cap removal, trajectory action-description recording, action/provider name disambiguation.
  • ui / onboarding / ios-local / ios-build — cloud-login resume after WebView eviction, first-run POST kernel route, name normalize, misc iOS build fixes.
  • native-bun-runtime / capacitor-llama — device inference fixes.

Evidence

🤖 Generated with Claude Code

lalalune and others added 30 commits June 30, 2026 19:19
… ram/threads (#10605)

Co-authored-by: Shaw <shaw@elizalabs.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… DB (#10730)

Co-authored-by: Shaw <shawgotbags@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
release: promote develop → production (money-integrity wave, monetization rails, auth overhaul, live rate limiting)
…2400s install timeout (#10839) (#11314)

Prod deploys run from main (production environment allows only the main
branch), but main cloud-cf-deploy still had the install-hang config: bun
canary + install cache under $PWD (box /tmp, slow FS) + 900s per-attempt cap.
Every money-integrity-wave prod deploy hung on bun install. Ports the three
fixes already merged to develop (#11235/#11268/#11304): pin bun to latest,
put the install cache on local $HOME (persistent/warm), and raise the
per-attempt timeout to 2400s so the slow-but-completing install finishes.

With this on main, a main-push deploy installs, then migrate-db runs
(branch=main satisfies the production environment policy) pending the
required-reviewer approval, then Worker/Pages deploy. Ships the merged money
fixes (#11190 payout gate, #11189 cron, escrow, #11163 launch gate) to prod.
release: promote develop → main (money-integrity + fleet wave, 2026-07-02)
release: promote develop→main — ship #11413 money-gate + runtime restores to prod
release: promote develop→main — ship #11413 restores + migrate-runner fix to prod
release: promote develop → main — ship the credit-mint fixes (#11473 + #11472) to prod
release: promote develop→main — 5 money-hardening fixes (#11539/#11556/#11497/#11482/#11481) + core/test
release: promote develop → main — ship #11606 (#11512 mint fix) + money-lane sweep to prod
chore(promote): develop → main — 36 commits (money fail-closed pricing, MCP debit refund, credential-pool + agent-api hardening, #11640 deploy-concurrency fix)
chore(release): promote develop to main — credit-gated app provisioning + money-surface cleanup
…e iOS load path (#11612)

The plugin-local-inference LocalAIManager is stubbed out of the mobile agent
bundle — the load that actually jetsammed the iPhone 16 Pro Max runs through
LlamaBridgeImpl.swift (n_gpu_layers 999 + n_ubatch 1024 via mobileBatchSizes)
and the @elizaos/capacitor-llama JS adapter. Apply the same admission fix
there:

- LlamaBridgeImpl.mobileBatchSizes: device physical micro-batch 1024 -> 256.
  Compute buffer 1037 -> ~260 MiB, so weights 4722 + compute 260 + KV 36
  ≈ 5018 MiB fits the ~5461 MiB (2/3 of 8 GiB) jetsam working set with
  full-GPU speed retained.
- LlamaBridgeImpl.loadModel: footprint model now includes the explicit
  n_ubatch-scaled compute-buffer term; admission order is ctx-shrink ->
  n_gpu_layers reduction (exact layer count via a CPU-only mmap metadata
  probe + llama_model_n_layer, exported by the shipped LlamaCpp.xcframework)
  -> clean failure. CPU-resident layers stay mmap-backed clean pages, so
  partial offload genuinely lowers the wired footprint; CPU-only loads no
  longer count un-wired weights against the budget.
- capacitor-llama adapter: n_ubatch 512 -> 256 on the non-speculative mobile
  path; unload-on-failure — initContext failure releases the native context,
  and a failed decode (e.g. Metal ret=-3) unloads the model instead of
  leaving multi-GiB wired buffers mapped until jetsam.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-login-verification

# Conflicts:
#	packages/cloud/api/__tests__/advertising-account-admin-routes.test.ts
#	packages/cloud/shared/src/db/migrations/meta/_journal.json
#	packages/cloud/shared/src/db/schemas/ad-accounts.ts
#	packages/ui/src/components/pages/__e2e__/output-launcher/desktop-rest.png
#	packages/ui/src/components/pages/__e2e__/output-launcher/launcher-walkthrough.webm
#	packages/ui/src/components/pages/__e2e__/output-launcher/mobile-after-swipe-home.png
#	packages/ui/src/components/pages/__e2e__/output-launcher/mobile-rest.png
#	packages/ui/src/components/shell/__e2e__/output-home/01-mobile-home.png
#	packages/ui/src/components/shell/__e2e__/output-home/02-mobile-notification-sheet.png
#	packages/ui/src/components/shell/__e2e__/output-home/03-mobile-launcher.png
#	packages/ui/src/components/shell/__e2e__/output-home/04-mobile-launcher-single-page.png
#	packages/ui/src/components/shell/__e2e__/output-home/05-desktop-home.png
#	packages/ui/src/components/shell/__e2e__/output-home/07-desktop-edge-buttons-home.png
#	packages/ui/src/components/shell/__e2e__/output-home/08-desktop-edge-buttons-launcher.png
#	packages/ui/src/components/shell/__e2e__/output-home/09-desktop-notification-panel.png
#	packages/ui/src/components/shell/__e2e__/output-home/home-screen.html
#	packages/ui/src/components/shell/__e2e__/output-home/mobile-launcher-flow.webm
#	packages/ui/src/components/shell/__e2e__/run-home-screen-e2e.mjs
…root cause + fixed-build load

Old build reproduced #11612 as an empty reply thread (silent bf16 mul_mm failure, no GPU/crash on sim); STT + vision driven through the UI; the rebuilt bf16 MSL-3.1 + recoverable + OOM-admission slice installs/launches/loads without crashing. Completed sim reply not captured (sim translated-Metal pipeline compile is pathologically slow — env characteristic, not a product defect; real inference proven on Mac fused lib + device bf16-loads).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…aths

Adds testCloudOnboardingChatAndVoice + testLocalOnboardingChatAndVoice to the
device capture harness: completes the real in-chat first-run conductor, sends a
prompt + awaits reply (chat), taps mic to assert recording state (voice, with
SpringBoard permission-grant). Filmstrip + AX dumps; honest skips on AX variance
/ cloud-session-gated OAuth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tal3.1 wedges the sim)

The #11612 bf16 fix bumped all iOS metallib slices to metal3.1 so the A-series
device slices emit kernel_mul_mm_bf16_f32. But the simulator's translated Metal
toolchain wedges compiling that metal3.1 bf16 kernel set at model load (fixed
slice pegs a core 20+ min with flat RSS, never finishes; the pre-fix 2.4 slice
loaded fine). The simulator doesn't need embedded bf16 kernels — the runtime
bf16-library gate (ggml_metal_device_init) routes bf16 ops to CPU when the kernel
is absent — so generation still runs. Gate metal3.1 to the physical-device slices
only; simulator slices revert to ios-metal2.4. Override via ELIZA_IOS_SIM_METAL_STD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, wedge is in the #11612 fixed-build load path (likely OOM-admission probe)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ted behind listLocalAgentBackups)

The first-run greeting+placement choice is seeded only after
client.listLocalAgentBackups() resolves, which waits on the agent API — on a
fresh device the local engine is still waking, so 30s was too short. Poll up to
the agent-ready budget (≤300s) for the placement choice before skipping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…) + document WKWebView XCUITest-invisibility blocker (#11612 device reply)

The on-device local-onboarding capture is blocked because the Capacitor WKWebView
onboarding controls are not exposed to XCUITest's element tree — the placement
choice renders on screen (evidence screenshot) but no button/staticText is
queryable. Hardened tapWebChoice with substring matching + a coordinate-tap
fallback on a matching staticText (helps any exposed web content) but the deeper
fix is app-level WKWebView accessibility. Real-device tap injection has no other
route (idb is sim-only; pymobiledevice3 has no touch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d + locked-composer placeholder

The onboarding-to-home ui-smoke suite (10 specs, desktop + mobile) had been
fully red: the shared helper still asserted the removed runtime:other choice
(the chooser is now cloud/local/remote — #11509) and the old locked-composer
placeholder 'Choose an option to continue' (shipped text is 'Tap a highlighted
option above to continue'). Point the runtime assertion at 'remote', reach the
provider:other handoff via runtime local, and match the real placeholder. All
10 pass — cloud + local + cloud-inference + other-provider + remote + tutorial,
desktop and mobile touch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…GPU-OOM fix loads gemma4-2b on A18 (0/36 GPU offload, no OOM)

BootCaptureUITests: raw normalized-coordinate taps for the invisible WKWebView
onboarding rows (placement + provider) + a re-send-until-ready chat loop. On-device
ggml.log proves the #11612 memory-admission fix: eliza-1-2b (gemma4, 601 tensors)
loads with n_gpu_layers reduced to 0/36 to fit the A18 working set — no
kIOGPUCommandBufferCallbackErrorOutOfMemory, no ret=-3, no jetsam (pre-fix OOM'd
at 999). Final generated-reply text pending one run with iOS Enable-UI-Automation
active (re-prompts passcode after idle — iOS security gate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… to stop the auto-lock stall (#11841)

On iOS the on-device runtime streams the multi-GB Eliza-1 model download
in-process (JSContext compat / sideload path). When the device auto-locks
mid-transfer the runtime is suspended and the download stalls at
"Loading eliza-1-2B…". This wires a reference-counted `keep_awake_set`
host function on the `__ELIZA_BRIDGE__` compatibility bridge so the
downloader disables `UIApplication.shared.isIdleTimerDisabled` for the
duration of an active transfer and restores it in the job's finally
(balanced acquire/release; overlapping downloads compose).

- KeepAwakeBridge.swift: new reference-counted idle-timer bridge module,
  installed from BridgeInstaller into the JSContext and held on BridgeKit.
- downloader.ts: setDownloadKeepAwake(true) on entering "downloading",
  (false) in the runJob finally — swallowed best-effort, never fails a
  download; safe no-op off-device and on the full-Bun engine.
- downloader.test.ts: 3 real tests over the download harness — releases on
  completion, releases on failure (balanced), and a throwing bridge never
  breaks the transfer. Full suite 20/20 green; typecheck + biome clean.

Scope: this removes the common *auto-lock* stall on the sideload/JSContext
path. A *manual* lock or backgrounding still needs the native background
URLSession download — the tracked #11841 primary fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
the manual redirect loop rebuilt each hop init from params.init, re-sending
method+body on every hop. 624325a (#11693) stripped credential headers
cross-origin but left the body: a POST with a secret body that a compromised
server 302s to an attacker origin re-POSTed the full body there. it also
deviated from standard fetch, which the header fix cites: 301/302-POST and any
303 rewrite to a bodyless GET.

reproduce that rewrite (whatwg http-redirect fetch): 301/302 on POST and 303 on
any non-GET/HEAD method switch to GET, drop the body, and delete the
body-describing headers (content-type/length/...); 307/308 still preserve
method+body. fixes both the cross-origin body exfil and the GET-after-303
functional deviation.

(cherry picked from commit 70e5c35)
…ub-agents via OPENCODE_CONFIG_CONTENT

gateway mode (86bc107, #11651) promised a child env dump contains no
raw provider key, but an opencode spawn broke the invariant twice over:
buildOpencodeSpawnConfig embedded the raw cerebras/opencode/cloud key as
provider options.apiKey inside the JSON assigned to
env.OPENCODE_CONFIG_CONTENT, and applyModelGatewayEnv — which runs after
and deletes only the seven named env keys — never touched it. the child
env carried the raw key AND the opencode child pointed its baseURL
straight at api.cerebras.ai / eliza cloud, bypassing the gateway.

- buildOpencodeSpawnConfig checks resolveModelGatewayConfig() first,
  before any credential read (env, runtime settings, or config-env —
  setting() falls back to all three, so env-key deletion alone could
  never fix this). in gateway mode it returns a gateway-pointed
  openai-compatible provider config: nothing raw to leak, and the child
  routes through the gateway instead of bypassing it.
- applyModelGatewayEnv enforces the stated invariant literally: raw
  values captured from the named keys are swept out of every remaining
  env value, so a composite carrier (a JSON blob like
  OPENCODE_CONFIG_CONTENT) that still embeds a raw key is dropped whole.
  fail-closed backstop for future merge steps.

off-mode behavior is byte-identical; a new off-mode test pins the legacy
direct-cerebras wiring. model-gateway-env.test.ts now exercises
agentType opencode — the untested gap that hid this.

(cherry picked from commit 3f6f49a158371957d2d50ffa8e723d5adbb471e6)
… agent-wake probe

Fresh-install onboarding stranded the user at a locked composer ('Tap a
highlighted option above to continue') with NO visible choices whenever the
local agent was slow/wedged to wake: the conductor only seeded the greeting +
runtime choice inside the then()/catch() of client.listLocalAgentBackups(),
which hits the still-booting agent API and can hang indefinitely.

Now the greeting + runtime choice seed synchronously on mount, independent of
agent readiness; the local-backup probe is a purely additive upgrade that
appends the restore choice below the greeting only if backups exist AND the
user hasn't already advanced past it (atomic updater, no double-seed). Two new
conductor tests cover the never-settling probe (greeting still appears + a
runtime pick works) and the racing-late-backups guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Shaw and others added 12 commits July 3, 2026 05:12
… + add onboarding probe

The assistant message bubble in ContinuousChatOverlay's ThreadLine wrapped its
content in role=button aria-label="Show message actions" whenever it had
row-actions. WebKit maps an ARIA button to an ATOMIC accessibility leaf (its
aria-label becomes the node name and ALL descendants are dropped), so the
onboarding greeting text and every ChoiceWidget button vanished from the native
AX tree: unreachable by VoiceOver AND by on-device XCUITest (only the collapsed
"Show message actions" node was exposed).

Fix: a choice/form/followups-bearing assistant turn (every first-run onboarding
turn) now stays a plain container -- bubbleInteractive gains a
!hasInteractiveWidget guard (detected via the existing choice/form/followups
parsers). Normal turns keep the tap-to-reveal Copy/Play/Edit row unchanged.
Also adds an sr-only onboarding-state-probe (mirroring chat-detent-probe /
home-launcher-page-probe) exposing the current first-run step id + choice ids
so on-device automation can observe/drive onboarding deterministically. Two new
unit tests cover both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…path (#11841)

The earlier keep-awake fix (6ea36ad) only installed keep_awake_set on
the JSContext compat bridge — but the production/sideload iOS build runs
the full-Bun engine (confirmed on device: `compiledEngine=full-bun`,
`[FullBunEngineHost] loaded ElizaBunEngine abi=3`), where that host
function was unregistered and the downloader's call was a silent no-op.
This routes it through the full-Bun host_call path so the idle-timer hold
actually fires on the device that has the stall.

- FullBunEngineHost.swift: add a `keep_awake_set` case to the host_call
  switch → KeepAwakeBridge.shared.setEnabled(enabled).
- KeepAwakeBridge.swift: add a process-wide `shared` singleton + public
  `setEnabled(_:)` so both engine paths drive one ref-counted idle-timer
  holder; BridgeInstaller now installs the shared instance.
- ios/bridge.ts: define `globalThis.__ELIZA_BRIDGE__.keep_awake_set` at
  boot (full-Bun) as a fire-and-forget `callIosHost("keep_awake_set", …)`,
  so the in-process downloader reaches native. Only defines it when the
  engine hasn't already; failures can't affect the download.

typecheck (bridge.ts) + biome clean; KeepAwakeBridge parses clean; the
native case uses existing helpers (boolValue/encodeHostEnvelope). Device
verification (build → deploy → download completes with the timer held)
follows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ixes local onboarding "not found" loop

On a dev iOS device the local agent runs through the JSContext compatibility
kernel (ios-local-agent-kernel.ts), which implemented GET /api/first-run/status
but had NO POST /api/first-run handler. finishLocal's submitFirstRun POST fell
through to the catch-all 404 ("Not found"); the conductor's seedError turned
that into a re-offer of the "where should your agent run?" runtime chooser — the
on-device "local path → not found → pick the targets again" loop the user hit.
(The full-Bun store build + the mocked web e2e both serve the route, which is
why neither caught it.) Add the handler: accept + ack the finish payload
(no-op success matching the full-Bun bundle). Regression test asserts the
kernel serves it 200 instead of 404.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ngine (split JSC-free core)

The full-Bun podspec source list is explicit and omits JavaScriptCore, so
`bridge/KeepAwakeBridge.swift` (which imported JavaScriptCore) was never
compiled there — `FullBunEngineHost` referencing `KeepAwakeBridge.shared`
failed to build (`cannot find 'KeepAwakeBridge' in scope`, xcodebuild 65).

Split it: the JavaScriptCore-free ref-counted idle-timer core stays in
`KeepAwakeBridge.swift` (now added to the full-Bun source list), and the
JSContext `install(into:)` closure moves to a compat-only
`KeepAwakeBridge+JSContext.swift` (picked up by the compat glob, excluded
from the full-Bun explicit list). Verified via `pod install` with
ELIZA_IOS_FULL_BUN_ENGINE=1: KeepAwakeBridge.swift is now in the Pods
project, the JSContext extension is not.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ume into chat after WebView eviction

On a native device the first-run cloud login opens an external browser
(SFSafariViewController) that backgrounds the WebView; iOS frequently
cold-launches the app on return, wiping the conductor's in-memory flow state and
the volatile __ELIZA_CLOUD_AUTH_TOKEN__ global. The result was a "restart": the
user was bounced back to "where should your agent run?" instead of landing in
chat.

Two durable channels close the gap:
- Persist the cloud token to the steward-session store (getCloudAuthToken reads
  it first) on poll/direct auth success, so elizaCloudConnected recomputes true
  after relaunch.
- A cloud-login resume marker (localStorage) armed at cloud/hybrid pick time and
  cleared on completion or a fresh runtime re-pick. On relaunch the conductor
  rehydrates the interrupted flow (draft + pending-resume) and continues into
  chat instead of re-seeding the greeting.

Fixes the effect-ordering trap where the auto-resume effect fired before the
mount effect armed the marker: the resume body is extracted into runCloudResume
and kicked directly when the connection is already live at mount.

Tests: first-run-cloud-resume unit (round-trip/validation), conductor
regressions (marker armed on pick, resume-on-relaunch with no greeting restart,
cleared on fresh local pick). 26 pass; typecheck + biome clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vq3VfLC939jy9e4aA12KGP
…sh first-run (MoonCycles A18)

Fresh-install XCUITest capture: locked onboarding chooser → composer unlocked after the
local finish path (POST /api/first-run) succeeds — no "not found → pick again" loop.
Plus README documenting both onboarding fixes, the 26 passing tests, and the remaining
manual cloud-OAuth step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lanner and trajectories can tell siblings apart

The agent picks actions by name + description (+ similes at Stage 1). Several
siblings share nouns/similes with no "when NOT to use" guidance, and duplicate
action/provider names were dropped silently at debug level. This lands the
high-confidence, mechanism-level disambiguation:

- routingHint is now the canonical "use when X; do NOT use when Y -> OTHER"
  carrier (documented in the Action type). Unlike `description` it is prepended
  verbatim to the planner tool (never compressed / 160-char truncated) and is
  captured in trajectories via the planner stage's model.tools.
- Populate routingHint on the top cross-domain collisions: orchestrator TASKS
  (reciprocal to SCHEDULED_TASKS: reminders/routines -> SCHEDULED_TASKS/OWNER_*),
  WEB_SEARCH (external web only; private data -> MEMORY; a URL -> WEB_FETCH),
  MEMORY, USE_SKILL, MCP, MESSAGE (reply -> REPLY, channel membership -> ROOM,
  feed -> POST), OWNER_GOALS (goals vs reminders/todos/routines).
- Prune generic cross-cutting similes: USE_CAPABILITY/RUN_CAPABILITY off
  USE_SKILL; USE_TOOL/RUN_TOOL/EXECUTE_TOOL/INVOKE_TOOL/GET_RESOURCE/… off MCP;
  ROOM off MESSAGE (collided with the ROOM action).
- Resolve the live SHELL x2 collision: rename the agent terminal action
  SHELL -> TERMINAL_SHELL (the coding-tools SHELL is the fuller impl and already
  owns the generated SHELL spec), drop its EXEC/RUN_COMMAND/CALL_MCP_TOOL
  similes, add a routingHint, keep it in the terminal-context compaction keep-set.
- Fix REPLY's description that pointed at connector send-actions that no longer
  exist -> MESSAGE(action=send)/POST (core.json + regenerated action-docs).
- registerAction/registerProvider now warn (was debug) on a duplicate name so
  load-order-dependent collisions (SHELL, SETTINGS/ROLES/CHARACTER/MCP providers)
  surface at boot instead of silently first-wins-dropping.
- Document OWNER_GOALS x2 as an intentional two-topology design (PA primary,
  plugin-goals fallback; same GoalsService) so it isn't "fixed" into a regression.

Verified: typecheck clean (core, agent, mcp, agent-skills, orchestrator);
prompts tests 34/34; action-docs regen scoped to the REPLY lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ive for the local model download

Two fixes uncovered while proving the #11841 on-device model download:

1) Voice/command onboarding parser (first-run.ts): the on-device option is
   labelled "On this device (recommended)", but the inference-step parser's
   cloud regex matched "recommended" — so an explicit local pick
   ("on this device (recommended)") set localInference="cloud-inference"
   and the local model download never triggered. "recommended" is not a
   cloud signal; cloud options still match on cloud/eliza cloud/online, and a
   bare "recommended" falls through to the same cloud-inference default. Added
   a regression test asserting the labelled option yields all-local +
   firstRunDownloadsLocalModel === true.

2) On-device onboarding capture (BootCaptureUITests + ios-device-capture): the
   local model download is fired fire-and-forget by first-run finish, but the
   XCUITest tore the app down before the agent-wait + download completed, so the
   ~5GB pull never landed in prior capture runs. Added an opt-in
   holdForLocalModelDownload step (ELIZA_LOCAL_MODEL_DOWNLOAD_WAIT_SECONDS,
   default 0) that keeps the app foregrounded — touching the AX tree so XCUITest
   doesn't idle-kill it and filming the wait — so the download runs to
   completion; [Downloader] completion + the native keep_awake_set hold are
   verified from device syslog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…on on the tool stage

The tool-execution trajectory stage (RecordedToolStage) recorded only
name/args/result — a reviewer or training pipeline judging "did the planner
have enough to disambiguate this action?" had to cross-reference the preceding
planner stage's model.tools. Capture the exposed ToolDefinition.description
(the action's routingHint + compressed description — exactly what the planner
saw) on the execution record so it is self-contained. Sourced from the
type-safe PlannerLoopParams.tools, not runtime.actions. Rendered in the markdown
review as `- description:`. Test covers JSON round-trip + markdown render.

Verified: core typecheck clean; trajectory-recorder 37/37; planner-loop 92/92.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…on descriptions

The action/provider description text shown to the planner was hard-truncated to
160 chars (compressPromptDescription) and the same cap was enforced as a lint
rule (description-compressed-lint) — so any "use when / do NOT use when" clause
past 160 chars was silently cut before the model saw it, and 22 baked
descriptions in the generated docs were already clipped with "...".

There is no reason to cap the text out to the model. This removes both caps:
- compressPromptDescription now returns the full normalized/compressed text (no
  MAX_DESCRIPTION_LENGTH, no truncateDescription); code spans/URLs/paths still
  protected, filler still stripped, but nothing is cut.
- lintDescriptionCompressed drops the length rule (keeps the filler/abbrev/
  imperative-lead style rules).
- Regenerated action-docs.ts + plugins.generated.json: all previously-truncated
  descriptionCompressed values are now full (remaining "..." are legit content:
  example texts, [[x,y],...] notation).

Verified: prompts 34/34, core description-compressed-lint 10/10; core + prompts
typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
evm/actions/transfer.ts exported a `transferAction` (name "WALLET") that was
never registered — the live WALLET action is walletRouterAction, and this
subaction's implementation is the TransferAction class + buildTransferDetails
(both kept, still used by chains/registry.ts + evm/chain-handler.ts). Removing
the orphan const (zero references repo-wide) and its now-unused imports; the
live transfer path is untouched.

Verified: tsc + biome clean; no remaining references.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…unctuation

ebd5203 (#11573) fixed the dead e.g/i.e entries by matching [\w.]+ but
anchored the match with (?:^|\s), which rejects abbreviations preceded by
quotes/parens/asterisks ('"Dr' / '(Mr') that the original \b handled — the
tts first-sentence early-emit path chopped mid-name ('He cited "Dr.').
drop the anchor: leftmost matching already captures the maximal trailing
[\w.] run and any other char or start-of-string delimits it.

(cherry picked from commit 99511f2)
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review. (313 files found, 100 file limit)

Bypass the limit by tagging @greptile-apps to review.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84270314-15a1-465d-a4c4-9c766325d07f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/multi-account-login-verification

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lalalune

lalalune commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

⚠️ Not mergeable as-is — needs a rebase onto develop before it can land. Flagging so it isn't force-merged and silently reverts recent fixes:

Recommend: git fetch origin && git rebase origin/develop, resolve every conflict (keeping develop's #12082/#12059/#12052 changes), re-run bun run verify, then split the self-contained iOS #11841 keep-awake thread out if the rest of the 42-commit batch isn't ready — a 25.9k-line batch at 487-behind is very hard to land safely in one shot. Leaving unmerged for the swarm-branch owner. [fable-5]

@lalalune

lalalune commented Jul 3, 2026

Copy link
Copy Markdown
Member Author

Closing — this batched the shared swarm branch wholesale (42 commits, 318 behind develop, 23 conflicts) and is mostly redundant: the #11841 keep-awake work already landed on develop via #11897. The one genuinely-unmerged fix (the "recommended"→cloud misclassification) is split out clean in #12098.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants