Skip to content

Commit

Permalink
feat: assistant-ui create CLI (#272)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yonom authored Jun 21, 2024
1 parent d5a6fd2 commit 3810443
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 43 deletions.
5 changes: 5 additions & 0 deletions .changeset/thick-baboons-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"assistant-ui": patch
---

feat: npx assistant-ui create
35 changes: 12 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,19 @@

- [Documentation](https://www.assistant-ui.com/docs/getting-started)

## Minimal Example with Vercel AI SDK
## Quick Start

Step 1: Create a new project with `assistant-ui` pre-configured:

```sh
npx assistant-ui@latest add modal
npx assistant-ui@latest create my-app
cd my-app
```

```tsx
"use client";

import { useChat } from "@ai-sdk/react";
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useVercelUseChatRuntime } from "@assistant-ui/react-ai-sdk";
import { AssistantModal } from "@/components/ui/assistant-ui/assistant-modal";

export default const MyApp = () => {
const chat = useChat({
api: "/api/chat" // your backend route
});
const runtime = useVercelUseChatRuntime(chat);

return (
<AssistantRuntimeProvider runtime={runtime}>
<AssistantModal />
</AssistantRuntimeProvider>
);
}
```
Step 2: Update the `.env` file with your OpenAI API key.

Step 3: Run the app:

```sh
npm run dev
```
49 changes: 31 additions & 18 deletions apps/www/pages/docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,42 @@ title: Getting Started
description: React Components for AI Chat
---

import Image from "next/image";
import architecture from "../../assets/docs/architecture.png";
import { Steps } from "nextra/components";

## Architecture
## Start with a new project

`assistant-ui` consists of two parts, **_Runtime_** and **_UI Components_**.
<Steps>

<Image
src={architecture}
height={300}
className="mx-auto my-2 dark:hue-rotate-180 dark:invert"
/>
### Create a new project

The Runtime and UI Components each require independent setup and both must be set up.
Create a new project with `assistant-ui` pre-configured:

## Setup
```sh
npx assistant-ui@latest create my-app
cd my-app
```

The recommended way to get started is with the following stack:
### Add API key

- NextJS
- Vercel's `ai` package
- `tailwindcss` for styling
- `shadcn/ui` for UI components
Add a new `.env` file to your project with your OpenAI API key:

### Step 1: Setup Runtime
```sh
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

### Start the app

```sh
npm run dev
```
</Steps>

## Install in an existing app


<Steps>

### Setup Runtime

You wrap your entire app in a `<AssistantRuntimeProvider runtime={runtime}>` component.

Expand All @@ -36,7 +47,7 @@ The `Runtime` takes care of LLM communication, tools, streaming, state managemen

Refer to [Picking a Runtime](/docs/runtimes/pick-a-runtime) to pick the right runtime for your use case.

### Step 2: Setup UI Components
### Setup UI Components

The easiest way to get started is with `shadcn/ui` + `tailwind` components.

Expand All @@ -45,3 +56,5 @@ Currently, two modes are supported:
- [`<AssistantModal />`](/docs/ui/AssistantModal): a modal chat UI in the bottom right corner
- [`<AssistantSidebar />`](/docs/ui/AssistantSidebar): a sidebar chat UI
- [`<Thread />`](/docs/ui/Thread): the raw chat UI

</Steps>
15 changes: 15 additions & 0 deletions apps/www/pages/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ title: Introduction
description: React Components for AI Chat
---

import Image from "next/image";
import architecture from "../../assets/docs/architecture.png";

### Composable Primitives

Inspired by [radix-ui](https://www.radix-ui.com/primitives), composable primitives allow you to mix and match the subset of features that you need.
Expand All @@ -14,3 +17,15 @@ assistant-ui does not ship with any styling or CSS code. Instead, you start with
### Open and Extensible

You have access to the entire internal state of assistant-ui and can mix and match your own promitives with ours.

### Architecture

`assistant-ui` consists of two parts, **_Runtime_** and **_UI Components_**.

<Image
src={architecture}
height={300}
className="mx-auto my-2 dark:hue-rotate-180 dark:invert"
/>

The Runtime and UI Components each require independent setup and both must be set up.
68 changes: 68 additions & 0 deletions packages/cli/src/commands/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Command } from "commander";
import chalk from "chalk";
import { spawn } from "child_process";

export const create = new Command()
.name("create")
.description("create a new project")
.arguments("<project-directory>")
.usage(`${chalk.green("<project-directory>")} [options]`)
.option(
"--use-npm",
`
Explicitly tell the CLI to bootstrap the application using npm
`,
)
.option(
"--use-pnpm",
`
Explicitly tell the CLI to bootstrap the application using pnpm
`,
)
.option(
"--use-yarn",
`
Explicitly tell the CLI to bootstrap the application using Yarn
`,
)
.option(
"--use-bun",
`
Explicitly tell the CLI to bootstrap the application using Bun
`,
)
.option(
"--skip-install",
`
Explicitly tell the CLI to skip installing packages
`,
)
.action(() => {
const child = spawn(
"npx",
[
`create-next-app@latest`,
...process.argv.slice(3),
"-e",
"https://github.com/Yonom/assistant-ui-starter",
],
{
stdio: "inherit",
},
);

child.on("error", (error) => {
console.error(`Error: ${error.message}`);
});

child.on("close", (code) => {
if (code !== 0) {
console.log(`other-package-script process exited with code ${code}`);
}
});
});
4 changes: 3 additions & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { add } from "@/src/commands/add";
import { Command } from "commander";

import { getPackageInfo } from "./utils/get-package-info";
import { create } from "./commands/create";

process.on("SIGINT", () => process.exit(0));
process.on("SIGTERM", () => process.exit(0));

async function main() {
const packageInfo = await getPackageInfo();
const packageInfo = getPackageInfo();

const program = new Command()
.name("assistant-ui")
Expand All @@ -21,6 +22,7 @@ async function main() {
);

program.addCommand(add);
program.addCommand(create);

program.parse();
}
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/src/utils/get-package-info.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import path from "node:path";
import fs from "node:fs";
import { fileURLToPath } from "node:url";

export function getPackageInfo() {
const packageJsonPath = path.join("package.json");
// Convert the current module URL to a file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageJsonPath = path.join(__dirname, "..", "package.json");

return JSON.parse(fs.readFileSync(packageJsonPath).toString("utf-8")) as {
version: string;
Expand Down

0 comments on commit 3810443

Please sign in to comment.