loomeye-agent 0.2.0__tar.gz

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.
@@ -0,0 +1,403 @@
1
+ Metadata-Version: 2.4
2
+ Name: loomeye-agent
3
+ Version: 0.2.0
4
+ Summary: LoomEye HPC Agent — connect your cluster to LoomEye
5
+ License: MIT
6
+ Project-URL: Homepage, https://loomeye.com
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: websockets>=14.0
10
+
11
+ # LoomEye HPC Agent
12
+
13
+ The LoomEye HPC Agent is a lightweight Python command-line tool that runs on a
14
+ user's remote machine, workstation, or HPC cluster. It opens an outbound
15
+ WebSocket connection to LoomEye so the web app can browse approved files and,
16
+ when the user opts in, run generated Python code on that machine.
17
+
18
+ The agent does not require inbound ports, SSH access from LoomEye, or exposing
19
+ the full filesystem. It runs as the current OS user and can only access paths
20
+ that user can already access.
21
+
22
+ ## Quick Start
23
+
24
+ Install the current LoomEye agent release:
25
+
26
+ ```bash
27
+ python3 -m pip install --user loomeye-agent
28
+ python3 -m loomeye_agent --version
29
+ ```
30
+
31
+ On Windows, replace `python3` with `py`.
32
+
33
+ Get an agent token from the LoomEye web app:
34
+
35
+ ```text
36
+ Sidebar -> HPC Files -> Connect Cluster
37
+ ```
38
+
39
+ Then connect:
40
+
41
+ ```bash
42
+ python3 -m loomeye_agent connect --token <YOUR_TOKEN>
43
+ ```
44
+
45
+ The agent asks which directory LoomEye may access. Press Enter to expose the
46
+ current directory, or enter one or more paths:
47
+
48
+ ```text
49
+ Directory to expose [/home/warren/project]:
50
+ ```
51
+
52
+ You can also skip the prompt:
53
+
54
+ ```bash
55
+ python3 loomeye_agent.py connect \
56
+ --token <YOUR_TOKEN> \
57
+ --dirs /home/warren/project /scratch/my-job
58
+ ```
59
+
60
+ Keep the process running while you use LoomEye. For long sessions, run it inside
61
+ `tmux` or `screen`.
62
+
63
+ ## Commands
64
+
65
+ | Command | Purpose |
66
+ | --- | --- |
67
+ | `python3 loomeye_agent.py -h` | Show top-level help. |
68
+ | `python3 loomeye_agent.py connect --token <TOKEN>` | Connect to LoomEye prod. Prompts for directories if needed. |
69
+ | `python3 loomeye_agent.py connect --dev --token <TOKEN>` | Connect to the LoomEye dev backend. |
70
+ | `python3 loomeye_agent.py connect --config ~/.loomeye/agent.json` | Reuse saved connection settings. |
71
+ | `python3 loomeye_agent.py status` | Print saved config, with the token masked. |
72
+ | `python3 loomeye_agent.py doctor --dirs <DIR> --file <PATH>` | Check local sandbox and selected-file wiring. |
73
+ | `python3 loomeye_agent.py disconnect` | Delete the saved config file. |
74
+
75
+ ## Important Options
76
+
77
+ | Option | Applies To | Meaning |
78
+ | --- | --- | --- |
79
+ | `--token <TOKEN>` | `connect` | One-time token generated by the LoomEye web app. |
80
+ | `--dirs <PATHS...>` | `connect` | Directories LoomEye may browse/read. Optional in interactive terminals. |
81
+ | `--dev` | `connect` | Use the dev backend instead of prod. |
82
+ | `--env-dir <PATH>` | `connect` | Use a different managed Python environment directory. |
83
+ | `--selected-file <PATH>` | `doctor` | Validate a file as if it were selected in the LoomEye UI. Repeat for multiple files. |
84
+ | `--run-python` | `doctor` | Also run a tiny script that checks the generated-code prelude. |
85
+
86
+ `--allow-exec` and `--allow-install` still exist for automation/backward
87
+ compatibility, but they are hidden from help. Normal users choose those settings
88
+ through interactive prompts.
89
+
90
+ ## Prod And Dev
91
+
92
+ Prod is the default:
93
+
94
+ ```bash
95
+ python3 loomeye_agent.py connect --token <TOKEN>
96
+ ```
97
+
98
+ Dev is explicit:
99
+
100
+ ```bash
101
+ python3 -m loomeye_agent connect --dev --token <TOKEN>
102
+ ```
103
+
104
+ The backend URLs are built into the agent so users do not need to copy or edit
105
+ them:
106
+
107
+ ```text
108
+ prod: wss://math-solver-prod-696616516071.us-west1.run.app
109
+ dev: wss://math-solver-dev-696616516071.us-west1.run.app
110
+ ```
111
+
112
+ ## Directory Access
113
+
114
+ LoomEye only sees files inside the approved sandbox roots.
115
+
116
+ On first connect, if `--dirs` is omitted, the agent prompts for directories. The
117
+ prompt supports:
118
+
119
+ - pressing Enter to use the current directory
120
+ - one directory path
121
+ - multiple space-separated directory paths
122
+ - quoted paths that contain spaces
123
+
124
+ Examples:
125
+
126
+ ```text
127
+ Directory to expose [/home/warren/project]: /home/warren/data
128
+ Directory to expose [/home/warren/project]: /data/job1 /scratch/job1
129
+ Directory to expose [/home/warren/project]: "/home/warren/my project"
130
+ ```
131
+
132
+ The sandbox resolves each path to its real absolute path. Any request outside
133
+ those roots is rejected.
134
+
135
+ ## Local Wiring Check
136
+
137
+ Use `doctor` when you want to confirm that a local HPC file will be passed to
138
+ LoomEye analysis correctly before doing a live demo:
139
+
140
+ ```bash
141
+ python3 loomeye_agent.py doctor \
142
+ --dirs /home/warren/project \
143
+ --file /home/warren/project/data.csv
144
+ ```
145
+
146
+ That validates the sandbox roots, normalizes the selected file paths, and prints
147
+ the metadata LoomEye will expose to generated code. To also verify the execution
148
+ prelude used for remote Python runs:
149
+
150
+ ```bash
151
+ python3 loomeye_agent.py doctor \
152
+ --dirs /home/warren/project \
153
+ --file /home/warren/project/data.csv \
154
+ --run-python
155
+ ```
156
+
157
+ ## Saved Config
158
+
159
+ After a successful connection, the agent saves settings to:
160
+
161
+ ```text
162
+ ~/.loomeye/agent.json
163
+ ```
164
+
165
+ The config includes:
166
+
167
+ - persistent agent token
168
+ - allowed directories
169
+ - backend URL
170
+ - Python execution permission
171
+ - package install permission
172
+ - managed env path
173
+ - whether execution choices should be remembered
174
+
175
+ The file is written with `0600` permissions because it contains a sensitive
176
+ token. The token can reconnect from the same machine until it is revoked or
177
+ replaced. To remove it from this machine:
178
+
179
+ ```bash
180
+ python3 loomeye_agent.py disconnect
181
+ ```
182
+
183
+ To inspect it without printing the full token:
184
+
185
+ ```bash
186
+ python3 loomeye_agent.py status
187
+ ```
188
+
189
+ ## Python Execution
190
+
191
+ By default, the agent only exposes approved files. During `connect`, it asks:
192
+
193
+ ```text
194
+ Allow LoomEye to run generated Python code on this machine?
195
+ ```
196
+
197
+ If you answer yes, LoomEye can send generated Python code to the connected
198
+ machine. Code runs in the managed LoomEye Python environment, not in the user's
199
+ shell environment.
200
+
201
+ The agent also asks:
202
+
203
+ ```text
204
+ Allow installing missing Python packages into ~/.loomeye/python-env?
205
+ ```
206
+
207
+ If enabled, LoomEye may request package installation when generated code imports
208
+ a package that is not available.
209
+
210
+ ## Managed Python Environment
211
+
212
+ Default environment:
213
+
214
+ ```text
215
+ ~/.loomeye/python-env
216
+ ```
217
+
218
+ The agent creates this environment on demand with Python's built-in `venv`
219
+ module:
220
+
221
+ - `with_pip=True`
222
+ - `system_site_packages=True`
223
+
224
+ That means the environment has its own package install location, but it can also
225
+ see system/user site packages when available.
226
+
227
+ Override the location:
228
+
229
+ ```bash
230
+ python3 loomeye_agent.py connect \
231
+ --token <TOKEN> \
232
+ --env-dir /scratch/warren/loomeye-python-env
233
+ ```
234
+
235
+ ## Environment Scanning
236
+
237
+ When Python execution is enabled, the agent scans the managed environment on
238
+ connect. It reports:
239
+
240
+ - Python executable path
241
+ - Python version
242
+ - installed package names
243
+ - package count
244
+ - importable top-level module count
245
+ - env directory
246
+ - scan timestamp
247
+
248
+ The scan result is cached in memory. The backend can ask for the cached summary
249
+ or force a refresh. After auto-installing packages, the agent rescans.
250
+
251
+ ## Missing Package Detection
252
+
253
+ Before running code, the agent parses imports using Python `ast`. It checks
254
+ whether each import is available with `importlib.util.find_spec`.
255
+
256
+ If imports are missing and auto-install is disabled, execution stops and LoomEye
257
+ returns the missing package list.
258
+
259
+ If auto-install is enabled, the agent maps common import names to pip package
260
+ names and runs:
261
+
262
+ ```bash
263
+ python -m pip install <packages>
264
+ ```
265
+
266
+ Examples of mappings:
267
+
268
+ | Import | Package |
269
+ | --- | --- |
270
+ | `PIL` | `pillow` |
271
+ | `cv2` | `opencv-python` |
272
+ | `sklearn` | `scikit-learn` |
273
+ | `bs4` | `beautifulsoup4` |
274
+ | `yaml` | `PyYAML` |
275
+ | `docx` | `python-docx` |
276
+ | `pptx` | `python-pptx` |
277
+
278
+ ## Remote Commands Supported By The Agent
279
+
280
+ These are internal WebSocket commands sent by the LoomEye backend:
281
+
282
+ | Command | Purpose |
283
+ | --- | --- |
284
+ | `list_files` | List files inside allowed directories. |
285
+ | `read_file` | Read text files or return binary files as base64. |
286
+ | `file_info` | Return metadata for a file or directory. |
287
+ | `search_files` | Search filenames inside allowed directories. |
288
+ | `head_file` | Read the first N lines of a text file. |
289
+ | `python_env` | Return the cached or refreshed Python environment summary. |
290
+ | `check_imports` | Parse code imports and report missing packages. |
291
+ | `run_python` | Run Python code in the managed environment. |
292
+
293
+ Safety limits include:
294
+
295
+ - max file read: 50 MB
296
+ - max directory listing: 5,000 entries
297
+ - default execution timeout: 240 seconds
298
+ - max execution timeout: 900 seconds
299
+ - max execution output capture: 2 MB
300
+
301
+ ## How Code Runs
302
+
303
+ For `run_python`, the agent:
304
+
305
+ 1. validates that Python execution is enabled
306
+ 2. validates the working directory is inside an allowed sandbox root
307
+ 3. checks imports
308
+ 4. optionally installs missing packages
309
+ 5. writes the generated code to `~/.loomeye/runs/<run_id>/code.py`
310
+ 6. runs that script with the managed Python executable
311
+ 7. returns stdout, stderr, return code, installed packages, working directory,
312
+ and Python executable path
313
+
314
+ The script receives two helper values through `builtins`:
315
+
316
+ ```python
317
+ builtins.loomeye_hpc_files
318
+ builtins.loomeye_hpc_file_metadata
319
+ builtins.loomeye_working_dir
320
+ ```
321
+
322
+ The same values are also available as top-level names in the generated script:
323
+ `loomeye_hpc_files`, `loomeye_hpc_file_metadata`, and
324
+ `loomeye_working_dir`.
325
+
326
+ ## Publishing To PyPI
327
+
328
+ The package metadata lives in `agent/pyproject.toml`, and releases are published
329
+ from `.github/workflows/publish-loomeye-agent.yml`.
330
+
331
+ Release flow:
332
+
333
+ ```bash
334
+ cd agent
335
+ python -m build
336
+ twine check dist/*
337
+ cd ..
338
+ git tag loomeye-agent-v0.2.0
339
+ git push origin loomeye-agent-v0.2.0
340
+ ```
341
+
342
+ The GitHub Actions workflow publishes the built package from `agent/dist` using
343
+ PyPI Trusted Publishing. Each release needs a new version in
344
+ `agent/pyproject.toml` before tagging.
345
+
346
+ After the first PyPI release, users can install with:
347
+
348
+ ```bash
349
+ python3 -m pip install --user --upgrade loomeye-agent==0.2.0
350
+ python3 -m loomeye_agent connect --token <TOKEN>
351
+ ```
352
+
353
+ ## Troubleshooting
354
+
355
+ ### Agent connects to the wrong backend
356
+
357
+ Prod is default. Use `--dev` for dev:
358
+
359
+ ```bash
360
+ python3 loomeye_agent.py connect --dev --token <TOKEN>
361
+ ```
362
+
363
+ There is also a hidden internal override for emergency testing:
364
+
365
+ ```bash
366
+ python3 loomeye_agent.py connect \
367
+ --backend-url wss://example.com \
368
+ --token <TOKEN>
369
+ ```
370
+
371
+ ### Directory does not show up in LoomEye
372
+
373
+ Make sure the directory exists on the remote machine and was included in the
374
+ prompt or `--dirs`. Run:
375
+
376
+ ```bash
377
+ python3 loomeye_agent.py status
378
+ ```
379
+
380
+ ### Python packages are missing
381
+
382
+ Reconnect and allow package installs, or install packages manually into:
383
+
384
+ ```text
385
+ ~/.loomeye/python-env
386
+ ```
387
+
388
+ Manual install example:
389
+
390
+ ```bash
391
+ ~/.loomeye/python-env/bin/python -m pip install pandas numpy scipy
392
+ ```
393
+
394
+ ## Security Model
395
+
396
+ - The agent initiates an outbound WebSocket connection.
397
+ - LoomEye does not need inbound network access to the user's machine.
398
+ - LoomEye does not receive SSH keys.
399
+ - File access is limited to approved sandbox directories.
400
+ - Python execution is opt-in.
401
+ - Package installation is a separate opt-in.
402
+ - The agent runs as the current user and inherits that user's OS permissions.
403
+ - The saved token is masked in `status` output and stored in a `0600` config file.