AI Agent Migration

Context Window Management for Multi-File Migration Tasks

Decompose codebases into focused fragments rather than relying on larger context windows alone.

Cover illustration for “Context Window Management for Multi-File Migration Tasks”
Cover illustration for “Context Window Management for Multi-File Migration Tasks”

Multi-file migration tasks expose a mismatch between how codebases are organized and how LLMs process information. Managing that mismatch requires more than a larger context window. In practice, managing that mismatch requires decomposing the codebase, loading only the context each fragment needs, preserving decisions outside the session, and validating translations before downstream code depends on them.

Why multi-file migrations break LLM context in a way single-file tasks do not

A source file is not necessarily a self-contained unit of meaning. An AngularJS controller imports services that import other services, while its templates reference directives elsewhere in the repository. Those relationships shape how the code behaves in ways the controller alone cannot explain. A model shown only that file can therefore produce syntactically correct code that violates the surrounding system’s requirements. The failure begins at the boundary of the supplied context.

A core module modification may miss an interface requirement from another file, while a later translation may contradict an earlier change or lose a constraint established near the start of the session. These are distinct ways of losing coherence. Migration combines structured refactoring, which tolerates longer context reasonably well, with cross-document reasoning, which degrades sharply. Success at the local transformation does not establish that the model has preserved the relationships around it.

What the context window actually guarantees — and what it does not

The advertised context window defines an input limit. Attention weights are uneven, and the KV cache imposes physical memory constraints that can bind before the nominal token limit. Maximum Effective Context Window research formalizes the distinction through MECW, the point beyond which additional tokens yield diminishing returns. That effective boundary falls short of the advertised maximum and shifts with the task.

Two mechanisms explain why filling the window can weaken results. Liu et al.’s Lost in the Middle established a U-shaped accuracy curve, with key information used most reliably at the beginning or end of the input. Position is only part of the problem. Chroma Research’s Context Rot, published in July 2025, tested 18 production models and found that every model degraded monotonically as input length grew. The steepest decline appeared in the high-context range, well before a million-token window filled.

Larger windows raise the point at which degradation becomes conspicuous, while tokens remain unevenly useful. A million-token input full of irrelevant files can be less useful than a focused input containing the dependencies needed for one translation.

What happens when production migrations hit these limits without a plan

Google’s 2025 Google Ads migration to a wider integer type hit context limits even in a system built to automate the work. Teams from Google Core and Google Ads built the system with Google’s internal Gemini LLM. The Google migration paper identified context capacity as an explicit blocker. Some large files did not fit at all, requiring engineers to intervene manually. Automated edit generation did not eliminate the need to accommodate the shape and size of the source.

Other failures are less visible than rejected input. A model that loses earlier context can continue generating code consistent with what remains visible but inconsistent with decisions made earlier in the session. It need not flag that loss as uncertainty. Such code can pass review even when files contradict each other in ways that are hard to spot. Context planning must therefore address both interruptions that stop a migration and semantic errors that allow it to continue on the wrong basis.

Decomposing the codebase before any LLM call touches it

A planned migration starts by choosing translation units through static analysis rather than asking the model to discover workable boundaries. AlphaTrans, presented at FSE 2025, illustrates this neuro-symbolic approach. It decomposes repositories into field and method fragments, processes them individually, and reassembles the results. Each fragment gets the context it needs, including translated callee methods, its class declaration, and global variables or fields.

AlphaTrans produced nearly all syntactically correct output and functionally validated a strong majority in its reported evaluation. A prior GPT-4 attempt on Apache Commons CLI, translating Java to Python, had produced non-compilable output. The result supports decomposition. AlphaTrans handles build errors poorly, struggles with special syntax such as Java method and constructor overloading, and has scalability gaps in its fixed-rule approach.

Google’s system similarly separates structural work from edit generation. It uses Kythe for dependency discovery and deterministic AST filters for targeting before invoking the LLM. AST-based tools make deterministic changes, while the model uses context to make judgments within the chosen scope.

For that split in the work to succeed, fragments should follow method, class, or module boundaries. Static analysis should resolve callee context, and translation should proceed from callees to callers so downstream fragments receive translated signatures. This does not capture every runtime relationship. Dynamic dispatch and runtime polymorphism can escape static decomposition, so those cases should be flagged for human review.

Giving the model structural awareness without loading full source text

Decomposition narrows the immediate task, but the model still needs to understand where the fragment belongs. A repository map shows where the fragment belongs without loading every implementation. Aider illustrates this compressed structural representation through repository maps. The underlying strategy is independent of the tool. File paths, public interfaces, class declarations, and import relationships can expose the codebase’s shape at a much lower context cost than full source.

For migration, the map should also record file roles and each fragment’s current translation status. Implementation bodies outside the active translation, test boilerplate, generated files, and build artifacts do not belong in that representation. Placement then determines how accessible the retained information is. The same positional study found accuracy degradation of more than 30% when key information was buried in the middle compared with placement at the start or end. Critical interface requirements and return types should go in those stronger positions in the prompt.

Migration combines structured refactoring, which tolerates longer context reasonably well, with cross-document reasoning, which degrades sharply.

Managing state across a migration that spans many sessions

A repository map shows how the code is structured, but migration decisions also need a record that lasts across sessions. Over hours or days, agents accumulate chat history, file reads, tool results, and intermediate choices beyond any single window. The core recommendation is to store migration state in files or a database, including fragment status, translated signatures, type-mapping decisions, and human overrides. Each session can then load the current fragment and its dependencies without reconstructing the entire conversation.

