Skip to content

fix(agent-core-v2): repair messages API history after resume - #1633

Merged
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:fix/v2-messages-rehydrate-media
Jul 13, 2026
Merged

fix(agent-core-v2): repair messages API history after resume#1633
sailist merged 1 commit into
MoonshotAI:mainfrom
sailist:fix/v2-messages-rehydrate-media

Conversation

@sailist

@sailist sailist commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below.

Problem

The v2 messages API (MessageLegacyService.list) served broken history for sessions read back from the record journal (e.g. after resume), diverging from v1's readWireTranscript behavior in three ways:

  • Restored journal entries carry dehydrated blobref: media URLs, so images/audio/video in history were served as unresolvable blobref: links instead of the inline data: URIs that live emissions carry.
  • Tool results that return media (e.g. ReadMediaFile) were flattened by joining only the text parts, so their media content collapsed to an empty string.
  • created_at was synthesized as session.createdAt + index, losing the real wire record time and producing timestamps that do not match v1 or the live event stream.

What changed

Single fix commit on top of origin/main, with tests:

  • MessageLegacyService rehydrates blobref: media URLs through the agent's blob store (IAgentBlobService.loadParts, mirroring v1's rehydrateBlobRefs); unresolvable refs fall back to the [media missing] placeholder, same as v1 and live replay.
  • messageProjection.buildProtocolContent passes tool results that carry media parts (image_url / video_url / audio_url) through as the raw kosong content-part array — the same shape the live tool.result event stream carries — while text-only results still flatten to joined text.
  • reduceContextTranscript now carries the originating wire record time per entry (ContextTranscript.times); created_at uses that time, nudged to stay strictly increasing so cursor consumers keep a stable total order, falling back to session.createdAt + index for entries without a source record (live tail).

Tests: new cases in test/app/messageLegacy/messageLegacy.test.ts (blobref rehydration, media tool-result pass-through, text flattening, record-time created_at) and test/agent/contextMemory/contextTranscript.test.ts (per-entry record times); snapshot hash updates in loop.test.ts / tool.test.ts. Changeset included (patch).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 394493a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@moonshot-ai/agent-core-v2 Patch
@moonshot-ai/kap-server Patch
@moonshot-ai/klient Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 13, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@394493a
npx https://pkg.pr.new/@moonshot-ai/kimi-code@394493a

commit: 394493a

@sailist
sailist force-pushed the fix/v2-messages-rehydrate-media branch from 7954671 to 585127b Compare July 13, 2026 15:28

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 79546711e8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +131 to +133
// Restored journal entries carry dehydrated `blobref:` media URLs while
// live emissions are inline — rehydrate through the agent's blob store so
// the messages API serves one shape (v1's `readWireTranscript`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove new inline implementation comments

packages/agent-core-v2/AGENTS.md says comments must live solely in top-of-file /** */ blocks and never beside functions, methods, or statements. This new inline block in loadMessages narrates an implementation step inside the method, so it violates the package rule; please remove it or fold durable context into the file header.

Useful? React with 👍 / 👎.

- rehydrate restored `blobref:` media URLs to inline `data:` URIs from the
  agent's blob store, matching the shape of live emissions
- pass tool results carrying media (e.g. ReadMediaFile) through as raw
  content parts instead of flattening them to empty text
- use wire record times for `created_at`, nudged to stay strictly
  increasing, instead of a synthesized session-start offset
- carry per-entry record times through `ContextTranscript` and the
  live-tail merge
@sailist
sailist force-pushed the fix/v2-messages-rehydrate-media branch from 585127b to 394493a Compare July 13, 2026 15:37
@sailist
sailist merged commit 5d1f904 into MoonshotAI:main Jul 13, 2026
14 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 14, 2026
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.

1 participant