You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Chara task layer: the middle layer the aspiration/goal split was missing — between the aspiration (the user-owned, read-only, never-completed why) and the in-session todo (the immediate step checklist). A task is the chara's own thread it carries over time: it adds / edits / seals its own, persisted to task.json, active ones riding every turn's volatile tail (recomputed per turn → cache-safe), surviving restarts, capped at 12 active. Why: a never-reachable aspiration gave no traction, and the old chara-mutable goal list was scattered and the chara "went on strike" once it emptied. A task is concrete enough to act on yet not digitally "completable" for every character — so the currency is "advance the thread + leave a real trace in whatever form fits your world", not "complete a project". Completion seals a task (immutable record); the aspiration's endlessness means the chara never runs dry, and it may keep none for a while. The value-direction still lives only in the user-owned aspiration — a task is purely instrumental. (33558a0, e222062)
Restart and Delete in chara settings, replacing the flawed old "clear-context" (which behaved like a half-delete): Restart (harmless, no confirm) bounces the chara's child process — unblocks a turn wedged by a bug AND applies pending card edits (the fresh process re-reads the frozen card; history is restored by make_session). Delete (confirm-gated, soft): the chara returns from awakened to not-awakened — off the board, its locked card off the deck — and its data is moved to ~/.lunamoth/.trash/ (recoverable, with an origin manifest), never erased; the name is freed for a clean re-wake. The deck template card it was woken from is untouched. (5f7b115)
Proactively wake the chara on background-job completion (live + chat): a finished background job (generate_image / delegate / background terminal) now wakes the chara to react to it, in both modes, via one shared path — because a job finishing is a synthetic USER turn, exactly your framing ("a tool return is also a user message"). Mechanism: StateSnapshot.pending_notices is a cheap, non-destructive peek; agent.stream_react() drains pending notices into context and runs the responsive reply loop; the dispatch react is a low-priority stream like idle — a real user send / event always supersedes it and it never supersedes a real turn (no way to wedge the stream lock); the supervisor idle loop, before the mode branch, re-reads a fresh snapshot and drives a one-shot react when notices are pending and no client is streaming. (cfc4a67)
Persisted reference images (参考图) in the asset library: the visual editor's reference tray was ephemeral (uploaded per generation, never saved) — it now persists in the card's asset library (loads the card's asset images on open; add/remove write through), so a reference survives leaving the view and keeps guiding generation. A tavern import (PNG drop + market cover) now lands its portrait as the sprite (立绘) AND a persisted reference (参考图), fixing the earlier mis-slotting into the keyvisual. (a82ad67)
Persisted send-queue + stream ordering: messages typed while a turn is in flight are queued and persisted (restored on remount, flushed one-per-turn at turn end); stream frames arriving during attach are buffered and replayed in order after history. Visual editor: confirm before deleting a persisted reference image (an irreversible asset unlink) + a hover-revealed remove (×) button. (bf65487)
Collapsible Profile sections + trimmed copy: Tasks / Skills / Memory now fold away (Memory defaults closed — it can be a wall of text; Aspiration stays always-open), with an on-brand uppercase-header toggle + a › chevron that rotates down when open + a soft reveal, light & dark. The copy drops its explanatory padding — the skills empty state is just "No skills yet." and tasks-empty is just "还没有任务 / No tasks yet". (6c08ab6, e47b3d4)
Fixes
Subagent (delegate) no longer blocks + enforced per-child timeout; re-enabled: delegate_task no longer blocks the turn — it runs as a background job like generate_image (the fan-out on a daemon thread, reporting via the completion queue), the call returns a {status: submitted} receipt immediately, the subagents run alongside the main agent, and their aggregated results drain as a synthetic user message at the next turn boundary. The per-child timeout is now enforced (it was defined but never applied — the root of the production "stuck" / "a stream is already in flight" hang): _run_fanout is always pooled and uses fut.result(timeout=…) → a real timed_out result, with shutdown(wait=False) so a hung worker can't re-block the return. (aec7516)
Atomic store writes + trim-by-id: the aspiration and task stores now write atomically (mkstemp → fsync → os.replace), eliminating a half-written corrupt file; completed-task trimming keys off a stable id instead of object id(); plus a sweep of stale wish comments. (b456a22)
CI: the release workflow's Node-20 actions moved to Node-24 (setup-uv v6→v8.2.0, action-gh-release v2→v3). (12c7233)