225 lines · 6.5 KB · TypeScript
RawDownload
import { assert, it } from "@effect/vitest";import * as Schema from "effect/Schema"; import * as CodexSchema from "./schema.ts"; const isGetAccountResponse = Schema.is(CodexSchema.V2GetAccountResponse);const isThreadReadResponse = Schema.is(CodexSchema.V2ThreadReadResponse);const isThreadResumeResponse = Schema.is(CodexSchema.V2ThreadResumeResponse);const isThreadRollbackResponse = Schema.is(CodexSchema.V2ThreadRollbackResponse);const isThreadForkResponse = Schema.is(CodexSchema.V2ThreadForkResponse);const isTurnCompletedNotification = Schema.is(CodexSchema.V2TurnCompletedNotification);const decodeThreadResumeResponse = Schema.decodeUnknownSync(CodexSchema.V2ThreadResumeResponse); it("keeps async questions in live notifications and thread history", () => {  const item = {    type: "agentMessage",    id: "question-1",    text: "Which package?\n- pnpm\n- npm\n\nWhat should it be named?",    phase: "final_answer",    delivery: "async",    questions: [      { title: "Which package manager?", options: ["pnpm", "npm"] },      { title: "What should it be named?" },    ],  } as const;  for (const schema of [    CodexSchema.ServerNotification__ThreadItem,    CodexSchema.V2ItemStartedNotification__ThreadItem,    CodexSchema.V2ItemCompletedNotification__ThreadItem,    CodexSchema.V2ThreadReadResponse__ThreadItem,    CodexSchema.V2ThreadResumeResponse__ThreadItem,  ]) {    assert.deepEqual(Schema.decodeUnknownSync(schema)(item), item);  }}); it("accepts Codex 0.150 multi-agent values", () => {  const schemas = [    CodexSchema.ServerNotification__SubAgentActivityKind,    CodexSchema.V2ItemStartedNotification__SubAgentActivityKind,    CodexSchema.V2ItemCompletedNotification__SubAgentActivityKind,    CodexSchema.V2ThreadReadResponse__SubAgentActivityKind,    CodexSchema.V2ThreadResumeResponse__SubAgentActivityKind,  ];   for (const schema of schemas) {    assert.equal(Schema.is(schema)("completed"), true);  }   for (const tool of ["sendMessage", "followupTask", "interruptAgent", "listAgents"]) {    assert.equal(Schema.is(CodexSchema.ServerNotification__CollabAgentTool)(tool), true);    assert.equal(Schema.is(CodexSchema.V2ThreadResumeResponse__CollabAgentTool)(tool), true);  }   assert.equal(    Schema.is(CodexSchema.ServerNotification__CollabAgentToolCallStatus)("interrupted"),    true,  );  assert.equal(    Schema.is(CodexSchema.V2ThreadResumeResponse__CollabAgentToolCallStatus)("interrupted"),    true,  );   const resumeResponse = {    approvalPolicy: "never",    approvalsReviewer: "user",    cwd: "/tmp/project",    model: "gpt-5.6-sol",    modelProvider: "openai",    sandbox: { type: "dangerFullAccess" },    thread: {      cliVersion: "0.150.0",      createdAt: 0,      cwd: "/tmp/project",      ephemeral: false,      id: "root-thread",      modelProvider: "openai",      preview: "",      sessionId: "session-1",      source: "cli",      status: { type: "idle" },      turns: [        {          id: "turn-1",          status: "completed",          items: [            {              agentsStates: {},              id: "item-1",              receiverThreadIds: ["child-thread"],              senderThreadId: "root-thread",              status: "interrupted",              tool: "followupTask",              type: "collabAgentToolCall",            },          ],        },      ],      updatedAt: 0,    },  };   assert.equal(Schema.is(CodexSchema.V2ThreadResumeResponse)(resumeResponse), true);}); it("accepts Codex rate limit errors for thread responses", () => {  const failedThread = {    cliVersion: "0.150.0",    createdAt: 0,    cwd: "/tmp/project",    ephemeral: false,    id: "thread-1",    modelProvider: "openai",    preview: "",    sessionId: "session-1",    source: "cli",    status: { type: "idle" },    turns: [      {        error: {          codexErrorInfo: "rateLimitExceeded",          message: "Rate limit exceeded",        },        id: "turn-1",        items: [],        status: "failed",      },    ],    updatedAt: 0,  };  assert.equal(isThreadReadResponse({ thread: failedThread }), true);  assert.equal(    isThreadResumeResponse({      approvalPolicy: "never",      approvalsReviewer: "user",      cwd: "/tmp/project",      model: "gpt-5.6-sol",      modelProvider: "openai",      sandbox: { type: "dangerFullAccess" },      thread: failedThread,    }),    true,  );  assert.equal(isThreadRollbackResponse({ thread: failedThread }), true);}); it("accepts Codex misalignment policy errors for thread responses", () => {  const failedThread = {    cliVersion: "0.150.0",    createdAt: 0,    cwd: "/tmp/project",    ephemeral: false,    id: "thread-1",    modelProvider: "openai",    preview: "",    sessionId: "session-1",    source: "cli",    status: { type: "idle" },    turns: [      {        error: {          codexErrorInfo: "misalignmentPolicyViolation",          message: "Misalignment policy violation",        },        id: "turn-1",        items: [],        status: "failed",      },    ],    updatedAt: 0,  };  const resumeLikeResponse = {    approvalPolicy: "never",    approvalsReviewer: "user",    cwd: "/tmp/project",    model: "gpt-5.6-sol",    modelProvider: "openai",    sandbox: { type: "dangerFullAccess" },    thread: failedThread,  };  assert.equal(isThreadReadResponse({ thread: failedThread }), true);  assert.equal(isThreadResumeResponse(resumeLikeResponse), true);  assert.equal(isThreadRollbackResponse({ thread: failedThread }), true);  assert.equal(isThreadForkResponse(resumeLikeResponse), true);  const decodedResume = decodeThreadResumeResponse(resumeLikeResponse);  assert.equal(decodedResume.thread.turns[0]?.error?.codexErrorInfo, "misalignmentPolicyViolation");  assert.equal(    isTurnCompletedNotification({      threadId: "thread-1",      turn: {        error: {          codexErrorInfo: "misalignmentPolicyViolation",          message: "Misalignment policy violation",        },        id: "turn-1",        items: [],        status: "failed",      },    }),    true,  );}); it("accepts Codex 0.150 account plan values", () => {  const planTypes = [    "self_serve_business_prolite",    "ent26",    "enterprise_cbp_automation",    "edu_plus",    "edu_pro",  ];   for (const planType of planTypes) {    const accountResponse = {      account: {        email: "user@example.com",        planType,        type: "chatgpt",      },      requiresOpenaiAuth: true,    };     assert.equal(isGetAccountResponse(accountResponse), true);  }});