1jehuang / 1jehuang/jcode

[Enhancement]: Memory candidate retrieval searches the full noisy session context instead of the focused query — relevant facts fall out of the top-N the judge can pick from

Open
#823 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

autonomous: no enhancement triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

In process_context (crates/jcode-base/src/memory_agent.rs) the candidate set
is retrieved with the full relevance context:

let context = memory::format_context_for_relevance(&messages);
...
let context_embedding = ...; // embedding of `context`
...
let candidates = memory_manager.find_similar_hybrid(
    &context,
    &context_embedding,
    memory::EMBEDDING_MAX_HITS,
)?;

A focused query (format_focused_query_for_relevance / focus_query_text) is
already built in the same function, but it is used only for the LLM rerank
step (rerank_candidates_consensus_attributed(&sidecar, &focused_query, ...)).
The full context includes <system-reminder> boilerplate, tool calls, tool
results and tool-error text, which dilutes the query embedding. Combined with a
small EMBEDDING_MAX_HITS (currently 10), the fact the task actually needs can be
ranked outside the pool the judge is even allowed to see, so no amount of judge
precision can recover it.

Impact

Users ask "how do I make X retrieve fact Y" and the answer is: it cannot, because
Y was never in the top-10. Concretely, in an ACP task asking about a Gitea access
token env var, the token fact was ranked below workflow/environment facts (the
noisy context was lexically closer to those), the judge never saw it, and the
agent answered incorrectly. This also silently defeats the whole two-stage design:
a good reranker over a bad candidate pool is bounded by the pool.

Root cause

process_context builds focused_query (line ~518) but retrieves candidates with
&context, &context_embedding (line ~657). The focused-query transform exists
precisely because the same function's benchmark notes that retrieval and reranking
degrade on long, noisy inputs:

/// Unlike [`format_context_for_relevance`], which concatenates up to a dozen
/// role-prefixed messages (including tool output) into one blob, this produces a
/// tighter query centered on the user's *current intent*. Memory retrieval and
/// (especially) cross-encoder reranking degrade badly on long, noisy inputs:
/// embeddings get diluted ...

Proposed change (implemented and verified locally)

Embed the focused query and retrieve candidates with it, falling back to the full
context only when the focused query is empty or identical to the context:

let (query_text, query_embedding) = if focused_query.trim().is_empty()
    || focused_query == context
{
    (context.clone(), context_embedding.clone())
} else {
    let q = focused_query.clone();
    let q_emb = match tokio::task::spawn_blocking(move || {
        crate::embedding_backend::embed_query_active(&q)
    })
    .await
    {
        Ok(Ok((emb, _model))) => emb,
        _ => context_embedding.clone(),
    };
    (focused_query.clone(), q_emb)
};
let candidates = memory_manager.find_similar_hybrid(
    &query_text,
    &query_embedding,
    memory::EMBEDDING_MAX_HITS,
)?;

Additionally, raise EMBEDDING_MAX_HITS (crates/jcode-base/src/memory.rs) from
10 to 30 so the judge sees a wider, more recall-complete pool before reranking:

/// Maximum embedding hits to verify with sidecar
pub const EMBEDDING_MAX_HITS: usize = 30;

Environment

  • jcode v0.68.0, Linux x86_64, DeepSeek provider, local all-MiniLM-L6-v2 embeddings.
  • ACP protocolVersion 1, host: Multica daemon.
  • Verified locally: with focused-query retrieval + pool 30, the token fact entered
    the judge's pool and was injected on the relevant turn.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in crates/jcode-base/src/memory_agent.rs, especially process_context, and trace how focused_query and context_embedding reach find_similar_hybrid. Check crates/jcode-base/src/memory.rs for EMBEDDING_MAX_HITS, then verify that focused-query retrieval falls back for empty or identical queries, uses a pool of 30, and admits the relevant fact in the described ACP scenario.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
ai
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.