@game_ryo/lsji 1.1.0 → 1.2.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.
@@ -8,7 +8,7 @@
8
8
  * { box-sizing: border-box; margin: 0; padding: 0; }
9
9
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0d1117; color: #e6edf3; }
10
10
  </style>
11
- <script type="module" crossorigin src="/assets/main-Dfki4A3Q.js"></script>
11
+ <script type="module" crossorigin src="/assets/main-v74qobjz.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/main-DNMVBaZA.css">
13
13
  </head>
14
14
  <body>
@@ -1,7 +1,34 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
 
3
- // Model definitions per provider (as of 2024)
3
+ // Model definitions per provider (as of 2024 - from official API docs)
4
+ // Source: https://ai.google.dev/gemini-api/docs/models?hl=ja
4
5
  const MODELS_BY_PROVIDER = {
6
+ gemini: [
7
+ // Gemini 3 (Latest)
8
+ { value: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro (Preview)' },
9
+ { value: 'gemini-3.5-flash', label: 'Gemini 3.5 Flash (Stable)' },
10
+ { value: 'gemini-3-flash-preview', label: 'Gemini 3 Flash (Preview)' },
11
+ { value: 'gemini-3.1-flash-lite', label: 'Gemini 3.1 Flash-Lite (Preview)' },
12
+ { value: 'gemini-3.1-flash-image', label: 'Nano Banana 2 (Image Generation)' },
13
+ { value: 'gemini-3.1-flash-lite-image', label: 'Nano Banana 2 Lite (Image Generation)' },
14
+ { value: 'gemini-3-pro-image', label: 'Nano Banana Pro (Image Generation)' },
15
+ { value: 'gemini-3.5-live-translate-preview', label: 'Gemini 3.5 Live Translate (Preview)' },
16
+ { value: 'gemini-3.1-flash-live-preview', label: 'Gemini 3.1 Flash Live (Preview)' },
17
+ { value: 'gemini-3.1-flash-tts-preview', label: 'Gemini 3.1 Flash TTS (Preview)' },
18
+ // Gemini 2.5 Flash
19
+ { value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash (Stable) - Best Price/Performance' },
20
+ { value: 'gemini-2.5-flash-image', label: 'Nano Banana (Image Generation)' },
21
+ { value: 'gemini-2.5-flash-native-audio-preview-12-2025', label: 'Gemini 2.5 Flash Live (Preview)' },
22
+ { value: 'gemini-2.5-flash-preview-tts', label: 'Gemini 2.5 Flash TTS (Preview)' },
23
+ // Gemini 2.5 Flash-Lite
24
+ { value: 'gemini-2.5-flash-lite', label: 'Gemini 2.5 Flash-Lite (Preview)' },
25
+ // Gemini 2.5 Pro
26
+ { value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro (Stable) - Best Reasoning' },
27
+ { value: 'gemini-2.5-pro-preview-tts', label: 'Gemini 2.5 Pro TTS (Preview)' },
28
+ // Legacy (Shutdown)
29
+ { value: 'gemini-2.0-flash', label: 'Gemini 2.0 Flash (Shutdown)' },
30
+ { value: 'gemini-2.0-flash-lite', label: 'Gemini 2.0 Flash-Lite (Shutdown)' },
31
+ ],
5
32
  openai: [
6
33
  { value: 'gpt-4o', label: 'GPT-4o (Latest)' },
7
34
  { value: 'gpt-4o-mini', label: 'GPT-4o Mini' },
@@ -16,13 +43,6 @@ const MODELS_BY_PROVIDER = {
16
43
  { value: 'claude-3-sonnet-20240229', label: 'Claude 3 Sonnet' },
17
44
  { value: 'claude-3-haiku-20240307', label: 'Claude 3 Haiku' },
18
45
  ],
19
- gemini: [
20
- { value: 'gemini-1.5-pro', label: 'Gemini 1.5 Pro' },
21
- { value: 'gemini-1.5-flash', label: 'Gemini 1.5 Flash (Default)' },
22
- { value: 'gemini-1.5-flash-8b', label: 'Gemini 1.5 Flash-8B' },
23
- { value: 'gemini-2.0-flash-exp', label: 'Gemini 2.0 Flash (Experimental)' },
24
- { value: 'gemini-2.0-flash-thinking-exp', label: 'Gemini 2.0 Flash Thinking (Experimental)' },
25
- ],
26
46
  local: [
27
47
  { value: 'llama3.2', label: 'Llama 3.2' },
28
48
  { value: 'llama3.1', label: 'Llama 3.1' },
@@ -35,9 +55,9 @@ const MODELS_BY_PROVIDER = {
35
55
 
36
56
  // Default models per provider
37
57
  const DEFAULT_MODELS = {
58
+ gemini: 'gemini-2.5-flash', // Best price/performance for general use
38
59
  openai: 'gpt-4o-mini',
39
60
  anthropic: 'claude-3-5-sonnet-20241022',
40
- gemini: 'gemini-1.5-flash',
41
61
  local: 'llama3.2',
42
62
  };
43
63
 
@@ -130,4 +130,35 @@ export class BetterSqliteStorage extends Storage {
130
130
  `);
131
131
  return stmt.all();
132
132
  }
133
+
134
+ // ===== Generic SQL methods =====
135
+
136
+ async all(sql, params = []) {
137
+ const stmt = this.db.prepare(sql);
138
+ return stmt.all(...params);
139
+ }
140
+
141
+ async get(sql, params = []) {
142
+ const stmt = this.db.prepare(sql);
143
+ return stmt.get(...params);
144
+ }
145
+
146
+ async run(sql, params = []) {
147
+ const stmt = this.db.prepare(sql);
148
+ const result = stmt.run(...params);
149
+ return { changes: result.changes, lastInsertRowid: result.lastInsertRowid };
150
+ }
151
+
152
+ async exec(sql) {
153
+ this.db.exec(sql);
154
+ }
155
+
156
+ prepare(sql) {
157
+ const stmt = this.db.prepare(sql);
158
+ return {
159
+ run: (...params) => stmt.run(...params),
160
+ get: (...params) => stmt.get(...params),
161
+ all: (...params) => stmt.all(...params),
162
+ };
163
+ }
133
164
  }
@@ -114,6 +114,56 @@ export class Storage {
114
114
  async getPerformanceStats() {
115
115
  throw new Error('getPerformanceStats() must be implemented');
116
116
  }
117
+
118
+ // ===== Generic SQL methods for custom queries =====
119
+
120
+ /**
121
+ * Execute a SELECT query returning all rows
122
+ * @param {string} sql - SQL query
123
+ * @param {Array} params - Query parameters
124
+ * @returns {Promise<Array<Object>>}
125
+ */
126
+ async all(sql, params = []) {
127
+ throw new Error('all() must be implemented');
128
+ }
129
+
130
+ /**
131
+ * Execute a SELECT query returning first row
132
+ * @param {string} sql - SQL query
133
+ * @param {Array} params - Query parameters
134
+ * @returns {Promise<Object|null>}
135
+ */
136
+ async get(sql, params = []) {
137
+ throw new Error('get() must be implemented');
138
+ }
139
+
140
+ /**
141
+ * Execute an INSERT/UPDATE/DELETE query
142
+ * @param {string} sql - SQL query
143
+ * @param {Array} params - Query parameters
144
+ * @returns {Promise<{changes: number, lastInsertRowid: number|bigint}>}
145
+ */
146
+ async run(sql, params = []) {
147
+ throw new Error('run() must be implemented');
148
+ }
149
+
150
+ /**
151
+ * Execute multiple SQL statements
152
+ * @param {string} sql - SQL statements
153
+ * @returns {Promise<void>}
154
+ */
155
+ async exec(sql) {
156
+ throw new Error('exec() must be implemented');
157
+ }
158
+
159
+ /**
160
+ * Prepare a statement for repeated execution
161
+ * @param {string} sql - SQL query
162
+ * @returns {Object} Prepared statement with run(), get(), all() methods
163
+ */
164
+ prepare(sql) {
165
+ throw new Error('prepare() must be implemented');
166
+ }
117
167
  }
118
168
 
119
169
  /**
@@ -17,6 +17,7 @@ export class MemoryStorage extends Storage {
17
17
  this.settings = new Map();
18
18
  this.battleHistory = [];
19
19
  this.qTable = new Map(); // key: "state:action" -> q_value
20
+ this.conversations = []; // For conversation memory
20
21
  this.initialized = false;
21
22
  }
22
23
 
@@ -93,6 +94,193 @@ export class MemoryStorage extends Storage {
93
94
  this.settings.clear();
94
95
  this.battleHistory = [];
95
96
  this.qTable.clear();
97
+ this.conversations = [];
96
98
  this.settings.set('is_active', '1');
97
99
  }
100
+
101
+ // ===== Generic SQL methods (in-memory implementation) =====
102
+
103
+ async all(sql, params = []) {
104
+ // Simple in-memory SQL-like query parser for basic SELECT queries
105
+ // This is a simplified implementation for testing
106
+ const lowerSql = sql.toLowerCase().trim();
107
+
108
+ if (lowerSql.startsWith('select')) {
109
+ if (lowerSql.includes('from conversations')) {
110
+ let results = [...this.conversations];
111
+
112
+ // Simple WHERE clause handling for session_id
113
+ const whereMatch = lowerSql.match(/where\s+session_id\s*=\s*\?/i);
114
+ if (whereMatch && params.length > 0) {
115
+ const sessionId = params[0];
116
+ results = results.filter(r => r.session_id === sessionId);
117
+ }
118
+
119
+ // ORDER BY created_at ASC
120
+ results.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
121
+
122
+ return results;
123
+ }
124
+
125
+ if (lowerSql.includes('from idempotency_keys')) {
126
+ // For idempotency store
127
+ return [];
128
+ }
129
+
130
+ if (lowerSql.includes('from checkpoints')) {
131
+ // For execution engine
132
+ return [];
133
+ }
134
+
135
+ if (lowerSql.includes('from approvals')) {
136
+ // For HITL
137
+ return [];
138
+ }
139
+ }
140
+
141
+ return [];
142
+ }
143
+
144
+ async get(sql, params = []) {
145
+ const results = await this.all(sql, params);
146
+ return results[0] || null;
147
+ }
148
+
149
+ async run(sql, params = []) {
150
+ const lowerSql = sql.toLowerCase().trim();
151
+
152
+ if (lowerSql.startsWith('insert')) {
153
+ if (lowerSql.includes('into conversations')) {
154
+ // INSERT INTO conversations (id, session_id, role, content, name, tool_call_id, tool_calls, tokens, created_at)
155
+ const id = params[0];
156
+ const sessionId = params[1];
157
+ const role = params[2];
158
+ const content = params[3];
159
+ const name = params[4];
160
+ const toolCallId = params[5];
161
+ const toolCalls = params[6];
162
+ const tokens = params[7];
163
+ const createdAt = params[8];
164
+
165
+ this.conversations.push({
166
+ id,
167
+ session_id: sessionId,
168
+ role,
169
+ content,
170
+ name,
171
+ tool_call_id: toolCallId,
172
+ tool_calls: toolCalls,
173
+ tokens,
174
+ created_at: createdAt,
175
+ });
176
+ }
177
+
178
+ if (lowerSql.includes('into idempotency_keys')) {
179
+ // For idempotency store
180
+ }
181
+
182
+ if (lowerSql.includes('into checkpoints')) {
183
+ // For execution engine
184
+ }
185
+
186
+ if (lowerSql.includes('into approvals')) {
187
+ // For HITL
188
+ }
189
+
190
+ if (lowerSql.includes('into settings')) {
191
+ // Handled by setSetting
192
+ }
193
+
194
+ if (lowerSql.includes('into battle_history')) {
195
+ // Handled by addBattle
196
+ }
197
+
198
+ if (lowerSql.includes('into q_table')) {
199
+ // Handled by updateQ
200
+ }
201
+
202
+ return { changes: 1, lastInsertRowid: Date.now() };
203
+ }
204
+
205
+ if (lowerSql.startsWith('update')) {
206
+ if (lowerSql.includes('idempotency_keys')) {
207
+ // For idempotency store
208
+ }
209
+
210
+ if (lowerSql.includes('approvals')) {
211
+ // For HITL
212
+ }
213
+
214
+ return { changes: 1, lastInsertRowid: 0 };
215
+ }
216
+
217
+ if (lowerSql.startsWith('delete')) {
218
+ if (lowerSql.includes('from conversations')) {
219
+ if (params[0]) {
220
+ this.conversations = this.conversations.filter(c => c.session_id !== params[0]);
221
+ }
222
+ }
223
+
224
+ if (lowerSql.includes('from idempotency_keys')) {
225
+ // For idempotency store
226
+ }
227
+
228
+ return { changes: 1, lastInsertRowid: 0 };
229
+ }
230
+
231
+ return { changes: 0, lastInsertRowid: 0 };
232
+ }
233
+
234
+ async exec(sql) {
235
+ // No-op for memory storage
236
+ }
237
+
238
+ prepare(sql) {
239
+ const self = this;
240
+ return {
241
+ run: async (...params) => (await self.run(sql, params)),
242
+ get: async (...params) => (await self.get(sql, params)),
243
+ all: async (...params) => (await self.all(sql, params)),
244
+ };
245
+ }
246
+
247
+ // Helper methods for conversation memory
248
+ _addConversation(message) {
249
+ this.conversations.push(message);
250
+ }
251
+
252
+ _getConversations(sessionId) {
253
+ return this.conversations.filter(c => c.session_id === sessionId);
254
+ }
255
+
256
+ _clearConversations(sessionId) {
257
+ this.conversations = this.conversations.filter(c => c.session_id !== sessionId);
258
+ }
259
+
260
+ // For idempotency store
261
+ _getIdempotencyKeys() {
262
+ return this.idempotencyKeys || new Map();
263
+ }
264
+
265
+ _setIdempotencyKeys(keys) {
266
+ this.idempotencyKeys = keys;
267
+ }
268
+
269
+ // For checkpoints
270
+ _getCheckpoints() {
271
+ return this.checkpoints || new Map();
272
+ }
273
+
274
+ _setCheckpoints(checkpoints) {
275
+ this.checkpoints = checkpoints;
276
+ }
277
+
278
+ // For approvals
279
+ _getApprovals() {
280
+ return this.approvals || new Map();
281
+ }
282
+
283
+ _setApprovals(approvals) {
284
+ this.approvals = approvals;
285
+ }
98
286
  }
@@ -120,4 +120,35 @@ export class SqliteStorage extends Storage {
120
120
  `);
121
121
  return stmt.all();
122
122
  }
123
+
124
+ // ===== Generic SQL methods =====
125
+
126
+ async all(sql, params = []) {
127
+ const stmt = this.db.prepare(sql);
128
+ return stmt.all(...params);
129
+ }
130
+
131
+ async get(sql, params = []) {
132
+ const stmt = this.db.prepare(sql);
133
+ return stmt.get(...params);
134
+ }
135
+
136
+ async run(sql, params = []) {
137
+ const stmt = this.db.prepare(sql);
138
+ const result = stmt.run(...params);
139
+ return { changes: result.changes, lastInsertRowid: result.lastInsertRowid };
140
+ }
141
+
142
+ async exec(sql) {
143
+ this.db.exec(sql);
144
+ }
145
+
146
+ prepare(sql) {
147
+ const stmt = this.db.prepare(sql);
148
+ return {
149
+ run: (...params) => stmt.run(...params),
150
+ get: (...params) => stmt.get(...params),
151
+ all: (...params) => stmt.all(...params),
152
+ };
153
+ }
123
154
  }