Skip to content

Commit

Permalink
examples: add external store runtime example (#634)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonom authored Aug 4, 2024
1 parent 6629dd8 commit 4921b51
Show file tree
Hide file tree
Showing 17 changed files with 290 additions and 40 deletions.
3 changes: 2 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"with-react-hook-form",
"with-playground",
"with-openai-assistants",
"with-vercel-ai-rsc"
"with-vercel-ai-rsc",
"with-external-store"
]
}
1 change: 1 addition & 0 deletions examples/with-external-store/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3 changes: 3 additions & 0 deletions examples/with-external-store/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions examples/with-external-store/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

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

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
54 changes: 54 additions & 0 deletions examples/with-external-store/app/MyRuntimeProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"use client";

import { ThreadMessageLike } from "@assistant-ui/react";
import { AppendMessage } from "@assistant-ui/react";
import {
AssistantRuntimeProvider,
useExternalStoreRuntime,
} from "@assistant-ui/react";
import { useState } from "react";

const convertMessage = (message: ThreadMessageLike) => {
return message;
};

export function MyRuntimeProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const [messages, setMessages] = useState<ThreadMessageLike[]>([]);

const onNew = async (message: AppendMessage) => {
if (message.content.length !== 1 || message.content[0]?.type !== "text")
throw new Error("Only text content is supported");

const userMessage: ThreadMessageLike = {
role: "user",
content: [{ type: "text", text: message.content[0].text }],
};
setMessages((currentMessages) => [...currentMessages, userMessage]);

// normally you would perform an API call here to get the assistant response
await new Promise((resolve) => setTimeout(resolve, 1000));

const assistantMessage: ThreadMessageLike = {
role: "assistant",
content: [{ type: "text", text: "Hello, world!" }],
};
setMessages((currentMessages) => [...currentMessages, assistantMessage]);
};

const runtime = useExternalStoreRuntime<ThreadMessageLike>({
messages,
setMessages,
onNew,
convertMessage,
});

return (
<AssistantRuntimeProvider runtime={runtime}>
{children}
</AssistantRuntimeProvider>
);
}
8 changes: 8 additions & 0 deletions examples/with-external-store/app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { openai } from "@ai-sdk/openai";
import { createEdgeRuntimeAPI } from "@assistant-ui/react/edge";

export const maxDuration = 30;

export const { POST } = createEdgeRuntimeAPI({
model: openai("gpt-4o"),
});
Binary file added examples/with-external-store/app/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions examples/with-external-store/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
26 changes: 26 additions & 0 deletions examples/with-external-store/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { MyRuntimeProvider } from "@/app/MyRuntimeProvider";

import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<MyRuntimeProvider>
<html lang="en" className="h-full">
<body className={`${inter.className} h-full`}>{children}</body>
</html>
</MyRuntimeProvider>
);
}
11 changes: 11 additions & 0 deletions examples/with-external-store/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";

import { Thread } from "@assistant-ui/react";

export default function Home() {
return (
<main className="h-full">
<Thread />
</main>
);
}
4 changes: 4 additions & 0 deletions examples/with-external-store/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};

export default nextConfig;
30 changes: 30 additions & 0 deletions examples/with-external-store/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "with-external-store",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@ai-sdk/openai": "^0.0.40",
"@assistant-ui/react": "^0.5",
"next": "14.2.5",
"react": "^18",
"react-dom": "^18",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@assistant-ui/tsconfig": "workspace:*",
"@types/node": "^22",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.5",
"postcss": "^8",
"tailwindcss": "^3.4.7",
"typescript": "^5"
}
}
8 changes: 8 additions & 0 deletions examples/with-external-store/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};

export default config;
17 changes: 17 additions & 0 deletions examples/with-external-store/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Config } from "tailwindcss";

const config = {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
],
plugins: [
require("tailwindcss-animate"),
require("@assistant-ui/react/tailwindcss"),
],
} satisfies Config;

export default config;
23 changes: 23 additions & 0 deletions examples/with-external-store/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"extends": "@assistant-ui/tsconfig/base.json",
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"],
"@assistant-ui/*": ["../../packages/*/src"],
"@assistant-ui/react/*": ["../../packages/react/src/*"]
},
"allowJs": true,
"strictNullChecks": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
36 changes: 0 additions & 36 deletions examples/with-vercel-ai-rsc/README.md

This file was deleted.

Loading

0 comments on commit 4921b51

Please sign in to comment.