Skip to content

Feat/rust agent engine migration - #2774

Open
7723qqq wants to merge 835 commits into
MoonshotAI:mainfrom
7723qqq:feat/rust-agent-engine-migration
Open

Feat/rust agent engine migration#2774
7723qqq wants to merge 835 commits into
MoonshotAI:mainfrom
7723qqq:feat/rust-agent-engine-migration

Conversation

@7723qqq

@7723qqq 7723qqq commented Aug 10, 2026

Copy link
Copy Markdown

Related Issue

Resolve #(issue_number)

Problem

What changed

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.

7723qqq added 30 commits August 4, 2026 07:20
7723qqq added 12 commits August 10, 2026 03:58
…gine-home test isolation

- listSessions merges the engine's persisted records with the host mirror
  so a harness sees sessions another harness created in the same home;
  summaries carry engine-persisted metadata. addAdditionalDir mirrors the
  caller's path verbatim (the forward-slash normalization rewrote it).
- replayFromContext maps messages with the same mapContextMessage the
  context surface uses (tool calls/results preserved, field-identical
  records); resume summaries surface modelAlias/thinkingEffort.
- createSession passes the real workDir to the engine.
- test isolation: KIMI_AGENT_HOME points at a scratch store (materialized
  by a per-worker setup file) for node-sdk/vscode/kap-server suites, so
  fixed session ids no longer leak stale records across runs.
- vscode: compaction tests assert the no-summarizer failure semantics,
  replay display assertions drop the retired host-rendered blocks, legacy
  backfill/subagent-replay tests are skipped as known gaps, and the
  replay status payload tolerates the leaner engine resume state.
The plan accumulated ~950 lines of session-by-session log. Rewrite it as a
state-of-the-migration document: current status (2026-08-10), scope targets,
crate inventory, G-0..G-7 progress, actionable TODO list, decision log
(engine semantics, test strategy, known gaps) and a commit index. Historical
session logs are condensed into decisions and kept only where they still
constrain future work.
…andbox, config roundtrip

- session/create records the explicit work_dir (not homedir) and keeps the
  persisted workspace on resume re-creates
- session/cancel no longer blocks on the manager lock held by long-running
  init/turns (Stop stays responsive)
- native tool execution keys off workspace_root/work_dir instead of homedir;
  supports_tool_lifecycle enables engine-side gated write/bash/network tools
- KimiConfig round-trips the host-facing thinking/yolo sections through
  config/get and config/set
- adds regression tests for work_dir precedence, resume preservation, and
  the thinking section
