Skip to content

feat(recall): budgeted context pack β€” --pack on CLI, HTTP, and MCP (#1281 Phase 1) - #1284

Merged
ajianaz merged 2 commits into
developfrom
feat/recall-pack-phase1
Sep 23, 2026
Merged

ajianaz merged 2 commits into
developfrom
feat/recall-pack-phase1

Conversation

@ajianaz

@ajianaz ajianaz commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

What

New pack mode on all recall surfaces: returns a {selected, skipped, budget_used, budget_chars} envelope instead of a bare ranked list β€” rank-order preserving greedy fill of a caller-supplied character budget, with per-item skip reasons.

  • uteke-core: pack_mode module (pack_context + ContextPack); Uteke::recall_unified_packed wraps recall_unified. Multibyte-safe char counting; constant per-item overhead. Ranking is untouched β€” fusion stays the default strategy. Deterministic, LLM-free.
  • CLI: uteke recall --pack [--budget <chars>] [--exclude-ids <ids>], human + --json output. Entity/category filters honoured; --at/--related/--where are rejected loudly on the packed path (no silent drop).
  • HTTP: POST /recall fields pack, budget_chars, exclude_ids; pack honours the caller's search_type with identical 400 validation.
  • MCP: uteke_recall params pack, budget_chars, exclude_ids; tool schema updated.
  • Docs: cli-reference, mcp.md, CHANGELOG [Unreleased].

Skip reasons: excluded (memory IDs already injected this turn β€” the caller owns turn state, Uteke stays pull-based) and budget (no longer fits; cheaper lower-ranked items may still fill residual space).

Why

Closes #1281 (Phase 1). Three independent users on the launch threads asked for exactly this: "the layer that decides what deserves to be present for this turn" (@roscherveniak), "dumps too much into context or misses the one note that mattered" (@0xhashlol), "retrieval that trusts it blindly" (@Synorb). Per the issue: Phase 1 = budget pack (this PR); Phase 2 = MMR diversity, an experiment gated on LongMemEval + redundancy benchmarks β€” intentionally NOT included here.

Testing

  • Unit: pack_mode 5/5 (rank order, exclusion, zero budget, residual-budget fill, multibyte).
  • Integration: new server API test β€” envelope shape, exclusion reporting, impossible budget; uteke-server 37/37 green; workspace suite green before test additions; clippy + fmt + cora review clean.
  • Live E2E (scratch UTEKE_HOME, real ONNX embeddings): remember Γ—3 β†’ --pack human output lists selected items with scores; JSON envelope 3 selected / 235 of 4000 chars; --exclude-ids reports exactly the excluded IDs with reason=excluded; --budget 120 selects 1 item (60 chars) and skips 2 as budget.

…1281 Phase 1)

Adds a selection primitive over unified recall: rank-order preserving
greedy fill of a caller-supplied character budget.

- uteke-core: new pack_mode module (pack_context + ContextPack envelope
  {selected, skipped, budget_used, budget_chars}); Uteke::
  recall_unified_packed wraps recall_unified. Skip reasons: excluded
  (caller-supplied memory IDs already injected this turn) and budget
  (no longer fits). Char-counted (multibyte-safe), per-item overhead
  constant. Ranking untouched β€” fusion stays the default strategy;
  deterministic, LLM-free. 5 unit tests.
- CLI: recall --pack / --budget <chars> / --exclude-ids <ids> with
  human + --json output. Entity/category filters are honoured; the
  packed path loudly rejects --at/--related/--where instead of
  silently dropping them.
- HTTP: POST /recall accepts pack, budget_chars, exclude_ids; pack
  honours the caller's search_type with the same 400 validation as the
  plain path; integration test covers envelope shape, exclusion
  reporting, and an impossible budget.
- MCP: uteke_recall accepts pack/budget_chars/exclude_ids; tool schema
  updated.
- Docs: cli-reference.md flags + examples, mcp.md tool description,
  CHANGELOG [Unreleased].

Phase 2 (MMR diversity) intentionally NOT included β€” experiment gated
on LongMemEval + redundancy benchmarks per #1281.

Testing: pack_mode 5/5; uteke-server 37 live tests green incl. the new
pack API test; workspace suite green before test additions. Live E2E
against a scratch UTEKE_HOME with real ONNX embeddings: remember x3,
--pack human + JSON envelope (3 selected, 235/4000 chars), --exclude-ids
reports reason=excluded for the right IDs, --budget 120 fills 1 item at
60 chars and skips 2 as budget.
if req_data.pack {
let parsed_search_type = match req_data.search_type.as_deref() {
Some("memory") => uteke_core::SearchType::Memory,
Some("doc") => uteke_core::SearchType::Document,
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

πŸ” Cora AI Code Review

βœ… No issues found. Code looks good!


Review powered by cora-code Β· BYOK Β· MIT

CodeCora review on #1284 flagged that the pack branch validated only
search_type: a request with pack+at silently returned non-time-travel
results while the plain path honours the filters (and the CLI pack path
already rejects --at loudly).

- POST /recall with pack + at/after/before now returns the same 400 as
  the CLI contract; integration test extended.
- docs/api-reference.md regenerated via docgen for the new public
  recall_unified_packed surface (API Docs Fresh gate).
@ajianaz
ajianaz merged commit 11730c2 into develop Sep 23, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

recall pack mode: budgeted, diversity-aware context selection (LLM-free, design-first)

2 participants