MCPcopy
hub / github.com/coder/mux / deleteSideQuestionPlaceholder

Function deleteSideQuestionPlaceholder

src/node/services/sideQuestionService.ts:528–577  ·  view source on GitHub ↗

* Tear down a /btw placeholder whose stream failed or produced empty text * before the next candidate is tried. * * Closes the stream with an empty `stream-end` first so side-question * terminal-event bookkeeping (including the aggregator/store side-answer * terminal guards) unwinds while the p

(opts: {
  workspaceId: string;
  assistantMessageId: string;
  assistantHistorySequence: number;
  modelString: string;
  historyService: HistoryService;
  emitChatEvent: (workspaceId: string, message: WorkspaceChatMessage) => void;
})

Source from the content-addressed store, hash-verified

526 * chat.jsonl, which is the same outcome we used to ship anyway.
527 */
528async function deleteSideQuestionPlaceholder(opts: {
529 workspaceId: string;
530 assistantMessageId: string;
531 assistantHistorySequence: number;
532 modelString: string;
533 historyService: HistoryService;
534 emitChatEvent: (workspaceId: string, message: WorkspaceChatMessage) => void;
535}): Promise<void> {
536 const {
537 workspaceId,
538 assistantMessageId,
539 assistantHistorySequence,
540 modelString,
541 historyService,
542 emitChatEvent,
543 } = opts;
544
545 // Close the stream slot while the side-answer placeholder still exists.
546 // The aggregator and WorkspaceStore look up this message by id to check
547 // its muxMetadata before dispatching their side-answer-aware branches
548 // (e.g. WorkspaceStore.bufferedEventHandlers["stream-end"] skips
549 // collapsePinnedTodoOnStreamStop iff the terminal stream belongs to a
550 // side answer; the aggregator's handleStreamEnd skips main-agent
551 // onResponseComplete / lastCompletedStreamStats updates). Deleting the
552 // placeholder first would make those lookups fail, and the terminal
553 // event would fall through to the main-agent code paths — clobbering
554 // pinned-todo state and producing stale completion stats for a stream
555 // that should be invisible to main-agent lifecycle.
556 emitChatEvent(workspaceId, {
557 type: "stream-end",
558 workspaceId,
559 messageId: assistantMessageId,
560 metadata: { model: modelString, historySequence: assistantHistorySequence },
561 parts: [],
562 });
563
564 const deleteResult = await historyService.deleteMessage(workspaceId, assistantMessageId);
565 if (!deleteResult.success) {
566 log.warn("Side question: failed to delete placeholder for retry", {
567 workspaceId,
568 assistantMessageId,
569 error: deleteResult.error,
570 });
571 }
572
573 emitChatEvent(workspaceId, {
574 type: "delete",
575 historySequences: [assistantHistorySequence],
576 });
577}
578
579async function buildSideQuestionTranscript(
580 workspaceId: string,

Callers 1

askSideQuestionFunction · 0.85

Calls 1

deleteMessageMethod · 0.45

Tested by

no test coverage detected