MCPcopy Create free account
hub / github.com/github/copilot-sdk / diagnoseMatchFailure

Function diagnoseMatchFailure

test/harness/replayingCapiProxy.ts:527–586  ·  view source on GitHub ↗

* Produces a human-readable explanation of why no stored conversation matched * a given request. For each stored conversation it reports the first reason * matching failed, mirroring the logic in findAssistantIndexAfterPrefix.

(
  requestMessages: NormalizedMessage[],
  rawMessages: unknown[],
  storedData: NormalizedData | undefined,
)

Source from the content-addressed store, hash-verified

525 * matching failed, mirroring the logic in {@link findAssistantIndexAfterPrefix}.
526 */
527function diagnoseMatchFailure(
528 requestMessages: NormalizedMessage[],
529 rawMessages: unknown[],
530 storedData: NormalizedData | undefined,
531): string {
532 const lines: string[] = [];
533 lines.push(
534 `Request has ${requestMessages.length} normalized messages (${rawMessages.length} raw).`,
535 );
536
537 if (!storedData || storedData.conversations.length === 0) {
538 lines.push("No stored conversations to match against.");
539 return lines.join("\n");
540 }
541
542 for (let c = 0; c < storedData.conversations.length; c++) {
543 const saved = storedData.conversations[c].messages;
544
545 // Same check as findAssistantIndexAfterPrefix: request must be a strict prefix
546 if (requestMessages.length >= saved.length) {
547 lines.push(
548 `Conversation ${c} (${saved.length} messages): ` +
549 `skipped — request has ${requestMessages.length} messages, need fewer than ${saved.length}.`,
550 );
551 continue;
552 }
553
554 // Find the first message that doesn't match
555 let mismatchIndex = -1;
556 for (let i = 0; i < requestMessages.length; i++) {
557 if (JSON.stringify(requestMessages[i]) !== JSON.stringify(saved[i])) {
558 mismatchIndex = i;
559 break;
560 }
561 }
562
563 if (mismatchIndex >= 0) {
564 const raw =
565 mismatchIndex < rawMessages.length
566 ? JSON.stringify(rawMessages[mismatchIndex]).slice(0, 300)
567 : "(no raw message)";
568 lines.push(
569 `Conversation ${c} (${saved.length} messages): mismatch at message ${mismatchIndex}:`,
570 ` request: ${JSON.stringify(requestMessages[mismatchIndex]).slice(0, 200)}`,
571 ` saved: ${JSON.stringify(saved[mismatchIndex]).slice(0, 200)}`,
572 ` raw (pre-normalization): ${raw}`,
573 );
574 } else {
575 // Prefix matched, but the next saved message isn't an assistant turn
576 const nextRole =
577 saved[requestMessages.length]?.role ?? "(end of conversation)";
578 lines.push(
579 `Conversation ${c} (${saved.length} messages): ` +
580 `prefix matched, but next saved message is "${nextRole}" (need "assistant").`,
581 );
582 }
583 }
584

Callers 1

Calls 2

joinMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…