Skip to content

Zelos Notebooks

A Zelos notebook is a plain markdown file with runnable Python cells. The local Zelos Agent executes each cell against real trace data through the Zelos Agent SDK — so a notebook is a repeatable analysis you can keep next to your code, diff in review, and re-run whenever the data changes.

Open it in the Zelos App for a visual editor and inline outputs, or use any text editor and run it from the command line. There's nothing proprietary about the file: prose is prose, and every top-level ```python fence is a cell.

What you get

  • Plain markdown

    Prose and ```python cells in one file. Version it, review it, edit it anywhere. Outputs are never written back into the file.

  • Run against live data

    Cells share one Python process and talk to the agent through connect() — query signals, compute on series, chart the result.

  • Reproducible runs

    Zelos resolves each notebook's environment once and locks it. A publish carries that lock, so a fresh machine that pulls the notebook runs the same versions. Each cell's outputs record the run that produced them.

  • Rendered output

    Add -o analysis.html (or .ipynb) to a run to also write a rendered notebook — prose, code, and every output — for archiving, sharing, or diffing runs. The app's Share dialog exports the same two formats.

Prerequisites

Choose either workflow:

  • Zelos App — install the app for the notebook library, visual editor, and inline outputs. Open a workspace before opening a notebook; notebooks live in workspace tabs.
  • Command line — run a Zelos Agent and install the Zelos CLI. The app also provides an agent on localhost:2300. A standalone agent keeps no samples by default, so queries fail until you start it with --store-type memory or --store-type disk.

The agent provisions Python for you (>=3.10); you do not need to install it yourself.

No live data yet?

Run the demo generator in another terminal so the agent has signals to serve:

zelos live demo --backfill 5m --duration 30m

The paths below (bus0/BMS_message/status.*) come from this generator. Substitute your own if your catalog differs.

Work in the Zelos App

Select Notebooks in the left sidebar rail:

  1. Choose New notebook to create a file in ~/Documents/Zelos Notebooks, Open notebook to open a .md or .markdown file elsewhere, or Examples to copy a runnable example into your library.
  2. Select a notebook to open it in a workspace tab. Edit its name, description, and tags in the document header. Editing the name renames the file. The sidebar switches from the library to the notebook's Parameters and Python settings. Back to Notebooks returns to the library.
  3. Write prose in the document and Python in code cells. Changes autosave to the markdown file. See The notebook format for the small canonicalization changes the visual editor makes when it saves.
  4. Run one cell with its Run button or Cmd/Ctrl+Enter, or choose Run all in the status bar.

The library

The library has two sections:

  • RECENTS lists the notebooks you opened most recently, including files outside your notebooks folder. Clear recents empties it. Remove from Recents in a row's menu drops one entry and leaves the file alone.
  • ALL is the folder tree of your notebooks folder. Its menu has New notebook, New folder, Expand All, and Collapse All. Drag a notebook or folder onto another folder to move it.

Each notebook row has a menu, on its ⋮ button or a right-click:

  • Rename edits the name in place in the row and renames the file.
  • Duplicate asks for a name and copies the notebook beside the original. The copy has no outputs and no cloud binding.
  • Move to moves it into another folder.
  • Copy file path and Show in folder locate the file on disk.
  • Delete removes the file and its stored outputs.

A folder row has New notebook, New subfolder, Rename, Move to, Show in folder, and Delete.

Renames and moves carry the notebook's separately stored outputs. Deletion removes them.

The rail search filters notebook names, descriptions, relative paths, and folders. While a term is in the field, the ALL section shows RESULTS instead. If a notebook's settings are open, typing a term shows the library and clearing it restores those settings. Press ↓ in the search field to enter the library. Opening a result ends the search.

Write prose

Prose is markdown, edited visually. Type / at the start of a line, or open Insert in the toolbar, to add a block:

Insert item Markdown it writes
Python cell a ```python fence
Heading 1, Heading 2, Heading 3 #, ##, ###
Bulleted list, Numbered list -, 1.
Task list - [ ] and - [x]
Table a GFM pipe table, column alignment included
Image ![caption](path). See Images.
Equation a $$…$$ block
Footnote a [^1] reference and its definition
Quote >
Divider ---

