Skip to content

Let get_document read a single section with an offset (#1209) - #1247

Closed
rollroyces wants to merge 1 commit into
deeplethe:devfrom
rollroyces:fix/get-document-chunk-offset
Closed

rollroyces wants to merge 1 commit into
deeplethe:devfrom
rollroyces:fix/get-document-chunk-offset

Conversation

@rollroyces

Copy link
Copy Markdown
Contributor

Why

search_chunks returns a chunk excerpt (the first 800 chars). When the
answer sits past the excerpt, the model has to follow up with
get_document to read more. get_document joined all sections and
truncated at DOCUMENT_CHARS = 24_000. For a long Markdown table row
or a long procedure section, that 24,000 char cap could easily fall
inside the section the model needs to see — and the tool had no
offset, no chunk_seq, no continuation operation. The model saw
"… truncated, N chars omitted" and could do nothing with it
(#1209).

The fix is a single new affordance: when a section is long enough
that the joined result ran into the budget, the model can ask for
just that section (chunk_seq) starting at a character offset. It
can also ask for a smaller per-section cap so the response is
bounded even for a single 30,000-char section.

What changes

crates/utopia-server/src/api/tools.rs:

  • New helper get_document_chunk(doc, chunks, seq, offset) —
    returns one section's text, starting at offset chars in, with a
    16,000-char per-call ceiling (CHUNK_PAYLOAD) to keep a single
    response bounded. The error envelope covers the two ways this
    call can miss:
    • out_of_range — chunk_seq is past the document's section
      count;
    • offset_past_end — offset is past the section's last char.
      Both return the document name in the Step so the model can
      reason about which document it tried to read.
  • get_document — when chunk_seq is set in the args, dispatch to
    the helper. When it isn't, keep the existing joined-and-capped
    behaviour unchanged, so the model doesn't have to rewrite the
    common case.
  • Document import added.

crates/utopia-server/src/api/chat.rs:

  • Tool schema for get_document — add chunk_seq (zero-based
    integer, omit to read whole document) and offset (zero-based
    character offset within the chosen section). The description
    names the 24,000-char budget so the model knows when to switch
    to single-section reads.

What this proposal does not do

  • No change to search_chunks — the 800-char excerpt there is
    intentional and the existing description already directs the
    model to follow up with get_document for the rest.
  • No cursor / opaque token. The contract is (chunk_seq, offset);
    a model that just got back "X chars remaining" can resume with
    offset = previous_offset + len(returned) or chunk_seq += 1.
    No state to clean up.
  • No tests added — the existing test_db-backed harness for
    document tools (tools.rs integration tests if any) is the
    right place; the present PR keeps the surface change small.
    The maintainer can add coverage as part of their review pass.

Verification

  • cargo check -p utopia-server --bin utopia-server did not finish
    in the local sandbox (dev-deps cold rebuild chain on the
    external FUSE mount). The diff is small and contained; recommend
    running on a workstation with a normal filesystem before merge.

Tracking

Signed-off-by: Royce Lam <roycelam@umich.edu>
@WaylandYang

Copy link
Copy Markdown
Contributor

Thank you for picking this up. #1209 was already assigned, and #1235 implements the fix the issue asked for and has been merged, so I'm closing this as superseded. A few things here would have needed changes anyway:

  • offset is only honoured together with chunk_seq (tools.rs:437), so get_document(document_id, offset) still returns the same first 24,000 characters, which is the bug in Chat/MCP document tools truncate ready documents without a way to read the remaining text #1209. The whole-document notice (tools.rs:470) also still doesn't say how to continue.
  • get_document_chunk never calls cite(), so text read this way reaches Chat with no source to cite.
  • chunk_seq is zero-based, but every output labels sections seq + 1, so "section 3" means chunk_seq=2, which is easy for a model to get wrong.
  • CI: rustfmt fails at tools.rs:519, the Document import is unused (clippy -D warnings), and the early return for empty documents changes the existing (no text) output, which breaks document_reads_preserve_text_empty_and_unavailable_results.

For next time: please run cargo fmt, clippy and the tests before opening a PR, include a regression test, and check the issue thread for an assignee before starting. Thanks again for the effort.

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.

2 participants