@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.
- package/package.json +4 -1
- package/docs/README.md +0 -43
- package/docs/blog/2019-05-28-first-blog-post.mdx +0 -12
- package/docs/blog/2019-05-29-long-blog-post.mdx +0 -44
- package/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -24
- package/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
- package/docs/blog/2021-08-26-welcome/index.mdx +0 -29
- package/docs/blog/authors.yml +0 -25
- package/docs/blog/tags.yml +0 -19
- package/docs/docs/api/agent.md +0 -151
- package/docs/docs/api/env.md +0 -133
- package/docs/docs/api/environments.md +0 -102
- package/docs/docs/api/qlearning.md +0 -138
- package/docs/docs/api/storage.md +0 -168
- package/docs/docs/architecture.md +0 -155
- package/docs/docs/cli.md +0 -210
- package/docs/docs/contributing.md +0 -162
- package/docs/docs/core-concepts.md +0 -152
- package/docs/docs/examples/advanced-training.md +0 -244
- package/docs/docs/examples/custom-environment.md +0 -198
- package/docs/docs/examples/custom-storage.md +0 -251
- package/docs/docs/getting-started.md +0 -91
- package/docs/docusaurus.config.ts +0 -149
- package/docs/package-lock.json +0 -19522
- package/docs/package.json +0 -49
- package/docs/sidebars.ts +0 -33
- package/docs/src/components/HomepageFeatures/index.tsx +0 -71
- package/docs/src/components/HomepageFeatures/styles.module.css +0 -11
- package/docs/src/css/custom.css +0 -79
- package/docs/src/pages/index.module.css +0 -23
- package/docs/src/pages/index.tsx +0 -44
- package/docs/src/pages/markdown-page.mdx +0 -7
- package/docs/static/.nojekyll +0 -0
- package/docs/static/img/docusaurus-social-card.jpg +0 -0
- package/docs/static/img/docusaurus.png +0 -0
- package/docs/static/img/favicon.ico +0 -0
- package/docs/static/img/logo.png +0 -0
- package/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
- package/docs/static/img/undraw_docusaurus_react.svg +0 -170
- package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
- package/docs/tsconfig.json +0 -12
- package/legacy/worker.js +0 -166
- 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
|
-
```
|
package/docs/docs/api/storage.md
DELETED
|
@@ -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
|
-
```
|