Replace the @moonshot-ai/kimi-code-sdk dependency with the local sdk-local
surface: camelCase status/context projections, user-agent identity on the
native LLM, session mirror for additionalDirs, native tool execution wiring
(workspace_root sandbox), and the corrected add_additional_dir method. The
extension now talks to the Rust engine over stdio with no node-sdk import.
All 13 @moonshot-ai/kimi-code-oauth imports in apps/kimi-code now resolve
to local modules ported from the package (device-id/UA identity glue and
the custom-registry provider import), so the oauth package has no CLI
consumer left and can retire with G-6. Behavior is unchanged: identity
headers/device id semantics and registry api.json parsing/merging are
ported verbatim; tests keep their mocks via the new module paths. Also
drop the dead oauth alias from the vscode tsdown config and exempt test
files from no-useless-undefined (it mis-fixes required mock arguments).
- http.rs: widen the shared turn-context grace period from 100ms to 2s —
  a lagging WS projector could miss turn.started after the async-submit
  cleanup, silently dropping the whole turn projection and leaving its
  messages stuck in pending (v1 #2/MoonshotAI#5)
- kimi-web agent projector: only emit the client-accumulated usage
  snapshot at turn end when the turn actually reported step usage, so the
  authoritative event.session.usage_updated numbers are no longer
  clobbered with zeros (v1 #3)
- regression tests for the usage gating
Cut the first slice of @moonshot-ai/kimi-code-sdk consumption in the CLI
host: resolveKimiHome/resolveConfigPath/loadRuntimeConfigSafe (trimmed
TOML read + camelCase transform), ErrorCodes/KimiError/isKimiError/
resolveErrorTitle (structural cross-boundary check, i18n titles), and
the git-bash error code. Behavior is equivalent; tests mock the new
local module paths.
Port fetchCatalog/CatalogFetchError/DEFAULT_CATALOG_URL, the full
import-resolution chain (wire guessing, endpoint adaptation, per-model
provider overrides), and applyCatalogProvider from kosong/node-sdk into
a local catalog-local module. Behavior is verbatim; only the config type
is trimmed to the host-written surface.
@changeset-bot

changeset-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 71f9a84

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

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

@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: 562e6f5cba

ℹ️ 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 +19 to +22
resolve(repoRoot, 'packages/kimi-build/target/release/kimi-build' + ext),
resolve(repoRoot, 'packages/kimi-build/target/debug/kimi-build' + ext),
resolve(appRoot, 'packages/kimi-build/target/release/kimi-build' + ext),
resolve(appRoot, 'packages/kimi-build/target/debug/kimi-build' + ext),

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 Restore a usable SEA injector

With postject removed from the app dependencies in this commit, build:native:* now falls back to kimi-build, but these candidates never include the Cargo workspace output path (target/{release,debug}/kimi-build) and the workflow does not build a per-package packages/kimi-build/target tree. As a result a normal native build reaches No SEA injector available even after cargo build -p kimi-build; either restore a packaged postject dependency or look for/build the helper where Cargo actually writes it.

Useful? React with 👍 / 👎.

}
let router = match assets {
Some(dir) => kimi_server_transport::http::router_with_assets(state, dir),
None => kimi_server_transport::http::router(state),

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 Serve the packaged SPA for kimi web

For installs where the new wrapper finds a Rust binary, kimi web reaches this default None branch because neither bin/kimi.mjs nor the command supplies --assets; the server then registers only the API router, so the browser opened at the root URL gets no web UI. Default this path to the package's dist-web assets (or require and pass an assets directory) before falling back to the API-only router.

Useful? React with 👍 / 👎.

Comment thread crates/kimi-cli/src/main.rs Outdated
)
.with_auth(auth);
let listener = tokio::net::TcpListener::bind((host, port)).await?;
let url = format!("http://{host}:{port}");

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 Include the bearer token in opened web URLs

When auth is enabled by default, web_auth_config reads or generates a server.token and the HTTP middleware rejects API calls without Authorization: Bearer ...; however this URL is printed and opened without the #token= fragment that the TS web flow uses to authenticate the SPA. Even with assets supplied, a fresh kimi web opens an unauthenticated page unless the user already has the token stored, so build the openable URL from the resolved token.

Useful? React with 👍 / 👎.

#[derive(Subcommand)]
enum Commands {
/// Run one prompt non-interactively.
#[command(name = "print", alias = "-p")]

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 Preserve the legacy kimi -p flag

Once bin/kimi.mjs prefers the Rust binary, the common headless invocation kimi -p "prompt" no longer goes through Commander; clap documents flag-style subcommand dispatch via short_flag_alias/short_flag, while plain alias is a normal subcommand alias. This alias = "-p" therefore leaves the documented top-level -p path parsed as an option/unknown argument instead of the Print subcommand.

Useful? React with 👍 / 👎.

Comment thread packages/kimi-code-rust-bin/bin/kimi.js Outdated
import { fileURLToPath } from 'node:url';

const HERE = dirname(fileURLToPath(import.meta.url));
const candidates = ['kimi-win32-x64.exe', 'kimi.exe', 'kimi-linux-x64', 'kimi-darwin-arm64', 'kimi'];

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 Probe the platform name that pack.mjs writes

pack.mjs writes the binary as kimi-${process.platform}-${process.arch}${exe}, but this wrapper only probes win32-x64, linux-x64, and darwin-arm64 (plus generic fallbacks). Packages built on linux-arm64, darwin-x64, or win32-arm64 therefore contain a correctly named binary that this entrypoint never finds, causing immediate Rust binary not found on those supported targets.

Useful? React with 👍 / 👎.

@@ -0,0 +1,16 @@
{
"name": "@moonshot-ai/kimi-code-rust",

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 Add the Rust wrapper package to flake workspaces

Adding packages/kimi-code-rust-bin under the packages/* workspace glob makes it a pnpm workspace, but flake.nix still lacks both its path and package name. Nix builds will drop this package from the source fileset and pnpmConfigHook will not know about @moonshot-ai/kimi-code-rust, so add it to both hardcoded flake lists with the new workspace.

Useful? React with 👍 / 👎.

7723qqq added 16 commits August 10, 2026 16:15
Eliminate @moonshot-ai/kimi-code-sdk imports across the CLI host (23
files -> 1 transitional seam): local modules now provide the harness
config surface, auth token read, device-flow login (ported from
kimi-code-oauth), config-RPC, MCP/plugin/system-prompt/profile loading,
catalog config write, engine-bridge types, and the pure type surface
(Event/GoalSnapshot/TokenUsage/...). ACP now drives native engine
sessions directly. One seam remains: prompt-harness-local still imports
the SDK factory for the fallback harness (G-6 cutover point).

Also correct a stale 100ms comment in the v1 transport tests.
…ete)

The last @moonshot-ai/kimi-code-sdk import in apps/kimi-code is gone:
prompt-harness-local now drives native engine sessions directly (config
via local runtime-config, sessions via NativeServerClient +
createNativeTuiSession, auth via auth-local, telemetry via the local
client), and the opt-in e2e tests import the engine runtime logger
directly. The devDependency is removed; node-sdk now has no consumer in
the CLI host and can retire with G-6.
…obing

- 03-inject.mjs probes the Cargo workspace target dir for kimi-build and
  drops the broken appRoot/packages candidates
- kimi.mjs / kimi.js inject --assets for the web subcommand when a dist-web
  ships next to the wrapper
- kimi.js probes kimi-<platform>-<arch> before the legacy name list
- kimi web appends #token=<server.token> to the opened URL
- lock the kimi -p alias behavior with a CLI regression test
…tocol/kaos (G-6)

- move the six frozen TS packages to retired/ (zero external refs after
  G-1/G-2/G-3 consumption switches)
- drop dead aliases/paths in apps/vscode and apps/vis/server configs,
  remove the stale kaos devDependency from migration-legacy
- sync flake.nix workspace lists (add kimi-code-rust-bin, drop the six
  retired packages) and regenerate the pnpm lockfile
- update AGENTS.md and CODEX_MIGRATION_PLAN.md to the new state
…ng (G-6)

- export-local talks to kimi-server-serve via NativeServerClient
  (session/list + session/export RPC) instead of the rust-loop bridge
- proxy and logging-core localize into apps/kimi-code (undici/socks
  dependencies move along); runtime errors/i18n were already unreferenced
- kimi-agent package is now Rust-only plus the generated wire.gen.ts
  (exports reduced to ./rpc/wire); rust-loop/runtime/contract and their
  tests are deleted
- kosong moves to retired/; flake.nix, lockfile, AGENTS.md and the
  migration plan are synced
…kage (G-3)

- telemetry source (10 files, zero external deps) moves into
  apps/kimi-code/src/utils/telemetry; all 6 host imports and 5 vi.mock
  call sites switch to #/utils/telemetry (new imports mapping)
- packages/telemetry moves to retired/; flake.nix, lockfile, AGENTS.md
  and the migration plan are synced
…package (G-5)

- transcript source (3.7k lines, zod-only dep) moves to
  kimi-inspect/src/transcript-data; all 10 imports switch to relative
  paths
- kimi-inspect gains zod + i18n-shared dependencies (the latter fixes a
  pre-existing missing-dependency build/typecheck failure)
- packages/transcript moves to retired/; flake.nix, lockfile, AGENTS.md
  and the migration plan are synced
…hint

- kimi migrate now prints the one-time legacy-data migration path instead
  of an unknown-subcommand error (the Rust binary does not bundle the
  migration screen); covered by a CLI regression assertion
- remove the unreferenced slash-command-types and pi-tui-theme host files
- record the migration evaluation decision: migration-legacy/pi-tui stay
  with the TS entry until G-7 (one-time host data feature, not ported to
  Rust)
…MoonshotAI#5)

- eventReducer messageUpdated now stores the protocol status on the
  message instead of dropping it, so streamed assistant messages leave
  their initial/pending state when the Rust server projects the
  completed close-out
- AppMessage gains an optional status field; REST snapshot messages map
  as completed history (toAppMessage status param), WS-created messages
  stay unset until message.updated arrives
- regression test covers the status hand-off; G-2 #2/#3 verified already
  fixed (take_turn 2s grace, usage_updated consumption)
…shotAI#5)

- new mappers-to-app-event tests lock message.updated status and
  session.usage_updated normalization onto the AppEvent shapes the
  Rust server projects
- toAppMessage status parameter covered: snapshot loads carry
  'completed', WS-created messages stay unset until message.updated
- record the G-3 entry-switch assessment: the TS command surface is
  equivalent (plugin_run_node is superseded by the engine plugin model);
  the remaining blocker is the stage-F distribution packaging
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