Skip to content

Commit

Permalink
feat: finished the example app
Browse files Browse the repository at this point in the history
  • Loading branch information
xdotli authored and tonyxiao committed Dec 3, 2023
1 parent ae06093 commit dde7be8
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 102 deletions.
2 changes: 1 addition & 1 deletion docs/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ void venice.GET('/core/resource').then((r) => console.log(r.data))

void apollo.GET('/v1/email_accounts').then((r) => console.log(r.data))

apollo.hello
apollo.hello
58 changes: 58 additions & 0 deletions examples/sum-pr/src/app/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use server'

import {initSDK} from '@opensdks/core'
import {githubSdkDef, type githubTypes} from '@opensdks/sdk-github'
import {openaiSdkDef} from '@opensdks/sdk-openai'

type Commit = githubTypes['components']['schemas']['commit']

const github = initSDK(githubSdkDef, {
headers: {
Authorization: `Bearer ${process.env['GITHUB_TOKEN']}`,
'X-GitHub-Api-Version': '2022-11-28',
},
})

export async function fetchCommits(prLink: string) {
const prUrl = new URL(prLink)
const [, owner, repo, , prNumber] = prUrl.pathname.split('/')

return github
.GET('/repos/{owner}/{repo}/pulls/{pull_number}/commits', {
params: {
path: {owner, repo, pull_number: Number(prNumber)},
},
})
.then((r) => r.data)
}

const apiKey = process.env['OPENAI_API_KEY']

const openai = initSDK(openaiSdkDef, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
})

