Panel SDK: window.scistudio
Stability:
provisional· Panel API version:1.0· SDK path:sdk/1/
The panel SDK is one dependency-free script that defines window.scistudio,
the only way a panel page talks to SciStudio. Load it from the SDK major the
panel's api_version names, before the page's own code:
<script src="../../sdk/1/scistudio-panel.js"></script>
Await scistudio.ready() first. Every operation returns a promise. Which
operations exist depends on the context the host opened the page in (see
the context table below): an operation the context does not provide is
absent from window.scistudio, so test for it rather than calling it.
Opened directly (not inside a SciStudio frame), the SDK runs in sample
mode: it reads panel.sample.json beside the page and answers from it, so a
page can be checked without a running host.
Contexts
What window.scistudio offers depends on the context. Operations and services a context does not provide are absent.
| Context | Operations | Services |
|---|---|---|
preview |
read |
open, save |
interactive |
writeBack |
save |
miniapp |
read, call (with panel.py), submitAnswers |
save |
Lifecycle
scistudio.ready()
Wait for the host to initialise the frame and tell it the page is
ready. Call it before anything else; other operations reject with
not_ready until it resolves. In sample mode it resolves once
panel.sample.json has loaded.
Returns: Promise<object> — window.scistudio, with its context properties set.
scistudio.onDispose(callback)
Release what the page holds when the host closes it. By then pending
operations have rejected with disposed and artifact URLs are revoked.
| Parameter | Type | Description |
|---|---|---|
callback |
function |
Runs once when the host disposes the panel. |
Returns: function — Call it to unsubscribe.
scistudio.reportError(message)
Show an error in the host's panel diagnostics. Uncaught errors and unhandled rejections are reported automatically. A message reported before the host initialises the frame is sent once it does.
| Parameter | Type | Description |
|---|---|---|
message |
string |
What went wrong. |
Returns: Promise<null>
Context properties
scistudio.context
Type: "preview" | "interactive" | "miniapp"
The context the host opened this page in. Also published on the root
element as data-panel-context, so a stylesheet can tell a preview frame
(whose height the host sets) from an interactive window (which sizes
itself to the panel).
scistudio.input
Type: object
What the host opened the context with. In preview and miniapp it
carries ref, the target that read uses when no params.ref is given.
scistudio.viewState
Type: any
The view state last stored with setViewState for this view, or
undefined when none was stored.
scistudio.apiVersion
Type: string
The MAJOR.MINOR panel API version the host serves.
scistudio.basePath
Type: string
The host's URL base path; empty in sample mode.
scistudio.libBaseUrl
Type: string
Base URL of the pinned shared libraries (see the library table below).
Pass it to components that load a library on demand, such as PlotView
for PDF figures.
View state and theme
scistudio.theme
Type: object
The current theme, {mode: "light" | "dark", tokens: {"--ss-*": value}}.
Kept current by the SDK; use onTheme to be told when it changes.
scistudio.setViewState(state)
Store view state (a zoom level, a selected tab) that the host passes
back as viewState the next time this view opens. Updates
scistudio.viewState immediately.
| Parameter | Type | Description |
|---|---|---|
state |
any |
JSON-safe state to keep for this view. |
Returns: Promise<null>
scistudio.onTheme(callback)
Follow the application's theme. The callback runs at once when a theme
is known and again on every change. The SDK has already applied the
--ss-* tokens to the root element and set its data-theme attribute
to light or dark, so a page styled with panel.css needs no
callback.
| Parameter | Type | Description |
|---|---|---|
callback |
function |
Receives the theme {mode, tokens}. |
Returns: function — Call it to unsubscribe.
Data
scistudio.read(op, params)
Contexts: preview, miniapp
Read a bounded part of a target. The host checks that the target is reachable from this context before reading.
An artifact.file result whose bytes the host transferred gains a
url (a blob: URL) that the SDK revokes on dispose or on the next
artifact.file read of the same target.
In sample mode the answer comes from the sample's reads map: first
the key JSON.stringify({ref, op, params}), then the key op.
| Parameter | Type | Description |
|---|---|---|
op |
string |
One of the read operations listed below. |
params (optional) |
object |
The operation's parameters. params.ref reads a different authorised target than input.ref, such as a collection item or composite slot. |
Returns: Promise<object> — The operation's result.
scistudio.open(ref)
Contexts: preview
Open a child target in the host's own preview of it. The host checks that the child belongs to the previewed target. Not available in sample mode.
| Parameter | Type | Description |
|---|---|---|
ref |
string |
A child of the previewed target: a collection item or composite slot ref returned by a read. |
Returns: Promise<any>
Decisions
scistudio.writeBack(value)
Contexts: interactive
Submit the decision the interactive block is waiting for. A decision is
submitted once; a second call rejects with already_used. In sample
mode it resolves with value.
| Parameter | Type | Description |
|---|---|---|
value |
object |
The decision, a JSON-safe object in the shape the block expects. |
Returns: Promise<any>
scistudio.cancel()
Contexts: interactive
Withdraw without deciding. The window around the frame already offers Cancel, so a panel does not draw its own; call this to withdraw from code. Pressing Escape inside the frame calls it.
Returns: Promise<null>
Python
scistudio.call(fn, args)
Contexts: miniapp
Call a function in the MiniApp's Python process. Present only when the
panel directory has a panel.py. A function that raised rejects with an
Error whose code is the exception type and whose traceback is the
Python traceback.
In sample mode the answer comes from the sample's calls map: first
the key JSON.stringify({fn, args}), then the key fn.
| Parameter | Type | Description |
|---|---|---|
fn |
string |
Name of a function defined in the panel's panel.py. |
args (optional) |
object |
Keyword arguments, a JSON-safe object. |
Returns: Promise<any> — The function's JSON-safe return value.
Questionnaire
scistudio.submitAnswers(answers)
Contexts: miniapp
Submit the MiniApp's questionnaire. The host checks the answers against
questionnaire.json, writes them to answers.json in the MiniApp's
folder (replacing an earlier submit), and, when the agent session that
is building this MiniApp is still open in SciStudio, types one line into
it saying the answers are ready; notified is then true. Otherwise
notified is false, reason is no_session, and message asks the
user to go back to their AI chat. Answers that do not fit the
questionnaire reject with invalid_answers. The Questionnaire
component calls this for you when given it as onSubmit.
In sample mode nothing is saved: it resolves with saved: false,
notified: false, and reason: "sample_mode".
| Parameter | Type | Description |
|---|---|---|
answers |
object |
One answer per question id: {status: "answered", value, other?}, {status: "decide_for_me"}, or {status: "skipped"}. A question left out counts as skipped. |
Returns: Promise<object> — {saved, path, submitted_at, notified, reason, message}.
Services
scistudio.save(value)
Save a file for the user through the host. An ArrayBuffer in
value.data is transferred, not copied. Not available in sample mode.
| Parameter | Type | Description |
|---|---|---|
value |
object |
{name, mime, data}: a file name, a MIME type, and the content as a string, ArrayBuffer, or typed array. |
Returns: Promise<object> — The host's report of where the file went.
Read operations
scistudio.read(op, params) accepts these operations. A parameter not listed is refused with invalid_request. Every operation also accepts format: "json" (the default) or "binary" for the array and series reads.
| Operation | Target | Parameters | Result |
|---|---|---|---|
metadata |
any target | ignored | {type_chain, metadata, shape, dtype} recorded for the target. |
composite.slots |
a composite | cursor, limit |
One page {slots: [{name, type_name, ref}], count, next_cursor, truncated, complete}; each slot ref can be read or opened. Pass the returned cursor to continue; complete is true on the last page. |
collection.items |
a collection | cursor, limit |
One page {items: [{ref, type_name, kind, display_name}], count, next_cursor, truncated, complete}; pass the returned cursor to continue. truncated means more pages remain. |
table.page |
a data object with a table | page, page_size, sort_by, sort_dir |
{columns, rows, total, total_rows, page, page_size, total_pages, sort: {by, direction}, complete}. Paging is navigation over complete data. |
table.xy |
a data object with a table | x_column, y_column, offset, limit |
One page of rows {x, y, columns, x_column, y_column, offset, next_offset, total, nonnumeric, truncated, complete} for two columns: x[i] and y[i] are the exact values of source row offset + i, a non-finite or missing value in place as "NaN"/"Infinity"/"-Infinity". limit is at most 100000; continue from next_offset until it is null. |
array.plane |
an array | slice_index, axis_indices |
The selected plane's geometry {source_shape, source_dtype, axes, slice_axes, height, width, tile_size, vmin, vmax, complete} (vmin/vmax over every cell). values holds the whole plane when it fits one read (complete true); otherwise values is empty and the plane's exact values are read with array.tile windows of at most tile_size per side. |
array.tile |
an array | slice_index, axis_indices, y0, x0, height, width |
The exact values of one window {values, y0, x0, height, width, truncated, complete} of the selected plane; truncated means the window was larger than one read and was cut at the tile size. |
series.points |
a series | offset, limit |
One page of points {index, values, offset, next_offset, total, nonnumeric, truncated, complete}: index[i] and values[i] are the exact x and y of source row offset + i, a non-finite or missing value in place as "NaN"/"Infinity"/"-Infinity". limit is at most 100000; continue from next_offset until it is null. |
text.chunk |
a text object | offset, length |
{text, content, offset, next_offset, total_bytes, encoding, truncated, complete}; continue from next_offset until it is null. |
artifact.info |
an artifact | none | {name, path, mime_type, size}, plus formats for a plot. |
artifact.file |
an artifact | variant |
artifact.info plus a url the page can load; variant selects one of a plot's formats. |
Errors
A rejected promise carries an Error whose code names the failure. The
host adds its own codes for refused requests (for example
invalid_request, unsupported, unauthorized_ref, read_budget,
invalid_answers, no_questionnaire); a
failed call uses the Python exception's type name as its code.
| Code | Meaning |
|---|---|
disposed |
The host disposed the panel; pending operations reject with this. |
not_ready |
An operation was attempted before the host initialised the frame. |
timeout |
The host did not answer within 60 seconds. |
not_found |
Sample mode has no reads or calls entry for the request. |
unsupported |
Sample mode cannot perform the request (no host save or open), or the sample's context is not a panel context. |
already_used |
writeBack was already called once for this decision. |
invalid_request |
call was given no function name, or submitAnswers was given something other than an object. |
sample_missing |
Sample mode could not load panel.sample.json. |
Shared libraries
Pinned third-party libraries served beside the SDK. Import them by relative path from the panel page (../../lib/<name>@<version>/<file>) or from scistudio.libBaseUrl.
| Library | Version | Files |
|---|---|---|
| d3 | 7.9.0 |
d3@7.9.0/dist/d3.min.js |
| lucide | 1.45.0 |
lucide@1.45.0/dist/lucide.min.js |
| pdfjs | 5.4.149 |
pdfjs@5.4.149/build/pdf.min.mjs, pdfjs@5.4.149/build/pdf.worker.min.mjs |
| plotly | 2.35.3 |
plotly@2.35.3/dist/plotly.min.js |
| preact-htm | 3.1.1 |
preact-htm@3.1.1/dist/preact-standalone.module.js |
| three | 0.180.0 |
three@0.180.0/build/three.module.min.js, three@0.180.0/build/three.core.min.js |
Sample mode
Opened outside a SciStudio frame, the SDK answers from panel.sample.json; its shape is in the panel descriptor reference.