| import path from "node:path"; |
| import { beforeEach, describe, expect, it, vi } from "vitest"; |
| import type { TemplateContext } from "../templating.js"; |
| import type { FollowupRun, QueueSettings } from "./queue.js"; |
| import { createMockFollowupRun, createMockTypingController } from "./test-helpers.js"; |
|
|
| const runEmbeddedPiAgentMock = vi.fn(); |
| const runWithModelFallbackMock = vi.fn(); |
|
|
| vi.mock("../../agents/model-fallback.js", () => ({ |
| runWithModelFallback: (params: { |
| provider: string; |
| model: string; |
| run: (provider: string, model: string) => Promise<unknown>; |
| }) => runWithModelFallbackMock(params), |
| })); |
|
|
| vi.mock("../../agents/pi-embedded.js", async () => { |
| const actual = await vi.importActual<typeof import("../../agents/pi-embedded.js")>( |
| "../../agents/pi-embedded.js", |
| ); |
| return { |
| ...actual, |
| queueEmbeddedPiMessage: vi.fn().mockReturnValue(false), |
| runEmbeddedPiAgent: (params: unknown) => runEmbeddedPiAgentMock(params), |
| }; |
| }); |
|
|
| vi.mock("./queue.js", async () => { |
| const actual = await vi.importActual<typeof import("./queue.js")>("./queue.js"); |
| return { |
| ...actual, |
| enqueueFollowupRun: vi.fn(), |
| scheduleFollowupDrain: vi.fn(), |
| }; |
| }); |
|
|
| import { runReplyAgent } from "./agent-runner.js"; |
|
|
| describe("runReplyAgent media path normalization", () => { |
| beforeEach(() => { |
| runEmbeddedPiAgentMock.mockReset(); |
| runWithModelFallbackMock.mockReset(); |
| runWithModelFallbackMock.mockImplementation( |
| async ({ |
| provider, |
| model, |
| run, |
| }: { |
| provider: string; |
| model: string; |
| run: (...args: unknown[]) => Promise<unknown>; |
| }) => ({ |
| result: await run(provider, model), |
| provider, |
| model, |
| }), |
| ); |
| }); |
|
|
| it("normalizes final MEDIA replies against the run workspace", async () => { |
| runEmbeddedPiAgentMock.mockResolvedValue({ |
| payloads: [{ text: "MEDIA:./out/generated.png" }], |
| meta: { |
| agentMeta: { |
| sessionId: "session", |
| provider: "anthropic", |
| model: "claude", |
| }, |
| }, |
| }); |
|
|
| const result = await runReplyAgent({ |
| commandBody: "generate", |
| followupRun: createMockFollowupRun({ |
| prompt: "generate", |
| run: { |
| agentId: "main", |
| agentDir: "/tmp/agent", |
| messageProvider: "telegram", |
| workspaceDir: "/tmp/workspace", |
| }, |
| }) as unknown as FollowupRun, |
| queueKey: "main", |
| resolvedQueue: { mode: "interrupt" } as QueueSettings, |
| shouldSteer: false, |
| shouldFollowup: false, |
| isActive: false, |
| isStreaming: false, |
| typing: createMockTypingController(), |
| sessionCtx: { |
| Provider: "telegram", |
| Surface: "telegram", |
| To: "chat-1", |
| OriginatingTo: "chat-1", |
| AccountId: "default", |
| MessageSid: "msg-1", |
| } as unknown as TemplateContext, |
| defaultModel: "anthropic/claude", |
| resolvedVerboseLevel: "off", |
| isNewSession: false, |
| blockStreamingEnabled: false, |
| resolvedBlockStreamingBreak: "message_end", |
| shouldInjectGroupIntro: false, |
| typingMode: "instant", |
| }); |
|
|
| expect(result).toMatchObject({ |
| mediaUrl: path.join("/tmp/workspace", "out", "generated.png"), |
| mediaUrls: [path.join("/tmp/workspace", "out", "generated.png")], |
| }); |
| }); |
| }); |
|
|