Commit graph

234 commits

Author SHA1 Message Date
qer
bd06178913
fix(kap-server): avoid duplicating steered prompt content (#3853)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* fix(kap-server): rebuild chat transcript after undo

* test(kap-server): provide undo registry in broadcaster fixtures

* fix(kap-server): preserve non-anchor steers through undo

* fix(kap-server): rebuild undo transcript after persistence completes

* test: complete restored notification origin fixture

* fix(kap-server): keep original prompt when steering

* chore: add changeset for steered prompt content fix

* fix(kap-server): keep restored prompt content after late projector attach

* fix(kap-server): prefer store prompt content after transcript backfill
2026-09-17 01:14:35 +08:00
Grapedge
0cf413f775
fix(kap-server): open a new turn for abort-reissued steers in cold transcripts (#3844) 2026-09-16 19:34:02 +08:00
7Sageer
da31c472a2
feat(agent-core-v2): add skill scopes and mark custom-theme as tui-only (#3843)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* feat(agent-core-v2): add skill scopes and mark custom-theme as tui-only

Builtin skills can now declare a scopes whitelist (tui | web); skills
without scopes stay visible everywhere. The value is carried through
SkillSummary, the klient RPC contract, and the kap-server REST wire,
and the TUI slash commands filter by it. HTTP clients (code-app) drop
skills whose scopes exclude their own UI mode, so TUI-only skills like
/custom-theme no longer leak into app/web.

* fix: filter scoped skills from the acp and vscode palettes

ACP slash commands and the VS Code GetSlashCommands handler also
project SkillSummary lists; both now drop skills that carry a scopes
restriction so tui-scoped skills stay out of non-tui clients.
2026-09-16 19:14:22 +08:00
Luyu Cheng
41eac5d2e7
feat(kap-server): keep client metadata on prompts and skill activations (#3764)
Store the optional metadata object on prompt submission and skill activation as opaque client metadata on the user or skill-activation origin, carry it through prompt events, the transcript projector, snapshots and history rebuilds, and echo it on prompt items without adding it to model content. Use display_text entries for session titles, undo labels and fork titles when every entry provides one. Project user turn payloads, live and rebuilt, through a path-free projection.
2026-09-16 17:56:43 +08:00
qer
cafd9b5a65
fix(kap-server): rebuild chat transcript after undo (#3837)
* fix(kap-server): rebuild chat transcript after undo

* test(kap-server): provide undo registry in broadcaster fixtures

* fix(kap-server): preserve non-anchor steers through undo

* fix(kap-server): rebuild undo transcript after persistence completes

* test: complete restored notification origin fixture
2026-09-16 17:15:35 +08:00
Luyu Cheng
1c7e996aa8
fix(kap-server): record user slash skill activations steered into a running turn (#3832)
Accept skill_activation origins with a user-slash trigger in onTurnSteered so a slash command sent while a turn is running gets a transcript frame, and keep those frames from draining a queued prompt's id. Project origin file attachments onto steered frames on both the immediate and deferred paths, matching onTurnStarted and the history rebuild.
2026-09-16 17:10:44 +08:00
tpoisonooo
8660a07b3a
fix(tower): subagent cards still showing "completed" during rework (#3833)
Co-authored-by: konghuanjun <konghuanjun@moonshot.ai>
2026-09-16 16:20:24 +08:00
Luyu Cheng
402ee71c1a
feat(kap-server): accept text parts in skill activation attachments (#3831)
Widen activateSkillAttachmentSchema so the attachments array accepts text parts alongside image, video and file, letting a caller interleave text and media in the order the model should read them. Schema only; the route already resolves attachments as WireContent.
2026-09-16 14:02:08 +08:00
HydrogenE7
7d174ac933
perf(agent-core-v2): evict completed subagent scopes behind an LRU cache (#3778)
* perf(tui): batch and cache agent swarm progress rendering

* perf(agent-core-v2): evict completed subagent scopes behind an LRU cache

* fix(agent-core-v2): stop the agent actor in the session machine when its scope is removed

* fix(agent-core-v2): emit a terminal event for the final rate-limited run and defer eviction while background tasks run

* fix(agent-core-v2): include in-flight retries when abandoning suspended agents

* fix(agent-core-v2): roll back the closing flag when scope removal fails and wait per the configured eviction timeout

* fix(agent-core-v2): terminalize subagents spawned after batch cancellation and report task timeouts as failures

* chore: restore upstream/main state of files mangled by lint-staged autofix in the merge commit

oxlint --fix rewrites (prefer-set-has, catch-error-name, prefer toSorted/.at(-1)/toReversed)
touched seven files the branch never modified; one of them (oauth managed-kimi-code.ts)
no longer typechecks. Restore all seven to their exact upstream/main state. Committed
with --no-verify so the same autofix does not re-mangle them.

* fix(agent-core-v2): retry deferred scope evictions without exhausting the attempt budget, dedupe terminal events for starting retries, and patch-level the changeset

* fix(agent-core-v2): finish scope teardown instead of reactivating a partially torn-down scope

* fix(agent-core-v2): terminalize subagent-start hook cancellations and re-acquire resume targets after metadata reads

* fix(tui): record cancelled background agents in the transcript

* fix(agent-core-v2): route mirror terminal events through the batch exactly-once guard

* fix(tui): guard terminal swarm members from re-cancellation and deliver terminal status to cancelled foreground subagent cards

* fix(agent-core-v2): classify eviction as removed when teardown already closed the scope

* Merge remote-tracking branch 'upstream/main' into perf/subagent-scope-eviction

Skip lint-staged for this merge: its oxlint --fix pass rewrites unrelated files
(prefer-set-has etc. mangled seven files in the previous merge commit), while the
merge content is upstream's lint-clean code plus conflict resolutions already
verified by oxlint.

* chore: restore upstream/main changes dropped by a stash roundtrip during the merge

A git stash/pop cycle used to isolate an unrelated flaky test reverted 82 files of the
merge result to the pre-merge branch state, so commit 375ff2a4a missed them. The
working tree already held the correct merged content; this commit restores it.

* fix(agent-core-v2): propagate the cancellation reason from turn abort to tool signals

Cancelling a turn aborted the turn's llm scope and every tool scope
without a reason, so tools and subagents only ever saw the default
AbortError and could not tell a user cancellation from a system abort.
With the swarm terminal-event classification this surfaced as
`subagent.failed` ("This operation was aborted") on Ctrl+C instead of
`subagent.cancelled`.

Carry the reason end to end: `MachineEngine.abort(reason)` sends it on
`input.abort`, the agent machine remembers it for the turn and forwards
it to `turn.abort` and to every tool scope it aborts, the turn machine
passes it to the llm scope, and the loop service hands its cancellation
(a `UserCancellationError` by default) to the engine.

* fix(agent-core-v2): stop rebuilding an evicted subagent after its caller aborts

`createAgentAwaitingClose` polled for the previous scope to finish
closing without ever looking at the caller's abort signal, so cancelling
an `Agent` or `AgentSwarm` resume during that wait still recreated the
scope afterwards. In the `Agent` path the run then rejected before any
terminal event was mirrored, leaving an idle scope that the scope cache
no longer tracked.

Thread the caller's signal into the helper and check it before every
attempt; the Agent tool passes its call controller and the swarm service
passes the attempt signal. Also trim the eviction changeset to the one
sentence the changeset rules ask for.

* fix(agent-core-v2): report task-manager aborts of a subagent as cancelled

When the task manager times out or stops a background subagent it aborts
the run with a plain reason ('Timed out', the TaskStop reason), and the
run rejects with that raw reason. The task manager therefore classifies
the task as timed_out or killed, but the mirror only recognised
`UserCancellationError` as a cancellation and emitted `subagent.failed`,
so the transcript recorded a failure before the authoritative
`background.task.terminated` event could land.

Classify a terminated run by the shape of its abort reason: a real
Error that is not an AbortError (the swarm's own per-item timeout) stays
a failure, everything else that aborted the run is a cancellation. The
swarm's start-failure path uses the same rule.

* fix(agent-core-v2): flush the wire before evicting a subagent scope and re-pick LRU candidates

Two gaps in the scope-cache eviction pass:

- `AgentLifecycleService.remove()` swallows a failed wire flush and still
  tears the scope down, so an eviction that hit a disk-full or transient
  I/O error would drop the in-memory scope and let a later resume rebuild
  from a stale wire. Flush the agent's wire explicitly before removing;
  if that fails, keep the scope resident and retry on a later pass. The
  idle and task checks are repeated after the flush so a resume that
  started meanwhile is not cancelled by the removal.
- The pass snapshotted its candidates up front and re-validated them by
  attempt count only, so a scope that was resumed and completed again
  while an earlier eviction was awaited kept matching with attempts 0 and
  was evicted despite now being the most recently used. Pick the oldest
  eligible entry from the live map on every step instead, skipping only
  the entries this pass already tried.

---------

Co-authored-by: Kaiyi <me@kaiyi.cool>
2026-09-15 20:33:24 +08:00
Kimi Agent
39a74556a6
fix(plugins): rename WebBridge display name to Kimi Browser Extension (#3803)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* fix(plugins): rename WebBridge display name to Kimi Browser Extension

The product has renamed WebBridge to Kimi Browser Extension in work and
Chrome. Update the user-facing display name across the built-in
capability entry, TUI plugins selector, managed plugin manifest,
marketplace catalog, skill docs, and user docs to match. Internal ids,
binary names, CDN paths, and daemon references are unchanged.

* fix(plugins): bump webbridge to 1.11.4 and keep legacy docs anchor

Address review: point the changeset at the scoped CLI package, bump the
renamed plugin's manifest/catalog/docs version so installed users are
offered the renamed package as an update, and preserve the published
#kimi-webbridge documentation anchor beside the renamed heading.

* docs(plugins): match only the known extension-update error messages

Broadening the version-mismatch trigger to the generic prefix 'Please
update the' would misclassify unrelated tool errors as an outdated
browser extension; match the two known full messages instead.

---------

Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>
2026-09-15 18:13:51 +08:00
liruifengv
bb0c66a15b
feat(oauth): switch the managed usage payload to the quota model (#3787)
The platform /usages payload now serves per-window used ratios
(goods_version, a usages map of limit5h/limit7d/monthTotal/monthCode
entries with used_ratio/reset_time, and boosterWallet) instead of
absolute used/limit rows.

- oauth: parse and fetch the quota model; keep the platform helpers
- toolkit / agent-core-v2 / node-sdk: getManagedUsage returns the quota
- kap-server: /oauth/usage passes the camelCase quota shape through
  (the legacy snake_case wire is gone)
- TUI /usage: plan rows are presence-driven from the quota payload;
  the monthly row carries a kimi/code breakdown line
- docs: server-api reference updated for the new response shape
2026-09-15 13:33:20 +08:00
HydrogenE7
f2486241fb
perf(agent-core-v2): shard the session event bus by agent id (#3775)
* perf(agent-core-v2): shard the session event bus by agent id

* fix(agent-core-v2): preserve full-stream-before-typed ordering in agent channels and render perAgent counts in the inspector

* fix(agent-core-v2): deliver agent full streams before session typed handlers and dispose sharded channels with the bus

* fix(agent-core-v2): prevent rebuilding agent channels after the event bus is disposed

* fix(agent-core-v2): isolate agent channels on generation replace and keep typed handlers on the shared per-type channel

* fix(agent-core-v2): require the active lifecycle context before firing an agent full-stream channel

* fix(agent-core-v2): reject stale lifecycle contexts when subscribing to an agent full-stream channel

* fix(agent-core-v2): honor the agent context in typed subscribeAgent subscriptions
2026-09-15 12:18:20 +08:00
tpoisonooo
0725ef1ce0
fix(agent-core-v2): tower mode mistaking newly agents for previous name (#3752)
* fix(agent-core-v2): resolve tower roster identities to the latest registration

Agent ids restart from agent-0 in each session, so a freshly spawned
worker collided with the previous session's roster entry and every
find-first lookup (caller identity, write guard, death bookkeeping)
resolved to the stale entry: workers read the wrong inbox, sent under
the wrong name, and were denied their own writes, mission updates, and
reviews.

- resolveAgent picks the latest roster entry for an agent id; all
  callers (resolveCallerName, write guard, resume veto, died/revived)
  go through it
- registerAgent retires same-agent-id entries before appending
- enter() (/tower on) now adopts the workspace roster itself instead of
  relying on a manual TowerInit

* fix(agent-core-v2): adopt the tower roster when a replayed tower mode finds a dead foreign owner

A forked or restored session replays the durable TowerModeEnter into an
active tower mode without ever calling enter(), so the roster adoption
added there never ran on the restore path: with the previous owner
session gone, the fork kept the mode (and the stale roster) until a
manual TowerInit. The dead-owner branch of the restore-time
reconciliation now adopts the workspace, mirroring enter()'s takeover
of an idle owner; a live foreign owner still causes an exit.

* fix(agent-core-v2): await the outgoing tower owner's release before adopting its roster

Taking tower mode over from a live but idle owner called the owner's
synchronous exit(), whose ownership release ran fire-and-forget, and
immediately adopted the roster — two concurrent load-modify-save cycles
on .tower/comms/state.json that could lose the new owner or resurrect
the stale roster. exit() now awaits the ownership release and the
takeover awaits the owner's exit(); the remaining callers either await
(RPC/HTTP tower-mode-off) or explicitly ignore the promise (mode mutex,
restore-time self-exit).

* fix(agent-core-v2): fail tower activation when the roster adoption cannot complete

Adoption failures (unreadable or unpersistable state.json) were
swallowed into a log warning, so enter() and the stale-owner restore
both activated tower mode with the foreign owner and stale roster still
in place — the exact identity mismatch the adoption is meant to
prevent, now with a false success report. adoptTowerRoster() now throws
a TowerProtocolError with the underlying cause: enter() propagates it
before any tool is activated, and the restore path drops the replayed
tower mode instead (it must not throw inside the restore hook chain).

* fix(agent-core-v2): propagate unreadable tower state during roster adoption

adopt() treated any state.json read failure as an uninitialized
workspace via isInitialized()'s catch-all, so an existing but
unreadable state file (EACCES, EISDIR, transient I/O) reported a
successful no-op adoption and enter() activated tower mode against the
foreign state — bypassing the activation guard added in the previous
commit. Only ENOENT now means uninitialized; every other read error
propagates into the fail-activation / deactivate-on-restore paths.

---------

Co-authored-by: konghuanjun <konghuanjun@moonshot.ai>
2026-09-15 12:03:10 +08:00
qer
1336be3877
fix(kap-server): verify indexed search results against session sources (#3631)
* fix(kap-server): verify indexed search results against session sources

* fix(kap-server): reject unverifiable search source identities

* fix(kap-server): bound search source checks by the query deadline

* fix(search): report sessions skipped during indexing

* fix(search): bound outstanding source identity checks

* refactor(search): group source check coordination state

* test(search): isolate source check limit from background sync
2026-09-14 21:36:33 +08:00
Haozhe
2d4d799ac3
fix(kap-server): omit hidden thinking summaries from v1 session history fold (#3765) 2026-09-14 19:56:55 +08:00
Haozhe
cd0d4a1d3e
fix(agent-core-v2): display reasoning_content over reasoning_details summary in chat completions (#3735) 2026-09-14 19:51:33 +08:00
Haozhe
4623395379
refactor(agent-core-v2): fold the prompt queue into the agent loop service (#3747)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* refactor(agent-core-v2): fold the prompt queue into the agent loop service

Delete AgentPromptService/IAgentPromptService: prompt submit/queue/steer/
abort now ride the agent machine queue through IAgentLoopService's extended
surface (submitPrompt/submitSteerPrompt/enqueuePrompt/steerPrompts/
abortPrompt/drainPrompts/injectPrompt/retryPrompt/promptQueue plus
hooks.onBeforeSubmitPrompt and the promptAdmission reservation slot).

Durable prompt.* event classes move to agent/prompt/promptEvents.ts and keep
their registrations; promptAdmissionKey keeps its fold. Dead assets go away:
promptResolutionKey, PROMPT_ALREADY_COMPLETED (kap-server 40903 path),
promptLaunchingKey and clear(). Compaction gating (queue while compacting,
resume on finish) moves into the loop reservation drain.

The 'agentPromptService' wire name keeps its shape: a thin AgentPromptChannel
facade (same decorator id) forwards submit/submitSteer to the loop, so
klient memory/ipc/debug transports and the kap-server dispatcher are
unchanged.

* test(agent-core-v2): re-pin prompt queue semantics on the loop service

Rewrite promptService.test.ts (25 cases, count unchanged) against the real
AgentLoopService with the scripted-LLM harness, fold the launch-window
reservation out of promptQueue().pending to match the old snapshot contract
exactly, and update the debug-channels pin to the facade's submit/submitSteer
surface.

* refactor(agent-core-v2): lint-align the loop prompt queue surface

* fix(agent-core-v2): settle prompt completions on the turn-result chain

Match the deleted service's microtask position: prompt.completed/aborted and
the completion deferreds fire from a result.then chain attached at bind time
instead of synchronously inside endTurn, so wire/emit ordering with
post-turn producers (tool unregister, next-prompt launch) stays identical to
the baseline snapshots. Steered children move onto the reservation so the
chain can settle them after the active turn is gone.

* refactor(agent-core-v2): move the prompt-submit gate into the agent machine

* refactor(agent-core-v2): keep image compression captions inline in prompt messages

* refactor(agent-core-v2): drop the durable prompt admission facility

* refactor(kap-server): resolve prompt auth at turn runtime instead of submit time

* refactor(agent-core-v2): teach the agent machine queue metadata, multi-id steer, gate rewrite, and pause

* refactor(agent-core-v2): converge prompt submission on machine queue user entries

* refactor(agent-core-v2): replace loop prompt records with a waiter registry fed by machine events
2026-09-14 15:07:18 +08:00
liruifengv
6126472c7a
feat(agent-core-v2): graduate AI session titles from experimental (#3749) 2026-09-14 11:53:19 +08:00
Haozhe
7d7e8de80c
refactor(agent-core-v2): rebuild wire persistence and flip agents to session-spawned actors (#3737)
Some checks are pending
CI / test-windows (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* feat(agent-core-v2): persist the human runtime mirror as human.* records in the wire journal

Introduce mode-2 coexistence: the machine eventStore journal becomes a
tree-projection-filtered adapter over the same wire file (single writer via
the WireService append queue), the engine switches from memoryJournal to the
file journal with a seed fallback while no human records exist, and cold
readers skip the new record family constructionally. Adds downgrade
round-trip e2e coverage, whitelists agent.switched/context.undone from
unknown-record telemetry, asserts the undo switch triple after flush, and
resets the machine engine after an undo rerun so machine and wire turn
clocks stay aligned.

Squashed from:
refact(agent-core-v2): project wire journal as an in-memory branch tree behind IAgentJournal
refact(agent-core-v2): undo as branch switch with dual-emitted legacy record and restore replay
refact(agent-core-v2): queue late attachments during restore rerun and flatten fork sources to the active chain
feat(agent-core-v2): persist the human runtime mirror as human.* records in the wire journal

* feat(agent-core-v2): add full compaction to the human agent domain

* refactor(agent-core-v2): keep pending input state events out of the wire journal

* refactor(agent-core-v2): flip agent DI scope ownership to session-spawned agent actors

* refactor(agent-core-v2): build the agent wire and blob views in the session layer

* refactor(agent-core-v2): persist human domain records under the agent.* wire namespace

- replace the human. record prefix with an explicit whitelist (AGENT_WIRE_RECORD_TYPES) guarded against the Event2 vocabulary; legacy human.agent.* journals stay readable through a transition prefix
- unknown-type records skipped during restore now go to the log file instead of the console (malformed records still report to the console)
2026-09-13 23:01:45 +08:00
Haozhe
f728cb158c
fix(agent-core-v2): rebuild session and search indexes on storage failures, journal session-index freshness (#3694)
* fix(agent-core-v2): rebuild session and search indexes on unrecoverable storage failures

* fix(agent-core-v2): propagate search sync truncation and track session count in index freshness

* fix(minidb): wipe derived stores under their own locks during rebuild

* fix(agent-core-v2): isolate wiped stores, invalidate stale projections, and account sync failures

* feat(agent-core-v2): replace session index freshness scans with a dirty journal and targeted reconciliation

* fix(agent-core-v2): split transient failures by op kind, surface failed startup reconciliation, and cool down search session skips
2026-09-10 23:23:08 +08:00
7Sageer
18f77efad6
refactor(agent-core-v2): plug llm credentials in through request config (#3682)
* fix(agent-core-v2): honor request-level toolMessageConversion in openai formats

The requester already forwarded LlmRequestConfig.toolMessageConversion
into formatRequest, but the openai chat and openai-responses formats
only read the trait hook, so the explicit request config was silently
ignored. Resolve the mode as request config, then trait default, then
the protocol default, and pass the resolved value into lowering.

* refactor(agent-core-v2): split the protocol trait into per-protocol dialects and provider connection

The ProtocolTrait interface bundled endpoint/headers connection config,
model capability, message/params conversion hooks, and error
classification into one bag, and every format received the whole bag
whether or not it consumed each hook — hooks a protocol ignores were
accepted by the type system and silently dead at runtime.

Split it by consumer:

- ProviderConnection (protocol/connection.ts): endpoint env
  declaration and default headers, still resolved per request inside
  generate.
- Per-protocol typed dialects (OpenAIDialect, OpenAIResponsesDialect,
  AnthropicDialect, GoogleGenAIDialect): only the customization points
  each protocol actually consumes; data-shaped hooks (reasoningKey,
  toolCallIdPolicy, toolMessageConversion, strictThinkingValidation)
  are data fields, and message/history hooks use the protocol wire
  types instead of Record<string, unknown>.
- convertError moves to a requester option, capability to a provider
  variant field.

Dialects are bound when the format is created (createOpenAIFormat and
siblings), so FormatRequestInput and the stream parser carry request
data only; ProtocolTrait is deleted. The thinking hook returns the
kwargs and the preserveThinking flag together as ThinkingApplication,
and the kimi dialect emits the final thinking params directly instead
of routing them through an extra_body flatten in buildParams. The
llm-adapter layer is migrated to the same {connection, dialect,
convertError} assembly.

* refactor(agent-core-v2): compose format stages and dialect hooks in the requester pipeline

* refactor(agent-core-v2): rename protocol dialects to traits

* fix(agent-core-v2): include the system message in openai mergeHistory input

* refactor(agent-core-v2): enforce the format/trait contract boundary

- move CONTEXT_MANAGEMENT_BETA into anthropic/contract and have the kimi
  trait import wire types from each protocol's contract.ts instead of
  format/lower; export the four contract modules from human/index.ts and
  guard the boundary in check-import-boundaries
- rename protocol/trait.ts to protocol/thinking.ts and move TraitContext
  to protocol/base.ts; clean up the remaining dialect-era test variable
- type extractUsage as OpenAIRawUsage / OpenAIResponsesRawUsage instead of
  Record<string, unknown> and drop the requester-side casts

* refactor(agent-core-v2): thread the request config by spread and drop dead format types

- the four requesters spread LlmRequestConfig into the plan input instead
  of hand-enumerating fields, so a new cross-protocol config field cannot
  be silently dropped per protocol
- ProtocolFormat loses the phantom TRequest/TResponse type parameters;
  the dead OpenAIRawResponse/AnthropicRawResponse/GoogleRawChunk contract
  types go with them
- the thinking test now names the extra_body flatten behavior explicitly

* refactor(agent-core-v2): keep protocol format modules internal to the requester pipeline

- drop the four format barrels (and openai/reasoning-key) from
  human/index.ts; each base's public seam is now exactly
  contract / trait / requester
- stop re-exporting contract wire types from format/lower modules so the
  neutral vocabulary has a single home; move the *LoweredMessage staging
  types out of contract into the owning format module
- guard the seam in check-import-boundaries: only llm/requester/bases
  code and tests may import format/lower/patterns/reasoning-key

* refactor(agent-core-v2): plug llm credentials in through request config

Replace the withAuth/withAuthUpload requester decorators with a
credential contribution point on LlmRequestConfig: the llm machine's
request actor (machine path) and ModelRequesterImpl (direct path)
resolve credentials per attempt, and a recoverable 401 is recovered by
invalidating and re-resolving — emitted as llm.recovering on the turn
machine's credentials branch.

* fix(agent-core-v2): surface request-actor failures as llm.failed.remote

A rejection inside the llm machine's detached request actor (credential
resolution, message resolvers, or a throwing requester) could not reach
the machine, leaving the turn stuck in thinking. Convert it to an
llm.failed.remote event so the turn lands in its failed state.

* docs(agent-core-v2): attribute retry/recovery to the turn machine in llm.md

* refactor(agent-core-v2): unify credentials in human/credentials, turn-owned 401 recovery

* fix(agent-core-v2): credential recovery for direct paths, abort guard, turn-snapshotted credentials

* feat(agent-core-v2): IModelCatalog.generate with stream credential recovery

* refactor(agent-core-v2): inline credential recovery at call sites

Remove the attemptWithCredentialRecovery/streamWithCredentialRecovery
helpers from human/credentials; the single-retry recovery is now written
out at each direct call site (catalog ping/generate, full compaction,
media upload) so the control flow reads linearly without a wrapper hop.
The credentials module keeps only the provider factories and the
credential application helpers; recoverability and invalidation stay on
the LlmCredentialProvider itself.

* fix(agent-core-v2): settle the queued turn when a machine turn settles before gating

When the llm machine fails before requester.generate() runs — for
example when OAuth credential resolution rejects — the loop cleared the
pending machine turn marker on turnSettled without ever binding or
settling the queued reservation, leaving the submitter's ready/result
promises and settled() hanging. The loop now settles the unbound
reservation explicitly: cancelled on abort, failed otherwise, mirroring
the evaluateSettle error propagation.

* fix(agent-core-v2): bind and end pre-gate failures through the normal turn lifecycle

The direct settlement resolved turn.result without endTurn(), so no
TurnPrompt/TurnStarted/TurnEnded/AgentErrorEvent was published and the
next queued reservation was never launched. The unbound reservation is
now bound via beginActiveTurn and ended via endTurn (failed, or
cancelled on abort), chained onto afterChain when the previous turn is
still settling, so pre-gate failures get the same lifecycle events and
queue progression as any other failed turn.

* fix(agent-core-v2): settle seeded turns on pre-gate failure, preserve coded credential errors, close steps on recovering

- Notification-seeded machine turns that fail before gating now bind a
  seeded reservation and end through endTurn like queued ones, instead
  of leaving the nudge pending and settled() hanging
- The llm machine's request actor attaches the raw error to
  llm.failed.remote and the turn machine prefers it for its terminal
  failure, so coded errors (e.g. auth.login_required) survive to
  endTurn's error payload
- projectMachineEvent now closes the current machine step on recovering
  exactly as it does on retrying, keeping step.begin/step.end balanced
  when credential recovery re-enters the request

* fix(kap-server): add generate to IModelCatalog test fakes

* fix(klient): migrate examples to the credentials API

* test(agent-core-v2): drop credential recovery coverage

* refactor(agent-core-v2): fold kimi-oauth credential adapter into credentials/

* refactor(agent-core-v2): pair credential refresh with invalidate, optional Model.credentials, abort-safe request actor

- oauthCredentials.invalidate() now starts the forced refresh eagerly and
  hands the pending token to the next resolve(), so the force signal can no
  longer leak into or be consumed by unrelated resolves
- Model.credentials becomes optional, dropping the {} as never /
  staticCredentials(undefined) filler in test fakes
- the llm machine request actor swallows abort outcomes instead of
  reporting llm.failed.remote, so an aborted turn settles as aborted
  rather than failed

* refactor(agent-core-v2): credentials recovery strategy chain, shared credential-recovery executors, single-proposal failure triage

* fix(agent-core-v2): settle message-less notifications on pre-gate failure, recover credentials in media resolver uploads

* test(kap-server): add the IModelCatalog.generate stub to the history suite
2026-09-10 20:39:22 +08:00
Haozhe
64505e36e3
feat(kap-server): add flat entity message protocol (v3 WS + history API) (#3532)
* feat(kap-server): add flat entity message protocol (v3 WS + history API)

* feat(kap-server): add task notification user messages, skill origins, and history has_more

* fix(kap-server): page history by turns so oversized turns stay reachable

* fix(kap-server): synthesize foreground subagent tasks in the cold fold when no task records exist

* fix(kap-server): dedupe queued prompts for turn records without a prompt id

* fix(kap-server): adapt v3 projection to agent-core-v2 API changes and filter empty thinking

* feat(kap-server): align v3 protocol with design revision 1094 and add agent.state

---------

Co-authored-by: liruifengv <liruifeng1024@gmail.com>
2026-09-10 19:08:27 +08:00
Kai
9f7e68e8bd
fix(mcp): preserve original attachments omitted from model output (#3688)
* fix(mcp): preserve original attachments omitted from model output

* test: register session media storage in agent lifecycle fixture

* fix(mcp): retain media originals and bound attachment details

* fix(mcp): resolve session attachments and honor cancellation

* test: check concrete media references in provider requests

* fix(media): read session attachments from their owning storage

* fix(media): preserve attachment access across runtime and history changes

* fix(mime): recognize structured application text attachments
2026-09-10 10:37:31 +08:00
Haozhe
6299cfda70
feat(kap-server): stream raw xstate inspection events over /api/v1/debug/ws (#3687) 2026-09-09 20:20:12 +08:00
Haozhe
56ed9549c6
refactor(agent-core-v2): remove AgentActivityView and project v1 agent phase at kap-server edge (#3678)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
2026-09-09 17:18:36 +08:00
Haozhe
27b7349ebb
refactor(agent-core-v2): rewire the model catalog runtime onto the provider-catalog state machine (#3606)
The human/llm provider-catalog state machine becomes the single source of
truth for the runtime model/provider directory. IModelCatalog's data plane
reads through a new llm-adapter catalog-runtime adapter that mirrors config
section diffs into catalog upserts, and CatalogEntry cache invalidation is
driven precisely by the machine's changed events instead of a blunt clear.
The persistence layer is untouched: config.toml stays the full source of
truth and refresh results keep being written to it.

Also remove the model resolution trace/inspect stack end to end:
ResolutionTraceCollector, the llm-adapter model/contract inspection modules,
IModelCatalog.inspect, the capability explainability indirection, and the
kimi-inspect model inspector panel.
2026-09-09 15:37:44 +08:00
Haozhe
68f8984a7c
refactor(agent-core-v2): single producer for turn and step ids (#3662)
- the human agent state machine now assigns turn ids and echoes the drained queue item in turn.started; the facade adopts machine ids instead of reserving its own
- the turn machine produces the step ordinal and surfaces it via a first-class step.started fact; the llm requester layer stays step-agnostic
- turn.prompt wire records carry an explicit turnId; turnKey and transcript foldFacts read it directly with a counting fallback for legacy records
- queued prompts are addressed by promptId: cancel(turnId) is active-turn only, cancelQueued targets queue entries, Turn.id resolves once the turn starts
- drop PromptPayload.disabledTools and its klient/node-sdk pass-through (no client consumer)
2026-09-09 15:24:02 +08:00
Kai
7f5debfa71
fix(agent-core-v2): fall back to the configured default model for image format gating (#3652) 2026-09-08 20:42:25 +08:00
Kai
80480c01d2
feat(agent-core-v2): accept HEIC, HEIF, and BMP images for Kimi models (#3649)
* feat(agent-core-v2): accept HEIC, HEIF, and BMP images for Kimi models

Key the accepted image MIME set by the provider the agent is bound to
instead of a single global allowlist: Kimi accepts PNG/JPEG/GIF/WebP plus
BMP/HEIC/HEIF, every other provider keeps the baseline set. The provider
image policy lives in the human layer (`llm/media/image-formats`) so both
the agent-side gates and the Anthropic protocol lowering share it.

- thread the provider type through every ingestion gate: ReadMediaFile,
  prompt entry, MCP tool results, session media references, kap-server
  prompt/skill routes; expose it via IAgentProfileService.getModelProviderType
- ReadMediaFile sends accepted formats it cannot re-encode locally inline
  up to the provider's per-image budget (5MB for Kimi, 3.75MB otherwise)
  and points at a conversion command above that; full_resolution uses the
  same provider budget
- acp-server no longer gates formats itself and leaves the decision to the
  engine prompt pipeline, which knows the bound provider
- the Anthropic lowering allowlist follows the bound provider so Kimi over
  the Anthropic-compatible protocol no longer rejects HEIC client-side

* fix(agent-core-v2): resolve the image format policy on the production paths

Follow-ups from review of the provider-aware image formats:

- the Anthropic lowering read the policy from `LlmModel.provider`, which
  the adapter registry sets to the route id (`anthropic`) rather than the
  model's provider type, so Kimi over the Anthropic-compatible protocol
  still rejected HEIC client-side; the accepted set now comes from a
  `ProtocolTrait.acceptedImageMimes` hook that the Kimi traits implement,
  and the test goes through the real trait with the routed provider id
- kap-server prompt ingestion gated media against the currently bound
  model even when the same request selected another model; the profile
  service now resolves the provider type for a requested alias
- the session media memo served a cached inline image to a provider that
  does not accept its format; memo hits are re-judged against the current
  provider before being returned
- the media tools registrar keyed ReadMediaFile only by alias and
  capabilities, so a reload that changed the alias's provider type or
  protocol kept the stale tool; both now take part in the key

* test(kap-server): keep the optional chain the lint autofix dropped
2026-09-08 19:28:23 +08:00
Haozhe
9188d03c99
refactor(protocol): remove package and relocate wire types into agent-core-v2 (#3646) 2026-09-08 17:41:41 +08:00
Haozhe
14cc78611d
refactor(agent-core-v2): replace interaction DI services with a global human singleton (#3644)
* refactor(interaction): replace per-agent InteractionService with human-native session facade

- add human/interaction: global interaction machine + tag-query facade (enqueue/respond/findAll/findOne/wait)
- add session-scope SessionInteractionService owning one interaction actor per session
- rewire approval/question/userTool/sessionActivity to the session facade and delete features/interaction

* refactor(interaction): rewire kap-server, klient and node-sdk to the session interaction facade

- kap-server routes, ws broadcaster and transcript binding read ISessionInteractionService (tags replace origin)
- klient memory dispatcher delegates to the session service; zod contract mirrors origin -> tags
- node-sdk session wiring subscribes the session service directly
- register interaction wire events in their new home and regenerate the wire manifest

* refactor(agent-core-v2): replace interaction DI services with a global human singleton

resolve rebase conflicts
2026-09-08 17:39:16 +08:00
Haozhe
324774d812
test: stabilize the full suite on macOS developer machines (#3643)
Some checks are pending
CI / lint (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
- scrub all ambient KIMI_CODE_* env vars in the agent-core-v2 and
  kap-server test setups so developer shell env cannot leak in
- drop the load-sensitive stepRetry fake-timer cases and the three
  FSEvents-based skill catalog watch cases
- give node-sdk, klient and the vscode extension project an explicit
  15s testTimeout matching their integration-test nature
- retry temp-dir removal in taskManager teardown to absorb async
  terminal-effect writes
2026-09-08 16:21:16 +08:00
Haozhe
c156ed5ea9
test(kap-server): drop the flaky two-pass swap catalog import case (#3636) 2026-09-08 12:55:30 +08:00
qer
fa87d040c3
feat(kap-server): expose session deletion with serialized cleanup (#3630)
Some checks are pending
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
2026-09-08 03:00:40 +08:00
HydrogenE7
5eea890165
fix(agent-core-v2): attribute event-loop-busy decode time to the client (#3607)
The decode-window split measured part arrival at the moment the event
loop resumed the pending await, so any loop-busy work (rendering,
timers, GC) between parts was reported as server time. Measure loop
utilization across the decode window with perf_hooks and split it into
loop-idle wait (server), per-part processing (client), and a new
clientBlockedMs bucket (loop busy with other work), carried through to
the step events, wire record, transcript contract, and the TUI debug
timing line.
2026-09-07 16:43:44 +08:00
Haozhe
369dbff8db
fix(remote-control): release the lock before reporting off and re-read the server token per forward (#3599)
* fix(remote-control): release the lock before reporting off and re-read the server token per forward

* fix(remote-control): pass the token provider through the manager
2026-09-07 14:15:28 +08:00
Haozhe
48f5dc9740
feat(kap-server): add remote-control runtime toggle API (#3594)
* feat(kap-server): add remote-control runtime toggle API

* feat(remote-control): manage tunnel lifecycle with an xstate state machine
2026-09-07 13:46:22 +08:00
Haozhe
3f967e1410
refactor(agent-core-v2): unify fs watching into a single xstate watch service (#3502) 2026-09-07 13:30:25 +08:00
Haozhe
c1cac3436d
fix(kap-server): stop event journal writes after server close (#3595) 2026-09-07 12:07:30 +08:00
Haozhe
f0434f2d25
feat: graduate remote-control, minidb read model and search worker from experimental flags (#3552)
- remote-control is always available: kimi rc, kimi web --remote-control and /remote-control no longer require KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL or the master flag
- add the [database] config section with base (session-index read model) and search (global search worker) kill switches, both defaulting to true
- rename the kill-switch env vars to KIMI_CODE_PERSISTENCE_MINIDB_READMODEL and KIMI_CODE_SEARCH_WORKER (precedence: env > config > default)
2026-09-07 11:28:35 +08:00
Haozhe
485594f65e
refactor(agent-core-v2): absorb the human layer and replace the agent loop with a facade over its turn state machine (#3580)
* refactor(agent-core-v2): absorb the human layer into src/human and rename vendored kosong to llm-adapter

* feat(agent-core-v2): preserve media attachment names in human message contract

* refactor(agent-core-v2): remove llm-adapter code duplicated in human/llm

* refactor(agent-core-v2): replace the agent loop with a facade over the human turn state machine

* refactor(agent-core-v2): rename the loop adapter layer to loop/machine

* test(acp-server): implement gateway resolve in the scripted provider stub

* refactor(agent-core-v2): restore v2 batch semantics in the loop machine tools adapter

- delegate each step's tool calls to the v2 tool executor as one whole
  batch: beginBatch arms the expected call set from the llm.done entry,
  per-actor execute calls collect into a pending barrier, and the full
  batch is submitted in tool-call order once complete
- drop the serial batchChain/batchStopped/skipped approximation so the
  executor's prepare-stage stopBatchAfterThis skip, veto short-circuit,
  and ToolScheduler access-based concurrency apply natively again

* fix(build): update flake pnpmDeps hash for the post-absorb lockfile

* fix(agent-core-v2): align loop facade reservations with the machine queue by id

* fix(agent-core-v2): drain persisted wire records before turn end

* fix(agent-core-v2): route executor-level tool errors to the loop error path and backfill aborted tool results on forced abort

* fix(agent-core-v2): keep turn step retrying in the facade step numbering space
2026-09-06 22:26:35 +08:00
Luyu Cheng
baf17a8fcc
feat(protocol): preserve media attachment names (#3548)
Some checks are pending
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
Preserve optional image and video filenames through media resolution, shared protocol schemas, turn events, and transcript reconstruction. Cover stored media reuse, unsupported image conversion, and steering with regression tests.
2026-09-06 14:30:52 +08:00
qer
eba23edb93
feat(agent-core-v2): drop the experimental gate from turn-level file history (#3525)
* feat(agent-core-v2): drop the experimental gate from turn-level file history

The file_history flag and its KIMI_CODE_EXPERIMENTAL_FILE_HISTORY env
var are removed; first-touch baselines, turn checkpoints, and the
changes/turnRecorded/contentAt reads now run unconditionally, so the
per-turn file diffs served by kap-server no longer depend on opt-in
configuration.

The changes REST response drops its enabled field — recorded alone
tells an authoritative empty result apart from a turn whose records
were never made, lost to a crash, or displaced by retention.

* fix(agent-core-v2): probe blob existence with a stat, not a directory listing

turnRecorded always answered false for turns whose snapshots lived under
the file-history/ prefix directory: BlobStoreService.has listed the
scope directory (a shallow readdir) and exact-matched the nested key
against top-level entries, so keyed blobs were never found and the
changes endpoint reported recorded=false for exactly the turns that had
edits. Stat the key through storage.size instead, and pin the
turn-recorded assertions against a real node-fs home so the harness
covers the production layout.

* fix(agent-core-v2): probe every keyed blob before calling a turn recorded

Merging the start and end entries let an end entry with key null (a
deleted or oversize-at-end file) shadow the start baseline, and probing
only one surviving key missed partial loss in the other phase: a
session displaced from the thirty-session window could still claim
authority for turns whose snapshots were gone. turnRecorded now stats
every distinct keyed blob across both checkpoints and reports the turn
unrecorded when any is missing.
2026-09-04 15:57:59 +08:00
Haozhe
20a0ba9b17
test: speed up kap-server suite and exclude minidb from default projects (#3504)
Some checks are pending
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / build (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
* test: speed up kap-server suite and exclude minidb from default projects

* test(kap-server): restore baseline server after sessions tests replace it
2026-09-03 14:32:28 +08:00
Kai
052e98ec17
fix(agent-core-v2): rebuild persisted subagents when resuming after a restart (#3478)
* fix(agent-core-v2): rebuild persisted subagents when resuming after a restart

Agent(resume=<id>) only consulted the in-memory agent roster, so once a
session was reopened in a new process every persisted subagent id failed
with "does not exist" even though its wire log and metadata were intact.
The resume path now reads the session metadata once, verifies the target
is a subagent owned by the caller, and re-creates its agent scope from
the persisted records when it is not live before running the turn.

* fix(agent-core-v2): sync rebuilt subagents to the caller mode and match rules by their persisted profile

A subagent rebuilt for resume replayed the permission mode it was
spawned with, so a child persisted in yolo kept running in yolo after
the parent had switched back to manual; the rebuild now copies the
caller's current mode the way a fresh spawn does.

Permission rules with a profile subject such as Agent(coder) were
matched against the fallback label while the target was offline,
because only live agents exposed their profile during execution
resolution. Every spawn site now records the profile name in the
subagent labels and the resume path reads it back for display and rule
matching when the agent is not live.

Adds a kap-server e2e case that spawns a subagent, restarts the server
on the same home directory, resumes it through the Agent tool, and
checks that its prior context reaches the next model request.

* fix(agent-core-v2): keep pinned permission modes when rebuilding a subagent for resume

Tower workers are pinned to auto mode at spawn and skipped by the
permission-mode broadcast, but the rebuild path synced every restored
subagent to the caller's mode, so a dead worker recovered through
Agent(resume=...) after a restart lost its pinned mode. The exception is
now a single predicate next to the worker profile, shared by the
broadcast and the rebuild.

* fix(agent-core-v2): record subagent profiles in the lifecycle instead of at each spawn site

The persisted profile name that offline resumes use for display and
permission-rule matching was written by three spawn sites, and the
session-init child was still missing it. The lifecycle now records it
centrally: create() takes the profile from the binding it is given and
fork() takes the override or the source agent's profile, so every
subagent spawn is covered and the spawn sites no longer pass it.

* chore: merge the subagent-resume changesets into one
2026-09-02 23:22:22 +08:00
7Sageer
b6f78f9fc8
Revert "fix(agent-core-v2): assemble flag-gated features after config ready (…" (#3486)
This reverts commit eb4cd4b38e.
2026-09-02 21:43:09 +08:00
Haozhe
c52d583143
docs: remove agent-core-v2, kap-server, and transcript package docs (#3481) 2026-09-02 21:33:58 +08:00
Haozhe
75708925a5
fix(kap-server): stop exiting the process on uncaughtException (#3477)
The process-level uncaughtException handler installed by startServer
called process.exit(1), so a single stray exception killed every
session the process served — and, embedded in the desktop main
process, killed the whole app past the shell's own crash guard. Log
the error at error level and keep serving instead.

createServerLogger gains an optional stream so hosts can route server
logs into their own log channel.
2026-09-02 21:16:58 +08:00
tpoisonooo
8057d30afb
fix(tower): support config.toml configuration (#3461)
* fix(agent-core-v2): rework tower mode enter failures and config-flag assembly

- IAgentTowerService.enter() returns a typed TowerEnterResult: the 4
  former silent failure points now carry their reason (not-main-agent /
  experiment-off / feature-not-assembled / owned-by-live-session with
  the owner session id + title); kap-server and node-sdk map each reason
  to a distinct SESSION_TOWER_MODE_INVALID message via
  towerEnterFailureMessage() instead of one misleading catch-all.
- Fix config-sourced [experimental] tower flag never assembling the
  tower feature: ConfigService seeds its state synchronously at
  construction with a best-effort readFileSync of the config document it
  owns, so the flag is already visible when TowerFeature's constructor
  runs during App-scope creation. No event machinery: a runtime config
  flip updates flag reads but does not re-run feature constructors — a
  restart is required, pinned by test. docs/flag.md + docs/features.md
  document the contract.
- Consolidated changeset for @moonshot-ai/kimi-code.

* fix(tower): release handler when teardown

---------

Co-authored-by: konghuanjun <konghuanjun@moonshot.ai>
2026-09-02 21:16:14 +08:00
7Sageer
eb4cd4b38e
fix(agent-core-v2): assemble flag-gated features after config ready (#3471)
FeatureAssemblyService ran during the eager bootstrap batch, while
ConfigService was still loading config.toml asynchronously, so
flags.enabled() always read false for config-sourced flags and gated
features (e.g. tower via [experimental] tower = true) never assembled.

registerFeature now accepts a { flag } option; gated registrations are
assembled in a deferred pass once IConfigService.ready resolves, and
IFeatureAssemblyService.ready exposes that pass. WorkspaceInstanceManager
.materialize also awaits config.ready so session creation cannot race
the deferred assembly.
2026-09-02 21:09:35 +08:00