@kokimoki/app 1.17.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.
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +3 -0
- package/dist/core/kokimoki-client.d.ts +361 -0
- package/dist/core/kokimoki-client.js +819 -0
- package/dist/core/room-subscription-mode.d.ts +5 -0
- package/dist/core/room-subscription-mode.js +6 -0
- package/dist/core/room-subscription.d.ts +15 -0
- package/dist/core/room-subscription.js +53 -0
- package/dist/fields.d.ts +110 -0
- package/dist/fields.js +158 -0
- package/dist/index.d.ts +4 -8
- package/dist/index.js +4 -9
- package/dist/kokimoki-ai.d.ts +153 -0
- package/dist/kokimoki-ai.js +164 -0
- package/dist/kokimoki-awareness.d.ts +14 -13
- package/dist/kokimoki-awareness.js +41 -33
- package/dist/kokimoki-client-refactored.d.ts +80 -0
- package/dist/kokimoki-client-refactored.js +400 -0
- package/dist/kokimoki-client.d.ts +282 -76
- package/dist/kokimoki-client.js +295 -232
- package/dist/kokimoki-leaderboard.d.ts +175 -0
- package/dist/kokimoki-leaderboard.js +203 -0
- package/dist/kokimoki-schema.d.ts +113 -0
- package/dist/kokimoki-schema.js +162 -0
- package/dist/kokimoki-storage.d.ts +156 -0
- package/dist/kokimoki-storage.js +208 -0
- package/dist/kokimoki.min.d.ts +775 -110
- package/dist/kokimoki.min.js +4088 -2408
- package/dist/kokimoki.min.js.map +1 -1
- package/dist/llms.txt +657 -0
- package/dist/message-queue.d.ts +8 -0
- package/dist/message-queue.js +19 -0
- package/dist/protocol/ws-message/index.d.ts +3 -0
- package/dist/protocol/ws-message/index.js +3 -0
- package/dist/protocol/ws-message/reader.d.ts +11 -0
- package/dist/protocol/ws-message/reader.js +36 -0
- package/dist/protocol/ws-message/type.d.ts +11 -0
- package/dist/protocol/ws-message/type.js +12 -0
- package/dist/protocol/ws-message/writer.d.ts +9 -0
- package/dist/protocol/ws-message/writer.js +45 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +3 -0
- package/dist/services/kokimoki-ai.d.ts +153 -0
- package/dist/services/kokimoki-ai.js +164 -0
- package/dist/services/kokimoki-leaderboard.d.ts +175 -0
- package/dist/services/kokimoki-leaderboard.js +203 -0
- package/dist/services/kokimoki-storage.d.ts +155 -0
- package/dist/services/kokimoki-storage.js +208 -0
- package/dist/stores/index.d.ts +3 -0
- package/dist/stores/index.js +3 -0
- package/dist/stores/kokimoki-local-store.d.ts +11 -0
- package/dist/stores/kokimoki-local-store.js +40 -0
- package/dist/stores/kokimoki-store.d.ts +22 -0
- package/dist/stores/kokimoki-store.js +117 -0
- package/dist/stores/kokimoki-transaction.d.ts +18 -0
- package/dist/stores/kokimoki-transaction.js +143 -0
- package/dist/synced-schema.d.ts +74 -0
- package/dist/synced-schema.js +83 -0
- package/dist/synced-store.d.ts +10 -0
- package/dist/synced-store.js +9 -0
- package/dist/synced-types.d.ts +47 -0
- package/dist/synced-types.js +67 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.js +3 -0
- package/dist/utils/valtio.d.ts +7 -0
- package/dist/utils/valtio.js +6 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -1
- package/dist/ws-message-type copy.d.ts +6 -0
- package/dist/ws-message-type copy.js +7 -0
- package/package.json +4 -3
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { KokimokiStore } from "../stores";
|
|
2
|
+
import type { KokimokiClient } from "./kokimoki-client";
|
|
3
|
+
export declare class RoomSubscription {
|
|
4
|
+
private kmClient;
|
|
5
|
+
readonly store: KokimokiStore<any>;
|
|
6
|
+
private _joined;
|
|
7
|
+
private _roomHash?;
|
|
8
|
+
private _onDisconnect;
|
|
9
|
+
constructor(kmClient: KokimokiClient, store: KokimokiStore<any>);
|
|
10
|
+
get roomName(): string;
|
|
11
|
+
get roomHash(): number;
|
|
12
|
+
get joined(): boolean;
|
|
13
|
+
applyInitialResponse(roomHash: number, initialUpdate?: Uint8Array): Promise<void>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { RoomSubscriptionMode } from "./room-subscription-mode";
|
|
3
|
+
export class RoomSubscription {
|
|
4
|
+
kmClient;
|
|
5
|
+
store;
|
|
6
|
+
_joined = false;
|
|
7
|
+
_roomHash;
|
|
8
|
+
_onDisconnect = () => {
|
|
9
|
+
this._joined = false;
|
|
10
|
+
};
|
|
11
|
+
constructor(kmClient, store) {
|
|
12
|
+
this.kmClient = kmClient;
|
|
13
|
+
this.store = store;
|
|
14
|
+
kmClient.on("disconnected", this._onDisconnect);
|
|
15
|
+
}
|
|
16
|
+
get roomName() {
|
|
17
|
+
return this.store.roomName;
|
|
18
|
+
}
|
|
19
|
+
get roomHash() {
|
|
20
|
+
if (!this._roomHash) {
|
|
21
|
+
throw new Error("Room not joined");
|
|
22
|
+
}
|
|
23
|
+
return this._roomHash;
|
|
24
|
+
}
|
|
25
|
+
get joined() {
|
|
26
|
+
return this._joined;
|
|
27
|
+
}
|
|
28
|
+
async applyInitialResponse(roomHash, initialUpdate) {
|
|
29
|
+
this._roomHash = roomHash;
|
|
30
|
+
// Apply initial state
|
|
31
|
+
if (initialUpdate) {
|
|
32
|
+
Y.applyUpdate(this.store.doc, initialUpdate, this);
|
|
33
|
+
}
|
|
34
|
+
// Set defaults if doc is empty after sync (only possible in ReadWrite mode)
|
|
35
|
+
if (this.store.mode === RoomSubscriptionMode.ReadWrite) {
|
|
36
|
+
await this.kmClient.transact([this.store], ([state]) => {
|
|
37
|
+
if (!("_connections" in state)) {
|
|
38
|
+
state._connections = {};
|
|
39
|
+
}
|
|
40
|
+
for (const key in this.store.defaultValue) {
|
|
41
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
42
|
+
if (!state.hasOwnProperty(key)) {
|
|
43
|
+
state[key] = this.store.defaultValue[key];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
this._joined = true;
|
|
49
|
+
}
|
|
50
|
+
close() {
|
|
51
|
+
this.kmClient.off("disconnected", this._onDisconnect);
|
|
52
|
+
}
|
|
53
|
+
}
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export interface FieldOptions {
|
|
2
|
+
label?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare abstract class Field<T> {
|
|
5
|
+
readonly options: FieldOptions;
|
|
6
|
+
constructor(options: FieldOptions);
|
|
7
|
+
abstract get value(): T;
|
|
8
|
+
abstract get schema(): any;
|
|
9
|
+
}
|
|
10
|
+
export declare class BooleanField extends Field<boolean> {
|
|
11
|
+
value: boolean;
|
|
12
|
+
constructor(value: boolean, options?: FieldOptions);
|
|
13
|
+
get schema(): {
|
|
14
|
+
type: string;
|
|
15
|
+
default: boolean;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare class ConstField<T extends string> extends Field<
|
|
19
|
+
string extends T ? never : T
|
|
20
|
+
> {
|
|
21
|
+
value: string extends T ? never : T;
|
|
22
|
+
constructor(value: string extends T ? never : T, options?: FieldOptions);
|
|
23
|
+
get schema(): {
|
|
24
|
+
const: string extends T ? never : T;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare class ImageField extends Field<string> {
|
|
28
|
+
value: string;
|
|
29
|
+
constructor(value: string, options?: FieldOptions);
|
|
30
|
+
get schema(): {
|
|
31
|
+
type: string;
|
|
32
|
+
default: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export declare class TextField extends Field<string> {
|
|
36
|
+
value: string;
|
|
37
|
+
constructor(value: string, options?: FieldOptions);
|
|
38
|
+
get schema(): {
|
|
39
|
+
type: string;
|
|
40
|
+
default: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export declare class EnumField<T extends Record<string, string>> extends Field<
|
|
44
|
+
keyof T
|
|
45
|
+
> {
|
|
46
|
+
enumValues: T;
|
|
47
|
+
value: keyof T;
|
|
48
|
+
constructor(enumValues: T, value: keyof T, options?: FieldOptions);
|
|
49
|
+
get schema(): {
|
|
50
|
+
enum: string[];
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export declare class IntegerField extends Field<number> {
|
|
54
|
+
value: number;
|
|
55
|
+
constructor(value: number, options?: FieldOptions);
|
|
56
|
+
get schema(): {
|
|
57
|
+
type: string;
|
|
58
|
+
default: number;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export declare class FloatField extends Field<number> {
|
|
62
|
+
value: number;
|
|
63
|
+
constructor(value: number, options?: FieldOptions);
|
|
64
|
+
get schema(): {
|
|
65
|
+
type: string;
|
|
66
|
+
default: number;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export declare class FormGroup<
|
|
70
|
+
T extends Record<string, Field<any>>,
|
|
71
|
+
O extends Record<string, Field<any>>,
|
|
72
|
+
> extends Field<
|
|
73
|
+
{
|
|
74
|
+
[key in keyof T]: T[key]["value"];
|
|
75
|
+
} & Partial<{
|
|
76
|
+
[key in keyof O]: O[key]["value"];
|
|
77
|
+
}>
|
|
78
|
+
> {
|
|
79
|
+
requiredFields: T;
|
|
80
|
+
optionalFields: O;
|
|
81
|
+
constructor(requiredFields: T, optionalFields?: O, options?: FieldOptions);
|
|
82
|
+
get value(): {
|
|
83
|
+
[key in keyof T]: T[key]["value"];
|
|
84
|
+
} & Partial<{
|
|
85
|
+
[key in keyof O]: O[key]["value"];
|
|
86
|
+
}>;
|
|
87
|
+
get schema(): {
|
|
88
|
+
type: string;
|
|
89
|
+
properties: any;
|
|
90
|
+
required: string[];
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export declare class FormArray<T> extends Field<T[]> {
|
|
94
|
+
private factory;
|
|
95
|
+
value: Field<T>["value"][];
|
|
96
|
+
constructor(
|
|
97
|
+
factory: () => Field<T>,
|
|
98
|
+
value: Field<T>["value"][],
|
|
99
|
+
options?: FieldOptions,
|
|
100
|
+
);
|
|
101
|
+
get schema(): {
|
|
102
|
+
type: string;
|
|
103
|
+
items: any;
|
|
104
|
+
default: T[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export declare class Form<
|
|
108
|
+
R extends Record<string, Field<any>>,
|
|
109
|
+
O extends Record<string, Field<any>>,
|
|
110
|
+
> extends FormGroup<R, O> {}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const defaultFieldOptions = {};
|
|
2
|
+
export class Field {
|
|
3
|
+
options;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class BooleanField extends Field {
|
|
9
|
+
value;
|
|
10
|
+
constructor(value, options = defaultFieldOptions) {
|
|
11
|
+
super(options);
|
|
12
|
+
this.value = value;
|
|
13
|
+
}
|
|
14
|
+
get schema() {
|
|
15
|
+
return {
|
|
16
|
+
type: "boolean",
|
|
17
|
+
default: this.value,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class ConstField extends Field {
|
|
22
|
+
value;
|
|
23
|
+
constructor(value, options = defaultFieldOptions) {
|
|
24
|
+
super(options);
|
|
25
|
+
this.value = value;
|
|
26
|
+
}
|
|
27
|
+
get schema() {
|
|
28
|
+
return {
|
|
29
|
+
const: this.value,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class ImageField extends Field {
|
|
34
|
+
value;
|
|
35
|
+
constructor(value, options = defaultFieldOptions) {
|
|
36
|
+
super(options);
|
|
37
|
+
this.value = value;
|
|
38
|
+
}
|
|
39
|
+
get schema() {
|
|
40
|
+
return {
|
|
41
|
+
type: "string",
|
|
42
|
+
default: this.value,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export class TextField extends Field {
|
|
47
|
+
value;
|
|
48
|
+
constructor(value, options = defaultFieldOptions) {
|
|
49
|
+
super(options);
|
|
50
|
+
this.value = value;
|
|
51
|
+
}
|
|
52
|
+
get schema() {
|
|
53
|
+
return {
|
|
54
|
+
type: "string",
|
|
55
|
+
default: this.value,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class EnumField extends Field {
|
|
60
|
+
enumValues;
|
|
61
|
+
value;
|
|
62
|
+
constructor(enumValues, value, options = defaultFieldOptions) {
|
|
63
|
+
super(options);
|
|
64
|
+
this.enumValues = enumValues;
|
|
65
|
+
this.value = value;
|
|
66
|
+
}
|
|
67
|
+
get schema() {
|
|
68
|
+
return {
|
|
69
|
+
enum: Object.keys(this.enumValues),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export class IntegerField extends Field {
|
|
74
|
+
value;
|
|
75
|
+
constructor(value, options = defaultFieldOptions) {
|
|
76
|
+
super(options);
|
|
77
|
+
this.value = value;
|
|
78
|
+
}
|
|
79
|
+
get schema() {
|
|
80
|
+
return {
|
|
81
|
+
type: "integer",
|
|
82
|
+
default: this.value,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export class FloatField extends Field {
|
|
87
|
+
value;
|
|
88
|
+
constructor(value, options = defaultFieldOptions) {
|
|
89
|
+
super(options);
|
|
90
|
+
this.value = value;
|
|
91
|
+
}
|
|
92
|
+
get schema() {
|
|
93
|
+
return {
|
|
94
|
+
type: "number",
|
|
95
|
+
default: this.value,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export class FormGroup extends Field {
|
|
100
|
+
requiredFields;
|
|
101
|
+
optionalFields;
|
|
102
|
+
constructor(
|
|
103
|
+
requiredFields,
|
|
104
|
+
optionalFields = {},
|
|
105
|
+
options = defaultFieldOptions,
|
|
106
|
+
) {
|
|
107
|
+
super(options);
|
|
108
|
+
this.requiredFields = requiredFields;
|
|
109
|
+
this.optionalFields = optionalFields;
|
|
110
|
+
}
|
|
111
|
+
get value() {
|
|
112
|
+
const value = Object.entries(this.requiredFields).reduce(
|
|
113
|
+
(acc, [key, field]) => {
|
|
114
|
+
acc[key] = field.value;
|
|
115
|
+
return acc;
|
|
116
|
+
},
|
|
117
|
+
{},
|
|
118
|
+
);
|
|
119
|
+
Object.entries(this.optionalFields).forEach(([key, field]) => {
|
|
120
|
+
if (field.value !== undefined) {
|
|
121
|
+
value[key] = field.value;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
get schema() {
|
|
127
|
+
const properties = {};
|
|
128
|
+
Object.entries(this.requiredFields).forEach(([key, field]) => {
|
|
129
|
+
properties[key] = field.schema;
|
|
130
|
+
});
|
|
131
|
+
Object.entries(this.optionalFields).forEach(([key, field]) => {
|
|
132
|
+
properties[key] = field.schema;
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
type: "object",
|
|
136
|
+
properties,
|
|
137
|
+
required: Object.keys(this.requiredFields),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class FormArray extends Field {
|
|
142
|
+
factory;
|
|
143
|
+
value;
|
|
144
|
+
constructor(factory, value, options = defaultFieldOptions) {
|
|
145
|
+
super(options);
|
|
146
|
+
this.factory = factory;
|
|
147
|
+
this.value = value;
|
|
148
|
+
}
|
|
149
|
+
get schema() {
|
|
150
|
+
const field = this.factory();
|
|
151
|
+
return {
|
|
152
|
+
type: "array",
|
|
153
|
+
items: field.schema,
|
|
154
|
+
default: this.value,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export class Form extends FormGroup {}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./kokimoki-store";
|
|
6
|
-
export * from "./room-subscription";
|
|
7
|
-
export * from "./room-subscription-mode";
|
|
8
|
-
export * from "./kokimoki-awareness";
|
|
1
|
+
export { KokimokiClient } from "./core";
|
|
2
|
+
export { KokimokiStore } from "./stores";
|
|
3
|
+
export type { KokimokiClientEvents, Paginated, Upload } from "./types";
|
|
4
|
+
export * from "./utils/valtio";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./kokimoki-store";
|
|
6
|
-
// export * from "./kokimoki-queue";
|
|
7
|
-
export * from "./room-subscription";
|
|
8
|
-
export * from "./room-subscription-mode";
|
|
9
|
-
export * from "./kokimoki-awareness";
|
|
1
|
+
export { KokimokiClient } from "./core";
|
|
2
|
+
export { KokimokiStore } from "./stores";
|
|
3
|
+
// Re-export Valtio utilities
|
|
4
|
+
export * from "./utils/valtio";
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { Upload } from "./types/upload";
|
|
2
|
+
import { KokimokiClient } from "./kokimoki-client";
|
|
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 KokimokiAi {
|
|
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
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kokimoki AI Integration Service
|
|
3
|
+
*
|
|
4
|
+
* Provides built-in AI capabilities for game applications without requiring API keys or setup.
|
|
5
|
+
* Includes text generation, structured JSON output, and image modification.
|
|
6
|
+
*
|
|
7
|
+
* **Key Features:**
|
|
8
|
+
* - Multiple AI models (GPT-4, GPT-5, Gemini variants)
|
|
9
|
+
* - Text generation with configurable creativity (temperature)
|
|
10
|
+
* - Structured JSON output for game data
|
|
11
|
+
* - AI-powered image modifications
|
|
12
|
+
* - No API keys or configuration required
|
|
13
|
+
*
|
|
14
|
+
* **Common Use Cases:**
|
|
15
|
+
* - Generate dynamic game content (quests, dialogues, stories)
|
|
16
|
+
* - Create AI opponents or NPCs with personalities
|
|
17
|
+
* - Generate quiz questions or trivia
|
|
18
|
+
* - Create game assets (character stats, item descriptions)
|
|
19
|
+
* - Transform user-uploaded images
|
|
20
|
+
* - Generate procedural content
|
|
21
|
+
*
|
|
22
|
+
* Access via `kmClient.ai`
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // Generate story text
|
|
27
|
+
* const story = await kmClient.ai.chat({
|
|
28
|
+
* systemPrompt: 'You are a fantasy story writer',
|
|
29
|
+
* userPrompt: 'Write a short quest description',
|
|
30
|
+
* temperature: 0.8
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Generate structured game data
|
|
34
|
+
* interface Enemy {
|
|
35
|
+
* name: string;
|
|
36
|
+
* health: number;
|
|
37
|
+
* attack: number;
|
|
38
|
+
* }
|
|
39
|
+
* const enemy = await kmClient.ai.generateJson<Enemy>({
|
|
40
|
+
* userPrompt: 'Create a level 5 goblin warrior'
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Transform image
|
|
44
|
+
* const modified = await kmClient.ai.modifyImage(
|
|
45
|
+
* imageUrl,
|
|
46
|
+
* 'Make it look like pixel art'
|
|
47
|
+
* );
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export class KokimokiAi {
|
|
51
|
+
client;
|
|
52
|
+
constructor(client) {
|
|
53
|
+
this.client = client;
|
|
54
|
+
}
|
|
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
|
+
async chat(req) {
|
|
99
|
+
const res = await fetch(`${this.client.apiUrl}/ai/chat`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: this.client.apiHeaders,
|
|
102
|
+
body: JSON.stringify(req),
|
|
103
|
+
});
|
|
104
|
+
if (!res.ok) {
|
|
105
|
+
throw await res.json();
|
|
106
|
+
}
|
|
107
|
+
return await res.json();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Generate structured JSON output from the AI model.
|
|
111
|
+
*
|
|
112
|
+
* Sends a chat request to the AI service with the expectation of receiving
|
|
113
|
+
* a JSON-formatted response. This is useful for scenarios where the output
|
|
114
|
+
* needs to be parsed or processed programmatically.
|
|
115
|
+
*
|
|
116
|
+
* @param req The chat request parameters.
|
|
117
|
+
* @param req.model Optional. The AI model to use. Defaults to server-side default if not specified.
|
|
118
|
+
* Available models:
|
|
119
|
+
* - `gpt-4o`: OpenAI GPT-4 Optimized
|
|
120
|
+
* - `gpt-4o-mini`: Smaller, faster GPT-4 variant
|
|
121
|
+
* - `gpt-5`: OpenAI GPT-5 (latest)
|
|
122
|
+
* - `gpt-5-mini`: Smaller GPT-5 variant
|
|
123
|
+
* - `gpt-5-nano`: Smallest GPT-5 variant for lightweight tasks
|
|
124
|
+
* - `gemini-2.5-flash-lite`: Google Gemini lite variant
|
|
125
|
+
* - `gemini-2.5-flash`: Google Gemini fast variant
|
|
126
|
+
* @param req.systemPrompt Optional. The system message that sets the behavior and context for the AI.
|
|
127
|
+
* This helps define the AI's role, personality, and constraints.
|
|
128
|
+
* @param req.userPrompt The user's message or question to send to the AI.
|
|
129
|
+
* @param req.temperature Optional. Controls randomness in the response (0.0 to 1.0).
|
|
130
|
+
* Lower values make output more focused and deterministic,
|
|
131
|
+
* higher values make it more creative and varied.
|
|
132
|
+
* @param req.maxTokens Optional. The maximum number of tokens to generate in the response.
|
|
133
|
+
* Controls the length of the AI's output.
|
|
134
|
+
*
|
|
135
|
+
* @returns A promise that resolves to the parsed JSON object generated by the AI.
|
|
136
|
+
*
|
|
137
|
+
* @throws An error object if the API request fails or if the response is not valid JSON.
|
|
138
|
+
*/
|
|
139
|
+
async generateJson(req) {
|
|
140
|
+
const { content } = await this.chat({
|
|
141
|
+
...req,
|
|
142
|
+
responseMimeType: "application/json",
|
|
143
|
+
});
|
|
144
|
+
return JSON.parse(content);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Modify an image using the AI service.
|
|
148
|
+
* @param baseImageUrl The URL of the base image to modify.
|
|
149
|
+
* @param prompt The modification prompt to apply to the image.
|
|
150
|
+
* @param tags Optional. Tags to associate with the image.
|
|
151
|
+
* @returns A promise that resolves to the modified image upload information.
|
|
152
|
+
*/
|
|
153
|
+
async modifyImage(baseImageUrl, prompt, tags = []) {
|
|
154
|
+
const res = await fetch(`${this.client.apiUrl}/ai/modify-image`, {
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: this.client.apiHeaders,
|
|
157
|
+
body: JSON.stringify({ baseImageUrl, prompt, tags }),
|
|
158
|
+
});
|
|
159
|
+
if (!res.ok) {
|
|
160
|
+
throw await res.json();
|
|
161
|
+
}
|
|
162
|
+
return await res.json();
|
|
163
|
+
}
|
|
164
|
+
}
|