Skip to content

fix(kimi-inspect): the sync's prompt-channel import pulls node:path into the browser bundle and breaks pnpm run build #82

Description

@arrrrny

pnpm run build fails in apps/kimi-inspect on the 2026-09-14 upstream sync. It is the only red check on the sync PR: lint, typecheck, test (1)–test (5), test-pi-tui, test-vscode-legacy, nix build .#kimi-code and the flake sync check all pass.

Failure

CI: https://github.com/arrrrny/kimi-code-sync/actions/runs/34935202474/job/104271512860

apps/kimi-inspect build: error during build:
../../packages/agent-core-v2/src/agent/media/mediaRef.ts (1:9): "join" is not exported by "__vite-browser-external",
imported by "../../packages/agent-core-v2/src/agent/media/mediaRef.ts".
1: import { join } from 'node:path';

apps/kimi-inspect is a browser app bundled by vite, so node:path is externalized and the named join import cannot resolve.

Root cause

apps/kimi-inspect/src/components/ChatView.tsx:28 takes a runtime import of an engine token:

import { IAgentPromptChannel } from '@moonshot-ai/agent-core-v2/agent/loop/promptChannel';

used as a DI token at ChatView.tsx:382 (.service(IAgentPromptChannel).submit(...)), so the module is genuinely bundled. That module is heavy at runtime — unlike a plain token module, it also declares the implementation class:

  • packages/agent-core-v2/src/agent/loop/promptChannel.ts:26 — createDecorator<IAgentPromptChannel>('agentPromptService'), plus value imports of #/session/agentLifecycle/agentLifecycle (MAIN_AGENT_ID), #/session/sessionContext/sessionContext, #/session/sessionMetadata/sessionMetadata, #/session/sessionMetadata/promptMetadata, #/agent/prompt/promptMetadataText, #/app/event/event, #/app/telemetry/telemetry and ./loop.
  • That graph reaches packages/agent-core-v2/src/agent/loop/loopService.ts:37 (daemonFileRefFromPart from #/agent/media/mediaRef), and mediaRef.ts:1 is import { join } from 'node:path'.
  • apps/kimi-inspect/vite.config.ts has no node:* shim, so this surfaces as a build error rather than a runtime one.

Why this is new in this sync

On master the same call site imported a type-only-heavy module:

  • apps/kimi-inspect/src/components/ChatView.tsx (master) — import { IAgentPromptService } from '@moonshot-ai/agent-core-v2/agent/prompt/prompt'.
  • packages/agent-core-v2/src/agent/prompt/prompt.ts (master) had exactly one runtime import (createDecorator); everything else — including #/agent/loop/loop — was import type, so almost the whole module was erased from the browser bundle.

Upstream's prompt-queue fold (upstream PR MoonshotAI#3747) deleted agent/prompt/prompt.ts, and the sync's review-fix commit 106192eb5 repointed the import to promptChannel.ts. That is the change that pulls the session graph, and node:path, into the bundle.

Not a conflict-resolution mistake: the old module no longer exists, so the import had to move somewhere. The new home is simply not browser-safe.

What needs to be fixed

Keep the token reference but stop importing the heavy module. The app already has the right pattern: apps/kimi-inspect/src/channel/channels.ts:15 imports createDecorator from the light @moonshot-ai/agent-core-v2/_base/di/instantiation, and channel/client.ts documents that "the decorator id (String(id)) is the channel name" — klient's channel layer routes by service-name string (packages/klient/src/core/channel.ts), and the engine token's id is the wire name agentPromptService.

Proposed change, confined to the fork's own app:

import type { IAgentPromptChannel as PromptChannel } from '@moonshot-ai/agent-core-v2/agent/loop/promptChannel';
import { createDecorator } from '@moonshot-ai/agent-core-v2/_base/di/instantiation';

const IAgentPromptChannel = createDecorator<PromptChannel>('agentPromptService');

import type is erased at build time, so only the light createDecorator module stays in the bundle.

Alternative (weigh against sync conflicts): move just the interface + decorator out of promptChannel.ts into a light token module in the engine, leaving the class behind. Structurally cleaner, but it diverges in an upstream-owned area and will conflict on every future sync.

Please do not fix this by aliasing or stubbing node:path in apps/kimi-inspect/vite.config.ts: that would silently let Node-only code paths into the browser bundle instead of keeping the import graph browser-safe.

Verification notes

  • Reproduce with the full workspace build (pnpm -r build from the repo root) — apps/kimi-inspect alone fails earlier with Rollup failed to resolve import "@moonshot-ai/kap-server/protocol" from apps/kimi-inspect/src/transcript/api.ts, because sibling packages must be built first. That earlier error is an artifact of building the app in isolation, not a second bug.
  • After the fix, confirm the bundle builds and that the prompt composer still submits: the token id must stay agentPromptService, since that string is what the RPC routes on.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsync

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions