@kokimoki/app 2.1.0 → 3.0.0

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 (38) hide show
  1. package/README.md +72 -0
  2. package/dist/core/kokimoki-client.d.ts +75 -15
  3. package/dist/core/kokimoki-client.js +137 -22
  4. package/dist/index.d.ts +6 -1
  5. package/dist/index.js +4 -0
  6. package/dist/kokimoki.min.d.ts +322 -2
  7. package/dist/kokimoki.min.js +1884 -72
  8. package/dist/kokimoki.min.js.map +1 -1
  9. package/dist/llms.txt +6 -0
  10. package/dist/protocol/ws-message/reader.d.ts +1 -1
  11. package/dist/services/index.d.ts +1 -0
  12. package/dist/services/index.js +1 -0
  13. package/dist/services/kokimoki-ai.d.ts +185 -122
  14. package/dist/services/kokimoki-ai.js +201 -109
  15. package/dist/services/kokimoki-i18n.d.ts +259 -0
  16. package/dist/services/kokimoki-i18n.js +325 -0
  17. package/dist/stores/kokimoki-local-store.d.ts +1 -1
  18. package/dist/types/common.d.ts +9 -0
  19. package/dist/types/env.d.ts +36 -0
  20. package/dist/types/env.js +1 -0
  21. package/dist/types/index.d.ts +1 -0
  22. package/dist/types/index.js +1 -0
  23. package/dist/utils/kokimoki-client.d.ts +31 -0
  24. package/dist/utils/kokimoki-client.js +38 -0
  25. package/dist/utils/kokimoki-dev.d.ts +30 -0
  26. package/dist/utils/kokimoki-dev.js +75 -0
  27. package/dist/utils/kokimoki-env.d.ts +20 -0
  28. package/dist/utils/kokimoki-env.js +30 -0
  29. package/dist/version.d.ts +1 -1
  30. package/dist/version.js +1 -1
  31. package/docs/kokimoki-ai.instructions.md +316 -0
  32. package/docs/kokimoki-dynamic-stores.instructions.md +439 -0
  33. package/docs/kokimoki-i18n.instructions.md +285 -0
  34. package/docs/kokimoki-leaderboard.instructions.md +189 -0
  35. package/docs/kokimoki-sdk.instructions.md +221 -0
  36. package/docs/kokimoki-storage.instructions.md +162 -0
  37. package/llms.txt +43 -0
  38. package/package.json +9 -13
