# `Agentic.Memory.ContextKeeper`

Per-workspace in-process working memory.

Maintains two data structures:

- **facts** — structured triples extracted from tool results and LLM responses
  (entity/relation/value). Capped at 500 entries, oldest dropped first.

- **working_set** — key-value pairs stored explicitly by the agent or loop stages.
  Supports TTL (seconds or `:infinity`) and priority (`:high`, `:normal`, `:low`).

Registered via `Agentic.Memory.ContextKeeperRegistry` so there is at most one keeper
per workspace. Survives session restarts but stops when the workspace disconnects.

# `fact`

```elixir
@type fact() :: %{
  entity: String.t(),
  relation: String.t(),
  value: String.t(),
  confidence: float(),
  source_turn: integer(),
  inserted_at: DateTime.t()
}
```

# `state`

```elixir
@type state() :: %{
  workspace_id: String.t(),
  facts: [fact()],
  working_set: %{required(String.t()) =&gt; working_entry()}
}
```

# `working_entry`

```elixir
@type working_entry() :: %{
  value: term(),
  ttl: integer() | :infinity,
  priority: :high | :normal | :low,
  inserted_at: DateTime.t()
}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_context`

```elixir
@spec get_context(String.t()) :: String.t() | nil
```

Return formatted context string for injection into system prompt.

Includes high-priority working set items and recent facts.

# `get_working_value`

```elixir
@spec get_working_value(String.t(), String.t()) :: term() | nil
```

Retrieve a value from the working set.

# `ingest`

```elixir
@spec ingest(String.t(), [fact()]) :: :ok
```

Ingest a list of facts from FactExtractor.

# `query`

```elixir
@spec query(String.t(), String.t()) :: {:ok, [fact()]}
```

Query facts matching a substring in entity or value fields.

# `running?`

```elixir
@spec running?(String.t()) :: boolean()
```

Check if a ContextKeeper is running for the given workspace.

# `set_working_value`

```elixir
@spec set_working_value(String.t(), String.t(), term(), keyword()) :: :ok
```

Store a key-value pair in the working set.

# `start_link`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
