├── src ├── components │ ├── spinner.tsx │ ├── ui │ │ ├── aspect-ratio.tsx │ │ ├── skeleton.tsx │ │ ├── collapsible.tsx │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── separator.tsx │ │ ├── progress.tsx │ │ ├── input.tsx │ │ ├── toaster.tsx │ │ ├── checkbox.tsx │ │ ├── slider.tsx │ │ ├── switch.tsx │ │ ├── badge.tsx │ │ ├── tooltip.tsx │ │ ├── hover-card.tsx │ │ ├── popover.tsx │ │ ├── avatar.tsx │ │ ├── toggle.tsx │ │ ├── radio-group.tsx │ │ ├── alert.tsx │ │ ├── scroll-area.tsx │ │ ├── toggle-group.tsx │ │ ├── button.tsx │ │ ├── tabs.tsx │ │ ├── card.tsx │ │ ├── accordion.tsx │ │ ├── calendar.tsx │ │ ├── table.tsx │ │ ├── dialog.tsx │ │ ├── use-toast.ts │ │ ├── form.tsx │ │ ├── sheet.tsx │ │ ├── alert-dialog.tsx │ │ ├── toast.tsx │ │ ├── command.tsx │ │ ├── navigation-menu.tsx │ │ ├── select.tsx │ │ ├── context-menu.tsx │ │ ├── dropdown-menu.tsx │ │ └── menubar.tsx │ ├── memoized-react-markdown.tsx │ ├── textarea-autosize.tsx │ ├── image-card.tsx │ ├── code-dropdown.tsx │ ├── icons.tsx │ ├── code-block.tsx │ └── markdown.tsx ├── app │ ├── favicon.ico │ ├── shared │ │ ├── file-upload.ts │ │ ├── process-message-stream.ts │ │ ├── process-polled-steps.ts │ │ ├── utils.ts │ │ └── types.ts │ ├── layout.tsx │ ├── globals.css │ ├── assistant-response.ts │ ├── hooks │ │ └── use-assistant.ts │ ├── page.tsx │ └── api │ │ └── assistant │ │ └── route.ts └── lib │ └── utils.ts ├── .eslintrc.json ├── plot.png ├── next.config.js ├── postcss.config.js ├── components.json ├── .vscode ├── settings.json └── launch.json ├── .gitignore ├── tailwind.config.ts ├── public ├── vercel.svg └── next.svg ├── tsconfig.json ├── README.md ├── package.json └── tailwind.config.js /src/components/spinner.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sullyo/CodeInterpreter/HEAD/plot.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sullyo/CodeInterpreter/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /src/app/shared/file-upload.ts: -------------------------------------------------------------------------------- 1 | import { nanoid } from "@/app/shared/utils"; 2 | import { put } from "@vercel/blob"; 3 | 4 | export async function uploadBlob(input: ArrayBuffer) { 5 | const blob = await put(`${nanoid}-plot.png`, input, { 6 | access: "public", 7 | }); 8 | 9 | return blob.url; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /src/components/memoized-react-markdown.tsx: -------------------------------------------------------------------------------- 1 | import { memo, type FC } from "react"; 2 | import ReactMarkdown, { type Options } from "react-markdown"; 3 | 4 | export const MemoizedReactMarkdown: FC = memo( 5 | ReactMarkdown, 6 | (prevProps, nextProps) => 7 | prevProps.children === nextProps.children && 8 | prevProps.className === nextProps.className 9 | ); 10 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/app/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true 11 | }, 12 | "aliases": { 13 | "components": "@/components", 14 | "utils": "@/lib/utils" 15 | } 16 | } -------------------------------------------------------------------------------- /src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "tailwindCSS.includeLanguages": { 3 | "plaintext": "html" 4 | }, 5 | "tailwindCSS.experimental.classRegex": [ 6 | ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], 7 | ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], 8 | ["tw=\"([^\"]*)\""] 9 | ], 10 | "tailwindCSS.classAttributes": [ 11 | "class", 12 | "className", 13 | "ngClass", 14 | ".*Class.*", 15 | ".*Classes.*" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next' 2 | import { Inter } from 'next/font/google' 3 | import './globals.css' 4 | 5 | const inter = Inter({ subsets: ['latin'] }) 6 | 7 | export const metadata: Metadata = { 8 | title: 'Create Next App', 9 | description: 'Generated by create next app', 10 | } 11 | 12 | export default function RootLayout({ 13 | children, 14 | }: { 15 | children: React.ReactNode 16 | }) { 17 | return ( 18 | 19 | {children} 20 | 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss' 2 | 3 | const config: Config = { 4 | content: [ 5 | './src/pages/**/*.{js,ts,jsx,tsx,mdx}', 6 | './src/components/**/*.{js,ts,jsx,tsx,mdx}', 7 | './src/app/**/*.{js,ts,jsx,tsx,mdx}', 8 | ], 9 | theme: { 10 | extend: { 11 | backgroundImage: { 12 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 13 | 'gradient-conic': 14 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 15 | }, 16 | }, 17 | }, 18 | plugins: [], 19 | } 20 | export default config 21 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /src/app/shared/process-message-stream.ts: -------------------------------------------------------------------------------- 1 | export async function processMessageStream( 2 | reader: ReadableStreamDefaultReader, 3 | processMessage: (message: string) => void | Promise 4 | ) { 5 | const decoder = new TextDecoder(); 6 | let buffer = ""; 7 | while (true) { 8 | const { done, value } = await reader.read(); 9 | 10 | if (done) { 11 | if (buffer.length > 0) { 12 | processMessage(buffer); 13 | } 14 | break; 15 | } 16 | 17 | buffer += decoder.decode(value, { stream: true }); 18 | 19 | let endIndex: number; 20 | while ((endIndex = buffer.indexOf("\n")) !== -1) { 21 | processMessage(buffer.substring(0, endIndex).trim()); 22 | buffer = buffer.substring(endIndex + 1); // Remove the processed instruction + delimiter 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/textarea-autosize.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import ReactTextareaAutosize, { 5 | type TextareaAutosizeProps, 6 | } from "react-textarea-autosize"; 7 | 8 | import { cn } from "@/lib/utils"; 9 | 10 | const TextareaAutosize = React.forwardRef< 11 | HTMLTextAreaElement, 12 | TextareaAutosizeProps & { skeletonClassName?: string } 13 | >(({ className, skeletonClassName, ...props }, ref) => { 14 | return ( 15 | 23 | ); 24 | }); 25 | 26 | TextareaAutosize.displayName = "TextareaAutosize"; 27 | 28 | export { TextareaAutosize }; 29 | -------------------------------------------------------------------------------- /src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /src/components/image-card.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @next/next/no-img-element */ 2 | /** 3 | * v0 by Vercel. 4 | * @see https://v0.dev/t/fiw0Sm8ha2x 5 | */ 6 | import { CardTitle, CardHeader, CardContent, Card } from "@/components/ui/card"; 7 | 8 | interface ImagePlotProps { 9 | src: string; 10 | } 11 | export default function ImagePlot({ src }: ImagePlotProps) { 12 | return ( 13 | 14 | 15 | Plot 16 | 17 | 18 | Card Image 25 | 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |