diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md index 6024c27..511a3e1 100644 --- a/CONTRIBUTION.md +++ b/CONTRIBUTION.md @@ -85,7 +85,7 @@ The kagent website includes a blog section where we post about kagent. If you'd - Posts should focus on the open source kagent project and not vendor specific projects or products - Any submitted blog posts must be original content and not a copy of existing blog posts -### Submitting a blog post +### Writing a new blog post on kagent 1. Create your blog post in `src/blogContent` folder. You can copy an existing blog post and modify it. 2. Make sure you add the following metadata at the top of your blog post - update the title, published date, description, author, and authorIds accordingly. @@ -124,6 +124,10 @@ If you need to add a new author, you can do that in the [authors.ts file](https: 4. All images can be added to the public/images folder. +### Adding an existing blog post + +To add an existing blog post, you can add a new entry into the `external-blog-posts.yaml` file. Same guidelines as above apply. + ## Style Guide - Follow the existing code style diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index 30a91c7..ee0be0b 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -1,6 +1,13 @@ import { Background } from "@/components/background"; import Link from "next/link"; import React from "react"; +import externalPostsData from "@/data/external-blog-posts.yaml"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { getAuthorById, type Author } from "./authors"; +import { DISCORD_LINK, GITHUB_LINK } from "@/data/links"; +import Discord from "@/components/icons/discord"; +import Github from "@/components/icons/github"; function shortDate(date: string) { return new Date(date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); @@ -12,33 +19,61 @@ const posts = [ publishDate: '2025-09-09', title: "Truly Reactive Cloud Native AI Agents with Kagent and Khook", description: "Khook makes Kagent Agents Reactive", + authorId: "antweiss", }, { slug: 'ai-reliability-aire', publishDate: '2025-05-14', title: 'AI Reliability Engineering For More Dependable Humans', description: 'AI Reliability Engineering (AIRE) brings AI agents to SRE and Platform Engineering workflows for dependable humans.', + authorId: "christianposta", }, { slug: 'kgateway-guardrails', publishDate: '2025-05-19', title: 'Adding Guardrails to kagent with kgateway AI Gateway', description: 'Adding guardrails, observability, and security to Agent to LLM communication with an AI gateway like kgateway', + authorId: "christianposta", }, { slug: 'kagent-celebrating-100-days', publishDate: '2025-07-01', title: 'Celebrating 100 Days of Kagent', description: '100+ contributors, 1000+ GitHub stars and more!', + authorId: "linsun", }, { slug: 'kmcp', publishDate: '2025-07-30', title: 'From MCP Servers to Services: Introducing kmcp for Enterprise-Grade MCP Development', description: 'Discover kmcp, the lightweight toolkit that takes MCP servers from prototype to production. Learn how to scaffold, build, and deploy enterprise-grade MCP services to Kubernetes in minutes—no Dockerfiles or complex manifests required. Includes demo video and complete getting started guide.', + authorId: "christianposta", } ] +type InternalPostCombined = { + title: string; + description: string; + publishDate: string; + href: string; + isExternal: false; + slug: string; + author: Author | null; +} + +type ExternalPostCombined = { + title: string; + description: string; + publishDate: string; + href: string; + isExternal: true; + author: string; // Keep as string for external posts since they're not in our authors.ts +} + +type CombinedPost = InternalPostCombined | ExternalPostCombined; + +type ExternalYamlPost = { title: string; description: string; publishDate: string; url: string; author: string }; + export default async function BlogPage() { return ( <> @@ -47,20 +82,81 @@ export default async function BlogPage() {

Blog

- {posts.sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime()).map((post) => ( -
-
- {shortDate(post.publishDate)} -
-
- {post.title} + {(() => { + const internalPosts: InternalPostCombined[] = posts.map(p => ({ + title: p.title, + description: p.description, + publishDate: p.publishDate, + href: `/blog/${p.slug}`, + isExternal: false as const, + slug: p.slug, + author: getAuthorById(p.authorId) || null, + })); + const rawExternal: ExternalYamlPost[] = (externalPostsData && (externalPostsData as { externalPosts?: ExternalYamlPost[] }).externalPosts) || []; + const externalPosts: ExternalPostCombined[] = rawExternal.map((p: ExternalYamlPost) => ({ + title: p.title, + description: p.description, + publishDate: p.publishDate, + href: p.url, + isExternal: true as const, + author: p.author, + })); + const allPosts: CombinedPost[] = [...internalPosts, ...externalPosts].sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime()); + return allPosts.map((post) => ( +
+
+ {shortDate(post.publishDate)} + {post.isExternal && External} +
+
+ {post.isExternal ? ( + {post.title} + ) : ( + {post.title} + )} +
+
+ by {post.isExternal ? post.author : post.author ? `${post.author.name}, ${post.author.title}` : 'Unknown Author'} +
+

{post.description}

+ {post.isExternal ? ( + + Read the post + + ) : ( + + Read the post + + )}
-

{post.description}

- - Read the post + )); + })()} +
+
+ + {/* Community Section */} +
+
+

+ Join our community +

+

+ Connect with other developers, share your experiences, and get support from the kagent community. +

+
+ +
- ))} + +
diff --git a/src/data/external-blog-posts.yaml b/src/data/external-blog-posts.yaml new file mode 100644 index 0000000..80c5c0b --- /dev/null +++ b/src/data/external-blog-posts.yaml @@ -0,0 +1,21 @@ +# External blog posts displayed on the blog index alongside internal posts +# Fields: title, description, publishDate (YYYY-MM-DD), url, author +externalPosts: + - title: "KAgent: Open-Source Agentic AI Framework for Autonomous Systems" + description: "KAgent is an open-source framework for building autonomous AI agents that can make decisions and perform tasks with minimal human oversight. Donated by Solo.io, it enables developers to create intelligent systems for virtual assistance, data processing, and workflow automation by leveraging generative AI and external API integrations." + publishDate: "2025-05-19" + url: "https://medium.com/@godhanipayal/kagent-open-source-agentic-ai-framework-for-autonomous-systems-cfde34a80742" + author: "Payal Godhani" + - title: "An Introduction to Kagent: The Open-Source Framework for AI Agents on Kubernetes" + description: "The article talks about how kagent democratizes cloud-native expertise by packaging expert knowledge into AI agents that can troubleshoot, diagnose, and automatically fix Kubernetes issues, demonstrated through a real-world example where an agent identified and resolved a misconfigured service routing problem by creating a GitHub pull request." + publishDate: "2025-08-15" + url: "https://www.platformers.community/post/an-introduction-to-kagent-the-open-source-framework-for-ai-agents-on-kubernetes" + author: "Guy Menahem" + - title: "Exploring Argocd’s New Mcp Server With Kagent" + description: "This technical walkthrough demonstrates how to integrate ArgoCD's new MCP (Model Context Protocol) Server with kagent, an AI agent framework for Kubernetes. The author shows step-by-step how to deploy kagent via ArgoCD, configure it with OpenAI integration, add ArgoCD's MCP server as a tool, and create an AI agent that can directly query and interact with ArgoCD applications - showcasing the potential for intelligent Kubernetes operations through AI-powered automation." + publishDate: "2025-05-08" + url: "https://chrismatcham.dev/Exploring-ArgoCD-s-New-MCP-Server-with-Kagent/" + author: "Chris Matcham" + + +