@game_ryo/lsji 0.1.0 → 0.3.0

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 (75) hide show
  1. package/package.json +15 -7
  2. package/src/cli.js +395 -62
  3. package/src/execution/budget/circuit-breaker.js +245 -0
  4. package/src/execution/budget/cost-tracker.js +387 -0
  5. package/src/execution/budget/index.js +63 -0
  6. package/src/execution/budget/token-counter.js +159 -0
  7. package/src/execution/engine.js +428 -0
  8. package/src/execution/hitl/approval-gate.js +210 -0
  9. package/src/execution/hitl/index.js +12 -0
  10. package/src/execution/hitl/notifier.js +151 -0
  11. package/src/execution/hitl/store.js +311 -0
  12. package/src/execution/idempotency.js +312 -0
  13. package/src/execution/index.js +14 -0
  14. package/src/index.js +80 -4
  15. package/src/llm/index.js +21 -0
  16. package/src/llm/llm-agent.js +357 -0
  17. package/src/llm/memory/conversation.js +271 -0
  18. package/src/llm/memory/episodic.js +312 -0
  19. package/src/llm/memory/index.js +12 -0
  20. package/src/llm/memory/semantic.js +324 -0
  21. package/src/llm/plugins/index.js +202 -0
  22. package/src/llm/prompt-manager.js +332 -0
  23. package/src/llm/providers/anthropic.js +250 -0
  24. package/src/llm/providers/base.js +116 -0
  25. package/src/llm/providers/local.js +163 -0
  26. package/src/llm/providers/openai.js +212 -0
  27. package/src/llm/tools/registry.js +342 -0
  28. package/src/server/index.js +416 -0
  29. package/src/server/ui/index.html +16 -0
  30. package/src/server/ui/package.json +19 -0
  31. package/src/server/ui/src/main.jsx +10 -0
  32. package/src/server/ui/src/styles.css +260 -0
  33. package/src/server/ui/vite.config.js +27 -0
  34. package/docs/README.md +0 -43
  35. package/docs/blog/2019-05-28-first-blog-post.mdx +0 -12
  36. package/docs/blog/2019-05-29-long-blog-post.mdx +0 -44
  37. package/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -24
  38. package/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  39. package/docs/blog/2021-08-26-welcome/index.mdx +0 -29
  40. package/docs/blog/authors.yml +0 -25
  41. package/docs/blog/tags.yml +0 -19
  42. package/docs/docs/api/agent.md +0 -151
  43. package/docs/docs/api/env.md +0 -133
  44. package/docs/docs/api/environments.md +0 -102
  45. package/docs/docs/api/qlearning.md +0 -138
  46. package/docs/docs/api/storage.md +0 -168
  47. package/docs/docs/architecture.md +0 -155
  48. package/docs/docs/cli.md +0 -210
  49. package/docs/docs/contributing.md +0 -162
  50. package/docs/docs/core-concepts.md +0 -152
  51. package/docs/docs/examples/advanced-training.md +0 -244
  52. package/docs/docs/examples/custom-environment.md +0 -198
  53. package/docs/docs/examples/custom-storage.md +0 -251
  54. package/docs/docs/getting-started.md +0 -91
  55. package/docs/docusaurus.config.ts +0 -149
  56. package/docs/package-lock.json +0 -19522
  57. package/docs/package.json +0 -49
  58. package/docs/sidebars.ts +0 -33
  59. package/docs/src/components/HomepageFeatures/index.tsx +0 -71
  60. package/docs/src/components/HomepageFeatures/styles.module.css +0 -11
  61. package/docs/src/css/custom.css +0 -79
  62. package/docs/src/pages/index.module.css +0 -23
  63. package/docs/src/pages/index.tsx +0 -44
  64. package/docs/src/pages/markdown-page.mdx +0 -7
  65. package/docs/static/.nojekyll +0 -0
  66. package/docs/static/img/docusaurus-social-card.jpg +0 -0
  67. package/docs/static/img/docusaurus.png +0 -0
  68. package/docs/static/img/favicon.ico +0 -0
  69. package/docs/static/img/logo.png +0 -0
  70. package/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
  71. package/docs/static/img/undraw_docusaurus_react.svg +0 -170
  72. package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
  73. package/docs/tsconfig.json +0 -12
  74. package/legacy/worker.js +0 -166
  75. package/legacy/wrangler.toml +0 -11