Explicit checkpoints make that record dependable across session boundaries. Before a session ends, the agent or engineer should write its state and preserve the decisions future work must honor. Summarization can help, but it remains lossy. Cline illustrates the tooling direction through context-window usage tracking and automatic summarization when the window fills. A deliberate summary is preferable to silent loss, while the ledger remains the structured source for resuming work.

Su et al.’s 2026 Visual Evidence-Retaining strategy, VERA, proposes using visual memory to keep long interaction histories and reports that, across benchmarks, it cuts cumulative non-cache tokens by up to 63.1% compared with no compression. This is an emerging direction. Its relevance is to migrations involving diagrams, architecture documents, or legacy UI screenshots.

Validating translated fragments in isolation rather than waiting for whole-program correctness

Decomposition creates a validation obligation at each new boundary. In a dense call chain, one faulty translated fragment can invalidate tests far downstream, obscuring the original cause. This is the test coupling effect. AlphaTrans addresses it by using GraalVM to run source-language tests on individual translated target fragments. Validation can then examine the translation unit before it becomes a dependency for another unit.

Ke et al.’s 2026 MOCKINGBIRD uses mocks to validate each fragment on its own in place of that cross-language execution. It captures I/O pairs and side effects per method invocation, serializes them, and generates target-language mocks for equivalence checking. Its evaluated scope is Java-to-Python translation. Across 10 tasks from the AlphaTrans benchmark, it improved functional equivalence to 43.10%, up from roughly a quarter, and reported zero false positives and negligible false negatives in a 700-fragment study. The approach is LLM-agnostic, retaining gains with both DeepSeekCoder and Devstral.

Those findings have specific conditions of applicability. The source language needs good API documentation for retrieval-augmented type resolution, and the target language needs a mature mocking framework. Translate a fragment, validate it, lock its signature, and make that signature available to the next fragment. Isolated checks catch errors where they are cheapest to trace, while a separate integration phase remains necessary for bugs that emerge only when fragments interact.

Deciding what to load, when, and how to represent it — the practical framework

Diagram: How Fragment-Level Context Is Assembled at Each Translation Step. Visualizes: Illustrate the three-boundary framework for what gets loaded before, during, and after each fragment translation.

The framework places context decisions at three boundaries. Before the first LLM call, static analysis should establish translation units and a dependency graph, with callees ordered before callers. A repository map should represent signatures, imports, and roles without full implementations. A translation ledger should begin recording durable state. This preparation separates structural discovery from generation, so the model does not spend its effective context range reconstructing relationships that deterministic tools can supply.

At each fragment boundary, the active context should contain the current source, its direct dependencies’ translated signatures from the ledger, and the relevant map slice. Interface constraints and type mappings should appear at the beginning or end, where positional degradation is less severe. Source that the fragment does not need and build artifacts should stay out. Session history should enter only where the current fragment needs it, and isolated validation should precede recording the translated signature for downstream use.

Before each session closes, the ledger should be updated with fragment status, type-mapping decisions, and human overrides. Decisions that future sessions must honor should be summarized deliberately. The next session starts from that record. This answers the question of when to reload context without treating the entire interaction history as necessary evidence for every step.

What the fragment needs for correct translation determines how much text to load. VS Code extensions with explicit context configuration, Cline’s tracking, and agentic frameworks supporting file-based state can automate parts of this process. They do not choose the structural boundaries themselves. Kodiak can support deliberate context assembly for migration workflows by making fragment-by-fragment, load-on-demand work easier to execute, rather than replacing the decomposition and validation decisions.

Where the gap between current capabilities and whole-program reasoning still sits

These strategies avoid requiring whole-program reasoning in a single model call. They do not give current LLM architectures that capability. AlphaTrans and MOCKINGBIRD split the task so each part can be translated and validated without tracking every change in behavior across the repository. The remaining gap concerns changes whose effects propagate into distant code through relationships the selected context does not fully capture.

No validation method closes that gap alone. The MOCKINGBIRD paper identifies limits in scaling formal verification to whole repositories, while test-based validation faces test coupling and overfitting. LLM-based validation also has a risk of false positives. MECW also varies by task, leaving migration’s combination of refactoring and cross-document reasoning more demanding than token counts suggest. A larger window cannot be treated as evidence that those behavioral relationships have been understood.

For practitioners, this means explicitly routing dynamic dispatch, complex inheritance, and cross-cutting concerns to human review when static analysis cannot capture them fully and they exceed the model’s effective range. That boundary is a useful design constraint. Progress toward whole-program reasoning will need to improve reliable understanding of dependencies and behavioral change.

Sources

  1. Advancing Automated In-Isolation Validation in Repository-Level Code Translation

    Provided details on the MOCKINGBIRD validation approach, including its I/O pair capture, mock generation, functional equivalence results, and fragment study findings.

  2. Migrating Code At Scale With LLMs At Google Celal Ziftci∗ celal@google.com

    Provided details on Google's large-scale integer-type migration, including Kythe-based dependency discovery, AST filtering, context limits as an explicit blocker, and the positional degradation figure.

  3. When History Is Multimodal: Rethinking Context Management for Long-Horizon Agents

    Provided the VERA visual evidence-retaining strategy and its reported 63.1% reduction in cumulative non-cache tokens across benchmarks.

Rafael Mendes-Correia

More in AI Agent Migration

← Front page