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.
- loomeye_agent-0.2.0/PKG-INFO +403 -0
- loomeye_agent-0.2.0/README.md +393 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/PKG-INFO +403 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/SOURCES.txt +9 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/dependency_links.txt +1 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/entry_points.txt +2 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/requires.txt +1 -0
- loomeye_agent-0.2.0/loomeye_agent.egg-info/top_level.txt +1 -0
- loomeye_agent-0.2.0/loomeye_agent.py +1458 -0
- loomeye_agent-0.2.0/pyproject.toml +23 -0
- loomeye_agent-0.2.0/setup.cfg +4 -0
|
@@ -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.
|