@galaxyproject/olit 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -1,188 +1,102 @@
1
- # Olit: A Browser-Native AI Co-Scientist for Galaxy
1
+ # Olit: an AI co-scientist inside Galaxy
2
2
 
3
- Olit is an AI co-scientist that runs directly inside Galaxy, in the web browser.
3
+ Olit runs in the browser, inside Galaxy. It inspects histories and datasets, plans analyses, finds
4
+ and runs Galaxy tools and workflows, follows their jobs, reads the results, and keeps a record of
5
+ the analysis as a Galaxy page.
4
6
 
5
- It can inspect histories and datasets, plan analyses, search for and run Galaxy tools and workflows, follow their execution, inspect results, perform local computation, create visualizations and other artifacts, and continue working from what it finds.
7
+ **The browser runs the agent; Galaxy runs the science.** Analyses are ordinary Galaxy jobs and
8
+ workflows with their usual provenance. Light Python runs in the browser through Pyodide. There is
9
+ no agent server and no per-user container: Olit uses your Galaxy session, and your model key stays
10
+ in your browser.
6
11
 
7
- **The browser runs the agent; Galaxy runs the science.**
12
+ ## Try it in Galaxy
8
13
 
9
- Galaxy provides the computational environment: datasets, tools, workflows, jobs, histories, and provenance. Lightweight Python runs locally through Pyodide. The agent uses the researcher's active Galaxy session, and model credentials remain in the browser.
14
+ **Requirements:** Galaxy 26.1 or newer; a model provider key (or a Galaxy whose admin configured
15
+ its chat proxy); a current Chrome or Firefox (Safari is untested).
10
16
 
11
- No separate agent server or per-user compute container is required.
17
+ 1. Add Olit to your Galaxy's `client/visualizations.yml`, with the version on npm:
12
18
 
13
- ## Why Olit?
19
+ ```yaml
20
+ olit:
21
+ package: "@galaxyproject/olit"
22
+ version: <version>
23
+ ```
14
24
 
15
- Galaxy already provides AI capabilities for tasks such as chat, error analysis, and tool recommendation. Olit explores a different question:
25
+ 2. Rebuild the client (`make client`, or `cd client && pnpm run plugins`) and restart Galaxy.
26
+ 3. Select a csv, tabular or txt dataset, choose **Visualize**, and open **AI Research
27
+ Assistant**. Olit works in that dataset's history.
28
+ 4. Pick a provider and paste its key: Gemini, DeepSeek, OpenRouter, OpenAI, Anthropic, Groq,
29
+ Mistral, xAI, Jetstream2, a local OpenAI-compatible server, or Galaxy's chat proxy. The key is
30
+ kept for this tab only and sent nowhere but to the provider.
16
31
 
17
- > **Can an open-ended AI co-scientist operate Galaxy directly from the browser, using Galaxy itself as its computational environment?**
18
-
19
- A research question can become a multi-step Galaxy analysis. Olit can inspect the available data, develop a plan, select and configure tools, submit jobs and workflows, wait for their results, inspect the outputs, and continue the analysis based on what it finds.
20
-
21
- Scientific computation remains in Galaxy. Tools, parameters, inputs, outputs, and provenance remain part of the normal Galaxy research record rather than moving into a separate agent environment.
32
+ Olit keeps its conversation in the browser's private file system, so a reload continues where you
33
+ left off; a private window keeps it in memory and says so. **Save** stores the conversation in
34
+ Galaxy as a visualization you can reopen anywhere, and the analysis record is a page attached to
35
+ the history.
22
36
 
23
37
  ## Architecture
24
38
 
