






















@@ -690,12 +690,77 @@ function assertMatrixQaToolProgressMentionsInert(event: MatrixQaObservedEvent) {
690690}
691691}
692692693+function hasMatrixQaToolProgressPreviewLine(body: string | undefined) {
694+return Boolean(
695+body?.split(/\r?\n/).some((line) => /^\s*[-*•]\s+`?[^`\s][^`]*`?\s*$/u.test(line)),
696+);
697+}
698+699+function truncateMatrixQaToolProgressBody(body: string | undefined) {
700+if (!body) {
701+return "<none>";
702+}
703+return body.length <= 240 ? body : `${body.slice(0, 237)}...`;
704+}
705+706+function describeMatrixQaToolProgressCandidate(event: MatrixQaObservedEvent) {
707+const relation = event.relatesTo?.relType
708+ ? `${event.relatesTo.relType}:${event.relatesTo.eventId ?? "<none>"}`
709+ : "<none>";
710+return [
711+`${event.eventId} kind=${event.kind}`,
712+`relation=${relation}`,
713+`body=${JSON.stringify(truncateMatrixQaToolProgressBody(event.body))}`,
714+].join(" ");
715+}
716+717+function buildMatrixQaToolProgressTimeoutMessage(params: {
718+cause: unknown;
719+events: MatrixQaObservedEvent[];
720+expectedPreviewKind: MatrixQaObservedEvent["kind"];
721+previewEventId: string;
722+roomId: string;
723+startIndex: number;
724+sutUserId: string;
725+}) {
726+const candidates = params.events
727+.slice(params.startIndex)
728+.filter((event) => {
729+if (
730+event.roomId !== params.roomId ||
731+event.sender !== params.sutUserId ||
732+event.type !== "m.room.message" ||
733+event.kind !== params.expectedPreviewKind
734+) {
735+return false;
736+}
737+return (
738+event.eventId === params.previewEventId ||
739+event.relatesTo?.eventId === params.previewEventId ||
740+/\bWorking\b/i.test(event.body ?? "")
741+);
742+})
743+.slice(-8);
744+const candidateDetails =
745+candidates.length === 0
746+ ? ["observed preview candidates: <none>"]
747+ : ["observed preview candidates:", ...candidates.map(describeMatrixQaToolProgressCandidate)];
748+return [
749+params.cause instanceof Error
750+ ? params.cause.message
751+ : `Matrix tool progress wait failed: ${String(params.cause)}`,
752+`preview event: ${params.previewEventId}`,
753+ ...candidateDetails,
754+].join("\n");
755+}
756+693757async function runMatrixToolProgressScenario(
694758context: MatrixQaScenarioContext,
695759params: {
696760expectedPreviewKind: MatrixQaObservedEvent["kind"];
697761finalText: string;
698762label: string;
763+allowGenericProgressLine?: boolean;
699764mentionSafety?: boolean;
700765progressPattern: RegExp;
701766triggerBodyBuilder: (sutUserId: string, finalText: string) => string;
@@ -721,22 +786,39 @@ async function runMatrixToolProgressScenario(
721786since: startSince,
722787timeoutMs: context.timeoutMs,
723788});
724-const progress = params.progressPattern.test(preview.event.body ?? "")
789+const matchesExpectedProgress = (body: string | undefined) =>
790+params.progressPattern.test(body ?? "") ||
791+(params.allowGenericProgressLine === true && hasMatrixQaToolProgressPreviewLine(body));
792+const progress = matchesExpectedProgress(preview.event.body)
725793 ? preview
726- : await client.waitForRoomEvent({
727-observedEvents: context.observedEvents,
728-predicate: (event) =>
729-event.roomId === context.roomId &&
730-event.sender === context.sutUserId &&
731-event.kind === params.expectedPreviewKind &&
732-event.relatesTo?.relType === "m.replace" &&
733-event.relatesTo.eventId === preview.event.eventId &&
734-/\bWorking\b/i.test(event.body ?? "") &&
735-params.progressPattern.test(event.body ?? ""),
736-roomId: context.roomId,
737-since: preview.since,
738-timeoutMs: context.timeoutMs,
739-});
794+ : await client
795+.waitForRoomEvent({
796+observedEvents: context.observedEvents,
797+predicate: (event) =>
798+event.roomId === context.roomId &&
799+event.sender === context.sutUserId &&
800+event.kind === params.expectedPreviewKind &&
801+event.relatesTo?.relType === "m.replace" &&
802+event.relatesTo.eventId === preview.event.eventId &&
803+/\bWorking\b/i.test(event.body ?? "") &&
804+matchesExpectedProgress(event.body),
805+roomId: context.roomId,
806+since: preview.since,
807+timeoutMs: context.timeoutMs,
808+})
809+.catch((err: unknown) => {
810+throw new Error(
811+buildMatrixQaToolProgressTimeoutMessage({
812+cause: err,
813+events: context.observedEvents,
814+expectedPreviewKind: params.expectedPreviewKind,
815+previewEventId: preview.event.eventId,
816+roomId: context.roomId,
817+startIndex: startObservedIndex,
818+sutUserId: context.sutUserId,
819+}),
820+);
821+});
740822741823if (params.mentionSafety) {
742824assertMatrixQaToolProgressMentionsInert(progress.event);
@@ -804,6 +886,7 @@ export async function runToolProgressPreviewScenario(context: MatrixQaScenarioCo
804886expectedPreviewKind: "notice",
805887finalText: buildMatrixQaToken("MATRIX_QA_TOOL_PROGRESS"),
806888label: "tool progress preview",
889+allowGenericProgressLine: true,
807890progressPattern: /\btool:\s*read\b/i,
808891triggerBodyBuilder: buildMatrixToolProgressPrompt,
809892});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。