diff --git a/apps/web/e2e/media-pipeline.spec.ts b/apps/web/e2e/media-pipeline.spec.ts index dc712cc..eb63fe8 100644 --- a/apps/web/e2e/media-pipeline.spec.ts +++ b/apps/web/e2e/media-pipeline.spec.ts @@ -54,10 +54,13 @@ test("an uploaded video streams from the artifact route and plays inline", async await captureScreenshot(page, testInfo, "media-video-block"); }); -test("the image lightbox downloads the original from the artifact route", async ({ page }) => { +test("an image in the main conversation opens and downloads from the artifact route", async ({ + page, +}) => { const stamp = Date.now(); await signup(page, `media-image-${stamp}@rakazo.test`, "password12", "Media Image"); - await completeOnboarding(page); + // The main conversation is a group thread, so this covers group uploads and reads. + await completeOnboarding(page, undefined, { mainConversation: true }); await page .locator('input[type="file"]') @@ -65,7 +68,7 @@ test("the image lightbox downloads the original from the artifact route", async await page.getByRole("combobox", { name: /Message/ }).fill("a pixel"); await page.keyboard.press("Enter"); - const thumbnail = page.getByRole("img", { name: "pixel.png" }); + const thumbnail = page.getByTestId("transcript").getByRole("img", { name: "pixel.png" }); await expect(thumbnail).toBeVisible({ timeout: 30_000 }); await expect(thumbnail).toHaveAttribute("src", /^\/api\/artifacts\/[^/?]+$/); await thumbnail.click(); diff --git a/packages/adapters/src/artifact-files.ts b/packages/adapters/src/artifact-files.ts index ad88094..b228bf1 100644 --- a/packages/adapters/src/artifact-files.ts +++ b/packages/adapters/src/artifact-files.ts @@ -47,6 +47,7 @@ export async function storeArtifactStream( stream: ArtifactStreamPut["stream"]; maxBytes?: number; signal?: AbortSignal; + operationId?: string; }, ) { validateAttachmentMimeType(input.mimeType); @@ -54,7 +55,8 @@ export async function storeArtifactStream( input.maxBytes ?? Number.POSITIVE_INFINITY, artifactMaxBytes(input.mimeType), ); - const operationId = `artifact-store:${input.runId ?? input.botId ?? input.userId}`; + const operationId = + input.operationId ?? `artifact-store:${input.runId ?? input.botId ?? input.userId}`; const context: AdapterContext = { operationId, traceId: operationId, diff --git a/packages/adapters/src/thread-artifacts.ts b/packages/adapters/src/thread-artifacts.ts index 8d82aef..f6630bd 100644 --- a/packages/adapters/src/thread-artifacts.ts +++ b/packages/adapters/src/thread-artifacts.ts @@ -37,7 +37,7 @@ const ATTACHMENT_BLOCK_KINDS: ReadonlySet = new Set(["image", "video", " export function attachableFileMaxBytes(artifacts: ArtifactStore, mimeType: string): number { return artifacts.describe().capabilities.stream ? artifactMaxBytes(mimeType) - : Math.min(ATTACHMENT_MAX_BYTES, artifactMaxBytes(mimeType)); + : ATTACHMENT_MAX_BYTES; } export function formatMiB(bytes: number): string { @@ -82,6 +82,7 @@ export async function attachWorkspaceFileToThread( yield bytes; })(), maxBytes, + operationId: input.operationId, }); return { artifactId: row.id, block: messageBlockForArtifact(row) }; }