25
39
  ```mermaid
26
- flowchart TB
27
- UI["Orbit's Chat Interface"]
28
-
29
- subgraph Olit
30
- UI
31
- Brain["Olit's Pyodide Brain"]
32
- Skill["Galaxy Skills"]
33
- Ops["Galaxy MCP"]
34
- State["State"]
35
- BrowserState["Browser Storage"]
36
- Notebook["Galaxy Notebook"]
37
- Session["Visualization Session"]
38
- end
39
-
40
- Model["LLM Provider"]
41
- GalaxyApi["Galaxy's API"]
42
-
43
- UI --> Brain
44
- Brain --> Skill
45
- Brain --> Ops
46
- Brain --> State
47
- State --> BrowserState
48
- State --> Notebook
49
- State --> Session
50
- Brain --> Model
51
- Ops --> GalaxyApi
40
+ flowchart LR
41
+ UI["Chat UI (from Orbit)"] --> Agent["Agent (pi-durable, Web Worker)"]
42
+ Agent --> Ops["galaxy-ops"] --> Galaxy["Galaxy API"]
43
+ Agent --> Python["Pyodide (isolated worker)"]
44
+ Agent --> Model["LLM provider"]
45
+ Agent --> Storage["Browser storage (OPFS)"]
46
+ Agent --> Record["Record page in Galaxy"]
52
47
  ```
53
48
 
