Release Notes¶
This page provides release notes for the Zelos App and the Zelos SDK.
26.0.6
Summary¶
Trace sharing is here. Save a recording to Zelos Cloud, send your team a link, and explore it together in Zelos. No more passing large trace files around. New Notebooks turn investigations into repeatable analyses you can publish through Zelos Cloud. A new Cloud library, a new Home, and a much more capable Zelos AI bring everything together.
Added¶
- Share Traces with Your Team: When you are recording data in Zelos, choose Save trace → Upload, copy the link, and share it in Slack, email, or anywhere your team works. Anyone in your organization can open the link and select Open in Zelos to explore the same trace in the app. Share a trace →
- Zelos Notebooks: Turn an investigation into a repeatable analysis by combining explanations, executable Python, and results in one document. Query live or recorded data, adjust parameters, rerun your work, and add images while keeping the reasoning, code, and results together. Get started with notebooks →
- Publish and Share Notebooks: Publish a notebook with its results to Zelos Cloud. Set access to Only me or your organization, or create a version-pinned public link. Browse its version history in the console and open any published notebook back in the app. Publish a notebook →
- Cloud Library: Browse your organization's uploaded traces and published notebooks from the new Cloud view. Search traces by name or tag, and notebooks by title, description, author, or tag. Open an item, inspect its details, copy its console or app link, edit tags, open it in the console, or delete a trace when permitted. Explore the Cloud view →
- Cloud Management: The console now has complete trace and notebook libraries with search, tag filters, notebook access controls, publish history, downloads, and links back into the app. See how much cloud storage the organization is using; owners can also pause new uploads without affecting existing cloud data. Manage Zelos Cloud →
- Home: Zelos now opens to one place to ask AI, connect to localhost, open local or cloud traces, or create a notebook. Recent workspaces show the layout, agents, and traces they contain. Pin your favorites, rename them, or remove them from the list without deleting any traces. Meet Home →
- More Capable Zelos AI: Create and work with notebooks, search your organization's cloud library, open cloud traces and notebooks, change panel options, control playback, and ask questions about Zelos using the published documentation. Notebook changes require your approval and can be undone from the conversation. Learn what Zelos AI can do →
- Organizations and Tags: Create or join an organization without leaving the app, accept invitations, and switch between organizations. Shared tags now organize traces, layouts, and notebooks everywhere they appear. Set up an organization →
- Standalone Extension Actions: Extensions can now offer actions even while the extension is stopped. This makes file-based tools such as CAN log conversion available without starting a long-running extension. Action panels show what an action printed and clearly report failures or timeouts.
- Remote Agent Settings: Open a remote agent's menu to manage its retention, storage settings, and logs, or to clear its stored data.
- Close Other Tabs: Right-click a tab to close every other tab at once. One Undo brings the whole group back.
- Drag and drop one or more
.trzfiles into Zelos to open them together. - Report a Problem: Send a problem report with recent diagnostics directly to Zelos Support, or choose Export to save the diagnostic bundle and send it to us manually. Diagnostics settings →
Changed¶
- Global Keyboard Shortcuts: Toggle the left sidebar with
Cmd+\/Ctrl+\, and open AI Chat withCmd+L/Ctrl+L. They used to beCmd+BandCmd+I, which are bold and italic in the notebook editor. App shortcuts now work inside notebooks, Python cells, and app extensions;Cmd+K/Ctrl+Kopens the command palette from any tab, even while typing. Keyboard shortcuts → - Agent Network Access: Zelos now keeps its built-in agent available only to your computer by default. If other computers need to connect to it, choose Settings → System → Network and select the address to use. Network settings →
Fixed¶
- Plot markers no longer appear and disappear unpredictably. Auto judges each signal by its own density, so sparse signals keep their markers beside high-rate signals, and Always renders a lone visible sample.
- Boolean signals now show
true/falsein plot tooltips and measurements instead of an empty value. - Zelos no longer crashes when working with hundreds of signals, and requests that are too broad now explain how to narrow them.
- Panels now keep identically named signals from different agents or traces distinct.
- A trace with an unsupported signal type now opens with its other signals still available.
- When a trace cannot be opened, Zelos now shows what went wrong instead of leaving you with an empty workspace.
- Local traces and connections keep working when Wi-Fi is unavailable.
- When another app or agent blocks Zelos from starting, the error now identifies what is in the way and explains how to fix it.
- A temporary connection problem no longer signs you out, and switching accounts or organizations no longer leaves data from the previous session on screen.
- Playback and Undo shortcuts no longer affect the workspace behind an open dialog, and grid-panel resize handles are easier to grab.
- Scaled and floating-point CAN signals now show their value-table labels instead of raw numbers, including in traces you already recorded.
- The Explorer and Notebooks trees now remember which folders you left open. Switching to another view and back, or restarting Zelos, keeps them the way you had them.
This is one of our biggest updates yet: Zelos AI, redesigned sidebars, layout version history, new State and Raw panels, richer Plot readouts, and many more panel controls.26.0.5
Summary¶
Added¶
Cmd+I / Ctrl+I. Zelos understands your agents, traces, panels, time range, and cursor. It can find signals, inspect values, summarize ranges, detect crossings, and evaluate checks across live or recorded data. It can also build panels and tabs, control the workspace, and run enabled actions with confirmation. Conversations are saved for later. Zelos AI is rolling out in phases to select users first, then everyone, so it may not appear immediately after updating. Open AI Chat →Changed¶
Fixed¶
This release introduces App Extensions, a new extension surface for building rich, custom workflows directly inside the Zelos desktop app. Extensions can now provide full APP tabs for dashboards and purpose-built tools, alongside major improvements to workspace history, panel display controls, layout editing, search, and large-workspace performance.26.0.4
Summary¶
Added¶
Cmd+Z / Ctrl+Z and Cmd+Shift+Z / Ctrl+Shift+Z. The command palette shows the next undo/redo action when history is available. Learn more →Changed¶
signal_2 appears before signal_10.Fixed¶
This release adds a Command Palette for instant access to any action in the app, along with trace re-export, multi-file open, and automatic segment expansion. It also includes a redesigned plot tooltip, improved measurement tool, and various panel sizing and UI refinements.26.0.2
Summary¶
Added¶
Cmd+K / Ctrl+K to quickly search and run any action across the app — playback controls, workspace management, layouts, settings, extensions, and more. Includes keyboard shortcut hints and fuzzy search. Learn more →.trz file. Supports time-range selection and merging multiple open traces into a single output..trz files at once.Changed¶
Fixed¶
This release introduces a brand-new timeline and playback experience for live and trace workflows. You can now navigate with a shared cursor across any panel, compare traces more easily with 26.0.1
Summary¶
ABS/REL modes, and inspect data faster in any workflow.Added¶
Esc shortcut)ABS/REL):
REL mode aligns traces at t=0 for side-by-side run comparisonABS mode preserves wall-clock timestamps for real-world event correlationChanged¶
Fixed¶
This release introduces multi-trace and multi-agent support. You can now open multiple trace files simultaneously, connect to multiple live agents, and compare data across them in the same panels.26.0.0
Summary¶
Added¶
flight_test_001:agent::motor/status.rpm)
Changed¶
Fixed¶
This release introduces a major redesign of the application with a new Extension Marketplace, improved navigation with redesigned sidebars, and enhanced plot panel capabilities. Key highlights include the ability to browse and install extensions directly from the app, multi-select signals for easier plot creation, and improved user feedback throughout. The layout has been completely reimagined with dedicated sections for connections and layouts, making it easier to manage your workspace.25.0.22
Summary¶
Added¶
Changed¶
Fixed¶
25.0.21
Added¶
Settings -> General -> Memory Limit to enforce a particular limitChanged¶
Fixed¶
25.0.20
Added¶
Changed¶
Fixed¶
25.0.19
Added¶
Changed¶
Fixed¶
25.0.17
Added¶
25.0.16
Fixed¶
25.0.15
Added¶
25.0.14
Added¶
Fixed¶
25.0.13
Added¶
25.0.12
Fixed¶
25.0.11
Fixed¶
25.0.9
Added¶
Fixed¶
25.0.8
Fixed¶
25.0.7
Added¶
Changed¶
25.0.6
Fixed¶
25.0.5
Changed¶
25.0.4
Fixed¶
25.0.2
Fixed¶
25.0.1
Fixed¶
25.0.0
Changed¶
Fixed¶
24.1.11
Added¶
Changed¶
Fixed¶
24.1.10
Added¶
ctrl-t new tabctrl-w close tabctrl-[1-9] switch to tabctrl-shift-[ previous tabctrl-shift-] next tabalt-left-arrow previous tabalt-right-arrow next tab
24.1.9
Fixed¶
0.0.11
The read side of the SDK — everything you do after the data is recorded — is now one surface. connect() returns a handle that browses the catalog, queries live and recorded data, computes on unit-carrying series, charts, checks invariants, and re-opens .trz files, with one glob grammar and one time grammar across every call. It is the surface Zelos Notebooks run on.
Everything you already wrote keeps working: every old spelling is kept as a deprecated alias that warns once. The behavior changes below are the exceptions, and each one replaces a result that was quietly wrong.
Added¶
connect()— one entry point for a running agent. It verifies the connection before returning, readsZELOS_AGENT_URLwhen given no argument, and works as a context manager. Read more.SignalFrame—agent.query(paths, start=…)returns a frame that is one row per distinct timestamp, one column per signal, and null wherever a signal had no sample.ffill(),dropna(),between(),resample(),head(),rename(),short_names()anddescribe()operate on it directly. Read more.SignalSeriescarries its unit through arithmetic.voltage * currentarrives asW,.integrate()over time givesJ, andpower / currentcancels back toV. Adding mismatched units raises instead of lying, and reductions return aNamedScalarthat prints3.629 V.plot()on a frame or a series emits Vega-Lite. It renders inline in the app, offline in an exported HTML page, and in any Jupyter viewer — with nothing added todependencies.- One glob grammar.
*and?expand against the catalog everywhere a path is accepted:match(),query(),latest(),at(),window()andexport(). - One time grammar. The sign tells a time from a duration:
"-30s"is a point on the clock,"30s"is a length. ISO 8601 strings,datetimeandtimedeltaare accepted wherever they fit. agent.check.that(lhs, op, rhs)reports a verdict instead of raising, so a suite always runs to completion. Every result carries its evidence — the first violating sample on a failure, the closest approach on a pass — with a timestamp.agent.check.count()measures without judging. Read more.CheckResults.raise_if_failed()raisesAssertionErrorlisting every check that did not pass, each with its predicate, window and evidence. For a single check,assert agent.check.that(...)— a result is truthy when it passed.agent.window()returns aReplayWindow— the opening snapshot plus one entry per change — for states and events, where a query would return thousands of rows repeating one string.agent.watch()streams live values on an interval, with a deadline.agent.export()saves a window to a.trzfile, and.open()re-reads it with the same calls you used against the agent.- Everything renders itself.
Agent,SignalCatalog,SignalFrame,SignalSeries,Snapshot,ReplayWindow,TraceandCheckResultall print a useful summary and render as a rich table in a notebook.to_pandas()is for handing data to pandas, not for looking at it.
Changed¶
- A multi-signal frame is one row per timestamp, not one row per message table. Cells are null where a signal had no sample; nothing is interpolated on the way in.
- A bare
intpassed where a time belongs raises below 1015 instead of being read as an epoch in nanoseconds. A number that small is nearly always seconds by mistake — write"-30s". - A naive
datetimeis accepted and read as UTC instead of being rejected. - Wildcards in
query()expand against the query window rather than a fixed 60-second catalog, so a glob over a long window matches what the window actually contains. latest()takes a wildcard.agent.latest("bus0/BMS_message/cells.*")returns aSnapshotof every match; one literal path still returns a singleLatestValue.Trace.latest()/Trace.at()and theTraceSetpair return the live shapes — aLatestValuefor one literal path, aSnapshototherwise — andReplayWindow.snapshotis aSnapshotrather than a list.TraceSet.query()on offset bounds puts the runs on one grid. Every sample is numbered by how many sample periods into its own run it sits, and the runs join on that number at the coarsest run's rate, so two runs recorded at different sub-second phases share rows instead of leaving each other's columns null. Only the edge of the window can leave a row unshared, when it holds one more sample of one run than of the other.to_pandas()on such a frame indexes by offset, not by a 1970 date.Trace.signals()andTraceSet.signals()come back sorted by path, and so do the columns of aTrace.query()frame.- Relative times on a file anchor to the file's own span rather than to wall-clock now.
where()masks out values as nulls instead ofNaN.- Mixing a series with a pandas or numpy object raises instead of silently producing garbage. Convert explicitly with
to_pandas(). count()returns aCheckResultwhose.countisNoneon error, instead of0— a failed measurement no longer reads as a real zero.- A literal-vs-literal type mismatch in a check raises when the check is built, instead of producing an error row at evaluation.
to_pandas()returns a timezone-aware UTCDatetimeIndex. Passindex=Falsefortimeas an ordinary column.producers=onquery(),latest(),at()andwindow()defaults to every connected producer instead of localhost only. Oncheck.that()/check.count()it stays the local store; a check reports one verdict per target.- A trace duration check (
temporal="for_duration"/"within_duration") anchors at the end of the recording — its last N seconds — instead of the start. trace.checkacceptslookback=for signature parity withagent.checkand ignores it.- Trace checks no longer emit
zelos.check.result.v1events. std()usesddof=1— the sample standard deviation, matching pandas.median()is exact instead of approximate.- An enum value compares equal to its wire string:
DataType.Int32 == "int32". - A derived series names itself.
voltage * currentisvoltage × current, and÷,+,−follow; a chart legend never readsnull. - A
NamedScalarprints as a measurement: four significant digits and the unit (3.629 V), withf"{peak:.2f}"keeping the unit too.float(peak)is still the exact value. ExportResultandTraceSet.series()render themselves — one row per producer, one column per run.from zelos_sdk import *binds the agentTimeRange.- Every repr shares one time and number format — UTC to the millisecond, four significant digits, the unit after the value — and a check result renders as a checkerboard row: when it happened, the rule with the measured value in it, the window, the verdict.
window(duration=…)with a plain number means seconds, not nanoseconds.TraceSet.time_rangeis aTimeRange.watch()yields aSnapshot— aMappingthat renders itself — instead of a plain dict.- A cell that raises
AssertionErrorfails the notebook run (exit code1); any other exception errors it. --paramnames must be ASCII Python identifiers — no keywords and no dunders — so a parameter is always usable asparams.<name>in a cell. A bad name is refused before the run starts.- Notebook front matter no longer gains an empty
dependencies:list when the notebook declares none. - Core dependencies shrank to
jsonschemaandpyarrow.pytest,richandcoloramaare no longer installed by default;pip install "zelos-sdk[test]"restores pytest and rich, and[notebook]adds the analysis stack (pandas,numpy).
Deprecated¶
Each of these still works and raises one DeprecationWarning naming its replacement. Nothing is removed.
| Old | New |
|---|---|
Agent.connect() |
zelos_sdk.connect(target, timeout=…) |
Agent.health_check() |
Agent.health() |
Agent.resolve_paths() |
agent.signals().match(pattern) |
SignalCatalog.by_path(path) |
catalog[path] |
SignalCatalog.to_list() |
list(catalog) |
SignalSeries.derive() |
SignalSeries.from_arrow(values, name=…, unit=…) |
SignalSeries.get() |
SignalSeries.to_pandas() |
SignalSeries.time_arrow() |
the SignalSeries.time attribute |
sort_order= |
sort="asc" / sort="desc" |
relative_start= / relative_end= |
start="+30s" / end="+30s" |
time_mode= |
nothing — the bounds pick the axis |
export(paths=…) |
export(signals=…) |
lookback= on query() |
nothing — wildcards resolve against the query window |
Kept without a warning: the [analysis] extra is an alias of [notebook];
TraceSet.traces and TraceSet.max_duration remain as properties beside the new
TraceSet.time_range; and every alphabetic and
natural-language operator spelling (gt, is greater than, is not equal to,
in, …) still parses to the same canonical operator as its symbol.
Fixed¶
integrate()andderivative()refuse a series with nulls instead of guessing across a gap, and nameffill()/dropna()as the fix.
Upgrade notes¶
Three one-line fixes cover almost every migration:
# 1. to_pandas() already indexes by time.
frame.to_pandas().set_index("time") # before
frame.to_pandas() # after — or to_pandas(index=False) to keep the column
# 2. Look a signal up by path with an index.
catalog.by_path("bus0/BMS_message/status.pack_current") # before
catalog["bus0/BMS_message/status.pack_current"] # after
# 3. A relative time is a signed string, not a number.
agent.query(paths, start=-30) # before
agent.query(paths, start="-30s") # after
If you combine columns from different messages, add .ffill().dropna() — a frame is joined on time and sparse by construction, and integrate() / derivative() refuse a series with nulls rather than guessing across a gap.
0.0.10
Added¶
zelos_sdk.agent): Connect to a running Zelos Agent from Python and query live or recorded data through one handle — browse the signal catalog, query and downsample time-series into Arrow/pandas, read latest values, watch for live updates, run actions, manage extensions, and open .trz trace files. Read more.agent.layouts CRUD (list/show/create/update/delete) plus full version history — list a layout's versions, restore a previous version, or label one. Read more.agent.check.that(lhs, op, rhs) asserts a predicate against a live signal or .trz trace, with temporal quantifiers such as always/eventually evaluated server-side; agent.check.suite(...) runs a JSON suite of checks in one round-trip. Read more.zelos_sdk.schemas.Log — a predefined schema for typed log events (zelos.log.v1); pass a schema class directly to add_event(name, schema) instead of a field list. Read more.TraceSource.log_batch() — log a pyarrow.RecordBatch or Table directly for zero-copy, high-throughput ingestion.TraceSource.log_many() — log a list of (time_ns, event_name, data) tuples in a single call, cutting Python↔Rust overhead for high-frequency sources like CAN decoders.TraceSource(name, strict=True) — opt into strict type coercion; rejects lossy float→int narrowing instead of silently truncating it.TraceNamespace.drain() — flush every source and block until all queued events reach subscribers, for deterministic teardown ahead of closing a TraceWriter.Changed¶
ActionExecuteResult (value + status) with PASS/FAIL/ERROR/DONE states instead of a bare value; the old ActionResult/ExecuteStatus names remain as deprecated aliases.@action declaration order end-to-end instead of being alphabetized, so generated forms render fields in the order they were declared.Fixed¶
SignalFrame now resolves columns correctly when the same signal name appears across multiple producers or segments, raising AmbiguousSignal on a genuine tie instead of matching the wrong column.TraceReader no longer drops a trace's last row when its timestamp has sub-microsecond precision.TraceWriter now captures every event logged before its with block exits, without needing a sleep before close to avoid losing in-flight data.TraceSourceCache now stores a Python None as a null value instead of raising an error.
0.0.9
Added¶
FolderPickerWidget for Actions, enabling folder selection in extension UIspyarrow as a direct dependency — no longer needs to be installed separately for TraceReaderFixed¶
None instead of causing serialization errors
0.0.8
Added¶
.trz trace files for offline analysis, debugging, and post-processing. Read more.
0.0.6
Added¶
field_type, enabling richer, type-aware
rendering in the Zelos App without custom widgets.required=True, surfacing missing inputs during
validation instead of at execution time.Improved¶
0.0.5
Added¶
object.Changed¶
setuptools dependency.Fixed¶
TraceSegmentStart message was missed.TracePublishClient.