@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.
- package/AGENTS.md +90 -21
- package/README.md +15 -15
- package/package.json +3 -2
- package/src/cli.js +11 -4
- package/src/execution/hitl/approval-gate.js +3 -1
- package/src/execution/idempotency.js +4 -2
- package/src/index.js +1 -1
- package/src/llm/llm-agent.js +30 -7
- package/src/llm/memory/conversation.js +11 -10
- package/src/llm/prompt-manager.js +58 -139
- package/src/server/index.js +6 -11
- package/src/server/ui/dist/assets/{main-Dfki4A3Q.js → main-v74qobjz.js} +8 -8
- package/src/server/ui/dist/index.html +1 -1
- package/src/server/ui/src/components/NewRunModal.jsx +29 -9
- package/src/storage/better-sqlite.js +31 -0
- package/src/storage/index.js +50 -0
- package/src/storage/memory.js +188 -0
- package/src/storage/sqlite.js +31 -0
|
@@ -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-
|
|
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
|
}
|
package/src/storage/index.js
CHANGED
|
@@ -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
|
/**
|
package/src/storage/memory.js
CHANGED
|
@@ -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
|
}
|
package/src/storage/sqlite.js
CHANGED
|
@@ -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
|
}
|