langwatch 0.2.0 → 0.3.0-prerelease.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +268 -1
  3. package/dist/chunk-4BZATFKJ.mjs +181 -0
  4. package/dist/chunk-4BZATFKJ.mjs.map +1 -0
  5. package/dist/chunk-CSC3CMIT.mjs +118 -0
  6. package/dist/chunk-CSC3CMIT.mjs.map +1 -0
  7. package/dist/chunk-F63YKTXA.mjs +47 -0
  8. package/dist/chunk-F63YKTXA.mjs.map +1 -0
  9. package/dist/chunk-G3AUABT7.js +4 -0
  10. package/dist/chunk-G3AUABT7.js.map +1 -0
  11. package/dist/chunk-HPC6Z7J4.js +118 -0
  12. package/dist/chunk-HPC6Z7J4.js.map +1 -0
  13. package/dist/chunk-KGDAENGD.js +50 -0
  14. package/dist/chunk-KGDAENGD.js.map +1 -0
  15. package/dist/chunk-LD74LVRU.js +47 -0
  16. package/dist/chunk-LD74LVRU.js.map +1 -0
  17. package/dist/chunk-OM7VY3XT.mjs +4 -0
  18. package/dist/chunk-PCQVQ7SB.js +45 -0
  19. package/dist/chunk-PCQVQ7SB.js.map +1 -0
  20. package/dist/chunk-PMBEK6YE.mjs +424 -0
  21. package/dist/chunk-PMBEK6YE.mjs.map +1 -0
  22. package/dist/chunk-PR3JDWC3.mjs +50 -0
  23. package/dist/chunk-PR3JDWC3.mjs.map +1 -0
  24. package/dist/chunk-PTJ6AAI7.js +360 -0
  25. package/dist/chunk-PTJ6AAI7.js.map +1 -0
  26. package/dist/chunk-QEWDG5QE.mjs +45 -0
  27. package/dist/chunk-QEWDG5QE.mjs.map +1 -0
  28. package/dist/chunk-REUCVT7A.mjs +39 -0
  29. package/dist/chunk-REUCVT7A.mjs.map +1 -0
  30. package/dist/chunk-SVJ7SCGB.js +424 -0
  31. package/dist/chunk-SVJ7SCGB.js.map +1 -0
  32. package/dist/chunk-VJSOCNPA.js +181 -0
  33. package/dist/chunk-VJSOCNPA.js.map +1 -0
  34. package/dist/chunk-WM2GRSRW.js +39 -0
  35. package/dist/chunk-WM2GRSRW.js.map +1 -0
  36. package/dist/chunk-Z5J5UI5E.mjs +360 -0
  37. package/dist/chunk-Z5J5UI5E.mjs.map +1 -0
  38. package/dist/client-B2HqIKg6.d.ts +51 -0
  39. package/dist/client-XyCqclCi.d.mts +51 -0
  40. package/dist/client-browser.d.mts +8 -0
  41. package/dist/client-browser.d.ts +8 -0
  42. package/dist/client-browser.js +83 -0
  43. package/dist/client-browser.js.map +1 -0
  44. package/dist/client-browser.mjs +83 -0
  45. package/dist/client-browser.mjs.map +1 -0
  46. package/dist/client-node.d.mts +8 -0
  47. package/dist/client-node.d.ts +8 -0
  48. package/dist/client-node.js +90 -0
  49. package/dist/client-node.js.map +1 -0
  50. package/dist/client-node.mjs +90 -0
  51. package/dist/client-node.mjs.map +1 -0
  52. package/dist/evaluation/index.d.mts +897 -0
  53. package/dist/evaluation/index.d.ts +897 -0
  54. package/dist/evaluation/index.js +13 -0
  55. package/dist/evaluation/index.js.map +1 -0
  56. package/dist/evaluation/index.mjs +13 -0
  57. package/dist/evaluation/index.mjs.map +1 -0
  58. package/dist/filterable-batch-span-processor-zO5kcjBY.d.mts +64 -0
  59. package/dist/filterable-batch-span-processor-zO5kcjBY.d.ts +64 -0
  60. package/dist/index.d.mts +45 -1027
  61. package/dist/index.d.ts +45 -1027
  62. package/dist/index.js +11 -27291
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +23 -956
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/observability/index.d.mts +260 -0
  67. package/dist/observability/index.d.ts +260 -0
  68. package/dist/observability/index.js +20 -0
  69. package/dist/observability/index.js.map +1 -0
  70. package/dist/observability/index.mjs +20 -0
  71. package/dist/observability/index.mjs.map +1 -0
  72. package/dist/observability/instrumentation/langchain/index.d.mts +40 -0
  73. package/dist/observability/instrumentation/langchain/index.d.ts +40 -0
  74. package/dist/observability/instrumentation/langchain/index.js +666 -0
  75. package/dist/observability/instrumentation/langchain/index.js.map +1 -0
  76. package/dist/observability/instrumentation/langchain/index.mjs +666 -0
  77. package/dist/observability/instrumentation/langchain/index.mjs.map +1 -0
  78. package/dist/prompt/index.d.mts +10 -0
  79. package/dist/prompt/index.d.ts +10 -0
  80. package/dist/prompt/index.js +18 -0
  81. package/dist/prompt/index.js.map +1 -0
  82. package/dist/prompt/index.mjs +18 -0
  83. package/dist/prompt/index.mjs.map +1 -0
  84. package/dist/prompt-BXJWdbQp.d.mts +1967 -0
  85. package/dist/prompt-BXJWdbQp.d.ts +1967 -0
  86. package/dist/record-evaluation-CmxMXa-3.d.mts +25 -0
  87. package/dist/record-evaluation-CmxMXa-3.d.ts +25 -0
  88. package/dist/trace-D-bZOuqb.d.mts +622 -0
  89. package/dist/trace-G2312klE.d.ts +622 -0
  90. package/package.json +86 -37
  91. package/.eslintrc.cjs +0 -37
  92. package/copy-types.sh +0 -17
  93. package/dist/chunk-LKD2K67J.mjs +0 -717
  94. package/dist/chunk-LKD2K67J.mjs.map +0 -1
  95. package/dist/utils-Cv-rUjJ1.d.mts +0 -313
  96. package/dist/utils-Cv-rUjJ1.d.ts +0 -313
  97. package/dist/utils.d.mts +0 -2
  98. package/dist/utils.d.ts +0 -2
  99. package/dist/utils.js +0 -709
  100. package/dist/utils.js.map +0 -1
  101. package/dist/utils.mjs +0 -11
  102. package/example/.env.example +0 -12
  103. package/example/.eslintrc.json +0 -26
  104. package/example/LICENSE +0 -13
  105. package/example/README.md +0 -12
  106. package/example/app/(chat)/chat/[id]/page.tsx +0 -60
  107. package/example/app/(chat)/layout.tsx +0 -14
  108. package/example/app/(chat)/page.tsx +0 -27
  109. package/example/app/actions.ts +0 -156
  110. package/example/app/globals.css +0 -76
  111. package/example/app/guardrails/page.tsx +0 -26
  112. package/example/app/langchain/page.tsx +0 -27
  113. package/example/app/langchain-rag/page.tsx +0 -28
  114. package/example/app/late-update/page.tsx +0 -27
  115. package/example/app/layout.tsx +0 -64
  116. package/example/app/login/actions.ts +0 -71
  117. package/example/app/login/page.tsx +0 -18
  118. package/example/app/manual/page.tsx +0 -27
  119. package/example/app/new/page.tsx +0 -5
  120. package/example/app/opengraph-image.png +0 -0
  121. package/example/app/share/[id]/page.tsx +0 -58
  122. package/example/app/signup/actions.ts +0 -111
  123. package/example/app/signup/page.tsx +0 -18
  124. package/example/app/twitter-image.png +0 -0
  125. package/example/auth.config.ts +0 -42
  126. package/example/auth.ts +0 -45
  127. package/example/components/button-scroll-to-bottom.tsx +0 -36
  128. package/example/components/chat-history.tsx +0 -49
  129. package/example/components/chat-list.tsx +0 -52
  130. package/example/components/chat-message-actions.tsx +0 -40
  131. package/example/components/chat-message.tsx +0 -80
  132. package/example/components/chat-panel.tsx +0 -139
  133. package/example/components/chat-share-dialog.tsx +0 -95
  134. package/example/components/chat.tsx +0 -84
  135. package/example/components/clear-history.tsx +0 -75
  136. package/example/components/empty-screen.tsx +0 -38
  137. package/example/components/external-link.tsx +0 -29
  138. package/example/components/footer.tsx +0 -19
  139. package/example/components/header.tsx +0 -114
  140. package/example/components/login-button.tsx +0 -42
  141. package/example/components/login-form.tsx +0 -97
  142. package/example/components/markdown.tsx +0 -9
  143. package/example/components/prompt-form.tsx +0 -115
  144. package/example/components/providers.tsx +0 -17
  145. package/example/components/sidebar-actions.tsx +0 -125
  146. package/example/components/sidebar-desktop.tsx +0 -19
  147. package/example/components/sidebar-footer.tsx +0 -16
  148. package/example/components/sidebar-item.tsx +0 -124
  149. package/example/components/sidebar-items.tsx +0 -42
  150. package/example/components/sidebar-list.tsx +0 -38
  151. package/example/components/sidebar-mobile.tsx +0 -31
  152. package/example/components/sidebar-toggle.tsx +0 -24
  153. package/example/components/sidebar.tsx +0 -21
  154. package/example/components/signup-form.tsx +0 -95
  155. package/example/components/stocks/events-skeleton.tsx +0 -31
  156. package/example/components/stocks/events.tsx +0 -30
  157. package/example/components/stocks/index.tsx +0 -36
  158. package/example/components/stocks/message.tsx +0 -134
  159. package/example/components/stocks/spinner.tsx +0 -16
  160. package/example/components/stocks/stock-purchase.tsx +0 -146
  161. package/example/components/stocks/stock-skeleton.tsx +0 -22
  162. package/example/components/stocks/stock.tsx +0 -210
  163. package/example/components/stocks/stocks-skeleton.tsx +0 -9
  164. package/example/components/stocks/stocks.tsx +0 -67
  165. package/example/components/tailwind-indicator.tsx +0 -14
  166. package/example/components/theme-toggle.tsx +0 -31
  167. package/example/components/ui/alert-dialog.tsx +0 -141
  168. package/example/components/ui/badge.tsx +0 -36
  169. package/example/components/ui/button.tsx +0 -57
  170. package/example/components/ui/codeblock.tsx +0 -148
  171. package/example/components/ui/dialog.tsx +0 -122
  172. package/example/components/ui/dropdown-menu.tsx +0 -205
  173. package/example/components/ui/icons.tsx +0 -507
  174. package/example/components/ui/input.tsx +0 -25
  175. package/example/components/ui/label.tsx +0 -26
  176. package/example/components/ui/select.tsx +0 -164
  177. package/example/components/ui/separator.tsx +0 -31
  178. package/example/components/ui/sheet.tsx +0 -140
  179. package/example/components/ui/sonner.tsx +0 -31
  180. package/example/components/ui/switch.tsx +0 -29
  181. package/example/components/ui/textarea.tsx +0 -24
  182. package/example/components/ui/tooltip.tsx +0 -30
  183. package/example/components/user-menu.tsx +0 -53
  184. package/example/components.json +0 -17
  185. package/example/instrumentation.ts +0 -11
  186. package/example/lib/chat/guardrails.tsx +0 -181
  187. package/example/lib/chat/langchain-rag.tsx +0 -191
  188. package/example/lib/chat/langchain.tsx +0 -112
  189. package/example/lib/chat/late-update.tsx +0 -208
  190. package/example/lib/chat/manual.tsx +0 -605
  191. package/example/lib/chat/vercel-ai.tsx +0 -576
  192. package/example/lib/hooks/use-copy-to-clipboard.tsx +0 -33
  193. package/example/lib/hooks/use-enter-submit.tsx +0 -23
  194. package/example/lib/hooks/use-local-storage.ts +0 -24
  195. package/example/lib/hooks/use-scroll-anchor.tsx +0 -86
  196. package/example/lib/hooks/use-sidebar.tsx +0 -60
  197. package/example/lib/hooks/use-streamable-text.ts +0 -25
  198. package/example/lib/types.ts +0 -41
  199. package/example/lib/utils.ts +0 -89
  200. package/example/middleware.ts +0 -8
  201. package/example/next-env.d.ts +0 -5
  202. package/example/next.config.js +0 -16
  203. package/example/package-lock.json +0 -10917
  204. package/example/package.json +0 -84
  205. package/example/pnpm-lock.yaml +0 -5712
  206. package/example/postcss.config.js +0 -6
  207. package/example/prettier.config.cjs +0 -34
  208. package/example/public/apple-touch-icon.png +0 -0
  209. package/example/public/favicon-16x16.png +0 -0
  210. package/example/public/favicon.ico +0 -0
  211. package/example/public/next.svg +0 -1
  212. package/example/public/thirteen.svg +0 -1
  213. package/example/public/vercel.svg +0 -1
  214. package/example/tailwind.config.ts +0 -81
  215. package/example/tsconfig.json +0 -35
  216. package/src/LangWatchExporter.ts +0 -96
  217. package/src/evaluations.ts +0 -219
  218. package/src/index.test.ts +0 -402
  219. package/src/index.ts +0 -596
  220. package/src/langchain.ts +0 -557
  221. package/src/server/types/.gitkeep +0 -0
  222. package/src/typeUtils.ts +0 -89
  223. package/src/types.ts +0 -82
  224. package/src/utils.ts +0 -205
  225. package/ts-to-zod.config.js +0 -24
  226. package/tsconfig.json +0 -32
  227. package/tsup.config.ts +0 -10
  228. package/vitest.config.ts +0 -8
  229. /package/dist/{utils.mjs.map → chunk-OM7VY3XT.mjs.map} +0 -0
