Skip to content

feat(node-sdk): migrate the SDK method surface to agent-core-v2 - #2262

Merged
sailist merged 9 commits into
MoonshotAI:mainfrom
sailist:feat/node-sdk-agent-core-v2
Jul 28, 2026
Merged

feat(node-sdk): migrate the SDK method surface to agent-core-v2#2262
sailist merged 9 commits into
MoonshotAI:mainfrom
sailist:feat/node-sdk-agent-core-v2

Conversation

@sailist

@sailist sailist commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below.

Problem

The CLI's interactive surface (TUI) runs entirely on the legacy v1 engine (agent-core) through @moonshot-ai/kimi-code-sdk. There was no way to boot the TUI on the agent-core-v2 engine, and no mechanism to tell whether a v2-backed SDK client behaves identically to the v1 one.

What changed

Builds on the previous two commits in this branch (v2 harness MVP, skills migration + parity gate) and completes the migration of the SDK's method surface:

  • Full method migrationSDKRpcClientV2 now implements every SDKRpcClientBase method (75 overrides), routed through the klient facade where covered, the in-process engineAccessor escape hatch where the engine has a service but the facade does not, or SDK-side rebuilds on v2 primitives where only primitives exist (config shape mapping, global mcp.json writes, MCP OAuth flows, importContext, session warnings, print background policy). deleteSession stays not_implemented — the v2 engine has no delete capability.
  • Event and interaction bridging — the v2 per-agent event stream is translated into the v1 Event union, and approval/question/user_tool interactions are bridged per live session so TUI handlers work unchanged.
  • Resume replay rebuild — resumed sessions rebuild per-agent replay state by folding the v2 wire.jsonl through the v1 agent restore pipeline, so the TUI renders history again when resuming a session on v2.
  • Parity gate — every migrated method has a v1↔v2 parity test running both engines on the same fixture; understood engine differences are pinned explicitly in KNOWN_DIFFS so the accepted gap list can only shrink.
  • TUI gate + dev script — the interactive shell picks the v2 harness when the dedicated KIMI_CODE_TUI_V2 env switch is set (deliberately separate from the master KIMI_CODE_EXPERIMENTAL_FLAG, which keeps gating only kimi -p), with a root pnpm dev:cli:v2 script. The default path is unchanged.
  • Engine telemetry forwarding — a host-supplied telemetry client is installed as the v2 engine's app-scope appender, so engine-side events reach the host telemetry pipeline (honoring telemetry = false in config).

No changeset: the v2 route only activates behind an experimental env switch, so there is no user-perceivable change on the shipped surface.

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 27, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d167b9e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

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

commit: d167b9e

@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: cdb566045a

ℹ️ 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 +391 to +398
const { app } = bootstrap(
{
homeDir: this.homeDir,
configPath: this.configPath,
clientVersion: this.identity?.version,
},
[...logSeed(resolveLoggingConfig({ homeDir: this.homeDir, env: process.env }))],
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Seed the v2 engine with the host identity headers

When an SDK or CLI caller supplies identity, this bootstrap only seeds logging, so agent-core-v2 falls back to an empty IHostRequestHeaders. Consequently, model and WebSearch requests from the new TUI route omit the User-Agent and X-Msh-* device/version headers that the v1 client supplies and the existing v2 print composition root explicitly seeds; build createKimiDefaultHeaders({ homeDir, ...identity }) and include hostRequestHeadersSeed(...) here.

Useful? React with 👍 / 👎.

Comment on lines +894 to +897
const agent = await this.materializeMainAgent(handle, {
model: input.model,
thinking: input.thinking,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Roll back sessions when post-create initialization fails

When the requested model is unknown, materializeMainAgent throws after sessionLifecycle.create has already persisted and indexed the session. The caller receives a rejected createSession, but the failed ID remains live/listed and a retry reports session_already_exists; pass the binding into the lifecycle create operation so its built-in rollback covers the failure, or otherwise remove the newly created session and its persisted index entry on initialization errors.

Useful? React with 👍 / 👎.

Comment on lines +531 to +534
for (const [domain, domainPatch] of Object.entries(patch)) {
if (domainPatch === undefined) continue;
await this.klient.global.config.set({ domain, patch: domainPatch });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply multi-domain config patches atomically

When a patch contains multiple domains and a later domain fails validation or persistence, every earlier config.set has already been written, even though setConfig rejects. For example, a valid providers update followed by an invalid thinking section leaves the provider change on disk; the v1 method validates the merged document before its single atomic write, so callers do not expect a failed update to partially mutate configuration.

Useful? React with 👍 / 👎.

Comment on lines +391 to +398
const { app } = bootstrap(
{
homeDir: this.homeDir,
configPath: this.configPath,
clientVersion: this.identity?.version,
},
[...logSeed(resolveLoggingConfig({ homeDir: this.homeDir, env: process.env }))],
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Attach the supplied telemetry client to the v2 engine

When callers pass options.telemetry (as runShell does), it is retained for KimiHarness events but never installed as an app-scope telemetry appender. The bootstrapped v2 ITelemetryService therefore keeps only its null appender, dropping engine-originated events such as session lifecycle, LLM, tool, compaction, and task telemetry that the v1 SDK forwards through the supplied client.

Useful? React with 👍 / 👎.

sailist added 5 commits July 27, 2026 20:15
- add SDKRpcClientV2 wiring the v2 engine (DI x Scope) in-process via the
  klient memory transport, with getExperimentalFeatures migrated to
  klient.global.flags.list() and unmigrated methods failing fast
- export createKimiHarnessV2 / SDKRpcClientV2 from the SDK index
- wire the experimental v2 gate into the CLI interactive shell (run-shell)
- extend build-dts to bundle agent-core-v2 and klient declarations
- add engineAccessor escape hatch exposing the in-process engine's app-scope
  service accessor for SDK methods the klient facade does not cover yet
- implement listWorkspaceSkills via ISkillDiscovery plus the v2 user/project
  root helpers and BUILTIN_SKILLS (plugin skills and skillDirs still gaps)
- add a v1-v2 parity test pinning identical return values per migrated
  method, with understood gaps listed explicitly in KNOWN_DIFFS
- implement the remaining SDKRpcClientBase methods on SDKRpcClientV2,
  routed through the klient facade where covered, the engineAccessor
  escape hatch where the engine has a service, or SDK-side rebuilds on
  v2 primitives where only primitives exist (config shape mapping,
  global mcp.json store, MCP OAuth flows, importContext, session
  warnings, print background policy)
- translate the v2 event stream into the v1 Event union and bridge
  approval/question/user_tool interactions per live session
- rebuild resume replay by folding the v2 wire.jsonl through the v1
  agent restore pipeline, so resumed sessions render history again
- keep deleteSession as not_implemented; the v2 engine has no delete
  capability
- extend the v1-v2 parity suite to every migrated method, pinning
  understood engine differences in KNOWN_DIFFS
- add the dev:cli:v2 root script to launch the TUI on the v2 engine
@sailist
sailist force-pushed the feat/node-sdk-agent-core-v2 branch from cdb5660 to 22aa5c4 Compare July 27, 2026 12:19
sailist added 4 commits July 27, 2026 22:30
The v2 SDK client accepted KimiHarnessOptions.skillDirs (the CLI's
--skills-dir) but never seeded it into the engine, so explicit skill
dirs were silently dropped on the v2 TUI route and the Skill tool
could not find skills from them. Seed skillCatalogRuntimeOptions at
bootstrap and let listWorkspaceSkills resolve the explicit dirs as
the user source, matching the engine's session skill catalog.
…lag again

Drop the dedicated KIMI_CODE_TUI_V2 switch: the TUI v2 harness route is
gated by KIMI_CODE_EXPERIMENTAL_FLAG, the same master switch as the
kimi -p v2 route. The gate tests are kept with updated assertions, and
dev:cli:v2 sets the master flag again.
@sailist
sailist merged commit f79fde2 into MoonshotAI:main Jul 28, 2026
14 checks passed
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