Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/with-peaka-mcp/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OPENAI_API_KEY=your_openai_api_key
PEAKA_API_KEY=your_peaka_api_key
3 changes: 3 additions & 0 deletions examples/with-peaka-mcp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
dist
.DS_Store
53 changes: 53 additions & 0 deletions examples/with-peaka-mcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div align="center">
<a href="https://voltagent.dev/">
<img width="1800" alt="435380213-b6253409-8741-462b-a346-834cd18565a9" src="https://github.com/user-attachments/assets/452a03e7-eeda-4394-9ee7-0ffbcf37245c" />
</a>

<br/>
<br/>

<div align="center">
<a href="https://voltagent.dev">Home Page</a> |
<a href="https://voltagent.dev/docs/">Documentation</a> |
<a href="https://github.com/voltagent/voltagent/tree/main/examples">Examples</a> |
<a href="https://s.voltagent.dev/discord">Discord</a> |
<a href="https://voltagent.dev/blog/">Blog</a>
</div>
</div>

<br/>

<div align="center">
<strong>VoltAgent is an open source TypeScript framework for building and orchestrating AI agents.</strong><br>
Escape the limitations of no-code builders and the complexity of starting from scratch.
<br />
<br />
</div>

<div align="center">

[![npm version](https://img.shields.io/npm/v/@voltagent/core.svg)](https://www.npmjs.com/package/@voltagent/core)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
[![Discord](https://img.shields.io/discord/1361559153780195478.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://s.voltagent.dev/discord)
[![Twitter Follow](https://img.shields.io/twitter/follow/voltagent_dev?style=social)](https://twitter.com/voltagent_dev)

</div>

<br/>

<div align="center">
<a href="https://voltagent.dev/">
<img width="896" alt="Screenshot 2025-04-20 at 22 44 38" src="https://github.com/user-attachments/assets/f0627868-6153-4f63-ba7f-bdfcc5dd603d" />
</a>

</div>

## VoltAgent: Build AI Agents Fast and Flexibly

VoltAgent is an open-source TypeScript framework for creating and managing AI agents. It provides modular components to build, customize, and scale agents with ease. From connecting to APIs and memory management to supporting multiple LLMs, VoltAgent simplifies the process of creating sophisticated AI systems. It enables fast development, maintains clean code, and offers flexibility to switch between models and tools without vendor lock-in.

## Try Example

```bash
npm create voltagent-app@latest -- --example with-peaka-mcp
```
30 changes: 30 additions & 0 deletions examples/with-peaka-mcp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "voltagent-example-with-peaka-mcp",
"private": true,
"keywords": [
"voltagent",
"ai",
"agent"
],
"license": "MIT",
"author": "",
"type": "module",
"scripts": {
"build": "tsc",
"dev": "tsx watch --env-file=.env ./src -- --trace-warnings",
"start": "node dist/index.js",
"volt": "volt"
},
"dependencies": {
"@ai-sdk/openai": "^1.3.10",
"@voltagent/cli": "^0.1.3",
"@voltagent/core": "^0.1.6",
"@voltagent/vercel-ai": "^0.1.3",
"zod": "^3.24.2"
},
"devDependencies": {
"@types/node": "^22.13.5",
"tsx": "^4.19.3",
"typescript": "^5.8.2"
}
}
34 changes: 34 additions & 0 deletions examples/with-peaka-mcp/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { VoltAgent, Agent, MCPConfiguration } from "@voltagent/core";
import { VercelAIProvider } from "@voltagent/vercel-ai";

import { openai } from "@ai-sdk/openai";

const mcp = new MCPConfiguration({
id: "peaka-mcp",
servers: {
peaka: {
type: "stdio",
command: "npx",
args: ["-y", "@peaka/mcp-server-peaka@latest"],
env: { PEAKA_API_KEY: process.env.PEAKA_API_KEY || "" },
},
},
});

(async () => {
const tools = await mcp.getTools();
const agent = new Agent({
name: "Peaka Data Assistant",
description: "An assistant that can query Peaka's sample data.",
llm: new VercelAIProvider(),
model: openai("gpt-4o-mini"),
tools: [...tools],
markdown: true,
});

new VoltAgent({
agents: {
agent,
},
});
})();
14 changes: 14 additions & 0 deletions examples/with-peaka-mcp/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"outDir": "dist",
"skipLibCheck": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
31 changes: 16 additions & 15 deletions packages/google-ai/src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,37 +152,38 @@ describe("GoogleGenAIProvider", () => {
yield { text: "Hello", responseId: "chunk1" };
yield { text: ", ", responseId: "chunk2" };
yield { text: "world!", responseId: "chunk3", candidates: [{ finishReason: "STOP" }] };
yield {
text: "", responseId: "final",
yield {
text: "",
responseId: "final",
usageMetadata: {
promptTokenCount: 5,
candidatesTokenCount: 15,
totalTokenCount: 20
}
totalTokenCount: 20,
},
};
}

const mockGenerateContentStream = jest.fn().mockResolvedValue(mockGenerator());

const provider = new GoogleGenAIProvider({ apiKey: "test-api-key" });
(provider as any).ai.models.generateContentStream = mockGenerateContentStream;

const onChunkMock = jest.fn();
const onStepFinishMock = jest.fn();

const result = await provider.streamText({
messages: [{ role: "user", content: "Hello!" }],
model: "gemini-2.0-flash-001",
onChunk: onChunkMock,
onStepFinish: onStepFinishMock
onStepFinish: onStepFinishMock,
});

expect(result.textStream).toBeInstanceOf(ReadableStream);

// Read all chunks from the stream
const reader = result.textStream.getReader();
const chunks = [];

let done = false;
while (!done) {
const { value, done: isDone } = await reader.read();
Expand All @@ -192,9 +193,9 @@ describe("GoogleGenAIProvider", () => {
chunks.push(value);
}
}

expect(chunks).toEqual(["Hello", ", ", "world!"]);

expect(onChunkMock).toHaveBeenCalledTimes(3);
expect(onStepFinishMock).toHaveBeenCalledTimes(1);
expect(onStepFinishMock).toHaveBeenCalledWith({
Expand All @@ -205,8 +206,8 @@ describe("GoogleGenAIProvider", () => {
usage: {
promptTokens: 5,
completionTokens: 15,
totalTokens: 20
}
totalTokens: 20,
},
});
});
});
Expand Down
28 changes: 28 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading