swift-agent
Version:
A building block of agentic systems: an LLM that can retrieve information, use tools, and store user inputs.
194 lines (172 loc) • 5.96 kB
text/typescript
import { describe, it, expect, beforeEach, vi } from "vitest";
import { FakeChatModel } from "@langchain/core/utils/testing";
import SwiftAgent from "../src/swift-agent";
vi.mock("@langchain/mcp-adapters", () => {
return {
MultiServerMCPClient: vi.fn().mockImplementation(() => {
return {
config: {
mcpServers: {
"test-mcp-server-1": {
command: "npx",
args: ["test-mcp-server-1"],
},
"test-mcp-server-2": {
command: "npx",
args: ["test-mcp-server-2"],
},
},
},
getTools: vi.fn().mockImplementation((serverName: string) => {
switch (serverName) {
case "test-mcp-server-1":
return [{ name: "test-tool-1" }, { name: "test-tool-2" }];
case "test-mcp-server-2":
return [{ name: "test-tool-3" }];
default:
return [];
}
}),
};
}),
};
});
describe("SwiftAgent", () => {
describe("Default Values", () => {
let llm: FakeChatModel;
let agent: SwiftAgent;
beforeEach(() => {
llm = new FakeChatModel({});
agent = new SwiftAgent(llm, {
mcp: {
mcpServers: {
"test-mcp-server-1": {
command: "npx",
args: ["test-mcp-server-1"],
},
"test-mcp-server-2": {
command: "npx",
args: ["test-mcp-server-2"],
},
},
},
});
});
it("should default throwOnLoadError to true when mcp options are provided without it", () => {
expect(agent.options?.mcp?.throwOnLoadError).toBe(true);
});
it("should default prefixToolNameWithServerName to true when mcp options are provided without it", () => {
expect(agent.options?.mcp?.prefixToolNameWithServerName).toBe(true);
});
it("should default additionalToolNamePrefix to 'mcp' when mcp options are provided without it", () => {
expect(agent.options?.mcp?.additionalToolNamePrefix).toBe("mcp");
});
});
describe("run", () => {
let llm: FakeChatModel;
let agent: SwiftAgent;
beforeEach(async () => {
llm = new FakeChatModel({});
agent = new SwiftAgent(llm, {
mcp: {
mcpServers: {
"test-mcp-server-1": {
command: "npx",
args: ["test-mcp-server-1"],
},
"test-mcp-server-2": {
command: "npx",
args: ["test-mcp-server-2"],
},
},
},
});
await agent.run("hi");
});
it("should load tools from MCP client", () => {
expect(agent.tools).toHaveLength(3);
expect(agent.tools?.find(tool => tool.name === "test-tool-1")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-2")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-3")?.isEnabled).toBe(true);
});
});
describe("setModel", () => {
let llm: FakeChatModel;
let agent: SwiftAgent;
beforeEach(() => {
llm = new FakeChatModel({});
agent = new SwiftAgent(llm);
});
it("should update the internal model", () => {
const newLlm = new FakeChatModel({});
agent.setModel(newLlm);
expect(agent.model).toBe(newLlm);
});
});
describe("enableMcpServer", () => {
let llm: FakeChatModel;
let agent: SwiftAgent;
beforeEach(async () => {
llm = new FakeChatModel({});
agent = new SwiftAgent(llm, {
mcp: {
mcpServers: {
"test-mcp-server-1": {
command: "npx",
args: ["test-mcp-server-1"],
},
"test-mcp-server-2": {
command: "npx",
args: ["test-mcp-server-2"],
},
},
},
});
await agent.run("hi");
});
it("should enable an MCP server by name", () => {
agent.disableMcpServer("test-mcp-server-2");
expect(agent.tools?.find(tool => tool.name === "test-tool-1")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-2")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-3")?.isEnabled).toBe(false);
agent.enableMcpServer("test-mcp-server-2");
expect(agent.tools?.find(tool => tool.name === "test-tool-1")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-2")?.isEnabled).toBe(true);
expect(agent.tools?.find(tool => tool.name === "test-tool-3")?.isEnabled).toBe(true);
});
it("should not throw error if server name does not exist", () => {
expect(() => agent.enableMcpServer("non-existent-server")).not.toThrow();
});
});
describe("disableMcpServer", () => {
let llm: FakeChatModel;
let agent: SwiftAgent;
beforeEach(async () => {
llm = new FakeChatModel({});
agent = new SwiftAgent(llm, {
mcp: {
mcpServers: {
"test-mcp-server-1": {
command: "npx",
args: ["test-mcp-server-1"],
},
"test-mcp-server-2": {
command: "npx",
args: ["test-mcp-server-2"],
},
},
},
});
await agent.run("hi");
});
it("should disable an MCP server by name", () => {
agent.disableMcpServer("test-mcp-server-1");
expect(agent.tools?.find(tool => tool.name === "test-tool-1")?.isEnabled).toBe(false);
expect(agent.tools?.find(tool => tool.name === "test-tool-2")?.isEnabled).toBe(false);
expect(agent.tools?.find(tool => tool.name === "test-tool-3")?.isEnabled).toBe(true);
});
it("should not throw error if server name does not exist", () => {
expect(() => agent.disableMcpServer("non-existent-server")).not.toThrow();
});
});
});