@kood/claude-code 0.1.2 → 0.1.4

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 (63) hide show
  1. package/dist/index.js +129 -5
  2. package/package.json +2 -2
  3. package/templates/hono/CLAUDE.md +20 -2
  4. package/templates/hono/docs/architecture/architecture.md +909 -0
  5. package/templates/hono/docs/commands/git.md +275 -0
  6. package/templates/hono/docs/deployment/cloudflare.md +527 -190
  7. package/templates/hono/docs/deployment/docker.md +514 -0
  8. package/templates/hono/docs/deployment/index.md +179 -214
  9. package/templates/hono/docs/deployment/railway.md +416 -0
  10. package/templates/hono/docs/deployment/vercel.md +567 -0
  11. package/templates/hono/docs/library/ai-sdk/index.md +427 -0
  12. package/templates/hono/docs/library/ai-sdk/openrouter.md +479 -0
  13. package/templates/hono/docs/library/ai-sdk/providers.md +468 -0
  14. package/templates/hono/docs/library/ai-sdk/streaming.md +447 -0
  15. package/templates/hono/docs/library/ai-sdk/structured-output.md +493 -0
  16. package/templates/hono/docs/library/ai-sdk/tools.md +513 -0
  17. package/templates/hono/docs/library/hono/env-setup.md +458 -0
  18. package/templates/hono/docs/library/hono/index.md +1 -3
  19. package/templates/hono/docs/library/pino/index.md +437 -0
  20. package/templates/hono/docs/library/prisma/cloudflare-d1.md +503 -0
  21. package/templates/hono/docs/library/prisma/config.md +362 -0
  22. package/templates/hono/docs/library/prisma/index.md +86 -13
  23. package/templates/hono/docs/skills/gemini-review/SKILL.md +116 -116
  24. package/templates/hono/docs/skills/gemini-review/references/checklists.md +125 -125
  25. package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +191 -191
  26. package/templates/npx/CLAUDE.md +309 -0
  27. package/templates/npx/docs/commands/git.md +275 -0
  28. package/templates/npx/docs/library/commander/index.md +164 -0
  29. package/templates/npx/docs/library/fs-extra/index.md +171 -0
  30. package/templates/npx/docs/library/prompts/index.md +253 -0
  31. package/templates/npx/docs/mcp/index.md +60 -0
  32. package/templates/npx/docs/skills/gemini-review/SKILL.md +220 -0
  33. package/templates/npx/docs/skills/gemini-review/references/checklists.md +134 -0
  34. package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +301 -0
  35. package/templates/tanstack-start/CLAUDE.md +43 -5
  36. package/templates/tanstack-start/docs/architecture/architecture.md +134 -4
  37. package/templates/tanstack-start/docs/commands/git.md +275 -0
  38. package/templates/tanstack-start/docs/deployment/cloudflare.md +223 -50
  39. package/templates/tanstack-start/docs/deployment/index.md +320 -30
  40. package/templates/tanstack-start/docs/deployment/nitro.md +195 -14
  41. package/templates/tanstack-start/docs/deployment/railway.md +302 -150
  42. package/templates/tanstack-start/docs/deployment/vercel.md +345 -75
  43. package/templates/tanstack-start/docs/guides/best-practices.md +203 -1
  44. package/templates/tanstack-start/docs/guides/env-setup.md +450 -0
  45. package/templates/tanstack-start/docs/library/ai-sdk/hooks.md +472 -0
  46. package/templates/tanstack-start/docs/library/ai-sdk/index.md +264 -0
  47. package/templates/tanstack-start/docs/library/ai-sdk/openrouter.md +371 -0
  48. package/templates/tanstack-start/docs/library/ai-sdk/providers.md +403 -0
  49. package/templates/tanstack-start/docs/library/ai-sdk/streaming.md +320 -0
  50. package/templates/tanstack-start/docs/library/ai-sdk/structured-output.md +454 -0
  51. package/templates/tanstack-start/docs/library/ai-sdk/tools.md +473 -0
  52. package/templates/tanstack-start/docs/library/pino/index.md +320 -0
  53. package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +404 -0
  54. package/templates/tanstack-start/docs/library/prisma/config.md +377 -0
  55. package/templates/tanstack-start/docs/library/prisma/index.md +3 -5
  56. package/templates/tanstack-start/docs/library/prisma/schema.md +123 -25
  57. package/templates/tanstack-start/docs/library/prisma/setup.md +0 -7
  58. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +80 -2
  59. package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +116 -116
  60. package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +138 -144
  61. package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +186 -187
  62. package/templates/hono/docs/git/index.md +0 -180
  63. package/templates/tanstack-start/docs/git/index.md +0 -203
