feat(kap-server): accept bundled skill activations on the prompt submission route - #2982
Conversation
…ission route The bundled-submission capability was only reachable through the in-process klient transports; the App talks to kap-server over /api/v1. The submit-prompt route now accepts an optional non-empty skills field and delegates to IAgentSkillService.promptWithSkills — same validation, events, and single bundled user message as the TUI path — skipping its own prompt-metadata update (the engine owns it there) and mapping skill.not_found / skill.type_unsupported onto the skills route's codes. To return the submission's queue identity, the engine's promptWithSkills now resolves with prompt_id / user_message_id / created_at / state (plus turn_id once launched), mirrored through the klient contract.
|
|
@codex review |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f76fa4a25b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Drop the user_message_id field (it is always the same identity as prompt_id — the route duplicates it) and narrow state to the running/queued/blocked vocabulary, mapped at the engine edge instead of exposing the internal seven-state PromptState on the wire.
|
Follow-up slimming in 6bce8b3 (minimal-footprint pass): dropped the redundant @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6bce8b31f2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ings - Validate bundled skill names and types before any media materialization or control override, so a rejected bundle leaves session state untouched (the engine still re-validates authoritatively). - Declare the 40415/40912 outcomes on the submit route so the generated API documentation includes them. - The klient output schema no longer tolerates a missing promptWithSkills result (a transport-level absence now raises instead of resolving undefined), and a failed launch surfaces as an error rather than a successful running result. - Add the changeset for the new public API field.
|
All five review threads addressed in 09deb90:
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09deb908b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…n and stabilize listed content - Skill preflight now runs on the session's catalog before the main agent is resolved, so a rejected bundle cannot mutate session metadata by registering main (regression test on a cold session without an agent). - The prompts list projection strips the stored skill blocks from a bundled prompt, so GET /prompts returns the same caller-only content as the submit response.
|
Both fixed in 90907f2:
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Coexist with the client-chosen prompt_id reservation and the session-media staging lifecycle: bundled submissions reject an explicit prompt_id (the engine assigns it), release staging once intake is known-complete (launched or blocked), and keep the shared session-media projection for listed content. Queued bundles release staging when their turn pops, which the result shape cannot observe — noted as a known limitation.
|
Merged current main (the merge commit documents the conflict decisions). Headline choices:
Verification: kap-server route suite 38 passed (both suites' tests kept), v2/klient/sdk suites pass, lint 0 errors. @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f3ef045275
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…an queued staging - The skills + prompt_id incompatibility rejection now runs at the initial bundled preflight, before the main agent is materialized or any override binds (previously a yolo override could bind before the 40001). - Queued bundles no longer skip staging cleanup forever: the discard is deferred to the bundle's prompt.completed / prompt.aborted lifecycle event, mirroring the plain path's launch-raced cleanup.
|
Both fixed in 4825665:
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 482566517a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A queued bundle steered into the active turn is consumed at steer time, but the engine publishes prompt.completed/aborted only for the parent — the deferred cleanup never fired and its subscription leaked. The prompt.steered event (matching promptIds) now counts as the child's intake-completion signal.
|
Fixed in eb4e6db: the steer path now counts as an intake-completion signal — a queued bundle steered into the active turn is consumed at steer time, and since @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eb4e6dbd14
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ect paths startNext materializes daemon file references into the session media store before a prompt's turn, but steer() and inject() enqueued the same references without that intake, leaving the staging upload as the only copy — any staging cleanup at steer time would delete the media the turn is about to consume. Both paths now run the same intake before the SteerStepRequest is created, so prompt.steered is a truthful intake-complete signal.
|
Addressed the root cause in e03a946 rather than delaying the cleanup: @codex review |
There was a problem hiding this comment.
💡 Codex Review
kimi-code/packages/agent-core-v2/src/agent/skill/skillService.ts
Lines 160 to 166 in e03a946
When a bundled request queues behind an active turn, this message content includes the rendered skill blocks, and AgentPromptService.publishQueued forwards that content unchanged; the kap-server broadcaster only applies media projection before sending prompt.queued. Consequently WebSocket clients still receive internal skill markdown while the submit response and GET /prompts expose only the caller's parts. Fresh evidence after the list-projection fix is this unchanged queued-event path; project the bundled prefix out of the event as well.
kimi-code/packages/agent-core-v2/src/agent/skill/skillService.ts
Lines 164 to 166 in e03a946
When a queued bundled prompt is steered, AgentPromptService.steer flattens its content into a new message with plain USER_PROMPT_ORIGIN, discarding the skillActivations metadata stored here. The durable turn.steer context therefore cannot be recognized by bundledSkillsFromOrigin or stripBundledSkillParts during replay, so the skill cards disappear and the rendered skill instructions are presented as user-authored text. Preserve or reconstruct the activation metadata when steering, including the multi-prompt case.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…teer time Prompt-intake materialization is best-effort: when it degrades, the daemon upload is the request-time resolver's fallback source. Discarding staging at prompt.steered could therefore delete the only readable copy before the parent's request ran. Cleanup is now uniformly event-driven — the bundle's own prompt.completed/aborted, or the steer parent's — so the upload always outlives the request it feeds.
|
Fixed in 0124751 by making cleanup uniformly settlement-driven: prompt intake is best-effort, and when it degrades the daemon upload is the resolver's fallback — so staging is now discarded only when the bundle's turn settles ( @codex review |
There was a problem hiding this comment.
💡 Codex Review
When a bundled prompt queues behind an active turn, storing the rendered blocks in its public prompt content makes publishQueued emit those internal instructions verbatim, while sessionEventBroadcaster.ts only converts their wire shape. If the bundle is steered, PromptSteered similarly carries the full content and coreEventMap.ts replaces the active transcript prompt with it. Fresh evidence after the caller-only list projection fix is these queued/steered event paths, which still expose content that the REST submit and list responses intentionally hide; preserve the caller-only boundary in lifecycle events as well.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A hook-blocked bundle completes synchronously inside the submission call, and an exceptionally fast launch can settle just as early — a post-call subscription misses the only settlement event and leaks both the staging blob and the listener. The tracker now subscribes before enqueueing, buffers lifecycle events, and settles against the returned prompt id (or its steer parent's).
|
Fixed in bbbaa60: steer records are now spliced out of the queue only AFTER the daemon-ref media intake completes (the file copy is where the active turn can finish), and if the turn is gone by enqueue time the records are restored to On the other thread (validation atomicity with overrides): the route's preflight and the engine's authoritative validation both read the live catalog, so a mid-request catalog refresh can in theory reopen the side-effect window. Rolling back is only partially possible at the edge ( @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bbbaa60faf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…media intake The daemon-ref copy yields, so settle/abort can consume selected records and the active turn can rotate meanwhile. Only records still pending are steered, and only into the turn that was active at entry; records that vanish from the queue are left to their own launch path, and a missing turn restores them to pending instead of splicing an unrelated tail prompt. The intake/queue-preservation contract is documented in the module header.
Re-applies the bundled-submission work onto the post-#3010 comment-free convention (headers stripped): contract result type, route preflight, settlement tracker, list projection, and the steer queue-revalidation, all without doc comments.
|
Threads addressed:
The validation-atomicity thread stays open pending a design decision (partial rollback vs moving overrides into the engine's atomic zone vs documenting best-effort); input welcome. @codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 246a6f21eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…edia truthful - The steered content is rebuilt from the records that are still pending after the media intake, so an aborted or concurrently consumed record's text is never injected (or injected twice) alongside the surviving handles. - The enqueue is wrapped so an activeTurnOnly rejection restores the records to pending (the loop throws instead of resolving a missing turn, which made the previous rollback unreachable). - The merged origin now carries the union of every record's bundled skillActivations, and prompt.steered publishes the caller-only content, so the skill instructions reach the model with their metadata intact while the event projection stops leaking internal skill markdown.
|
All three addressed in c5164a6:
@codex review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5164a66c6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a27a8575b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 95d3679997
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ece08d44e0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ix skill blocks in merged steer
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a0e27922fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7d7c911067
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Breezy! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Related Issue
Follow-up to #1736 (multi-skill prompts, landed as #2934 + #2935). The bundled-submission engine capability was only reachable through the in-process klient transports (the TUI path); the Kimi Code App talks to kap-server over
/api/v1, where no route exposed it.Problem
IAgentSkillService.promptWithSkills(bundled multi-skill prompt submissions) is not exposed on kap-server's production surface:POST /api/v1/sessions/{id}/promptsaccepts noskillsfield, and the skills route only activates one skill at a time. The App cannot submit a prompt with multiple skill activations.What changed
kap-server —
POST /api/v1/sessions/{sid}/promptsnow accepts an optional non-emptyskills: [{ name, args? }]field:IAgentSkillService.promptWithSkills— the same engine path the TUI uses: every skill validated up front (unknown name rejects the whole submission with zero side effects), oneskill.activatedevent per skill, and the prompt enqueues as a single bundled user message (rendered skill blocks first, then the caller's content; one turn, one undo unit).skill.not_found→40415,skill.type_unsupported→40912,request.invalid→40001alongside the existing codes.PromptItemshape (prompt_id/user_message_id/status/content/created_at).Contract chain — to return that queue identity, the engine's
promptWithSkillsnow resolves with aPromptWithSkillsResult(prompt_id/user_message_id/created_at/state, plusturn_idonce launched) instead of{ turn_id } | undefined. klient mirrors it (promptWithSkillsResultSchema+ facade type + parity assertion). The API is additive over the not-yet-published #2934 surface.Verification
tsc --noEmiton agent-core-v2, klient, kap-serverpnpm run lint: 0 errorsChecklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.