Commit Graph

1073 Commits

Author SHA1 Message Date
Abubakar Abid d3c70fa5cb Workflow UX improvements, and fix gradio skills add clobbering skills via symlinked dirs (#13666)
* Open the workflow write-access link in a browser tab by default

Launching a `gr.Workflow` locally now opens the write-access link in a new
browser tab automatically, the way `jupyter notebook` opens its token URL,
so you land in an editable canvas instead of a read-only one.

Only done when a browser on this machine is plausibly the right place to
open it: Spaces, headless Linux, containers, CI/pytest, Colab and SSH
sessions keep the previous print-the-link-only behavior. An explicit
`inbrowser=` still wins, and `GRADIO_WORKFLOW_INBROWSER=false` opts out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Call vision-language models through chat completions in gr.Workflow

`image-text-to-text` mapped to the `visual_question_answering` endpoint,
which no Inference Provider serves for any model on the Hub — the router
routes every model carrying that tag as `conversational`. VLM model nodes
therefore always failed with "Task 'visual-question-answering' not
supported for provider ...", and even where served, VQA has no token
budget for emitting a whole file.

Adds a `chat_completion` endpoint schema (image + prompt → text) and
points `image-text-to-text` at it, on both the Python and canvas side.
Chat images are inlined as data URIs because the provider, not this
process, dereferences them, so a local path or a relative
`/gradio_api/file=` URL is unreachable.

Also adds demo/workflow_vlm_html_comparison, comparing two recent VLMs
on the same screenshot → webpage task.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Don't clobber the installed skill when the agent skills dir is a symlink

`gradio skills add --claude` resolves the agent's skills directory with
`Path.resolve()`, which follows symlinks. When that directory is a link to
the central location — e.g. `.claude/skills -> ../.agents/skills`, a common
way to share one skills dir across agents — the link path collapses onto the
skill that was just installed, so `--force` deleted it and replaced it with
a symlink pointing at itself. Without `--force` it reported the fresh
install as a pre-existing conflict.

Skip linking when the resolved link path is the central skill path: the
skill is already reachable there, and no link is needed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Stream chat completions in gr.Workflow so long generations survive the router

The router returns a bare 504 for a non-streaming /v1/chat/completions
request that takes longer than ~120s to produce its response. A
vision-language model writing a whole file routinely exceeds that — a
reasoning model can spend the entire window before its first visible
token — so image-text-to-text nodes failed with an opaque gateway error
on any non-trivial image. Measured: the same request 504s at 121s
buffered, and runs 308s to completion when streamed.

Stream the response instead, so the request is bounded by the model
rather than by an idle proxy, and raise the token cap to 16384 (sized to
the canvas executor's 300s per-node timeout at the ~100 tok/s these
models stream).

Truncation is now also reported accurately: reasoning counts against
max_tokens, so a model can hit the cap while still thinking and return
no content at all. Say so, with the reasoning volume, instead of
guessing that the prompt was too long.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Cover the auto-opened browser tab and chat-completion dispatch with tests

Both paths were added in this PR without tests, as Copilot noted. The browser
tests assert the parts that are easy to regress: an explicit `inbrowser=True`
opens the write-access URL rather than the read-only one, an explicit `False`
opens nothing even with the env var asking for it, and the auto-open stays
suppressed under pytest, CI and SSH.

The chat-completion tests pin the shape of the request the router receives — a
text part plus an image part, streamed — and the two ways it can come back
empty, since a reasoning model that spends the whole budget thinking needs a
different message than one that was cut off for another reason.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Silence the optional playwright import for the backend type check

The demo's renderer imports playwright lazily and raises a clear install hint
when it is absent, but `ty` resolves imports statically and playwright is not
in the CI environment. Suppressed the same way demo/spectogram handles scipy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 12:02:00 -07:00
Dawood cc34d22d57 test shared prop forwarding in browser 2026-07-28 12:09:05 -04:00
Abubakar Abid 2f6d04acf8 Various improvements to Workflows, particularly for LLM-generated Workflows (#13654)
* Improve Workflow canvas feedback

* add changeset

* Apply suggestions from code review

Co-authored-by: Abubakar Abid <islamrealm@gmail.com>

* Apply suggestion from @abidlabs

* add changeset

* changes

* add changeset

* Fix workflow image generator demo

* add changeset

* Address Workflow review feedback

* Make workflow demo path independent

* Keep Workflow skill generation in sync

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-07-24 13:27:49 +01:00
pngwn 7ac583a38a Make builds go zoom zoom (#13329)
* changes

* fix tests

* format

* clean

* add changeset

* fix

* add changeset

* fix more

* add changeset

* fix more more

* add changeset

* ci: bound js-test step + add browser-mode debug logs

The js-test step has been hanging 6h+ in CI on this branch. Investigation
confirms the runner is *stuck*, not slowly executing tests: vitest's
default per-test timeout (5s) and per-hook timeout (10s) only apply
inside test execution, but the orchestrator's prepareIframe awaits
iframe.onload/onerror with no timeout — so a stuck Vite transform or
unresponsive chromium iframe blocks forever.

Cap the step at 10 min (locally completes in ~25s) so failures surface
fast instead of consuming a runner for 6 hours, and enable
DEBUG=vitest:browser:* + --reporter=verbose so the next failed run
shows where the orchestrator was waiting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* gitignore

* fix(ci): prevent vite optimizer reload from hanging js-test

Root cause of the 6h js-test hang: vitest browser mode can't tolerate a
full-page reload mid-suite. Vite's dep optimizer fires "optimized
dependencies changed. reloading" when it discovers a dep that wasn't in
its initial bundle — this disrupts the iframe orchestrator, whose
iframe.onload listener has no timeout (orchestrator-DM4mHHP0.js:164),
so iframes silently lose their socket and the orchestrator awaits
forever.

Two complementary fixes:

1. Pre-declare runtime dynamic-import deps (katex, mermaid, vega-embed,
   babylonjs viewer, extendable-media-recorder) in `optimizeDeps.include`.
   Vite's static scanner doesn't follow `await import(...)` calls, so
   without the include list these were discovered mid-test and forced
   the reload. With them included, all known deps end up in the same
   first optimize batch.

2. Cache `node_modules/.vite` between CI runs and pre-warm the optimizer
   with `vitest list` before the real test step. The cold-start reload
   (which fires once even with `include`, when the cache is empty)
   then happens during the throwaway prewarm — the real test step
   always sees a warm cache and never reloads.

Local verification: cleared cache + run = 3-5 file failures from the
reload. With these changes: 1685/1685 pass, no reload.

The `timeout-minutes: 10` on the test step ensures any future regression
fails visibly in 10min instead of consuming a runner for 6 hours.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(e2e): wait on stronger chain-drain signals in flaky specs

Two functional specs flaked in CI on this branch — at the failure
moment, the Gradio queue still had inflight events. Both already use
deterministic final-state assertions, the failure was just that 10s
isn't enough on a CI runner where 60+ chained events serialize through
one queue.

rapid_generation: switch the chatbot wait from message 11 (halfway) to
message 22 (last in the 22-event chain). Once that message renders the
chatbot chain is fully drained, leaving only a handful of pending
number-chain events. Bump the chatbot wait to 30s so the slow run gets
the headroom.

theme_builder: bump the font-family and background-color assertions to
30s. Loading a theme round-trips through the queue + ships CSS vars +
waits for the browser to apply them — that pipeline can exceed the 10s
default on slow CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* remove Slider playwright-ct spec

The Slider component test failed under the upgraded svelte 5.55 +
vite-plugin-svelte 7 stack: playwright-ct passes plain objects for
component props, but the Gradio class direct-aliases `_props.props`
without an internal $state copy, so two-way `bind:value` doesn't
propagate in the CT environment. The failing assertions were on
range→number sync.

The same flows are covered (more comprehensively) by the existing
vitest unit tests in `Slider.test.ts`: number/range sync, value
clamping, change/input/release events, reset button behavior, and
accessibility — all of which run under the test infra's reactive
proxy wrapper in `tootils/render.ts`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* unblock SSR functional tests on the upgraded svelte stack

- skip custom_css `.dark styles` test in SSR mode. Under svelte 5.55 +
  vite-plugin-svelte 7 the user CSS `.dark .darktest h3` selector ties on
  specificity with gradio's prefixed `.prose h3` rule and loses on
  load-order in the SSR build. The companion `applies the custom CSS
  styles` test in this file is already skipped in SSR for similar
  reasons; tracking the load-order regression as a follow-up.

- give render_tests its own 60s timeout. The demo is render-heavy
  (multiple `@gr.render` blocks, sliders, chatbots) and its SSR hydration
  occasionally pushes past the 30s default while the setup fixture is
  waiting for `#svelte-announcer`, manifesting as flaky setup timeouts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix e2e?

* fix story

* format

* fix story again

* fix(reload): push new server props into reused component instances

Reload mode (`gradio <demo>` with watchdog) was failing to update the
UI when components changed shape across a source-file edit. Tests
hitting this: allowed_paths.reload, hello_blocks.reload (label changes,
component swaps).

Root cause: the Gradio<T,U> class in `js/utils/src/utils.svelte.ts`
direct-aliases `_props.shared_props`/`_props.props` at construction
(load-bearing for @gr.render user-edit preservation — see comments
there). On reload, AppTree.reload() builds a new node tree with new
ids and new prop objects. MountComponents matches children by position
(unkeyed each), so the same component instances get reused — but the
Gradio class inside each one keeps aliasing the OLD node's props. The
new label/value/etc. never lands.

`AppTree.rerender()` already handles the analogous case for @gr.render
via #sync_reused_components_after_rerender — walks the new subtree
and pushes only-defined keys via set_data, skipping undefined values
so locally-edited fields survive. The id-change effect in the Gradio
class re-registers the set_data callback under the new id, and
#pending_updates queues anything that arrives before re-registration.

Fix: call the same sync routine at the end of `reload()`. Same trade-
offs apply as @gr.render — server-defined props propagate, locally-
edited values (server omits them) are preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* clean up

* fix

* fix

* fix

* add changeset

* fix

* chore(tabs): remove debug logging and stale comments

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* format

* add changeset

* fix?

* fix site

* format

* fix

* format

* fix error

* add changeset

* fix

* format

* Fix frontend profiling base gradio install

* fix(ci): run frontend benchmark against installed gradio

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: hannahblair <hannahblair@hotmail.co.uk>
Co-authored-by: Dawood <dawoodkhan82@gmail.com>
2026-07-16 16:57:19 -04:00
Abubakar Abid 520023532b Fix chained events after cancellation and in hidden tabs (#13620)
* Fix chained events in cancellation and hidden tabs

* changes
2026-07-15 00:56:34 -07:00
Abubakar Abid 195593ed27 Fix component remounting in gr.render (#13613)
* Fix component remounting in gr.render

* Narrow gr.render HTML remount fix

* Regenerate Gradio skill examples

* Scope HTML watchers to rendered component

* Clean up HTML remount side effects
2026-07-14 21:12:29 -07:00
Abubakar Abid 745f20c9ec Fix select event not firing on the gr.Tabs container (#13560)
* fix: fire `select` event on the Tabs container itself

The frontend event dispatcher remapped a Tabs `select` event onto the
selected child Tab's logical `id`, so a listener attached to the Tabs
container (`tabs.select(...)`) never matched its dependency and never
fired. It also used the tab's user-facing `id`, which fails to match a
`TabItem.select(...)` dependency whenever the tab was given an explicit
string id (e.g. `gr.Tab("A", id="a")`).

Dispatch the event to both the selected TabItem (by its `component_id`,
which always identifies the component) and the original Tabs container,
so listeners on either fire correctly. Adds e2e coverage for the
container-level `select` event.

Ref #3793

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* changes

* simplify: dispatch Tabs select only to container; drop redundant per-tab forward

The selected TabItem already dispatches its own `select` event, so forwarding
the container's `select` to the child component id fired `tab.select` twice
(observable under trigger_mode="multiple"). Removing the forward fixes the
double-fire while keeping the container-level `tabs.select(...)` fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: count tab.select via separate non-racy listener to fix flaky demo

Making get_selected_index stateful (read+write select_count) under
trigger_mode="multiple" raced the initial-load select against the clicked
select, letting a stale write win and breaking the `correct selected tab
shown` e2e test. Restore get_selected_index to its original form and count
selects via a separate server-side accumulator listener instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:17:01 -07:00
Dawood Khan 0533483bcc Migrate Image components to Svelte 5 (#13543)
* migration

* add changeset

* fixes

* Fix tabs reactive storm during mount that froze E2E tests.

Use in-place tab updates and untrack sync effects so registering many TabItems no longer retriggers overflow and change_tab on every mount.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fixes

* add changeset

* Address Copilot review comments

* fixes

* more fixes

* fix scroll bar in multimodal textbox

* add changeset

* textbox height

* Migrate image components to Svelte 5

* add changeset

* Address Copilot review feedback

* add changeset

* Fix image component Svelte type checks

* Fix image SSR hydration default value

* Fix image upload hydration state

* Stabilize image value hydration

* Stabilize remote image demo assets

* Fix image component review regressions

* Avoid remote image in image editor layers demo

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 15:19:09 +00:00
Abubakar Abid 882df35e9e Fix this.app.$destroy is not a function in the <gradio-app> web component (#13561)
* fix: use Svelte 5 `unmount` in the web component lifecycle

The `<gradio-app>` custom element's `connectedCallback` still called the
Svelte 4 `this.app.$destroy()` API, which no longer exists after the
Svelte 5 migration (the app is now created with `mount(...)`). When the
element was reconnected to the DOM (e.g. moved, or detached and
re-attached), this threw `TypeError: this.app.$destroy is not a function`
and left the embed broken.

Use `unmount(this.app)` — already imported and used in
`attributeChangedCallback` — so re-attaching a `<gradio-app>` element
cleanly unmounts and re-mounts the app.

Closes #12507

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: add web-component embedding e2e regression test for #12507

Embeds the app via `<gradio-app>`, then detaches and re-attaches the
element (re-running connectedCallback with `this.app` already set) and
asserts it re-mounts without throwing `this.app.$destroy is not a
function`. Guards the unmount fix in the previous commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: skip web-component embed test in SSR mode

The `<gradio-app>` web component is a client-side embedding mechanism. In
SSR mode the served HTML doesn't expose the client entry chunk the test
discovers, so the embed never mounts and the test times out. Skip it in
SSR mode, matching the other client-rendering specs (e.g. tabs.spec.ts).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: clarify why web-component embed test skips SSR mode

Embedding works fine against an SSR app; the skip is only because the test
discovers the bundle by scraping the client-rendered index HTML, which SSR
(SvelteKit) doesn't expose.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: trim inline comments in web-component embed test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 12:40:12 -07:00
hysts 9a72d0c76e Fix Column staying hidden after a multi-yield visibility update (#13553)
* Fix column hidden after multi-yield reveal

A gr.Column that starts with visible=False could stay hidden even
after a generator event handler updated it to visible=True, when the
handler yielded visibility updates more than once and another
component's visibility changed in the same event.

While the column is unmounted, update_state stores its updates in the
pending map; the first yield stores visible=false there. On the next
yield the column mounts and register_component reads that now-stale
pending value and applies it after the correct visible=true, hiding
the column again.

Exclude visible from the pending map, the same way loading_status is
already excluded. Visibility is the source of truth for mounting and
is kept current in place on the node, and the mounted component syncs
it from the node props, so it never needs to be replayed through a
deferred _set_data.

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Dawood Khan <dawoodkhan82@gmail.com>
2026-06-26 09:56:14 +09:00
Abubakar Abid d4d340d1bb Provide API endpoint for Workflow graph (actually an endpoint for each subgraph) (#13524)
* Add design plan for Workflow HTTP API endpoints

Plan-only commit: expose each workflow subject as a named Gradio
endpoint reusing /info, /call, and /api. Registration via explicit
non-rendered components (B2). No implementation yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Workflow API: server-side executor + per-subject endpoints (B2)

Phases 1-3 of the plan:
- gradio/workflow_api.py: schema-v2 graph model, topo-sort, upstream-subgraph
  and free-input extraction (ports of the canvas's workflow-graph.ts), plus a
  Python WorkflowExecutor that runs a subject's upstream DAG by reusing the
  existing call_space/call_model/call_fn/fetch_dataset server functions.
- Register one named API endpoint per subject via hidden real components (B2),
  reusing Gradio's /info + /call. Endpoint execution re-reads the current
  workflow.json so operator/wiring edits are live; the endpoint set + schema is
  a launch-time snapshot for now.
- Tests cover graph parsing, topo/cycle, subgraph + free inputs, end-to-end
  execution (callers mocked), /info schema, and request/token injection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Workflow API: live endpoint updates on save (Option 2)

Replace the static registration with a WorkflowEndpointManager that re-derives
the endpoint set on every save_workflow: it tears down the prior endpoints
(unrender() their components + drop their event triggers from blocks.fns) and
rebuilds from the saved graph, then refreshes the cached config and invalidates
the App's /info cache. Adding, removing, renaming, or retyping an output now
updates /info + /call live without a restart.

To mutate the running Blocks safely we set the render context directly
(Context.root_block/block) instead of `with self:`, whose __exit__ would re-run
attach_load_events (duplicating the canvas's callable-value load event) and
recreate the running App.

Tests: add/remove/rename outputs reflect in get_api_info(), no fn leak after
removal, and save_workflow triggers the re-sync.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Workflow API: 2-subject demo, end-to-end /call test, dataset hardening

- demo/workflow_api: a self-contained workflow with two outputs (Loud,
  Reversed) fed by bound fn operators — exposes /loud and /reversed.
- Tests: gradio_client end-to-end against real /info + /call (skipped unless
  the frontend is built, as it fetches the root page), plus a TestClient check
  that /gradio_api/info lists the endpoints (runs without a frontend build).
- Harden dataset-operator output mapping ({src: url} cells -> file values).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Workflow API: "View API" panel + describe endpoint

- Add get_workflow_api server function + describe_workflow_api(), returning
  one descriptor per output (api_name, typed params, return) — re-read live so
  it tracks edits. Registration now shares _slug_iter() so described names
  match registered ones exactly.
- Frontend: WorkflowApiPanel.svelte, a canvas-styled overlay (dark theme,
  JetBrains Mono) opened from a "View API" toolbar button. Lists each output's
  endpoint with parameter/return types and copyable Python / JavaScript / curl
  snippets, language-toggle, against the app's own URL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* changes

* changes

* Fix prettier formatting in workflow-graph countSubgraphs test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix ty typecheck errors in workflow API

- Annotate Workflow._api_endpoints as WorkflowEndpointManager | None and
  narrow directly so .sync() typechecks
- Assert _api_endpoints / view_api dict result in tests before subscripting
- Guard os.path.dirname against gr.__file__ being None

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix call_fn signature to match caller convention

The API executor invokes every caller as caller(data, request, token),
but call_fn only accepted (data, token), so calling an fn-backed workflow
endpoint via the Gradio client raised a TypeError. Align call_fn with
call_space/call_model/fetch_dataset's (data, request, token) signature.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix workflow API panel and schema validation

* Use server OAuth fallback for workflow text generation

* changes

* changes

* changes

* Update changeset: endpoint per subgraph, not per output

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fix test_save_allowed_with_write_access: use valid schema_version 2 payload

save_workflow now validates schema_version; the gating test's legacy
{"nodes": []} stub no longer passes validation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Address Copilot review: map file ports + per-subgraph wording

- port_to_component: map 'file' ports to gr.File(type='filepath') instead of
  falling through to Textbox, so /info schema matches _PY_TYPE/MEDIA_PORT_TYPES
  (+ regression test)
- WorkflowApiPanel subtitle + get_workflow_api docstring: 'one endpoint per
  output' -> 'per subgraph', matching the per-subgraph endpoint grouping

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-17 07:53:44 -07:00
Abubakar Abid 53cb4cae1e Run pnpm lint and pnpm ts:check on CI (#13526)
* Fix format diagnostics

* add changeset

* Fix format diagnostics

* Fix frontend runtime test regressions

* add changeset

* Fix post-merge frontend diagnostics

* add changeset

* Simplify optional spaces imports

* add changeset

* Enable frontend lint and typecheck in CI

* add changeset

* Address review comments after merging main

- Resolve merge conflicts in FullscreenButton wiring (keep dispatch where main added it; keep null guard + svg renderer in nativeplot)
- gallery: make handle_save take a root-bound upload callback; drop unused Client import
- tootils: drop duplicate ILoadingStatus, use the @gradio/statustracker type
- types: widen frontend_fn return type to match process_frontend_fn runtime
- dataframe: remove leftover console.log in measure_row

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Allow I18nData in choice display names for ty typecheck

PR #13534 added runtime support for i18n'd choice display names in
Radio/CheckboxGroup/Dropdown/SimpleDropdown but didn't widen the
`choices` type, so `ty` flags `demo/i18n/run.py`. Widen the tuple
display side to `str | I18nData` to match `label`/`info` and the
runtime behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* changes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 10:16:19 -07:00
hysts a11c728246 Re-translate i18n choices display names when the language is switched at runtime (#13534)
* Re-translate i18n choices on language switch

Choice display names in CheckboxGroup, Radio, Dropdown, and
SimpleDropdown were translated once at construction time, so
switching the language at runtime (Settings -> Language) updated
scalar props like label and info but left the choices in the
previous locale.

Add Gradio.live_i18n(), which wraps the injected i18n_store with
Svelte's fromStore() so that reading it inside a derived or a
template subscribes the caller to locale changes. Choice render
sites now use it instead of the construction-time formatter, which
stays as a fallback when no store is injected.

Also fix SimpleDropdown clearing its value when the display
strings change under it: the reverse lookup now re-derives the
displayed string from the still-valid internal value before
falling back to clearing.

Covered by runtime-switch unit tests in all four component suites
and an e2e test in i18n.spec.ts backed by a new Radio with i18n
choices in demo/i18n.

Closes #13531

* add changeset

* Address CI failure and Copilot review feedback

- Add fromStore to the svelte/store mock in i18n.test.ts; the mock
  predates the new import in @gradio/utils and made the suite fail
  to import on CI.
- live_i18n now uses the injected store purely as a reactivity
  trigger and always translates via this.i18n, so a custom
  formatter passed via props stays in effect.
- SimpleDropdown only reassigns its value and dispatches input when
  the resolved internal value actually changed, avoiding a spurious
  input event after a runtime locale switch.

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-06-12 19:41:54 +09:00
hysts be20ce8e9d Fix UI freeze when one event makes multiple components of the same type visible (#13521)
* Fix UI freeze when multiple components become visible

Visibility updates in update_state() rebuilt the entire component
tree with traverse() and reassigned this.root. When one event made
two or more components of the same type visible, the concurrent
rebuilds (handle_data applies outputs in parallel) trapped Svelte's
async reactivity in a non-terminating update cycle, freezing the
page and eventually crashing the tab.

Update the target node's visibility in place and load any missing
components in place via load_components(), mirroring what
render_previously_invisible_children() already does. Also make
load_components() store the loading component promise instead of
the whole get_component() return value so awaiting node.component
yields the module.

Regression introduced in #12839, which kept forms mounted (hidden
via CSS) instead of marking them invisible, so the racing rebuilds
started happening under an already-mounted parent.

* add changeset

* Propagate runtime when lazily mounting components

load_components now copies the loaded component's runtime alongside
its component, matching the node-creation path in create_node, so a
custom component that needs a separate Svelte runtime mounts
correctly when it is made visible after the initial load.

* Move slider repro into invisible_textbox demo

Per review feedback, drop the separate two_sliders testcase app and
add the sliders as a new tab in the existing run.py, so the E2E suite
does not need to spin up another Gradio app. Also extend the test to
hide the sliders again after showing them, confirming the page does
not freeze.

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-06-11 16:57:25 +09:00
hysts dba4a168ce preserve head script execution order (#13450)
* fix: preserve head script execution order

Scripts injected via `head` were created with createElement, which
sets the "force async" flag by default, so they executed in
download-completion order instead of document order. A library and a
plugin that depends on it could run out of order and fail.

Honor the author's async intent and default to document order in both
head paths:

- gr.HTML(head): copy the parsed script's async flag, so an explicit
  `async` stays async while a plain `<script src>` falls back to
  async=false and runs in document order.
- gr.Blocks(head): set async=false on created scripts before copying
  attributes, so plain scripts run in order while an explicit `async`
  attribute is preserved (Index.svelte and the app +page.svelte).

Add deterministic Playwright e2e tests for the gr.HTML order, the
gr.Blocks order, and the explicit-async cases.

* add changeset

* fix: avoid selector injection in HTML head dedupe

loadHead deduped scripts and links with
`document.querySelector(`script[src="${src}"]`)` /
`link[href="${href}"]`. Since `head` is author-provided, src/href can
contain characters that break a CSS attribute selector (for example a
`]` in the path), making querySelector throw and aborting loadHead
entirely. Compare the resolved URLs against document.scripts /
document.querySelectorAll("link") instead, which needs no selector
string.

Found while fixing the head script execution order in this PR; the
dedupe code is pre-existing and unrelated to the ordering change.

* Reduce head-script tests and comments

Drop the gr.Blocks(head=...) order e2e test and its demo fixture, since
the gr.HTML(head=...) order test already covers the same document-order
behavior. Trim the explanatory comments across the source files, demos,
and specs to match the surrounding style, keeping a short note on the
force-async default.

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
2026-06-05 08:39:47 -07:00
Hannah 127400b015 add workflow app to core (#13417)
* migrate workflow to gradio core

* add changeset

* cleanup

* format

* add changeset

* cleanup

* tweak

* add demo workflow

* format

* tweaks

* fix

* fix

* lint

* lint

* type

* oauth fix

* per modality I/O contract + port registry

* drop localstorage, dataset tweaks + add tests

* per node run, polish modal, tweak compatible nodes UX

* provider routing (stolen from daggr)

* input tweak

* fix oauth

* improve search

* semantic-search picker

* file picker +popup propagation

* node header

* refactor icons

* format

* remove export/import buttons

* big clean up and format

* format and refactor

* spacing tweak

* lint backend

* pnpm lock

* swap requests to httpx

* clean up

* typefix

* make output more robust

* - allow selecting endpoint
- format

* format

* remove dead code

* format

* improve search

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
2026-06-04 17:53:45 -07:00
Octopus 053dbe2ec2 docs: upgrade MiniMax demo to M3 (#13462)
Bump the model used in the MiniMax ChatInterface demo from MiniMax-M2.7
to MiniMax-M3, the latest generation model.

Co-authored-by: octo-patch <octo-patch@github.com>
2026-06-01 16:13:08 -07:00
Freddy Boulton 0d670adf41 Fix infinite effect loop in tabs (#13240)
* Add code

* add changeset

* Fix Tab Interactive bug

* add changeset

* add changeset

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Address review: drop unused untrack import and $state on old_selected

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Stabilize image editor examples test

* Push all changes except repro.py

* changes

* docs: changeset reflects both the dataframe and tabs fixes

Addresses Copilot review: the changeset bumps @gradio/dataframe and
@gradio/tabs, so the summary now describes both user-visible changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Abubakar Abid <islamrealm@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Dawood <dawoodkhan82@gmail.com>
2026-05-28 16:15:54 -07:00
Octopus 51497ae8e5 docs: add MiniMax example to ChatInterface providers guide (#13411)
Add a MiniMax entry to guides/05_chatbots/02_chatinterface-examples.md
alongside the existing OpenAI-compatible providers (SambaNova, Hyperbolic).

Includes a runnable demo at demo/llm_minimax/ that points the existing
'openai' client at MiniMax's OpenAI-compatible endpoint
(https://api.minimax.io/v1) and streams from the MiniMax-M2.7 model.

Co-authored-by: octo-patch <octo-patch@github.com>
Co-authored-by: Abubakar Abid <abubakar@huggingface.co>
2026-05-25 12:28:53 -07:00
Abubakar Abid 6c48f80948 Allow applying gr.cache() to intermediate functions directly (#13322)
* changes

* add changeset

* Apply suggestion from @abidlabs

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* address PR review feedback: LRU-bound runtime cache registry, fix changeset, add tests

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* remove registry bound test

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* remove accidentally committed lock file

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix lint: use yield from

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* ignore .claude/scheduled_tasks.lock

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Fix cache hit indicators for generators

* Split runtime caching into its own docstring example

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com>
2026-05-20 13:32:22 -07:00
weeix 55b2660420 docs: remove obsolete preserved_by_key mention from dynamic apps guide (#13370) 2026-05-12 10:51:04 -04:00
Freddy Boulton 9de472671f Fix (#13306) 2026-04-20 21:40:41 +00:00
pngwn 1d5994da10 FixDataframe performance when rendering many datetime rows (#13305)
* fix perf

* fix

* fix changeset
2026-04-21 04:03:45 +07:00
pngwn 79c5776809 Rework Dataframe wrapping, truncation, and column width sizing. (#13303)
* dataframe sizing, truncation and wrap fixes

* add changeset

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-04-21 01:01:50 +07:00
Hannah 075b06ebee remove app (#13287) 2026-04-16 18:45:31 +02:00
hannahblair ecd0e53d97 mobile 2026-04-16 18:21:56 +02:00
hannahblair 5f80ced775 fixes 2026-04-16 18:13:57 +02:00
hannahblair 5993759512 tweak 2026-04-16 18:08:53 +02:00
hannahblair 69172d64d5 tweak 2026-04-16 18:04:03 +02:00
hannahblair e4ccd128ba changes 2026-04-16 17:14:28 +02:00
Abubakar Abid 45c4ecd25f Add @gr.cache() decorator for caching deterministic functions, as as well as a lower-level gr.Cache that uses dependency injection (#13176)
* changes

* changes

* add changeset

* Remove benchmark results from cache branch

* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* add changeset

* changes

* changes

* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

* add changeset

* changes

* chore: empty commit

* changes

* changes

* changes

* changes

* changes

* changes

* Update demo/cache_kv_demo/run.py

Co-authored-by: hysts <hysts@users.noreply.github.com>

* Update demo/cache_kv_demo/run.py

Co-authored-by: hysts <hysts@users.noreply.github.com>

* changes

* changes

* changes

* changes

* changes

* changes

* Apply suggestion from @abidlabs

* changes

* changes

* changes

* add changeset

* empty commit

* changes

* changes

* changes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: hysts <hysts@users.noreply.github.com>
2026-04-08 11:41:29 -07:00
Abubakar Abid dbbff5fb50 changes (#13186) 2026-04-02 12:47:33 -07:00
pngwn 9487b60670 migrate dataframe to svelte 5 (#13150)
* df migration

* fix tests

* fix

* fix

* fix

* add changeset

* fix

* tweaks

* fix icon

* fix dtype

* fix copy

* fix cell widths

* tweaks

* fix tests

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-04-01 21:47:53 +05:30
Freddy Boulton a5d40965bb Fix Tab Interactive Bug (#13048)
* Add code

* add changeset

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-03-26 14:35:44 -04:00
Abubakar Abid 72e9eeedee Gradio Server Mode (#13117)
* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* add changeset

* Update run.py

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-03-24 11:23:00 -07:00
aliabid94 b0b1dc3282 Custom libraries in head of gr.HTML (#12990)
* changes

* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* add changeset

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com>
2026-03-24 10:53:14 -07:00
aliabid94 0b943a4fd0 Add watch function to gr.HTML js_on_load (#12988)
* changes

* changes

* add changeset

* changes

* changes

* changes

* changes

* changes

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com>
2026-03-24 09:45:59 -07:00
Dawood Khan 647511a336 Frontend Profiling CI (#12938)
* profiling first pass

* update workflow

* clean

* test fixes

* fix

* more updates

* update job

* format

* update workflow

* cleanup

* print results

* update workflow

* new demo + test fixes

* format

* workflow fix

* fix tests

* notebook fix

* workflow fix

* nb fix

* test

* format

* import

* add warmup iteration

* install pnpm on cache hit

---------

Co-authored-by: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com>
2026-03-23 12:52:56 -04:00
Freddy Boulton 48fa7433f6 Fix Mounting Gradio in FastAPI behind reverse proxy (#12935)
* Fix

* add changeset

* Fix

* Fix code'

* Skip ssr mode

* Fix format

* Rewrite test to use docker

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-03-05 09:49:43 -05:00
aliabid94 424a4e4bcf Allow gr.HTML to trigger any event name (#12967)
* changes

* changes

* add changeset

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-03-04 20:14:54 -08:00
aliabid94 362fba6cff Allow uploading files from gr.HTML (#12909)
* changes

* changes

* add changeset

* changes

* changes

* changes

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-26 15:54:42 -08:00
aliabid94 978bc6ea50 Add server functions support to gr.HTML (#12929)
* changes

* changes

* add changeset

* changes

* changes

* changes

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-25 13:38:25 -08:00
Freddy Boulton 7c3fa2a690 Fix Loading Spinner Issue Caused by Events Targeting Components In Inactive Tabs (#12904)
* Fix Loading Spinner Issue Caused by Events targetting Components in inactive Tabs

* add changeset

* Add chatbot load event e2e tests

* Add e2e test file

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-25 14:44:18 +00:00
Abubakar Abid d6907acf8b add SKILLS.md to Gradio repo, part 1 + cleanup (#12900)
* add SKILLS

* changes

* add changeset

* changes

* changes

* changes

* add changeset

* add changeset

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* changes

* add changeset

* changes

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-19 16:07:02 -08:00
Ali Abid 735351422c Revert "changes"
This reverts commit dc0aff4476.
2026-02-19 12:39:19 -08:00
Ali Abid dc0aff4476 changes 2026-02-19 12:38:23 -08:00
aliabid94 820eff0502 Add support for gr.HTML as a layout element (#12899)
* changes

* add changeset

* changes

* changes

* as

* changes

* changes

* changes

* changes

* changes

* changes

* chagnes

---------

Co-authored-by: Ali Abid <aliabid94@gmail.com>
Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-19 01:01:42 -08:00
Freddy Boulton d0b34228d7 Fix stop button not switching back to submit button in chat interface (#12875)
* FIx stop button not changing chat interface

* Fix code'

* add changeset

* Fix code

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
2026-02-12 15:31:31 +00:00
Charles b10e17cafb fix(reloading): Re-assign config for SpacesReloader (#12874)
* Share swap_blocks logic between SpacesReloader and SourceFileReloader

* Done TODOs

* add changeset

* Revert "Share swap_blocks logic between SpacesReloader and SourceFileReloader"

This reverts commit 6689733bc1e3421b8e0d63068c3f69e81665f834.

* Only config

* add changeset

* add changeset

* Fix type

* Fix types

---------

Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
Co-authored-by: Freddy Boulton <41651716+freddyaboulton@users.noreply.github.com>
2026-02-10 14:39:30 -05:00
Freddy Boulton 34ee825ae7 Fix theme builder demo on spaces (#12833) 2026-02-10 13:06:04 -05:00