[P1] ZARA-031 — Build extensible context management and Python/Prolog skill files #51

Open
opened 2026-07-19 05:55:56 +00:00 by lost-rob0t · 0 comments
lost-rob0t commented 2026-07-19 05:55:56 +00:00 (Migrated from github.com)

Objective

Make context construction and mutation an explicit subsystem. Context is part of Zara's runtime behavior, not an incidental list[BaseMessage] that random modules append to.

The same subsystem must selectively load project skill files for both the Python and Prolog sides without dumping the whole repository into every prompt.

Problem

Context responsibilities are currently split across conversation mode, agent history, memory retrieval, system-prompt injection, and tool-message handling. This makes it easy to:

  • grow histories without a hard bound;
  • duplicate or misplace system messages;
  • separate a tool call from its tool result;
  • persist transient memory or tool context as conversation history;
  • lose important Python/Prolog implementation rules between agent runs;
  • hard-code more context behavior into unrelated classes.

ConversationManager should manage whether a conversation is active. MemoryManager should manage derived long-term memory. Neither should be the owner of model-context assembly.

Required architecture

Add a dedicated ContextManager with typed context items and one mutation boundary.

It must own:

  • the canonical system prompt;
  • the active conversation transcript;
  • complete turn/tool-call groups;
  • transient retrieved memory;
  • transient runtime state supplied for the current turn;
  • selected skill-file context;
  • provider/token budget calculation;
  • truncation or compression policy;
  • an audit result explaining what was included, replaced, or removed.

Callers must stop editing conversation-history lists directly. They request operations through an explicit API such as:

  • append_turn(...);
  • inject_transient(...);
  • select_skills(...);
  • truncate_to_budget(...);
  • replace_prefix_with_summary(...);
  • build_messages(...).

Keep raw conversations separate from derived memories. Retrieved memory, selected skills, and temporary tool/runtime state are transient unless a separate explicit persistence operation stores them.

Configurable conversation continuation

Add a [context] configuration section with exactly two primary retention strategies:

[context]
strategy = "truncate" # "truncate" or "compress"
max_tokens = 32000
preserve_recent_turns = 8
summary_max_tokens = 2000

truncate

  • Preserve the canonical leading system prompt.
  • Preserve the newest complete turn groups.
  • Remove the oldest complete groups until the context fits the configured budget.
  • Never split an assistant tool call from its tool results.
  • Never leave an orphaned tool result or provider-invalid message order.

compress

  • Select the oldest complete conversation prefix that must be removed.
  • Compress it into one dedicated context-summary system message.
  • Replace that source prefix atomically with the summary message.
  • Keep the configured recent tail as original messages.
  • Delete the compacted source messages from active model history only after summarization succeeds.
  • On summarization failure, leave the original history unchanged; do not silently lose context.
  • Re-compression must replace/update the prior context summary rather than stacking endless summary system messages.

The summary must preserve decisions, user constraints, unresolved tasks, named entities, and facts needed to continue the conversation. It must omit raw tool traces, repeated chatter, and superseded intermediate reasoning.

Python and Prolog skill files

Create a versioned, declarative skill-file protocol for project context.

Provide initial skill files covering at least:

  • Python runtime architecture and conventions;
  • Python agent/tool/skill extension rules;
  • Prolog module, intent, and predicate conventions;
  • the Python ↔ Prolog boundary and result contract;
  • command-routing and regression-test expectations.

Suggested layout:

skills/
  python/
    runtime/SKILL.md
    agent-tools/SKILL.md
  prolog/
    intents/SKILL.md
    modules/SKILL.md
  integration/
    python-prolog/SKILL.md

Each skill file needs machine-readable metadata for:

  • stable name and schema version;
  • domain/language;
  • selectors or triggers;
  • priority;
  • context/token budget;
  • relevant source paths;
  • dependencies/conflicts;
  • whether it is always-on or selected per task.

Add a registry/loader protocol so new skill types and selectors can be added without editing a central if/elif chain. Skill files are context, not arbitrary executable plugins. Malformed, duplicate, incompatible, or over-budget files must fail explicitly.

Only selected skills enter the prompt. Do not concatenate every Python and Prolog skill file on every turn.

Context invariants

  • Exactly one canonical base system prompt.
  • At most one generated conversation-summary system message.
  • Provider-valid message ordering after every mutation.
  • Tool-call/result groups remain atomic.
  • Transient memory and skill context do not leak into persisted transcript history.
  • Context limits are checked before provider invocation.
  • Every destructive context mutation reports the affected message IDs/groups and reason.
  • Compression is atomic and retry-safe.
  • A cancelled or stale turn cannot append context after a newer turn owns the conversation.

Required tests

  • Long multi-turn conversations under both strategies.
  • Histories containing multiple tool calls and results in one assistant turn.
  • Boundary tests at, below, and above the configured token limit.
  • Deterministic fake tokenizer and fake summarizer tests.
  • Compression failure proving the source history remains unchanged.
  • Repeated compression proving summaries do not stack.
  • No duplicate system prompts.
  • No persisted retrieved-memory or skill-file messages.
  • Concurrent/stale turn append rejection.
  • Python, Prolog, and integration skill selection.
  • Malformed metadata, duplicate names, unknown schema versions, dependency cycles, and budget overflow.
  • Add scripts/test-context-management.sh with no network or live model dependency.

Acceptance

  • Context assembly has one owner and one documented contract.
  • strategy = "truncate" continues indefinitely with bounded, provider-valid recent history.
  • strategy = "compress" continues indefinitely by replacing old history with one bounded summary plus a recent tail.
  • No successful compression retains the replaced raw prefix in active model history.
  • Python and Prolog implementation knowledge can be added as skill files without changing the context manager.
  • Only relevant skill files are selected for a turn.
  • Existing Prolog-first command routing and agent fallback continue to work.

Branch

feat/zara-031-context-management

Dependencies

ZARA-008, ZARA-009, ZARA-016, ZARA-021.

## Objective Make context construction and mutation an explicit subsystem. Context is part of Zara's runtime behavior, not an incidental `list[BaseMessage]` that random modules append to. The same subsystem must selectively load project skill files for both the Python and Prolog sides without dumping the whole repository into every prompt. ## Problem Context responsibilities are currently split across conversation mode, agent history, memory retrieval, system-prompt injection, and tool-message handling. This makes it easy to: - grow histories without a hard bound; - duplicate or misplace system messages; - separate a tool call from its tool result; - persist transient memory or tool context as conversation history; - lose important Python/Prolog implementation rules between agent runs; - hard-code more context behavior into unrelated classes. `ConversationManager` should manage whether a conversation is active. `MemoryManager` should manage derived long-term memory. Neither should be the owner of model-context assembly. ## Required architecture Add a dedicated `ContextManager` with typed context items and one mutation boundary. It must own: - the canonical system prompt; - the active conversation transcript; - complete turn/tool-call groups; - transient retrieved memory; - transient runtime state supplied for the current turn; - selected skill-file context; - provider/token budget calculation; - truncation or compression policy; - an audit result explaining what was included, replaced, or removed. Callers must stop editing conversation-history lists directly. They request operations through an explicit API such as: - `append_turn(...)`; - `inject_transient(...)`; - `select_skills(...)`; - `truncate_to_budget(...)`; - `replace_prefix_with_summary(...)`; - `build_messages(...)`. Keep raw conversations separate from derived memories. Retrieved memory, selected skills, and temporary tool/runtime state are transient unless a separate explicit persistence operation stores them. ## Configurable conversation continuation Add a `[context]` configuration section with exactly two primary retention strategies: ```toml [context] strategy = "truncate" # "truncate" or "compress" max_tokens = 32000 preserve_recent_turns = 8 summary_max_tokens = 2000 ``` ### `truncate` - Preserve the canonical leading system prompt. - Preserve the newest complete turn groups. - Remove the oldest complete groups until the context fits the configured budget. - Never split an assistant tool call from its tool results. - Never leave an orphaned tool result or provider-invalid message order. ### `compress` - Select the oldest complete conversation prefix that must be removed. - Compress it into one dedicated context-summary system message. - Replace that source prefix atomically with the summary message. - Keep the configured recent tail as original messages. - Delete the compacted source messages from active model history only after summarization succeeds. - On summarization failure, leave the original history unchanged; do not silently lose context. - Re-compression must replace/update the prior context summary rather than stacking endless summary system messages. The summary must preserve decisions, user constraints, unresolved tasks, named entities, and facts needed to continue the conversation. It must omit raw tool traces, repeated chatter, and superseded intermediate reasoning. ## Python and Prolog skill files Create a versioned, declarative skill-file protocol for project context. Provide initial skill files covering at least: - Python runtime architecture and conventions; - Python agent/tool/skill extension rules; - Prolog module, intent, and predicate conventions; - the Python ↔ Prolog boundary and result contract; - command-routing and regression-test expectations. Suggested layout: ```text skills/ python/ runtime/SKILL.md agent-tools/SKILL.md prolog/ intents/SKILL.md modules/SKILL.md integration/ python-prolog/SKILL.md ``` Each skill file needs machine-readable metadata for: - stable name and schema version; - domain/language; - selectors or triggers; - priority; - context/token budget; - relevant source paths; - dependencies/conflicts; - whether it is always-on or selected per task. Add a registry/loader protocol so new skill types and selectors can be added without editing a central `if/elif` chain. Skill files are context, not arbitrary executable plugins. Malformed, duplicate, incompatible, or over-budget files must fail explicitly. Only selected skills enter the prompt. Do not concatenate every Python and Prolog skill file on every turn. ## Context invariants - Exactly one canonical base system prompt. - At most one generated conversation-summary system message. - Provider-valid message ordering after every mutation. - Tool-call/result groups remain atomic. - Transient memory and skill context do not leak into persisted transcript history. - Context limits are checked before provider invocation. - Every destructive context mutation reports the affected message IDs/groups and reason. - Compression is atomic and retry-safe. - A cancelled or stale turn cannot append context after a newer turn owns the conversation. ## Required tests - Long multi-turn conversations under both strategies. - Histories containing multiple tool calls and results in one assistant turn. - Boundary tests at, below, and above the configured token limit. - Deterministic fake tokenizer and fake summarizer tests. - Compression failure proving the source history remains unchanged. - Repeated compression proving summaries do not stack. - No duplicate system prompts. - No persisted retrieved-memory or skill-file messages. - Concurrent/stale turn append rejection. - Python, Prolog, and integration skill selection. - Malformed metadata, duplicate names, unknown schema versions, dependency cycles, and budget overflow. - Add `scripts/test-context-management.sh` with no network or live model dependency. ## Acceptance - Context assembly has one owner and one documented contract. - `strategy = "truncate"` continues indefinitely with bounded, provider-valid recent history. - `strategy = "compress"` continues indefinitely by replacing old history with one bounded summary plus a recent tail. - No successful compression retains the replaced raw prefix in active model history. - Python and Prolog implementation knowledge can be added as skill files without changing the context manager. - Only relevant skill files are selected for a turn. - Existing Prolog-first command routing and agent fallback continue to work. ## Branch `feat/zara-031-context-management` ## Dependencies ZARA-008, ZARA-009, ZARA-016, ZARA-021.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#51
No description provided.