Skip to content

Commit

Permalink
finally fix major prompting issues (#194)
Browse files Browse the repository at this point in the history
* streaming refactor

* improve prompting framework

* more refactoring

* update prompts to match main

* fix stuff

* fix honcho history in response

* Enhance Dialectic Query (#195)

* fix(honcho): Enhance Dialectic Query

* chore: Fix Build Errors

---------

Co-authored-by: Vineeth Voruganti <[email protected]>
  • Loading branch information
hyusap and VVoruganti authored Dec 27, 2024
1 parent d3c5b7b commit 2a8a99d
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 170 deletions.
21 changes: 19 additions & 2 deletions www/app/api/chat/honcho/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,18 @@ export const runtime = 'nodejs';
export const maxDuration = 100;
export const dynamic = 'force-dynamic'; // always run dynamically


function parseHonchoContent(str: string) {
try {
const match = str.match(/<honcho>(.*?)<\/honcho>/s);
return match ? match[1].trim() : str;
} catch (error) {
return str;
}
}

export async function POST(req: NextRequest) {
const { message, conversationId } = await req.json();
const { message, thought, conversationId } = await req.json();

const userData = await getUserData();

Expand All @@ -17,12 +27,19 @@ export async function POST(req: NextRequest) {

const { appId, userId } = userData;



const query = `Given the following user message: <user>${message}</user> I had the following message: ${parseHonchoContent(thought)}`

const dialecticQuery = await honcho.apps.users.sessions.chat(
appId,
userId,
conversationId,
{ queries: message }
{ queries: query }
);

console.log('dialecticQuery:', query);
console.log('dialecticQuery Response:', dialecticQuery);

return NextResponse.json({ content: dialecticQuery.content });
}
130 changes: 102 additions & 28 deletions www/app/api/chat/response/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { createStream, getUserData, Message } from '@/utils/ai';
import {
assistant,
createStream,
getUserData,
Message,
user,
} from '@/utils/ai';
import { honcho } from '@/utils/honcho';
import { responsePrompt } from '@/utils/prompts/response';
import { NextRequest, NextResponse } from 'next/server';
Expand All @@ -8,7 +14,9 @@ export const maxDuration = 100;
export const dynamic = 'force-dynamic'; // always run dynamically

export async function POST(req: NextRequest) {
const { message, conversationId, honchoThought } = await req.json();
const { message, conversationId, thought, honchoThought } = await req.json();

console.log('honchoThought', honchoThought);

const userData = await getUserData();
if (!userData) {
Expand All @@ -17,44 +25,110 @@ export async function POST(req: NextRequest) {

const { appId, userId } = userData;

const history: Message[] = [];
const responseIter = await honcho.apps.users.sessions.metamessages.list(
const responseIter = await honcho.apps.users.sessions.messages.list(
appId,
userId,
conversationId,
{}
);

const responseHistory = Array.from(responseIter.items);

const honchoIter = await honcho.apps.users.sessions.metamessages.list(
appId,
userId,
conversationId,
{
metamessage_type: 'response',
metamessage_type: 'honcho',
}
);

for await (const metamessage of responseIter) {
const associatedMessage = await honcho.apps.users.sessions.messages.get(
appId,
userId,
conversationId,
metamessage.message_id
);
const honchoHistory = Array.from(honchoIter.items);

history.push({ role: 'user', content: metamessage.content });
history.push({ role: 'assistant', content: associatedMessage.content });
}
console.log('honchoHistory', honchoHistory);
console.log('responseHistory', responseHistory);

const getHonchoMessage = (id: string) =>
honchoHistory.find((m) => m.message_id === id)?.content ||
'No Honcho Message';

const history = responseHistory.map((message, i) => {
if (message.is_user) {
return user`<honcho>${getHonchoMessage(message.id)}</honcho>
${message.content}`;
} else {
return assistant`${message.content}`;
}
});

const messages = [
...responsePrompt,
...history,
const finalMessage = user`<honcho>${honchoThought}</honcho>
${message}`;

const prompt = [...responsePrompt, ...history, finalMessage];

console.log('responsePrompt', prompt);

// Create logs directory if it doesn't exist

const stream = await createStream(
prompt,
{
role: 'user',
content: `<honcho-response>${honchoThought}</honcho-response>\n${message}`,
sessionId: conversationId,
userId,
type: 'response',
},
] as Message[];
async (response) => {
const newUserMessage = await honcho.apps.users.sessions.messages.create(
appId,
userId,
conversationId,
{
is_user: true,
content: message,
}
);

const stream = await createStream('response', messages, {
appId,
userId,
sessionId: conversationId,
userInput: message,
honchoContent: honchoThought,
});
// Execute all requests in parallel
await Promise.all([
// Save the thought metamessage
honcho.apps.users.sessions.metamessages.create(
appId,
userId,
conversationId,
{
message_id: newUserMessage.id,
metamessage_type: 'thought',
content: thought || '',
metadata: { type: 'assistant' },
}
),

// Save honcho metamessage
honcho.apps.users.sessions.metamessages.create(
appId,
userId,
conversationId,
{
message_id: newUserMessage.id,
metamessage_type: 'honcho',
content: honchoThought || '',
metadata: { type: 'assistant' },
}
),

// Save assistant message
honcho.apps.users.sessions.messages.create(
appId,
userId,
conversationId,
{
is_user: false,
content: response.text,
}
),
]);
}
);

if (!stream) {
throw new Error('Failed to get stream');
Expand Down
87 changes: 49 additions & 38 deletions www/app/api/chat/thought/route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
createStream,
getUserData,
HistoryWithoutResponse,
Message,
user,
assistant,
// parsePrompt,
Expand All @@ -15,76 +13,89 @@ export const runtime = 'nodejs';
export const maxDuration = 100;
export const dynamic = 'force-dynamic'; // always run dynamically

const CONTEXT_LIMIT = 10;

interface Metadata {
summary?: string;
interface ThoughtCallProps {
message: string;
conversationId: string;
}

export async function POST(req: NextRequest) {
const { message, conversationId } = await req.json();
const { message, conversationId } = (await req.json()) as ThoughtCallProps;

const userData = await getUserData();
if (!userData) {
return new NextResponse('Unauthorized', { status: 401 });
}
const { appId, userId } = userData;

const messageIter = await honcho.apps.users.sessions.messages.list(
appId,
userId,
conversationId,
{}
);

const messageHistory = Array.from(messageIter.items);

const thoughtIter = await honcho.apps.users.sessions.metamessages.list(
appId,
userId,
conversationId,
{
metamessage_type: 'thought',
filter: { type: 'user' },
}
);

const thoughtHistory = thoughtIter.items.map(
(metamessage) => user`${metamessage.content}`
);
const thoughtHistory = Array.from(thoughtIter.items);

const recentResponseMeta = await honcho.apps.users.sessions.metamessages.list(
const honchoIter = await honcho.apps.users.sessions.metamessages.list(
appId,
userId,
conversationId,
{
metamessage_type: 'response',
filter: { type: 'user' },
reverse: true,
size: 1,
metamessage_type: 'honcho',
}
);

const [recentResponse] = recentResponseMeta.items;
const content = recentResponse?.content ?? '';

const honchoResponse =
content.match(/<honcho>([^]*?)<\/honcho>/)?.[1]?.trim() ?? 'None';
const bloomResponse =
content.match(/<tutor>([^]*?)<\/tutor>/)?.[1]?.trim() ?? 'None';
const honchoHistory = Array.from(honchoIter.items);

const history = messageHistory.map((message, i) => {
if (message.is_user) {
if (i == 0) {
return user`${message.content}`;
}
const lastUserMessage = messageHistory[i - 2];
const honchoResponse = honchoHistory.find(
(h) => h.message_id === lastUserMessage.id
);
const tutorResponse = messageHistory[i - 1];

return user`<honcho-response>${honchoResponse?.content || 'None'}</honcho-response>
<tutor>${tutorResponse?.content || 'None'}</tutor>
${message.content}`;
} else {
const lastUserMessage = messageHistory[i - 1];
const thoughtResponse = thoughtHistory.find(
(t) => t.message_id === lastUserMessage.id
);
return assistant`${thoughtResponse?.content || 'None'}`;
}
});

const prompt: Message[] = [
...thoughtPrompt,
...thoughtHistory,
{
role: 'user',
content: `<honcho-response>${honchoResponse}</honcho-response>\n<tutor>${bloomResponse}</tutor>\n${message}`,
},
];
const finalMessage = user`<honcho-response>${honchoHistory[honchoHistory.length - 1]?.content || 'None'}</honcho-response>
<tutor>${messageHistory[messageHistory.length - 1]?.content || 'None'}</tutor>
${message}`;

const honchoPayload: HistoryWithoutResponse = {
appId,
userId,
sessionId: conversationId,
userInput: message,
};
const prompt = [...thoughtPrompt, ...history, finalMessage];

console.log('Messages:\n');
console.log(prompt);
console.log('\n\n\n');

const stream = await createStream('thought', prompt, honchoPayload);
const stream = await createStream(prompt, {
sessionId: conversationId,
userId,
type: 'thought',
});

if (!stream) {
throw new Error('Failed to get stream');
Expand Down
Loading

0 comments on commit 2a8a99d

Please sign in to comment.