@@ -0,0 +1,316 @@
1
+ ---
2
+ description: "AI text generation and image transformation with Kokimoki SDK"
3
+ applyTo: "**/*.ts,**/*.tsx"
4
+ ---
5
+
6
+ # AI Integration
7
+
8
+ Built-in methods for AI text generation and image transformation. No API keys required.
9
+ All generation methods are **async job-based** - they submit a job and return immediately with a `jobId`.
10
+ Use the corresponding poll method to wait for the result.
11
+
12
+ For core SDK concepts, see [Kokimoki SDK](./kokimoki-sdk.instructions.md).
13
+
14
+ Access AI API via `kmClient.ai`.
15
+
16
+ ## Key Features
17
+
18
+ - Multiple AI models (GPT-4, GPT-5, Gemini variants)
19
+ - Text generation with configurable creativity (temperature)
20
+ - Structured JSON output with Zod schema validation
21
+ - AI-powered image generation and modification
22
+ - Job-based async processing with polling support
23
+ - Resumable after page reload (persist jobId)
24
+
25
+ ## Available Models
26
+
27
+ **Text Models:**
28
+
29
+ - `gpt-4o`: OpenAI GPT-4 Optimized
30
+ - `gpt-4o-mini`: Smaller, faster GPT-4 variant
31
+ - `gpt-5`: OpenAI GPT-5 (latest)
32
+ - `gpt-5-mini`: Smaller GPT-5 variant
33
+ - `gpt-5-nano`: Smallest GPT-5 variant for lightweight tasks
34
+ - `gemini-2.5-flash-lite`: Google Gemini lite variant
35
+ - `gemini-2.5-flash`: Google Gemini fast variant
36
+ - `gemini-3-flash-preview`: Google Gemini 3 Flash preview
37
+ - `gemini-3-pro-preview`: Google Gemini 3 Pro preview
38
+
39
+ **Image Models:**
40
+
41
+ - `gemini-2.5-flash-image`: Google Gemini image generation
42
+ - `gemini-3-pro-image-preview`: Google Gemini 3 Pro image preview
43
+
44
+ ## API Methods
45
+
46
+ ### ai.generateText(req): Promise<{ jobId: string }>
47
+
48
+ Submits a text generation job. Use `pollText()` to wait for the result.
49
+
50
+ **Parameters:**
51
+
52
+ - **req.model**: `string` AI model to use (optional)
53
+ - **req.systemPrompt**: `string` AI role/behavior (optional)
54
+ - **req.prompt**: `string` The user's message or question to send to the AI
55
+ - **req.temperature**: `number` Creativity level from 0.0 = factual to 1.0 = creative (optional)
56
+ - **req.imageUrls**: `string[]` Image URLs to include with the prompt (Gemini models only) (optional)
57
+
58
+ **Example:**
59
+
60
+ ```typescript
61
+ // Submit text generation job
62
+ const { jobId } = await kmClient.ai.generateText({
63
+ model: "gemini-2.5-flash-lite",
64
+ systemPrompt: "You are a fantasy story writer",
65
+ prompt: "Write a short quest description",
66
+ temperature: 0.8,
67
+ });
68
+
69
+ // Poll for result
70
+ const text = await kmClient.ai.pollText(jobId);
71
+ ```
72
+
73
+ ### ai.generateJson<T>(req): Promise<{ jobId: string }>
74
+
75
+ Submits a JSON generation job with Zod schema validation. Use `pollJson()` to wait for the result with type inference.
76
+
77
+ **Parameters:**
78
+
79
+ - **req.schema**: `ZodType` Zod schema that defines the expected JSON structure
80
+ - **req.model**: `string` AI model to use (optional)
81
+ - **req.systemPrompt**: `string` AI role/behavior (optional)
82
+ - **req.prompt**: `string` The user's message or question to send to the AI
83
+ - **req.temperature**: `number` Creativity level from 0.0 = factual to 1.0 = creative (optional)
84
+ - **req.imageUrls**: `string[]` Image URLs to include with the prompt (Gemini models only) (optional)
85
+
86
+ **Example:**
87
+
88
+ ```typescript
89
+ import { z } from "zod/v4";
90
+
91
+ // Define schema with Zod
92
+ const enemySchema = z.object({
93
+ name: z.string(),
94
+ health: z.number(),
95
+ attack: z.number(),
96
+ abilities: z.array(z.string()),
97
+ });
98
+
99
+ // Submit JSON generation job
100
+ const { jobId } = await kmClient.ai.generateJson({
101
+ schema: enemySchema,
102
+ prompt: "Create a level 5 goblin warrior",
103
+ temperature: 0.7,
104
+ });
105
+
106
+ // Save jobId to store for persistence across reloads
107
+ await saveJobId(jobId);
108
+
109
+ // Poll with schema for type inference and validation
110
+ const enemy = await kmClient.ai.pollJson(jobId, { schema: enemySchema });
111
+ console.log(enemy.name, enemy.health); // Fully typed!
112
+ ```
113
+
114
+ ```typescript
115
+ // Generate quiz questions
116
+ const questionSchema = z.array(
117
+ z.object({
118
+ question: z.string(),
119
+ options: z.array(z.string()),
120
+ correctAnswer: z.number(),
121
+ })
122
+ );
123
+
124
+ const { jobId } = await kmClient.ai.generateJson({
125
+ schema: questionSchema,
126
+ systemPrompt: "Generate quiz questions",
127
+ prompt: "Create 5 history quiz questions with 4 options each",
128
+ });
129
+
130
+ const questions = await kmClient.ai.pollJson(jobId, { schema: questionSchema });
131
+ questions.forEach((q) => console.log(q.question));
132
+ ```
133
+
134
+ ### ai.generateImage(req): Promise<{ jobId: string }>
135
+
136
+ Submits an image generation/modification job. Use `pollImage()` to wait for the result.
137
+ The result is stored as `Upload` object (see [Storage](./kokimoki-storage.instructions.md)).
138
+
139
+ **Parameters:**
140
+
141
+ - **req.model**: `string` Image model to use (optional, default: `gemini-2.5-flash-image`)
142
+ - **req.prompt**: `string` The prompt describing the image or modification
143
+ - **req.imageUrls**: `string[]` Source image URLs to include in the generation (optional)
144
+ - **req.tags**: `string[]` Tags for the result in `Upload` format (optional, default: [])
145
+
146
+ **Example:**
147
+
148
+ ```typescript
149
+ // Generate a new image
150
+ const { jobId } = await kmClient.ai.generateImage({
151
+ prompt: "A fantasy castle on a mountain at sunset",
152
+ tags: ["background", "ai-generated"],
153
+ });
154
+
155
+ const upload = await kmClient.ai.pollImage(jobId);
156
+ console.log(upload.url); // CDN URL to the generated image
157
+ ```
158
+
159
+ ```typescript
160
+ // Modify an existing image
161
+ const { jobId } = await kmClient.ai.generateImage({
162
+ imageUrls: ["https://static.kokimoki.com/game/image.jpg"],
163
+ prompt: "Make it look like pixel art",
164
+ tags: ["art", "ai-generated"],
165
+ });
166
+
167
+ const upload: Upload = await kmClient.ai.pollImage(jobId);
168
+ ```
169
+
170
+ ### ai.getJob(jobId): Promise<AiJob>
171
+
172
+ Get the current status of an AI job without polling.
173
+
174
+ **Parameters:**
175
+
176
+ - **jobId**: `string` The job ID to check
177
+
178
+ **Returns:** `AiJob` object with status and result
179
+
180
+ ```typescript
181
+ interface AiJob {
182
+ jobId: string;
183
+ type: "text" | "json" | "image";
184
+ status: "processing" | "queued" | "completed" | "failed";
185
+ result?: unknown;
186
+ error?: { message: string; code?: string };
187
+ createdAt: number;
188
+ }
189
+ ```
190
+
191
+ **Example:**
192
+
193
+ ```typescript
194
+ const job = await kmClient.ai.getJob(jobId);
195
+ if (job.status === "completed") {
196
+ console.log("Result:", job.result);
197
+ } else if (job.status === "failed") {
198
+ console.error("Error:", job.error?.message);
199
+ }
200
+ ```
201
+
202
+ ### ai.pollText(jobId, options?): Promise<string>
203
+
204
+ Poll a text generation job until completion.
205
+
206
+ **Parameters:**
207
+
208
+ - **jobId**: `string` The job ID to poll
209
+ - **options.pollInterval**: `number` Polling interval in ms (default: 2000, min: 1000)
210
+ - **options.timeout**: `number` Timeout in ms (default: 120000)
211
+ - **options.onProgress**: `(status: AiJobStatus) => void` Progress callback
212
+
213
+ **Example:**
214
+
215
+ ```typescript
216
+ const text = await kmClient.ai.pollText(jobId, {
217
+ timeout: 60000,
218
+ onProgress: (status) => console.log("Status:", status),
219
+ });
220
+ ```
221
+
222
+ ### ai.pollJson<T>(jobId, options): Promise<T>
223
+
224
+ Poll a JSON generation job until completion with schema validation.
225
+
226
+ **Parameters:**
227
+
228
+ - **jobId**: `string` The job ID to poll
229
+ - **options.schema**: `ZodType` Zod schema for validation and type inference (required)
230
+ - **options.pollInterval**: `number` Polling interval in ms (default: 2000, min: 1000)
231
+ - **options.timeout**: `number` Timeout in ms (default: 120000)
232
+ - **options.onProgress**: `(status: AiJobStatus) => void` Progress callback
233
+
234
+ **Example:**
235
+
236
+ ```typescript
237
+ const enemy = await kmClient.ai.pollJson(jobId, {
238
+ schema: enemySchema,
239
+ timeout: 60000,
240
+ onProgress: (status) => console.log("Status:", status),
241
+ });
242
+ ```
243
+
244
+ ### ai.pollImage(jobId, options?): Promise<Upload>
245
+
246
+ Poll an image generation job until completion.
247
+
248
+ **Parameters:**
249
+
250
+ - **jobId**: `string` The job ID to poll
251
+ - **options.pollInterval**: `number` Polling interval in ms (default: 2000, min: 1000)
252
+ - **options.timeout**: `number` Timeout in ms (default: 120000)
253
+ - **options.onProgress**: `(status: AiJobStatus) => void` Progress callback
254
+
255
+ **Example:**
256
+
257
+ ```typescript
258
+ const upload = await kmClient.ai.pollImage(jobId, {
259
+ timeout: 60000,
260
+ onProgress: (status) => console.log("Status:", status),
261
+ });
262
+ ```
263
+
264
+ ## Common Patterns
265
+
266
+ ### Example: Persist Jobs Across Page Reloads
267
+
268
+ ```typescript
269
+ // Store jobId in local store for persistence
270
+ const { jobId } = await kmClient.ai.generateJson({
271
+ schema: questSchema,
272
+ prompt: "Generate an epic quest",
273
+ });
274
+
275
+ await kmClient.transact([localStore], ([state]) => {
276
+ state.pendingQuestJobId = jobId;
277
+ });
278
+
279
+ // On page load, resume polling if job is pending
280
+ const pendingJobId = localStore.proxy.pendingQuestJobId;
281
+ if (pendingJobId) {
282
+ const quest = await kmClient.ai.pollJson(pendingJobId, {
283
+ schema: questSchema,
284
+ });
285
+ // Clear pending job
286
+ await kmClient.transact([localStore], ([state]) => {
287
+ state.pendingQuestJobId = null;
288
+ });
289
+ }
290
+ ```
291
+
292
+ ### Example: Show Loading State
293
+
294
+ ```typescript
295
+ setLoading(true);
296
+ const { jobId } = await kmClient.ai.generateText({
297
+ prompt: "Write a story",
298
+ });
299
+
300
+ const text = await kmClient.ai.pollText(jobId, {
301
+ onProgress: (status) => {
302
+ if (status === "queued") setLoadingText("Waiting in queue...");
303
+ if (status === "processing") setLoadingText("Generating...");
304
+ },
305
+ });
306
+ setLoading(false);
307
+ ```
308
+
309
+ ## Key Points
310
+
311
+ - **Job-based**: All generation methods return `{ jobId }` immediately, use poll methods for results
312
+ - **Resumable**: Save `jobId` to store to resume polling after page reload
313
+ - **Zod Schemas**: Use Zod schemas for `generateJson` to get automatic type inference and validation
314
+ - **Temperature**: Range 0.0 (factual) to 1.0 (creative)
315
+ - **Polling Options**: Configure `pollInterval`, `timeout`, and `onProgress` callback
316
+ - **Image URLs**: Gemini models support multimodal input via `imageUrls` parameter