feat(v2): land agent-core-v2 engine and kap-server behind experimental flag#1441
Open
sailist wants to merge 408 commits into
Open
feat(v2): land agent-core-v2 engine and kap-server behind experimental flag#1441sailist wants to merge 408 commits into
sailist wants to merge 408 commits into
Conversation
- remove SubAgentHost / ISessionSubagentHost; a subagent is now a plain agent scope created via IAgentLifecycleService and driven through the child agent's own turn/loop services - add IAgentLifecycleService.fork(parentAgentId); startBtw forks main - move the Agent collaboration tool into the new agentTool domain (stateless runChildAgent helpers, no runner class, no subagent service) - move SubagentBatch + runChildAgentQueued into the swarm domain - seed IAgentScopeContext (agentId) per agent so the Agent tool and swarm can name themselves as the parent
- Inline SessionCronStore, CronScheduler, and CronPersistence into AgentCronService: state lives as private fields, the poll loop uses a shared timer, and persistence calls IAtomicDocumentStore directly. - Drop CronToolManager; the cron tools take IAgentCronService directly, matching the background domain. - Add a generic IntervalTimer to _base/utils and use it for the poll loop. - Move cron-expr/jitter/clock to the cron root, merge time-format and cron-fire-xml into format.ts, and fold the cron types and telemetry constants into the contract and service.
Replace the god-object `IKaos` interface and the `@moonshot-ai/kaos`
package dependency with atomic services:
- `IHostEnvironment` (App scope) — memoised OS / shell / path-style /
home probe; sync fields plus a `ready` promise the composition root
awaits before seeding Session scopes.
- `IExecContext` (Session scope) — immutable cwd + env-layers seed
value with `withCwd` / `withEnv` derivations; replaces
`IKaos.cwd/withCwd/withEnv` and `IKaosFactory`.
- `ISessionAgentFileSystem` / `ISessionProcessRunner` — inline
`node:fs/promises` and `child_process.spawn` directly; the
`IKaos.backend` leak that let `profile/context.ts`, `fileTools/glob`
and `agentFs/runRg` reach around the facades is gone.
Vendor the pure helpers into `src/_base/execEnv/` (`BufferedReadable`,
`decodeTextWithErrors`, `globPatternToRegex`, host-environment probe).
`src/app/kaos/` and `test/kaos/` are deleted; session-lifecycle awaits
`hostEnv.ready` and then seeds `IExecContext` into the child scope.
Rewrites every `@IKaos` consumer:
- `shellTools/bash`, `fileTools/{read,write,edit,glob,grep}`,
`media/read-media`, `_base/tools/policies/path-access`
- `permissionPolicy/git-cwd-write-approve` and
`permissionPolicy/git-control-path-access-ask`
- `agent/rpc`, `agent/agentTool`, `agent/profile/{context,profileService}`
- `session/{sessionWarning,workspaceContext}`
- `app/bootstrap` (drops `IBootstrapService.detect()`)
- `fileTools/glob` and `agentFs/runRg` now route rg through
`ISessionProcessRunner.exec` with per-call `{ cwd }` overrides
`test/tools/fixtures/fake-kaos.ts` is replaced by `fake-exec.ts` with
per-atom factories (`createFakeHostEnvironment`, `createFakeExecContext`,
`createFakeAgentFs`, `createFakeProcessRunner`). Domain-layer registry,
PUML diagram, tsdown externals and `package.json` deps are updated
accordingly.
`packages/kaos/` stays in the workspace — v1, node-sdk and acp-adapter
still depend on it. Only `agent-core-v2` has been detached.
…into kimi-code-v2 # Conflicts: # packages/agent-core-v2/src/agent/agentTool/agentTool.ts # packages/agent-core-v2/src/agent/background/agent-task.ts # packages/agent-core-v2/src/session/subagentHost/index.ts # packages/agent-core-v2/src/session/subagentHost/subagentHost.ts # packages/agent-core-v2/src/session/subagentHost/subagentHostService.ts # packages/agent-core-v2/test/agentTool/agentTool.test.ts # packages/agent-core-v2/test/agentTool/runChildAgent.test.ts # packages/agent-core-v2/test/agentTool/subagentHostService.default.test.ts # packages/agent-core-v2/test/background/ids.test.ts # packages/agent-core-v2/test/background/manager.test.ts # packages/agent-core-v2/test/background/rpc-events.test.ts # packages/agent-core-v2/test/harness/agent.ts # packages/agent-core-v2/test/subagentHost/defaultSessionSubagentHost.test.ts # packages/agent-core-v2/test/subagentHost/subagentHostService.test.ts # packages/agent-core-v2/test/swarm/swarm.test.ts # packages/agent-core-v2/test/tool/tool.test.ts # packages/agent-core-v2/test/turn/turn.test.ts
Move config-section registration out of Service constructors and into import-time contributions, mirroring the existing registerScopedService pattern so a section is available as soon as its domain barrel is imported. - add configSectionContributions collector (module-level, no DI) with registerConfigSection / get / _clearForTests - ConfigRegistry drains the collected contributions on construction - each owner configSection.ts calls registerConfigSection at top level (providers, models, modelCatalog, experimental, thinking/defaultThinking, loopControl, permission, hooks, background, microCompaction, cron) - domain barrels import their configSection to guarantee the side effect - remove registerSection calls and the now-unused IConfigRegistry injection from the 11 owning Services The KIMI_MODEL_* effective overlay is still registered by modelService and left for a follow-up.
The domain-layer checker placed `event` at L7 (edge) and `session-context` at L6 (coordination), producing false-positive violations for legitimate foundational dependencies: - `event` is the App-scope pub/sub bus over `_base/event`; it belongs in L1 (root), matching its file header and the design doc. - `session-context` is a pure Session-scope seed value (like `execContext`), so it also sits in L1. Moving both to L1 removes the false positives for auth, modelCatalog, sessionLog and permissionGate, and lets us drop the now-unnecessary `session>event`, `cron>session-context` and `background>session-context` exceptions. lint:domain goes from 13 to 8 violations; the remaining 8 are the unrelated permissionPolicy -> plan/swarm inversion.
- add IAgentRecordService: append(record) fans out to durable persistence, live broadcast, and replay capture via per-type facets (toLive/toReplay/resume/blobs); signal(event) emits live-only events - remove IAgentEventSinkService; fold live emission into IAgentRecordService - migrate all agent domains to record.append/signal/define - server-v2 subscribes to agent events via IAgentRecordService - delete dead createLoopEventDispatcher - AgentRecordMap extends WireRecordMap so record types stay on WireRecordMap
- make IScopeHandle generic over LifecycleScope and add IAppScopeHandle / ISessionScopeHandle / IAgentScopeHandle so session and agent handles cannot be passed to each other's parameters at compile time - thread the aliases through IAgentLifecycleService / ISessionLifecycleService and their consumers (sessionLegacy, messageLegacy, server-v2 mainAgent and skills), narrowing at the lifecycle boundary - dep-graph viewer: render scope-mismatch (token registered at a scope the caller cannot see) distinctly from a genuinely missing implementation
- add Session-scoped ISessionBtwService/SessionBtwService that forks the
main agent into a side-question child agent (tools disabled,
side-channel reminder) via IAgentLifecycleService.fork('main')
- remove startBtw from AgentAPI (core-api) and ISessionLegacyService;
the server-v2 POST /sessions/{id}/btw route now resolves
ISessionBtwService directly
- add a unit test for SessionBtwService
- Drop parentAgentId/type from agent-lifecycle; forkedFrom is provenance only, not used by business logic
- Rename IAgentLifecycleService.fork() to clone(); add list({ prefix }) for prefix-based queries
- Lift swarm batch scheduling to Session scope (new SessionSwarmService); SubagentBatch becomes its internal scheduler, no longer exported
- AgentSwarmService keeps mode UI + tool registration, delegates batch runs to SessionSwarmService
- Move ownership/cancellation out of lifecycle: drop activeChildrenByParent/cancelAllChildren/markChildDetached/SubagentDetachHandle; callers own cancellation via abort signals
- cron/permissionGate: derive subagent behavior from agentId !== 'main' instead of type
- protocol: SubagentSpawnedEvent.parentAgentId -> callerAgentId (wire break)
- Remove stale IKaos imports left after kaos was dropped; use IExecContext
… as default - remove App-scope registration of InMemoryStorageService for IStorageService, IAppendLogStorage, IAtomicDocumentStorage, and IBlobStorage - composition root now seeds FileStorageService and the test harness seeds the in-memory backend, so a scope that seeds neither fails on first use - update the class doc comment to describe storage as a deployment choice
- add examples/README.md with the run command, two example styles, the L0-L3 learning path, and a roadmap covering the registered services - add di-container.example.ts (Example 01): decorator/registration, the App/Session/Agent scope tree, sibling isolation, and disposal order - add file-tools.example.ts (Example 13): the smallest real 3-tier slice, wiring AgentFileToolsService with stubbed Session/App leaf dependencies
- add tags.ts: TagMap model with localStorage persistence, tag counts, equality check, and deterministic dark-theme tag colors - add a Tags section to Filters with all/none toggles and per-tag focus rows that drive the new activeTags filter state - thread tags state through App: load on init, persist on change, and an edit handler passed down to GraphView
- add ServerClient under src/v2: typed /api/v2 resource tree over HTTP plus events over WebSocket, with core/session/agent scopes and a v1 escape hatch for the legacy REST surface - add resource modules (core/session/agent/events), a manifest mirroring the server-v2 actionMap, shared types, and transport (HttpRpc, rpcProxy, V2Socket) - expose @moonshot-ai/server-v2/contract (actionMap + channel helpers) so the SDK drift test stays in lockstep with the server surface - add an in-process smoke test and the vitest raw-text/hash-imports plugins needed to import server-v2 source from the e2e tests - add optional bearer token support to the legacy HttpClient and document the two-client package layout
- add SkipList.iterate and DtIndex.iterate: lazy range scans that let a caller stop early without materializing the whole range - add IndexManager.hasEq for O(1) equality-index membership checks that avoid materializing the full posting list - add MiniDb.tryDtOrderedLimit (with cheapEqChecks): for a query bounded by a single dt column whose result order is that column, walk the dt skiplist in order and stop at limit, pre-filtering cheap equality predicates before decode; wire it into query() - fix text-index tokenization overflowing the call stack on large docs by loop-pushing instead of spreading the match array - add bench/* benchmarks and tests for the fast path and skiplist iteration
- rename 6 domain dirs (sessionIndex, sessionLifecycle, agentLifecycle, sessionActivity, sessionContext, sessionMetadata) to match the camelCase convention used by siblings like sessionLegacy and modelCatalog - update #/ import paths, registerScopedService names, barrel exports, and the DI layer map keys/exceptions - sync examples, di-scope-domains docs, AGENTS.md, and agent-core-dev skill docs
…vice - Move git status/diff and `gh pr` lookup out of `session/agentFs` into a new App-scope `IGitService` (`app/git`), which spawns git via `node:child_process` and owns the pull-request cache. - `ISessionFsService.gitStatus/diff` now only confine paths and delegate to `IGitService`; the wire surface and the `FS_GIT_UNAVAILABLE` error code are unchanged. - Move pure git-output parsers to `app/git/gitParsers`, add real-git `GitService` tests, and rewrite the `fsService` git tests as delegation tests.
- collapse activate/activateFromModel into a single activate on IAgentSkillService; the model wrapping (resolve, inline and disableModelInvocation gates, isError result, prompt.steer) now lives in SkillTool behind a shared executeModelSkill helper - keep activation recording in the service via a recordActivation callback passed to the tool - drop the redundant ModelSkillTool and the TestAgentSkillService harness subclass; update skill tests
AgentCronService wrote every task to one global `<homeDir>/cron/<id>.json` scope, so tasks were shared across all sessions and agents (id collisions, cross-session resume) and diverged from the v1 layout. Derive a per-agent atomic-document scope from ISessionContext and IEnvironmentService (`sessions/<ws>/<sid>/agents/<agentId>/cron`), so tasks land at `<sessionDir>/agents/<agentId>/cron/<id>.json`, matching v1 and letting CLI/v1 and v2 sessions read each other's cron files. When the agent has no id (ephemeral / test seam) persistence is skipped, mirroring v1's "no homedir, no persistence" behaviour.
AgentBlobStoreService now derives its storage scope from a per-agent `homedir` (`<agentDir>/blobs/<sha256>`) instead of the global `blobs` scope, matching v1 so v2 can rehydrate blobs from v1-written sessions. AgentLifecycleService seeds the per-agent `homedir` when creating an agent scope, alongside the existing wire-record seed.
Thread ExecutableToolContext.signal through the web tool chain so an aborted turn actually cancels the underlying HTTP request instead of merely racing it at the executor. - UrlFetcher.fetch and WebSearchProvider.search accept an optional AbortSignal; the tools forward ctx.signal - LocalFetchURLProvider, MoonshotFetchURLProvider, and MoonshotWebSearchProvider pass the signal to fetch() - MoonshotFetchURLProvider no longer falls back to the local fetcher when the caller aborted - the tools re-throw on abort so the executor classifies user cancellation instead of surfacing a retryable network error
- add examples/session-skill.example.ts demonstrating the Session-scoped skill catalog: loads skills from the current workDir and reports each skill's source provenance (builtin / user / project) - list the example in the examples README roadmap
…into kimi-code-v2
- add an Agent-scope runtime domain that holds the whole live phase as one discriminated-union field (idle, running, streaming, tool_call, retrying, awaiting_approval, interrupted, ended) - drive it from existing turn, step, delta, tool, retry, interrupt and approval events, edge-triggered with reference-equality dedup so delta bursts do not flood the wire log - carry the phase on the existing agent.status.updated channel and add the AgentPhase type/schema to the protocol (backward compatible)
…into kimi-code-v2
…into kimi-code-v2
- write `kimi version <version>` to stderr first in text mode - emit a `system.version` meta line first in stream-json mode - gate behind isKimiV2Enabled() so the default v1 path is unchanged
…cap to 3000px (#1460) * fix(agent-core): report EXIF-rotated image dimensions and raise edge cap to 3000px Image compression now reports original dimensions in the decoded (EXIF-rotated) space, matching the coordinate system of the sent image and of ReadMediaFile region readback; previously portrait JPEGs (orientation 5-8) got swapped width/height in captions. The longest-edge downscale cap rises from 2000px to 3000px, and the default jimp resize path is documented as the anti-aliased area-average one so it is not accidentally switched to a point-sampled interpolation mode. * test: shrink oversized image fixtures to fit CI timeouts The 3600x3600 fixtures introduced for the 3000px edge cap nearly doubled the pixel area jimp has to decode and deflate, pushing the slowest compression tests past the 5s vitest timeout on CI runners. 3600x1800 keeps every fixture over the cap while restoring roughly the workload of the old 2600x2600 fixtures that CI handled comfortably. * test: pin anti-aliased downscale quality with executable guards A 1px checkerboard probe pins the compressor to full-coverage averaging at integer and fractional ratios, with jimp's point-sampled BILINEAR mode kept as the executable aliasing counter-example (it collapses the 50%-gray pattern to solid black at 4:1). Also guards the other classic downscale bugs: transparent-pixel color bleed, mean-brightness drift, iterative recompression degradation, and zero-size collapse on extreme aspect ratios. * fix(agent-core): report decoded EXIF-rotated dimensions in ReadMediaFile notes The media note derived its original-dimensions line from the header sniff, which reports pre-rotation values for EXIF orientation 5-8 JPEGs. The sent image and region readback both live in the decoded (rotated) space, so portrait photos got axis-swapped coordinate guidance. Once a decode has happened — compression or crop — its dimensions now overwrite the sniffed ones. * fix(agent-core): improve handling of EXIF orientation in image dimensions and metadata * fix(agent-core): sniff EXIF orientation and step budget fallback through 2000px Two follow-ups to the EXIF and 3000px-cap changes: sniffImageDimensions now reads the JPEG EXIF Orientation tag (pure header parse, both byte orders) and reports display-space dimensions for orientations 5-8. Passthrough images — never decoded — previously kept the pre-rotation header size in compression results and media read notes, disagreeing with the decoded space that region readback uses. encodeWithinBudget steps the over-budget fallback through 2000px before the 1000px last resort. Raising the cap to 3000px had left a regression window: an image whose 2000px encode fits the byte budget was sent at 1000px where the old 2000px cap used to send it at 2000px. * fix(kimi-code): record pasted image dimensions in display space The TUI paste path recorded attachment and original dimensions from its raw header parser, which ignores EXIF orientation. For a portrait JPEG the submit-time caption then contradicted the sent image's aspect and region readback coordinates were axis-swapped. Dimensions now come from the compression result, which reports display space on both the compressed and passthrough paths; parseImageMeta remains only the format/mime gate. * feat(agent-core): add image compression and crop telemetry Every image ingestion path now reports an image_compress event — outcome (compressed / passthrough fast, guard, unsupported, unhelpful, error), input/output formats, byte and pixel sizes, EXIF transposition, and duration — and region readback reports an image_crop event with a failure classification and the region's share of the original area. Wiring is per call site via a new CompressImageOptions.telemetry option, so the outcome split and timing are measured inside the compressor while each caller only names its source: ReadMediaFile (tool construction, like GrepTool), MCP tool results (McpOutputOptions), server prompt ingestion (ICoreProcessService now exposes the host telemetry client), ACP prompts (session track adapter), and TUI paste (host.track adapter). Properties are numeric/enum only — never paths or content — and a throwing client can never affect the compression result. * fix(agent-core): run the full JPEG quality ladder at fallback sizes The fallback rescales encoded only at quality 20, so a JPEG whose ladder failed at the fitted size collapsed straight to the lowest quality even when the smaller size left budget headroom for a higher rung (the realistic window is the 1000px step, where the 4x pixel drop pays for q80/q60). Each fallback edge now walks the same q80-to-q20 ladder as the fitted size. * test: shrink heavy JPEG fixtures and add explicit timeouts The fallback-ladder test runs ~11 pure-JS JPEG encodes and the EXIF paste test decodes, rotates, and re-encodes a 6.5MP frame; both sat at the edge of the 5s vitest timeout on CI runners. Narrower fixtures cut the pixel area (the ladder test keeps its width above 2000px so the full fallback chain still runs) and explicit 15s timeouts absorb runner variance. * fix(server): scope prompt image compression telemetry to the session The prompt-ingestion image_compress events were emitted with the bare host telemetry client, while every agent-side source inherits a session-scoped client — so prompt_inline/prompt_file events could not be correlated with their session. The route now wraps the client with withTelemetryContext({ sessionId }) like rpc/core-impl does for session telemetry. * chore(changeset): consolidate image compression changesets One entry covering the cap raise and the EXIF dimension fix, listed for both the CLI and the SDK so the SDK changelog's compression description (previously pinned at 2000px) stays accurate.
Align progressive tool disclosure with the discard-on-compaction model: compaction no longer rebuilds loaded dynamic tool schemas. The boundary announcement re-lists every loadable name, the model re-selects what it still needs, and a from-memory call to a no-longer-loaded tool is rejected by preflight with select guidance. This removes the keep-all rebuild and its half-trigger budget heuristics entirely: the post-compaction floor is back to users + summary, which is structurally outside the auto-compaction trigger band, and the guard baseline degenerates to summary + reinjected reminders. Every downstream mechanism already treated the empty loaded set as its consistent base state (ledger scan, pending clear at the compaction boundary, deferred extras, preflight wording), so this is a strict simplification. Co-authored-by: fengchenchen <fengchenchen@moonshot.ai>
Headless (`kimi -p`) failures could exit with code 0 when the event loop drained during the shutdown cleanup (e.g. telemetry's unref'd retry backoff when the network is blocked), because the rejection never reached the process.exit(1) call. Set the failure exit code before any await in both the run-prompt catch and the main catch, and keep the cleanup timeout ref'd so the loop stays alive long enough for the rejection to propagate.
* feat(web): redesign cron reminder as a message bubble Restyle the cron trigger notice as a right-aligned user-style message bubble that shows the scheduled prompt in full (wrapping across lines), with a small meta row beneath it for the schedule, status, job id and run time. Extract a shared MessageTime component used by both user messages and the cron reminder so the timestamp format and click-to-expand behavior stay consistent, and give the CronCreate/CronList/CronDelete tools distinct calendar icons. * refactor(web): render cron reminders only as standalone turns Remove the embedded cron block path from the web transcript projector so cron reminder fires always render through the standalone right-aligned bubble path. * chore(web): simplify cron redesign changeset
) * fix(web): composer model switch also updates global default model The composer model switcher still switches the active session's model via POST /sessions/{id}/profile (awaited, so the model pill reflects the result), and additionally fires POST /api/v1/config with { default_model } as a fire-and-forget side effect so new sessions inherit the chosen default. The config request is skipped when the model already matches the current default. * fix(web): route ModelPicker overlay selection through the default-model update The overlay opened from the composer's "More models" row (and /model) is a continuation of the same switch flow, so its selection now also bumps the global default model instead of only switching the active session. * fix(web): only persist the default model after a confirmed session switch setModel now returns whether the switch was accepted (true for the draft path), so the composer flow no longer writes a stale or invalid model alias into the global config when the session-level switch failed and rolled back.
- port probeLoginShellPath/mergeLoginShellPath/applyLoginShellPath into _base/execEnv/loginShellPath.ts as a pure helper (no DI) - export execFileText from environmentProbe for reuse by the probe - run applyLoginShellPathFromNode concurrently with the host probe in HostEnvironmentService, mirroring kaos LocalKaos.create() Aligns agent-core-v2 with kaos 021786f so the Bash tool finds user-installed tools (e.g. Homebrew's gh) when kimi-code is launched from a GUI or non-login shell.
…into kimi-code-v2
…into kimi-code-v2
…into kimi-code-v2
…into kimi-code-v2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
N/A — integration PR that lands the long-lived
kimi-code-v2branch; see Problem below.Problem
The v2 line — the DI × Scope based
agent-core-v2engine, thekap-serverthat hosts it, and theminidbread model — has been built up on the long-livedkimi-code-v2integration branch. This PR merges that branch intomain.The v2 engine and server are not the default runtime yet. Both the
kimi -pprompt path andkimi server runroute to v2 only whenKIMI_CODE_EXPERIMENTAL_FLAGis set, and the v2 module graph is lazy-imported so it stays off the default path. With the flag unset, the CLI keeps the v1 engine and@moonshot-ai/server.What changed
Scope: 1,207 files, +192,653 / −285. The bulk is three new packages; everything else is CLI wiring, e2e coverage, skills, and small v1 touch-ups.
1. agent-core-v2: the new DI × Scope engine (
packages/agent-core-v2, +146k, 872 files)agent-core-v2package: a DI scope engine with an explicit agent / session lifecycle.ReplayTimelineModel;IEventBusandOp.toEventalongsidewire.signal; context writes routed through ops and declared tool delivery.wire.jsonl); flattened agent hierarchy with swarm lifted to session.Modelgod-object and protocol domains; kosong vendored as the internalllmProtocol/kosongimplementation (drops the@moonshot-ai/kosongand@moonshot-ai/kaosdependencies).rglocator/runner, AGENTS.md hierarchy loading.2. kap-server: the v2 server (
packages/kap-server, +26k, 139 files)@moonshot-ai/kap-serverpackage — the Kimi Code server backed byagent-core-v2(codenamed "server-v2").agent-core-v2sessions over REST (/api/v1, ~25 route modules) and WebSocket (/api/v1/wswith seq/epoch watermark and resync), and serves the web assets./openapi.jsonvia@fastify/swagger, and v2 session export (diagnostic zip archives).before_idpagination cursor, treat loopback origins as same-origin for WS upgrade, and align MCP media output with v1.3. minidb: embedded read model (
packages/minidb, +13k, 77 files)@moonshot-ai/minidbpackage — a pure-Node.js embedded KV database (Redis-style in-memory KV with SQLite-style WAL/snapshot persistence, secondary indexes, TTL), used as the session-index read model.4. CLI wiring (
apps/kimi-code, +762, 19 files)kimi -pandkimi server runselect v2 vs. v1 viaKIMI_CODE_EXPERIMENTAL_FLAG(lazy import); v1 stays the default.cli/v2/*) and theprompt-sessionabstraction shared by both engines; update TUI adapters to handle v2 events.5. Tooling, e2e and docs
packages/server-e2e: typed v2ServerClientSDK with a drift test and e2e coverage..agents/skills: add theagent-core-devandwrite-testsskills plus other skill updates; add the dependency-graph dev viewer.GOAL.md: design doc for the goal-mode feature split.packages/protocol,packages/acp-adapter,packages/agent-core,packages/server,packages/node-sdk,apps/kimi-web, thehash-importsbuild loaders,flake.nix, and changesets.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.