Commit graph

791 commits

Author SHA1 Message Date
Kaiyi
3baf993d55 fix(flow): close the flag-disable race across prompt submission
A flow activation enqueued behind an active turn could slip past the
flag-disable cleanup: the disable listener scans queuedFlowPrompts
before the post-await tracking ran, leaving the prompt to launch the
supervisor blueprint with no flow runtime. Both the bundled and the
single-activation paths now re-check the flag right after tracking the
handle and abort the prompt (discarding its pending activation and
carried definition) when the flag went off during the await.
2026-08-20 17:51:54 +08:00
Kaiyi
88f3d3192e fix(flow): record the finished reason in the final verdict fold
If the process stops after the durable final FlowVerdict but before
the separate FlowRunEnded lands, replay used to leave an inactive run
with no ended_reason, making a completed run indistinguishable from an
incomplete termination. The verdict fold now stamps endedReason
'finished' when the stage pointer passes the last stage; the later
FlowRunEnded replay stays idempotent over it.
2026-08-20 17:30:07 +08:00
Kaiyi
88b98197a6 fix(flow): enforce the reserved flow namespace at parse time, advertise shadowed flow tool names
An ordinary SKILL.md can no longer claim a name inside the flow:
namespace — the shared skill parser rejects it, so the projected-flow
predicate's name-and-type check is backed by real provenance; and the
Agent tool's profile descriptions filter a flow tool name only when it
resolves to the builtin registration, so a user/MCP tool shadowing one
of those names stays advertised.
2026-08-20 16:54:45 +08:00
Kaiyi
8f94ea58e9 fix(flow): watch the user flows directory, declare both FlowStart read paths, teach concurrent dispatch
The flows skill source now watches ~/.kimi-code/flows/ so user-level
definitions hot-reload like project ones (a missing directory degrades
to load-time scanning); FlowStart declares both candidate definition
paths as read accesses so path-aware hooks and the access conflict
check see the user-level fallback; and the supervisor contract teaches
concurrent worker dispatch for independent sub-goals within one stage
(background workers joined before a single per-branch-evidenced
verdict, limited to read-only or non-overlapping file scopes).
2026-08-20 16:43:48 +08:00
Kaiyi
34a9ecf925 fix(agent-core-v2): carry the agent id on flow status events after the session-scope refactor
Adapts the flow feature to main's session-scoped event contract: flow
state folds and the flow service stamp agentId on AgentStatusUpdated
(flow events fold only in the main agent's journal), the duplicated
scope-context parameter from the merge is dropped, and the flow service
tests publish agent-domain events through activated lifecycle contexts.
2026-08-20 16:43:37 +08:00
Kaiyi
89e28b1607 Merge origin/main into feat/flow-feature 2026-08-20 16:43:18 +08:00
Kaiyi
1199188295 fix(flow): source-check auxiliary flow guards and prefer any valid definition in FlowStart
The TodoList veto now applies only when both TodoList and the batched
FlowStart resolve to builtin registrations; worker-agent undo events no
longer publish a session flow status of null over the main agent's
active run; FlowStart mirrors discovery precedence by falling back to a
valid user-level definition when the project file is readable but
invalid; and spawnable profile descriptions no longer advertise the
supervisor-only flow tools that a worker can never receive.
2026-08-20 16:08:43 +08:00
Haozhe
a09d904140
refactor(agent-core-v2): migrate agent domains to model-as-container architecture (#3103) 2026-08-20 16:06:59 +08:00
Kaiyi
cd9c9cdce5 fix(flow): key flow lifecycle and slash naming on projected flows only
Three sites still treated a bare type: flow declaration as an
engine-managed flow: queued-prompt tracking (a flag-off toggle aborted
an unrelated skill's queued prompt), the steer multi-flow limit (two
ordinary flow-typed skills could not be steered together), and the
TUI/ACP slash builders (a flow-typed file skill took a bare /<name>
that could shadow builtins). All now use the shared isProjectedFlowSkill
predicate (type: flow AND the flow: catalog namespace), exported from
flowsSkillSource; the flow_invoked telemetry marker follows suit.
2026-08-20 15:43:21 +08:00
Kaiyi
1e2c58ddaf feat(flow): surface the stage-jump reason under every jump policy
The flow_jump_review display now attaches to every resolvable jump, not
only under the approval policy, so UIs can show the from → to move and
the model's stated reason even when no review happens; the execution
hook gates the human review on the run's jump policy instead of display
presence, and the tool output echoes the reason for the transcript.
2026-08-20 15:28:27 +08:00
Kaiyi
1c9331091d feat(flow): load user-level flow definitions from ~/.kimi-code/flows
Flows are now discovered from the user-level flows directory under the
kimi home in addition to the project's .kimi-code/flows/, mirroring how
user skills work; a project flow shadows a user flow with the same id.
The activation auto-start accepts the user-level definition path, and
FlowStart falls back to the user directory when the project file is
missing.
2026-08-20 15:27:18 +08:00
Haozhe
15da84606a
feat(kap-server): add workspace-grouped sessions view and lifecycle events (#3114)
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 / 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
Nix Build / Check flake.nix workspace sync (push) Waiting to run
GET /api/v2/sessions gains view=by_workspace: one request returns every
workspace with a matching session, each carrying its first group.page_size
sessions under the requested sort plus the workspace's full matching total,
with group-level page_token pagination (40922 on condition drift). Groups
key on the alias-canonical workspace id, so legacy split buckets of one
physical directory merge into a single group, matching the v1 alias
semantics. meta.has_prompt filters sessions by prompt presence (the v1
exclude_empty equivalent) in both views. The flat view and v1 routes stay
byte-compatible.

The global WS stream now fans out event.session.archived (live and cold
paths; payload carries the session id and workspace_id) and
event.workspace.created/updated/deleted, published by the core
IWorkspaceService on every mutation path including the implicit
createOrTouch on session creation.

kimi-inspect consumes the grouped projection as a single-column
workspace/session tree in the chat view; the session pane merges into the
right dock as the Session tab. The server API reference (en + zh) documents
the new parameters, the grouped response, and the new events.
2026-08-20 13:45:38 +08:00
liruifengv
f1208c8d72
feat(agent-core-v2): rework the title generation excerpts (#3109)
* feat(agent-core-v2): rework the title generation excerpts

- Rebalance the excerpt budgets toward the user's prompts (400 chars
  each) and trim the assistant segments (300) so titles follow the
  user's task instead of narrating the assistant's reply.
- Cap each prompt in the default user_prompts excerpt so one long
  paste no longer starves the remaining prompts.
- Compose the digest excerpt from the full conversation arc: every
  natural-language user prompt in the live window paired with its own
  turn's final assistant text, interleaved chronologically, with
  per-segment caps and a 3000-char total budget (middle turns elided).

* chore: scope the title changeset to agent-core-v2

* fix(agent-core-v2): dedupe digest prompts and elide whole turns

- Drop the redundant `| undefined` from the optional
  TitleDigestTurn.assistant per the monorepo optional-property
  convention.
- Deduplicate user messages by id when constructing digest turns, so a
  prompt already in the context and still active in the queue does not
  produce two turns.
- Elide the over-budget digest at whole-turn granularity, keeping each
  assistant line paired with its own user line.

* docs(agent-core-v2): describe the full-arc digest in the SessionTitleSource contract
2026-08-20 12:25:51 +08:00
Kimi Agent
d96b4a0149
fix: fail fast on provider-filtered empty responses (#3101)
* fix: fail fast on provider-filtered empty responses

An APIEmptyResponseError carrying finishReason 'filtered' (OpenAI
content_filter, Anthropic refusal) is deterministic: replaying the same
request re-triggers the provider safety filter. Both isRetryableGenerateError
implementations (kosong, agent-core-v2) treated every empty response as
retryable, so step retry replayed the doomed request the full 10 attempts
before the filter notice surfaced. Return non-retryable for filtered empty
responses in both engines; the error already carries the provider.filtered
code, so the turn fails immediately with the existing filter notice.

* fix: skip the compaction shrink-retry for filtered empty responses

Both full-compaction loops routed every APIEmptyResponseError into the
shrink-and-continue branch before isRetryableGenerateError was consulted,
so a filtered response was retried with shrinking input instead of failing
fast. Exclude finishReason 'filtered' from the shrink branch in both
engines; it now falls through to the retryability check and throws
immediately. Add end-to-end tests (real kosong generate over a filtered
think-only stream) asserting a single attempt with the history untouched.

---------

Co-authored-by: kimi-agent-bot <kimi-agent-bot@users.noreply.github.com>
2026-08-20 11:55:26 +08:00
liruifengv
3d7762003a
feat(kimi-code): support two OAuth login endpoints (#2862)
* feat(kimi-code): add China/International region selection for OAuth login

- Add region profiles (cn/overseas) and resolver in @moonshot-ai/kimi-code-oauth:
  env override → persisted login host → install-channel marker → default cn
- /login now offers Kimi Code (China) / Kimi Code (International); the CLI
  login entries (kimi login, kimi acp --login) accept --region cn|overseas
- Update/plugin/site/telemetry endpoints derive from the selected region;
  plugin trust list covers both .com and .ai hosts
- kap-server: POST /oauth/login accepts an optional region; new GET /oauth/region

* fix(oauth): keep an explicit default-slot login ahead of the install marker

A China login persists no oauthHost (the default credential slot carries
no host trace), so after switching back from International the resolver
fell through to a stale overseas install marker. Treat a persisted
default-slot oauth ref (key === oauth/kimi-code) as an explicit-cn signal
that outranks the marker; getRegion() on the v2 side mirrors it.

* fix(agent-core-v2): thread the default-slot key through capability region resolution

Capability installs resolved the region from the persisted oauthHost only,
so an explicit China login (which persists no host) lost to a stale
overseas install marker. Pass the oauth ref key through as well, matching
getRegion(). Also move the region contract notes into the auth.ts file
header per the package comment convention.

* fix(agent-core-v2): honor the region-marker opt-out for the telemetry endpoint

Hosts that set KIMI_CODE_REGION_MARKER=off (the desktop embedded server)
skip the install marker in getRegion(), but the default telemetry endpoint
still consulted it, so a stale overseas marker could split the reported
region from the telemetry destination.

* feat(cli): show region site domains in login platform selector

* chore: reword oauth login changesets

* fix: honor the region marker opt-out in the CLI and capability resolvers

* refactor: rename login region values to mainland-cn and global

* fix: keep the --region help text in English

* fix: simplify the --region help text to site domains

* feat: drop the suggested login platform order

* feat: split a browser-safe region profile table out of the region resolver

* Revert "feat: split a browser-safe region profile table out of the region resolver"

This reverts commit a037b1143e.

* fix: read the install marker from the bootstrapped home directory

* fix: resolve the server plugin marketplace from the active login region

* feat: expose the login region option through the klient auth facade

* fix: drop a comment from the v2 auth region test

* fix: keep scoped base-only logins on their environment for a bare login

* fix: invalidate the region cache on the provider-manager logout path

* fix: route client-config fetches through the active region profile

* fix: resolve the telemetry endpoint per flush so a login region switch applies in-process

* test: expect the telemetry endpoint resolver in the CLI init assertions

* fix: resolve the default telemetry endpoint from the bootstrapped home

* chore: reword the oauth login changeset around the two login methods

* chore: trim the oauth login changeset to the headline

* feat: let hosts override the region marker env through the server bootstrap env bag
2026-08-20 11:24:02 +08:00
Haozhe
ca87c58e62
fix(agent-core-v2): cap default subagent delegation at one level (#3012)
- give the builtin agent profile an explicit subagents allowlist (coder, explore, plan), restoring v1 semantics
- inherit the default profile's allowlist when a caller profile declares none, instead of leaving delegation unrestricted
- pass a lone "*" subagents field through as an explicit unrestricted marker
2026-08-20 09:53:11 +08:00
Haozhe
67fbcdf1ba
feat(agent-core-v2): guard Edit and Write against stale or unread files (#3096)
* feat(agent-core-v2): guard Edit and Write against stale or unread files

* feat(agent-core-v2): guard Edit and Write against stale or unread files
2026-08-19 22:55:55 +08:00
Haozhe
4ff06f17e3
fix(kap-server): serve real session usage in snapshot and persist per-turn context readings (#3094)
* fix(kap-server): serve real session usage in snapshot and persist per-turn context readings

* fix(kap-server): omit unknown session usage fields instead of reporting zero
2026-08-19 22:06:53 +08:00
Haozhe
056f02c2de
fix(agent-core-v2): record step.end for failed or interrupted steps in wire log (#3095)
Some checks are pending
CI / build (push) Waiting to run
CI / test-vscode-legacy (push) Waiting to run
CI / test-windows (push) Waiting to run
Release / Publish native release assets (push) Blocked by required conditions
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 / 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
2026-08-19 21:30:56 +08:00
Haozhe
eac9ea88e8
refactor(agent-core-v2): persist cron tasks as durable wire records (#3093)
* refactor(agent-core-v2): persist cron tasks as durable wire records

- write CronAdd/CronDelete/CronCursor as durable wire records and rebuild the cron task table from dispatcher replay
- migrate legacy per-workspace cron JSON files into the wire on first resume, then drop the file-based persistence service, its registrations, and the bootstrap cron scope
- derive the session cron view from the agent replayable cron state and remove the redundant session-level copy
- let session forks inherit cron tasks through the copied wire instead of duplicating task files

* fix(agent-core-v2): keep legacy cron tasks on cold forks and flush before cleanup

- inherit legacy cron task files into a full fork's wire so cold sessions forked before their first post-upgrade resume do not silently lose scheduled tasks
- flush the migrated wire records before deleting legacy files so a crash cannot lose both copies

* refactor(agent-core-v2): drop the legacy cron file migration

- stop reading legacy per-workspace cron JSON files entirely; pre-upgrade tasks simply stop applying instead of being migrated into the wire
- remove the legacy read path, the fork-time legacy inheritance, and the now-unused session context/document store injections
2026-08-19 21:26:57 +08:00
Haozhe
c843d3a7f9
refactor(kap-server): table-driven dispatch for multi-action routes (#3092)
* refactor(kap-server): table-driven dispatch for multi-action routes

- add a shared action-dispatch helper; sessions, prompts, plugins, questions, and modelCatalog collection routes declare action tables with module-level handlers
- add ISessionManager.status returning the session summary; the archive action checks it instead of resuming the session
- archive cold sessions through the persisted-metadata path shared with batch archive

* fix(agent-core-v2): read-your-writes for session index point gets

Overlay pending mirror summaries in getFromReadModel so a freshly recorded
summary (e.g. cold-session archive) is visible to GET immediately, matching
the existing pending overlays in list and cursor resolution.
2026-08-19 21:19:50 +08:00
qer
38a5a934ae
feat: project prompt attachments into the live transcript and clear the transcript goal on clear (#3088)
* feat(agent-core-v2): carry prompt attachments on turn.started so the live transcript projects them

* fix(transcript): clear the transcript goal when the goal is cleared

* fix(agent-core-v2): count a prompt media part as a transcript attachment only when its id matches its daemon file URL

* test(kap-server): expect the session-media file id on converted prompt parts
2026-08-19 18:38:21 +08:00
Kaiyi
862268e5aa fix(flow): scope the flow execution hooks to builtin registrations
Review round 46: the batching vetoes and gate/jump approval hook
resolved flow tools by name only, so a user/MCP tool shadowing a
flow-tool name inherited flow semantics (solo-response vetoes, gate
review). The hook now confirms the builtin registration in the tool
registry, mirroring the approval-policy fix.
2026-08-19 17:29:30 +08:00
Kaiyi
1724d90f7e fix(flow): metadata-failure rollback, guard only projected flow skills
Review round 45:

- A metadata persistence failure between bundle preparation and the
  activation dispatch now discards the stored activation payloads
  before rethrowing, so retries cannot accumulate entries in the
  unbounded activation-data map.
- The flow admission guards (flag, active/queued run, main-agent)
  apply only to projected flow skills (the flow: catalog namespace):
  an ordinary SKILL.md that declares type: flow is not engine-managed
  and activates like any other skill again.
2026-08-19 17:15:23 +08:00
7Sageer
2ea2ef62e4
feat(agent-core-v2): report the bound model alias in subagent_created telemetry (#3086) 2026-08-19 17:13:03 +08:00
Kaiyi
c03bdc0697 Merge origin/main into feat/flow-feature
The only conflict was the generated state manifest; regenerated on
top of main (now also carrying the flow jump policy and audit
records).
2026-08-19 17:11:04 +08:00
Kaiyi
67c879750c fix(flow): fast-fail known activation conflicts, honest reviewer shell wording
Review round 44:

- promptWithSkills rejects a deterministically-known flow conflict
  (active or queued run, disabled feature) before the prompt metadata
  update persists the doomed request as lastPrompt or a session
  title; the post-metadata check stays as the race-closing final
  admission next to the SkillActivated dispatch.
- The flow-reviewer profile description no longer claims read-only
  tools: shell access is verification-only by contract and every
  command still goes through the approval policy.
2026-08-19 16:57:03 +08:00
Haozhe
16499408d5
refactor(agent-core-v2): extract externalHooks into a scope-organized feature (#2805)
Move the external hook services out of app/externalHooksRunner,
session/externalHooks, and agent/externalHooks into
features/externalHooks, assembled as the ExternalHooksFeature unit:

- services live under per-scope subdirectories (app/, session/, agent/);
  shared pure helpers (types, hook matching/dispatch, process spawn,
  prompt result rendering) live under internal/
- the runner and the two observers are contributed through the Feature
  seams (ScopeUnits materialization); the hooks config section stays on
  the static import=register channel
- update the package entry leaf exports, the plugin domain imports, the
  kap-server events-zod import, and the affected tests; regenerate the
  state manifest
2026-08-19 16:52:51 +08:00
Kaiyi
99cf19b3ff Merge origin/main into feat/flow-feature
Conflicts were all generated or baseline-tracking artifacts: the wire
manifest is regenerated (now including flow_run.jumped), the tool
snapshot tests are re-recorded, and the compaction token baselines are
re-shifted on top of main's new values (+11 for the FlowJump tool).
2026-08-19 16:50:37 +08:00
Haozhe
cb8a7e5f81
feat(kap-server): expose engine feature list on /api/v1/meta (#3085) 2026-08-19 16:32:45 +08:00
7Sageer
571bcc2f75
fix(agent-core-v2): register needs-auth MCP authenticate tool regardless of settle timing (#3083) 2026-08-19 16:32:26 +08:00
Kaiyi
016c28d1a2 fix(flow): reservation-aware FlowStart, source-checked auto-approval, inject failure cleanup
Review round 43:

- FlowStart reports a queued activation reservation with a dedicated
  message instead of racing it: the queued prompt keeps its start.
- The default-approve policy resolves the flow tools' registry source
  and auto-approves them only when they are the builtin registrations,
  so a user/MCP tool shadowing a flow tool name (possible while the
  flag is off) no longer inherits the approval bypass.
- A failed prompt delivery during a flow activation (inject/enqueue
  rejection) now releases the pending reservation and stored
  definition on the error path.
- The projected blueprint no longer promises that every UI shows flow
  progress (UIs with flow support do).
2026-08-19 15:33:17 +08:00
Kaiyi
9bafcf8b53 fix(flow): map activation conflicts to validation errors, export the FlowJump contract
Review round 42:

- The skills route maps REQUEST_INVALID activation failures (active
  or queued run, disabled feature, non-main agent) to the
  VALIDATION_FAILED envelope instead of rethrowing them as a 500 —
  these are client conflicts, not server failures.
- The package entry point re-exports the FlowJump input schema and
  tool contract alongside the other flow tools.
2026-08-19 15:14:00 +08:00
qer
be8e017597
fix(agent-core-v2): emit subagent.spawned after task registration (#3005)
* fix(agent-core-v2): emit subagent.spawned after task registration

The spawned signal previously fired at launch, before the run's task
registration, so clients learned the agent id with no task id to bind
cancel/status actions to; a failed registration also left a spawned row
behind for a run that never registered. Emit it only after registerTask
succeeds and carry the task id on the event.

* fix(agent-core-v2): keep spawned ahead of started for Agent-tool runs

The TUI drops subagent.started until spawned has established the row,
and a failed registration must not leave a started row behind with no
terminal event. Defer the mirrored started dispatch so the Agent tool
can emit it itself after registration and spawned.

* fix(agent-core-v2): void the deferred started dispatch

* fix(kap-server): key Agent-tool transcript rows by the registered task id

Transcript-protocol clients suppress the raw task.*/subagent.* session
events, so they only saw a subagent row keyed by agent id that cannot
address /tasks/{id}, plus a second row once task.started landed. Key the
spawned row by the task id it now carries, fold task.started and the
subagent lifecycle back into it, and keep the agent-id path for spawns
without a registration (swarm/session-init/tower). Statement-level
ordering notes move to the file headers per package convention.

* test(agent-core-v2): split the spawned/started ordering contract into its own test

* fix(kap-server): keep subagent result details across task termination and drop stale task mappings on taskless respawns

* fix(kap-server): recover the agent-to-task association from a backfilled task.started

* fix(kap-server): seed pre-attach Agent task mappings on the transcript binding

* fix(kap-server): seed the full in-flight task row on transcript bind, not only its id

* docs(agent-core-v2): name the state-domain event dispatcher in the Agent tool header

* style(kap-server): drop comments in transcript services per the no-comments lint rule
2026-08-19 14:58:55 +08:00
Kaiyi
f785e127c7 fix(flow): reject and cancel flow activations across a flag disable
Review round 41:

- The activation guard now treats a disabled flow flag as a rejection
  (the tools and injector are gone), instead of as permission to
  continue — closing the window where a request prepared from the old
  catalog published its activation after the feature was retracted.
- The skill service tracks queued flow prompts (bundled and single)
  and aborts them when the flag turns off, so an accepted supervisor
  blueprint no longer launches into a session whose flow machinery
  has been withdrawn; the abort flows through the existing completion
  cleanup, releasing the reservation and stored definition.
2026-08-19 14:57:37 +08:00
Kaiyi
946b8ec03d feat(flow): FlowJump — stage jumps with per-flow approval policy
The supervisor can now move an active run to another stage: backward
to redo work whose conclusion was invalidated, forward to skip stages
that do not apply to the task. The definition's frontmatter governs
it via jumps: approval (default — every jump goes through a user
review), free (unsupervised), or disabled (strictly linear, the old
behavior).

- New FlowJump tool (to + reason, both required): validated like the
  other flow tools, solo-response only, supervisor-only, flag-gated.
- A durable FlowJumped event moves the undoable stage pointer and
  appends a kind: 'jump' record (from/to/reason/decidedBy) to the
  retained audit trail; the run epoch bumps on every jump so verdicts
  and reminders prepared before it are void, and a revisited stage
  re-discloses its reminder.
- The approval flow reuses the gate-review machinery: a new
  flow_jump_review display (protocol + kap-server + engine schemas),
  epoch-bound reviews, observed-rejection provenance, and no
  session-wide approval anywhere (TUI choices, ACP options, VS Code
  downgrade all treat jumps like gates).
- GET /sessions/{id}/flow exposes run.jump_policy and the audit
  records as a verdict/jump union.
- The supervisor contract's Order rule now teaches FlowJump instead
  of mandating abort-and-restart.
2026-08-19 14:48:23 +08:00
Luyu Cheng
01eeacb59b
feat(kimi-code): specialize the WaitFor tool's transcript display (#3066)
* feat(kimi-code): specialize the WaitFor tool's transcript display

* feat(agent-core-v2): emit status progress while WaitFor is pending

* fix(kimi-code): route WaitFor dimming through the TUI theme

* feat(kimi-code): support replaceable status updates in tool progress

* fix(kimi-code): forward status progress to subagent activity surfaces

* fix(agent-core-v2): drop the redundant undefined from ToolUpdate.replace

* fix(kimi-code): honor replace semantics in the subagent live status path

* test(agent-core-v2): drive the WaitFor progress test through a manual tick

* fix(kap-server): mirror ToolUpdate.replace in the ws event schema

* refactor(agent-core-v2): expose the WaitFor progress scheduler as a public seam

* fix(kimi-code): pass child wait statuses without the trailing newline

* feat(agent-core-v2): tick the WaitFor progress status every second

* feat(agent-core-v2): format WaitFor progress durations as 1m 15s

* feat(agent-core-v2): omit zero seconds and minutes in WaitFor durations
2026-08-19 14:15:38 +08:00
Kaiyi
83a9d00912 fix(flow): release reservations for blocked prompts and on flag disable
Review round 40:

- The completion cleanup also treats the blocked terminal state as a
  release: a hook-blocked bundled flow prompt never reaches a step
  head, so its reservation must not outlive it (the blueprint's
  FlowStart recovery covers a later retry).
- Turning the flow flag off clears queued reservations, since the
  retracted step-head injector can no longer consume them; re-enabling
  no longer inherits a dead pending activation that rejects every new
  flow.
2026-08-19 14:13:32 +08:00
7Sageer
c908a39e32
refactor(agent-core-v2): unify the loop-event fold into one core with two materializations (#3018)
* refactor(agent-core-v2): unify the loop-event fold into one core with two materializations

The loop-event stream was reduced by two hand-mirrored state machines:
loopEventFold.ts for the live/replayed context and contextTranscript.ts
for the full transcript behind the messages endpoints, kept in sync by
comments alone and already drifted (transcript dropped tool-result note
metadata and never closed a dangling tool exchange at step.end).

createLoopEventFold now owns the shared state machine once (settle,
pending tool exchanges, deferred appends, vacuous tracking) and both
views plug in as LoopEventFoldSink materializations. New parity tests
pin the foldedLength === live length invariant the endpoints splice on.

* fix(agent-core-v2): drop every removed prompt's injections on multi-turn transcript undo

The transcript undo only walked prompt-owned injections off the oldest
counted anchor, so with count > 1 an injection owned by a newer removed
prompt (e.g. an image-compression caption) survived the display undo
while the live context removed it. Collect every counted anchor's id
during the walk and sweep their owned injections afterwards, keeping
the transcript's 'prompt-owned ones leave with their prompt' contract
for every count and matching the live view.

* refactor(agent-core-v2): drop module headers from the context fold modules

The comment-free zone lint only allows JSDoc on exported symbols.

* fix(agent-core-v2): recover fold state after rehydration

* fix(agent-core-v2): scope undo injections to their prompt

* fix(agent-core-v2): settle open transcript frames when compaction lands mid-fold

An overflow-triggered compaction arrives with the failed attempt's
frame still open. The transcript appended the summary marker and reset
the fold but left the frame, so a vacuous partial stayed in the entries
while the live context dropped it, and a pending tool exchange lost its
interrupted result. Settle through the shared fold core at the marker
instead: close pending tool calls, drop or seal the open frame, then
append the summary. recoverFoldedLength recomputes the absolute count
right after either way.

* fix(agent-core-v2): keep legacy compaction recovery on the pre-settlement count

A legacy context.apply_compaction record (compactedCount without
keptUserMessageCount) recovers foldedLength as 1 + (foldedLength -
compactedCount), and the live legacy tail shape keeps the unsettled
open frame inside history.slice(compactedCount). Settling the fold for
those records shifted foldedLength by the settlement delta before the
recovery read it, leaving the transcript count one off the live
context. Gate the settle to modern records; legacy records keep the
previous freeze-and-reset behavior.
2026-08-19 14:09:22 +08:00
Kaiyi
a35b1b7ce7 fix(flow): release aborted reservations, close the pre-publication race, protect feature profiles
Review round 39:

- A queued flow prompt that is aborted (or fails) before reaching a
  step head now releases its reservation: the prompt handle's
  completion discards the pending activation and its stored
  definition, so an orphaned entry can no longer block every later
  flow activation. The single-activation busy path does the same.
- The active/pending admission check moved after the awaited metadata
  update, directly adjacent to the synchronous SkillActivated
  dispatch, so two concurrent promptWithSkills requests can no longer
  both pass the check before either publishes its activation.
- Bundle preparation rolls back stored activation data when a later
  skill in the bundle fails to prepare.
- The profile catalog's builtin protection now covers every
  builtin-priority contribution (features included), so a workspace
  file profile named flow-reviewer cannot silently replace the flow
  reviewer without override: true.
2026-08-19 13:57:40 +08:00
Kaiyi
df294b0b4a fix(flow): reject queued-concurrent activations, downgrade VS Code gate session approvals, unbounded activation data
Review round 38:

- The activation entry points also reject a flow activation while one
  is already queued (pending, not yet consumed at a step head), so two
  flow prompts admitted behind a running turn no longer deliver a
  second blueprint whose run never starts.
- The VS Code webview downgrades approve_for_session on a flow gate
  to a one-shot approval — the engine re-asks every human gate, so
  recording a session rule would promise what is never honored
  (mirrors the ACP option change).
- The activation-data store no longer caps entries (a concurrent
  burst could evict a definition before its SkillActivated consumed
  it); failure paths in both entry points now discard what they
  stored.
2026-08-19 13:35:06 +08:00
Kaiyi
afe78a26d4 fix(flow): reject a flow activation while another run is active
Review round 37: activating /flow:<id> during an active run delivered
the new blueprint whose recovery instruction then collides with the
running flow (FlowStart reports the active run). Both activation
entry points now reject the request up front with a clear message to
finish or abort the current run first.
2026-08-19 13:18:52 +08:00
Kaiyi
912ee18183 fix(flow): reject multi-flow steers, drop session-wide approval from ACP flow gates
Review round 36:

- Steering rejects a selection that would merge more than one flow
  activation into a single step: the merged prompt would carry two
  supervisor blueprints whose recovery instructions conflict once the
  first run starts.
- The ACP permission prompt for a flow_gate_review offers only Pass
  gate / Reject — a flow gate is a per-stage decision, so the
  allow-always option is deliberately absent, and a stray
  approve_always id degrades to a one-shot approval instead of
  installing a session rule the engine would never honor. The Reject
  option's label rides selectedLabel, satisfying the observed-decision
  provenance rule.
2026-08-19 13:04:49 +08:00
Kaiyi
bf0731cc27 fix(flow): flag-aware todo suppression, conditional start instruction, undo epoch while disabled
Review round 35:

- The stale-todo suppression checks the flow flag alongside the run
  state, so a retained run left behind by disabling the feature no
  longer silences todo reminders it can no longer justify.
- The supervisor contract's Start step now describes the automatic
  engine start as the normal path and reserves FlowStart for the
  no-reminder recovery, matching the projected prompt instead of
  contradicting it.
- Conversation undo advances the run epoch even while the flag is
  off, so re-enabling the feature cannot dedup a restored stage
  against a stale pre-undo disclosure.
2026-08-19 12:44:02 +08:00
7Sageer
f13f379044
fix(agent-core-v2): stop advertising unavailable ReadMediaFile to non-multimodal models (#3046)
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 / Publish native release assets (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
* fix(agent-core-v2): stop advertising unavailable ReadMediaFile to non-multimodal models

* fix(agent-core-v2): honor the effective tool policy before advertising ReadMediaFile

* fix(agent-core-v2): keep media-unavailable guidance reason-neutral and within the active toolset

* fix(agent-core-v2): recommend MCP fallbacks only when an active MCP tool exists

* fix(agent-core-v2): stop naming other tools in Read descriptions and errors

* fix(agent-core-v2): drop tool roster from plan agent prompt
2026-08-19 12:43:50 +08:00
Kaiyi
53d9bdd0b4 fix(flow): suppress the stale-todo reminder while a flow run is active
Review round 34: the session todo service injected its ten-turn
stale reminder during flow runs (it only checked tool-policy
activity), telling the model to use a tool whose execution the flow
hook then vetoes. The reminder now checks the agent's flow run first,
matching the veto.
2026-08-19 12:27:07 +08:00
Kaiyi
d5ee53d61a fix(flow): namespace projected skills, unbounded queued activations, steer-merge guard
Review round 33:

- Projected flow skills now live under their own catalog namespace
  (flow:<id>), so a flow can never shadow an ordinary skill with the
  same id; the TUI and ACP slash builders pass the name through
  instead of prefixing, which also fixes queued-prompt recall text
  losing the /flow: prefix.
- The pending-activation map no longer caps at eight entries: a
  deep queue of admitted flow prompts keeps every activation, since a
  silent eviction would deliver a blueprint whose run never starts
  (leftover entries from aborted prompts are small and bounded by
  user action).
- A steered prompt that merged several flow activations starts only
  the first and clears the rest, so a later reconciliation cannot
  surprise-start the second flow against the same merged prompt.
- The live flag-flip status publisher runs only on the main agent, so
  a worker's null frame can no longer race the session's flow
  indicator.
2026-08-19 12:03:34 +08:00
Kaiyi
fa130d376e feat(flow): drop the generic /flow builtin entry
The bare /flow skill was a dead end in both directions: with no flow
definitions it could only report an empty directory (it carried no
authoring guide), and with definitions present it bypassed every
guarantee of the projected /flow:<id> path (activation-carried
definition, automatic start, provenance checks) in favor of a manual
read-and-FlowStart route. Discovery is already served by the slash
menu listing each projected flow with its description. The supervisor
contract stays as the shared body of the projected skills; the
flag-flip reload of builtin visibility stays as a general mechanism.
2026-08-19 11:41:38 +08:00
Kai
6595a6989a
fix(kosong): emit null content for assistant messages with no text in chat completions (#3052)
Assistant messages carrying only tool calls were serialized without a
content key (JSON.stringify drops undefined), which strict
chat-completions validators such as LiteLLM reject with a 422,
permanently poisoning the session. Emit content: null for such messages
in both the kosong and agent-core-v2 converters, matching the shape
OpenAI responses use alongside tool_calls. The think-only empty-string
behavior in agent-core-v2 and both Kimi providers' deliberate content
omission are unchanged.
2026-08-19 11:39:32 +08:00
Luyu Cheng
8440801de4
feat(agent-core-v2): add the WaitFor tool for waiting on background tasks (#3060)
* feat(agent-core-v2): add the WaitFor tool for waiting on background tasks

* fix(agent-core-v2): mark WaitFor deliveries only after formatting succeeds

* fix(agent-core-v2): cancel losing waits once the WaitFor race resolves

* test(node-sdk): project WaitFor out of the v1-v2 resume parity roster

* fix(agent-core-v2): gate WaitFor goal guidance behind the wait_for flag

* fix(agent-core-v2): gate WaitFor goal guidance on actual tool availability

* fix(agent-core-v2): enforce the wait_for flag at WaitFor execution time

* fix(agent-core-v2): consult the live tool policy in the WaitFor availability check
2026-08-19 11:26:59 +08:00