Skip to content

feat(kap-server): broadcast agent.created/agent.disposed session events - #1997

Merged
sailist merged 2 commits into
MoonshotAI:mainfrom
sailist:feat/agent-lifecycle-events
Jul 21, 2026
Merged

feat(kap-server): broadcast agent.created/agent.disposed session events#1997
sailist merged 2 commits into
MoonshotAI:mainfrom
sailist:feat/agent-lifecycle-events

Conversation

@sailist

@sailist sailist commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below.

Problem

WebSocket clients of a session (web UI, inspectors, SDK consumers) have no way to learn an agent's lifecycle: they never hear when an agent is created or disposed, so late-joining or filtered subscribers cannot reconcile their agent roster with the server's. Likewise, transcript REST consumers cannot tell a disposed agent apart from a live one — a disposed agent keeps its history in the roster with no marker.

What changed

1. Session-grained agent lifecycle events

Problem: Agent creation/disposal was invisible on the wire; only per-agent stream events existed.

What was done:

  • The session event broadcaster now emits durable agent.created / agent.disposed events from the agent lifecycle callbacks. agent.created is enqueued ahead of the agent's own events, and disposal is only reported for agents the session actually attached (creation-failure ghosts stay silent).
  • Lifecycle events bypass per-subscription agent allowlists — they are session-grained facts, never per-agent stream content — and are journaled for replay.
  • Added the two event types to the v1 wire protocol and the zod schemas.

2. Disposal marker in the transcript roster

Problem: After disposal, an agent's transcript correctly stays readable, but roster consumers had no way to know the agent is gone.

What was done:

  • The transcript store now stamps disposedAt on the agent's roster descriptor at disposal (idempotent, first stamp wins; unknown agents gain no entry).
  • The wire schema exposes the optional disposedAt field so REST and fresh-reset consumers can render dead agents accordingly.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

sailist added 2 commits July 21, 2026 11:38
- emit durable agent.created / agent.disposed facts from the
  SessionEventBroadcaster lifecycle callbacks, ahead of the agent's own
  events, and let them bypass per-subscription agent allowlists
- add the agent.created / agent.disposed wire types and zod schemas
- stamp disposedAt on the transcript roster entry via
  TranscriptStore.markDisposed so REST consumers can tell a dead agent
  from a live one
@changeset-bot

changeset-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1c33b65

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 21, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@1c33b65
npx https://pkg.pr.new/@moonshot-ai/kimi-code@1c33b65

commit: 1c33b65

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c33b6541f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

agentDisposables.delete(agentId);
subscribedAgents.delete(agentId);
projectors.delete(agentId);
store.markDisposed(agentId, new Date().toISOString());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist disposedAt before dropping the live store

When a session is closed or the daemon restarts, TranscriptService.dropSession discards this live TranscriptStore and the REST transcript route falls back to readColdRoster from state.json; this line only stamps the in-memory store and no metadata update is written. In that cold-session path, agents that were disposed during the live run lose disposedAt, so transcript API consumers viewing history cannot distinguish them from non-disposed roster entries.

Useful? React with 👍 / 👎.

Comment on lines +543 to +549
export const agentCreatedEventSchema = z.object({
type: z.literal('agent.created'),
});

export const agentDisposedEventSchema = z.object({
type: z.literal('agent.disposed'),
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the shared protocol catalog in sync

Adding these events only to kap-server's private protocol catalog leaves @moonshot-ai/protocol stale; I verified rg "agent.created|agent.disposed" packages/protocol returns no matches, so packages/protocol/src/events.ts still omits these types from AgentEvent and sessionEventMessageSchema. Any SDK/client/test code validating or typing WS frames through the shared package will reject or fail to model events the server now emits.

Useful? React with 👍 / 👎.

@sailist
sailist merged commit 74da87a into MoonshotAI:main Jul 21, 2026
15 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant