/** * Optional live-model smoke for the current Claude SDK runner. * * Skips unless explicitly enabled with RUN_REAL_MODEL_TESTS=true and an * OpenRouter/Anthropic token is available. When enabled, it verifies that * `runAgent` can complete one real SDK turn and project the user/assistant * messages into the structured AgentMessage table shape. */ import { describe, it, expect } from "vitest"; import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import "dotenv/config"; import { runAgent } from "../../src/agent/runner.js"; import type { PrismaClient } from "@prisma/client"; const API_KEY = process.env["OPENROUTER_API_KEY"] ?? process.env["ANTHROPIC_AUTH_TOKEN"]; const HAS_KEY = API_KEY !== undefined && API_KEY !== ""; const ENABLED = HAS_KEY && process.env["RUN_REAL_MODEL_TESTS"] === "true"; const describeOrSkip = ENABLED ? describe : describe.skip; if (ENABLED) { process.env["ANTHROPIC_AUTH_TOKEN"] = API_KEY; process.env["ANTHROPIC_BASE_URL"] ??= "https://openrouter.ai/api"; process.env["ANTHROPIC_API_KEY"] ??= ""; } const MODEL = process.env["SMOKE_MODEL"] ?? process.env["ANTHROPIC_DEFAULT_SONNET_MODEL"] ?? "z-ai/glm-4.7"; describeOrSkip("real model integration (OpenRouter)", () => { it("completes one live SDK turn and records structured messages", async () => { const workspace = await mkdtemp(join(tmpdir(), "hub-real-model-")); const messages: unknown[] = []; const stubPrisma = { projectAgentLock: { update: async () => ({}) }, agentMessage: { create: async (input: unknown) => { messages.push(input); return {}; }, }, } as unknown as PrismaClient; try { const result = await runAgent({ runId: "real-test-run", sessionId: "real-test-session", prompt: "请只回复: OK", model: MODEL, project: { projectId: "real-test-project", boundChatId: "chat-test", workspaceRoot: dirname(workspace), workspaceDir: workspace, }, prisma: stubPrisma, systemPrompt: "你是一个极简 smoke test 助手。请严格按用户要求回复。", maxTurns: 3, }); expect(result.status, result.error).toBe("completed"); expect(result.text.length).toBeGreaterThan(0); expect(messages.length).toBeGreaterThanOrEqual(2); } finally { await rm(workspace, { recursive: true, force: true }); } }, 60_000); });