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

feat: add code and text block types #609

Merged
merged 15 commits into from
Dec 16, 2024
84 changes: 64 additions & 20 deletions app/(chat)/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
type Message,
StreamData,
convertToCoreMessages,
generateObject,
streamObject,
streamText,
} from 'ai';
Expand All @@ -10,7 +11,7 @@ import { z } from 'zod';
import { auth } from '@/app/(auth)/auth';
import { customModel } from '@/lib/ai';
import { models } from '@/lib/ai/models';
import { systemPrompt } from '@/lib/ai/prompts';
import { codePrompt, systemPrompt } from '@/lib/ai/prompts';
import {
deleteChatById,
getChatById,
Expand Down Expand Up @@ -119,11 +120,12 @@ export async function POST(request: Request) {
},
},
createDocument: {
description: 'Create a document for a writing activity',
description: 'Create a document for a writing activity.',
parameters: z.object({
title: z.string(),
kind: z.enum(['text', 'code']),
}),
execute: async ({ title }) => {
execute: async ({ title, kind }) => {
const id = generateUUID();
let draftText = '';

Expand All @@ -137,38 +139,78 @@ export async function POST(request: Request) {
content: title,
});

streamingData.append({
type: 'kind',
content: kind,
});

streamingData.append({
type: 'clear',
content: '',
});

const { fullStream } = streamText({
model: customModel(model.apiIdentifier),
system:
'Write about the given topic. Markdown is supported. Use headings wherever appropriate.',
prompt: title,
});
if (kind === 'text') {
const { fullStream } = streamText({
model: customModel(model.apiIdentifier),
system:
'Write about the given topic. Markdown is supported. Use headings wherever appropriate.',
prompt: title,
});

for await (const delta of fullStream) {
const { type } = delta;
for await (const delta of fullStream) {
const { type } = delta;

if (type === 'text-delta') {
const { textDelta } = delta;
if (type === 'text-delta') {
const { textDelta } = delta;

draftText += textDelta;
streamingData.append({
type: 'text-delta',
content: textDelta,
});
draftText += textDelta;
streamingData.append({
type: 'text-delta',
content: textDelta,
});
}
}
}
} else if (kind === 'code') {
const { object } = await generateObject({
model: customModel(model.apiIdentifier),
system: codePrompt,
prompt: title,
schema: z.object({
code: z.string(),
}),
});

streamingData.append({ type: 'finish', content: '' });
streamingData.append({
type: 'text-delta',
content: object.code,
});

draftText = object.code;

console.log(draftText);

streamingData.append({ type: 'finish', content: '' });

// for await (const delta of partialObjectStream) {
// const { type } = delta;

// if (type === "text-delta") {
// const { textDelta } = delta;

// draftText += textDelta;
// streamingData.append({
// type: "text-delta",
// content: textDelta,
// });
// }
// }
}

if (session.user?.id) {
await saveDocument({
id,
title,
kind,
content: draftText,
userId: session.user.id,
});
Expand All @@ -177,6 +219,7 @@ export async function POST(request: Request) {
return {
id,
title,
kind,
content: 'A document was created and is now visible to the user.',
};
},
Expand Down Expand Up @@ -248,6 +291,7 @@ export async function POST(request: Request) {
id,
title: document.title,
content: draftText,
kind: document.kind,
userId: session.user.id,
});
}
Expand Down
7 changes: 6 additions & 1 deletion app/(chat)/api/document/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,19 @@ export async function POST(request: Request) {
return new Response('Unauthorized', { status: 401 });
}

const { content, title }: { content: string; title: string } =
const {
content,
title,
kind,
}: { content: string; title: string; kind: 'text' | 'code' } =
await request.json();

if (session.user?.id) {
const document = await saveDocument({
id,
content,
title,
kind,
userId: session.user.id,
});

Expand Down
15 changes: 11 additions & 4 deletions app/(chat)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AppSidebar } from '@/components/app-sidebar';
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';

import { auth } from '../(auth)/auth';
import Script from 'next/script';

export const experimental_ppr = true;

Expand All @@ -16,9 +17,15 @@ export default async function Layout({
const isCollapsed = cookieStore.get('sidebar:state')?.value !== 'true';

return (
<SidebarProvider defaultOpen={!isCollapsed}>
<AppSidebar user={session?.user} />
<SidebarInset>{children}</SidebarInset>
</SidebarProvider>
<>
<Script
src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"
strategy="beforeInteractive"
/>
<SidebarProvider defaultOpen={!isCollapsed}>
<AppSidebar user={session?.user} />
<SidebarInset>{children}</SidebarInset>
</SidebarProvider>
</>
);
}
Loading
Loading