Write inline math as $…$ and display math as $$…$$. Equations render as typeset math in the app and in an HTML export. Typing the markdown directly works too: - [ ] starts a task list, and # starts a heading.

Run cells

Every Python cell has a toolbar:

  • Run runs this cell.
  • Fix with AI appears on a cell that raised. It asks Zelos AI to fix the error.
  • Ask AI opens the chat with this cell attached, ready for your question.
  • Hide code hides the cell's code and keeps its outputs in view. Show code brings the code back.
  • The ⋮ menu has Clear output and Delete cell.

The status bar at the bottom of the notebook holds the run controls:

  • Run all runs every cell, top to bottom. During a run it becomes Stop, which interrupts the run.
  • The arrow beside it opens three more options:
    • Run out-of-date cells starts at the first changed cell and runs everything below it.
    • Restart and run all clears every variable, then runs the notebook.
    • Clear all outputs removes every rendered output. The kernel keeps its variables.
  • Hide code and Show code collapse or expand the code in every cell at once.

The middle of the status bar shows one summary of the notebook: Cell N of M with the elapsed time during a run, then Not run yet, N errors, N cells out of date, or Up to date. When the summary points at a cell, select it to scroll to that cell.

The left of the status bar shows Python's state: Not started, Preparing environment, Starting, Ready, Running, Restarting, Crashed, Environment failed, or Disconnected. A disconnected agent pauses runs but does not stop edits from saving.

Select that state to open the Python popover. It shows the Python version, interpreter path, working directory, environment id, and process ID. It also has two buttons:

  • Restart Python discards every variable and any hardware connection the notebook opened.
  • Update packages resolves the notebook's dependencies again and moves to the newest versions they allow. The front matter does not change.

When the environment fails to resolve, the popover shows the resolver's message with Retry and Edit packages instead.

Opening a notebook prepares its Python environment but does not start Python. The app starts Python in the background for the notebook in view, so the first run starts fast. If you never run code in it, that Python process stops ten minutes after the notebook leaves view.

Keyboard shortcuts

Shortcut Action
Cmd/Ctrl+Enter Run the cell the caret is in
Cmd/Ctrl+Shift+Enter Run out-of-date cells
Cmd/Ctrl+. Stop the run
Cmd/Ctrl+Shift+C Insert a Python cell below the current block
Cmd/Ctrl+Shift+K Add a link to the selected text
Cmd/Ctrl+S Save now
Shift+Esc Leave the code cell

The command palette also offers New Notebook, Open Notebook, Save Notebook Now, Run Out-of-date Cells, and Interrupt Run.

Write a notebook

Get started with notebooks walks the whole round trip — create, query, chart, check, run, export. What that page leaves out is what a finished file looks like.

Any text is prose; every top-level ```python fence is a cell. Cells run top to bottom and share one Python process, so you connect once and reuse the handle everywhere below.

analysis.md
---
description: Rank the pack's cells and find the one that sags.
dependencies:
  - zelos-sdk[notebook]
params:
  window: "-2m"
---

Connect once, then later cells reuse `agent`.

```python
from zelos_sdk import connect