@@ -0,0 +1,472 @@
1
+ # AI SDK - React Hooks
2
+
3
+ > **상위 문서**: [AI SDK](./index.md)
4
+
5
+ ---
6
+
7
+ ## 개요
8
+
9
+ AI SDK는 React 애플리케이션을 위한 훅을 제공합니다:
10
+ - `useChat`: 채팅 인터페이스
11
+ - `useCompletion`: 텍스트 완성
12
+ - `useObject`: 구조화된 객체 생성 (실험적)
13
+
14
+ ```bash
15
+ npm install @ai-sdk/react
16
+ ```
17
+
18
+ ---
19
+
20
+ ## useChat
21
+
22
+ 채팅 인터페이스를 쉽게 구현할 수 있는 훅입니다.
23
+
24
+ ### 기본 사용
25
+
26
+ ```tsx
27
+ 'use client'
28
+
29
+ import { useChat } from '@ai-sdk/react'
30
+
31
+ export default function Chat() {
32
+ const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
33
+ api: '/api/chat',
34
+ })
35
+
36
+ return (
37
+ <div>
38
+ {messages.map((m) => (
39
+ <div key={m.id}>
40
+ <strong>{m.role}:</strong> {m.content}
41
+ </div>
42
+ ))}
43
+
44
+ <form onSubmit={handleSubmit}>
45
+ <input
46
+ value={input}
47
+ onChange={handleInputChange}
48
+ placeholder="Type a message..."
49
+ disabled={isLoading}
50
+ />
51
+ <button type="submit" disabled={isLoading}>
52
+ {isLoading ? 'Sending...' : 'Send'}
53
+ </button>
54
+ </form>
55
+ </div>
56
+ )
57
+ }
58
+ ```
59
+
60
+ ### 반환값
61
+
62
+ ```typescript
63
+ const {
64
+ // 메시지 관련
65
+ messages, // Message[] - 전체 메시지 목록
66
+ setMessages, // 메시지 직접 설정
67
+
68
+ // 입력 관련
69
+ input, // string - 현재 입력값
70
+ setInput, // 입력값 직접 설정
71
+ handleInputChange, // 입력 변경 핸들러
72
+
73
+ // 제출 관련
74
+ handleSubmit, // 폼 제출 핸들러
75
+ append, // 메시지 추가 및 전송
76
+ reload, // 마지막 응답 재생성
77
+
78
+ // 상태 관련
79
+ isLoading, // 응답 대기 중
80
+ error, // 에러 객체
81
+ stop, // 스트리밍 중단
82
+ } = useChat()
83
+ ```
84
+
85
+ ### 메시지 타입
86
+
87
+ ```typescript
88
+ interface Message {
89
+ id: string
90
+ role: 'user' | 'assistant' | 'system'
91
+ content: string
92
+ createdAt?: Date
93
+ toolInvocations?: ToolInvocation[]
94
+ }
95
+ ```
96
+
97
+ ### API Route 설정
98
+
99
+ ```typescript
100
+ // app/api/chat/route.ts
101
+ import { streamText, convertToModelMessages } from 'ai'
102
+ import { openai } from '@ai-sdk/openai'
103
+
104
+ export async function POST(req: Request) {
105
+ const { messages } = await req.json()
106
+
107
+ const result = streamText({
108
+ model: openai('gpt-4o'),
109
+ messages: convertToModelMessages(messages),
110
+ })
111
+
112
+ return result.toUIMessageStreamResponse()
113
+ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## useChat 고급 기능
119
+
120
+ ### 초기 메시지
121
+
122
+ ```tsx
123
+ const { messages } = useChat({
124
+ api: '/api/chat',
125
+ initialMessages: [
126
+ { id: '1', role: 'assistant', content: 'Hello! How can I help you?' },
127
+ ],
128
+ })
129
+ ```
130
+
131
+ ### 동적 요청 데이터
132
+
133
+ ```tsx
134
+ const [temperature, setTemperature] = useState(0.7)
135
+
136
+ const { messages, handleSubmit } = useChat({
137
+ api: '/api/chat',
138
+ body: {
139
+ temperature,
140
+ userId: 'user-123',
141
+ },
142
+ headers: {
143
+ Authorization: `Bearer ${token}`,
144
+ },
145
+ })
146
+ ```
147
+
148
+ 서버에서 추가 데이터 접근:
149
+
150
+ ```typescript
151
+ // app/api/chat/route.ts
152
+ export async function POST(req: Request) {
153
+ const { messages, temperature, userId } = await req.json()
154
+
155
+ const result = streamText({
156
+ model: openai('gpt-4o'),
157
+ messages: convertToModelMessages(messages),
158
+ temperature, // 동적 파라미터 사용
159
+ })
160
+
161
+ return result.toUIMessageStreamResponse()
162
+ }
163
+ ```
164
+
165
+ ### 콜백 함수
166
+
167
+ ```tsx
168
+ const { messages } = useChat({
169
+ api: '/api/chat',
170
+ onResponse: (response) => {
171
+ console.log('Received response:', response)
172
+ },
173
+ onFinish: (message) => {
174
+ console.log('Finished:', message)
175
+ },
176
+ onError: (error) => {
177
+ console.error('Error:', error)
178
+ toast.error('Something went wrong')
179
+ },
180
+ })
181
+ ```
182
+
183
+ ### 메시지 직접 추가
184
+
185
+ ```tsx
186
+ const { append } = useChat()
187
+
188
+ // 사용자 메시지 추가 및 전송
189
+ const handleClick = async () => {
190
+ await append({
191
+ role: 'user',
192
+ content: 'Tell me a joke',
193
+ })
194
+ }
195
+ ```
196
+
197
+ ### 스트리밍 중단
198
+
199
+ ```tsx
200
+ const { stop, isLoading } = useChat()
201
+
202
+ return (
203
+ <button onClick={stop} disabled={!isLoading}>
204
+ Stop generating
205
+ </button>
206
+ )
207
+ ```
208
+
209
+ ### 마지막 응답 재생성
210
+
211
+ ```tsx
212
+ const { reload, messages } = useChat()
213
+
214
+ return (
215
+ <button onClick={reload} disabled={messages.length === 0}>
216
+ Regenerate response
217
+ </button>
218
+ )
219
+ ```
220
+
221
+ ### UI 업데이트 쓰로틀링
222
+
223
+ 대량의 스트리밍 데이터가 있을 때 성능 최적화:
224
+
225
+ ```tsx
226
+ const { messages } = useChat({
227
+ api: '/api/chat',
228
+ experimental_throttle: 50, // 50ms마다 UI 업데이트
229
+ })
230
+ ```
231
+
232
+ ---
233
+
234
+ ## useCompletion
235
+
236
+ 단순 텍스트 완성을 위한 훅입니다.
237
+
238
+ ### 기본 사용
239
+
240
+ ```tsx
241
+ 'use client'
242
+
243
+ import { useCompletion } from '@ai-sdk/react'
244
+
245
+ export default function Completion() {
246
+ const { completion, input, handleInputChange, handleSubmit, isLoading } = useCompletion({
247
+ api: '/api/completion',
248
+ })
249
+
250
+ return (
251
+ <div>
252
+ <form onSubmit={handleSubmit}>
253
+ <input
254
+ value={input}
255
+ onChange={handleInputChange}
256
+ placeholder="Enter a prompt..."
257
+ />
258
+ <button type="submit" disabled={isLoading}>
259
+ Complete
260
+ </button>
261
+ </form>
262
+
263
+ <div>{completion}</div>
264
+ </div>
265
+ )
266
+ }
267
+ ```
268
+
269
+ ### 반환값
270
+
271
+ ```typescript
272
+ const {
273
+ completion, // string - 생성된 텍스트
274
+ complete, // 직접 완성 요청
275
+ input, // string - 현재 입력값
276
+ setInput, // 입력값 설정
277
+ handleInputChange, // 입력 변경 핸들러
278
+ handleSubmit, // 폼 제출 핸들러
279
+ isLoading, // 로딩 상태
280
+ error, // 에러 객체
281
+ stop, // 스트리밍 중단
282
+ setCompletion, // 완성 텍스트 직접 설정
283
+ } = useCompletion()
284
+ ```
285
+
286
+ ### API Route
287
+
288
+ ```typescript
289
+ // app/api/completion/route.ts
290
+ import { streamText } from 'ai'
291
+ import { openai } from '@ai-sdk/openai'
292
+
293
+ export async function POST(req: Request) {
294
+ const { prompt } = await req.json()
295
+
296
+ const result = streamText({
297
+ model: openai('gpt-4o'),
298
+ prompt,
299
+ })
300
+
301
+ return result.toUIMessageStreamResponse()
302
+ }
303
+ ```
304
+
305
+ ### 프로그래매틱 호출
306
+
307
+ ```tsx
308
+ const { complete, completion } = useCompletion({
309
+ api: '/api/completion',
310
+ })
311
+
312
+ const handleClick = async () => {
313
+ await complete('Write a haiku about programming')
314
+ }
315
+ ```
316
+
317
+ ### 콜백
318
+
319
+ ```tsx
320
+ const { completion } = useCompletion({
321
+ onResponse: (response) => {
322
+ console.log('Response received')
323
+ },
324
+ onFinish: (prompt, completion) => {
325
+ console.log('Finished:', completion)
326
+ },
327
+ onError: (error) => {
328
+ console.error('Error:', error)
329
+ },
330
+ })
331
+ ```
332
+
333
+ ---
334
+
335
+ ## useObject (실험적)
336
+
337
+ 구조화된 객체를 스트리밍으로 생성합니다.
338
+
339
+ ### 기본 사용
340
+
341
+ ```tsx
342
+ 'use client'
343
+
344
+ import { experimental_useObject as useObject } from '@ai-sdk/react'
345
+ import { z } from 'zod'
346
+
347
+ const schema = z.object({
348
+ name: z.string(),
349
+ age: z.number(),
350
+ hobbies: z.array(z.string()),
351
+ })
352
+
353
+ export default function ObjectGenerator() {
354
+ const { object, submit, isLoading, error } = useObject({
355
+ api: '/api/generate-object',
356
+ schema,
357
+ })
358
+
359
+ return (
360
+ <div>
361
+ <button onClick={() => submit('Generate a random person')} disabled={isLoading}>
362
+ Generate
363
+ </button>
364
+
365
+ {object && (
366
+ <pre>{JSON.stringify(object, null, 2)}</pre>
367
+ )}
368
+ </div>
369
+ )
370
+ }
371
+ ```
372
+
373
+ ### API Route
374
+
375
+ ```typescript
376
+ // app/api/generate-object/route.ts
377
+ import { streamObject } from 'ai'
378
+ import { openai } from '@ai-sdk/openai'
379
+ import { z } from 'zod'
380
+
381
+ const schema = z.object({
382
+ name: z.string(),
383
+ age: z.number(),
384
+ hobbies: z.array(z.string()),
385
+ })
386
+
387
+ export async function POST(req: Request) {
388
+ const { prompt } = await req.json()
389
+
390
+ const result = streamObject({
391
+ model: openai('gpt-4o'),
392
+ schema,
393
+ prompt,
394
+ })
395
+
396
+ return result.toTextStreamResponse()
397
+ }
398
+ ```
399
+
400
+ ---
401
+
402
+ ## 도구 호출 표시
403
+
404
+ 채팅에서 도구 호출을 표시하는 방법:
405
+
406
+ ```tsx
407
+ 'use client'
408
+
409
+ import { useChat } from '@ai-sdk/react'
410
+
411
+ export default function Chat() {
412
+ const { messages } = useChat({
413
+ api: '/api/chat',
414
+ })
415
+
416
+ return (
417
+ <div>
418
+ {messages.map((m) => (
419
+ <div key={m.id}>
420
+ <strong>{m.role}:</strong>
421
+
422
+ {/* 텍스트 콘텐츠 */}
423
+ {m.content}
424
+
425
+ {/* 도구 호출 표시 */}
426
+ {m.toolInvocations?.map((tool, i) => (
427
+ <div key={i} className="tool-call">
428
+ <strong>Tool: {tool.toolName}</strong>
429
+ <pre>Input: {JSON.stringify(tool.args, null, 2)}</pre>
430
+ {tool.state === 'result' && (
431
+ <pre>Result: {JSON.stringify(tool.result, null, 2)}</pre>
432
+ )}
433
+ </div>
434
+ ))}
435
+ </div>
436
+ ))}
437
+ </div>
438
+ )
439
+ }
440
+ ```
441
+
442
+ ---
443
+
444
+ ## 스트림 프로토콜
445
+
446
+ AI SDK v5에서는 기본 스트림 프로토콜이 변경되었습니다:
447
+
448
+ ```tsx
449
+ // v5 기본값 (data protocol)
450
+ const { messages } = useChat()
451
+
452
+ // 레거시 텍스트 프로토콜 사용
453
+ const { messages } = useChat({
454
+ streamProtocol: 'text',
455
+ })
456
+ ```
457
+
458
+ ---
459
+
460
+ ## 타입 안전성
461
+
462
+ ```typescript
463
+ import { useChat, Message } from '@ai-sdk/react'
464
+
465
+ // 메시지 타입 확장
466
+ interface CustomMessage extends Message {
467
+ customField?: string
468
+ }
469
+
470
+ // 타입 지정
471
+ const { messages } = useChat<CustomMessage>()
472
+ ```
@@ -0,0 +1,264 @@
1
+ # Vercel AI SDK
2
+
3
+ > **Version**: 4.x / 5.x | TypeScript AI Toolkit
4
+
5
+ ---
6
+
7
+ ## 🚀 Quick Reference (복사용)
8
+
9
+ ```typescript
10
+ // 텍스트 생성
11
+ import { generateText, streamText } from 'ai'
12
+ import { openai } from '@ai-sdk/openai'
13
+
14
+ const { text } = await generateText({
15
+ model: openai('gpt-4o'),
16
+ prompt: 'Hello, world!',
17
+ })
18
+
19
+ // 스트리밍
20
+ const result = streamText({
21
+ model: openai('gpt-4o'),
22
+ prompt: 'Write a story.',
23
+ })
24
+
25
+ for await (const chunk of result.textStream) {
26
+ console.log(chunk)
27
+ }
28
+
29
+ // 구조화된 출력
30
+ import { generateObject } from 'ai'
31
+ import { z } from 'zod'
32
+
33
+ const { object } = await generateObject({
34
+ model: openai('gpt-4o'),
35
+ schema: z.object({ name: z.string(), age: z.number() }),
36
+ prompt: 'Generate a user.',
37
+ })
38
+
39
+ // React Hook
40
+ import { useChat } from '@ai-sdk/react'
41
+
42
+ const { messages, input, handleInputChange, handleSubmit } = useChat()
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 문서 구조
48
+
49
+ - [프로바이더 설정](./providers.md) - OpenAI, Anthropic, Google 등
50
+ - [OpenRouter](./openrouter.md) - 통합 AI 게이트웨이 (수백 개 모델)
51
+ - [텍스트 생성](./streaming.md) - generateText, streamText
52
+ - [React Hooks](./hooks.md) - useChat, useCompletion
53
+ - [Tool Calling](./tools.md) - 도구 정의 및 호출
54
+ - [구조화된 출력](./structured-output.md) - generateObject, 스키마 기반 출력
55
+
56
+ ---
57
+
58
+ ## 설치
59
+
60
+ ```bash
61
+ # 코어 패키지
62
+ npm install ai
63
+
64
+ # 프로바이더 패키지 (필요한 것만 설치)
65
+ npm install @ai-sdk/openai # OpenAI
66
+ npm install @ai-sdk/anthropic # Anthropic (Claude)
67
+ npm install @ai-sdk/google # Google (Gemini)
68
+
69
+ # React Hook 사용 시
70
+ npm install @ai-sdk/react
71
+ ```
72
+
73
+ ---
74
+
75
+ ## 핵심 개념
76
+
77
+ ### 프로바이더 (Providers)
78
+
79
+ AI 모델 서비스와의 연결을 담당합니다.
80
+
81
+ ```typescript
82
+ import { openai } from '@ai-sdk/openai'
83
+ import { anthropic } from '@ai-sdk/anthropic'
84
+ import { google } from '@ai-sdk/google'
85
+
86
+ // 모델 인스턴스 생성
87
+ const gpt4 = openai('gpt-4o')
88
+ const claude = anthropic('claude-3-5-sonnet-20241022')
89
+ const gemini = google('gemini-1.5-pro')
90
+ ```
91
+
92
+ ### 코어 함수
93
+
94
+ | 함수 | 용도 | 반환 |
95
+ |------|------|------|
96
+ | `generateText` | 텍스트 생성 (비스트리밍) | `{ text, toolCalls, ... }` |
97
+ | `streamText` | 텍스트 스트리밍 | `{ textStream, ... }` |
98
+ | `generateObject` | 구조화된 객체 생성 | `{ object }` |
99
+ | `streamObject` | 구조화된 객체 스트리밍 | `{ partialObjectStream }` |
100
+
101
+ ### React Hooks
102
+
103
+ | Hook | 용도 |
104
+ |------|------|
105
+ | `useChat` | 채팅 인터페이스 |
106
+ | `useCompletion` | 텍스트 완성 |
107
+ | `useObject` | 구조화된 객체 생성 (실험적) |
108
+
109
+ ---
110
+
111
+ ## 기본 사용법
112
+
113
+ ### 텍스트 생성
114
+
115
+ ```typescript
116
+ import { generateText } from 'ai'
117
+ import { openai } from '@ai-sdk/openai'
118
+
119
+ const { text, usage } = await generateText({
120
+ model: openai('gpt-4o'),
121
+ prompt: 'Explain quantum computing in simple terms.',
122
+ })
123
+
124
+ console.log(text)
125
+ console.log(`Tokens used: ${usage.totalTokens}`)
126
+ ```
127
+
128
+ ### 스트리밍
129
+
130
+ ```typescript
131
+ import { streamText } from 'ai'
132
+ import { openai } from '@ai-sdk/openai'
133
+
134
+ const result = streamText({
135
+ model: openai('gpt-4o'),
136
+ prompt: 'Write a haiku about programming.',
137
+ })
138
+
139
+ for await (const chunk of result.textStream) {
140
+ process.stdout.write(chunk)
141
+ }
142
+ ```
143
+
144
+ ### 채팅 (메시지 기반)
145
+
146
+ ```typescript
147
+ import { generateText } from 'ai'
148
+ import { openai } from '@ai-sdk/openai'
149
+
150
+ const { text } = await generateText({
151
+ model: openai('gpt-4o'),
152
+ messages: [
153
+ { role: 'system', content: 'You are a helpful assistant.' },
154
+ { role: 'user', content: 'What is TypeScript?' },
155
+ ],
156
+ })
157
+ ```
158
+
159
+ ---
160
+
161
+ ## TanStack Start 통합
162
+
163
+ ### API Route 설정
164
+
165
+ ```typescript
166
+ // app/api/chat/route.ts
167
+ import { streamText, convertToModelMessages } from 'ai'
168
+ import { openai } from '@ai-sdk/openai'
169
+
170
+ export async function POST(req: Request) {
171
+ const { messages } = await req.json()
172
+
173
+ const result = streamText({
174
+ model: openai('gpt-4o'),
175
+ messages: convertToModelMessages(messages),
176
+ })
177
+
178
+ return result.toUIMessageStreamResponse()
179
+ }
180
+ ```
181
+
182
+ ### 클라이언트 컴포넌트
183
+
184
+ ```tsx
185
+ 'use client'
186
+
187
+ import { useChat } from '@ai-sdk/react'
188
+
189
+ export default function Chat() {
190
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
191
+ api: '/api/chat',
192
+ })
193
+
194
+ return (
195
+ <div>
196
+ {messages.map((m) => (
197
+ <div key={m.id}>
198
+ <strong>{m.role}:</strong> {m.content}
199
+ </div>
200
+ ))}
201
+
202
+ <form onSubmit={handleSubmit}>
203
+ <input value={input} onChange={handleInputChange} placeholder="Say something..." />
204
+ <button type="submit">Send</button>
205
+ </form>
206
+ </div>
207
+ )
208
+ }
209
+ ```
210
+
211
+ ---
212
+
213
+ ## 환경 변수
214
+
215
+ ```bash
216
+ # .env
217
+ OPENAI_API_KEY=sk-...
218
+ ANTHROPIC_API_KEY=sk-ant-...
219
+ GOOGLE_GENERATIVE_AI_API_KEY=...
220
+ ```
221
+
222
+ ---
223
+
224
+ ## v5 주요 변경사항
225
+
226
+ ### 스트림 프로토콜 변경
227
+
228
+ ```typescript
229
+ // v4 - text protocol 명시 필요
230
+ const { messages } = useChat({ streamProtocol: 'text' })
231
+
232
+ // v5 - 기본값이 data protocol
233
+ const { messages } = useChat()
234
+ ```
235
+
236
+ ### 프로바이더 초기화 변경
237
+
238
+ ```typescript
239
+ // v4 (deprecated)
240
+ const openai = new OpenAI({ /* ... */ })
241
+
242
+ // v5
243
+ import { createOpenAI } from '@ai-sdk/openai'
244
+ const openai = createOpenAI({ /* ... */ })
245
+ ```
246
+
247
+ ### responseMessages 제거
248
+
249
+ ```typescript
250
+ // v4
251
+ const { text, responseMessages } = await generateText({ ... })
252
+
253
+ // v5
254
+ const { text, response } = await generateText({ ... })
255
+ const responseMessages = response.messages
256
+ ```
257
+
258
+ ---
259
+
260
+ ## 참고 자료
261
+
262
+ - [AI SDK 공식 문서](https://sdk.vercel.ai/docs)
263
+ - [AI SDK GitHub](https://github.com/vercel/ai)
264
+ - [AI SDK 예제](https://github.com/vercel/ai/tree/main/examples)