Commit graph

242 commits

Author SHA1 Message Date
liruifengv
92c3c59b22
feat: expose resolved base_url on models.dev catalog provider items (#3909)
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 / Publish native release assets (push) Blocked by required conditions
Publish VS Code extension / Publish VSIX to marketplaces (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
2026-09-18 20:43:06 +08:00
Grapedge
3cc6b2a330
feat(kimi-code): carry turn trace id and copilot stats in rating surveys (#3907) 2026-09-18 19:49:19 +08:00
Haozhe
60f2a63278
fix(agent-core-v2): reuse the queued prompt id for a single steer (#3906)
* fix(agent-core-v2): reuse the queued prompt id for a single steer

A follow-up sent during a turn minted a second context id, so cancel
while the model was still requesting could show the same text twice
and make the host prompt un-undoable. Reuse the queued prompt id when
one prompt is steered, mark that user as in-turn so undo targets the
host turn, and project it as a non-anchor origin for the client.

* fix(agent-core-v2): type in-turn steer origin on the human prompt

The human PromptOrigin type rejected the inTurn field, which failed
typecheck/build and left the generated state manifest stale.
2026-09-18 18:56:08 +08:00
7Sageer
b0d0a80c32
feat: add usage telemetry for swarm, tower, external hooks, and remote control (#3897)
* feat(agent-core-v2): add tower_mode_enter telemetry for tower mode entry

* feat(agent-core-v2): add swarm_mode_entered/exited telemetry

* feat(agent-core-v2): add external_hook_resolved telemetry

* feat(agent-core-v2): add tower_mode_exit telemetry

* feat(kap-server): add remote_control_toggle telemetry

* fix(agent-core-v2): exclude aborted hooks from failure count and track tower entry errors

* fix(agent-core-v2): keep decorated params contiguous in ExternalHooksRunnerService

* fix(kap-server): classify failed remote control disables in telemetry

* fix(kap-server): ignore stale tunnel errors when disabling an already-off remote control

* fix(kap-server): distinguish a failed concurrent startup from a disable failure

* refactor: slim telemetry event payloads and outcome branches

* refactor: inline remote-control tracking and drop redundant event properties

* refactor: tighten hook failure filter and remote-control test fake

* fix(agent-core-v2): count hook spawn and wait failures in failed_count
2026-09-18 18:36:02 +08:00
Haozhe
73ebe9ab2f
fix(transcript): attach promptIds to cold-folded steer frames (#3896)
* fix(transcript): attach promptIds to cold-folded steer frames

* chore(changeset): note cold-folded steer frames after reload
2026-09-18 16:37:33 +08:00
Haozhe
53e5e3fca6
fix(agent-core-v2): pair steered follow-ups by reserved message id (#3891)
Reserve the context message id when a prompt is steered, emit turn.steer only after that message is appended, and join live/cold transcript plus fork by the id instead of content.
2026-09-18 16:05:27 +08:00
HydrogenE7
5108cad9b6
perf: speed up session resume and session index on large workspaces (#3889)
- engine: single-pass wire restore, deferred immer freeze during replay,
  concurrent task-file reads, O(1) token-counting/file-history folds
- sdk: windowed tail-read replay fold overlapped with engine restore
- kap-server: incremental wire cache for transcript reads, bounded-concurrent
  user-messages fan-out, search sync fingerprints and capped passes
- session index: O(1) by-id lookup, dir-mtime freshness signals,
  incremental cold prepare, session_index.jsonl compaction
- cli: deduplicate the user skills watcher
2026-09-18 15:05:23 +08:00
7Sageer
c5ad17f06a
feat(agent-core-v2): support api_key_env for provider credentials (#3762)
* feat(agent-core-v2): support api_key_env for provider credentials

Providers can declare api_key_env = "VAR" in config.toml to read their
Bearer token from an environment variable instead of storing it inline.
The value is resolved per request (rotation-friendly); an unset or empty
variable fails with config.invalid naming the provider and variable.
apiKey+apiKeyEnv and apiKeyEnv+oauth are rejected as conflicts.

The /models refresh path resolves the same chain (inline apiKey ->
apiKeyEnv -> env sub-table); a provider whose variable is unset lands in
failed[] without affecting others, and open-platform providers keep the
env declaration instead of persisting the resolved secret.

Custom registries: applyCustomRegistryProvider consumes the api.json env
field — imported providers get apiKeyEnv, the legacy inline apiKey is
dropped, and a hand-edited apiKeyEnv survives refreshes (tracked via
source.envKey). kimi provider add --api-key and the TUI registry token
field are now optional so public registries import without a key.

* docs: document api_key_env provider credentials

* fix(oauth): preserve hand-edited apiKeyEnv on registry refresh and address review nits

* fix(oauth): validate apiKeyEnv conflicts during refresh and address review nits

* fix(oauth): mirror apiKeyEnv in the klient provider contract and harden refresh validation

* fix(oauth): stop auto-binding registry env names to provider credentials

* fix(oauth): preserve hand-edited apiKeyEnv across registry re-imports

* fix(oauth): scope apiKeyEnv preservation to the owning registry

* fix(agent-core-v2): preserve apiKeyEnv across models.dev catalog re-imports

* fix(kap-server): drop apiKeyEnv when the provider update route receives a replacement key

* fix(agent-core-v2): replace provider credential fields on TOML writeback

* fix(kap-server): normalize whitespace-only api_key in the provider update route

* refactor(oauth): unify provider credential rules into shared primitives

A new provider-credential module in the oauth package owns the credential
precedence chain, the mutual-exclusion conflicts, the user-facing messages,
and the write-side tri-state reconciliation; the refresh orchestrator,
agent-core-v2 (model-auth, catalog, auth readiness), and the kap-server
provider routes compose it instead of re-deriving the rules per layer.

applyOpenPlatformConfig now takes credential: {apiKey}|{apiKeyEnv} and
merges onto the existing record, so open-platform refreshes no longer drop
hand-written fields (customHeaders, the env sub-table) on the inline-key
path either, and the refresh's write-then-undo block is gone.

Registry imports converge on removeCustomRegistryEntries +
applyCustomRegistryEntries (prior-snapshot provenance): the exported
capture/restore helpers are gone, the CLI persists a re-import with a
single setConfig instead of per-id removeProvider RPCs, and
default_model/default_provider survive a re-import whenever they still
resolve. kap-server's importCustomRegistry keeps the purge-then-rewrite
two-phase replace the config service's raw-merging writeback requires.

kap-server create/replace routes accept api_key_env (tri-state, mutually
exclusive with api_key), and GET /config plus the provider catalog item
expose the binding. A declared-but-unset api_key_env now fails readiness
checks with config.invalid (was auth.token_missing), matching request-time
behavior. Registry 401/403 without a key prints an authentication hint.

* fix(cli): persist registry re-import removals on both harness generations

The v2 harness's setConfig deep-merges per domain (retaining omitted keys
and skipping undefined defaults), so a shrunk re-import left removed
providers and aliases in config.toml and kept a cleared default dangling.
The CLI and TUI registry flows now share persistRegistryImport: on v2 the
removal phase and the rebuilt records go out as two atomic
replaceConfigSections writes (the writeback merges alias fields from raw
TOML, so the purge must be persisted first); on v1 the removeProvider RPC
cascades the removals before one merge write. defaultModel/defaultProvider
snapshots are captured before any removal so the restore works on both
paths.

* fix(oauth): reject oauth before the legacy env fallback and persist cleared thinking on re-import

refreshProviderModels' env sub-table fallback now throws the same
apiKey+oauth conflict the chat path rejects, instead of authenticating
with the fallback key and rewriting the provider to drop oauth.

persistRegistryImport writes the cleared thinking section through the
replacement payload, and drops the v1 fallback branch — registry imports
always persist through replaceConfigSections, so the removal phase no
longer needs per-id removeProvider RPCs.

* chore: consolidate provider credential changesets into one entry

* chore: trim changeset to the api_key_env entry

* fix: harden provider credential status and registry imports

* fix(oauth): expose browser-safe provider credential rules

* fix(node-sdk): replace serialized provider credentials

* fix(oauth): reject credential conflicts during refresh

* fix: harden custom registry re-imports

Reject reserved provider collisions and credential endpoint drift before mutation. Replace registry-owned sections atomically with compare-and-set guards, and carry the replacement contract through klient and node-sdk.

* refactor(registry): centralize custom registry import ownership

Route CLI and TUI imports through the engine via the typed SDK and Klient operation. Keep registry replacement policy inside the engine and preserve credential edits made while fetching the registry.

Cover the shared entry point with real configuration storage and memory/IPC transport tests.

* test: trim redundant api_key_env and registry-import coverage

* fix(cli): reuse the stored registry key on keyless re-import

Both first-party clients encoded "no key given" as an empty string, but
the engine's fallback chain (options.apiKey ?? registryKeyFromExisting)
only reuses the key parked in the provider's source blob when the option
is undefined. A keyless re-import of a private registry therefore went
out without an Authorization header and failed with 401 from the CLI
and the TUI dialog, while the kap-server REST route (which passes
undefined) reused the stored key fine.

Pass undefined from the CLI handler and the TUI import dialog instead
of normalizing to ''. The dialog's result type now marks apiKey
optional, matching the engine contract.

* test: pin CAS rejection and credential-conflict behavior

The coverage trim went past redundancy in three places, leaving the
PR's headline guards untested. Restore the compare-and-set rejection
path (guarded value changed on disk -> retry error, no write) and the
absent-section guard normalization in config.test.ts, the
apiKey+apiKeyEnv / apiKeyEnv+oauth conflict rejections at runtime
resolution (modelAuth) and at the refresh orchestrator (discovery,
with per-provider failure isolation), and the open-platform refresh
through api_key_env proving the resolved secret never lands in the
provider record. Also add the first direct unit tests for the shared
declaredProviderCredential / reconcileProviderCredentialUpdate
primitives.

* refactor(oauth): share reserved provider id rules between import and refresh

* Delete .changeset/registry-import-concurrent-credentials.md

Signed-off-by: 7Sageer <sag77r@hotmail.com>

* test: trim cross-layer duplicate registry and credential coverage

---------

Signed-off-by: 7Sageer <sag77r@hotmail.com>
2026-09-17 22:02:53 +08:00
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