export const summarizeCommits = async (commits: Commit[]) => {
const messages = commits.map((commit) => commit.commit.message).join('\n')
const prompt = `I have a list of software commit messages and need a summary of the changes. Here are the commit messages:\n${messages}\nCan you provide a summary?`

try {
const response = await openai.POST('/chat/completions', {
body: {
model: 'gpt-3.5-turbo',
max_tokens: 1000,
messages: [
{role: 'system', content: prompt},
{role: 'user', content: messages},
],
},
})
return response.data.choices[0].message.content
} catch (err) {
console.error('Error summarizing commits:', err)
throw err
}
}
12 changes: 4 additions & 8 deletions examples/sum-pr/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import type {Metadata} from 'next'
import {Inter} from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })
const inter = Inter({subsets: ['latin']})

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
export default function RootLayout({children}: {children: React.ReactNode}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
Expand Down
113 changes: 40 additions & 73 deletions examples/sum-pr/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
'use client'

/**
* v0 by Vercel.
* @see https://v0.dev/t/yL79BMw9qDt
*/
import Link from 'next/link'
import {ChangeEvent, useState} from 'react'
import {initSDK} from '@opensdks/core'
import {githubSdkDef} from '@opensdks/sdk-github'
import {openaiSdkDef} from '@opensdks/sdk-openai'
import type {githubTypes} from '@opensdks/sdk-github'
import CommitsList from '@/components/CommitsList'
// shadcn imports
import {Button} from '@/components/ui/button'
import {
Card,
Expand All @@ -21,100 +13,75 @@ import {
} from '@/components/ui/card'
import {Input} from '@/components/ui/input'
import {Label} from '@/components/ui/label'
import {fetchCommits, summarizeCommits} from './actions'

const apiKey = process.env['OPENAI_API_KEY']

export const github = initSDK(githubSdkDef, {
headers: {
Authorization: `Bearer ${process.env['GITHUB_TOKEN']}`,
'X-GitHub-Api-Version': '2022-11-28',
},
})

export const openai = initSDK(openaiSdkDef, {
// headers: {
// 'Content-Type': 'application/json',
// Authorization: `Bearer ${apiKey}`,
// },
})
type Commit = githubTypes['components']['schemas']['commit']

export default function Component() {
const [commits, setCommits] = useState<Commit[]>([])
const [prLink, setPrLink] = useState('')
const [commits, setCommits] = useState([])
const [summary, setSummary] = useState('')

const handlePRLinkChange = (event: ChangeEvent<HTMLInputElement>) => {
setPrLink(event.target.value)
}

const fetchCommits = async () => {
const prUrl = new URL(prLink)
const pathParts = prUrl.pathname.split('/') // Splitting the pathname to extract owner, repo, and PR number
const owner = pathParts[1]
const repo = pathParts[2]
const prNumber = pathParts[4]
// "/repos/{owner}/{repo}/pulls/{pull_number}/comments"
try {
const response = await github.GET(
'/repos/{owner}/{repo}/pulls/{pull_number}/commits',
{
params: {
path: {owner, repo, pull_number: Number(prNumber)},
},
},
)
setCommits(response.data as never)
} catch (err) {
console.error('Error fetching commits:', err)
}
}
const [summary, setSummary] = useState<string | null>('')

return (
<div className="flex flex-col w-full min-h-screen p-10">
<div className="flex flex-col w-md min-h-screen p-10">
<div className="max-w-3xl mx-auto">
<h1 className="text-3xl font-bold mb-6">GitHub PR Summary</h1>
<p className="text-gray-500 dark:text-gray-400 mb-6">
Enter a GitHub PR link to view a summary of the commits.
</p>
<div className="space-y-4">
<form
className="space-y-4"
action={async (formData: FormData) => {
const prLink = formData.get('pr-link') as string
if (!prLink) {
return
}
const fetchedCommits = await fetchCommits(prLink)
setCommits(fetchedCommits)
const summary = await summarizeCommits(fetchedCommits)
setSummary(summary)
}}>
<div className="space-y-2">
<Label htmlFor="pr-link">Pull Request Link</Label>
<Input
id="pr-link"
name="pr-link"
placeholder="https://github.com/user/repo/pull/123"
value={prLink}
onChange={handlePRLinkChange}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
setPrLink(e.target.value)
}}
required
/>
</div>
<Button
className="w-full bg-primary text-primary-foreground hover:bg-primary/90"
type="submit"
onClick={fetchCommits}>
type="submit">
Analyze
</Button>
</div>
<Card className="mt-8">
<CardHeader>
<CardTitle className="text-xl">Summarized Commits</CardTitle>
<CardDescription>
A brief summary of all commits generated by OpenAI
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-gray-500 dark:text-gray-400 text-sm">
OpenAI generated commit summary goes here...
</p>
</CardContent>
</form>
<Card className="mt-8 max-w-md">
<div className="">
<CardHeader>
<CardTitle className="text-xl">Summarized Commits</CardTitle>
<CardDescription>
A brief summary of all commits generated by OpenAI
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-gray-500 dark:text-gray-400 text-sm break-words">
{summary || 'OpenAI generated commit summary goes here...'}
</p>
</CardContent>
</div>
</Card>
<Card className="mt-8">
<Card className="mt-8 max-w-md">
<CardHeader>
<CardTitle className="text-xl">Commits Summary</CardTitle>
<CardDescription>
List of commits for the provided GitHub PR
</CardDescription>
</CardHeader>
<CardContent>
<CardContent className="">
<CommitsList commits={commits} />
</CardContent>
</Card>
Expand Down
25 changes: 5 additions & 20 deletions examples/sum-pr/src/components/CommitsList.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,19 @@
import Link from 'next/link'
import {type githubTypes} from '@opensdks/sdk-github'
import {Avatar, AvatarFallback, AvatarImage} from '@/components/ui/avatar'
import {Badge} from '@/components/ui/badge'

interface Commit {
sha: string
commit: {
author: {
name: string
email: string
date: string
}
message: string
}
author?: {
login: string
avatar_url: string
}
html_url: string
}

type Commit = githubTypes['components']['schemas']['commit']
interface CommitsListProps {
commits: Commit[]
}

const CommitsList: React.FC<CommitsListProps> = ({commits}) => (
<div className="space-y-4">
<div className="space-y-4 max-w-full">
{commits.map((commit, index) => (
<div key={index}>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
{/* Avatar and User Info */}
<Avatar>
<AvatarImage
alt="User Avatar"
Expand All @@ -38,14 +22,15 @@ const CommitsList: React.FC<CommitsListProps> = ({commits}) => (
<AvatarFallback>{commit.author?.login.charAt(0)}</AvatarFallback>
</Avatar>
<div>
<h2 className="text-lg">{commit.commit.author.name}</h2>
<h2 className="text-lg">{commit.commit.author?.name}</h2>
<Badge variant="outline">{commit.sha.slice(0, 7)}</Badge>
</div>
</div>
<Link className="underline text-right" href={commit.html_url}>
View Commit
</Link>
</div>

<p className="text-sm text-gray-500 dark:text-gray-400">
{commit.commit.message}
</p>
Expand Down

1 comment on commit dde7be8

@vercel
Copy link

@vercel vercel bot commented on dde7be8 Dec 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

opensdks – ./

opensdks-venice.vercel.app
opensdks-git-main-venice.vercel.app
opensdks.vercel.app
opensdks.org

Please sign in to comment.