@@ -1,27 +0,0 @@
1
- import { nanoid } from '@/lib/utils'
2
- import { Chat } from '@/components/chat'
3
- import { auth } from '@/auth'
4
- import { Session } from '@/lib/types'
5
- import { getMissingKeys } from '@/app/actions'
6
- import { LateUpdateTracing } from '../../lib/chat/late-update'
7
-
8
- export const metadata = {
9
- title: 'Late Update Tracing Example'
10
- }
11
-
12
- export default async function IndexPage() {
13
- const id = nanoid()
14
- const session = (await auth()) as Session
15
- const missingKeys = await getMissingKeys()
16
-
17
- return (
18
- <>
19
- <div className="text-center w-full absolute pt-1">
20
- Late Update Tracing Example
21
- </div>
22
- <LateUpdateTracing initialAIState={{ chatId: id, messages: [] }}>
23
- <Chat id={id} session={session} missingKeys={missingKeys} />
24
- </LateUpdateTracing>
25
- </>
26
- )
27
- }
@@ -1,64 +0,0 @@
1
- import { GeistSans } from 'geist/font/sans'
2
- import { GeistMono } from 'geist/font/mono'
3
-
4
- import '@/app/globals.css'
5
- import { cn } from '@/lib/utils'
6
- import { TailwindIndicator } from '@/components/tailwind-indicator'
7
- import { Providers } from '@/components/providers'
8
- import { Header } from '@/components/header'
9
- import { Toaster } from '@/components/ui/sonner'
10
-
11
- export const metadata = {
12
- metadataBase: process.env.VERCEL_URL
13
- ? new URL(`https://${process.env.VERCEL_URL}`)
14
- : undefined,
15
- title: {
16
- default: 'Next.js AI Chatbot',
17
- template: `%s - Next.js AI Chatbot`
18
- },
19
- description: 'An AI-powered chatbot template built with Next.js and Vercel.',
20
- icons: {
21
- icon: '/favicon.ico',
22
- shortcut: '/favicon-16x16.png',
23
- apple: '/apple-touch-icon.png'
24
- }
25
- }
26
-
27
- export const viewport = {
28
- themeColor: [
29
- { media: '(prefers-color-scheme: light)', color: 'white' },
30
- { media: '(prefers-color-scheme: dark)', color: 'black' }
31
- ]
32
- }
33
-
34
- interface RootLayoutProps {
35
- children: React.ReactNode
36
- }
37
-
38
- export default function RootLayout({ children }: RootLayoutProps) {
39
- return (
40
- <html lang="en" suppressHydrationWarning>
41
- <body
42
- className={cn(
43
- 'font-sans antialiased',
44
- GeistSans.variable,
45
- GeistMono.variable
46
- )}
47
- >
48
- <Toaster position="top-center" />
49
- <Providers
50
- attribute="class"
51
- defaultTheme="system"
52
- enableSystem
53
- disableTransitionOnChange
54
- >
55
- <div className="flex flex-col min-h-screen">
56
- <Header />
57
- <main className="flex flex-col flex-1 bg-muted/50">{children}</main>
58
- </div>
59
- <TailwindIndicator />
60
- </Providers>
61
- </body>
62
- </html>
63
- )
64
- }
@@ -1,71 +0,0 @@
1
- 'use server'
2
-
3
- import { signIn } from '@/auth'
4
- import { User } from '@/lib/types'
5
- import { AuthError } from 'next-auth'
6
- import { z } from 'zod'
7
- import { kv } from '@vercel/kv'
8
- import { ResultCode } from '@/lib/utils'
9
-
10
- export async function getUser(email: string) {
11
- const user = await kv.hgetall<User>(`user:${email}`)
12
- return user
13
- }
14
-
15
- interface Result {
16
- type: string
17
- resultCode: ResultCode
18
- }
19
-
20
- export async function authenticate(
21
- _prevState: Result | undefined,
22
- formData: FormData
23
- ): Promise<Result | undefined> {
24
- try {
25
- const email = formData.get('email')
26
- const password = formData.get('password')
27
-
28
- const parsedCredentials = z
29
- .object({
30
- email: z.string().email(),
31
- password: z.string().min(6)
32
- })
33
- .safeParse({
34
- email,
35
- password
36
- })
37
-
38
- if (parsedCredentials.success) {
39
- await signIn('credentials', {
40
- email,
41
- password,
42
- redirect: false
43
- })
44
-
45
- return {
46
- type: 'success',
47
- resultCode: ResultCode.UserLoggedIn
48
- }
49
- } else {
50
- return {
51
- type: 'error',
52
- resultCode: ResultCode.InvalidCredentials
53
- }
54
- }
55
- } catch (error) {
56
- if (error instanceof AuthError) {
57
- switch (error.type) {
58
- case 'CredentialsSignin':
59
- return {
60
- type: 'error',
61
- resultCode: ResultCode.InvalidCredentials
62
- }
63
- default:
64
- return {
65
- type: 'error',
66
- resultCode: ResultCode.UnknownError
67
- }
68
- }
69
- }
70
- }
71
- }
@@ -1,18 +0,0 @@
1
- import { auth } from '@/auth'
2
- import LoginForm from '@/components/login-form'
3
- import { Session } from '@/lib/types'
4
- import { redirect } from 'next/navigation'
5
-
6
- export default async function LoginPage() {
7
- const session = (await auth()) as Session
8
-
9
- if (session) {
10
- redirect('/')
11
- }
12
-
13
- return (
14
- <main className="flex flex-col p-4">
15
- <LoginForm />
16
- </main>
17
- )
18
- }
@@ -1,27 +0,0 @@
1
- import { nanoid } from '@/lib/utils'
2
- import { Chat } from '@/components/chat'
3
- import { ManualTracing } from '@/lib/chat/manual'
4
- import { auth } from '@/auth'
5
- import { Session } from '@/lib/types'
6
- import { getMissingKeys } from '@/app/actions'
7
-
8
- export const metadata = {
9
- title: 'Manual Tracing Example'
10
- }
11
-
12
- export default async function IndexPage() {
13
- const id = nanoid()
14
- const session = (await auth()) as Session
15
- const missingKeys = await getMissingKeys()
16
-
17
- return (
18
- <>
19
- <div className="text-center w-full absolute pt-1">
20
- Manual Tracing Example
21
- </div>
22
- <ManualTracing initialAIState={{ chatId: id, messages: [] }}>
23
- <Chat id={id} session={session} missingKeys={missingKeys} />
24
- </ManualTracing>
25
- </>
26
- )
27
- }
@@ -1,5 +0,0 @@
1
- import { redirect } from 'next/navigation'
2
-
3
- export default async function NewPage() {
4
- redirect('/')
5
- }
Binary file
@@ -1,58 +0,0 @@
1
- import { type Metadata } from 'next'
2
- import { notFound, redirect } from 'next/navigation'
3
-
4
- import { formatDate } from '@/lib/utils'
5
- import { getSharedChat } from '@/app/actions'
6
- import { ChatList } from '@/components/chat-list'
7
- import { FooterText } from '@/components/footer'
8
- import { AI, UIState, getUIStateFromAIState } from '@/lib/chat/vercel-ai'
9
-
10
- export const runtime = 'edge'
11
- export const preferredRegion = 'home'
12
-
13
- interface SharePageProps {
14
- params: {
15
- id: string
16
- }
17
- }
18
-
19
- export async function generateMetadata({
20
- params
21
- }: SharePageProps): Promise<Metadata> {
22
- const chat = await getSharedChat(params.id)
23
-
24
- return {
25
- title: chat?.title.slice(0, 50) ?? 'Chat'
26
- }
27
- }
28
-
29
- export default async function SharePage({ params }: SharePageProps) {
30
- const chat = await getSharedChat(params.id)
31
-
32
- if (!chat || !chat?.sharePath) {
33
- notFound()
34
- }
35
-
36
- const uiState: UIState = getUIStateFromAIState(chat)
37
-
38
- return (
39
- <>
40
- <div className="flex-1 space-y-6">
41
- <div className="border-b bg-background px-4 py-6 md:px-6 md:py-8">
42
- <div className="mx-auto max-w-2xl">
43
- <div className="space-y-1 md:-mx-8">
44
- <h1 className="text-2xl font-bold">{chat.title}</h1>
45
- <div className="text-sm text-muted-foreground">
46
- {formatDate(chat.createdAt)} · {chat.messages.length} messages
47
- </div>
48
- </div>
49
- </div>
50
- </div>
51
- <AI>
52
- <ChatList messages={uiState} isShared={true} />
53
- </AI>
54
- </div>
55
- <FooterText className="py-8" />
56
- </>
57
- )
58
- }
@@ -1,111 +0,0 @@
1
- 'use server'
2
-
3
- import { signIn } from '@/auth'
4
- import { ResultCode, getStringFromBuffer } from '@/lib/utils'
5
- import { z } from 'zod'
6
- import { kv } from '@vercel/kv'
7
- import { getUser } from '../login/actions'
8
- import { AuthError } from 'next-auth'
9
-
10
- export async function createUser(
11
- email: string,
12
- hashedPassword: string,
13
- salt: string
14
- ) {
15
- const existingUser = await getUser(email)
16
-
17
- if (existingUser) {
18
- return {
19
- type: 'error',
20
- resultCode: ResultCode.UserAlreadyExists
21
- }
22
- } else {
23
- const user = {
24
- id: crypto.randomUUID(),
25
- email,
26
- password: hashedPassword,
27
- salt
28
- }
29
-
30
- await kv.hmset(`user:${email}`, user)
31
-
32
- return {
33
- type: 'success',
34
- resultCode: ResultCode.UserCreated
35
- }
36
- }
37
- }
38
-
39
- interface Result {
40
- type: string
41
- resultCode: ResultCode
42
- }
43
-
44
- export async function signup(
45
- _prevState: Result | undefined,
46
- formData: FormData
47
- ): Promise<Result | undefined> {
48
- const email = formData.get('email') as string
49
- const password = formData.get('password') as string
50
-
51
- const parsedCredentials = z
52
- .object({
53
- email: z.string().email(),
54
- password: z.string().min(6)
55
- })
56
- .safeParse({
57
- email,
58
- password
59
- })
60
-
61
- if (parsedCredentials.success) {
62
- const salt = crypto.randomUUID()
63
-
64
- const encoder = new TextEncoder()
65
- const saltedPassword = encoder.encode(password + salt)
66
- const hashedPasswordBuffer = await crypto.subtle.digest(
67
- 'SHA-256',
68
- saltedPassword
69
- )
70
- const hashedPassword = getStringFromBuffer(hashedPasswordBuffer)
71
-
72
- try {
73
- const result = await createUser(email, hashedPassword, salt)
74
-
75
- if (result.resultCode === ResultCode.UserCreated) {
76
- await signIn('credentials', {
77
- email,
78
- password,
79
- redirect: false
80
- })
81
- }
82
-
83
- return result
84
- } catch (error) {
85
- if (error instanceof AuthError) {
86
- switch (error.type) {
87
- case 'CredentialsSignin':
88
- return {
89
- type: 'error',
90
- resultCode: ResultCode.InvalidCredentials
91
- }
92
- default:
93
- return {
94
- type: 'error',
95
- resultCode: ResultCode.UnknownError
96
- }
97
- }
98
- } else {
99
- return {
100
- type: 'error',
101
- resultCode: ResultCode.UnknownError
102
- }
103
- }
104
- }
105
- } else {
106
- return {
107
- type: 'error',
108
- resultCode: ResultCode.InvalidCredentials
109
- }
110
- }
111
- }
@@ -1,18 +0,0 @@
1
- import { auth } from '@/auth'
2
- import SignupForm from '@/components/signup-form'
3
- import { Session } from '@/lib/types'
4
- import { redirect } from 'next/navigation'
5
-
6
- export default async function SignupPage() {
7
- const session = (await auth()) as Session
8
-
9
- if (session) {
10
- redirect('/')
11
- }
12
-
13
- return (
14
- <main className="flex flex-col p-4">
15
- <SignupForm />
16
- </main>
17
- )
18
- }
Binary file
@@ -1,42 +0,0 @@
1
- import type { NextAuthConfig } from 'next-auth'
2
-
3
- export const authConfig = {
4
- secret: process.env.AUTH_SECRET,
5
- pages: {
6
- signIn: '/login',
7
- newUser: '/signup'
8
- },
9
- callbacks: {
10
- async authorized({ auth, request: { nextUrl } }) {
11
- const isLoggedIn = !!auth?.user
12
- const isOnLoginPage = nextUrl.pathname.startsWith('/login')
13
- const isOnSignupPage = nextUrl.pathname.startsWith('/signup')
14
-
15
- if (isLoggedIn) {
16
- if (isOnLoginPage || isOnSignupPage) {
17
- return Response.redirect(new URL('/', nextUrl))
18
- }
19
- }
20
-
21
- return true
22
- },
23
- async jwt({ token, user }) {
24
- if (user) {
25
- token = { ...token, id: user.id }
26
- }
27
-
28
- return token
29
- },
30
- async session({ session, token }) {
31
- if (token) {
32
- const { id } = token as { id: string }
33
- const { user } = session
34
-
35
- session = { ...session, user: { ...user, id } }
36
- }
37
-
38
- return session
39
- }
40
- },
41
- providers: []
42
- } satisfies NextAuthConfig
package/example/auth.ts DELETED
@@ -1,45 +0,0 @@
1
- import NextAuth from 'next-auth'
2
- import Credentials from 'next-auth/providers/credentials'
3
- import { authConfig } from './auth.config'
4
- import { z } from 'zod'
5
- import { getStringFromBuffer } from './lib/utils'
6
- import { getUser } from './app/login/actions'
7
-
8
- export const { auth, signIn, signOut } = NextAuth({
9
- ...authConfig,
10
- providers: [
11
- Credentials({
12
- async authorize(credentials) {
13
- const parsedCredentials = z
14
- .object({
15
- email: z.string().email(),
16
- password: z.string().min(6)
17
- })
18
- .safeParse(credentials)
19
-
20
- if (parsedCredentials.success) {
21
- const { email, password } = parsedCredentials.data
22
- const user = await getUser(email)
23
-
24
- if (!user) return null
25
-
26
- const encoder = new TextEncoder()
27
- const saltedPassword = encoder.encode(password + user.salt)
28
- const hashedPasswordBuffer = await crypto.subtle.digest(
29
- 'SHA-256',
30
- saltedPassword
31
- )
32
- const hashedPassword = getStringFromBuffer(hashedPasswordBuffer)
33
-
34
- if (hashedPassword === user.password) {
35
- return user
36
- } else {
37
- return null
38
- }
39
- }
40
-
41
- return null
42
- }
43
- })
44
- ]
45
- })
@@ -1,36 +0,0 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
-
5
- import { cn } from '@/lib/utils'
6
- import { Button, type ButtonProps } from '@/components/ui/button'
7
- import { IconArrowDown } from '@/components/ui/icons'
8
-
9
- interface ButtonScrollToBottomProps extends ButtonProps {
10
- isAtBottom: boolean
11
- scrollToBottom: () => void
12
- }
13
-
14
- export function ButtonScrollToBottom({
15
- className,
16
- isAtBottom,
17
- scrollToBottom,
18
- ...props
19
- }: ButtonScrollToBottomProps) {
20
- return (
21
- <Button
22
- variant="outline"
23
- size="icon"
24
- className={cn(
25
- 'absolute right-4 top-1 z-10 bg-background transition-opacity duration-300 sm:right-8 md:top-2',
26
- isAtBottom ? 'opacity-0' : 'opacity-100',
27
- className
28
- )}
29
- onClick={() => scrollToBottom()}
30
- {...props}
31
- >
32
- <IconArrowDown />
33
- <span className="sr-only">Scroll to bottom</span>
34
- </Button>
35
- )
36
- }
@@ -1,49 +0,0 @@
1
- import * as React from 'react'
2
-
3
- import Link from 'next/link'
4
-
5
- import { cn } from '@/lib/utils'
6
- import { SidebarList } from '@/components/sidebar-list'
7
- import { buttonVariants } from '@/components/ui/button'
8
- import { IconPlus } from '@/components/ui/icons'
9
-
10
- interface ChatHistoryProps {
11
- userId?: string
12
- }
13
-
14
- export async function ChatHistory({ userId }: ChatHistoryProps) {
15
- return (
16
- <div className="flex flex-col h-full">
17
- <div className="flex items-center justify-between p-4">
18
- <h4 className="text-sm font-medium">Chat History</h4>
19
- </div>
20
- <div className="mb-2 px-2">
21
- <Link
22
- href="/"
23
- className={cn(
24
- buttonVariants({ variant: 'outline' }),
25
- 'h-10 w-full justify-start bg-zinc-50 px-4 shadow-none transition-colors hover:bg-zinc-200/40 dark:bg-zinc-900 dark:hover:bg-zinc-300/10'
26
- )}
27
- >
28
- <IconPlus className="-translate-x-2 stroke-2" />
29
- New Chat
30
- </Link>
31
- </div>
32
- <React.Suspense
33
- fallback={
34
- <div className="flex flex-col flex-1 px-4 space-y-4 overflow-auto">
35
- {Array.from({ length: 10 }).map((_, i) => (
36
- <div
37
- key={i}
38
- className="w-full h-6 rounded-md shrink-0 animate-pulse bg-zinc-200 dark:bg-zinc-800"
39
- />
40
- ))}
41
- </div>
42
- }
43
- >
44
- {/* @ts-ignore */}
45
- <SidebarList userId={userId} />
46
- </React.Suspense>
47
- </div>
48
- )
49
- }
@@ -1,52 +0,0 @@
1
- import { Separator } from '@/components/ui/separator'
2
- import { UIState } from '@/lib/chat/vercel-ai'
3
- import { Session } from '@/lib/types'
4
- import Link from 'next/link'
5
- import { ExclamationTriangleIcon } from '@radix-ui/react-icons'
6
-
7
- export interface ChatList {
8
- messages: UIState
9
- session?: Session
10
- isShared: boolean
11
- }
12
-
13
- export function ChatList({ messages, session, isShared }: ChatList) {
14
- if (!messages.length) {
15
- return null
16
- }
17
-
18
- return (
19
- <div className="relative mx-auto max-w-2xl px-4">
20
- {!isShared && !session ? (
21
- <>
22
- <div className="group relative mb-4 flex items-start md:-ml-12">
23
- <div className="bg-background flex size-[25px] shrink-0 select-none items-center justify-center rounded-md border shadow-sm">
24
- <ExclamationTriangleIcon />
25
- </div>
26
- <div className="ml-4 flex-1 space-y-2 overflow-hidden px-1">
27
- <p className="text-muted-foreground leading-normal">
28
- Please{' '}
29
- <Link href="/login" className="underline">
30
- log in
31
- </Link>{' '}
32
- or{' '}
33
- <Link href="/signup" className="underline">
34
- sign up
35
- </Link>{' '}
36
- to save and revisit your chat history!
37
- </p>
38
- </div>
39
- </div>
40
- <Separator className="my-4" />
41
- </>
42
- ) : null}
43
-
44
- {messages.map((message, index) => (
45
- <div key={message.id}>
46
- {message.display}
47
- {index < messages.length - 1 && <Separator className="my-4" />}
48
- </div>
49
- ))}
50
- </div>
51
- )
52
- }
@@ -1,40 +0,0 @@
1
- 'use client'
2
-
3
- import { type Message } from 'ai'
4
-
5
- import { Button } from '@/components/ui/button'
6
- import { IconCheck, IconCopy } from '@/components/ui/icons'
7
- import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard'
8
- import { cn } from '@/lib/utils'
9
-
10
- interface ChatMessageActionsProps extends React.ComponentProps<'div'> {
11
- message: Message
12
- }
13
-
14
- export function ChatMessageActions({
15
- message,
16
- className,
17
- ...props
18
- }: ChatMessageActionsProps) {
19
- const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 })
20
-
21
- const onCopy = () => {
22
- if (isCopied) return
23
- copyToClipboard(message.content)
24
- }
25
-
26
- return (
27
- <div
28
- className={cn(
29
- 'flex items-center justify-end transition-opacity group-hover:opacity-100 md:absolute md:-right-10 md:-top-2 md:opacity-0',
30
- className
31
- )}
32
- {...props}
33
- >
34
- <Button variant="ghost" size="icon" onClick={onCopy}>
35
- {isCopied ? <IconCheck /> : <IconCopy />}
36
- <span className="sr-only">Copy message</span>
37
- </Button>
38
- </div>
39
- )
40
- }