@kood/claude-code 0.1.7 → 0.1.9
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.
- package/dist/index.js +118 -3
- package/package.json +8 -2
- package/templates/hono/CLAUDE.md +53 -326
- package/templates/hono/docs/architecture/architecture.md +93 -747
- package/templates/hono/docs/deployment/cloudflare.md +59 -513
- package/templates/hono/docs/deployment/docker.md +41 -356
- package/templates/hono/docs/deployment/index.md +49 -190
- package/templates/hono/docs/deployment/railway.md +36 -306
- package/templates/hono/docs/deployment/vercel.md +49 -434
- package/templates/hono/docs/library/ai-sdk/index.md +53 -290
- package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
- package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
- package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
- package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
- package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
- package/templates/hono/docs/library/hono/env-setup.md +24 -313
- package/templates/hono/docs/library/hono/error-handling.md +34 -295
- package/templates/hono/docs/library/hono/index.md +24 -122
- package/templates/hono/docs/library/hono/middleware.md +21 -188
- package/templates/hono/docs/library/hono/rpc.md +40 -341
- package/templates/hono/docs/library/hono/validation.md +35 -195
- package/templates/hono/docs/library/pino/index.md +42 -333
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
- package/templates/hono/docs/library/prisma/config.md +19 -260
- package/templates/hono/docs/library/prisma/index.md +64 -320
- package/templates/hono/docs/library/zod/index.md +53 -257
- package/templates/npx/CLAUDE.md +58 -276
- package/templates/npx/docs/references/patterns.md +160 -0
- package/templates/tanstack-start/CLAUDE.md +0 -4
- package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
- package/templates/tanstack-start/docs/design/index.md +119 -12
- package/templates/tanstack-start/docs/guides/conventions.md +103 -0
- package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
- package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
- package/templates/tanstack-start/docs/guides/hooks.md +166 -0
- package/templates/tanstack-start/docs/guides/routes.md +166 -0
- package/templates/tanstack-start/docs/guides/services.md +143 -0
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +18 -2
- package/templates/tanstack-start/docs/library/zod/index.md +16 -1
- package/templates/tanstack-start/docs/design/accessibility.md +0 -163
- package/templates/tanstack-start/docs/design/color.md +0 -93
- package/templates/tanstack-start/docs/design/spacing.md +0 -122
- package/templates/tanstack-start/docs/design/typography.md +0 -80
- package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
- package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
- package/templates/tanstack-start/docs/guides/prettier.md +0 -189
- package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
- package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -48
- package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# AI SDK - Hono 통합
|
|
1
|
+
# AI SDK - Hono 통합
|
|
2
2
|
|
|
3
|
-
> Vercel AI SDK
|
|
3
|
+
> Vercel AI SDK + Hono
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
@providers.md
|
|
6
|
+
@openrouter.md
|
|
7
|
+
@streaming.md
|
|
8
|
+
@tools.md
|
|
9
|
+
@structured-output.md
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -14,22 +14,26 @@ AI SDK는 TypeScript 기반의 AI 애플리케이션 개발 라이브러리입
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install ai @ai-sdk/openai
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### 프로바이더별 설치
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
npm install @ai-sdk/anthropic
|
|
23
|
-
npm install @ai-sdk/google
|
|
24
|
-
npm install @ai-sdk/mistral # Mistral
|
|
25
|
-
npm install @ai-sdk/groq # Groq
|
|
18
|
+
# 다른 프로바이더
|
|
19
|
+
npm install @ai-sdk/anthropic # Claude
|
|
20
|
+
npm install @ai-sdk/google # Gemini
|
|
26
21
|
```
|
|
27
22
|
|
|
28
23
|
---
|
|
29
24
|
|
|
30
|
-
##
|
|
25
|
+
## 핵심 함수
|
|
26
|
+
|
|
27
|
+
| 함수 | 용도 |
|
|
28
|
+
|------|------|
|
|
29
|
+
| `generateText` | 텍스트 생성 (비스트리밍) |
|
|
30
|
+
| `streamText` | 텍스트 스트리밍 |
|
|
31
|
+
| `generateObject` | 구조화된 객체 생성 |
|
|
32
|
+
| `streamObject` | 객체 스트리밍 |
|
|
33
|
+
|
|
34
|
+
---
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
## 기본 채팅 API
|
|
33
37
|
|
|
34
38
|
```typescript
|
|
35
39
|
import { Hono } from 'hono'
|
|
@@ -48,18 +52,14 @@ app.post('/api/chat', async (c) => {
|
|
|
48
52
|
|
|
49
53
|
return result.toUIMessageStreamResponse()
|
|
50
54
|
})
|
|
51
|
-
|
|
52
|
-
export default app
|
|
53
55
|
```
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 텍스트 생성
|
|
56
60
|
|
|
57
61
|
```typescript
|
|
58
|
-
import { Hono } from 'hono'
|
|
59
62
|
import { generateText } from 'ai'
|
|
60
|
-
import { openai } from '@ai-sdk/openai'
|
|
61
|
-
|
|
62
|
-
const app = new Hono()
|
|
63
63
|
|
|
64
64
|
app.post('/api/generate', async (c) => {
|
|
65
65
|
const { prompt } = await c.req.json()
|
|
@@ -71,170 +71,17 @@ app.post('/api/generate', async (c) => {
|
|
|
71
71
|
|
|
72
72
|
return c.json({ text })
|
|
73
73
|
})
|
|
74
|
-
|
|
75
|
-
export default app
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 핵심 함수
|
|
81
|
-
|
|
82
|
-
| 함수 | 용도 | 응답 타입 |
|
|
83
|
-
|------|------|----------|
|
|
84
|
-
| `generateText` | 텍스트 생성 (비스트리밍) | `Promise<{ text }>` |
|
|
85
|
-
| `streamText` | 텍스트 스트리밍 | `StreamTextResult` |
|
|
86
|
-
| `generateObject` | 구조화된 객체 생성 | `Promise<{ object }>` |
|
|
87
|
-
| `streamObject` | 객체 스트리밍 | `StreamObjectResult` |
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## Hono 미들웨어 패턴
|
|
92
|
-
|
|
93
|
-
### AI 컨텍스트 미들웨어
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
import { Hono } from 'hono'
|
|
97
|
-
import { createMiddleware } from 'hono/factory'
|
|
98
|
-
import { openai } from '@ai-sdk/openai'
|
|
99
|
-
|
|
100
|
-
type AIVariables = {
|
|
101
|
-
aiModel: ReturnType<typeof openai>
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const aiMiddleware = createMiddleware<{ Variables: AIVariables }>(
|
|
105
|
-
async (c, next) => {
|
|
106
|
-
c.set('aiModel', openai('gpt-4o'))
|
|
107
|
-
await next()
|
|
108
|
-
}
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
const app = new Hono<{ Variables: AIVariables }>()
|
|
112
|
-
|
|
113
|
-
app.use('/api/ai/*', aiMiddleware)
|
|
114
|
-
|
|
115
|
-
app.post('/api/ai/chat', async (c) => {
|
|
116
|
-
const model = c.get('aiModel')
|
|
117
|
-
const { messages } = await c.req.json()
|
|
118
|
-
|
|
119
|
-
const result = streamText({
|
|
120
|
-
model,
|
|
121
|
-
messages,
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
return result.toUIMessageStreamResponse()
|
|
125
|
-
})
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Rate Limiting 미들웨어
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
import { Hono } from 'hono'
|
|
132
|
-
import { rateLimiter } from 'hono-rate-limiter'
|
|
133
|
-
import { streamText } from 'ai'
|
|
134
|
-
import { openai } from '@ai-sdk/openai'
|
|
135
|
-
|
|
136
|
-
const app = new Hono()
|
|
137
|
-
|
|
138
|
-
// AI 엔드포인트에 Rate Limiting 적용
|
|
139
|
-
app.use(
|
|
140
|
-
'/api/ai/*',
|
|
141
|
-
rateLimiter({
|
|
142
|
-
windowMs: 60 * 1000, // 1분
|
|
143
|
-
limit: 10, // 최대 10 요청
|
|
144
|
-
standardHeaders: 'draft-6',
|
|
145
|
-
keyGenerator: (c) => c.req.header('x-forwarded-for') ?? 'anonymous',
|
|
146
|
-
})
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
app.post('/api/ai/chat', async (c) => {
|
|
150
|
-
const { messages } = await c.req.json()
|
|
151
|
-
|
|
152
|
-
const result = streamText({
|
|
153
|
-
model: openai('gpt-4o'),
|
|
154
|
-
messages,
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
return result.toUIMessageStreamResponse()
|
|
158
|
-
})
|
|
159
74
|
```
|
|
160
75
|
|
|
161
76
|
---
|
|
162
77
|
|
|
163
|
-
##
|
|
164
|
-
|
|
165
|
-
### 기본 스트리밍
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
import { Hono } from 'hono'
|
|
169
|
-
import { streamText } from 'ai'
|
|
170
|
-
import { openai } from '@ai-sdk/openai'
|
|
171
|
-
|
|
172
|
-
const app = new Hono()
|
|
173
|
-
|
|
174
|
-
app.post('/api/stream', async (c) => {
|
|
175
|
-
const { prompt } = await c.req.json()
|
|
176
|
-
|
|
177
|
-
const result = streamText({
|
|
178
|
-
model: openai('gpt-4o'),
|
|
179
|
-
prompt,
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
// UI 메시지 스트림 (프론트엔드용)
|
|
183
|
-
return result.toUIMessageStreamResponse()
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
app.post('/api/stream-text', async (c) => {
|
|
187
|
-
const { prompt } = await c.req.json()
|
|
188
|
-
|
|
189
|
-
const result = streamText({
|
|
190
|
-
model: openai('gpt-4o'),
|
|
191
|
-
prompt,
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
// 텍스트 스트림 (SSE)
|
|
195
|
-
return result.toTextStreamResponse()
|
|
196
|
-
})
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### 커스텀 스트림 처리
|
|
78
|
+
## 도구 (Tool)
|
|
200
79
|
|
|
201
80
|
```typescript
|
|
202
|
-
import { Hono } from 'hono'
|
|
203
|
-
import { streamText } from 'ai'
|
|
204
|
-
import { openai } from '@ai-sdk/openai'
|
|
205
|
-
import { stream } from 'hono/streaming'
|
|
206
|
-
|
|
207
|
-
const app = new Hono()
|
|
208
|
-
|
|
209
|
-
app.post('/api/custom-stream', async (c) => {
|
|
210
|
-
const { prompt } = await c.req.json()
|
|
211
|
-
|
|
212
|
-
const result = streamText({
|
|
213
|
-
model: openai('gpt-4o'),
|
|
214
|
-
prompt,
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
return stream(c, async (stream) => {
|
|
218
|
-
for await (const chunk of result.textStream) {
|
|
219
|
-
await stream.write(chunk)
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## 도구 (Tool) 통합
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
import { Hono } from 'hono'
|
|
231
81
|
import { streamText, tool, convertToModelMessages } from 'ai'
|
|
232
|
-
import { openai } from '@ai-sdk/openai'
|
|
233
82
|
import { z } from 'zod'
|
|
234
83
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
app.post('/api/chat-with-tools', async (c) => {
|
|
84
|
+
app.post('/api/chat', async (c) => {
|
|
238
85
|
const { messages } = await c.req.json()
|
|
239
86
|
|
|
240
87
|
const result = streamText({
|
|
@@ -247,20 +94,9 @@ app.post('/api/chat-with-tools', async (c) => {
|
|
|
247
94
|
location: z.string().describe('City name'),
|
|
248
95
|
}),
|
|
249
96
|
execute: async ({ location }) => {
|
|
250
|
-
// 실제 날씨 API 호출
|
|
251
97
|
return { location, temperature: 22, condition: 'Sunny' }
|
|
252
98
|
},
|
|
253
99
|
}),
|
|
254
|
-
searchDatabase: tool({
|
|
255
|
-
description: 'Search the database',
|
|
256
|
-
inputSchema: z.object({
|
|
257
|
-
query: z.string(),
|
|
258
|
-
}),
|
|
259
|
-
execute: async ({ query }) => {
|
|
260
|
-
// 데이터베이스 검색
|
|
261
|
-
return { results: [] }
|
|
262
|
-
},
|
|
263
|
-
}),
|
|
264
100
|
},
|
|
265
101
|
})
|
|
266
102
|
|
|
@@ -273,20 +109,15 @@ app.post('/api/chat-with-tools', async (c) => {
|
|
|
273
109
|
## 구조화된 출력
|
|
274
110
|
|
|
275
111
|
```typescript
|
|
276
|
-
import {
|
|
277
|
-
import { generateObject, streamObject } from 'ai'
|
|
278
|
-
import { openai } from '@ai-sdk/openai'
|
|
112
|
+
import { generateObject } from 'ai'
|
|
279
113
|
import { z } from 'zod'
|
|
280
114
|
|
|
281
|
-
const app = new Hono()
|
|
282
|
-
|
|
283
115
|
const userSchema = z.object({
|
|
284
116
|
name: z.string(),
|
|
285
117
|
age: z.number(),
|
|
286
|
-
email: z.
|
|
118
|
+
email: z.email(),
|
|
287
119
|
})
|
|
288
120
|
|
|
289
|
-
// 비스트리밍 객체 생성
|
|
290
121
|
app.post('/api/generate-user', async (c) => {
|
|
291
122
|
const { prompt } = await c.req.json()
|
|
292
123
|
|
|
@@ -298,89 +129,21 @@ app.post('/api/generate-user', async (c) => {
|
|
|
298
129
|
|
|
299
130
|
return c.json(object)
|
|
300
131
|
})
|
|
301
|
-
|
|
302
|
-
// 스트리밍 객체 생성
|
|
303
|
-
app.post('/api/stream-user', async (c) => {
|
|
304
|
-
const { prompt } = await c.req.json()
|
|
305
|
-
|
|
306
|
-
const result = streamObject({
|
|
307
|
-
model: openai('gpt-4o'),
|
|
308
|
-
schema: userSchema,
|
|
309
|
-
prompt,
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
return result.toTextStreamResponse()
|
|
313
|
-
})
|
|
314
132
|
```
|
|
315
133
|
|
|
316
134
|
---
|
|
317
135
|
|
|
318
|
-
##
|
|
136
|
+
## Cloudflare Workers
|
|
319
137
|
|
|
320
138
|
```typescript
|
|
321
|
-
import { Hono } from 'hono'
|
|
322
|
-
import { HTTPException } from 'hono/http-exception'
|
|
323
|
-
import { streamText } from 'ai'
|
|
324
|
-
import { openai } from '@ai-sdk/openai'
|
|
325
|
-
|
|
326
|
-
const app = new Hono()
|
|
327
|
-
|
|
328
|
-
app.post('/api/chat', async (c) => {
|
|
329
|
-
try {
|
|
330
|
-
const { messages } = await c.req.json()
|
|
331
|
-
|
|
332
|
-
if (!messages || !Array.isArray(messages)) {
|
|
333
|
-
throw new HTTPException(400, { message: 'Invalid messages format' })
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
const result = streamText({
|
|
337
|
-
model: openai('gpt-4o'),
|
|
338
|
-
messages,
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
return result.toUIMessageStreamResponse()
|
|
342
|
-
} catch (error) {
|
|
343
|
-
if (error instanceof HTTPException) {
|
|
344
|
-
throw error
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
console.error('AI Error:', error)
|
|
348
|
-
throw new HTTPException(500, { message: 'AI processing failed' })
|
|
349
|
-
}
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
// 글로벌 에러 핸들러
|
|
353
|
-
app.onError((err, c) => {
|
|
354
|
-
if (err instanceof HTTPException) {
|
|
355
|
-
return c.json({ error: err.message }, err.status)
|
|
356
|
-
}
|
|
357
|
-
return c.json({ error: 'Internal server error' }, 500)
|
|
358
|
-
})
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
## Cloudflare Workers 배포
|
|
364
|
-
|
|
365
|
-
### 기본 설정
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
// src/index.ts
|
|
369
|
-
import { Hono } from 'hono'
|
|
370
|
-
import { streamText, convertToModelMessages } from 'ai'
|
|
371
139
|
import { createOpenAI } from '@ai-sdk/openai'
|
|
372
140
|
|
|
373
|
-
type Bindings = {
|
|
374
|
-
OPENAI_API_KEY: string
|
|
375
|
-
}
|
|
141
|
+
type Bindings = { OPENAI_API_KEY: string }
|
|
376
142
|
|
|
377
143
|
const app = new Hono<{ Bindings: Bindings }>()
|
|
378
144
|
|
|
379
145
|
app.post('/api/chat', async (c) => {
|
|
380
|
-
const openai = createOpenAI({
|
|
381
|
-
apiKey: c.env.OPENAI_API_KEY,
|
|
382
|
-
})
|
|
383
|
-
|
|
146
|
+
const openai = createOpenAI({ apiKey: c.env.OPENAI_API_KEY })
|
|
384
147
|
const { messages } = await c.req.json()
|
|
385
148
|
|
|
386
149
|
const result = streamText({
|
|
@@ -390,38 +153,38 @@ app.post('/api/chat', async (c) => {
|
|
|
390
153
|
|
|
391
154
|
return result.toUIMessageStreamResponse()
|
|
392
155
|
})
|
|
393
|
-
|
|
394
|
-
export default app
|
|
395
156
|
```
|
|
396
157
|
|
|
397
|
-
|
|
158
|
+
---
|
|
398
159
|
|
|
399
|
-
|
|
400
|
-
name = "ai-api"
|
|
401
|
-
main = "src/index.ts"
|
|
402
|
-
compatibility_date = "2024-01-01"
|
|
160
|
+
## 에러 처리
|
|
403
161
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
```
|
|
162
|
+
```typescript
|
|
163
|
+
import { HTTPException } from 'hono/http-exception'
|
|
407
164
|
|
|
408
|
-
|
|
165
|
+
app.post('/api/chat', async (c) => {
|
|
166
|
+
try {
|
|
167
|
+
const { messages } = await c.req.json()
|
|
409
168
|
|
|
410
|
-
|
|
169
|
+
if (!messages || !Array.isArray(messages)) {
|
|
170
|
+
throw new HTTPException(400, { message: 'Invalid messages' })
|
|
171
|
+
}
|
|
411
172
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
173
|
+
const result = streamText({ model: openai('gpt-4o'), messages })
|
|
174
|
+
return result.toUIMessageStreamResponse()
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error('AI Error:', error)
|
|
177
|
+
throw new HTTPException(500, { message: 'AI processing failed' })
|
|
178
|
+
}
|
|
179
|
+
})
|
|
417
180
|
```
|
|
418
181
|
|
|
419
182
|
---
|
|
420
183
|
|
|
421
184
|
## 관련 문서
|
|
422
185
|
|
|
423
|
-
- [프로바이더](./providers.md)
|
|
424
|
-
- [OpenRouter](./openrouter.md)
|
|
425
|
-
- [스트리밍](./streaming.md)
|
|
426
|
-
- [도구](./tools.md)
|
|
427
|
-
- [구조화된 출력](./structured-output.md)
|
|
186
|
+
- [프로바이더](./providers.md)
|
|
187
|
+
- [OpenRouter](./openrouter.md)
|
|
188
|
+
- [스트리밍](./streaming.md)
|
|
189
|
+
- [도구](./tools.md)
|
|
190
|
+
- [구조화된 출력](./structured-output.md)
|