@kokimoki/app 2.0.0 → 2.0.1

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 (45) hide show
  1. package/dist/core/index.d.ts +3 -0
  2. package/dist/core/index.js +3 -0
  3. package/dist/core/kokimoki-client.d.ts +361 -0
  4. package/dist/core/kokimoki-client.js +819 -0
  5. package/dist/core/room-subscription-mode.d.ts +5 -0
  6. package/dist/core/room-subscription-mode.js +6 -0
  7. package/dist/core/room-subscription.d.ts +15 -0
  8. package/dist/core/room-subscription.js +53 -0
  9. package/dist/index.d.ts +4 -7
  10. package/dist/index.js +4 -7
  11. package/dist/kokimoki.min.d.ts +54 -58
  12. package/dist/kokimoki.min.js +3080 -1794
  13. package/dist/kokimoki.min.js.map +1 -1
  14. package/dist/llms.txt +75 -67
  15. package/dist/protocol/ws-message/index.d.ts +3 -0
  16. package/dist/protocol/ws-message/index.js +3 -0
  17. package/dist/protocol/ws-message/reader.d.ts +11 -0
  18. package/dist/protocol/ws-message/reader.js +36 -0
  19. package/dist/protocol/ws-message/type.d.ts +11 -0
  20. package/dist/protocol/ws-message/type.js +12 -0
  21. package/dist/protocol/ws-message/writer.d.ts +9 -0
  22. package/dist/protocol/ws-message/writer.js +45 -0
  23. package/dist/services/index.d.ts +3 -0
  24. package/dist/services/index.js +3 -0
  25. package/dist/services/kokimoki-ai.d.ts +153 -0
  26. package/dist/services/kokimoki-ai.js +164 -0
  27. package/dist/services/kokimoki-leaderboard.d.ts +175 -0
  28. package/dist/services/kokimoki-leaderboard.js +203 -0
  29. package/dist/services/kokimoki-storage.d.ts +155 -0
  30. package/dist/services/kokimoki-storage.js +208 -0
  31. package/dist/stores/index.d.ts +3 -0
  32. package/dist/stores/index.js +3 -0
  33. package/dist/stores/kokimoki-local-store.d.ts +11 -0
  34. package/dist/stores/kokimoki-local-store.js +40 -0
  35. package/dist/stores/kokimoki-store.d.ts +22 -0
  36. package/dist/stores/kokimoki-store.js +117 -0
  37. package/dist/stores/kokimoki-transaction.d.ts +18 -0
  38. package/dist/stores/kokimoki-transaction.js +143 -0
  39. package/dist/types/index.d.ts +3 -0
  40. package/dist/types/index.js +3 -0
  41. package/dist/utils/valtio.d.ts +7 -0
  42. package/dist/utils/valtio.js +6 -0
  43. package/dist/version.d.ts +1 -1
  44. package/dist/version.js +2 -1
  45. package/package.json +4 -3
package/dist/llms.txt CHANGED
@@ -1,8 +1,3 @@
1
- ---
2
- description: Instructions for the Kokimoki SDK
3
- applyTo: '**/*.tsx,**/*.ts'
4
- ---
5
-
6
1
  # Kokimoki SDK
7
2
 
8
3
  The Kokimoki SDK is a comprehensive development toolkit for building real-time collaborative game applications
@@ -51,7 +46,7 @@ Kokimoki Store powered by `valtio` and `valtio-yjs` for real-time state manageme
51
46
  **Example: Creating a Store**
52
47
 
53
48
  ```typescript
54
- import { kmClient } from '@services/km-client';
49
+ import { kmClient } from "@services/km-client";
55
50
 
56
51
  interface State {
57
52
  title: string;
@@ -59,12 +54,12 @@ interface State {
59
54
  }
60
55
 
61
56
  const initialState: State = {
62
- title: 'Store',
63
- count: 0
57
+ title: "Store",
58
+ count: 0,
64
59
  };
65
60
 
66
61
  // Initialize global store with initial state
67
- export const store = kmClient.store<PlayerState>('store-name', initialState);
62
+ export const store = kmClient.store<PlayerState>("store-name", initialState);
68
63
  ```
