Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 41 additions & 0 deletions agent-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
27 changes: 27 additions & 0 deletions agent-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
This is the [assistant-ui](https://github.com/Yonom/assistant-ui) starter project.

## Getting Started

First, add your OpenAI API key to `.env.local` file:

```
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Then, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

test
41 changes: 41 additions & 0 deletions agent-demo/app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { openai } from "@ai-sdk/openai";
import { frontendTools } from "@assistant-ui/react-ai-sdk";
import {
aiDocumentFormats,
injectDocumentStateMessages,
} from "@blocknote/xl-ai/server";
import { convertToModelMessages, streamText, UIMessage } from "ai";
import { JSONSchema7 } from "json-schema";

export async function POST(req: Request) {
const {
messages,
tools,
}: {
messages: UIMessage[];
tools: Record<string, { description?: string; parameters: JSONSchema7 }>;
} = await req.json();
const result = streamText({
system: aiDocumentFormats.html.systemPrompt,
model: openai("gpt-4o-2024-08-06"), // openai("gpt-5-nano"),
messages: convertToModelMessages(injectDocumentStateMessages(messages)),
tools: {
...(frontendTools(tools) as any), // TODO: tools vs toolDefinitions
web_search: openai.tools.webSearch({}),
},
// providerOptions: {
// openai: {
// reasoningEffort: "low",
// },
// },
// toolChoice: "required", // TODO: make configurable from client and make toolbar "required"
});

return result.toUIMessageStreamResponse();
}

// - the "getDocument" tool shows the document as an array of html blocks (the cursor is BETWEEN two blocks as indicated by cursor: true).
// - the "getDocumentSelection" tool shows the current user selection, if any.
// - when the document is empty, prefer updating the empty block before adding new blocks. Otherwise, prefer updating existing blocks over removing and adding (but this also depends on the user's question).
// Don't call "getDocument" or "getDocumentSelection" tools directly, the information is already available.
// When there is a selection, issue operations against the result of "getDocumentSelection". You can still use the result of "getDocument" (which includes the selection as well) to understand the context.
81 changes: 81 additions & 0 deletions agent-demo/app/assistant.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client";

import { AssistantModal } from "@/components/assistant-ui/assistant-modal";
import { ThreadListSidebar } from "@/components/assistant-ui/threadlist-sidebar";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbList,
} from "@/components/ui/breadcrumb";
import { Separator } from "@/components/ui/separator";
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useAISDKRuntime } from "@assistant-ui/react-ai-sdk";

import { useChatContext } from "@/components/ChatContext";
import { useChat } from "@ai-sdk/react";
import dynamic from "next/dynamic";
import { useEffect } from "react";

const Document = dynamic(() => import("./document"), {
ssr: false,
});

console.log("Assistant", Document);
export const Assistant = () => {
const ctx = useChatContext();
const chat = useChat({
chat: ctx.chat,
});

const runtime = useAISDKRuntime(chat);

useEffect(() => {
// not documented!
(ctx.transport as any).setRuntime(runtime);
}, [runtime, ctx.transport]);

return (
<AssistantRuntimeProvider runtime={runtime}>
<SidebarProvider>
<div className="flex h-dvh w-full pr-0.5">
<ThreadListSidebar />
<SidebarInset>
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
<SidebarTrigger />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
{/* <BreadcrumbLink
href="https://www.assistant-ui.com/docs/getting-started"
target="_blank"
rel="noopener noreferrer"
> */}
Agent demo
{/* </BreadcrumbLink> */}
</BreadcrumbItem>
{/* <BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>Starter Template</BreadcrumbPage>
</BreadcrumbItem> */}
</BreadcrumbList>
</Breadcrumb>
</header>
<div className="flex-1 overflow-scroll">
{/* <Thread /> */}
<div className="mx-auto max-w-2xl">
<Document />
</div>
</div>
</SidebarInset>
</div>
</SidebarProvider>
<AssistantModal />
</AssistantRuntimeProvider>
);
};
Loading
Loading