54
- ## Olit and Orbit
49
+ - The agent runs on [pi-durable](https://github.com/earendil-works/pi): conversations, runs and
50
+ submitted Galaxy work are committed to SQLite in the browser, so they survive a reload.
51
+ - Galaxy operations come from `@galaxyproject/galaxy-ops`, the same operations galaxy-mcp serves,
52
+ described to the model as galaxy-mcp describes them.
53
+ - Python runs in its own worker with an opaque origin: it has no Galaxy session, no page storage
54
+ and no model key.
55
+
56
+ `LAYOUT.md` maps the source tree.
55
57
 
56
- [Orbit](https://github.com/galaxyproject/loom) is Galaxy's flagship AI environment and the main functional reference for Olit. Orbit pioneered the AI co-scientist model for Galaxy: an open-ended agent that can plan analyses, work with Galaxy tools and workflows, inspect results, and continue a research process over multiple steps.
58
+ ## Olit and Orbit
57
59
 
58
- Olit explores how that model translates to a browser-native architecture. Its name reflects that lineage, in a relationship similar in spirit to JupyterLab and JupyterLite: the research experience is adapted to a different runtime environment.
60
+ [Orbit](https://github.com/galaxyproject/loom) is Galaxy's AI environment and Olit's functional
61
+ reference; Olit reuses Orbit's chat interface.
59
62
 
60
63
  | | Orbit | Olit |
61
64
  | --- | --- | --- |
62
- | Agent runtime | Local/server Python | Browser / Pyodide |
63
- | Scientific computation | Local environment + Galaxy | Galaxy |
64
- | Shell | Available | None |
65
- | Filesystem | Local filesystem | Galaxy data + browser storage |
66
- | Galaxy access | MCP | Active Galaxy session |
67
- | Deployment | Agent environment | Galaxy visualization plugin |
68
- | Per-user agent backend | Required | None |
69
-
70
- The architectures have different capability envelopes. Orbit provides a shell, local processes, unrestricted networking, and a conventional filesystem. Olit investigates what an AI co-scientist can do when the browser provides the agent runtime and Galaxy provides the scientific computational environment.
71
-
72
- ## Galaxy as the computational environment
73
-
74
- Olit's constraints are deliberate.
75
-
76
- Scientific analyses execute as normal Galaxy jobs and workflows. Inputs and outputs remain Galaxy datasets and collections. Galaxy records the tools, parameters, inputs, outputs, and provenance of the analysis.
77
-
78
- Pyodide complements that remote computation with local Python for lightweight exploration and intermediate computation. Browser storage provides local agent state, while persistent research outputs can be represented using Galaxy-native artifacts.
79
-
80
- The result is a division of responsibilities:
81
-
82
- - **Galaxy** provides scientific tools, workflows, data, jobs, provenance, and persistent research outputs.
83
- - **Pyodide** provides lightweight local Python computation.
84
- - **The browser** provides the agent runtime, interface, local state, networking, and model connection.
85
-
86
- Olit therefore does not introduce another general-purpose computational environment alongside Galaxy.
87
-
88
- ## Inside Galaxy
89
-
90
- Olit is built as an application on Galaxy's Charts visualization plugin framework.
65
+ | Agent runtime | Local or server (pi) | Browser worker (pi-durable) |
66
+ | Computation | Local environment and Galaxy | Galaxy, plus Pyodide |
67
+ | Shell | Yes | No |
68
+ | Galaxy access | MCP | Your Galaxy session |
69
+ | Delivered as | Desktop app or web service | Galaxy visualization plugin |
91
70
 
92
- Galaxy visualization plugins are not limited to plots and viewers: they can be complete browser applications with access to Galaxy data and services. Olit uses that existing extension point to deliver an AI co-scientist inside the Galaxy interface.
71
+ For a shell, local software or unrestricted networking, use Orbit.
93
72
 
94
- Because Olit is served by Galaxy, it is same-origin with the Galaxy API and can operate through the researcher's active session. In normal embedded operation, this avoids a local proxy, a separate agent process, or a long-lived Galaxy API key held by another service.
95
-
96
- The Python agent runs in a Web Worker through Pyodide. The surrounding TypeScript application connects the interface, browser runtime, model provider, and active Galaxy session. Model credentials remain in the browser rather than being held by a separate Olit backend.
97
-
98
- This allows Olit to be distributed through Galaxy's existing visualization infrastructure without requiring a separate agent service.
99
-
100
- `LAYOUT.md` maps the repository and its major components.
73
+ ## Scope
101
74
 
102
- ## Running it
75
+ `run_python` runs in Pyodide. Top-level `await` and `pyfetch` work; network access follows browser
76
+ rules, so CORS-enabled APIs are reachable and other sites are not. Galaxy is reached only through
77
+ Olit's Galaxy tools, where destructive operations ask before they run. Stop ends a running Python
78
+ call.
103
79
 
104
- Install dependencies once:
80
+ ## Development
105
81
 
106
82
  ```bash
107
83
  npm install
84
+ npm run dev # builds (fetching Pyodide and the skills corpus on first run), then serves
85
+ npm test # unit tests, linting, type checks, vendored-file checks, browser tests
86
+ npm run stale # where the pinned upstreams stand
108
87
  ```
109
88
 
110
- Then start the development environment:
89
+ `npm run dev` against a local Galaxy and a model:
111
90
 
112
91
  ```bash
92
+ GALAXY_ROOT=http://127.0.0.1:8080 GALAXY_KEY=<galaxy-api-key> \
93
+ LLM_PROVIDER=google LLM_KEY="$GEMINI_API_KEY" LLM_MODEL=gemini-3.7-flash \
113
94
  npm run dev
114
95
  ```
115
96
 
116
- The first run builds the Pyodide assets and the Olit brain wheel and can take several minutes.
117
-
118
- To serve what is already built:
119
-
120
- ```bash
121
- npx vite
122
- ```
123
-
124
- Changes under `brain/` require rebuilding the wheel and restarting the development server:
125
-
126
- ```bash
127
- npm run build:olit
128
- ```
129
-
130
- ### Against the stub
131
-
132
- The end-to-end stub requires neither Galaxy nor a model. See `e2e/README.md`.
133
-
134
- ```bash
135
- node e2e/stub.cjs &
136
- GALAXY_ROOT=http://127.0.0.1:8099 \
137
- LLM_PROVIDER=local \
138
- LLM_ROOT=http://127.0.0.1:8099 \
139
- LLM_PATH=/v1 \
140
- LLM_MODEL=stub-model \
141
- LLM_CONTEXT_WINDOW=40000 \
142
- npm run dev
143
- ```
144
-
145
- ### Against Galaxy and a model
146
-
147
- ```bash
148
- GALAXY_ROOT=http://127.0.0.1:8080 \
149
- GALAXY_KEY=<galaxy-api-key> \
150
- LLM_PROVIDER=gemini \
151
- LLM_KEY="$GEMINI_KEY" \
152
- LLM_MODEL=gemini-3.7-flash \
153
- npm run dev
154
- ```
155
-
156
- `LLM_PROVIDER` names an entry in `brain/olit/substrate/llm/providers.py`, which defines the endpoint, context window, and rate limit. Set `LLM_ROOT` and `LLM_PATH` for an endpoint the registry does not contain.
157
-
158
- `GALAXY_KEY` is needed during local development because Vite serves Olit outside Galaxy, where the Galaxy session cookie does not apply.
159
-
160
- Leave `LLM_PROVIDER` unset to use the provider picker. This is the production path: the model key remains in the browser worker and never enters the Python agent.
161
-
162
- ## Tests
163
-
164
- ```bash
165
- npm test
166
- ```
167
-
168
- This runs Vitest, pytest, TypeScript type checking, vendored-file verification, and the end-to-end drives.
169
-
170
- To inspect the surface exposed to the agent:
171
-
172
- ```bash
173
- npm run describe
174
- ```
175
-
176
- This reports the tools and parameters exposed to the agent, the Galaxy queries they construct, guards that can refuse calls, and the sampling and loop policies.
177
-
178
- ## Scope
179
-
180
- Olit deliberately does not reproduce a general-purpose local computing environment.
181
-
182
- `run_python` executes inside Pyodide. Submitted code is asynchronous, so top-level `await` and `pyfetch` work, but networking follows browser security rules: CORS-enabled APIs are accessible; arbitrary network resources are not.
183
-
184
- For research requiring a shell, unrestricted networking, local software installation, or a full filesystem, Orbit provides the appropriate execution environment.
185
-
186
- Olit instead tests a different architectural proposition:
97
+ `GALAXY_KEY` is needed only because the dev server runs outside Galaxy. Leave `LLM_PROVIDER` unset
98
+ to get the provider picker, as in production. Providers are listed in `src/agent/providers.ts`.
187
99
 
188
- > **Galaxy is the computational environment. The browser is the agent runtime.**
100
+ The browser tests run against a stub Galaxy and model (`e2e/README.md`). The eval harness drives
101
+ a Node build of the agent: `npm run build:session`, and `node dist/session.mjs --describe --root .`
102
+ prints the tools, guards and policies the agent is given.
package/package.json CHANGED
@@ -1,61 +1,58 @@
1
1
  {
2
2
  "name": "@galaxyproject/olit",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "static"
8
8
  ],
9
9
  "scripts": {
10
- "build": "npm run build:pyodide && npm run build:skills && npm run build:providers && npm run build:ops && npm run build:olit && vite build",
11
- "build:olit": "cd brain && rm -rf build dist olit.egg-info && SOURCE_DATE_EPOCH=315532800 python -m build --wheel && cd .. && node scripts/stamp_wheel.js && mkdir -p static/pyodide && rm -f static/pyodide/olit-*.whl && cp brain/dist/olit-*.whl static/pyodide/",
12
- "build:ops": "node scripts/install_ops.js",
13
- "build:providers": "python3 scripts/dump_providers.py",
10
+ "build": "npm run build:pyodide && npm run build:skills && vite build",
14
11
  "build:pyodide": "node scripts/install_pyodide.js",
15
12
  "build:skills": "node scripts/install_skills.js",
16
- "describe": "python3 contract/describe.py --root .",
17
13
  "dev": "npm run build && vite",
18
- "galaxy-mcp-docs": "python3 scripts/capture_galaxy_mcp_docs.py",
19
14
  "lint:js": "prettier --config ./prettier.config.js --check './*.{js,ts,json}' 'src/**/*.{js,ts,json,css}'",
20
- "lint:contract": "python3 -m black --check --config brain/pyproject.toml contract && ruff check --config brain/pyproject.toml contract",
21
- "lint:scripts": "python3 -m black --check --config brain/pyproject.toml scripts && ruff check --config brain/pyproject.toml scripts",
22
- "lint:python": "cd brain && python -m black --check . && ruff check .",
15
+ "lint:scripts": "python3 -m black --check --line-length 120 scripts && ruff check --line-length 120 scripts",
23
16
  "prettier": "prettier --config ./prettier.config.js --write './*.{js,ts,json}' 'src/**/*.{js,ts,json,css}'",
24
17
  "preview": "vite preview",
25
18
  "stale": "node scripts/check_stale.js",
26
- "test": "npm run test:unit && npm run test:python && npm run test:contract && npm run lint:python && npm run lint:contract && npm run lint:scripts && npm run lint:js && npm run typecheck && npm run typecheck:python && npm run vendored && npm run test:e2e",
19
+ "sync:orbit": "node scripts/sync_orbit_ui.js",
20
+ "test": "npm run test:unit && npm run lint:scripts && npm run lint:js && npm run typecheck && npm run vendored && npm run test:e2e",
27
21
  "test:e2e": "bash e2e/run-all.sh",
28
- "test:contract": "python3 -m pytest contract/tests -v -r s --import-mode=importlib",
29
- "test:python": "cd brain && python -m pytest tests/ -v -r s --import-mode=importlib",
30
22
  "test:ui": "vitest --ui",
31
23
  "test:unit": "vitest run",
32
24
  "test:watch": "vitest --watch",
33
25
  "typecheck": "tsc --noEmit",
34
26
  "vendored": "python3 scripts/check_vendored.py",
35
- "galaxy-ops-registry": "node scripts/capture_galaxy_ops_registry.mjs",
36
- "typecheck:python": "cd brain && python -m mypy olit ../contract ../scripts"
37
- },
38
- "dependencies": {
39
- "@galaxyproject/galaxy-ops": "https://github.com/guerler/galaxy-mcp/releases/download/ops-v0.3.0-fork.1/galaxyproject-galaxy-ops-0.3.0-fork.1.tgz",
40
- "galaxy-charts": "^0.1.16",
41
- "mermaid": "^11.16.1",
42
- "vega": "^5.30.0",
43
- "vega-embed": "^6.26.0",
44
- "vega-lite": "^5.21.0"
27
+ "build:session": "npm run build:pyodide && npm run build:skills && vite build --config vite.config.session.ts"
45
28
  },
46
29
  "devDependencies": {
30
+ "@earendil-works/chord": "^1.0.4",
31
+ "@earendil-works/pi-ai": "^1.0.4",
32
+ "@earendil-works/pi-durable": "https://github.com/guerler/pi/releases/download/durable-v1.0.4-olit.2/earendil-works-pi-durable-1.0.4-olit.2.tgz",
33
+ "@galaxyproject/galaxy-ops": "https://github.com/guerler/galaxy-mcp/releases/download/ops-v0.3.2-ops.3/galaxyproject-galaxy-ops-0.3.2-ops.3.tgz",
34
+ "@sqlite.org/sqlite-wasm": "^3.53.4-build2",
47
35
  "@types/dompurify": "^3.0.5",
48
36
  "@types/node": "^22.9.0",
49
37
  "dompurify": "^3.4.1",
38
+ "galaxy-charts": "^0.1.17",
50
39
  "galaxy-charts-xml-parser": "^1.0.3",
51
40
  "happy-dom": "^20.0.11",
52
41
  "marked": "^18.0.0",
42
+ "mermaid": "^11.16.1",
53
43
  "playwright": "^1.62.1",
54
44
  "prettier": "^3.7.4",
55
45
  "pyodide": "^0.29.0",
56
46
  "typescript": "^5.9.3",
47
+ "vega": "^6.4.0",
48
+ "vega-embed": "^7.3.0",
49
+ "vega-lite": "^6.4.3",
57
50
  "vite": "^7.3.0",
58
- "vite-plugin-static-copy": "^3.1.4",
59
- "vitest": "^4.0.16"
51
+ "vitest": "^4.0.16",
52
+ "yaml": "^2.9.1",
53
+ "zod": "^4.6.5"
54
+ },
55
+ "overrides": {
56
+ "katex": "^0.19.0"
60
57
  }
61
58
  }