mirror of
https://github.com/sortedcord/omnia.git
synced 2026-07-22 12:02:49 +05:30
feat(llm): Added Groq and Deepseek providers
This commit is contained in:
98
packages/llm/tests/deepseek.test.ts
Normal file
98
packages/llm/tests/deepseek.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { describe, test, expect, vi } from "vitest";
|
||||
import { z } from "zod";
|
||||
import { DeepSeekProvider } from "../src/providers/deepseek.js";
|
||||
import { llmConfig } from "../src/config.js";
|
||||
|
||||
// Mock the ChatDeepSeek class
|
||||
vi.mock("@langchain/deepseek", () => {
|
||||
return {
|
||||
ChatDeepSeek: class {
|
||||
config: unknown;
|
||||
constructor(config: unknown) {
|
||||
this.config = config;
|
||||
}
|
||||
withStructuredOutput = vi.fn().mockImplementation(() => {
|
||||
return {
|
||||
invoke: vi.fn().mockImplementation(async () => {
|
||||
return {
|
||||
parsed: {
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
},
|
||||
raw: {
|
||||
usage_metadata: {
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
total_tokens: 15,
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe("DeepSeekProvider Unit Tests (Tier 1)", () => {
|
||||
test("initializes successfully with a provided apiKey", () => {
|
||||
const provider = new DeepSeekProvider("dummy-key");
|
||||
expect(provider.providerName).toBe("DeepSeek");
|
||||
});
|
||||
|
||||
test("initializes successfully with apiKey from config", () => {
|
||||
const originalKey = llmConfig.DEEPSEEK_API_KEY;
|
||||
llmConfig.DEEPSEEK_API_KEY = "env-dummy-key";
|
||||
|
||||
try {
|
||||
const provider = new DeepSeekProvider();
|
||||
expect(provider.providerName).toBe("DeepSeek");
|
||||
} finally {
|
||||
llmConfig.DEEPSEEK_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("throws error if no API key is provided or in config", () => {
|
||||
const originalKey = llmConfig.DEEPSEEK_API_KEY;
|
||||
llmConfig.DEEPSEEK_API_KEY = undefined;
|
||||
|
||||
try {
|
||||
expect(() => new DeepSeekProvider()).toThrow(
|
||||
"DEEPSEEK_API_KEY is required to initialize DeepSeekProvider",
|
||||
);
|
||||
} finally {
|
||||
llmConfig.DEEPSEEK_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("generateStructuredResponse invokes the model with structured output, records usage and updates lastCalls", async () => {
|
||||
const provider = new DeepSeekProvider("dummy-key");
|
||||
const TestSchema = z.object({
|
||||
name: z.string(),
|
||||
success: z.boolean(),
|
||||
});
|
||||
|
||||
const response = await provider.generateStructuredResponse({
|
||||
systemPrompt: "system prompt",
|
||||
userContext: "user context",
|
||||
schema: TestSchema,
|
||||
});
|
||||
|
||||
expect(response.success).toBe(true);
|
||||
expect(response.data).toEqual({
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
});
|
||||
|
||||
expect(response.usage).toEqual({
|
||||
inputTokens: 10,
|
||||
outputTokens: 5,
|
||||
totalTokens: 15,
|
||||
modelName: "deepseek-chat",
|
||||
providerInstanceName: "Default",
|
||||
maxContext: 64000,
|
||||
});
|
||||
|
||||
expect(provider.lastCalls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
98
packages/llm/tests/groq.test.ts
Normal file
98
packages/llm/tests/groq.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { describe, test, expect, vi } from "vitest";
|
||||
import { z } from "zod";
|
||||
import { GroqProvider } from "../src/providers/groq.js";
|
||||
import { llmConfig } from "../src/config.js";
|
||||
|
||||
// Mock the ChatGroq class
|
||||
vi.mock("@langchain/groq", () => {
|
||||
return {
|
||||
ChatGroq: class {
|
||||
config: unknown;
|
||||
constructor(config: unknown) {
|
||||
this.config = config;
|
||||
}
|
||||
withStructuredOutput = vi.fn().mockImplementation(() => {
|
||||
return {
|
||||
invoke: vi.fn().mockImplementation(async () => {
|
||||
return {
|
||||
parsed: {
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
},
|
||||
raw: {
|
||||
usage_metadata: {
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
total_tokens: 15,
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe("GroqProvider Unit Tests (Tier 1)", () => {
|
||||
test("initializes successfully with a provided apiKey", () => {
|
||||
const provider = new GroqProvider("dummy-key");
|
||||
expect(provider.providerName).toBe("Groq");
|
||||
});
|
||||
|
||||
test("initializes successfully with apiKey from config", () => {
|
||||
const originalKey = llmConfig.GROQ_API_KEY;
|
||||
llmConfig.GROQ_API_KEY = "env-dummy-key";
|
||||
|
||||
try {
|
||||
const provider = new GroqProvider();
|
||||
expect(provider.providerName).toBe("Groq");
|
||||
} finally {
|
||||
llmConfig.GROQ_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("throws error if no API key is provided or in config", () => {
|
||||
const originalKey = llmConfig.GROQ_API_KEY;
|
||||
llmConfig.GROQ_API_KEY = undefined;
|
||||
|
||||
try {
|
||||
expect(() => new GroqProvider()).toThrow(
|
||||
"GROQ_API_KEY is required to initialize GroqProvider",
|
||||
);
|
||||
} finally {
|
||||
llmConfig.GROQ_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("generateStructuredResponse invokes the model with structured output, records usage and updates lastCalls", async () => {
|
||||
const provider = new GroqProvider("dummy-key");
|
||||
const TestSchema = z.object({
|
||||
name: z.string(),
|
||||
success: z.boolean(),
|
||||
});
|
||||
|
||||
const response = await provider.generateStructuredResponse({
|
||||
systemPrompt: "system prompt",
|
||||
userContext: "user context",
|
||||
schema: TestSchema,
|
||||
});
|
||||
|
||||
expect(response.success).toBe(true);
|
||||
expect(response.data).toEqual({
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
});
|
||||
|
||||
expect(response.usage).toEqual({
|
||||
inputTokens: 10,
|
||||
outputTokens: 5,
|
||||
totalTokens: 15,
|
||||
modelName: "llama-3.3-70b-versatile",
|
||||
providerInstanceName: "Default",
|
||||
maxContext: 8192,
|
||||
});
|
||||
|
||||
expect(provider.lastCalls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
135
packages/llm/tests/openai.test.ts
Normal file
135
packages/llm/tests/openai.test.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { describe, test, expect, vi } from "vitest";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
OpenAIProvider,
|
||||
OpenAIEmbeddingProvider,
|
||||
} from "../src/providers/openai.js";
|
||||
import { llmConfig } from "../src/config.js";
|
||||
|
||||
// Mock the ChatOpenAI and OpenAIEmbeddings classes
|
||||
vi.mock("@langchain/openai", () => {
|
||||
return {
|
||||
ChatOpenAI: class {
|
||||
config: unknown;
|
||||
constructor(config: unknown) {
|
||||
this.config = config;
|
||||
}
|
||||
withStructuredOutput = vi.fn().mockImplementation(() => {
|
||||
return {
|
||||
invoke: vi.fn().mockImplementation(async () => {
|
||||
return {
|
||||
parsed: {
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
},
|
||||
raw: {
|
||||
usage_metadata: {
|
||||
input_tokens: 10,
|
||||
output_tokens: 5,
|
||||
total_tokens: 15,
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
},
|
||||
OpenAIEmbeddings: class {
|
||||
config: unknown;
|
||||
constructor(config: unknown) {
|
||||
this.config = config;
|
||||
}
|
||||
embedQuery = vi.fn().mockImplementation(async (text: string) => {
|
||||
return [0.1, 0.2, 0.3];
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe("OpenAIProvider Unit Tests (Tier 1)", () => {
|
||||
test("initializes successfully with a provided apiKey", () => {
|
||||
const provider = new OpenAIProvider("dummy-key");
|
||||
expect(provider.providerName).toBe("OpenAI");
|
||||
});
|
||||
|
||||
test("initializes successfully with apiKey from config", () => {
|
||||
const originalKey = llmConfig.OPENAI_API_KEY;
|
||||
llmConfig.OPENAI_API_KEY = "env-dummy-key";
|
||||
|
||||
try {
|
||||
const provider = new OpenAIProvider();
|
||||
expect(provider.providerName).toBe("OpenAI");
|
||||
} finally {
|
||||
llmConfig.OPENAI_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("throws error if no API key is provided or in config", () => {
|
||||
const originalKey = llmConfig.OPENAI_API_KEY;
|
||||
llmConfig.OPENAI_API_KEY = undefined;
|
||||
|
||||
try {
|
||||
expect(() => new OpenAIProvider()).toThrow(
|
||||
"OPENAI_API_KEY is required to initialize OpenAIProvider",
|
||||
);
|
||||
} finally {
|
||||
llmConfig.OPENAI_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("generateStructuredResponse invokes the model with structured output, records usage and updates lastCalls", async () => {
|
||||
const provider = new OpenAIProvider("dummy-key");
|
||||
const TestSchema = z.object({
|
||||
name: z.string(),
|
||||
success: z.boolean(),
|
||||
});
|
||||
|
||||
const response = await provider.generateStructuredResponse({
|
||||
systemPrompt: "system prompt",
|
||||
userContext: "user context",
|
||||
schema: TestSchema,
|
||||
});
|
||||
|
||||
expect(response.success).toBe(true);
|
||||
expect(response.data).toEqual({
|
||||
name: "mocked response",
|
||||
success: true,
|
||||
});
|
||||
|
||||
expect(response.usage).toEqual({
|
||||
inputTokens: 10,
|
||||
outputTokens: 5,
|
||||
totalTokens: 15,
|
||||
modelName: "gpt-4o-mini",
|
||||
providerInstanceName: "Default",
|
||||
maxContext: 128000,
|
||||
});
|
||||
|
||||
expect(provider.lastCalls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("OpenAIEmbeddingProvider Unit Tests (Tier 1)", () => {
|
||||
test("initializes successfully with a provided apiKey", () => {
|
||||
const provider = new OpenAIEmbeddingProvider("dummy-key");
|
||||
expect(provider.providerName).toBe("OpenAI");
|
||||
});
|
||||
|
||||
test("initializes successfully with apiKey from config", () => {
|
||||
const originalKey = llmConfig.OPENAI_API_KEY;
|
||||
llmConfig.OPENAI_API_KEY = "env-dummy-key";
|
||||
|
||||
try {
|
||||
const provider = new OpenAIEmbeddingProvider();
|
||||
expect(provider.providerName).toBe("OpenAI");
|
||||
} finally {
|
||||
llmConfig.OPENAI_API_KEY = originalKey;
|
||||
}
|
||||
});
|
||||
|
||||
test("embed returns dummy array successfully", async () => {
|
||||
const provider = new OpenAIEmbeddingProvider("dummy-key");
|
||||
const result = await provider.embed("hello");
|
||||
expect(result).toEqual([0.1, 0.2, 0.3]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user