agent = connect()
agent
```

Pull the pack's cell voltages over the parameterized window. `params.window`
comes from the front matter and can be overridden at run time. A bare object
on a cell's last line renders itself, so this is the table.

```python
frame = agent.query("bus0/BMS_message/cells.*", start=params.window)
frame
```

Chart it. `plot()` emits Vega-Lite — the app renders it inline and an HTML
export renders it offline, with no plotting library in `dependencies`.

```python
frame.short_names().plot()
```

Summarize the spread across the pack.

```python
frame.short_names().describe()
```

zelos notebook run analysis.md runs it. The last line names the run's outcome and the exit code matches it — see Notebooks as tests.

The querying, series math, and charting all come from the Agent SDK — see Query Live Data for the full surface. List zelos-sdk in dependencies like any other package — the environment's lock pins the exact version it resolved to, and the [notebook] extra brings pandas and numpy with it.

Use the command line

Every zelos notebook command talks to an agent. It uses --host, then ZELOS_AGENT_URL, then localhost:2300. --host goes before the command: zelos notebook --host bench-01.internal:2300 run analysis.md.

A bare name such as analysis.md means the file in the current directory when one exists there. Otherwise it means that name in your notebooks folder. A path that starts with ./, ../, or / always means exactly that path. The agent reads the file from its own disk, so a path must exist on the agent's machine.

Command What it does Flags
new <path> Writes the starter notebook and prints where it landed. Never overwrites: a taken name lands on the next free name N. none
list [path] Lists notebooks with their description and authors. Searches your notebooks folder unless you pass a folder or file. --json
run <path> Runs the cells and streams their output. Exits 0, 1, 2, or 130; see Notebooks as tests. --cell <N>, --param <key=value>, -o <file>, --offline, --dry-run, --publish, --org, --visibility, --tag
publish <path> Publishes the saved source and stored outputs as a new cloud version. Does not run cells. --org, --visibility, --tag, --new, --json
pull <notebook-id> Saves a cloud notebook into your notebooks folder as a new file. --org, --version <publish-id>, --json
rename <from> <to> Renames or moves a notebook or folder inside your notebooks folder. Stored outputs and the environment follow. none
copy <path> <name> Copies a notebook beside the original. The copy has no outputs and no cloud binding. none
delete <path> Permanently deletes a notebook or folder inside your notebooks folder, with its stored outputs. There is no trash. --force (required)
mkdir <path> Creates a folder in your notebooks folder. none
import <file.ipynb> Converts a Jupyter notebook to this format. See Converting existing notebooks. -o, --out <file> (required)
env warm <path> Prepares the notebook's Python environment without running a cell. --offline

The run flags:

Flag What it does
--cell <N> Run only the code cell at index N, counting from 0. Repeatable. Without it, every cell runs.
--param <key=value> Override a parameter for this run. Repeatable. See Parameters.
-o, --output <file> Also write the rendered notebook. The extension picks the format: .html or .ipynb.
--offline Prepare the environment from the local uv cache only. Fails rather than using the network.
--dry-run Prepare and check the environment, print the run plan, and exit without running a cell.
--publish Publish to Zelos Cloud after the run settles. Errored runs publish too.
--org, --visibility, --tag Publish options. --visibility and --tag require --publish, and --org is used only with it. See From the CLI.

Publish and share with Zelos Cloud

Each publish adds an immutable version: the saved source snapshot plus the latest settled outputs. Publishing does not run cells. A publish also ships the notebook's environment lock, so a machine that pulls the notebook and has never resolved its environment spec runs the same versions — see Environments. The first publish writes a remote block into the notebook's front matter, so this file — and every clone of it — publishes to the same cloud notebook from then on. Commit that block; see The remote block.

Publishing needs a signed-in account. Sign in with the Zelos App, or run zelos login on a headless machine — it authenticates in a browser and stores the credential in the system keyring.

A published notebook counts against your organization's cloud storage.

From the Zelos App

Choose Share in the notebook header, then select who can open the cloud notebook: Only me, Organization, or Public link. See Publishing Notebooks for what each one lets in.

The owner or an organization admin can change organization-wide access; only the owner can switch a published notebook to Only me.

The app blocks publishing and exporting in three cases: the notebook is not open yet, a run is active, or its outputs could not be saved. The dialog names the reason. Zelos Cloud can still refuse a publish, for example when the organization has no room for it. The dialog then shows the cloud's reason, and the file stays unchanged.

If edited cells have stale outputs, the dialog warns you but lets you publish. The snapshot stays an honest record of the current state.

Export in the same dialog saves a copy to this computer, with no cloud account needed:

  • HTML page writes a single page with prose, code, and every output. Vega-Lite charts, such as plot() output, render with no network access. Plotly charts load the Plotly library from the web when the page opens.
  • Jupyter notebook writes an .ipynb file with its outputs.

Both formats match what run -o writes.

After publishing succeeds, the Cloud view refreshes the notebook's row and publish history immediately. You do not need to reload it.

Public links are capabilities with two important constraints:

  • A link stays pinned to the version it was created for. Publishing an update does not move existing links; create a new link to share the new version.
  • Copy a newly created URL when it appears. For security, Zelos does not show that secret URL again. You can still rename or revoke the link later. Changing access from Public link to a restricted option revokes every active public link.

The Share dialog shows the three most recent versions. View opens a version in a read-only tab, with no file written and no kernel started. See all opens the complete history in Zelos Cloud.

Read a cloud notebook

Opening a notebook from the Cloud view, from a link, or from the console's Open in Zelos App renders the published version in a read-only tab. The tab switches between versions in place and offers the next step:

  • Save to library saves the notebook into your notebooks folder, outputs and environment lock included, and opens it for editing. The file stays bound to the cloud notebook, so publishing from it adds a version there.
  • Open local copy appears instead when your library already holds a file bound to that cloud notebook. Save a copy is the only way to get a second file.
  • Update to latest appears when your local copy matches an older published version; it replaces the file with the newest version. A copy with local edits shows Local edits instead and is left alone.

Publishing from a copy of someone else's notebook that you cannot change offers Publish as a copy, which publishes to a new cloud notebook of your own and rebinds the file to it.

From the CLI

publish publishes the notebook's currently saved state and prints its cloud page:

zelos notebook publish analysis.md

To run and publish in one step, add --publish to a run. Errored runs publish too, because a failed test is exactly the run someone needs to see:

zelos notebook run analysis.md --publish
Flag Accepted by What it does
--org <slug> publish, run --publish, pull Which organization to use. Needed only when you belong to several.
--visibility <org\|personal> publish, run --publish Who can see the cloud notebook: org for Organization, personal for Only me. First publish only. Defaults to org.
--tag <name> publish, run --publish Add an existing organization tag. Repeatable. Never removes one.
--new publish Ignore the existing binding and fork onto a fresh cloud notebook.
--json publish Print the publish coordinates as JSON.

Create and manage public links from the app or the cloud notebook page. A publish that the cloud refuses fails with the cloud's reason, exits 2, and leaves the file untouched.

pull does the reverse. It saves a cloud notebook into your notebooks folder as a new file, with its outputs and environment lock:

zelos notebook pull 7b7f3d24-9c1a-4f6e-8a2d-5e0c1b9f4a33

The id is the UUID in the cloud notebook's console URL. --version <publish-id> saves a specific version instead of the newest. A pull never overwrites a file: a taken name lands on the next free name N.

Tagging a notebook

Tags are organization vocabulary, shared with cloud traces and layouts, so a label means the same thing across everything your team publishes. They live in Zelos Cloud rather than in the file, which is what lets a rename reach every notebook, trace, and layout carrying the tag at once.

Tag a notebook in the app, from the header beside its authors. Search the organization's tags, tick them on and off, or type a name that isn't there yet to add it — anyone in the organization may. Each chip's colored dot opens the same color picker a signal chip uses.

Two rules decide what the header offers you, and it says which when it refuses:

  • Changing a notebook's tags is for its owner, or an organization owner or admin.
  • Renaming or recoloring a tag itself is for whoever created it, or an organization owner or admin. That one is per tag, so you can recolor the tags you made and not the ones you didn't.

A notebook you haven't published yet has no cloud copy to hold tags, so what you pick is applied by its first publish.

The console shows the same tags on the notebooks list, with Edit tags… on each row and a filter across the top. zelos tags list prints the vocabulary.

Publishing from the CLI can tag too:

zelos notebook publish analysis.md --tag battery --tag ci

--tag only ever adds, and every name must already exist — an unknown one fails before anything is published rather than quietly minting a tag nobody meant to create. Publishing the same tags again changes nothing, so a nightly run --publish --tag ci cannot wipe labels somebody curated.

That asymmetry is deliberate. A notebook's tags belong to the notebook, not to one version of it: publish version 9 and versions 1 through 8 carry the same tags, because there is one set for the whole notebook. A script that could rewrite it would be relabeling the whole history without seeing what it was overwriting. Removing a tag is something you do where you can see the whole set — the app's header or the console's list.

Tags say what a notebook is about. What a particular run did — its outcome, its parameters, when it ran and who published it — is already recorded on the version itself.

Where to next

  • Example notebooks

    Seven complete, runnable examples — from first query to a CI release gate — against demo data.

  • Notebooks as tests

    Checks score every rule, one assertion gates the run, and the exit code is the contract.

  • The notebook format

    Front matter, cells, {.norun}, parameters, and environments.

  • CLI reference

    new, list, run, publish, pull, rename, copy, delete, mkdir, import, and env warm, with every flag.

  • Query Live Data

    The SDK surface your cells use: frames, series, latest values, charts.

  • Open Trace Files

    Point the same query API at a saved .trz file.