@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@game_ryo/lsji",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A general-purpose reinforcement learning agent framework (Node.js)",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -22,5 +22,8 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "vitest": "^2.0.0"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
25
28
  }
26
29
  }
package/docs/README.md DELETED
@@ -1,43 +0,0 @@
1
- # Website
2
-
3
- This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install
9
- ```
10
-
11
- **Note**: feel free to use the package manager of your choice.
12
-
13
- ## Local Development
14
-
15
- ```bash
16
- npm run start
17
- ```
18
-
19
- This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
20
-
21
- ## Build
22
-
23
- ```bash
24
- npm run build
25
- ```
26
-
27
- This command generates static content into the `build` directory and can be served using any static contents hosting service.
28
-
29
- ## Deployment
30
-
31
- Using SSH:
32
-
33
- ```bash
34
- USE_SSH=true npm run deploy
35
- ```
36
-
37
- Not using SSH:
38
-
39
- ```bash
40
- GIT_USER=<Your GitHub username> npm run deploy
41
- ```
42
-
43
- If you are using GitHub Pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
@@ -1,12 +0,0 @@
1
- ---
2
- slug: first-blog-post
3
- title: First Blog Post
4
- authors: [slorber, yangshun]
5
- tags: [hola, docusaurus]
6
- ---
7
-
8
- Lorem ipsum dolor sit amet...
9
-
10
- {/* truncate */}
11
-
12
- ...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
@@ -1,44 +0,0 @@
1
- ---
2
- slug: long-blog-post
3
- title: Long Blog Post
4
- authors: yangshun
5
- tags: [hello, docusaurus]
6
- ---
7
-
8
- This is the summary of a very long blog post,
9
-
10
- Use a `{/*` `truncate` `*/}` comment to limit blog post size in the list view.
11
-
12
- {/* truncate */}
13
-
14
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
15
-
16
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
17
-
18
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
19
-
20
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
21
-
22
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
23
-
24
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
25
-
26
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
27
-
28
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
29
-
30
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
31
-
32
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
33
-
34
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
35
-
36
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
37
-
38
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
39
-
40
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
41
-
42
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
43
-
44
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
@@ -1,24 +0,0 @@
1
- ---
2
- slug: mdx-blog-post
3
- title: MDX Blog Post
4
- authors: [slorber]
5
- tags: [docusaurus]
6
- ---
7
-
8
- Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/).
9
-
10
- :::tip
11
-
12
- Use the power of React to create interactive blog posts.
13
-
14
- :::
15
-
16
- {/* truncate */}
17
-
18
- For example, use JSX to create an interactive button:
19
-
20
- ```js
21
- <button onClick={() => alert('button clicked!')}>Click me!</button>
22
- ```
23
-
24
- <button onClick={() => alert('button clicked!')}>Click me!</button>
@@ -1,29 +0,0 @@
1
- ---
2
- slug: welcome
3
- title: Welcome
4
- authors: [slorber, yangshun]
5
- tags: [facebook, hello, docusaurus]
6
- ---
7
-
8
- [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog).
9
-
10
- Here are a few tips you might find useful.
11
-
12
- {/* truncate */}
13
-
14
- Simply add Markdown files (or folders) to the `blog` directory.
15
-
16
- Regular blog authors can be added to `authors.yml`.
17
-
18
- The blog post date can be extracted from filenames, such as:
19
-
20
- - `2019-05-30-welcome.md`
21
- - `2019-05-30-welcome/index.md`
22
-
23
- A blog post folder can be convenient to co-locate blog post images:
24
-
25
- ![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg)
26
-
27
- The blog supports tags as well!
28
-
29
- **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config.
@@ -1,25 +0,0 @@
1
- yangshun:
2
- name: Yangshun Tay
3
- title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd
4
- url: https://linkedin.com/in/yangshun
5
- image_url: https://github.com/yangshun.png
6
- page: true
7
- socials:
8
- x: yangshunz
9
- linkedin: yangshun
10
- github: yangshun
11
- newsletter: https://www.greatfrontend.com
12
-
13
- slorber:
14
- name: Sébastien Lorber
15
- title: Docusaurus maintainer
16
- url: https://sebastienlorber.com
17
- image_url: https://github.com/slorber.png
18
- page:
19
- # customize the url of the author page at /blog/authors/<permalink>
20
- permalink: '/all-sebastien-lorber-articles'
21
- socials:
22
- x: sebastienlorber
23
- linkedin: sebastienlorber
24
- github: slorber
25
- newsletter: https://thisweekinreact.com
@@ -1,19 +0,0 @@
1
- facebook:
2
- label: Facebook
3
- permalink: /facebook
4
- description: Facebook tag description
5
-
6
- hello:
7
- label: Hello
8
- permalink: /hello
9
- description: Hello tag description
10
-
11
- docusaurus:
12
- label: Docusaurus
13
- permalink: /docusaurus
14
- description: Docusaurus tag description
15
-
16
- hola:
17
- label: Hola
18
- permalink: /hola
19
- description: Hola tag description
@@ -1,151 +0,0 @@
1
- ---
2
- title: Agent API
3
- description: High-level agent orchestration
4
- ---
5
-
6
- # Agent API
7
-
8
- The `Agent` class provides high-level orchestration of Q-Learning, Storage, and Environment.
9
-
10
- ## Import
11
-
12
- ```typescript
13
- import { Agent } from 'lsji';
14
- ```
15
-
16
- ## Constructor
17
-
18
- ```typescript
19
- const agent = new Agent({
20
- qlearning: QLearning, // Required: Q-Learning engine
21
- storage: Storage, // Required: Storage backend
22
- env: Env // Optional: Environment for train/play
23
- });
24
- ```
25
-
26
- ## Methods
27
-
28
- ### `start()`
29
- Enable the system for training and play.
30
-
31
- ```typescript
32
- await agent.start();
33
- // Returns: { status: 'success', message: 'System STARTED' }
34
- ```
35
-
36
- ### `stop()`
37
- Disable the system (pauses training and play).
38
-
39
- ```typescript
40
- await agent.stop();
41
- // Returns: { status: 'success', message: 'System STOPPED' }
42
- ```
43
-
44
- ### `status()`
45
- Get current system status and statistics.
46
-
47
- ```typescript
48
- const status = await agent.status();
49
- // Returns:
50
- {
51
- status: 'running' | 'stopped',
52
- todayTotal: number, // Battles today
53
- limit: 90000, // Daily limit
54
- performance: [ // Per-mode statistics
55
- { mode: 'train', total: 100, win_rate: 65.5 },
56
- { mode: 'test', total: 50, win_rate: 72.0 }
57
- ],
58
- aiBrain: [ // Full Q-table
59
- { state: '0', action: 0, q_value: 0.45 },
60
- { state: '0', action: 1, q_value: 0.12 },
61
- ...
62
- ]
63
- }
64
- ```
65
-
66
- ### `train(options)`
67
- Train the agent.
68
-
69
- ```typescript
70
- const result = await agent.train({
71
- episodes: 200, // Number of episodes (default: 200)
72
- actionSelector: (episode, lastAction) => number, // Custom pattern (optional)
73
- batchSize: 200 // DB batch size (default: 200)
74
- });
75
-
76
- // Returns:
77
- {
78
- episodes: 200,
79
- wins: 85,
80
- losses: 62,
81
- draws: 53
82
- }
83
- ```
84
-
85
- **Built-in Training Patterns:**
86
- ```typescript
87
- import { TrainingPattern, getTrainingAction } from 'lsji';
88
-
89
- // Pattern 0: Random (default)
90
- await agent.train({ episodes: 500 });
91
-
92
- // Pattern 1: Always Rock
93
- await agent.train({
94
- episodes: 500,
95
- actionSelector: (ep, last) => getTrainingAction(TrainingPattern.ALWAYS_ROCK, ep, last)
96
- });
97
-
98
- // Pattern 2: Counter
99
- await agent.train({
100
- episodes: 500,
101
- actionSelector: (ep, last) => getTrainingAction(TrainingPattern.COUNTER, ep, last)
102
- });
103
-
104
- // Pattern 3: Sequential
105
- await agent.train({
106
- episodes: 500,
107
- actionSelector: (ep, last) => getTrainingAction(TrainingPattern.SEQUENTIAL, ep, last)
108
- });
109
- ```
110
-
111
- ### `play(options)`
112
- Play a single step against the agent.
113
-
114
- ```typescript
115
- const result = await agent.play({
116
- userAction: 0 // Optional: user action for envs that need it
117
- });
118
-
119
- // Returns:
120
- {
121
- action: 1, // Agent's chosen action
122
- reward: 1, // Reward received
123
- done: false, // Episode ended
124
- info: { opponentAction: 0 } // Environment-specific info
125
- }
126
- ```
127
-
128
- ### `setEnvironment(env)`
129
- Inject or change the environment at runtime.
130
-
131
- ```typescript
132
- agent.setEnvironment(new MyCustomEnv());
133
- ```
134
-
135
- ## Example
136
-
137
- ```typescript
138
- import { Agent, QLearning, createStorage, RockPaperScissorsEnv } from 'lsji';
139
-
140
- const storage = await createStorage('sqlite', { path: './agent.db' });
141
- const qlearning = new QLearning({ alpha: 0.1, gamma: 0.9, epsilon: 0.1, storage });
142
- const env = new RockPaperScissorsEnv({ opponent: 'random' });
143
-
144
- const agent = new Agent({ qlearning, storage, env });
145
-
146
- await agent.train({ episodes: 1000 });
147
- const result = await agent.play(0); // Play Rock
148
- console.log(`AI played: ${result.action}, Result: ${result.reward > 0 ? 'WIN' : result.reward < 0 ? 'LOSE' : 'DRAW'}`);
149
-
150
- await storage.close();
151
- ```
@@ -1,133 +0,0 @@
1
- ---
2
- title: Env Interface
3
- description: Base environment interface for RL problems
4
- ---
5
-
6
- # Env Interface
7
-
8
- All reinforcement learning environments must extend the abstract `Env` class.
9
-
10
- ## Import
11
-
12
- ```typescript
13
- import { Env } from 'lsji';
14
- ```
15
-
16
- ## Abstract Methods
17
-
18
- ### `getState()`
19
- Return current state as a string key.
20
-
21
- ```typescript
22
- getState(): string;
23
- ```
24
-
25
- ### `step(action)`
26
- Execute an action and return the result.
27
-
28
- ```typescript
29
- async step(action: number): Promise<StepResult>;
30
- ```
31
-
32
- **StepResult:**
33
- ```typescript
34
- interface StepResult {
35
- state: string; // New state
36
- reward: number; // Reward for this step
37
- done: boolean; // Episode ended
38
- info?: object; // Additional info
39
- }
40
- ```
41
-
42
- ### `actionSize()`
43
- Return number of possible actions.
44
-
45
- ```typescript
46
- actionSize(): number;
47
- ```
48
-
49
- ### `reset()`
50
- Reset environment to initial state.
51
-
52
- ```typescript
53
- async reset(): Promise<string>; // Returns initial state
54
- ```
55
-
56
- ## Optional Methods
57
-
58
- ### `render()`
59
- Human-readable representation for debugging.
60
-
61
- ```typescript
62
- render(): string;
63
- ```
64
-
65
- ## StateEncoder Utility
66
-
67
- Helper for encoding/decoding complex states:
68
-
69
- ```typescript
70
- import { StateEncoder } from 'lsji';
71
-
72
- // Encode object to string
73
- const key = StateEncoder.encode({ position: 5, inventory: ['sword'] });
74
- // Returns: '{"position":5,"inventory":["sword"]}'
75
-
76
- // Decode string to object
77
- const state = StateEncoder.decode(key);
78
- // Returns: { position: 5, inventory: ['sword'] }
79
- ```
80
-
81
- ## Creating a Custom Environment
82
-
83
- ```typescript
84
- import { Env } from 'lsji';
85
-
86
- class GridWorldEnv extends Env {
87
- constructor() {
88
- super();
89
- this.position = 0;
90
- this.gridSize = 10;
91
- }
92
-
93
- getState() {
94
- return String(this.position);
95
- }
96
-
97
- async step(action) {
98
- // Actions: 0=left, 1=right
99
- if (action === 0) this.position = Math.max(0, this.position - 1);
100
- if (action === 1) this.position = Math.min(this.gridSize - 1, this.position + 1);
101
-
102
- const done = this.position === this.gridSize - 1;
103
- const reward = done ? 1 : -0.01;
104
-
105
- return {
106
- state: String(this.position),
107
- reward,
108
- done,
109
- info: { position: this.position }
110
- };
111
- }
112
-
113
- actionSize() {
114
- return 2;
115
- }
116
-
117
- async reset() {
118
- this.position = 0;
119
- return '0';
120
- }
121
-
122
- render() {
123
- return `GridWorld: position ${this.position}/${this.gridSize - 1}`;
124
- }
125
- }
126
- ```
127
-
128
- ## Best Practices
129
-
130
- 1. **State as string** — Use simple string keys for Q-table indexing
131
- 2. **Deterministic rewards** — Same state-action should give consistent rewards
132
- 3. **Action space** — Keep action space small for tabular Q-learning
133
- 4. **Reset** — Always implement proper reset for episode boundaries
@@ -1,102 +0,0 @@
1
- ---
2
- title: Built-in Environments
3
- description: Pre-built environments for quick start
4
- ---
5
-
6
- # Built-in Environments
7
-
8
- LSJI includes a Rock-Paper-Scissors environment for demonstration and testing.
9
-
10
- ## Import
11
-
12
- ```typescript
13
- import {
14
- RockPaperScissorsEnv,
15
- TrainingPattern,
16
- getTrainingAction
17
- } from 'lsji';
18
- ```
19
-
20
- ## RockPaperScissorsEnv
21
-
22
- Classic Rock-Paper-Scissors game environment.
23
-
24
- ### Constructor
25
-
26
- ```typescript
27
- const env = new RockPaperScissorsEnv({
28
- opponent: 'random' // 'random' | 'always_rock' | 'counter' | 'sequential'
29
- });
30
- ```
31
-
32
- ### Opponent Strategies
33
-
34
- | Strategy | Description |
35
- |----------|-------------|
36
- | `'random'` | Uniform random actions (default) |
37
- | `'always_rock'` | Always plays Rock (0) |
38
- | `'counter'` | Plays counter to agent's previous action |
39
- | `'sequential'` | Cycles through Rock→Scissors→Paper |
40
-
41
- ### Methods
42
-
43
- All standard `Env` methods plus:
44
-
45
- ```typescript
46
- // Static helpers
47
- RockPaperScissorsEnv.getHandName(0); // 'Rock'
48
- RockPaperScissorsEnv.getHandName(1); // 'Scissors'
49
- RockPaperScissorsEnv.getHandName(2); // 'Paper'
50
-
51
- const { judge, reward, outcome } = RockPaperScissorsEnv.calculateOutcome(0, 2);
52
- // judge: 2, reward: 1, outcome: 'WIN'
53
- ```
54
-
55
- ### Training Patterns
56
-
57
- ```typescript
58
- import { TrainingPattern, getTrainingAction } from 'lsji';
59
-
60
- // Pattern IDs
61
- TrainingPattern.RANDOM; // 0
62
- TrainingPattern.ALWAYS_ROCK; // 1
63
- TrainingPattern.COUNTER; // 2
64
- TrainingPattern.SEQUENTIAL; // 3
65
-
66
- // Get action for pattern
67
- const action = getTrainingAction(TrainingPattern.COUNTER, episode, lastAction);
68
- ```
69
-
70
- ### Example
71
-
72
- ```typescript
73
- import {
74
- Agent, QLearning, createStorage,
75
- RockPaperScissorsEnv, TrainingPattern, getTrainingAction
76
- } from 'lsji';
77
-
78
- const storage = await createStorage('sqlite', { path: './rps.db' });
79
- const qlearning = new QLearning({ alpha: 0.1, gamma: 0.9, epsilon: 0.1, storage });
80
-
81
- // Train against counter opponent
82
- const env = new RockPaperScissorsEnv({ opponent: 'counter' });
83
- const agent = new Agent({ qlearning, storage, env });
84
-
85
- await agent.train({
86
- episodes: 1000,
87
- actionSelector: (ep, last) => getTrainingAction(TrainingPattern.RANDOM, ep, last)
88
- });
89
-
90
- // Play against random opponent
91
- const playEnv = new RockPaperScissorsEnv({ opponent: 'random' });
92
- agent.setEnvironment(playEnv);
93
-
94
- const result = await agent.play(0); // You play Rock
95
- console.log(`AI: ${RockPaperScissorsEnv.getHandName(result.action)} | ${result.reward > 0 ? 'WIN' : 'LOSE'}`);
96
-
97
- await storage.close();
98
- ```
99
-
100
- ## Creating Custom Environments
101
-
102
- See [Custom Environment Example](/docs/examples/custom-environment) for a complete guide.