@@ -0,0 +1,260 @@
1
+ :root {
2
+ --bg-primary: #0d1117;
3
+ --bg-secondary: #161b22;
4
+ --bg-tertiary: #21262d;
5
+ --border: #30363d;
6
+ --text-primary: #e6edf3;
7
+ --text-secondary: #8b949e;
8
+ --accent: #58a6ff;
9
+ --accent-hover: #79c0ff;
10
+ --success: #3fb950;
11
+ --warning: #d29922;
12
+ --danger: #f85149;
13
+ --purple: #a371f7;
14
+ }
15
+
16
+ * { box-sizing: border-box; }
17
+
18
+ body { margin: 0; background: var(--bg-primary); color: var(--text-primary); font-size: 14px; line-height: 1.5; }
19
+
20
+ #root { min-height: 100vh; display: flex; flex-direction: column; }
21
+
22
+ .app { display: flex; flex-direction: column; min-height: 100vh; }
23
+
24
+ .header {
25
+ background: var(--bg-secondary);
26
+ border-bottom: 1px solid var(--border);
27
+ padding: 12px 24px;
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: space-between;
31
+ position: sticky;
32
+ top: 0;
33
+ z-index: 100;
34
+ }
35
+
36
+ .header-left { display: flex; align-items: center; gap: 16px; }
37
+ .logo { font-size: 18px; font-weight: 600; color: var(--accent); }
38
+ .version { font-size: 12px; color: var(--text-secondary); background: var(--bg-tertiary); padding: 2px 8px; border-radius: 4px; }
39
+
40
+ .header-right { display: flex; align-items: center; gap: 16px; }
41
+ .connection-status { display: flex; align-items: center; gap: 8px; font-size: 12px; }
42
+ .status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); }
43
+ .status-dot.disconnected { background: var(--danger); }
44
+
45
+ .main { display: flex; flex: 1; overflow: hidden; }
46
+
47
+ .sidebar {
48
+ width: 280px;
49
+ background: var(--bg-secondary);
50
+ border-right: 1px solid var(--border);
51
+ display: flex;
52
+ flex-direction: column;
53
+ overflow-y: auto;
54
+ }
55
+
56
+ .sidebar-section { padding: 16px; border-bottom: 1px solid var(--border); }
57
+ .sidebar-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-secondary); margin-bottom: 12px; font-weight: 600; }
58
+
59
+ .run-list { display: flex; flex-direction: column; gap: 8px; }
60
+ .run-item {
61
+ background: var(--bg-tertiary);
62
+ border: 1px solid var(--border);
63
+ border-radius: 6px;
64
+ padding: 12px;
65
+ cursor: pointer;
66
+ transition: all 0.15s;
67
+ }
68
+ .run-item:hover { border-color: var(--accent); }
69
+ .run-item.active { border-color: var(--accent); background: rgba(88, 166, 255, 0.1); }
70
+ .run-item-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px; }
71
+ .run-id { font-family: monospace; font-size: 12px; color: var(--accent); }
72
+ .run-status { font-size: 11px; padding: 2px 8px; border-radius: 12px; font-weight: 500; }
73
+ .run-status.running { background: rgba(88, 166, 255, 0.2); color: var(--accent); }
74
+ .run-status.completed { background: rgba(63, 185, 80, 0.2); color: var(--success); }
75
+ .run-status.failed { background: rgba(248, 81, 73, 0.2); color: var(--danger); }
76
+ .run-status.stopped { background: rgba(210, 153, 34, 0.2); color: var(--warning); }
77
+ .run-task { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
78
+ .run-meta { font-size: 11px; color: var(--text-secondary); margin-top: 8px; display: flex; gap: 16px; }
79
+
80
+ .content { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
81
+
82
+ .content-header {
83
+ background: var(--bg-secondary);
84
+ border-bottom: 1px solid var(--border);
85
+ padding: 16px 24px;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: space-between;
89
+ }
90
+
91
+ .content-title { font-size: 16px; font-weight: 600; }
92
+ .content-actions { display: flex; gap: 8px; }
93
+
94
+ .btn {
95
+ padding: 8px 16px;
96
+ border-radius: 6px;
97
+ border: 1px solid var(--border);
98
+ background: var(--bg-tertiary);
99
+ color: var(--text-primary);
100
+ font-size: 13px;
101
+ cursor: pointer;
102
+ transition: all 0.15s;
103
+ display: inline-flex;
104
+ align-items: center;
105
+ gap: 6px;
106
+ }
107
+ .btn:hover { background: var(--border); }
108
+ .btn.primary { background: var(--accent); border-color: var(--accent); color: #0d1117; }
109
+ .btn.primary:hover { background: var(--accent-hover); }
110
+ .btn.danger { background: var(--danger); border-color: var(--danger); color: white; }
111
+ .btn.success { background: var(--success); border-color: var(--success); color: white; }
112
+ .btn:disabled { opacity: 0.5; cursor: not-allowed; }
113
+
114
+ .panels { display: flex; flex: 1; overflow: hidden; }
115
+
116
+ .panel {
117
+ flex: 1;
118
+ display: flex;
119
+ flex-direction: column;
120
+ min-width: 0;
121
+ }
122
+
123
+ .panel-header {
124
+ padding: 12px 16px;
125
+ background: var(--bg-secondary);
126
+ border-bottom: 1px solid var(--border);
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: space-between;
130
+ }
131
+
132
+ .panel-title { font-size: 13px; font-weight: 600; }
133
+ .panel-content { flex: 1; overflow-y: auto; padding: 16px; }
134
+
135
+ /* Thought Log */
136
+ .thought-log { display: flex; flex-direction: column; gap: 8px; }
137
+ .thought-entry {
138
+ background: var(--bg-tertiary);
139
+ border: 1px solid var(--border);
140
+ border-radius: 6px;
141
+ padding: 12px;
142
+ animation: slideIn 0.2s ease;
143
+ }
144
+ @keyframes slideIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
145
+ .thought-header { display: flex; justify-content: space-between; margin-bottom: 8px; font-size: 11px; color: var(--text-secondary); }
146
+ .thought-type { font-weight: 600; text-transform: uppercase; }
147
+ .thought-type.thought { color: var(--purple); }
148
+ .thought-type.action { color: var(--accent); }
149
+ .thought-type.observation { color: var(--success); }
150
+ .thought-type.error { color: var(--danger); }
151
+ .thought-content { font-family: monospace; font-size: 12px; white-space: pre-wrap; word-break: break-word; }
152
+ .thought-tool { background: rgba(88, 166, 255, 0.1); padding: 8px; border-radius: 4px; margin-top: 8px; font-size: 11px; }
153
+
154
+ /* Approval Queue */
155
+ .approval-list { display: flex; flex-direction: column; gap: 12px; }
156
+ .approval-card {
157
+ background: var(--bg-tertiary);
158
+ border: 1px solid var(--border);
159
+ border-radius: 8px;
160
+ padding: 16px;
161
+ }
162
+ .approval-header { display: flex; justify-content: space-between; margin-bottom: 12px; }
163
+ .approval-action { font-weight: 600; color: var(--accent); font-family: monospace; font-size: 13px; }
164
+ .approval-badge { font-size: 11px; padding: 2px 8px; border-radius: 12px; font-weight: 500; }
165
+ .approval-badge.pending { background: rgba(210, 153, 34, 0.2); color: var(--warning); }
166
+ .approval-context { font-size: 12px; color: var(--text-secondary); margin-bottom: 12px; }
167
+ .approval-context pre { background: var(--bg-primary); padding: 8px; border-radius: 4px; overflow-x: auto; font-size: 11px; }
168
+ .approval-actions { display: flex; gap: 8px; justify-content: flex-end; }
169
+
170
+ /* Budget Panel */
171
+ .budget-overview { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 24px; }
172
+ .budget-card {
173
+ background: var(--bg-tertiary);
174
+ border: 1px solid var(--border);
175
+ border-radius: 8px;
176
+ padding: 16px;
177
+ }
178
+ .budget-card.warning { border-color: var(--warning); }
179
+ .budget-card.danger { border-color: var(--danger); }
180
+ .budget-label { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; margin-bottom: 4px; }
181
+ .budget-value { font-size: 24px; font-weight: 600; font-family: monospace; }
182
+ .budget-value.warning { color: var(--warning); }
183
+ .budget-value.danger { color: var(--danger); }
184
+ .budget-details { font-size: 11px; color: var(--text-secondary); margin-top: 8px; display: flex; justify-content: space-between; }
185
+
186
+ /* Plugins Panel */
187
+ .plugin-list { display: flex; flex-direction: column; gap: 8px; }
188
+ .plugin-card {
189
+ background: var(--bg-tertiary);
190
+ border: 1px solid var(--border);
191
+ border-radius: 6px;
192
+ padding: 12px;
193
+ display: flex;
194
+ justify-content: space-between;
195
+ align-items: center;
196
+ }
197
+ .plugin-info { display: flex; flex-direction: column; gap: 2px; }
198
+ .plugin-name { font-weight: 500; }
199
+ .plugin-version { font-size: 11px; color: var(--text-secondary); }
200
+ .plugin-tools { font-size: 11px; color: var(--accent); }
201
+
202
+ /* New Run Modal */
203
+ .modal-overlay {
204
+ position: fixed;
205
+ inset: 0;
206
+ background: rgba(0, 0, 0, 0.8);
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ z-index: 1000;
211
+ }
212
+ .modal {
213
+ background: var(--bg-secondary);
214
+ border: 1px solid var(--border);
215
+ border-radius: 12px;
216
+ padding: 24px;
217
+ width: 100%;
218
+ max-width: 500px;
219
+ max-height: 90vh;
220
+ overflow-y: auto;
221
+ }
222
+ .modal-title { font-size: 18px; font-weight: 600; margin-bottom: 20px; }
223
+ .form-group { margin-bottom: 16px; }
224
+ .form-label { display: block; font-size: 12px; font-weight: 500; margin-bottom: 6px; }
225
+ .form-input, .form-textarea, .form-select {
226
+ width: 100%;
227
+ padding: 10px 12px;
228
+ background: var(--bg-primary);
229
+ border: 1px solid var(--border);
230
+ border-radius: 6px;
231
+ color: var(--text-primary);
232
+ font-size: 13px;
233
+ font-family: inherit;
234
+ }
235
+ .form-input:focus, .form-textarea:focus, .form-select:focus {
236
+ outline: none;
237
+ border-color: var(--accent);
238
+ }
239
+ .form-textarea { min-height: 100px; resize: vertical; font-family: monospace; }
240
+ .form-row { display: flex; gap: 12px; }
241
+ .form-row .form-group { flex: 1; }
242
+ .modal-actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 24px; }
243
+
244
+ .empty-state {
245
+ display: flex;
246
+ flex-direction: column;
247
+ align-items: center;
248
+ justify-content: center;
249
+ height: 100%;
250
+ color: var(--text-secondary);
251
+ text-align: center;
252
+ gap: 12px;
253
+ }
254
+ .empty-state svg { width: 48px; height: 48px; opacity: 0.5; }
255
+
256
+ /* Scrollbar */
257
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
258
+ ::-webkit-scrollbar-track { background: var(--bg-primary); }
259
+ ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
260
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
@@ -0,0 +1,27 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import { resolve } from 'path';
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ root: '.',
8
+ build: {
9
+ outDir: 'dist',
10
+ emptyOutDir: true,
11
+ rollupOptions: {
12
+ input: {
13
+ main: resolve(__dirname, 'index.html'),
14
+ },
15
+ },
16
+ },
17
+ server: {
18
+ port: 5173,
19
+ proxy: {
20
+ '/api': 'http://localhost:3456',
21
+ '/socket.io': {
22
+ target: 'http://localhost:3456',
23
+ ws: true,
24
+ },
25
+ },
26
+ },
27
+ });
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
- ```