fix: multi-user distillation + datetime in context + session log labels
Distillation was silently operating on scott/inara for all users due to ContextVar defaults. All three distill endpoints now require ?user=&persona= query params and validate them via persona.validate(). Memory distiller signatures changed from Optional to required positional args — no more global settings fallback. Scheduler now iterates all users/personas instead of hardcoding the primary user. - context_loader: inject current date/time as first system prompt section - session_logger: use get_user()/get_persona() from context instead of settings globals so Holly/Brian sessions show correct speaker labels - memory_distiller: system prompts now reference u.title()/p.title() instead of settings.user_name/settings.agent_name - distill router: Query(...) enforces params; _resolve() validates persona - scheduler: _all_personas() helper iterates every user/persona for distill - app.js: runDistill() now appends ?user=&persona= via _fileParams Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,7 +74,7 @@ def distill_short(username: str | None = None, persona: str | None = None) -> di
|
||||
}
|
||||
|
||||
|
||||
async def distill_mid(username: str | None = None, persona: str | None = None) -> dict:
|
||||
async def distill_mid(username: str, persona: str) -> dict:
|
||||
"""
|
||||
Ask the LLM to summarize MEMORY_SHORT.md → MEMORY_MID.md.
|
||||
Uses DISTILL_BACKEND_MID if set (e.g. "local"), otherwise primary_backend.
|
||||
@@ -82,8 +82,7 @@ async def distill_mid(username: str | None = None, persona: str | None = None) -
|
||||
from llm_client import complete
|
||||
from persona import set_context
|
||||
|
||||
u = username or settings.user_name.lower()
|
||||
p = persona or settings.agent_name.lower()
|
||||
u, p = username, persona
|
||||
set_context(u, p)
|
||||
|
||||
inara_dir = _persona_path(u, p)
|
||||
@@ -93,13 +92,15 @@ async def distill_mid(username: str | None = None, persona: str | None = None) -
|
||||
return {"error": "MEMORY_SHORT.md is empty — run distill/short first"}
|
||||
|
||||
budget_tokens = settings.memory_budget_mid
|
||||
persona_name = p.title()
|
||||
user_name = u.title()
|
||||
system_prompt = (
|
||||
f"You are {settings.agent_name}'s memory distillation system. "
|
||||
f"You are {persona_name}'s memory distillation system. "
|
||||
"Summarize the following recent session logs into a concise mid-term memory digest. "
|
||||
f"Target length: under {budget_tokens} tokens. "
|
||||
"Focus on: recurring themes, important decisions made, ongoing projects, "
|
||||
f"{settings.user_name}'s current state and priorities, and anything that should persist into future sessions. "
|
||||
f"Write in first person as {settings.agent_name} (e.g. '{settings.user_name} and I worked on...'). "
|
||||
f"{user_name}'s current state and priorities, and anything that should persist into future sessions. "
|
||||
f"Write in first person as {persona_name} (e.g. '{user_name} and I worked on...'). "
|
||||
"Use markdown headings. Be specific and concrete — no filler."
|
||||
)
|
||||
|
||||
@@ -126,7 +127,7 @@ async def distill_mid(username: str | None = None, persona: str | None = None) -
|
||||
}
|
||||
|
||||
|
||||
async def distill_long(username: str | None = None, persona: str | None = None) -> dict:
|
||||
async def distill_long(username: str, persona: str) -> dict:
|
||||
"""
|
||||
Ask the LLM to integrate MEMORY_MID.md into MEMORY_LONG.md.
|
||||
Uses DISTILL_BACKEND_LONG if set, otherwise primary_backend.
|
||||
@@ -134,8 +135,7 @@ async def distill_long(username: str | None = None, persona: str | None = None)
|
||||
from llm_client import complete
|
||||
from persona import set_context
|
||||
|
||||
u = username or settings.user_name.lower()
|
||||
p = persona or settings.agent_name.lower()
|
||||
u, p = username, persona
|
||||
set_context(u, p)
|
||||
|
||||
inara_dir = _persona_path(u, p)
|
||||
@@ -146,8 +146,9 @@ async def distill_long(username: str | None = None, persona: str | None = None)
|
||||
return {"error": "MEMORY_MID.md is empty — run distill/mid first"}
|
||||
|
||||
budget_tokens = settings.memory_budget_long
|
||||
persona_name = p.title()
|
||||
system_prompt = (
|
||||
f"You are {settings.agent_name}'s long-term memory curator. "
|
||||
f"You are {persona_name}'s long-term memory curator. "
|
||||
"You will receive the current long-term memory and a recent mid-term digest. "
|
||||
f"Integrate the new information into the long-term memory. Target: under {budget_tokens} tokens. "
|
||||
"Rules: preserve important historical facts; update or replace stale information; "
|
||||
@@ -170,7 +171,7 @@ async def distill_long(username: str | None = None, persona: str | None = None)
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
if not response_text.lstrip().startswith("# MEMORY_LONG"):
|
||||
response_text = (
|
||||
f"# MEMORY_LONG.md — {settings.agent_name} Long-Term Memory\n\n"
|
||||
f"# MEMORY_LONG.md — {persona_name} Long-Term Memory\n\n"
|
||||
f"*Last distilled: {now} via {backend}.*\n\n---\n\n"
|
||||
+ response_text
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user