fix(task-chat): place a steered yielded reply in its own segment

A steering anchor can split a yielded turn. The authored reply now
renders in the last segment that contains an authored final, not
always in the last populated segment. The settled final-response
choice moves from a nested ternary into a small helper, and the
runner turn's suppressFinal prop is renamed awaitingContinuation,
since it no longer suppresses authored prose.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DottaandClaude Opus 5.5 committed 2026-11-05 13:52:09 -06:00
1 parent c134d72620
commit 4f300fbb3e
4 files changed
+117 -35

No files matched your search

+64
View File
@@ -3267,6 +3267,70 @@ describe("TaskChatThread runtime transcript selection", () => {
);
});
it("keeps a steered yielded turn's reply in the segment that wrote it", () => {
const runId = "steered-interview";
nativeTranscriptState.transcriptByRun.set(runId, [
assistantEntry("2026-08-25T18:00:02.000Z", "Here is the question card I just posted for you.", "final"),
assistantEntry("2026-08-25T18:00:10.000Z", "Folding in the steering note.", "progress"),
]);
renderThread({
comments: [
{
id: "steer",
companyId: "company-1",
issueId: "issue-1",
authorType: "user",
authorAgentId: null,
authorUserId: "user-1",
body: "Steering note from the user.",
presentation: null,
metadata: null,
runId: null,
consumedByRunId: runId,
steeredIntoRunId: runId,
conversationAnchorAt: new Date("2026-08-25T18:00:05.000Z"),
createdAt: new Date("2026-08-25T18:00:05.000Z"),
updatedAt: new Date("2026-08-25T18:00:05.000Z"),
},
],
onAdd: async () => {},
issueStatus: "in_progress",
interactions: [
{
...questionInteraction("steered-card", "Pick one", "2026-08-25T18:00:03.000Z"),
sourceRunId: runId,
} as IssueThreadInteraction,
],
linkedRuns: [
{
runId,
runtimeMode: "native",
status: "succeeded",
agentId: "agent-1",
agentName: "Runner",
adapterType: "paperclip_runner",
createdAt: "2026-08-25T18:00:00.000Z",
startedAt: "2026-08-25T18:00:00.000Z",
finishedAt: "2026-08-25T18:00:20.000Z",
resultJson: {
nativeResult: {
schema: "paperclip.run_result.v1",
reportedWorkDisposition: "yielded",
summary: "Waiting for Pick one.",
},
},
},
],
});
const text = container.textContent ?? "";
const replyAt = text.indexOf("Here is the question card I just posted");
const steerAt = text.indexOf("Steering note from the user.");
expect(replyAt).toBeGreaterThanOrEqual(0);
expect(steerAt).toBeGreaterThanOrEqual(0);
expect(replyAt).toBeLessThan(steerAt);
expect(text.split("Here is the question card I just posted")).toHaveLength(2);
});
it("keeps a yielded question turn out of the final-response slot", () => {
nativeTranscriptState.transcriptByRun.set("native-question", [
assistantEntry("2026-08-25T18:00:01.000Z", "Preparing the verification question.", "progress"),