2329 lines · 68.3 KB · TypeScript
RawDownload
import {  classifyTaskAgentKind,  EventId,  MessageId,  ThreadId,  TurnId,  type OrchestrationThreadActivity,} from "@t3tools/contracts";import { describe, expect, it } from "vite-plus/test"; import {  deriveActiveWorkStartedAt,  deriveActivePlanState,  deriveTurnPlans,  derivePendingApprovals,  derivePendingUserInputs,  deriveTimelineEntries,  deriveWorkLogEntries,  findLatestProposedPlan,  hasActionableProposedPlan,  isLatestTurnSettled,  workEntryIndicatesToolFailure,  workEntryIndicatesToolNeutralStatus,  workEntryIndicatesToolSuccess,} from "./session-logic"; let nextActivityId = 0; function makeActivity(overrides: {  id?: string;  createdAt?: string;  kind?: string;  summary?: string;  tone?: OrchestrationThreadActivity["tone"];  payload?: Record<string, unknown>;  turnId?: string;  sequence?: number;}): OrchestrationThreadActivity {  // Fixtures model post-ingestion rows: ingestion stamps agentKind on every  // task.* payload. Pass an explicit agentKind to model legacy rows.  const rawPayload = overrides.payload ?? {};  const payload =    overrides.kind?.startsWith("task.") && !("agentKind" in rawPayload)      ? {          ...rawPayload,          agentKind: classifyTaskAgentKind({            taskType: typeof rawPayload.taskType === "string" ? rawPayload.taskType : undefined,            agentId: typeof rawPayload.agentId === "string" ? rawPayload.agentId : undefined,          }),        }      : rawPayload;  return {    id: EventId.make(overrides.id ?? `activity-${nextActivityId++}`),    createdAt: overrides.createdAt ?? "2026-02-23T00:00:00.000Z",    kind: overrides.kind ?? "tool.started",    summary: overrides.summary ?? "Tool call",    tone: overrides.tone ?? "tool",    payload,    turnId: overrides.turnId ? TurnId.make(overrides.turnId) : null,    ...(overrides.sequence !== undefined ? { sequence: overrides.sequence } : {}),  };} describe("derivePendingApprovals", () => {  it("tracks open approvals and removes resolved ones", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "approval-open",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "approval.requested",        summary: "Command approval requested",        tone: "approval",        payload: {          requestId: "req-1",          requestKind: "command",          detail: "bun run lint",        },      }),      makeActivity({        id: "approval-close",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "approval.resolved",        summary: "Approval resolved",        tone: "info",        payload: { requestId: "req-2" },      }),      makeActivity({        id: "approval-closed-request",        createdAt: "2026-02-23T00:00:01.500Z",        kind: "approval.requested",        summary: "File-change approval requested",        tone: "approval",        payload: { requestId: "req-2", requestKind: "file-change" },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([      {        requestId: "req-1",        requestKind: "command",        createdAt: "2026-02-23T00:00:01.000Z",        detail: "bun run lint",      },    ]);  });   it("maps canonical requestType payloads into pending approvals", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "approval-open-request-type",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "approval.requested",        summary: "Command approval requested",        tone: "approval",        payload: {          requestId: "req-request-type",          requestType: "command_execution_approval",          detail: "pwd",        },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([      {        requestId: "req-request-type",        requestKind: "command",        createdAt: "2026-02-23T00:00:01.000Z",        detail: "pwd",      },    ]);  });   it("keeps app access approvals and persistence choices from remote activities", () => {    const options = [      { decision: "decline", label: "Decline" },      { decision: "acceptAlways", label: "Always allow Safari" },      { decision: "accept", label: "Approve" },    ];    const activities = [      makeActivity({        kind: "approval.requested",        summary: "App access approval requested",        tone: "approval",        payload: {          requestId: "req-safari",          requestType: "mcp_elicitation_approval",          detail: "Allow ChatGPT to use Safari?",          appName: "Safari",          options,        },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([      {        requestId: "req-safari",        requestKind: "mcp-elicitation",        createdAt: "2026-02-23T00:00:00.000Z",        detail: "Allow ChatGPT to use Safari?",        appName: "Safari",        options,      },    ]);  });   it("derives dynamic tool requests as actionable generic approvals", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "approval-open-dynamic-tool",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "approval.requested",        summary: "Approval requested",        tone: "approval",        payload: {          requestId: "req-dynamic-tool",          requestType: "dynamic_tool_call",          detail: "Search the web",        },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([      {        requestId: "req-dynamic-tool",        requestKind: "command",        createdAt: "2026-02-23T00:00:01.000Z",        detail: "Search the web",      },    ]);  });   it("clears stale pending approvals when provider reports unknown pending request", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "approval-open-stale",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "approval.requested",        summary: "Command approval requested",        tone: "approval",        payload: {          requestId: "req-stale-1",          requestKind: "command",        },      }),      makeActivity({        id: "approval-failed-stale",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "provider.approval.respond.failed",        summary: "Provider approval response failed",        tone: "error",        payload: {          requestId: "req-stale-1",          detail: "Unknown pending permission request: req-stale-1",        },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([]);  });   it("clears stale pending approvals when the backend marks them stale after restart", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "approval-open-stale-restart",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "approval.requested",        summary: "Command approval requested",        tone: "approval",        payload: {          requestId: "req-stale-restart-1",          requestKind: "command",        },      }),      makeActivity({        id: "approval-failed-stale-restart",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "provider.approval.respond.failed",        summary: "Provider approval response failed",        tone: "error",        payload: {          requestId: "req-stale-restart-1",          detail:            "Stale pending approval request: req-stale-restart-1. Provider callback state does not survive app restarts or recovered sessions. Restart the turn to continue.",        },      }),    ];     expect(derivePendingApprovals(activities)).toEqual([]);  });}); describe("derivePendingUserInputs", () => {  it("tracks open structured prompts and removes resolved ones", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "user-input-open",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "user-input.requested",        summary: "User input requested",        tone: "info",        payload: {          requestId: "req-user-input-1",          questions: [            {              id: "sandbox_mode",              header: "Sandbox",              question: "Which mode should be used?",              options: [                {                  label: "workspace-write",                  description: "Allow workspace writes only",                },              ],              multiSelect: true,            },          ],        },      }),      makeActivity({        id: "user-input-resolved",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "user-input.resolved",        summary: "User input submitted",        tone: "info",        payload: {          requestId: "req-user-input-2",          answers: {            sandbox_mode: "workspace-write",          },        },      }),      makeActivity({        id: "user-input-open-2",        createdAt: "2026-02-23T00:00:01.500Z",        kind: "user-input.requested",        summary: "User input requested",        tone: "info",        payload: {          requestId: "req-user-input-2",          questions: [            {              id: "approval",              header: "Approval",              question: "Continue?",              options: [                {                  label: "yes",                  description: "Continue execution",                },              ],              multiSelect: false,            },          ],        },      }),    ];     expect(derivePendingUserInputs(activities)).toEqual([      {        requestId: "req-user-input-1",        createdAt: "2026-02-23T00:00:01.000Z",        questions: [          {            id: "sandbox_mode",            header: "Sandbox",            question: "Which mode should be used?",            options: [              {                label: "workspace-write",                description: "Allow workspace writes only",              },            ],            multiSelect: true,          },        ],      },    ]);  });   it("clears stale pending user-input prompts when the provider reports an orphaned request", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "user-input-open-stale",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "user-input.requested",        summary: "User input requested",        tone: "info",        payload: {          requestId: "req-user-input-stale-1",          questions: [            {              id: "sandbox_mode",              header: "Sandbox",              question: "Which mode should be used?",              options: [                {                  label: "workspace-write",                  description: "Allow workspace writes only",                },              ],              multiSelect: false,            },          ],        },      }),      makeActivity({        id: "user-input-failed-stale",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "provider.user-input.respond.failed",        summary: "Provider user input response failed",        tone: "error",        payload: {          requestId: "req-user-input-stale-1",          detail:            "Provider adapter request failed (codex) for item/tool/requestUserInput: Unknown pending Codex user input request: req-user-input-stale-1",        },      }),    ];     expect(derivePendingUserInputs(activities)).toEqual([]);  });}); describe("deriveActivePlanState", () => {  it("returns the latest plan update for the active turn", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "plan-old",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: {          explanation: "Initial plan",          plan: [{ step: "Inspect code", status: "pending" }],        },      }),      makeActivity({        id: "plan-latest",        createdAt: "2026-02-23T00:00:02.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: {          explanation: "Refined plan",          plan: [{ step: "Implement Codex user input", status: "inProgress" }],        },      }),    ];     expect(deriveActivePlanState(activities, TurnId.make("turn-1"))).toEqual({      createdAt: "2026-02-23T00:00:02.000Z",      turnId: "turn-1",      explanation: "Refined plan",      steps: [{ step: "Implement Codex user input", status: "inProgress" }],    });  });   it("falls back to the most recent plan from a previous turn", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "plan-from-turn-1",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: {          plan: [{ step: "Write tests", status: "completed" }],        },      }),    ];     // Current turn is turn-2, which has no plan activity — should fall back to turn-1's plan    const result = deriveActivePlanState(activities, TurnId.make("turn-2"));    expect(result).toEqual({      createdAt: "2026-02-23T00:00:01.000Z",      turnId: "turn-1",      steps: [{ step: "Write tests", status: "completed" }],    });  });   it("starts timing again after a plan is cleared and recreated", () => {    const activities: OrchestrationThreadActivity[] = [      makeActivity({        id: "plan-old-start",        createdAt: "2026-02-23T00:00:01.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: { plan: [{ step: "Check", status: "inProgress" }] },      }),      makeActivity({        id: "plan-old-complete",        createdAt: "2026-02-23T00:00:05.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: { plan: [{ step: "Check", status: "completed" }] },      }),      makeActivity({        id: "plan-clear",        createdAt: "2026-02-23T00:00:06.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: { plan: [] },      }),      makeActivity({        id: "plan-new-start",        createdAt: "2026-02-23T00:00:10.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: { plan: [{ step: "Check", status: "inProgress" }] },      }),      makeActivity({        id: "plan-new-complete",        createdAt: "2026-02-23T00:00:13.000Z",        kind: "turn.plan.updated",        summary: "Plan updated",        tone: "info",        turnId: "turn-1",        payload: { plan: [{ step: "Check", status: "completed" }] },      }),    ];     expect(deriveActivePlanState(activities, TurnId.make("turn-1"))?.steps).toEqual([      { durationMs: 3_000, step: "Check", status: "completed" },    ]);  });}); describe("deriveTurnPlans", () => {

Lines 1–500 of 2329.