import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; import test from "node:test"; const root = path.resolve(import.meta.dirname, ".."); const read = (...parts) => fs.readFileSync(path.join(root, ...parts), "utf8"); const { SuperAgentApiError, assertAgentUuid, isAgentUuid, parseAgentErrorPayload, parseAgentPage, shouldSendIdempotencyKey, } = await import("../client/src/sections/superAgent/utils/agentApiParse.js"); const { superAgentServiceApiTable } = await import("../client/src/utils/superAgentApiTable.js"); const { isUploadIntentExpired, normalizeAttachmentUploadIntent, } = await import("../client/src/sections/superAgent/utils/attachmentUpload.js"); test("new api table uses live agent paths", () => { assert.equal(superAgentServiceApiTable.tasksets, "/tasksets"); assert.equal(superAgentServiceApiTable.conversations, "/conversations"); assert.equal( superAgentServiceApiTable.attachmentUploadIntents, "/conversations/:conversationId/attachments/upload-intents", ); assert.equal(superAgentServiceApiTable.threadCommands, "/threads/:threadId/commands"); assert.equal(superAgentServiceApiTable.threadEvents, "/threads/:threadId/stream/events"); assert.equal(superAgentServiceApiTable.threadCancel, "/threads/:threadId/runs/:runId/cancel"); assert.equal(superAgentServiceApiTable.artifacts, "/conversations/:conversationId/artifacts"); assert.doesNotMatch(JSON.stringify(superAgentServiceApiTable), /\/api\/v1/); }); test("uuid and page helpers normalize agent payloads", () => { assert.equal(isAgentUuid("2c1f3c0e-1a2b-4c5d-8e9f-0123456789ab"), true); assert.equal(isAgentUuid("task-1"), false); assert.equal(assertAgentUuid("2c1f3c0e-1a2b-4c5d-8e9f-0123456789ab"), "2c1f3c0e-1a2b-4c5d-8e9f-0123456789ab"); assert.throws( () => assertAgentUuid("task-1", "conversation_id"), (error) => error instanceof SuperAgentApiError && error.status === 422, ); assert.deepEqual(parseAgentPage({ items: [{ id: "a" }], next_cursor: "c1" }), { items: [{ id: "a" }], nextCursor: "c1", }); assert.deepEqual(parseAgentPage({}), { items: [], nextCursor: null }); const error = parseAgentErrorPayload( { code: "AUTHENTICATION_REQUIRED", message: "missing", request_id: "req_1" }, 401, "fallback", ); assert.equal(error.code, "AUTHENTICATION_REQUIRED"); assert.equal(error.requestId, "req_1"); assert.equal(shouldSendIdempotencyKey("POST", "k"), true); assert.equal(shouldSendIdempotencyKey("GET", "k"), false); }); test("attachment upload intent follows the v2 three-stage payload", () => { const intent = normalizeAttachmentUploadIntent({ attachment: { id: "2c1f3c0e-1a2b-4c5d-8e9f-0123456789ab" }, upload: { method: "POST", url: "https://upload.example.test", fields: { token: "opaque", key: "uploads/file.txt" }, expires_at: "2030-01-01T00:00:00Z", }, }); assert.equal(intent.attachmentId, "2c1f3c0e-1a2b-4c5d-8e9f-0123456789ab"); assert.equal(intent.upload.method, "POST"); assert.equal(intent.upload.fields.key, "uploads/file.txt"); assert.equal(isUploadIntentExpired(intent, Date.parse("2029-01-01T00:00:00Z")), false); assert.equal(isUploadIntentExpired(intent, Date.parse("2031-01-01T00:00:00Z")), true); }); test("adapter source exchanges login token for agent jwt and omits identity headers", () => { const table = read("client", "src", "utils", "superAgentApiTable.js"); const agentApi = read("client", "src", "sections", "superAgent", "utils", "agentApi.js"); const streamHook = read("client", "src", "sections", "superAgent", "hooks", "useSuperAgentStream.js"); const protocol = read("..", "api", "app", "controllers", "superAgentProtocol.js"); const actions = read("client", "src", "sections", "superAgent", "actions", "api.js"); const resources = read("client", "src", "sections", "superAgent", "actions", "agentResources.js"); const chatHook = read("client", "src", "sections", "superAgent", "hooks", "useSuperAgentChat.js"); const uploadUtils = read("client", "src", "sections", "superAgent", "utils", "attachmentUpload.js"); assert.doesNotMatch(table, /\/api\/v1\/tasks/); assert.match(agentApi, /ACCESS_TOKEN_PATH = "\/_api\/super-agent\/access-token"/); assert.match(agentApi, /Authorization: `Bearer \$\{token\}`/); assert.match(agentApi, /headers\.delete\("X-User-Id"\)/); assert.match(agentApi, /headers\.delete\("X-Search-Token"\)/); assert.match(agentApi, /Idempotency-Key/); assert.match(streamHook, /withAgentAuthorization/); assert.doesNotMatch(streamHook, /X-User-Id/); assert.doesNotMatch(streamHook, /\/api\/v1/); assert.match(protocol, /issueAgentAccessToken/); assert.doesNotMatch(protocol, /'X-User-Id'/); assert.match(protocol, /\/threads\/\$\{encodeURIComponent/); assert.match(actions, /requestAgentJson/); assert.match(resources, /createAttachmentUploadIntent/); assert.match(resources, /completeAttachmentUpload/); assert.match(resources, /listAttachments/); assert.match(chatHook, /createAttachmentUploadIntent\(conversationId/); assert.match(chatHook, /completeAttachmentUpload\(uploadIntent\.attachmentId\)/); assert.match(chatHook, /listAttachments\(conversationId\)/); assert.match(chatHook, /attachment\.status === "ready" && !attachment\.message_id/); assert.match(chatHook, /handleCancelUpload/); assert.doesNotMatch(chatHook, /uploadSuperAgentFile/); assert.match(uploadUtils, /FormData/); assert.match(uploadUtils, /xhr\.send\(file\)/); assert.match(resources, /cancelThreadRun/); });