add resource link
This commit is contained in:
parent
4d03b243e3
commit
7e59081b43
1 changed files with 433 additions and 16 deletions
|
|
@ -1,4 +1,11 @@
|
|||
import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "./types.js";
|
||||
import {
|
||||
LATEST_PROTOCOL_VERSION,
|
||||
SUPPORTED_PROTOCOL_VERSIONS,
|
||||
ResourceLinkSchema,
|
||||
ContentBlockSchema,
|
||||
PromptMessageSchema,
|
||||
CallToolResultSchema
|
||||
} from "./types.js";
|
||||
|
||||
describe("Types", () => {
|
||||
|
||||
|
|
@ -14,4 +21,206 @@ describe("Types", () => {
|
|||
expect(SUPPORTED_PROTOCOL_VERSIONS).toContain("2024-10-07");
|
||||
});
|
||||
|
||||
describe("ResourceLink", () => {
|
||||
test("should validate a minimal ResourceLink", () => {
|
||||
const resourceLink = {
|
||||
type: "resource_link",
|
||||
uri: "file:///path/to/file.txt",
|
||||
name: "file.txt"
|
||||
};
|
||||
|
||||
const result = ResourceLinkSchema.safeParse(resourceLink);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("resource_link");
|
||||
expect(result.data.uri).toBe("file:///path/to/file.txt");
|
||||
expect(result.data.name).toBe("file.txt");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate a ResourceLink with all optional fields", () => {
|
||||
const resourceLink = {
|
||||
type: "resource_link",
|
||||
uri: "https://example.com/resource",
|
||||
name: "Example Resource",
|
||||
title: "A comprehensive example resource",
|
||||
description: "This resource demonstrates all fields",
|
||||
mimeType: "text/plain",
|
||||
_meta: { custom: "metadata" }
|
||||
};
|
||||
|
||||
const result = ResourceLinkSchema.safeParse(resourceLink);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.title).toBe("A comprehensive example resource");
|
||||
expect(result.data.description).toBe("This resource demonstrates all fields");
|
||||
expect(result.data.mimeType).toBe("text/plain");
|
||||
expect(result.data._meta).toEqual({ custom: "metadata" });
|
||||
}
|
||||
});
|
||||
|
||||
test("should fail validation for invalid type", () => {
|
||||
const invalidResourceLink = {
|
||||
type: "invalid_type",
|
||||
uri: "file:///path/to/file.txt",
|
||||
name: "file.txt"
|
||||
};
|
||||
|
||||
const result = ResourceLinkSchema.safeParse(invalidResourceLink);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
test("should fail validation for missing required fields", () => {
|
||||
const invalidResourceLink = {
|
||||
type: "resource_link",
|
||||
uri: "file:///path/to/file.txt"
|
||||
// missing name
|
||||
};
|
||||
|
||||
const result = ResourceLinkSchema.safeParse(invalidResourceLink);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("ContentBlock", () => {
|
||||
test("should validate text content", () => {
|
||||
const textContent = {
|
||||
type: "text",
|
||||
text: "Hello, world!"
|
||||
};
|
||||
|
||||
const result = ContentBlockSchema.safeParse(textContent);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("text");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate image content", () => {
|
||||
const imageContent = {
|
||||
type: "image",
|
||||
data: "aGVsbG8=", // base64 encoded "hello"
|
||||
mimeType: "image/png"
|
||||
};
|
||||
|
||||
const result = ContentBlockSchema.safeParse(imageContent);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("image");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate audio content", () => {
|
||||
const audioContent = {
|
||||
type: "audio",
|
||||
data: "aGVsbG8=", // base64 encoded "hello"
|
||||
mimeType: "audio/mp3"
|
||||
};
|
||||
|
||||
const result = ContentBlockSchema.safeParse(audioContent);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("audio");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate resource link content", () => {
|
||||
const resourceLink = {
|
||||
type: "resource_link",
|
||||
uri: "file:///path/to/file.txt",
|
||||
name: "file.txt",
|
||||
mimeType: "text/plain"
|
||||
};
|
||||
|
||||
const result = ContentBlockSchema.safeParse(resourceLink);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("resource_link");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate embedded resource content", () => {
|
||||
const embeddedResource = {
|
||||
type: "resource",
|
||||
resource: {
|
||||
uri: "file:///path/to/file.txt",
|
||||
mimeType: "text/plain",
|
||||
text: "File contents"
|
||||
}
|
||||
};
|
||||
|
||||
const result = ContentBlockSchema.safeParse(embeddedResource);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.type).toBe("resource");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("PromptMessage with ContentBlock", () => {
|
||||
test("should validate prompt message with resource link", () => {
|
||||
const promptMessage = {
|
||||
role: "assistant",
|
||||
content: {
|
||||
type: "resource_link",
|
||||
uri: "file:///project/src/main.rs",
|
||||
name: "main.rs",
|
||||
description: "Primary application entry point",
|
||||
mimeType: "text/x-rust"
|
||||
}
|
||||
};
|
||||
|
||||
const result = PromptMessageSchema.safeParse(promptMessage);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.content.type).toBe("resource_link");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("CallToolResult with ContentBlock", () => {
|
||||
test("should validate tool result with resource links", () => {
|
||||
const toolResult = {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "Found the following files:"
|
||||
},
|
||||
{
|
||||
type: "resource_link",
|
||||
uri: "file:///project/src/main.rs",
|
||||
name: "main.rs",
|
||||
description: "Primary application entry point",
|
||||
mimeType: "text/x-rust"
|
||||
},
|
||||
{
|
||||
type: "resource_link",
|
||||
uri: "file:///project/src/lib.rs",
|
||||
name: "lib.rs",
|
||||
description: "Library exports",
|
||||
mimeType: "text/x-rust"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const result = CallToolResultSchema.safeParse(toolResult);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.content).toHaveLength(3);
|
||||
expect(result.data.content[0].type).toBe("text");
|
||||
expect(result.data.content[1].type).toBe("resource_link");
|
||||
expect(result.data.content[2].type).toBe("resource_link");
|
||||
}
|
||||
});
|
||||
|
||||
test("should validate empty content array with default", () => {
|
||||
const toolResult = {};
|
||||
|
||||
const result = CallToolResultSchema.safeParse(toolResult);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data.content).toEqual([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue