@game_ryo/lsji 0.1.0 → 0.1.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 (43) hide show
  1. package/package.json +4 -1
  2. package/docs/README.md +0 -43
  3. package/docs/blog/2019-05-28-first-blog-post.mdx +0 -12
  4. package/docs/blog/2019-05-29-long-blog-post.mdx +0 -44
  5. package/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -24
  6. package/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  7. package/docs/blog/2021-08-26-welcome/index.mdx +0 -29
  8. package/docs/blog/authors.yml +0 -25
  9. package/docs/blog/tags.yml +0 -19
  10. package/docs/docs/api/agent.md +0 -151
  11. package/docs/docs/api/env.md +0 -133
  12. package/docs/docs/api/environments.md +0 -102
  13. package/docs/docs/api/qlearning.md +0 -138
  14. package/docs/docs/api/storage.md +0 -168
  15. package/docs/docs/architecture.md +0 -155
  16. package/docs/docs/cli.md +0 -210
  17. package/docs/docs/contributing.md +0 -162
  18. package/docs/docs/core-concepts.md +0 -152
  19. package/docs/docs/examples/advanced-training.md +0 -244
  20. package/docs/docs/examples/custom-environment.md +0 -198
  21. package/docs/docs/examples/custom-storage.md +0 -251
  22. package/docs/docs/getting-started.md +0 -91
  23. package/docs/docusaurus.config.ts +0 -149
  24. package/docs/package-lock.json +0 -19522
  25. package/docs/package.json +0 -49
  26. package/docs/sidebars.ts +0 -33
  27. package/docs/src/components/HomepageFeatures/index.tsx +0 -71
  28. package/docs/src/components/HomepageFeatures/styles.module.css +0 -11
  29. package/docs/src/css/custom.css +0 -79
  30. package/docs/src/pages/index.module.css +0 -23
  31. package/docs/src/pages/index.tsx +0 -44
  32. package/docs/src/pages/markdown-page.mdx +0 -7
  33. package/docs/static/.nojekyll +0 -0
  34. package/docs/static/img/docusaurus-social-card.jpg +0 -0
  35. package/docs/static/img/docusaurus.png +0 -0
  36. package/docs/static/img/favicon.ico +0 -0
  37. package/docs/static/img/logo.png +0 -0
  38. package/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
  39. package/docs/static/img/undraw_docusaurus_react.svg +0 -170
  40. package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
  41. package/docs/tsconfig.json +0 -12
  42. package/legacy/worker.js +0 -166
  43. package/legacy/wrangler.toml +0 -11
