Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

👌 IMPROVE: Career prep coach updated with memory ui #52

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4cec7b1
gitignore
AIENGINE Jul 25, 2024
d91d1fd
added env example file
AIENGINE Jul 25, 2024
4e74c81
updated image, pipelinks, code blocks, bullet points for career-prep-…
AIENGINE Jul 25, 2024
d1d07e4
updated metadata for career-prep-coach chatbot
AIENGINE Jul 25, 2024
52d7fa7
update package name for career-prep-coach chatbot
AIENGINE Jul 25, 2024
3c4dd42
updated opening comp for career-prep-coach
AIENGINE Jul 25, 2024
2c50dc9
updated header comp for career-prep-coach
AIENGINE Jul 25, 2024
1d1ba8b
nextjs chat ui
AIENGINE Jul 25, 2024
ed8c706
update route for handling update and create memory
AIENGINE Aug 7, 2024
7d317e5
integrated Memory sidenav comp
AIENGINE Aug 7, 2024
8f889d6
memory comp
AIENGINE Aug 7, 2024
7a5427c
updated comp name
AIENGINE Aug 9, 2024
b71194f
updated comp name
AIENGINE Aug 9, 2024
6f71271
ownerLogin from env var
AIENGINE Aug 9, 2024
d5688d4
corrected button rendering issues
AIENGINE Aug 9, 2024
7ae942a
adjusted button styles
AIENGINE Aug 9, 2024
478f748
removed console logs
AIENGINE Aug 9, 2024
039b8c1
removed console logs
AIENGINE Aug 9, 2024
e576498
remove memory sidbar from main chatbot page
AIENGINE Aug 9, 2024
e9c4cdf
adjust MemorySidebar comp flex to fit popover
AIENGINE Aug 9, 2024
1d08688
integrated memsidebar comp in promp form comp
AIENGINE Aug 9, 2024
a60c25c
added popover comp
AIENGINE Aug 9, 2024
bf7d065
added popover shadcn
AIENGINE Aug 9, 2024
8da613e
added memsidebar description
AIENGINE Aug 9, 2024
5b53095
added space and gap for popover
AIENGINE Aug 9, 2024
de52eda
remove unsed modules
AIENGINE Aug 12, 2024
4695fff
updated gitignore
AIENGINE Aug 12, 2024
d9cef8f
added state to main chat component to persist memory
AIENGINE Aug 20, 2024
ed0a9ea
propagate memset state
AIENGINE Aug 20, 2024
4dee1b3
propagate memset state
AIENGINE Aug 20, 2024
4f396f6
updated mem attach and added mem set fetch
AIENGINE Aug 20, 2024
a43c9be
memory comp
AIENGINE Aug 20, 2024
a29661f
select comp
AIENGINE Aug 20, 2024
b44a94e
updated packages
AIENGINE Aug 20, 2024
99aed44
update route to handle user api key from frontend
AIENGINE Aug 20, 2024
a55fee9
propagate userapikey prop
AIENGINE Aug 20, 2024
5dcca4c
propagate userapikey prop
AIENGINE Aug 20, 2024
8aee22e
added userapi key state to persist
AIENGINE Aug 20, 2024
3d44aa8
added save api key button and userapi state change
AIENGINE Aug 20, 2024
c9e5225
updated nextjs package
AIENGINE Aug 20, 2024
71273cb
propagate owner login
AIENGINE Aug 20, 2024
65b45a7
propagate owner login
AIENGINE Aug 20, 2024
2464af7
propagate owner login
AIENGINE Aug 20, 2024
c3a83de
propagate owner login
AIENGINE Aug 20, 2024
27d2c11
propagate owner login
AIENGINE Aug 20, 2024
2a77bcb
updated gitignore
AIENGINE Aug 20, 2024
a04d909
Updated readme links and text
AIENGINE Oct 23, 2024
d0d99a5
update var in env example
AIENGINE Oct 23, 2024
46df356
updated package for career-prep-coach-example
AIENGINE Oct 23, 2024
a68ee1c
updated readme
AIENGINE Oct 23, 2024
138728d
fixed memory selection bug, fixed pipe backend to career-prep-coach-e…
AIENGINE Oct 23, 2024
b878e92
Integrated suggestions comp
AIENGINE Oct 23, 2024
b270b59
updated link in header comp
AIENGINE Oct 23, 2024
22ce130
update opening comp
AIENGINE Oct 23, 2024
5423560
add conversation tips to the career-prep-coach-example
AIENGINE Oct 23, 2024
fef4a04
added suggestions comp
AIENGINE Oct 23, 2024
2e5d378
added hovercard comp
AIENGINE Oct 23, 2024
89783ef
Merge branch 'main' into career-prep-coach-updated
AIENGINE Oct 23, 2024
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
3 changes: 2 additions & 1 deletion examples/career-prep-coach/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
NEXT_LB_PIPE_API_KEY=""
LANGBASE_PIPE_API_KEY=""

4 changes: 2 additions & 2 deletions examples/career-prep-coach/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ To get started with Langbase, you'll need to [create a free personal account on
6. Add the following environment variables (.env.local):
```
# Replace `PIPE_API_KEY` with the copied API key.
NEXT_LB_PIPE_API_KEY="PIPE_API_KEY"
LANGBASE_PIPE_API_KEY="PIPE_API_KEY"
```

7. Issue the following in your CLI:
Expand Down Expand Up @@ -65,7 +65,7 @@ This project is created by [Langbase][lb] team members, with contributions from:

[demo]: https://career-prep-coach.langbase.dev
[lb]: https://langbase.com
[pipe]: https://beta.langbase.com/examples/career-prep-coach
[pipe]: https://langbase.com/examples/career-prep-coach
[gh]: https://github.com/LangbaseInc/langbase-examples/tree/main/examples/career-prep-coach
[cover]:https://raw.githubusercontent.com/LangbaseInc/docs-images/main/examples/career-prep-coach/career-prep-coach.png
[download]:https://download-directory.github.io/?url=https://github.com/LangbaseInc/langbase-examples/tree/main/examples/career-prep-coach
Expand Down
21 changes: 14 additions & 7 deletions examples/career-prep-coach/app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export async function POST(req: Request) {
}


if (!process.env.NEXT_LB_PIPE_API_KEY) {
if (!process.env.LANGBASE_PIPE_API_KEY) {
throw new Error(
'Please set NEXT_LB_PIPE_API_KEY in your environment variables.'
'Please set LANGBASE_PIPE_API_KEY in your environment variables.'
)
}

Expand All @@ -39,14 +39,14 @@ export async function POST(req: Request) {
} else if (action === 'getMemorySets') {
return handleGetMemorySets(userApiKey)
} else if (action === 'updatePipe') {
const { memoryName } = await req.json()
const { memoryName } = body;
return updatePipe(ownerLogin, memoryName, userApiKey)
} else {
const endpointUrl = 'https://api.langbase.com/beta/chat'

const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.NEXT_LB_PIPE_API_KEY}`
Authorization: `Bearer ${process.env.LANGBASE_PIPE_API_KEY}`
}

// Get chat prompt messages and threadId from the client.
Expand Down Expand Up @@ -153,11 +153,18 @@ async function handleFileUpload(req: Request, userApiKey: string, ownerLogin: st
}

async function updatePipe(ownerLogin: string | undefined, memoryName: string, userApiKey: string) {
const url = `https://api.langbase.com/beta/pipes/${ownerLogin}/shoes-expert`;

if (!ownerLogin || !memoryName || !userApiKey) {
return new Response(JSON.stringify({ error: 'Missing required parameters' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
const url = `https://api.langbase.com/beta/pipes/${ownerLogin}/career-prep-coach`;

const pipe = {
name: "shoes-expert",
description: "An AI-powered shoe expert that recommends Nike and Adidas footwear based on customer preferences and provides personalized shopping assistance.",
name: "career-prep-coach",
description: "Your AI-powered personal interview coach, expertly preparing you for success using proven techniques and tailored feedback.",
status: "private",
config: {
memorysets: [memoryName]
Expand Down
25 changes: 24 additions & 1 deletion examples/career-prep-coach/components/chatbot-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useState, useCallback } from 'react'
import { toast } from 'sonner'
import { ChatInput } from './chat-input'
import { Opening } from './opening'
import { Suggestions } from './suggestions'

export interface ChatProps extends React.ComponentProps<'div'> {
id?: string // Optional: Thread ID if you want to persist the chat in a DB
Expand Down Expand Up @@ -38,10 +39,24 @@ export function Chatbot({ id, initialMessages, className }: ChatProps) {
})

const fetchMemorySets = useCallback(async () => {

if (!userApiKey || !ownerLogin) {
toast.error('Please set both API Key and Owner Login first');
return;
}
try {
const response = await fetch('/api/chat?action=getMemorySets', {
method: 'POST',
body: JSON.stringify({ userApiKey, ownerLogin })
body: JSON.stringify({ userApiKey, ownerLogin,
pipe: {
name: "career-prep-coach",
description: "Your AI-powered personal interview coach",
status: "private",
config: {
memorysets: [] // This will be populated when memory is selected
},
}
})
})
if (!response.ok) throw new Error('Failed to fetch memory sets')
const data = await response.json()
Expand All @@ -59,6 +74,11 @@ export function Chatbot({ id, initialMessages, className }: ChatProps) {
const handleMemorySelect = useCallback((memoryUrl: string) => {
setSelectedMemory(memoryUrl)
}, [])

const sendSuggestedPrompt = (prompt: string) => {
setInput(prompt)
}


return (
<div className="min-h-screen">
Expand All @@ -68,7 +88,10 @@ export function Chatbot({ id, initialMessages, className }: ChatProps) {
<ChatList messages={messages} />
</>
) : (
<>
<Opening />
<Suggestions sendSuggestedPrompt={sendSuggestedPrompt} />
</>
)}
<ChatInput
id={id}
Expand Down
2 changes: 1 addition & 1 deletion examples/career-prep-coach/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function Header() {
</a>
<a
target="_blank"
href="https://beta.langbase.com/examples/career-prep-coach"
href="https://langbase.com/examples/career-prep-coach"
rel="noopener noreferrer"
className={cn(buttonVariants({ variant: 'default' }))}
>
Expand Down
4 changes: 2 additions & 2 deletions examples/career-prep-coach/components/opening.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function Opening() {
<Link
target="_blank"
className="underline hover:text-indigo-400 mb-2"
href="https://beta.langbase.com/examples/career-prep-coach"
href="https://langbase.com/examples/career-prep-coach"
>
<span className="font-bold">pipe on ⌘ Langbase</span>
</Link>
Expand All @@ -31,7 +31,7 @@ export function Opening() {
<div className="mt-4 flex flex-col gap-4 text-sm [&>p]:my-0 [&>p]:py-0">
<p>Learn more by checking out:</p>
<div className="flex flex-col gap-4 mt-2 text-sm">
<Dlink href="https://beta.langbase.com/examples/career-prep-coach">
<Dlink href="https://langbase.com/examples/career-prep-coach">
<span>1.</span>
<span>Fork this Career Prep Coach Chatbot Pipe on ⌘ Langbase</span>
</Dlink>
Expand Down
20 changes: 20 additions & 0 deletions examples/career-prep-coach/components/prompt-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as React from 'react'
import Textarea from 'react-textarea-autosize'
import { Popover, PopoverTrigger, PopoverContent } from '@radix-ui/react-popover'
import { MemorySidebar } from './memory-sidebar'
import { HoverCard, HoverCardTrigger, HoverCardContent } from 'components/ui/hovercard'

export interface PromptProps
extends Pick<UseChatHelpers, 'input' | 'setInput'> {
Expand Down Expand Up @@ -71,6 +72,25 @@ export function PromptForm({
aria-hidden="true"
/>
<h3>Chat</h3>
<HoverCard>
<HoverCardTrigger asChild>
<Button variant="link" size="lg" className="text-inherit">@conversation tips</Button>
</HoverCardTrigger>
<HoverCardContent>
<ul className="list-disc pl-4">
<li>
You can use Langbase memory with this chatbot to upload your resume, and for that you need a&nbsp;
<a href="https://langbase.com/docs/api-reference/api-keys#step-1-go-to-profile-settings" target="_blank" rel="noopener noreferrer" className="underline">
user API key and your login name.
</a>.
</li>
<li>
Once the user API key and owner login are entered, please make sure to save and then refresh to select the memory directly from the Langbase memory. This action will attach the memory to the current pipe.
</li>
</ul>
</HoverCardContent>
</HoverCard>

</div>

<div className="flex items-center justify-center gap-2 md:justify-start">
Expand Down
48 changes: 48 additions & 0 deletions examples/career-prep-coach/components/suggestions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import cn from 'mxcn'
import { IconSparkles } from './ui/icons'

// Prompt suggestions – Change these to match your use-case/company
const suggestions = [
{
title: `How to use this chatbot?`,
prompt: `How can I use your services?`
},
]

export const Suggestions = ({
sendSuggestedPrompt
}: {
sendSuggestedPrompt: (prompt: string) => void
}) => {
const handleClick = (prompt: string) => {
sendSuggestedPrompt(prompt)
}

return (
<div className="mx-auto mt-12 max-w-4xl">
<label className="font-semibold">Suggestions</label>
<div className="grid grid-cols-1 gap-4 pt-6 md:grid-cols-2">
{suggestions.map((suggestion, index) => {
return (
<div
key={index}
className={cn(
'border-muted-foreground/20 flex cursor-pointer items-center gap-4 rounded-md border p-4',
'hover:bg-background transition-all'
)}
onClick={() => handleClick(suggestion.prompt)}
>
<IconSparkles
className="text-muted-foreground size-4"
aria-hidden="true"
/>
<p className="text-foreground/70 line-clamp-2 font-light leading-6">
{suggestion.title}
</p>
</div>
)
})}
</div>
</div>
)
}
29 changes: 29 additions & 0 deletions examples/career-prep-coach/components/ui/hovercard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client"

import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"

import cn from 'mxcn'

const HoverCard = HoverCardPrimitive.Root

const HoverCardTrigger = HoverCardPrimitive.Trigger

const HoverCardContent = React.forwardRef<
React.ElementRef<typeof HoverCardPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<HoverCardPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
))
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName

export { HoverCard, HoverCardTrigger, HoverCardContent }
1 change: 1 addition & 0 deletions examples/career-prep-coach/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@radix-ui/react-hover-card": "^1.1.2",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-select": "^2.1.1",
Expand Down