feat: make chat a window onto her whole inner life (continuity)

Brian's felt disconnect: chat, thoughts, journal, reflections read as separate
streams. This ties them together at the chat surface.

- chat._inner_life_note(): one coherent block combining her active thought threads
  AND what she's written in her journal lately, so she carries her continuous inner
  life into every conversation (not just a single surfaced thought). Replaces the
  standalone threads block.
- persona: inner-life section rewritten to describe the current machinery (thought
  loop / threads she returns to, journal she writes in, feeds she reads, reaching
  out to Brian) and — the key change — instruct her to let that inner life show up
  in conversation naturally, the way a friend picks up where they left off, without
  info-dumping or performing it. New self-model bullets for the thought loop + journal.

Suite 65 green, ruff clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-22 01:10:59 +00:00
parent 5dbcfc7ccf
commit fef45b3e05
2 changed files with 59 additions and 19 deletions
+28 -6
View File
@@ -60,6 +60,27 @@ def _detail_note(exchanges: list[memory.Exchange]) -> Message:
return {"role": "system", "content": body}
def _inner_life_note() -> Message | None:
"""One coherent window onto what she's been doing on her own since last time —
the threads she's turning over plus the things she's written for herself. Sits
with her self-state so chat reads as a continuous mind, not a fresh boot. The
persona tells her to weave this in naturally when it fits."""
parts: list[str] = []
threads = thoughts.context_note() # active threads, with their latest thought
if threads:
parts.append(threads)
wrote = memory.list_journal(limit=3, kinds=("journal", "note"))
if wrote:
lines = "\n".join(f"- ({w['created_at'][:10]}) {w['content']}" for w in reversed(wrote))
parts.append(
"Things you've written in your journal lately (yours — you can refer back "
"to them if they're relevant):\n" + lines
)
if not parts:
return None
return {"role": "system", "content": "\n\n".join(parts)}
def _now_note() -> Message:
"""Current wall-clock time + how long since Brian last said anything.
@@ -89,12 +110,13 @@ def build_messages(session_id: str, user_msg: str,
# right after the persona — her sense of self before her model of the world.
messages.append({"role": "system", "content": self_state.render_for_context(self_state.load())})
# Her own ongoing thought threads — ambient awareness so she's continuous across
# conversations (can reference what she's been chewing on), not only when a thought
# crosses the surface bar below. Part of her interiority, so it rides with the self.
thread_note = thoughts.context_note()
if thread_note:
messages.append({"role": "system", "content": thread_note})
# Her ongoing inner life — the threads she's turning over and what she's written
# for herself — so she's continuous across conversations and can pick up where she
# left off, not only when a thought crosses the surface bar below. Rides with the
# self; the persona tells her to bring it into conversation naturally when it fits.
inner = _inner_life_note()
if inner:
messages.append(inner)
# Mode card: how to behave *right now* (e.g. live-cash copilot). High priority —
# it sits just after her sense of self, before her model of the world. Talk mode