File size: 1,704 Bytes
f5c4bfe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# src/memory/core.py
"""Core memory helpers.

Core memory is the always-in-prompt tier of MemGPT-lite's three-tier memory.
Backed by ADK session state under keys `user:core:persona` and `user:core:human`.
The `user:` prefix triggers ADK's user-scoped persistence.

Helpers accept any dict-like state object — `session.state` outside a tool call,
or `tool_context.state` inside one.
"""

from typing import Literal

Section = Literal["persona", "human"]

PERSONA_KEY = "user:core:persona"
HUMAN_KEY = "user:core:human"

_SECTION_TO_KEY = {"persona": PERSONA_KEY, "human": HUMAN_KEY}


def _key_for(section: str) -> str:
    """Resolve a section name to its state key. Raises ValueError on bad input."""
    if section not in _SECTION_TO_KEY:
        raise ValueError(f"section must be 'persona' or 'human', got {section!r}")
    return _SECTION_TO_KEY[section]


def get_block(state, section: str) -> str:
    """Return the contents of a core memory block. Empty string if unset."""
    return state.get(_key_for(section), "")


def append(state, section: str, content: str) -> None:
    """Append a fact to a core memory block as a new bullet line."""
    key = _key_for(section)
    current = state.get(key, "")
    state[key] = f"{current}\n- {content}" if current else f"- {content}"


def replace(state, section: str, old: str, new: str) -> bool:
    """Replace `old` with `new` in the given block.

    Returns True if the replacement happened, False if `old` was not found.
    Callers surface the miss as a tool error.
    """
    key = _key_for(section)
    current = state.get(key, "")
    if old not in current:
        return False
    state[key] = current.replace(old, new)
    return True