69
64
 
70
65
  ### State management
@@ -79,11 +74,11 @@ export const store = kmClient.store<PlayerState>('store-name', initialState);
79
74
  **Example: Updating State**
80
75
 
81
76
  ```typescript
82
- import { store } from '../store';
77
+ import { store } from "../store";
83
78
 
84
79
  // Update state
85
80
  await kmClient.transact([store], ([state]) => {
86
- state.title = 'New store';
81
+ state.title = "New store";
87
82
  state.count += 1;
88
83
  });
89
84
  ```
@@ -98,8 +93,8 @@ await kmClient.transact([store], ([state]) => {
98
93
  ```typescript
99
94
  // Update multiple stores in a single transaction
100
95
  await kmClient.transact([store1, store2], ([state1, state2]) => {
101
- state1.name = 'My Store1';
102
- state2.name = 'My Store2';
96
+ state1.name = "My Store1";
97
+ state2.name = "My Store2";
103
98
  });
104
99
  ```
105
100
 
@@ -111,8 +106,8 @@ await kmClient.transact([store1, store2], ([state1, state2]) => {
111
106
  **Example: Using State in Components**
112
107
 
113
108
  ```tsx
114
- import { useSnapshot } from 'valtio';
115
- import { store } from '../store';
109
+ import { useSnapshot } from "valtio";
110
+ import { store } from "../store";
116
111
 
117
112
  const Component = () => {
118
113
  // Get reactive snapshot of the store state
@@ -156,9 +151,9 @@ Uploads a file to storage.
156
151
  **Example:**
157
152
 
158
153
  ```typescript
159
- const upload: Upload = await kmClient.storage.upload('filename.jpg', fileBlob, [
160
- 'tag1',
161
- 'tag2'
154
+ const upload: Upload = await kmClient.storage.upload("filename.jpg", fileBlob, [
155
+ "tag1",
156
+ "tag2",
162
157
  ]);
163
158
  // Use upload.url to access the media file
164
159
  ```
@@ -180,7 +175,7 @@ Query uploaded files by filter and pagination
180
175
  ```typescript
181
176
  // Query uploads by tag and uploaded by this client
182
177
  const { items, total } = await kmClient.storage.listUploads(
183
- { clientId: kmClient.id, tags: ['tag1'] },
178
+ { clientId: kmClient.id, tags: ["tag1"] },
184
179
  skip,
185
180
  limit
186
181
  );
@@ -199,7 +194,7 @@ Replace uploaded file tags with new tags
199
194
 
200
195
  ```typescript
201
196
  const updatedUpload: Upload = await kmClient.storage.updateUpload(upload.id, {
202
- tags: ['new']
197
+ tags: ["new"],
203
198
  });
204
199
  ```
205
200
 
@@ -245,7 +240,9 @@ interface Paginated<T> {
245
240
 
246
241
  ```typescript
247
242
  // Get uploaded files by clientId
248
- const clientUploads = await kmClient.storage.listUploads({ clientId: kmClient.id });
243
+ const clientUploads = await kmClient.storage.listUploads({
244
+ clientId: kmClient.id,
245
+ });
249
246
  ```
250
247
 
251
248
  #### Example: Filter by file type
@@ -253,7 +250,7 @@ const clientUploads = await kmClient.storage.listUploads({ clientId: kmClient.id
253
250
  ```typescript
254
251
  // Get only uploaded images
255
252
  const images = await kmClient.storage.listUploads({
256
- mimeTypes: ['image/jpeg', 'image/png']
253
+ mimeTypes: ["image/jpeg", "image/png"],
257
254
  });
258
255
  ```
259
256
 
@@ -261,17 +258,19 @@ const images = await kmClient.storage.listUploads({
261
258
 
262
259
  ```typescript
263
260
  // Upload file with tag
264
- await kmClient.storage.upload('avatar.jpg', blob, ['profile']);
261
+ await kmClient.storage.upload("avatar.jpg", blob, ["profile"]);
265
262
 
266
263
  // Query uploads by tag
267
- const profileUploads = await kmClient.storage.listUploads({ tags: ['profile'] });
264
+ const profileUploads = await kmClient.storage.listUploads({
265
+ tags: ["profile"],
266
+ });
268
267
  ```
269
268
 
270
269
  #### Example: Usage in Kokimoki Store
271
270
 
272
271
  ```typescript
273
272
  // Upload image from Blob
274
- const upload = await kmClient.storage.upload('file.jpg', blob);
273
+ const upload = await kmClient.storage.upload("file.jpg", blob);
275
274
 
276
275
  await kmClient.transact([store], (state) => {
277
276
  // Add image to images array in the store
@@ -319,11 +318,11 @@ Used to generate text response with AI
319
318
  ```typescript
320
319
  // Generate text response
321
320
  const { content } = await kmClient.ai.chat({
322
- model: 'gemini-2.5-flash-lite',
323
- systemPrompt: 'You are a sarcastic assistant',
324
- userPrompt: 'Write a story about dragons',
321
+ model: "gemini-2.5-flash-lite",
322
+ systemPrompt: "You are a sarcastic assistant",
323
+ userPrompt: "Write a story about dragons",
325
324
  temperature: 0.7, // moderate creativity
326
- maxTokens: 500 // limit to 500 tokens
325
+ maxTokens: 500, // limit to 500 tokens
327
326
  });
328
327
  ```
329
328
 
@@ -359,13 +358,13 @@ interface Question {
359
358
  }
360
359
 
361
360
  const questions = await kmClient.ai.generateJson<Question[]>({
362
- systemPrompt: 'Generate quiz questions as JSON array',
363
- userPrompt: 'Create 5 history quiz questions with 4 options each',
364
- temperature: 0.7
361
+ systemPrompt: "Generate quiz questions as JSON array",
362
+ userPrompt: "Create 5 history quiz questions with 4 options each",
363
+ temperature: 0.7,
365
364
  });
366
365
 
367
366
  // questions is already parsed and typed
368
- questions.forEach(q => console.log(q.question));
367
+ questions.forEach((q) => console.log(q.question));
369
368
  ```
370
369
 
371
370
  ```typescript
@@ -378,8 +377,8 @@ interface Character {
378
377
  }
379
378
 
380
379
  const character = await kmClient.ai.generateJson<Character>({
381
- userPrompt: 'Create a fantasy warrior character with stats',
382
- temperature: 0.8
380
+ userPrompt: "Create a fantasy warrior character with stats",
381
+ temperature: 0.8,
383
382
  });
384
383
 
385
384
  console.log(character.name, character.strength);
@@ -400,9 +399,9 @@ Used to modify/transform image with AI. The result is stored as [`Upload`](#stor
400
399
  ```typescript
401
400
  // Modify image from url
402
401
  const upload: Upload = await kmClient.ai.modifyImage(
403
- 'https://static.kokimoki.com/game/image.jpg',
404
- 'Make it look like a painting',
405
- ['art', 'ai-generated']
402
+ "https://static.kokimoki.com/game/image.jpg",
403
+ "Make it look like a painting",
404
+ ["art", "ai-generated"]
406
405
  );
407
406
  ```
408
407
 
@@ -420,8 +419,8 @@ Each Kokimoki store has a `connections` property that provides real-time presenc
420
419
  ### Example: Track Online Players
421
420
 
422
421
  ```tsx
423
- import { useSnapshot } from 'valtio';
424
- import { globalStore } from '@/state/stores/global-store';
422
+ import { useSnapshot } from "valtio";
423
+ import { globalStore } from "@/state/stores/global-store";
425
424
 
426
425
  const Component = () => {
427
426
  // Get online client IDs from store connections
@@ -440,8 +439,8 @@ const Component = () => {
440
439
  ### Example: Display Player List with Online Status
441
440
 
442
441
  ```tsx
443
- import { useSnapshot } from 'valtio';
444
- import { globalStore } from '@/state/stores/global-store';
442
+ import { useSnapshot } from "valtio";
443
+ import { globalStore } from "@/state/stores/global-store";
445
444
 
446
445
  const PlayerList = () => {
447
446
  const players = useSnapshot(globalStore.proxy).players;
@@ -451,14 +450,14 @@ const PlayerList = () => {
451
450
  clientId,
452
451
  name: player.name,
453
452
 
454
- isOnline: onlineClientIds.has(clientId)
453
+ isOnline: onlineClientIds.has(clientId),
455
454
  }));
456
455
 
457
456
  return (
458
457
  <ul>
459
458
  {playersList.map((player) => (
460
459
  <li key={player.clientId}>
461
- {player.name} - {player.isOnline ? 'Online' : 'Offline'}
460
+ {player.name} - {player.isOnline ? "Online" : "Offline"}
462
461
  </li>
463
462
  ))}
464
463
  </ul>
@@ -483,12 +482,14 @@ Access leaderboard API via `kmClient.leaderboard`.
483
482
  ### When to Use Leaderboard API vs Global Store
484
483
 
485
484
  **Use the Leaderboard API when:**
485
+
486
486
  - You have a large number of entries (hundreds to thousands of players)
487
487
  - You need efficient ranking and sorting with database indexes
488
488
  - You want pagination and optimized queries for top scores
489
489
  - Memory and network efficiency are important
490
490
 
491
491
  **Use a Global Store when:**
492
+
492
493
  - You have a small number of players (typically under 100)
493
494
  - You need real-time updates and live leaderboard changes
494
495
  - You want to combine player scores with other game state
@@ -516,11 +517,11 @@ Add a new entry to a leaderboard. Creates a new entry each time it's called.
516
517
 
517
518
  ```typescript
518
519
  const { rank } = await kmClient.leaderboard.insertEntry(
519
- 'high-scores',
520
- 'desc',
520
+ "high-scores",
521
+ "desc",
521
522
  1500,
522
- { playerName: 'Alice', level: 10 },
523
- { sessionId: 'abc123' }
523
+ { playerName: "Alice", level: 10 },
524
+ { sessionId: "abc123" }
524
525
  );
525
526
  console.log(`New rank: ${rank}`);
526
527
  ```
@@ -543,11 +544,11 @@ Add or update the latest entry for the current client in a leaderboard. Replaces
543
544
 
544
545
  ```typescript
545
546
  const { rank } = await kmClient.leaderboard.upsertEntry(
546
- 'daily-scores',
547
- 'desc',
547
+ "daily-scores",
548
+ "desc",
548
549
  2000,
549
- { playerName: 'Bob', completionTime: 120 },
550
- { deviceId: 'xyz789' }
550
+ { playerName: "Bob", completionTime: 120 },
551
+ { deviceId: "xyz789" }
551
552
  );
552
553
  console.log(`Updated rank: ${rank}`);
553
554
  ```
@@ -569,14 +570,16 @@ List entries in a leaderboard with pagination.
569
570
 
570
571
  ```typescript
571
572
  const { items, total } = await kmClient.leaderboard.listEntries(
572
- 'weekly-scores',
573
- 'desc',
573
+ "weekly-scores",
574
+ "desc",
574
575
  0, // skip
575
576
  10 // limit - get top 10
576
577
  );
577
578
 
578
- items.forEach(entry => {
579
- console.log(`Rank ${entry.rank}: ${entry.metadata.playerName} - ${entry.score}`);
579
+ items.forEach((entry) => {
580
+ console.log(
581
+ `Rank ${entry.rank}: ${entry.metadata.playerName} - ${entry.score}`
582
+ );
580
583
  });
581
584
  ```
582
585
 
@@ -596,14 +599,14 @@ Get the best entry for a specific client in a leaderboard.
596
599
 
597
600
  ```typescript
598
601
  // Get current client's best entry
599
- const myBest = await kmClient.leaderboard.getBestEntry('all-time-high', 'desc');
602
+ const myBest = await kmClient.leaderboard.getBestEntry("all-time-high", "desc");
600
603
  console.log(`My best: Rank ${myBest.rank}, Score ${myBest.score}`);
601
604
 
602
605
  // Get another player's best entry
603
606
  const otherBest = await kmClient.leaderboard.getBestEntry(
604
- 'all-time-high',
605
- 'desc',
606
- 'other-client-id'
607
+ "all-time-high",
608
+ "desc",
609
+ "other-client-id"
607
610
  );
608
611
  ```
609
612
 
@@ -614,15 +617,20 @@ const otherBest = await kmClient.leaderboard.getBestEntry(
614
617
  ```typescript
615
618
  // Submit a new high score
616
619
  await kmClient.leaderboard.upsertEntry(
617
- 'high-scores',
618
- 'desc',
620
+ "high-scores",
621
+ "desc",
619
622
  score,
620
623
  { playerName: player.name },
621
624
  { timestamp: Date.now() }
622
625
  );
623
626
 
624
627
  // Display top 10
625
- const { items } = await kmClient.leaderboard.listEntries('high-scores', 'desc', 0, 10);
628
+ const { items } = await kmClient.leaderboard.listEntries(
629
+ "high-scores",
630
+ "desc",
631
+ 0,
632
+ 10
633
+ );
626
634
  ```
627
635
 
628
636
  #### Example: Track Speed Run Times
@@ -630,15 +638,15 @@ const { items } = await kmClient.leaderboard.listEntries('high-scores', 'desc',
630
638
  ```typescript
631
639
  // Submit completion time (lower is better)
632
640
  await kmClient.leaderboard.upsertEntry(
633
- 'speed-run',
634
- 'asc',
641
+ "speed-run",
642
+ "asc",
635
643
  completionTimeInSeconds,
636
- { playerName: player.name, difficulty: 'hard' },
644
+ { playerName: player.name, difficulty: "hard" },
637
645
  {}
638
646
  );
639
647
 
640
648
  // Get personal best
641
- const myBest = await kmClient.leaderboard.getBestEntry('speed-run', 'asc');
649
+ const myBest = await kmClient.leaderboard.getBestEntry("speed-run", "asc");
642
650
  ```
643
651
 
644
652
  ### Key Points
@@ -0,0 +1,3 @@
1
+ export { WsMessageReader } from "./reader";
2
+ export { WsMessageType } from "./type";
3
+ export { WsMessageWriter } from "./writer";
@@ -0,0 +1,3 @@
1
+ export { WsMessageReader } from "./reader";
2
+ export { WsMessageType } from "./type";
3
+ export { WsMessageWriter } from "./writer";
@@ -0,0 +1,11 @@
1
+ export declare class WsMessageReader {
2
+ private buffer;
3
+ private _view;
4
+ private _offset;
5
+ constructor(buffer: ArrayBuffer);
6
+ readInt32(): number;
7
+ readUint32(): number;
8
+ readString(): string;
9
+ readUint8Array(): Uint8Array<ArrayBuffer>;
10
+ get end(): boolean;
11
+ }
@@ -0,0 +1,36 @@
1
+ export class WsMessageReader {
2
+ buffer;
3
+ _view;
4
+ _offset = 0;
5
+ constructor(buffer) {
6
+ this.buffer = buffer;
7
+ this._view = new DataView(buffer);
8
+ }
9
+ readInt32() {
10
+ const value = this._view.getInt32(this._offset, true);
11
+ this._offset += 4;
12
+ return value;
13
+ }
14
+ readUint32() {
15
+ const value = this._view.getUint32(this._offset, true);
16
+ this._offset += 4;
17
+ return value;
18
+ }
19
+ readString() {
20
+ const length = this.readInt32();
21
+ let value = "";
22
+ for (let i = 0; i < length; i++) {
23
+ value += String.fromCharCode(this._view.getUint8(this._offset++));
24
+ }
25
+ return value;
26
+ }
27
+ readUint8Array() {
28
+ const length = this.readInt32();
29
+ const value = new Uint8Array(this.buffer, this._offset, length);
30
+ this._offset += length;
31
+ return value;
32
+ }
33
+ get end() {
34
+ return this._offset === this.buffer.byteLength;
35
+ }
36
+ }
@@ -0,0 +1,11 @@
1
+ export declare enum WsMessageType {
2
+ SubscribeReq = 1,
3
+ SubscribeRes = 2,
4
+ Transaction = 3,
5
+ RoomUpdate = 4,
6
+ Error = 5,
7
+ Ping = 6,
8
+ Pong = 7,
9
+ UnsubscribeReq = 8,
10
+ UnsubscribeRes = 9
11
+ }
@@ -0,0 +1,12 @@
1
+ export var WsMessageType;
2
+ (function (WsMessageType) {
3
+ WsMessageType[WsMessageType["SubscribeReq"] = 1] = "SubscribeReq";
4
+ WsMessageType[WsMessageType["SubscribeRes"] = 2] = "SubscribeRes";
5
+ WsMessageType[WsMessageType["Transaction"] = 3] = "Transaction";
6
+ WsMessageType[WsMessageType["RoomUpdate"] = 4] = "RoomUpdate";
7
+ WsMessageType[WsMessageType["Error"] = 5] = "Error";
8
+ WsMessageType[WsMessageType["Ping"] = 6] = "Ping";
9
+ WsMessageType[WsMessageType["Pong"] = 7] = "Pong";
10
+ WsMessageType[WsMessageType["UnsubscribeReq"] = 8] = "UnsubscribeReq";
11
+ WsMessageType[WsMessageType["UnsubscribeRes"] = 9] = "UnsubscribeRes";
12
+ })(WsMessageType || (WsMessageType = {}));
@@ -0,0 +1,9 @@
1
+ export declare class WsMessageWriter {
2
+ private _parts;
3
+ writeInt32(value: number): void;
4
+ writeUint32(value: number): void;
5
+ writeString(value: string): void;
6
+ writeChar(value: string): void;
7
+ writeUint8Array(value: Uint8Array): void;
8
+ getBuffer(): ArrayBuffer;
9
+ }
@@ -0,0 +1,45 @@
1
+ export class WsMessageWriter {
2
+ _parts = [];
3
+ writeInt32(value) {
4
+ const buffer = new Uint8Array(4);
5
+ const view = new DataView(buffer.buffer);
6
+ view.setInt32(0, value, true);
7
+ this._parts.push(buffer);
8
+ }
9
+ writeUint32(value) {
10
+ const buffer = new Uint8Array(4);
11
+ const view = new DataView(buffer.buffer);
12
+ view.setUint32(0, value, true);
13
+ this._parts.push(buffer);
14
+ }
15
+ writeString(value) {
16
+ // Write length
17
+ this.writeInt32(value.length);
18
+ // Write chars
19
+ const buffer = new Uint8Array(value.length);
20
+ for (let i = 0; i < value.length; i++) {
21
+ buffer[i] = value.charCodeAt(i);
22
+ }
23
+ this._parts.push(buffer);
24
+ }
25
+ writeChar(value) {
26
+ const buffer = new Uint8Array(1);
27
+ buffer[0] = value.charCodeAt(0);
28
+ this._parts.push(buffer);
29
+ }
30
+ writeUint8Array(value) {
31
+ this.writeInt32(value.byteLength);
32
+ this._parts.push(value);
33
+ }
34
+ getBuffer() {
35
+ const size = this._parts.reduce((acc, part) => acc + part.byteLength, 0);
36
+ const buffer = new ArrayBuffer(size);
37
+ let offset = 0;
38
+ for (const part of this._parts) {
39
+ const view = new Uint8Array(buffer, offset);
40
+ view.set(part);
41
+ offset += part.byteLength;
42
+ }
43
+ return buffer;
44
+ }
45
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./kokimoki-ai";
2
+ export * from "./kokimoki-leaderboard";
3
+ export * from "./kokimoki-storage";
@@ -0,0 +1,3 @@
1
+ export * from "./kokimoki-ai";
2
+ export * from "./kokimoki-leaderboard";
3
+ export * from "./kokimoki-storage";
@@ -0,0 +1,153 @@
1
+ import { KokimokiClient } from "../core";
2
+ import type { Upload } from "../types";
3
+ /**
4
+ * Kokimoki AI Integration Service
5
+ *
6
+ * Provides built-in AI capabilities for game applications without requiring API keys or setup.
7
+ * Includes text generation, structured JSON output, and image modification.
8
+ *
9
+ * **Key Features:**
10
+ * - Multiple AI models (GPT-4, GPT-5, Gemini variants)
11
+ * - Text generation with configurable creativity (temperature)
12
+ * - Structured JSON output for game data
13
+ * - AI-powered image modifications
14
+ * - No API keys or configuration required
15
+ *
16
+ * **Common Use Cases:**
17
+ * - Generate dynamic game content (quests, dialogues, stories)
18
+ * - Create AI opponents or NPCs with personalities
19
+ * - Generate quiz questions or trivia
20
+ * - Create game assets (character stats, item descriptions)
21
+ * - Transform user-uploaded images
22
+ * - Generate procedural content
23
+ *
24
+ * Access via `kmClient.ai`
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // Generate story text
29
+ * const story = await kmClient.ai.chat({
30
+ * systemPrompt: 'You are a fantasy story writer',
31
+ * userPrompt: 'Write a short quest description',
32
+ * temperature: 0.8
33
+ * });
34
+ *
35
+ * // Generate structured game data
36
+ * interface Enemy {
37
+ * name: string;
38
+ * health: number;
39
+ * attack: number;
40
+ * }
41
+ * const enemy = await kmClient.ai.generateJson<Enemy>({
42
+ * userPrompt: 'Create a level 5 goblin warrior'
43
+ * });
44
+ *
45
+ * // Transform image
46
+ * const modified = await kmClient.ai.modifyImage(
47
+ * imageUrl,
48
+ * 'Make it look like pixel art'
49
+ * );
50
+ * ```
51
+ */
52
+ export declare class KokimokiAiService {
53
+ private readonly client;
54
+ constructor(client: KokimokiClient);
55
+ /**
56
+ * Generate a chat response from the AI model.
57
+ *
58
+ * Sends a chat request to the AI service and returns the generated response.
59
+ * Supports multiple AI models including GPT and Gemini variants with configurable
60
+ * parameters for fine-tuning the response behavior.
61
+ *
62
+ * @param req The chat request parameters.
63
+ * @param req.model Optional. The AI model to use. Defaults to server-side default if not specified.
64
+ * Available models:
65
+ * - `gpt-4o`: OpenAI GPT-4 Optimized
66
+ * - `gpt-4o-mini`: Smaller, faster GPT-4 variant
67
+ * - `gpt-5`: OpenAI GPT-5 (latest)
68
+ * - `gpt-5-mini`: Smaller GPT-5 variant
69
+ * - `gpt-5-nano`: Smallest GPT-5 variant for lightweight tasks
70
+ * - `gemini-2.5-flash-lite`: Google Gemini lite variant
71
+ * - `gemini-2.5-flash`: Google Gemini fast variant
72
+ * @param req.systemPrompt Optional. The system message that sets the behavior and context for the AI.
73
+ * This helps define the AI's role, personality, and constraints.
74
+ * @param req.userPrompt The user's message or question to send to the AI.
75
+ * @param req.temperature Optional. Controls randomness in the response (0.0 to 1.0).
76
+ * Lower values make output more focused and deterministic,
77
+ * higher values make it more creative and varied.
78
+ * @param req.maxTokens Optional. The maximum number of tokens to generate in the response.
79
+ * Controls the length of the AI's output.
80
+ *
81
+ * @returns A promise that resolves to an object containing the AI-generated response.
82
+ * @returns {string} content The text content of the AI's response.
83
+ *
84
+ * @throws An error object if the API request fails.
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const response = await client.ai.chat({
89
+ * model: "gpt-4o",
90
+ * systemPrompt: "You are a helpful coding assistant.",
91
+ * userPrompt: "Explain what TypeScript is in one sentence.",
92
+ * temperature: 0.7,
93
+ * maxTokens: 100
94
+ * });
95
+ * console.log(response.content);
96
+ * ```
97
+ */
98
+ chat(req: {
99
+ model?: "gpt-4o" | "gpt-4o-mini" | "gpt-5" | "gpt-5-mini" | "gpt-5-nano" | "gemini-2.5-flash-lite" | "gemini-2.5-flash";
100
+ systemPrompt?: string;
101
+ userPrompt: string;
102
+ temperature?: number;
103
+ maxTokens?: number;
104
+ responseMimeType?: string;
105
+ }): Promise<{
106
+ content: string;
107
+ }>;
108
+ /**
109
+ * Generate structured JSON output from the AI model.
110
+ *
111
+ * Sends a chat request to the AI service with the expectation of receiving
112
+ * a JSON-formatted response. This is useful for scenarios where the output
113
+ * needs to be parsed or processed programmatically.
114
+ *
115
+ * @param req The chat request parameters.
116
+ * @param req.model Optional. The AI model to use. Defaults to server-side default if not specified.
117
+ * Available models:
118
+ * - `gpt-4o`: OpenAI GPT-4 Optimized
119
+ * - `gpt-4o-mini`: Smaller, faster GPT-4 variant
120
+ * - `gpt-5`: OpenAI GPT-5 (latest)
121
+ * - `gpt-5-mini`: Smaller GPT-5 variant
122
+ * - `gpt-5-nano`: Smallest GPT-5 variant for lightweight tasks
123
+ * - `gemini-2.5-flash-lite`: Google Gemini lite variant
124
+ * - `gemini-2.5-flash`: Google Gemini fast variant
125
+ * @param req.systemPrompt Optional. The system message that sets the behavior and context for the AI.
126
+ * This helps define the AI's role, personality, and constraints.
127
+ * @param req.userPrompt The user's message or question to send to the AI.
128
+ * @param req.temperature Optional. Controls randomness in the response (0.0 to 1.0).
129
+ * Lower values make output more focused and deterministic,
130
+ * higher values make it more creative and varied.
131
+ * @param req.maxTokens Optional. The maximum number of tokens to generate in the response.
132
+ * Controls the length of the AI's output.
133
+ *
134
+ * @returns A promise that resolves to the parsed JSON object generated by the AI.
135
+ *
136
+ * @throws An error object if the API request fails or if the response is not valid JSON.
137
+ */
138
+ generateJson<T extends object>(req: {
139
+ model?: "gpt-4o" | "gpt-4o-mini" | "gpt-5" | "gpt-5-mini" | "gpt-5-nano" | "gemini-2.5-flash-lite" | "gemini-2.5-flash";
140
+ systemPrompt?: string;
141
+ userPrompt: string;
142
+ temperature?: number;
143
+ maxTokens?: number;
144
+ }): Promise<T>;
145
+ /**
146
+ * Modify an image using the AI service.
147
+ * @param baseImageUrl The URL of the base image to modify.
148
+ * @param prompt The modification prompt to apply to the image.
149
+ * @param tags Optional. Tags to associate with the image.
150
+ * @returns A promise that resolves to the modified image upload information.
151
+ */
152
+ modifyImage(baseImageUrl: string, prompt: string, tags?: string[]): Promise<Upload>;
153
+ }