MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / _project

Function _project

apps/kimi-web/src/api/daemon/agentEventProjector.ts:617–1237  ·  view source on GitHub ↗
(
    rawType: string,
    payload: unknown,
    sessionId: string,
    meta?: ProjectMeta,
  )

Source from the content-addressed store, hash-verified

615 }
616
617 function _project(
618 rawType: string,
619 payload: unknown,
620 sessionId: string,
621 meta?: ProjectMeta,
622 ): AppEvent[] {
623 const s = getOrCreate(sessionId);
624 // eslint-disable-next-line @typescript-eslint/no-explicit-any
625 const p = payload as any;
626 const out: AppEvent[] = [];
627
628 // Drop subagent-scoped transcript frames (see MAIN_AGENT_TRANSCRIPT_FRAMES).
629 // A subagent carries its own agentId; only the main agent's stream builds the
630 // visible transcript. Lifecycle frames (subagent.*, goal.*, background.*) are
631 // intentionally NOT in the set — they describe the subagent for the task view
632 // and must always be projected.
633 const frameAgentId: unknown = p?.agentId;
634 if (typeof frameAgentId === 'string' && frameAgentId !== MAIN_AGENT_ID) {
635 const isSideChannel = sideChannelAgents.has(frameAgentId);
636 // Side-channel agents (e.g. BTW side chat) stream text/thinking deltas and
637 // a turn boundary over the parent session channel. Route them to the web
638 // layer as agent-scoped events instead of dropping them or folding them
639 // into the parent transcript.
640 if (isSideChannel && (rawType === 'thinking.delta' || rawType === 'assistant.delta')) {
641 const deltaText: string = p?.delta ?? '';
642 if (!deltaText) return [];
643 return [
644 {
645 type: 'agentDelta' as const,
646 sessionId,
647 agentId: frameAgentId,
648 delta: { [rawType === 'thinking.delta' ? ('thinking' as const) : ('text' as const)]: deltaText },
649 },
650 ];
651 }
652 if (isSideChannel && rawType === 'turn.ended') {
653 return [
654 { type: 'agentTurnEnded' as const, sessionId, agentId: frameAgentId, reason: p?.reason },
655 ];
656 }
657 if (MAIN_AGENT_TRANSCRIPT_FRAMES.has(rawType)) {
658 return projectSubagentProgress(s, sessionId, frameAgentId, rawType, p ?? {}, sideChannelAgents);
659 }
660 }
661
662 switch (rawType) {
663 // -----------------------------------------------------------------------
664 case 'session.meta.updated': {
665 // The daemon auto-generates a title from the first prompt (and other
666 // clients can rename a session); it also reports the latest user prompt
667 // via patch.lastPrompt. It announces all of these via this event. We
668 // don't have the full AppSession here, so emit a lightweight
669 // sessionMetaUpdated that patches only the changed meta fields.
670 const title: string | undefined = p?.patch?.title ?? p?.title;
671 const lastPrompt: string | undefined = p?.patch?.lastPrompt;
672 const patch: { title?: string; lastPrompt?: string } = {};
673 if (typeof title === 'string' && title.length > 0) patch.title = title;
674 if (typeof lastPrompt === 'string') patch.lastPrompt = lastPrompt;

Callers 1

projectFunction · 0.85

Calls 15

getOrCreateFunction · 0.85
projectSubagentProgressFunction · 0.85
toAppPromptContentFunction · 0.85
startUserMessageFunction · 0.85
cloneMessageFunction · 0.85
ulidFunction · 0.85
startAssistantMessageFunction · 0.85
alignDeltaFunction · 0.85
appendAssistantDeltaFunction · 0.85
appendToolUseFunction · 0.85
getMsgByIdFunction · 0.85
toolProgressOutputFunction · 0.85

Tested by

no test coverage detected