@kood/claude-code 0.1.7 → 0.1.10

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 (49) hide show
  1. package/dist/index.js +137 -3
  2. package/package.json +8 -2
  3. package/templates/hono/CLAUDE.md +53 -326
  4. package/templates/hono/docs/architecture/architecture.md +93 -747
  5. package/templates/hono/docs/deployment/cloudflare.md +59 -513
  6. package/templates/hono/docs/deployment/docker.md +41 -356
  7. package/templates/hono/docs/deployment/index.md +49 -190
  8. package/templates/hono/docs/deployment/railway.md +36 -306
  9. package/templates/hono/docs/deployment/vercel.md +49 -434
  10. package/templates/hono/docs/library/ai-sdk/index.md +53 -290
  11. package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
  12. package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
  13. package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
  14. package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
  15. package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
  16. package/templates/hono/docs/library/hono/env-setup.md +24 -313
  17. package/templates/hono/docs/library/hono/error-handling.md +34 -295
  18. package/templates/hono/docs/library/hono/index.md +24 -122
  19. package/templates/hono/docs/library/hono/middleware.md +21 -188
  20. package/templates/hono/docs/library/hono/rpc.md +40 -341
  21. package/templates/hono/docs/library/hono/validation.md +35 -195
  22. package/templates/hono/docs/library/pino/index.md +42 -333
  23. package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
  24. package/templates/hono/docs/library/prisma/config.md +19 -260
  25. package/templates/hono/docs/library/prisma/index.md +64 -320
  26. package/templates/hono/docs/library/zod/index.md +53 -257
  27. package/templates/npx/CLAUDE.md +58 -276
  28. package/templates/npx/docs/references/patterns.md +160 -0
  29. package/templates/tanstack-start/CLAUDE.md +0 -4
  30. package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
  31. package/templates/tanstack-start/docs/design/index.md +119 -12
  32. package/templates/tanstack-start/docs/guides/conventions.md +103 -0
  33. package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
  34. package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
  35. package/templates/tanstack-start/docs/guides/hooks.md +166 -0
  36. package/templates/tanstack-start/docs/guides/routes.md +166 -0
  37. package/templates/tanstack-start/docs/guides/services.md +143 -0
  38. package/templates/tanstack-start/docs/library/tanstack-query/index.md +18 -2
  39. package/templates/tanstack-start/docs/library/zod/index.md +16 -1
  40. package/templates/tanstack-start/docs/design/accessibility.md +0 -163
  41. package/templates/tanstack-start/docs/design/color.md +0 -93
  42. package/templates/tanstack-start/docs/design/spacing.md +0 -122
  43. package/templates/tanstack-start/docs/design/typography.md +0 -80
  44. package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
  45. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
  46. package/templates/tanstack-start/docs/guides/prettier.md +0 -189
  47. package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
  48. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -48
  49. package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
@@ -1,22 +1,6 @@
1
- # AI SDK - OpenRouter (Hono)
1
+ # AI SDK - OpenRouter
2
2
 
