-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove Separate API Service for Web Interface (#174)
* Adds 50 turn free message allotment. * Fixes * Cleanup. * Better message. * Use server/admin actions to prevent js injection. * Cleanup * Updates auth check to support trial membership. * chore: Upgrade Honcho Version (#170) * fix(stripe) Handle de-duplication between trial and active subscriptions * Rendering Fully without stripe * chore: consolidate lib and utils * fix(www) Chat, reactions, and get thought working * fix(conversations): Automatically make new convo if none exist on load * Fix unstable stream via vercel sdk * README Updates --------- Co-authored-by: Ben Lopata <[email protected]>
- Loading branch information
1 parent
b1c4351
commit bd12699
Showing
28 changed files
with
1,231 additions
and
412 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
'use server'; | ||
|
||
import { createClient } from '@/utils/supabase/server'; | ||
import { honcho, getHonchoApp } from '@/utils/honcho'; | ||
|
||
// TODO add proper authorization check | ||
|
||
type Conversation = { | ||
conversationId: string; | ||
name: string; | ||
}; | ||
|
||
export async function getConversations() { | ||
const supabase = createClient(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
const honchoApp = await getHonchoApp(); | ||
|
||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
const acc = []; | ||
for await (const convo of honcho.apps.users.sessions.list( | ||
honchoApp.id, | ||
honchoUser.id, | ||
{ is_active: true, reverse: true } | ||
)) { | ||
const name = (convo.metadata?.name as string) ?? 'Untitled'; | ||
const instance: Conversation = { | ||
conversationId: convo.id, | ||
name, | ||
}; | ||
acc.push(instance); | ||
} | ||
return acc; | ||
} | ||
|
||
export async function createConversation() { | ||
const supabase = createClient(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
const honchoApp = await getHonchoApp(); | ||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
const session = await honcho.apps.users.sessions.create( | ||
honchoApp.id, | ||
honchoUser.id, | ||
{} | ||
); | ||
|
||
return { conversationId: session.id, name: 'Untitled' }; | ||
} | ||
|
||
export async function deleteConversation(conversationId: string) { | ||
const supabase = createClient(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
const honchoApp = await getHonchoApp(); | ||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
await honcho.apps.users.sessions.delete( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId | ||
); | ||
|
||
return true; | ||
} | ||
|
||
export async function updateConversation(conversationId: string, name: string) { | ||
const supabase = createClient(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
const honchoApp = await getHonchoApp(); | ||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
await honcho.apps.users.sessions.update( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId, | ||
{ metadata: { name } } | ||
); | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
'use server'; | ||
import { createClient } from '@/utils/supabase/server'; | ||
import { honcho, getHonchoApp } from '@/utils/honcho'; | ||
import { Message } from '@/utils/types'; | ||
|
||
const defaultMessage: Message = { | ||
content: `I'm your Aristotelian learning companion — here to help you follow your curiosity in whatever direction you like. My engineering makes me extremely receptive to your needs and interests. You can reply normally, and I’ll always respond!\n\nIf I'm off track, just say so!\n\nNeed to leave or just done chatting? Let me know! I’m conversational by design so I’ll say goodbye 😊.`, | ||
isUser: false, | ||
id: '', | ||
}; | ||
|
||
export async function getMessages(conversationId: string) { | ||
const supabase = createClient(); | ||
|
||
const honchoApp = await getHonchoApp(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
const session = await honcho.apps.users.sessions.get( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId | ||
); | ||
const messages = []; | ||
// TODO check if empty params is necessary | ||
for await (const message of honcho.apps.users.sessions.messages.list( | ||
honchoApp.id, | ||
honchoUser.id, | ||
session.id, | ||
{} | ||
)) { | ||
messages.push({ | ||
id: message.id, | ||
content: message.content, | ||
isUser: message.is_user, | ||
metadata: message.metadata, | ||
}); | ||
} | ||
|
||
return [defaultMessage, ...messages]; | ||
} | ||
|
||
export async function getThought(conversationId: string, messageId: string) { | ||
const supabase = createClient(); | ||
|
||
const honchoApp = await getHonchoApp(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
try { | ||
const thoughts = await honcho.apps.users.sessions.metamessages.list( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId, | ||
{ | ||
message_id: messageId, | ||
metamessage_type: 'thought', | ||
filter: { type: 'assistant' }, | ||
} | ||
); | ||
|
||
return thoughts.items[0]?.content || null; | ||
} catch (error) { | ||
console.error('Error in getThought:', error); | ||
throw new Error('Internal server error'); | ||
} | ||
} | ||
|
||
export async function addOrRemoveReaction( | ||
conversationId: string, | ||
messageId: string, | ||
reaction: 'thumbs_up' | 'thumbs_down' | null | ||
) { | ||
const supabase = createClient(); | ||
|
||
const honchoApp = await getHonchoApp(); | ||
|
||
const { | ||
data: { user }, | ||
} = await supabase.auth.getUser(); | ||
|
||
if (!user) { | ||
throw new Error('Unauthorized'); | ||
} | ||
|
||
if (reaction && !['thumbs_up', 'thumbs_down'].includes(reaction)) { | ||
throw new Error('Invalid reaction type'); | ||
} | ||
|
||
const honchoUser = await honcho.apps.users.getOrCreate(honchoApp.id, user.id); | ||
|
||
const message = await honcho.apps.users.sessions.messages.get( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId, | ||
messageId | ||
); | ||
|
||
if (!message) { | ||
throw new Error('Message not found'); | ||
} | ||
|
||
const metadata = message.metadata || {}; | ||
|
||
if (reaction === null) { | ||
delete metadata.reaction; | ||
} else { | ||
metadata.reaction = reaction; | ||
} | ||
|
||
await honcho.apps.users.sessions.messages.update( | ||
honchoApp.id, | ||
honchoUser.id, | ||
conversationId, | ||
messageId, | ||
{ metadata } | ||
); | ||
} |
Oops, something went wrong.