@@ -1,138 +0,0 @@
1
- ---
2
- title: QLearning API
3
- description: Tabular Q-Learning engine with TD updates
4
- ---
5
-
6
- # QLearning API
7
-
8
- The `QLearning` class implements tabular Q-Learning with epsilon-greedy exploration.
9
-
10
- ## Import
11
-
12
- ```typescript
13
- import { QLearning } from 'lsji';
14
- ```
15
-
16
- ## Constructor
17
-
18
- ```typescript
19
- const qlearning = new QLearning({
20
- alpha: 0.1, // Learning rate [0, 1] (default: 0.1)
21
- gamma: 0.9, // Discount factor [0, 1] (default: 0.9)
22
- epsilon: 0.1, // Exploration rate [0, 1] (default: 0.1)
23
- storage: Storage // Required: Storage backend
24
- });
25
- ```
26
-
27
- Values are automatically clamped to [0, 1] range.
28
-
29
- ## Methods
30
-
31
- ### `initialize()`
32
- Load Q-table from storage. Called automatically by other methods.
33
-
34
- ```typescript
35
- await qlearning.initialize();
36
- ```
37
-
38
- ### `getQValue(state, action)`
39
- Get Q-value for a state-action pair.
40
-
41
- ```typescript
42
- const value = qlearning.getQValue('state1', 0);
43
- // Returns: number (0 if unseen)
44
- ```
45
-
46
- ### `setQValue(state, action, value)`
47
- Set Q-value and persist to storage.
48
-
49
- ```typescript
50
- await qlearning.setQValue('state1', 0, 0.5);
51
- ```
52
-
53
- ### `act(state, actionSize)`
54
- Select action using epsilon-greedy policy.
55
-
56
- ```typescript
57
- const action = await qlearning.act('state1', 3);
58
- // Returns: number (0 to actionSize-1)
59
- ```
60
-
61
- **Behavior:**
62
- - With probability `epsilon`: random action
63
- - With probability `1-epsilon`: best known action (ties broken randomly)
64
-
65
- ### `learn(state, action, reward, nextState, nextActionSize)`
66
- Full TD update: Q(s,a) ← Q(s,a) + α[r + γ·maxₐ' Q(s',a') - Q(s,a)]
67
-
68
- ```typescript
69
- const newQ = await qlearning.learn('state1', 0, 1, 'state2', 3);
70
- // Returns: updated Q-value
71
- ```
72
-
73
- ### `learnSimple(state, action, reward)`
74
- Simplified update for terminal states: Q(s,a) ← Q(s,a) + α[r - Q(s,a)]
75
-
76
- ```typescript
77
- const newQ = await qlearning.learnSimple('state1', 0, 1);
78
- // Returns: updated Q-value
79
- ```
80
-
81
- ### `reset()`
82
- Clear in-memory Q-table cache.
83
-
84
- ```typescript
85
- await qlearning.reset();
86
- // Note: Does not clear storage
87
- ```
88
-
89
- ### `getStateValues(state, actionSize)`
90
- Get all Q-values for a state.
91
-
92
- ```typescript
93
- const values = qlearning.getStateValues('state1', 3);
94
- // Returns: { 0: 0.5, 1: 0.2, 2: -0.1 }
95
- ```
96
-
97
- ### `getFullQTable()`
98
- Get entire Q-table for inspection.
99
-
100
- ```typescript
101
- const table = await qlearning.getFullQTable();
102
- // Returns:
103
- [
104
- { state: 'state1', action: 0, q_value: 0.5 },
105
- { state: 'state1', action: 1, q_value: 0.2 },
106
- ...
107
- ]
108
- ```
109
-
110
- ## Hyperparameters
111
-
112
- | Parameter | Default | Range | Description |
113
- |-----------|---------|-------|-------------|
114
- | `alpha` | 0.1 | [0, 1] | Learning rate — how much new info overrides old |
115
- | `gamma` | 0.9 | [0, 1] | Discount factor — future reward importance |
116
- | `epsilon` | 0.1 | [0, 1] | Exploration rate — random action probability |
117
-
118
- ## Example
119
-
120
- ```typescript
121
- import { QLearning, createStorage } from 'lsji';
122
-
123
- const storage = await createStorage('memory');
124
- const ql = new QLearning({ alpha: 0.1, gamma: 0.9, epsilon: 0.1, storage });
125
-
126
- await ql.initialize();
127
-
128
- // Train on simple state-action pairs
129
- await ql.learnSimple('state1', 0, 1); // Win
130
- await ql.learnSimple('state1', 0, 1); // Win again
131
- await ql.learnSimple('state1', 1, -1); // Lose
132
-
133
- // Check learned values
134
- console.log(ql.getQValue('state1', 0)); // ~0.19
135
- console.log(ql.getQValue('state1', 1)); // ~-0.1
136
-
137
- await storage.close();
138
- ```
@@ -1,168 +0,0 @@
1
- ---
2
- title: Storage API
3
- description: Pluggable storage backends
4
- ---
5
-
6
- # Storage API
7
-
8
- LSJI provides a pluggable storage abstraction with three built-in implementations.
9
-
10
- ## Import
11
-
12
- ```typescript
13
- import { createStorage, Storage, SqliteStorage, BetterSqliteStorage, MemoryStorage } from 'lsji';
14
- ```
15
-
16
- ## Factory Function
17
-
18
- ```typescript
19
- const storage = await createStorage(type, options);
20
- ```
21
-
22
- **Types:**
23
- - `'sqlite'` — Node.js built-in `node:sqlite` (recommended)
24
- - `'better-sqlite'` — `better-sqlite3` package
25
- - `'memory'` — In-memory (testing only)
26
-
27
- **Options:**
28
- ```typescript
29
- // SQLite
30
- { path: './my-agent.db' }
31
-
32
- // Better-SQLite
33
- { path: './my-agent.db' }
34
-
35
- // Memory
36
- {} // No options needed
37
- ```
38
-
39
- ## Storage Interface
40
-
41
- All backends implement this interface:
42
-
43
- ```typescript
44
- interface Storage {
45
- initialize(): Promise<void>;
46
- close(): Promise<void>;
47
- getSetting(key: string): Promise<{key: string, value: string} | null>;
48
- setSetting(key: string, value: string | number): Promise<void>;
49
- getQTable(): Promise<Array<{state: string, action: number, q_value: number}>>;
50
- updateQ(state: string, action: number, qValue: number): Promise<void>;
51
- addBattle(record: BattleRecord): Promise<void>;
52
- getTodayBattleCount(): Promise<number>;
53
- getPerformanceStats(): Promise<Array<{mode: string, total: number, win_rate: number}>>;
54
- }
55
-
56
- interface BattleRecord {
57
- mode: 'train' | 'test';
58
- handA: number;
59
- handB: number;
60
- reward: number;
61
- createdAt: string; // ISO timestamp
62
- }
63
- ```
64
-
65
- ## Backends
66
-
67
- ### SqliteStorage (Recommended)
68
-
69
- Uses Node.js 22+ built-in `node:sqlite` — **zero dependencies**.
70
-
71
- ```typescript
72
- import { SqliteStorage } from 'lsji';
73
-
74
- const storage = new SqliteStorage('./agent.db');
75
- await storage.initialize();
76
- // ... use storage
77
- await storage.close();
78
- ```
79
-
80
- **Features:**
81
- - Synchronous API (fast)
82
- - Automatic schema creation
83
- - Indexes on battle_history for performance
84
- - Persistent across process restarts
85
-
86
- ### BetterSqliteStorage
87
-
88
- Uses `better-sqlite3` for high-performance synchronous access.
89
-
90
- ```typescript
91
- import { BetterSqliteStorage } from 'lsji';
92
-
93
- const storage = new BetterSqliteStorage('./agent.db');
94
- await storage.initialize();
95
- ```
96
-
97
- **Requires:** `npm install better-sqlite3`
98
-
99
- **Use when:** You need faster writes or advanced SQLite features.
100
-
101
- ### MemoryStorage
102
-
103
- Pure in-memory implementation.
104
-
105
- ```typescript
106
- import { MemoryStorage } from 'lsji';
107
-
108
- const storage = new MemoryStorage();
109
- await storage.initialize();
110
- ```
111
-
112
- **Features:**
113
- - No persistence (data lost on exit)
114
- - Fastest for testing/CI
115
- - Implements `clear()` for test isolation
116
-
117
- ## Database Schema
118
-
119
- All SQL backends create these tables:
120
-
121
- ```sql
122
- -- Settings (key-value)
123
- CREATE TABLE settings (
124
- key TEXT PRIMARY KEY,
125
- value TEXT NOT NULL
126
- );
127
-
128
- -- Battle history
129
- CREATE TABLE battle_history (
130
- id INTEGER PRIMARY KEY AUTOINCREMENT,
131
- mode TEXT NOT NULL CHECK (mode IN ('train', 'test')),
132
- hand_a INTEGER NOT NULL,
133
- hand_b INTEGER NOT NULL,
134
- reward INTEGER NOT NULL,
135
- created_at TEXT NOT NULL
136
- );
137
-
138
- -- Q-table
139
- CREATE TABLE q_table (
140
- state TEXT NOT NULL,
141
- action INTEGER NOT NULL,
142
- q_value REAL NOT NULL DEFAULT 0,
143
- PRIMARY KEY (state, action)
144
- );
145
-
146
- -- Indexes
147
- CREATE INDEX idx_battle_history_date ON battle_history(created_at);
148
- CREATE INDEX idx_battle_history_mode ON battle_history(mode);
149
- ```
150
-
151
- ## Example
152
-
153
- ```typescript
154
- import { createStorage, QLearning, Agent, RockPaperScissorsEnv } from 'lsji';
155
-
156
- // Production: persistent SQLite
157
- const storage = await createStorage('sqlite', { path: './production.db' });
158
-
159
- // Testing: in-memory
160
- const testStorage = await createStorage('memory');
161
-
162
- const qlearning = new QLearning({ alpha: 0.1, gamma: 0.9, epsilon: 0.1, storage });
163
- const env = new RockPaperScissorsEnv({ opponent: 'random' });
164
- const agent = new Agent({ qlearning, storage, env });
165
-
166
- await agent.train({ episodes: 1000 });
167
- await storage.close();
168
- ```
@@ -1,155 +0,0 @@
1
- ---
2
- title: Architecture
3
- description: Design decisions and internals
4
- ---
5
-
6
- # Architecture
7
-
8
- ## Design Principles
9
-
10
- 1. **Single Package** — All core functionality in one npm package
11
- 2. **Zero Dependencies** — Core runs on Node.js 22+ built-ins only
12
- 3. **Storage Abstraction** — Easy to swap backends
13
- 4. **ESM Only** — Modern JavaScript modules
14
- 5. **Apache 2.0** — License compatible with Apache Incubator
15
-
16
- ## Project Structure
17
-
18
- ```
19
- src/
20
- ├── core/
21
- │ ├── env.ts # Environment interface
22
- │ ├── qlearning.ts # Q-Learning engine
23
- │ └── agent.ts # Agent orchestration
24
- ├── storage/
25
- │ ├── index.ts # Storage interface + factory
26
- │ ├── sqlite.ts # node:sqlite implementation
27
- │ ├── better-sqlite.ts # better-sqlite3 implementation
28
- │ └── memory.ts # In-memory implementation
29
- ├── envs/
30
- │ └── rps.ts # Rock-Paper-Scissors environment
31
- ├── cli.ts # Command-line interface
32
- └── index.ts # Public API exports
33
- ```
34
-
35
- ## Core Components
36
-
37
- ### Q-Learning Engine
38
-
39
- **Algorithm:** Tabular Q-Learning with Temporal Difference updates
40
-
41
- **Update Rules:**
42
- - Full TD: `Q(s,a) ← Q(s,a) + α[r + γ·maxₐ' Q(s',a') - Q(s,a)]`
43
- - Simple: `Q(s,a) ← Q(s,a) + α[r - Q(s,a)]` (terminal states)
44
-
45
- **Exploration:** Epsilon-greedy with configurable ε
46
-
47
- **State Representation:** String keys for Q-table indexing
48
-
49
- ### Storage Layer
50
-
51
- **Interface:** Abstract `Storage` class with 9 required methods
52
-
53
- **Implementations:**
54
- 1. `SqliteStorage` — Node.js built-in `node:sqlite` (sync API)
55
- 2. `BetterSqliteStorage` — `better-sqlite3` (faster, more features)
56
- 3. `MemoryStorage` — Pure JS Maps/Arrays (testing)
57
-
58
- **Schema:**
59
- - `settings` — Key-value configuration
60
- - `battle_history` — Training/play records with timestamps
61
- - `q_table` — State-action values with composite primary key
62
-
63
- **Indexes:** Date and mode indexes on battle_history for fast queries
64
-
65
- ### Agent Orchestration
66
-
67
- **Responsibilities:**
68
- - System lifecycle (start/stop)
69
- - Training loop with batching
70
- - Play/evaluation loop
71
- - Statistics aggregation
72
-
73
- **Training Loop:**
74
- ```
75
- for episode in episodes:
76
- state = env.getState()
77
- action = qlearning.act(state, actionSize) // ε-greedy
78
- result = env.step(action)
79
- qlearning.learnSimple(state, action, result.reward)
80
- storage.addBattle(record)
81
- batch.flush()
82
- ```
83
-
84
- ### Environment Interface
85
-
86
- **Contract:**
87
- ```typescript
88
- abstract class Env {
89
- abstract getState(): string;
90
- abstract step(action: number): Promise<StepResult>;
91
- abstract actionSize(): number;
92
- abstract reset(): Promise<string>;
93
- render(): string; // Optional
94
- }
95
- ```
96
-
97
- **Built-in:** `RockPaperScissorsEnv` with 4 opponent strategies
98
-
99
- ## Data Flow
100
-
101
- ```
102
- ┌─────────┐ ┌──────────────┐ ┌─────────┐
103
- │ Env │────▶│ Agent │────▶│ Storage │
104
- │ (State) │ │ Orchestrates│ │(Persist)│
105
- └─────────┘ └──────┬───────┘ └─────────┘
106
-
107
-
108
- ┌──────────────┐
109
- │ QLearning │
110
- │ (Updates) │
111
- └──────────────┘
112
- ```
113
-
114
- ## Concurrency Model
115
-
116
- - **Single-threaded** Node.js event loop
117
- - **Synchronous SQLite** — No async/await for DB operations
118
- - **Batch writes** — Reduce I/O overhead
119
- - **In-memory Q-table cache** — Fast reads, periodic persistence
120
-
121
- ## Migration from Cloudflare Workers
122
-
123
- **Original:** Worker.js with D1 database, cron triggers, HTTP endpoints
124
-
125
- **Changes:**
126
- | Before | After |
127
- |--------|-------|
128
- | `env.DB` (D1) | `Storage` abstraction |
129
- | Cron triggers | Manual/CLI training |
130
- | HTTP endpoints | Library API + CLI |
131
- | Global state | Instance-based |
132
- | `Request/Response` | Function parameters |
133
-
134
- **Preserved:**
135
- - Q-Learning algorithm (α=0.1, γ=0.9, ε=0.1)
136
- - Reward calculation: `(ai - user + 3) % 3`
137
- - Training patterns (0-3)
138
- - Battle history schema
139
-
140
- ## Performance Characteristics
141
-
142
- | Operation | Complexity | Notes |
143
- |-----------|------------|-------|
144
- | `act()` | O(actions) | Scans all actions for max Q |
145
- | `learnSimple()` | O(1) | Single Q-value update |
146
- | `learn()` | O(actions) | Finds max next Q |
147
- | `getFullQTable()` | O(states×actions) | Full table scan |
148
- | Batch insert | O(batch) | Single transaction |
149
-
150
- ## Future Extensibility
151
-
152
- - **New algorithms:** Extend `QLearning` or add `SARSA`, `DQN` classes
153
- - **New environments:** Implement `Env` interface
154
- - **New storage:** Implement `Storage` interface
155
- - **Function approximation:** Replace tabular Q-table with neural networks
package/docs/docs/cli.md DELETED
@@ -1,210 +0,0 @@
1
- ---
2
- title: CLI Reference
3
- description: Command-line interface for training and playing
4
- ---
5
-
6
- # CLI Reference
7
-
8
- LSJI includes a command-line interface for training and playing without writing code.
9
-
10
- ## Installation
11
-
12
- ```bash
13
- # Global install
14
- npm install -g lsji
15
-
16
- # Or use npx
17
- npx lsji --help
18
- ```
19
-
20
- ## Commands
21
-
22
- ### `lsji train`
23
-
24
- Train the agent.
25
-
26
- ```bash
27
- lsji train [options]
28
- ```
29
-
30
- **Options:**
31
-
32
- | Option | Description | Default |
33
- |--------|-------------|---------|
34
- | `--episodes <n>` | Number of training episodes | 200 |
35
- | `--pattern <0-3>` | Training pattern | 0 |
36
- | `--batch-size <n>` | Database batch size | 200 |
37
- | `--opponent <type>` | Opponent strategy | random |
38
- | `--storage <type>` | Storage backend | sqlite |
39
- | `--db-path <path>` | Database file path | ./lsji.db |
40
- | `--alpha <n>` | Learning rate | 0.1 |
41
- | `--gamma <n>` | Discount factor | 0.9 |
42
- | `--epsilon <n>` | Exploration rate | 0.1 |
43
- | `--json` | Output as JSON | false |
44
-
45
- **Training Patterns:**
46
- - `0` — Random actions
47
- - `1` — Always Rock
48
- - `2` — Counter previous action
49
- - `3` — Sequential (0,1,2,0,1,2...)
50
-
51
- **Opponent Strategies:**
52
- - `random` — Random actions
53
- - `always_rock` — Always plays Rock
54
- - `counter` — Counters agent's previous action
55
- - `sequential` — Cycles through actions
56
-
57
- **Examples:**
58
- ```bash
59
- # Default training
60
- lsji train --episodes 500
61
-
62
- # Train against always-rock opponent
63
- lsji train --episodes 100 --pattern 1 --opponent always_rock
64
-
65
- # Train with custom hyperparameters
66
- lsji train --episodes 1000 --alpha 0.05 --gamma 0.95 --epsilon 0.2
67
-
68
- # Use memory storage (ephemeral)
69
- lsji train --episodes 100 --storage memory
70
- ```
71
-
72
- ### `lsji play`
73
-
74
- Play a single game against the agent.
75
-
76
- ```bash
77
- lsji play --hand <0|1|2> [options]
78
- ```
79
-
80
- **Options:**
81
-
82
- | Option | Description |
83
- |--------|-------------|
84
- | `--hand <0\|1\|2>` | Your hand: 0=Rock, 1=Scissors, 2=Paper |
85
- | `--opponent <type>` | Opponent strategy |
86
- | `--storage <type>` | Storage backend |
87
- | `--db-path <path>` | Database file path |
88
- | `--json` | Output as JSON |
89
-
90
- **Examples:**
91
- ```bash
92
- lsji play --hand 0 # Play Rock
93
- lsji play --hand 1 # Play Scissors
94
- lsji play --hand 2 --json # Play Paper, JSON output
95
- ```
96
-
97
- ### `lsji status`
98
-
99
- Show system status and statistics.
100
-
101
- ```bash
102
- lsji status [options]
103
- ```
104
-
105
- **Options:**
106
-
107
- | Option | Description |
108
- |--------|-------------|
109
- | `--storage <type>` | Storage backend |
110
- | `--db-path <path>` | Database file path |
111
- | `--json` | Output as JSON |
112
-
113
- **Example:**
114
- ```bash
115
- lsji status --json
116
- ```
117
-
118
- Output:
119
- ```json
120
- {
121
- "status": "running",
122
- "todayTotal": 42,
123
- "limit": 90000,
124
- "performance": [
125
- { "mode": "train", "total": 1000, "win_rate": 65.5 },
126
- { "mode": "test", "total": 50, "win_rate": 72.0 }
127
- ],
128
- "aiBrain": [
129
- { "state": "0", "action": 0, "q_value": 0.45 },
130
- { "state": "0", "action": 1, "q_value": 0.12 }
131
- ]
132
- }
133
- ```
134
-
135
- ### `lsji start`
136
-
137
- Enable training and play.
138
-
139
- ```bash
140
- lsji start [options]
141
- ```
142
-
143
- ### `lsji stop`
144
-
145
- Disable training and play (system paused).
146
-
147
- ```bash
148
- lsji stop [options]
149
- ```
150
-
151
- ### `lsji help`
152
-
153
- Show help message.
154
-
155
- ```bash
156
- lsji help
157
- lsji --help
158
- lsji -h
159
- ```
160
-
161
- ## Environment Variables
162
-
163
- | Variable | Description | Default |
164
- |----------|-------------|---------|
165
- | `LSJI_STORAGE` | Default storage backend | sqlite |
166
- | `LSJI_DB_PATH` | Default database path | ./lsji.db |
167
-
168
- ## Examples
169
-
170
- ### Full Training Session
171
-
172
- ```bash
173
- # Start fresh
174
- rm -f lsji.db
175
-
176
- # Train against random opponent
177
- lsji train --episodes 500 --opponent random
178
-
179
- # Train against counter opponent
180
- lsji train --episodes 500 --opponent counter
181
-
182
- # Check progress
183
- lsji status --json
184
-
185
- # Play a few games
186
- lsji play --hand 0
187
- lsji play --hand 1
188
- lsji play --hand 2
189
- ```
190
-
191
- ### Using Memory Storage (CI/Testing)
192
-
193
- ```bash
194
- lsji train --episodes 100 --storage memory
195
- lsji play --hand 0 --storage memory
196
- lsji status --storage memory
197
- ```
198
-
199
- ### Custom Hyperparameters
200
-
201
- ```bash
202
- lsji train \
203
- --episodes 2000 \
204
- --alpha 0.05 \
205
- --gamma 0.95 \
206
- --epsilon 0.2 \
207
- --opponent random \
208
- --storage sqlite \
209
- --db-path ./custom.db
210
- ```