






























@@ -2,7 +2,7 @@
22// session lookup, list/get/download responses, and validation errors.
33import { beforeEach, describe, expect, it, vi } from "vitest";
44import { expectRecordFields } from "../test-helpers.assertions.js";
5-import { artifactsHandlers, collectArtifactsFromMessages } from "./artifacts.js";
5+import { artifactsHandlers } from "./artifacts.js";
6677const hoisted = vi.hoisted(() => ({
88getTaskSessionLookupByIdForStatus: vi.fn(),
@@ -325,11 +325,9 @@ describe("artifacts RPC handlers", () => {
325325});
326326327327it("gets and downloads an inline artifact", async () => {
328-const listed = collectArtifactsFromMessages({
329-sessionKey: "agent:main:main",
330-messages: [resultImageMessage()],
331-});
332-const artifactId = listed[0]?.id;
328+const listed = await listArtifacts({ sessionKey: "agent:main:main" }, { id: "list-inline" });
329+const listedPayload = expectArtifactList(listed.calls);
330+const artifactId = listedPayload.artifacts?.[0]?.id;
333331const artifactIdString = requireNonEmptyString(artifactId, "expected listed artifact id");
334332335333const get = await getArtifact(
@@ -354,37 +352,35 @@ describe("artifacts RPC handlers", () => {
354352expectFields(downloadPayload.artifact, { id: artifactId });
355353});
356354357-it("can scan artifact summaries without retaining inline data", () => {
358-const artifacts = collectArtifactsFromMessages({
359-sessionKey: "agent:main:main",
360-includeDownloadData: false,
361-messages: [
362-{
363-role: "assistant",
364-content: [
365-{
366-type: "image",
367-data: "aGVsbG8=",
368-mimeType: "image/png",
369-alt: "result.png",
370-},
371-],
372-__openclaw: { seq: 2 },
373-},
374-],
375-});
355+it("can scan artifact summaries without retaining inline data", async () => {
356+mockedMessages([
357+{
358+role: "assistant",
359+content: [
360+{
361+type: "image",
362+data: "aGVsbG8=",
363+mimeType: "image/png",
364+alt: "result.png",
365+},
366+],
367+__openclaw: { seq: 2 },
368+},
369+]);
376370371+const { calls } = await listArtifacts({ sessionKey: "agent:main:main" });
372+const artifacts = expectArtifactList(calls).artifacts;
377373expect(artifacts).toHaveLength(1);
378-expectFields(artifacts[0], {
374+expectFields(artifacts?.[0], {
379375title: "result.png",
380376mimeType: "image/png",
381377sizeBytes: 5,
382378});
383-expectFields(artifacts[0]?.download, { mode: "bytes" });
384-expect(artifacts[0]).not.toHaveProperty("data");
379+expectFields(artifacts?.[0]?.download, { mode: "bytes" });
380+expect(artifacts?.[0]).not.toHaveProperty("data");
385381});
386382387-it("hydrates inline data only for the requested download artifact", () => {
383+it("hydrates inline data only for the requested download artifact", async () => {
388384const messages = [
389385{
390386role: "assistant",
@@ -405,23 +401,28 @@ describe("artifacts RPC handlers", () => {
405401__openclaw: { seq: 2 },
406402},
407403];
408-const summaries = collectArtifactsFromMessages({
409-sessionKey: "agent:main:main",
410-includeDownloadData: false,
411- messages,
412-});
413-const secondArtifactId = requireNonEmptyString(summaries[1]?.id, "expected second artifact id");
404+mockedMessages(messages);
414405415-const hydrated = collectArtifactsFromMessages({
406+const summaries = await listArtifacts({ sessionKey: "agent:main:main" });
407+const summaryArtifacts = expectArtifactList(summaries.calls).artifacts;
408+const secondArtifactId = requireNonEmptyString(
409+summaryArtifacts?.[1]?.id,
410+"expected second artifact id",
411+);
412+expect(summaryArtifacts?.[0]).not.toHaveProperty("data");
413+expect(summaryArtifacts?.[1]).not.toHaveProperty("data");
414+415+const download = await downloadArtifact({
416416sessionKey: "agent:main:main",
417-downloadArtifactId: secondArtifactId,
418- messages,
417+artifactId: secondArtifactId,
419418});
419+const downloadPayload = expectOkPayload(download.calls) as {
420+artifact?: Record<string, unknown>;
421+data?: string;
422+};
420423421-expect(hydrated).toHaveLength(2);
422-expectFields(hydrated[0], { title: "first.png" });
423-expect(hydrated[0]).not.toHaveProperty("data");
424-expectFields(hydrated[1], { title: "second.png", data: "c2Vjb25k" });
424+expectFields(downloadPayload.artifact, { title: "second.png" });
425+expectFields(downloadPayload, { data: "c2Vjb25k" });
425426});
426427427428it("resolves runId queries through the gateway run-to-session lookup", async () => {
@@ -700,76 +701,73 @@ describe("artifacts RPC handlers", () => {
700701expectFields(artifact?.download, { mode: "bytes" });
701702});
702703703-it("treats transcript non-base64 data URLs as unsupported downloads", () => {
704-const artifacts = collectArtifactsFromMessages({
705-sessionKey: "agent:main:main",
706-messages: [
707-{
708-role: "user",
709-content: [
710-{
711-type: "input_image",
712-image_url: "data:text/plain,hello",
713-alt: "uploaded.txt",
714-},
715-],
716-__openclaw: { seq: 4 },
717-},
718-],
719-});
704+it("treats transcript non-base64 data URLs as unsupported downloads", async () => {
705+mockedMessages([
706+{
707+role: "user",
708+content: [
709+{
710+type: "input_image",
711+image_url: "data:text/plain,hello",
712+alt: "uploaded.txt",
713+},
714+],
715+__openclaw: { seq: 4 },
716+},
717+]);
720718719+const { calls } = await listArtifacts({ sessionKey: "agent:main:main" });
720+const artifacts = expectArtifactList(calls).artifacts;
721721expect(artifacts).toHaveLength(1);
722-expectFields(artifacts[0], {
722+expectFields(artifacts?.[0], {
723723type: "image",
724724title: "uploaded.txt",
725725});
726-expectFields(artifacts[0]?.download, { mode: "unsupported" });
727-expect(artifacts[0]?.download).not.toHaveProperty("encoding", "base64");
726+expectFields(artifacts?.[0]?.download, { mode: "unsupported" });
727+expect(artifacts?.[0]?.download).not.toHaveProperty("encoding", "base64");
728728});
729729730-it("treats non-base64 data URLs in the content field as unsupported downloads", () => {
731-const artifacts = collectArtifactsFromMessages({
732-sessionKey: "agent:main:main",
733-messages: [
734-{
735-role: "assistant",
736-content: [
737-{
738-type: "file",
739-content: "data:text/plain,hello",
740-title: "plain.txt",
741-},
742-],
743-__openclaw: { seq: 5 },
744-},
745-],
746-});
730+it("treats non-base64 data URLs in the content field as unsupported downloads", async () => {
731+mockedMessages([
732+{
733+role: "assistant",
734+content: [
735+{
736+type: "file",
737+content: "data:text/plain,hello",
738+title: "plain.txt",
739+},
740+],
741+__openclaw: { seq: 5 },
742+},
743+]);
747744745+const { calls } = await listArtifacts({ sessionKey: "agent:main:main" });
746+const artifacts = expectArtifactList(calls).artifacts;
748747expect(artifacts).toHaveLength(1);
749-expectFields(artifacts[0], {
748+expectFields(artifacts?.[0], {
750749title: "plain.txt",
751750});
752-expectFields(artifacts[0]?.download, { mode: "unsupported" });
753-expect(artifacts[0]).not.toHaveProperty("data");
751+expectFields(artifacts?.[0]?.download, { mode: "unsupported" });
752+expect(artifacts?.[0]).not.toHaveProperty("data");
754753});
755754756-it("treats unsafe artifact URLs as unsupported downloads", () => {
757-const artifacts = collectArtifactsFromMessages({
758-sessionKey: "agent:main:main",
759-messages: [
760-{
761-role: "assistant",
762-content: [{ type: "file", title: "secret.txt", url: "file:///etc/passwd" }],
763-__openclaw: { seq: 4 },
764-},
765-],
766-});
755+it("treats unsafe artifact URLs as unsupported downloads", async () => {
756+mockedMessages([
757+{
758+role: "assistant",
759+content: [{ type: "file", title: "secret.txt", url: "file:///etc/passwd" }],
760+__openclaw: { seq: 4 },
761+},
762+]);
767763768-expectFields(artifacts[0], {
764+const { calls } = await listArtifacts({ sessionKey: "agent:main:main" });
765+const artifacts = expectArtifactList(calls).artifacts;
766+expectFields(artifacts?.[0], {
769767title: "secret.txt",
770768});
771-expectFields(artifacts[0]?.download, { mode: "unsupported" });
772-expect(artifacts[0]).not.toHaveProperty("url");
769+expectFields(artifacts?.[0]?.download, { mode: "unsupported" });
770+expect(artifacts?.[0]).not.toHaveProperty("url");
773771});
774772775773it("returns typed errors for missing query scope and missing artifacts", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。