786 lines · 19.2 KB · TypeScript
RawDownload
import { describe, expect, test } from "bun:test"import { MessageV2 } from "../../src/session/message-v2"import type { Provider } from "../../src/provider/provider" const sessionID = "session"const model: Provider.Model = {  id: "test-model",  providerID: "test",  api: {    id: "test-model",    url: "https://example.com",    npm: "@ai-sdk/openai",  },  name: "Test Model",  capabilities: {    temperature: true,    reasoning: false,    attachment: false,    toolcall: true,    input: {      text: true,      audio: false,      image: false,      video: false,      pdf: false,    },    output: {      text: true,      audio: false,      image: false,      video: false,      pdf: false,    },    interleaved: false,  },  cost: {    input: 0,    output: 0,    cache: {      read: 0,      write: 0,    },  },  limit: {    context: 0,    input: 0,    output: 0,  },  status: "active",  options: {},  headers: {},  release_date: "2026-01-01",} function userInfo(id: string): MessageV2.User {  return {    id,    sessionID,    role: "user",    time: { created: 0 },    agent: "user",    model: { providerID: "test", modelID: "test" },    tools: {},    mode: "",  } as unknown as MessageV2.User} function assistantInfo(  id: string,  parentID: string,  error?: MessageV2.Assistant["error"],  meta?: { providerID: string; modelID: string },): MessageV2.Assistant {  const infoModel = meta ?? { providerID: model.providerID, modelID: model.api.id }  return {    id,    sessionID,    role: "assistant",    time: { created: 0 },    error,    parentID,    modelID: infoModel.modelID,    providerID: infoModel.providerID,    mode: "",    agent: "agent",    path: { cwd: "/", root: "/" },    cost: 0,    tokens: {      input: 0,      output: 0,      reasoning: 0,      cache: { read: 0, write: 0 },    },  } as unknown as MessageV2.Assistant} function basePart(messageID: string, id: string) {  return {    id,    sessionID,    messageID,  }} describe("session.message-v2.toModelMessage", () => {  test("filters out messages with no parts", () => {    const input: MessageV2.WithParts[] = [      {        info: userInfo("m-empty"),        parts: [],      },      {        info: userInfo("m-user"),        parts: [          {            ...basePart("m-user", "p1"),            type: "text",            text: "hello",          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [{ type: "text", text: "hello" }],      },    ])  })   test("filters out messages with only ignored parts", () => {    const messageID = "m-user"     const input: MessageV2.WithParts[] = [      {        info: userInfo(messageID),        parts: [          {            ...basePart(messageID, "p1"),            type: "text",            text: "ignored",            ignored: true,          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([])  })   test("includes synthetic text parts", () => {    const messageID = "m-user"     const input: MessageV2.WithParts[] = [      {        info: userInfo(messageID),        parts: [          {            ...basePart(messageID, "p1"),            type: "text",            text: "hello",            synthetic: true,          },        ] as MessageV2.Part[],      },      {        info: assistantInfo("m-assistant", messageID),        parts: [          {            ...basePart("m-assistant", "a1"),            type: "text",            text: "assistant",            synthetic: true,          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [{ type: "text", text: "hello" }],      },      {        role: "assistant",        content: [{ type: "text", text: "assistant" }],      },    ])  })   test("converts user text/file parts and injects compaction/subtask prompts", () => {    const messageID = "m-user"     const input: MessageV2.WithParts[] = [      {        info: userInfo(messageID),        parts: [          {            ...basePart(messageID, "p1"),            type: "text",            text: "hello",          },          {            ...basePart(messageID, "p2"),            type: "text",            text: "ignored",            ignored: true,          },          {            ...basePart(messageID, "p3"),            type: "file",            mime: "image/png",            filename: "img.png",            url: "https://example.com/img.png",          },          {            ...basePart(messageID, "p4"),            type: "file",            mime: "text/plain",            filename: "note.txt",            url: "https://example.com/note.txt",          },          {            ...basePart(messageID, "p5"),            type: "file",            mime: "application/x-directory",            filename: "dir",            url: "https://example.com/dir",          },          {            ...basePart(messageID, "p6"),            type: "compaction",            auto: true,          },          {            ...basePart(messageID, "p7"),            type: "subtask",            prompt: "prompt",            description: "desc",            agent: "agent",          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [          { type: "text", text: "hello" },          {            type: "file",            mediaType: "image/png",            filename: "img.png",            data: "https://example.com/img.png",          },          { type: "text", text: "What did we do so far?" },          { type: "text", text: "The following tool was executed by the user" },        ],      },    ])  })   test("converts assistant tool completion into tool-call + tool-result messages with attachments", () => {    const userID = "m-user"    const assistantID = "m-assistant"     const input: MessageV2.WithParts[] = [      {        info: userInfo(userID),        parts: [          {            ...basePart(userID, "u1"),            type: "text",            text: "run tool",          },        ] as MessageV2.Part[],      },      {        info: assistantInfo(assistantID, userID),        parts: [          {            ...basePart(assistantID, "a1"),            type: "text",            text: "done",            metadata: { openai: { assistant: "meta" } },          },          {            ...basePart(assistantID, "a2"),            type: "tool",            callID: "call-1",            tool: "bash",            state: {              status: "completed",              input: { cmd: "ls" },              output: "ok",              title: "Bash",              metadata: {},              time: { start: 0, end: 1 },              attachments: [                {                  ...basePart(assistantID, "file-1"),                  type: "file",                  mime: "image/png",                  filename: "attachment.png",                  url: "data:image/png;base64,Zm9v",                },              ],            },            metadata: { openai: { tool: "meta" } },          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [{ type: "text", text: "run tool" }],      },      {        role: "assistant",        content: [          { type: "text", text: "done", providerOptions: { openai: { assistant: "meta" } } },          {            type: "tool-call",            toolCallId: "call-1",            toolName: "bash",            input: { cmd: "ls" },            providerExecuted: undefined,            providerOptions: { openai: { tool: "meta" } },          },        ],      },      {        role: "tool",        content: [          {            type: "tool-result",            toolCallId: "call-1",            toolName: "bash",            output: {              type: "content",              value: [                { type: "text", text: "ok" },                { type: "media", mediaType: "image/png", data: "Zm9v" },              ],            },            providerOptions: { openai: { tool: "meta" } },          },        ],      },    ])  })   test("omits provider metadata when assistant model differs", () => {    const userID = "m-user"    const assistantID = "m-assistant"     const input: MessageV2.WithParts[] = [      {        info: userInfo(userID),        parts: [          {            ...basePart(userID, "u1"),            type: "text",            text: "run tool",          },        ] as MessageV2.Part[],      },      {        info: assistantInfo(assistantID, userID, undefined, { providerID: "other", modelID: "other" }),        parts: [          {            ...basePart(assistantID, "a1"),            type: "text",            text: "done",            metadata: { openai: { assistant: "meta" } },          },          {            ...basePart(assistantID, "a2"),            type: "tool",            callID: "call-1",            tool: "bash",            state: {              status: "completed",              input: { cmd: "ls" },              output: "ok",              title: "Bash",              metadata: {},              time: { start: 0, end: 1 },            },            metadata: { openai: { tool: "meta" } },          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [{ type: "text", text: "run tool" }],      },      {        role: "assistant",        content: [          { type: "text", text: "done" },          {            type: "tool-call",            toolCallId: "call-1",            toolName: "bash",            input: { cmd: "ls" },            providerExecuted: undefined,          },        ],      },      {        role: "tool",        content: [          {            type: "tool-result",            toolCallId: "call-1",            toolName: "bash",            output: { type: "text", value: "ok" },          },        ],      },    ])  })   test("replaces compacted tool output with placeholder", () => {    const userID = "m-user"    const assistantID = "m-assistant"     const input: MessageV2.WithParts[] = [      {        info: userInfo(userID),        parts: [          {            ...basePart(userID, "u1"),            type: "text",            text: "run tool",          },        ] as MessageV2.Part[],      },      {        info: assistantInfo(assistantID, userID),        parts: [          {            ...basePart(assistantID, "a1"),            type: "tool",            callID: "call-1",            tool: "bash",            state: {              status: "completed",              input: { cmd: "ls" },              output: "this should be cleared",              title: "Bash",              metadata: {},              time: { start: 0, end: 1, compacted: 1 },            },          },        ] as MessageV2.Part[],      },    ]     expect(MessageV2.toModelMessages(input, model)).toStrictEqual([      {        role: "user",        content: [{ type: "text", text: "run tool" }],      },      {        role: "assistant",        content: [          {            type: "tool-call",            toolCallId: "call-1",            toolName: "bash",            input: { cmd: "ls" },            providerExecuted: undefined,          },        ],      },      {        role: "tool",        content: [          {            type: "tool-result",            toolCallId: "call-1",            toolName: "bash",            output: { type: "text", value: "[Old tool result content cleared]" },          },        ],      },    ])  })   test("converts assistant tool error into error-text tool result", () => {    const userID = "m-user"

Lines 1–500 of 786.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t