3
- > **상위 문서**: [AI SDK](./index.md) | [프로바이더](./providers.md)
4
-
5
- ---
6
-
7
- ## 개요
8
-
9
- [OpenRouter](https://openrouter.ai/)는 Anthropic, Google, Meta, Mistral 등 주요 AI 프로바이더의 수백 개 모델에 단일 API로 접근할 수 있는 통합 게이트웨이입니다.
10
-
11
- ### 주요 장점
12
-
13
- | 장점 | 설명 |
14
- |------|------|
15
- | **통합 API** | 하나의 API 키로 수백 개 모델 접근 |
16
- | **비용 효율** | 월정액 없이 사용량 기반 과금 |
17
- | **투명한 가격** | 모델별 토큰당 비용 명확히 표시 |
18
- | **고가용성** | 엔터프라이즈급 인프라와 자동 장애 조치 |
19
- | **최신 모델** | 새 모델 출시 즉시 사용 가능 |
3
+ > 수백 모델을 단일 API로
20
4
 
21
5
  ---
22
6
 
@@ -28,33 +12,13 @@ npm install @openrouter/ai-sdk-provider
28
12
 
29
13
  ---
30
14
 
31
- ## 기본 설정
32
-
33
- ### Provider 인스턴스 생성
34
-
35
- ```typescript
36
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
37
-
38
- const openrouter = createOpenRouter({
39
- apiKey: process.env.OPENROUTER_API_KEY,
40
- })
41
- ```
42
-
43
- API 키는 [OpenRouter Dashboard](https://openrouter.ai/keys)에서 발급받을 수 있습니다.
44
-
45
- ---
46
-
47
- ## Hono 통합
48
-
49
- ### 기본 채팅 API
15
+ ## 기본 사용
50
16
 
51
17
  ```typescript
52
18
  import { Hono } from 'hono'
53
19
  import { streamText, convertToModelMessages } from 'ai'
54
20
  import { createOpenRouter } from '@openrouter/ai-sdk-provider'
55
21
 
56
- const app = new Hono()
57
-
58
22
  const openrouter = createOpenRouter({
59
23
  apiKey: process.env.OPENROUTER_API_KEY,
60
24
  })
@@ -69,38 +33,25 @@ app.post('/api/chat', async (c) => {
69
33
 
70
34
  return result.toUIMessageStreamResponse()
71
35
  })
72
-
73
- export default app
74
36
  ```
75
37
 
76
- ### 동적 모델 선택
38
+ ---
39
+
40
+ ## 동적 모델 선택
77
41
 
78
42
  ```typescript
79
- import { Hono } from 'hono'
80
- import { streamText, convertToModelMessages } from 'ai'
81
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
82
43
  import { HTTPException } from 'hono/http-exception'
83
44
 
84
- const app = new Hono()
85
-
86
- const openrouter = createOpenRouter({
87
- apiKey: process.env.OPENROUTER_API_KEY,
88
- })
89
-
90
- // 허용된 모델 목록
91
45
  const ALLOWED_MODELS = [
92
46
  'anthropic/claude-3.5-sonnet',
93
- 'anthropic/claude-3-opus',
94
47
  'openai/gpt-4o',
95
- 'openai/gpt-4-turbo',
96
48
  'google/gemini-pro-1.5',
97
49
  'meta-llama/llama-3.1-70b-instruct',
98
50
  ]
99
51
 
100
52
  app.post('/api/chat', async (c) => {
101
- const { messages, model = 'anthropic/claude-3.5-sonnet' } = await c.req.json()
53
+ const { messages, model } = await c.req.json()
102
54
 
103
- // 모델 검증
104
55
  if (!ALLOWED_MODELS.includes(model)) {
105
56
  throw new HTTPException(400, { message: 'Invalid model' })
106
57
  }
@@ -112,25 +63,16 @@ app.post('/api/chat', async (c) => {
112
63
 
113
64
  return result.toUIMessageStreamResponse()
114
65
  })
115
-
116
- export default app
117
66
  ```
118
67
 
119
68
  ---
120
69
 
121
- ## Cloudflare Workers 배포
122
-
123
- ### 기본 설정
70
+ ## Cloudflare Workers
124
71
 
125
72
  ```typescript
126
- // src/index.ts
127
- import { Hono } from 'hono'
128
- import { streamText, convertToModelMessages } from 'ai'
129
73
  import { createOpenRouter } from '@openrouter/ai-sdk-provider'
130
74
 
131
- type Bindings = {
132
- OPENROUTER_API_KEY: string
133
- }
75
+ type Bindings = { OPENROUTER_API_KEY: string }
134
76
 
135
77
  const app = new Hono<{ Bindings: Bindings }>()
136
78
 
@@ -148,332 +90,22 @@ app.post('/api/chat', async (c) => {
148
90
 
149
91
  return result.toUIMessageStreamResponse()
150
92
  })
151
-
152
- export default app
153
- ```
154
-
155
- ### wrangler.toml
156
-
157
- ```toml
158
- name = "ai-api"
159
- main = "src/index.ts"
160
- compatibility_date = "2024-01-01"
161
-
162
- # API 키는 Cloudflare 대시보드에서 설정
163
- # Settings > Variables > Environment Variables
164
- ```
165
-
166
- ---
167
-
168
- ## 인기 모델
169
-
170
- | 모델 ID | 설명 |
171
- |---------|------|
172
- | `anthropic/claude-3.5-sonnet` | Claude 3.5 Sonnet |
173
- | `anthropic/claude-3-opus` | Claude 3 Opus |
174
- | `openai/gpt-4o` | GPT-4o |
175
- | `openai/gpt-4-turbo` | GPT-4 Turbo |
176
- | `google/gemini-pro-1.5` | Gemini Pro 1.5 |
177
- | `meta-llama/llama-3.1-405b-instruct` | Llama 3.1 405B |
178
- | `meta-llama/llama-3.1-70b-instruct` | Llama 3.1 70B |
179
- | `mistralai/mistral-large` | Mistral Large |
180
-
181
- 전체 모델 목록: [OpenRouter Models](https://openrouter.ai/docs#models)
182
-
183
- ---
184
-
185
- ## 도구 사용
186
-
187
- ```typescript
188
- import { Hono } from 'hono'
189
- import { streamText, tool, convertToModelMessages } from 'ai'
190
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
191
- import { z } from 'zod'
192
-
193
- type Bindings = {
194
- OPENROUTER_API_KEY: string
195
- }
196
-
197
- const app = new Hono<{ Bindings: Bindings }>()
198
-
199
- app.post('/api/assistant', async (c) => {
200
- const openrouter = createOpenRouter({
201
- apiKey: c.env.OPENROUTER_API_KEY,
202
- })
203
-
204
- const { messages } = await c.req.json()
205
-
206
- const result = streamText({
207
- model: openrouter.chat('anthropic/claude-3.5-sonnet'),
208
- messages: convertToModelMessages(messages),
209
- tools: {
210
- getWeather: tool({
211
- description: 'Get weather for a location',
212
- inputSchema: z.object({
213
- location: z.string().describe('City name'),
214
- }),
215
- execute: async ({ location }) => {
216
- // 실제 날씨 API 호출
217
- return { location, temperature: 22, condition: 'Sunny' }
218
- },
219
- }),
220
- searchProducts: tool({
221
- description: 'Search products in database',
222
- inputSchema: z.object({
223
- query: z.string(),
224
- limit: z.number().optional().default(10),
225
- }),
226
- execute: async ({ query, limit }) => {
227
- // 데이터베이스 검색
228
- return { products: [], total: 0 }
229
- },
230
- }),
231
- },
232
- })
233
-
234
- return result.toUIMessageStreamResponse()
235
- })
236
-
237
- export default app
238
- ```
239
-
240
- ---
241
-
242
- ## 구조화된 출력
243
-
244
- ```typescript
245
- import { Hono } from 'hono'
246
- import { generateObject } from 'ai'
247
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
248
- import { z } from 'zod'
249
-
250
- type Bindings = {
251
- OPENROUTER_API_KEY: string
252
- }
253
-
254
- const app = new Hono<{ Bindings: Bindings }>()
255
-
256
- const userSchema = z.object({
257
- name: z.string(),
258
- age: z.number(),
259
- skills: z.array(z.string()),
260
- })
261
-
262
- app.post('/api/generate-user', async (c) => {
263
- const openrouter = createOpenRouter({
264
- apiKey: c.env.OPENROUTER_API_KEY,
265
- })
266
-
267
- const { prompt } = await c.req.json()
268
-
269
- const { object } = await generateObject({
270
- model: openrouter.chat('anthropic/claude-3.5-sonnet'),
271
- schema: userSchema,
272
- prompt,
273
- })
274
-
275
- return c.json(object)
276
- })
277
-
278
- export default app
279
- ```
280
-
281
- ---
282
-
283
- ## 미들웨어 패턴
284
-
285
- ### OpenRouter 미들웨어
286
-
287
- ```typescript
288
- import { Hono } from 'hono'
289
- import { createMiddleware } from 'hono/factory'
290
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
291
-
292
- type Bindings = {
293
- OPENROUTER_API_KEY: string
294
- }
295
-
296
- type Variables = {
297
- openrouter: ReturnType<typeof createOpenRouter>
298
- }
299
-
300
- const openrouterMiddleware = createMiddleware<{
301
- Bindings: Bindings
302
- Variables: Variables
303
- }>(async (c, next) => {
304
- const openrouter = createOpenRouter({
305
- apiKey: c.env.OPENROUTER_API_KEY,
306
- })
307
- c.set('openrouter', openrouter)
308
- await next()
309
- })
310
-
311
- const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()
312
-
313
- app.use('/api/*', openrouterMiddleware)
314
-
315
- app.post('/api/chat', async (c) => {
316
- const openrouter = c.get('openrouter')
317
- const { messages } = await c.req.json()
318
-
319
- const result = streamText({
320
- model: openrouter.chat('anthropic/claude-3.5-sonnet'),
321
- messages,
322
- })
323
-
324
- return result.toUIMessageStreamResponse()
325
- })
326
-
327
- export default app
328
- ```
329
-
330
- ### Rate Limiting
331
-
332
- ```typescript
333
- import { Hono } from 'hono'
334
- import { rateLimiter } from 'hono-rate-limiter'
335
- import { streamText, convertToModelMessages } from 'ai'
336
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
337
-
338
- type Bindings = {
339
- OPENROUTER_API_KEY: string
340
- }
341
-
342
- const app = new Hono<{ Bindings: Bindings }>()
343
-
344
- // Rate limiting 적용
345
- app.use(
346
- '/api/*',
347
- rateLimiter({
348
- windowMs: 60 * 1000, // 1분
349
- limit: 20, // 최대 20 요청
350
- standardHeaders: 'draft-6',
351
- keyGenerator: (c) => c.req.header('x-forwarded-for') ?? 'anonymous',
352
- })
353
- )
354
-
355
- app.post('/api/chat', async (c) => {
356
- const openrouter = createOpenRouter({
357
- apiKey: c.env.OPENROUTER_API_KEY,
358
- })
359
-
360
- const { messages } = await c.req.json()
361
-
362
- const result = streamText({
363
- model: openrouter.chat('anthropic/claude-3.5-sonnet'),
364
- messages: convertToModelMessages(messages),
365
- })
366
-
367
- return result.toUIMessageStreamResponse()
368
- })
369
-
370
- export default app
371
93
  ```
372
94
 
373
95
  ---
374
96
 
375
- ## 에러 처리
376
-
377
- ```typescript
378
- import { Hono } from 'hono'
379
- import { HTTPException } from 'hono/http-exception'
380
- import { streamText, convertToModelMessages } from 'ai'
381
- import { createOpenRouter } from '@openrouter/ai-sdk-provider'
382
-
383
- type Bindings = {
384
- OPENROUTER_API_KEY: string
385
- }
386
-
387
- const app = new Hono<{ Bindings: Bindings }>()
388
-
389
- app.post('/api/chat', async (c) => {
390
- try {
391
- const openrouter = createOpenRouter({
392
- apiKey: c.env.OPENROUTER_API_KEY,
393
- })
394
-
395
- const body = await c.req.json()
396
-
397
- if (!body.messages || !Array.isArray(body.messages)) {
398
- throw new HTTPException(400, { message: 'Invalid messages format' })
399
- }
400
-
401
- const result = streamText({
402
- model: openrouter.chat(body.model ?? 'anthropic/claude-3.5-sonnet'),
403
- messages: convertToModelMessages(body.messages),
404
- })
405
-
406
- return result.toUIMessageStreamResponse()
407
- } catch (error) {
408
- if (error instanceof HTTPException) {
409
- throw error
410
- }
411
-
412
- console.error('OpenRouter Error:', error)
413
- throw new HTTPException(500, { message: 'AI processing failed' })
414
- }
415
- })
416
-
417
- // 글로벌 에러 핸들러
418
- app.onError((err, c) => {
419
- if (err instanceof HTTPException) {
420
- return c.json({ error: err.message }, err.status)
421
- }
422
- return c.json({ error: 'Internal server error' }, 500)
423
- })
424
-
425
- export default app
426
- ```
97
+ ## 주요 모델
427
98
 
428
- ---
429
-
430
- ## 비용 관리
431
-
432
- ### 사용량 추적
433
-
434
- ```typescript
435
- app.post('/api/generate', async (c) => {
436
- const openrouter = createOpenRouter({
437
- apiKey: c.env.OPENROUTER_API_KEY,
438
- })
439
-
440
- const { prompt } = await c.req.json()
441
-
442
- const result = await generateText({
443
- model: openrouter.chat('anthropic/claude-3.5-sonnet'),
444
- prompt,
445
- })
446
-
447
- return c.json({
448
- text: result.text,
449
- usage: result.usage,
450
- // { promptTokens: 10, completionTokens: 50, totalTokens: 60 }
451
- })
452
- })
453
- ```
454
-
455
- ---
456
-
457
- ## 환경 변수
458
-
459
- ```bash
460
- # .env (로컬 개발)
461
- OPENROUTER_API_KEY=sk-or-v1-...
462
- ```
463
-
464
- ```toml
465
- # wrangler.toml (Cloudflare Workers)
466
- # API 키는 Cloudflare 대시보드에서 설정:
467
- # Settings > Variables > Environment Variables
468
- ```
99
+ | 프로바이더 | 모델 |
100
+ |-----------|------|
101
+ | Anthropic | `anthropic/claude-3.5-sonnet`, `anthropic/claude-3-opus` |
102
+ | OpenAI | `openai/gpt-4o`, `openai/gpt-4-turbo` |
103
+ | Google | `google/gemini-pro-1.5` |
104
+ | Meta | `meta-llama/llama-3.1-70b-instruct` |
469
105
 
470
106
  ---
471
107
 
472
- ## 리소스
108
+ ## 관련 문서
473
109
 
474
- - [OpenRouter 공식 문서](https://openrouter.ai/docs)
475
- - [OpenRouter 대시보드](https://openrouter.ai/dashboard)
476
- - [API 키 발급](https://openrouter.ai/keys)
477
- - [모델 목록](https://openrouter.ai/docs#models)
478
- - [GitHub 저장소](https://github.com/OpenRouterTeam/ai-sdk-provider)
479
- - [상태 페이지](https://status.openrouter.ai)
110
+ - [AI SDK 개요](./index.md)
111
+ - [프로바이더](./providers.md)