Skip to content

build(deps): bump the bun-frontend group across 1 directory with 16 updates#2

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/bun/studio/frontend/bun-frontend-0d2d17d7a5
Closed

build(deps): bump the bun-frontend group across 1 directory with 16 updates#2
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/bun/studio/frontend/bun-frontend-0d2d17d7a5

Conversation

@dependabot
Copy link
Copy Markdown

@dependabot dependabot Bot commented on behalf of github Apr 6, 2026

Bumps the bun-frontend group with 16 updates in the /studio/frontend directory:

Package From To
@dagrejs/dagre 2.0.4 3.0.0
@dagrejs/graphlib 3.0.4 4.0.1
@hugeicons/core-free-icons 3.3.0 4.1.1
@streamdown/cjk 1.0.2 1.0.3
@streamdown/code 1.0.2 1.1.1
lucide-react 0.577.0 1.7.0
recharts 3.7.0 3.8.1
shadcn 3.8.5 4.1.2
streamdown 2.3.0 2.5.0
@biomejs/biome 1.9.4 2.4.10
@eslint/js 9.39.4 10.0.1
@types/node 24.12.2 25.5.2
eslint 9.39.4 10.2.0
eslint-plugin-react-refresh 0.4.26 0.5.2
globals 16.5.0 17.4.0
typescript 5.9.3 6.0.2

Updates @dagrejs/dagre from 2.0.4 to 3.0.0

Changelog

Sourced from @​dagrejs/dagre's changelog.

[3.0.0] - 2026

Major Improvements: TypeScript Migration

  • Full TypeScript Rewrite (PR #509): Migrated the entire core codebase from JavaScript to TypeScript for improved type safety, better IDE autocompletion, and easier maintenance.
  • Native Type Definitions: Removed the need for external @types/dagre packages; high-quality types are now shipped directly with the library.
  • Modern Build Pipeline: * Replaced JSHint with ESLint for stricter code quality.
    • Replaced Browserify/Karma with modern bundling and testing tools.
    • Standardized project indentation to 2 spaces (aligning .eslintrc and .editorconfig).

Refactoring & Fixes

  • Dependency Cleanup: Removed deprecated dependencies including bower.json and legacy test configurations.
  • Module Exports: Standardized ESM and CommonJS exports to ensure compatibility with modern bundlers like Webpack 5, Vite, and Rollup.
  • Internal Logic: Refined internal graph traversal algorithms to utilize TypeScript interfaces, reducing "undefined" runtime errors.

[2.0.0] - Legacy Modernization

Major Changes

  • Organization Transfer: Formally moved the repository to the @dagrejs GitHub organization.
  • Package Renaming: Published under the @dagrejs/dagre npm scope.
  • Dropped Legacy Environments: Discontinued support for extremely old Node.js versions (pre-v10) and legacy browsers that do not support ES6 features.

Fixes

  • Performance Optimizations: Improved layout calculation speeds for large-scale directed graphs.
  • Bug Fixes: Resolved edge cases in rank constraints and node spacing that caused overlapping in specific hierarchical layouts.

[1.0.0] - Initial Stable Release

  • Legacy documentation for versions prior to the @dagrejs migration can be found in the historical archives.
Commits
  • 5bbd601 Copying minor changes from graphlib to dagre release
  • 80e2257 Typo in the release
  • 68cda58 Bumping version and building for release
  • d17ea43 Merge pull request #509 from wandri/feat-convert-the-package-into-TypeScript
  • 2dcebc1 feat: convert the package into TypeScript
  • 2595d05 Building with graphlib 4.0
  • 0b35778 Merge pull request #508 from meganlee18/meganlee
  • 7c28961 Add missing constraints to layout configuration
  • 9d445b2 Bump version and set as pre-release
  • See full diff in compare view

Updates @dagrejs/graphlib from 3.0.4 to 4.0.1

Commits

Updates @hugeicons/core-free-icons from 3.3.0 to 4.1.1

Updates @streamdown/cjk from 1.0.2 to 1.0.3

Release notes

Sourced from @​streamdown/cjk's releases.

@​streamdown/cjk@​1.0.3

Patch Changes

  • 6f1ea07: Updated remark-cjk-friendly and remark-cjk-friendly-gfm-strikethrough from v1.x to v2.x. The only breaking change in v2.0.0 is dropping Node.js 16 support, which Streamdown has already dropped (requires Node.js ≥18), so there is no actual impact. The actual code is identical to the latest v1.x release (v2.0.1 only added the ability to import package.json).
Changelog

Sourced from @​streamdown/cjk's changelog.

1.0.3

Patch Changes

  • 6f1ea07: Updated remark-cjk-friendly and remark-cjk-friendly-gfm-strikethrough from v1.x to v2.x. The only breaking change in v2.0.0 is dropping Node.js 16 support, which Streamdown has already dropped (requires Node.js ≥18), so there is no actual impact. The actual code is identical to the latest v1.x release (v2.0.1 only added the ability to import package.json).
Commits
  • 15ba1ae Version Packages (#457)
  • 6f1ea07 chore(deps): update remark-cjk-friendly and remark-cjk-friendly-gfm-strikethr...
  • 1102f18 Fix all Biome lint and formatting errors
  • 6b1fc5b streamdown-cjk: 100% test coverage
  • See full diff in compare view

Updates @streamdown/code from 1.0.2 to 1.1.1

Release notes

Sourced from @​streamdown/code's releases.

@​streamdown/code@​1.1.1

Patch Changes

  • 651873d: Fall back to plain text highlighting when the code block language identifier is unknown or truncated mid-stream, preventing Shiki from throwing on unsupported language names.

@​streamdown/code@​1.1.0

Minor Changes

  • 01d27e9: Add support for custom Shiki themes via a themes option on createCodePlugin, accepting a [light, dark] pair of bundled theme names or full theme registration objects.

@​streamdown/code@​1.0.3

Patch Changes

  • c597336: Use JS engine
Changelog

Sourced from @​streamdown/code's changelog.

1.1.1

Patch Changes

  • 651873d: Fall back to plain text highlighting when the code block language identifier is unknown or truncated mid-stream, preventing Shiki from throwing on unsupported language names.

1.1.0

Minor Changes

  • 01d27e9: Add support for custom Shiki themes via a themes option on createCodePlugin, accepting a [light, dark] pair of bundled theme names or full theme registration objects.

1.0.3

Patch Changes

  • c597336: Use JS engine
Commits

Updates lucide-react from 0.577.0 to 1.7.0

Release notes

Sourced from lucide-react's releases.

Version 1.7.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.6.0...1.7.0

Version 1.6.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.5.0...1.6.0

Version 1.5.0

What's Changed

Full Changelog: lucide-icons/lucide@1.4.0...1.5.0

Version 1.4.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.3.0...1.4.0

Version 1.3.0

What's Changed

New Contributors

Full Changelog: lucide-icons/lucide@1.2.0...1.3.0

Version 1.2.0

What's Changed

New Contributors

... (truncated)

Commits

Updates recharts from 3.7.0 to 3.8.1

Release notes

Sourced from recharts's releases.

v3.8.1

What's Changed

Bugfixes!

New Contributors

Full Changelog: recharts/recharts@v3.8.0...v3.8.1

v3.8.0

What's Changed

We added generics to our data and dataKey props and now you can have your charts validated by TypeScript. See the full guide here: https://recharts.github.io/en-US/guide/typescript/

We are releasing new helper functions and hooks that will allow you to precisely target mouse interactions, and convert coordinates. See the guide here: https://recharts.github.io/en-US/guide/coordinateSystems/

And new functions and hooks:

getRelativeCoordinate - converts mouse events to pixel positions

Convert Data → Pixels:

useXAxisScale - returns a function to convert X data values to pixel positions useYAxisScale - returns a function to convert Y data values to pixel positions useCartesianScale - convenience hook for converting both at once

Pixels → Data:

... (truncated)

Commits
  • 5b10788 chore(deps-dev): bump diff from 8.0.3 to 8.0.4 (#7156)
  • 222396f chore(deps): bump react-router-dom from 7.13.1 to 7.13.2 (#7164)
  • c2642da chore(deps-dev): bump typescript-eslint from 8.57.1 to 8.57.2 (#7166)
  • b186929 fix(RechartsWrapper): prevent ResizeObserver memory leak on ref update (#7161)
  • 738f71f fix(Tooltip): prevent crash on sparse or undefined payload entries (#7149)
  • 00daf0b chore(deps-dev): bump rollup from 4.59.0 to 4.60.0 (#7158)
  • eba4f2a chore(deps-dev): bump marked from 17.0.4 to 17.0.5 (#7157)
  • 201d060 fix: resolve keyboard navigation and tooltip issues for Pie charts (#6921) (#...
  • 670d092 chore(deps-dev): bump flatted from 3.3.3 to 3.4.2 (#7150)
  • 86ca8de fix: stackOffset expand should not override numerical XAxis domain (#7152)
  • Additional commits viewable in compare view
Maintainer changes

This version was pushed to npm by corkscreewe, a new releaser for recharts since your current version.


Updates shadcn from 3.8.5 to 4.1.2

Release notes

Sourced from shadcn's releases.

shadcn@4.1.2

Patch Changes

shadcn@4.1.1

Patch Changes

shadcn@4.1.0

Minor Changes

shadcn@4.0.8

Patch Changes

shadcn@4.0.7

Patch Changes

shadcn@4.0.6

Patch Changes

shadcn@4.0.5

Patch Changes

shadcn@4.0.4

Patch Changes

shadcn@4.0.3

Patch Changes

shadcn@4.0.2

Patch Changes

... (truncated)

Changelog

Sourced from shadcn's changelog.

4.1.2

Patch Changes

4.1.1

Patch Changes

4.1.0

Minor Changes

4.0.8

Patch Changes

4.0.7

Patch Changes

4.0.6

Patch Changes

4.0.5

Patch Changes

4.0.4

Patch Changes

... (truncated)

Commits

Updates streamdown from 2.3.0 to 2.5.0

Release notes

Sourced from streamdown's releases.

streamdown@2.5.0

Minor Changes

  • d6666b6: Add lineNumbers prop to disable line numbers in code blocks
  • d4ec6c0: Add meta prop to CustomRendererProps. Custom renderers now receive the raw metastring from the code fence (everything after the language identifier, e.g. ```rust {1} title="foo"meta = '{1} title="foo"'). The prop is optional (meta?: string) and is undefined when no metastring is present. Existing custom renderers are unaffected.

Patch Changes

  • ac8d839: Add staggered animation-delay to streaming word/character animations so new content cascades in sequentially instead of all animating simultaneously. Configurable via the new stagger option (default 40ms). Set stagger: 0 to restore the previous behavior.

  • add5374: Enable horizontal scrolling on code blocks so long lines are accessible instead of being clipped by overflow-hidden.

  • 75845c0: Fix unnecessary re-renders of code blocks during streaming updates.

    Problem: In streaming mode, when new content arrives (e.g. a paragraph is appended), completed code blocks that haven't changed were still re-rendering. This happened because the Streamdown component used inline object literals as default parameter values for linkSafety ({ enabled: true }). Every time children changed and Streamdown re-rendered, these inline defaults created new references, which caused the contextValue useMemo to recompute a new StreamdownContext object. Since React propagates context changes through memo boundaries, any context consumer inside a memoized Block (such as CodeBlock) would re-render even though the block's own props were unchanged.

    Fix: Extract the inline default values for linkSafety into module-level constants (defaultLinkSafetyConfig). This ensures referential stability across renders, so contextValue only recomputes when the actual values change — not just because children updated.

  • 8b1c262: fix: prepend UTF-8 BOM to CSV downloads for Excel compatibility

    • save() now prepends \uFEFF for text/csv string content so Excel on Windows detects UTF-8 encoding instead of falling back to ANSI.
    • TableDownloadButton refactored to use save() instead of inline Blob creation, ensuring the public API also gets the BOM fix.
  • b105c64: Fix custom tag content being prematurely split when content follows the opening tag on the same line and contains double newlines (\n\n). The preprocessor now ensures proper HTML block structure so the parser treats the entire tag as a single unit.

  • 9e6f991: Increase dropdown z-index for table copy and download menus to prevent clipping by surrounding elements.

  • 9c18748: docs: document required CSS custom properties (shadcn/ui design tokens) in README

  • 7b62e9a: Replace Tailwind v4-only *:last: and *:first: variant syntax with [&>*:last-child]: and [&>*:first-child]: arbitrary variants for compatibility with both Tailwind CSS v3 and v4. Fixes caret rendering on every line instead of only the last child in v3.

  • Updated dependencies [e50b0c4]

  • Updated dependencies [716a5f0]

    • remend@1.3.0

streamdown@2.4.0

Minor Changes

  • 5edff75: Clarified Tailwind @source configuration for Streamdown and optional plugins. Updated documentation to keep the global @source for core streamdown only, move plugin @source guidance to plugin docs with examples, and add a caveat to include plugin entries only if installed.

  • 57cd3b5: Add support for custom starting line numbers in code blocks via the startLine meta option.

    Code blocks can now specify a starting line number in the meta string:

    ```js startLine=10

... (truncated)

Changelog

Sourced from streamdown's changelog.

2.5.0

Minor Changes

  • d6666b6: Add lineNumbers prop to disable line numbers in code blocks
  • d4ec6c0: Add meta prop to CustomRendererProps. Custom renderers now receive the raw metastring from the code fence (everything after the language identifier, e.g. ```rust {1} title="foo"meta = '{1} title="foo"'). The prop is optional (meta?: string) and is undefined when no metastring is present. Existing custom renderers are unaffected.

Patch Changes

  • ac8d839: Add staggered animation-delay to streaming word/character animations so new content cascades in sequentially instead of all animating simultaneously. Configurable via the new stagger option (default 40ms). Set stagger: 0 to restore the previous behavior.

  • add5374: Enable horizontal scrolling on code blocks so long lines are accessible instead of being clipped by overflow-hidden.

  • 75845c0: Fix unnecessary re-renders of code blocks during streaming updates.

    Problem: In streaming mode, when new content arrives (e.g. a paragraph is appended), completed code blocks that haven't changed were still re-rendering. This happened because the Streamdown component used inline object literals as default parameter values for linkSafety ({ enabled: true }). Every time children changed and Streamdown re-rendered, these inline defaults created new references, which caused the contextValue useMemo to recompute a new StreamdownContext object. Since React propagates context changes through memo boundaries, any context consumer inside a memoized Block (such as CodeBlock) would re-render even though the block's own props were unchanged.

    Fix: Extract the inline default values for linkSafety into module-level constants (defaultLinkSafetyConfig). This ensures referential stability across renders, so contextValue only recomputes when the actual values change — not just because children updated.

  • 8b1c262: fix: prepend UTF-8 BOM to CSV downloads for Excel compatibility

    • save() now prepends \uFEFF for text/csv string content so Excel on Windows detects UTF-8 encoding instead of falling back to ANSI.
    • TableDownloadButton refactored to use save() instead of inline Blob creation, ensuring the public API also gets the BOM fix.
  • b105c64: Fix custom tag content being prematurely split when content follows the opening tag on the same line and contains double newlines (\n\n). The preprocessor now ensures proper HTML block structure so the parser treats the entire tag as a single unit.

  • 9e6f991: Increase dropdown z-index for table copy and download menus to prevent clipping by surrounding elements.

  • 9c18748: docs: document required CSS custom properties (shadcn/ui design tokens) in README

  • 7b62e9a: Replace Tailwind v4-only *:last: and *:first: variant syntax with [&>*:last-child]: and [&>*:first-child]: arbitrary variants for compatibility with both Tailwind CSS v3 and v4. Fixes caret rendering on every line instead of only the last child in v3.

  • Updated dependencies [e50b0c4]

  • Updated dependencies [716a5f0]

    • remend@1.3.0

2.4.0

Minor Changes

  • 5edff75: Clarified Tailwind @source configuration for Streamdown and optional plugins. Updated documentation to keep the global @source for core streamdown only, move plugin @source guidance to plugin docs with examples, and add a caveat to include plugin entries only if installed.

  • 57cd3b5: Add support for custom starting line numbers in code blocks via the startLine meta option.

    Code blocks can now specify a starting line number in the meta string:

    ```js startLine=10
    const x = 1;
    ```

    This renders line numbers beginning at 10 instead of the default 1. The feature works by parsing the startLine=N value from the fenced-code meta string and applying counter-reset: line N-1 to the <code> element.

... (truncated)

Commits
  • 15ba1ae Version Packages (#457)
  • b752b44 fix(streamdown): move mermaid from devDependencies to dependencies (#466)
  • 90a7b58 Run fix
  • 9e6f991 fix(streamdown): increase dropdown z-index (#463)
  • d6666b6 feat: add lineNumbers prop to disable line numbers in code blocks (#460)
  • 6a79e04 fix(streamdown): preserve double newlines in literalTagContent tags (#459)
  • b9796c8 Improve test coverage
  • 6b49db1 Fix polynomial regular expression issue
  • 6d4100a Update utils.test.ts
  • 9f8ed4c Lint fixes
  • Additional commits viewable in compare view

Updates @biomejs/biome from 1.9.4 to 2.4.10

Release notes

Sourced from @​biomejs/biome's releases.

Biome CLI v2.4.10

2.4.10

Patch Changes

  • #8838 f3a6a6b Thanks @​baeseokjae! - Added new lint nursery rule noImpliedEval.

    The rule detects implied eval() usage through functions like setTimeout, setInterval, and setImmediate when called with string arguments.

    // Invalid
    setTimeout("alert('Hello');", 100);
    // Valid
    setTimeout(() => alert("Hello"), 100);

  • #9320 93c3b6c Thanks @​taberoajorge! - Fixed #7664: noUnusedVariables no longer reports false positives for TypeScript namespace declarations that participate in declaration merging with an exported or used value declaration (const, function, or class) of the same name. The reverse direction is also handled: a value declaration merged with an exported namespace is no longer flagged.

  • #9630 1dd4a56 Thanks @​raashish1601! - Fixed #9629: noNegationElse now keeps ternary branch comments attached to the correct branch when applying its fixer.

  • #9216 04243b0 Thanks @​FrederickStempfle! - Fixed #9061: noProcessEnv now also detects process.env when process is imported from the "process" or "node:process" modules.

    Previously, only the global process object was flagged:

    import process from "node:process";
    // This was not flagged, but now it is:
    console.log(process.env.NODE_ENV);
  • #9692 61b7ec5 Thanks @​mkosei! - Fixed Svelte #each destructuring parsing and formatting for nested patterns such as [key, { a, b }].

  • #9627 06a0f35 Thanks @​ematipico! - Fixed #191: Improved the performance of how the Biome Language Server pulls code actions and diagnostics.

    Before, code actions were pulled and computed all at once in one request. This approach couldn't work in big files, and caused Biome to stale and have CPU usage spikes up to 100%.

    Now, code actions are pulled and computed lazily, and Biome won't choke anymore in big files.

  • #9643 5bfee36 Thanks @​dyc3! - Fixed #9347: useVueValidVBind no longer reports valid object bindings like v-bind="props".

  • #9627 06a0f35 Thanks @​ematipico! - Fixed assist diagnostics being invisible when using --diagnostic-level=error. Enforced assist violations (e.g. useSortedKeys) were filtered out before being promoted to errors, causing biome check to incorrectly return success.

  • #9695 9856a87 Thanks @​dyc3! - Added the new nursery rule noUnsafePlusOperands, which reports + and += operations that use object-like, symbol, unknown, or never operands, or that mix number with bigint.

  • #9627 06a0f35 Thanks @​ematipico! - Fixed duplicate parse errors in check and ci output. When a file had syntax errors, the same parse error was printed twice and the error count was inflated.

  • #9627 06a0f35 Thanks @​ematipico! - Improved the performance of the commands lint and check when they are called with --write.

... (truncated)

Changelog

Sourced from @​biomejs/biome's changelog.

2.4.10

Patch Changes

  • #8838 f3a6a6b Thanks @​baeseokjae! - Added new lint nursery rule noImpliedEval.

    The rule detects implied eval() usage through functions like setTimeout, setInterval, and setImmediate when called with string arguments.

    // Invalid
    setTimeout("alert('Hello');", 100);
    // Valid
    setTimeout(() => alert("Hello"), 100);

  • #9320 93c3b6c Thanks @​taberoajorge! - Fixed #7664: noUnusedVariables no longer reports false positives for TypeScript namespace declarations that participate in declaration merging with an exported or used value declaration (const, function, or class) of the same name. The reverse direction is also handled: a value declaration merged with an exported namespace is no longer flagged.

  • #9630 1dd4a56 Thanks @​raashish1601! - Fixed #9629: noNegationElse now keeps ternary branch comments attached to the correct branch when applying its fixer.

  • #9216 04243b0 Thanks @​FrederickStempfle! - Fixed #9061: noProcessEnv now also detects process.env when process is imported from the "process" or "node:process" modules.

    Previously, only the global process object was flagged:

    import process from "node:process";
    // This was not flagged, but now it is:
    console.log(process.env.NODE_ENV);
  • #9692 61b7ec5 Thanks @​mkosei! - Fixed Svelte #each destructuring parsing and formatting for nested patterns such as [key, { a, b }].

  • #9627

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Apr 6, 2026
Bumps the bun-frontend group in /studio/frontend with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [@dagrejs/dagre](https://github.com/dagrejs/dagre) | `2.0.4` | `3.0.0` |
| [@dagrejs/graphlib](https://github.com/dagrejs/graphlib) | `3.0.4` | `4.0.1` |
| @hugeicons/core-free-icons | `3.3.0` | `4.1.1` |
| [@streamdown/cjk](https://github.com/vercel/streamdown/tree/HEAD/packages/streamdown-cjk) | `1.0.2` | `1.0.3` |
| [@streamdown/code](https://github.com/vercel/streamdown/tree/HEAD/packages/streamdown-code) | `1.0.2` | `1.1.1` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `0.577.0` | `1.7.0` |
| [recharts](https://github.com/recharts/recharts) | `3.7.0` | `3.8.1` |
| [shadcn](https://github.com/shadcn-ui/ui/tree/HEAD/packages/shadcn) | `3.8.5` | `4.1.2` |
| [streamdown](https://github.com/vercel/streamdown/tree/HEAD/packages/streamdown) | `2.3.0` | `2.5.0` |
| [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `1.9.4` | `2.4.10` |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.39.4` | `10.0.1` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `24.12.2` | `25.5.2` |
| [eslint](https://github.com/eslint/eslint) | `9.39.4` | `10.2.0` |
| [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) | `0.4.26` | `0.5.2` |
| [globals](https://github.com/sindresorhus/globals) | `16.5.0` | `17.4.0` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.9.3` | `6.0.2` |


Updates `@dagrejs/dagre` from 2.0.4 to 3.0.0
- [Release notes](https://github.com/dagrejs/dagre/releases)
- [Changelog](https://github.com/dagrejs/dagre/blob/master/changelog.md)
- [Commits](dagrejs/dagre@v2.0.4...v3.0.0)

Updates `@dagrejs/graphlib` from 3.0.4 to 4.0.1
- [Release notes](https://github.com/dagrejs/graphlib/releases)
- [Changelog](https://github.com/dagrejs/graphlib/blob/master/changelog.md)
- [Commits](dagrejs/graphlib@v3.0.4...v4.0.1)

Updates `@hugeicons/core-free-icons` from 3.3.0 to 4.1.1

Updates `@streamdown/cjk` from 1.0.2 to 1.0.3
- [Release notes](https://github.com/vercel/streamdown/releases)
- [Changelog](https://github.com/vercel/streamdown/blob/main/packages/streamdown-cjk/CHANGELOG.md)
- [Commits](https://github.com/vercel/streamdown/commits/@streamdown/cjk@1.0.3/packages/streamdown-cjk)

Updates `@streamdown/code` from 1.0.2 to 1.1.1
- [Release notes](https://github.com/vercel/streamdown/releases)
- [Changelog](https://github.com/vercel/streamdown/blob/main/packages/streamdown-code/CHANGELOG.md)
- [Commits](https://github.com/vercel/streamdown/commits/@streamdown/code@1.1.1/packages/streamdown-code)

Updates `lucide-react` from 0.577.0 to 1.7.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.7.0/packages/lucide-react)

Updates `recharts` from 3.7.0 to 3.8.1
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](recharts/recharts@v3.7.0...v3.8.1)

Updates `shadcn` from 3.8.5 to 4.1.2
- [Release notes](https://github.com/shadcn-ui/ui/releases)
- [Changelog](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/CHANGELOG.md)
- [Commits](https://github.com/shadcn-ui/ui/commits/shadcn@4.1.2/packages/shadcn)

Updates `streamdown` from 2.3.0 to 2.5.0
- [Release notes](https://github.com/vercel/streamdown/releases)
- [Changelog](https://github.com/vercel/streamdown/blob/main/packages/streamdown/CHANGELOG.md)
- [Commits](https://github.com/vercel/streamdown/commits/streamdown@2.5.0/packages/streamdown)

Updates `@biomejs/biome` from 1.9.4 to 2.4.10
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.10/packages/@biomejs/biome)

Updates `@eslint/js` from 9.39.4 to 10.0.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v10.0.1/packages/js)

Updates `@types/node` from 24.12.2 to 25.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `eslint` from 9.39.4 to 10.2.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v9.39.4...v10.2.0)

Updates `eslint-plugin-react-refresh` from 0.4.26 to 0.5.2
- [Release notes](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/releases)
- [Changelog](https://github.com/ArnaudBarre/eslint-plugin-react-refresh/blob/main/CHANGELOG.md)
- [Commits](ArnaudBarre/eslint-plugin-react-refresh@v0.4.26...v0.5.2)

Updates `globals` from 16.5.0 to 17.4.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](sindresorhus/globals@v16.5.0...v17.4.0)

Updates `typescript` from 5.9.3 to 6.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](microsoft/TypeScript@v5.9.3...v6.0.2)

---
updated-dependencies:
- dependency-name: "@dagrejs/dagre"
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: "@dagrejs/graphlib"
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: "@hugeicons/core-free-icons"
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: "@streamdown/cjk"
  dependency-version: 1.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: bun-frontend
- dependency-name: "@streamdown/code"
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: bun-frontend
- dependency-name: lucide-react
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: recharts
  dependency-version: 3.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: bun-frontend
- dependency-name: shadcn
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: streamdown
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: bun-frontend
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.10
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: "@eslint/js"
  dependency-version: 10.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: "@types/node"
  dependency-version: 25.5.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: eslint
  dependency-version: 10.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: eslint-plugin-react-refresh
  dependency-version: 0.5.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: bun-frontend
- dependency-name: globals
  dependency-version: 17.4.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
- dependency-name: typescript
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: bun-frontend
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot changed the title build(deps): bump the bun-frontend group in /studio/frontend with 16 updates build(deps): bump the bun-frontend group across 1 directory with 16 updates Apr 6, 2026
@dependabot dependabot Bot force-pushed the dependabot/bun/studio/frontend/bun-frontend-0d2d17d7a5 branch from fe350af to 8f947e2 Compare April 6, 2026 16:00
@dependabot @github
Copy link
Copy Markdown
Author

dependabot Bot commented on behalf of github Apr 9, 2026

Looks like these dependencies are updatable in another way, so this is no longer needed.

@dependabot dependabot Bot closed this Apr 9, 2026
@dependabot dependabot Bot deleted the dependabot/bun/studio/frontend/bun-frontend-0d2d17d7a5 branch April 9, 2026 10:33
danielhanchen added a commit that referenced this pull request Apr 16, 2026
…comment-safe end scan

Resolves three reviewer findings on PR unslothai#5049 (`fix/chat-template-followups`):

Finding #1 [10/10]: dict/list variants now route through
`_fix_chat_template_for_tokenizer` via a new `_VariantTokenizerProxy`
adapter. Previously the dict/list branches called `_fix_chat_template`
directly, silently bypassing the warn/strict (`UNSLOTH_STRICT_CHAT_TEMPLATE`)
contract, the `no == yes` diagnostic, broken-existing-block detection,
and `_validate_patched_template` guard. The proxy swaps
`base.chat_template` to the variant string before each
`apply_chat_template` call so tokenizer globals (`bos_token`, custom
filters, `raise_exception`) remain available; if the base is read-only
it falls back to isolated Jinja rendering.

Finding #2 [1/10]: `_has_add_generation_prompt_block` now requires the
`If` body to contain at least one `Output` node (a new
`_if_body_emits_content` helper walks descendants). This distinguishes a
real generation-prompt block from a header guard like
`{% if not add_generation_prompt is defined %}{% set ... %}{% endif %}`
(body contains only `Assign`) which references the name but emits
nothing. Also dropped a now-redundant `"add_generation_prompt" not in
scrubbed` guard in `_fix_chat_template` Case 2 so header-guarded
templates still get repaired.

Finding #4 [1/10]: `_find_end_position` now replaces Jinja comments with
equal-length whitespace before scanning for `{% endfor %}` / `{% endif %}`
tokens. This prevents a trailing comment containing those tokens from
being picked as the real end tag. Positions in the padded string map 1:1
to positions in the original template.

Tests:
  - tests/test_chat_template_followups.py: 21/21 (T19 strict-mode
    dict variant, T20 header-guard repair, T21 comment-endfor trap
    added; T4/T5 stubs updated with a working apply_chat_template
    that routes through Jinja).
  - tests/test_fix_chat_template_pr4426.py: 51/51 cells unchanged.
  - tests/test_load_correct_tokenizer_pr4426.py: 5/5.
  - tests/test_mistral_pr4426.py: 5/5 byte-identical.
  - tests/test_qwen_pr4426.py: 14/14 byte-identical.
  - temp/sim/battery.py: 79/79 followup; 0 regressions vs baseline.
  - Phase 3 Hermes-3 broken-LoRA reload: inference still returns
    `'The answer to the equation 2+2 is 4.'`.
  - Spot-checks on Hermes-3 / Phi-4 / Llama-3.2-1B / Gemma-3-1B real
    stripped templates: probe still derives the expected prefix.
danielhanchen added a commit that referenced this pull request Apr 17, 2026
…rt (unslothai#5049)

* Chat-template repair: warn-by-default, AST classification, dict support

Follow-up hardening on top of PR unslothai#4426 (which fixed the unslothai#4150
RuntimeError for ChatML LoRA reloads).

Behavior changes:

- Warn-by-default instead of RuntimeError. When fix_chat_template cannot
  repair a broken template, emit a warning and return the original.
  Set UNSLOTH_STRICT_CHAT_TEMPLATE=1 to restore the pre-warn hard fail.
  Fixes the UX where a missing `{% if add_generation_prompt %}` block on
  a saved LoRA (typical after LlamaFactory / Axolotl re-serialize) would
  block model loading entirely.

- Local path vs HF hub distinguished in the warning message. For local
  paths the message points at the likely downstream tool; for HF IDs it
  points at the upstream model maintainers. Previously both said "file a
  bug report to the maintainers of <path>" even when <path> was the
  user's own saves/ directory.

- Dict / list chat_template now handled. Hermes-3 ships with
  {default, tool_use} and the previous code crashed with
  AttributeError: 'dict' object has no attribute 'find' when entering
  _fix_chat_template with a dict. Each variant is now fixed
  independently; structure is preserved.

Internals:

- _find_end_position now matches all four Jinja whitespace-control
  variants ({% %}, {%- %}, {% -%}, {%- -%}) and returns the rightmost
  endfor/endif so multi-for templates aren't locked onto the first loop.
  Previously {%- endfor -%} (both-side dash, used by Qwen3-Guard) was
  silently bypassed.

- _has_add_generation_prompt_block uses Jinja AST via
  jinja2.nodes.If/Name walks instead of substring matching, so
  templates that hide the block behind comments or dash-style variants
  are classified correctly.

- _template_ends_with_toplevel_for gates the GH#4150 ChatML repair on
  the AST: only fires when the last structural top-level node is a For
  (standard ChatML shape), ignoring trailing pure-whitespace output
  nodes. Templates wrapped in an outer If (Qwen3-Guard) are now
  explicitly skipped at the _fix_chat_template level as well, not just
  at load_correct_tokenizer's name-based exemption.

- _validate_patched_template renders the patched template with and
  without add_generation_prompt and confirms the patched output
  responds to the flag by appending (not replacing) content. If
  validation fails, the patch is discarded and we fall through to the
  warn path.

Verified with an expanded regression suite in tests/:
- test_fix_chat_template_pr4426.py: 42/42 template-matrix cells
- test_load_correct_tokenizer_pr4426.py: 5/5 tokenizer loads
- test_chat_template_followups.py: 10/10 new follow-up tests
- test_mistral_pr4426.py: 5 Mistral variants byte-identical
- test_qwen_pr4426.py: 14 Qwen variants byte-identical
  (Qwen1.5, Qwen2, Qwen2.5-Instruct/Coder/Math/VL, Qwen3,
  Qwen3-Coder, QwQ, Qwen3-Guard-Gen)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Guard _validate_patched_template against read-only chat_template

If tokenizer.chat_template is a property or otherwise read-only, the
validation helper would crash with AttributeError when trying to
temporarily set the patched template. Catch the assignment failure and
return False (skip validation), and best-effort restore in the finally
block.

* Replace regex separator inference with render-diff; broaden repair to non-ChatML templates

The previous `_infer_assistant_separator` was a four-tier regex heuristic that
only worked on ChatML-shaped templates and forced a hard `<|im_start|>` /
`<|im_end|>` presence gate on Case 2 repair. This meant a Llama-3, Gemma, or
Phi-3 template stripped of its generation-prompt block by a downstream tool
(LlamaFactory, Axolotl, etc.) would still warn-and-return even though the
structural shape is identical to the ChatML case the PR already handles.

This replaces the regex with `_derive_assistant_prefix_by_render`: render the
template with two dialogs that differ only in assistant content, then
`os.path.commonprefix` on the tails captures the exact assistant-turn prefix
the template emits. The template itself is ground truth, so non-ChatML shapes
work as long as the assistant block is a literal the template emits once per
message.

Three guards keep the derivation safe:
  A. both assistant renders extend the base render (no reordering);
  B. the divergence point is exactly the content-insertion site (sentinel
     follows the common prefix);
  C. a user-role cross-check: if a render with a user sentinel also emits
     the same prefix, role has no effect on output and we reject. A render
     failure on [user, user] (e.g. Gemma's `raise_exception` alternation
     check) is evidence that role matters; we accept.

Sentinels differ at character 0 so `commonprefix` cannot absorb them, and
trailing whitespace/comments after the last `{% endfor %}` are stripped
before probing (they would appear in base but not after the appended
assistant turn and break Guard A).

`_fix_chat_template` and `_repair_string_template` now thread an
`is_sharegpt` kwarg; `_fix_chat_template` retries once with
`is_sharegpt=True` if the first probe returns None (dual-probe fallback
for dict/list callers).

The ChatML `<|im_start|>` / `<|im_end|>` hard gate in Case 2 is dropped.
`_infer_assistant_separator` is deleted.

Verified via:
  - tests/test_fix_chat_template_pr4426.py: 51/51 cells (new Llama-3,
    Gemma, Phi-3 broken-template rows all repair FIX-OK)
  - tests/test_load_correct_tokenizer_pr4426.py: 5/5
  - tests/test_chat_template_followups.py: 18/18 (T11-T18 cover
    non-ChatML repair + probe failure modes)
  - tests/test_mistral_pr4426.py: 5/5 byte-identical
  - tests/test_qwen_pr4426.py: 14/14 byte-identical (Qwen3-Guard AST
    gate still rejects)
  - tests/hermes3_lora_pr4426.py reload: patched template ends with
    `<|im_start|>assistant\n`, inference returns sensible output.
  - temp/sim/battery.py: 79/79 followup; vs baseline: 0 regressions,
    9 improvements.
  - Spot-check probe on real stripped tokenizers (Hermes-3, Phi-4,
    Llama-3.2-1B, Gemma-3-1B): all derive the expected prefix.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Address reviewer findings: variant routing, positive-gate detection, comment-safe end scan

Resolves three reviewer findings on PR unslothai#5049 (`fix/chat-template-followups`):

Finding #1 [10/10]: dict/list variants now route through
`_fix_chat_template_for_tokenizer` via a new `_VariantTokenizerProxy`
adapter. Previously the dict/list branches called `_fix_chat_template`
directly, silently bypassing the warn/strict (`UNSLOTH_STRICT_CHAT_TEMPLATE`)
contract, the `no == yes` diagnostic, broken-existing-block detection,
and `_validate_patched_template` guard. The proxy swaps
`base.chat_template` to the variant string before each
`apply_chat_template` call so tokenizer globals (`bos_token`, custom
filters, `raise_exception`) remain available; if the base is read-only
it falls back to isolated Jinja rendering.

Finding #2 [1/10]: `_has_add_generation_prompt_block` now requires the
`If` body to contain at least one `Output` node (a new
`_if_body_emits_content` helper walks descendants). This distinguishes a
real generation-prompt block from a header guard like
`{% if not add_generation_prompt is defined %}{% set ... %}{% endif %}`
(body contains only `Assign`) which references the name but emits
nothing. Also dropped a now-redundant `"add_generation_prompt" not in
scrubbed` guard in `_fix_chat_template` Case 2 so header-guarded
templates still get repaired.

Finding #4 [1/10]: `_find_end_position` now replaces Jinja comments with
equal-length whitespace before scanning for `{% endfor %}` / `{% endif %}`
tokens. This prevents a trailing comment containing those tokens from
being picked as the real end tag. Positions in the padded string map 1:1
to positions in the original template.

Tests:
  - tests/test_chat_template_followups.py: 21/21 (T19 strict-mode
    dict variant, T20 header-guard repair, T21 comment-endfor trap
    added; T4/T5 stubs updated with a working apply_chat_template
    that routes through Jinja).
  - tests/test_fix_chat_template_pr4426.py: 51/51 cells unchanged.
  - tests/test_load_correct_tokenizer_pr4426.py: 5/5.
  - tests/test_mistral_pr4426.py: 5/5 byte-identical.
  - tests/test_qwen_pr4426.py: 14/14 byte-identical.
  - temp/sim/battery.py: 79/79 followup; 0 regressions vs baseline.
  - Phase 3 Hermes-3 broken-LoRA reload: inference still returns
    `'The answer to the equation 2+2 is 4.'`.
  - Spot-checks on Hermes-3 / Phi-4 / Llama-3.2-1B / Gemma-3-1B real
    stripped templates: probe still derives the expected prefix.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Tighten comments in chat-template helpers

Pure comment minimization across `_find_end_position`,
`_has_add_generation_prompt_block`, `_if_body_emits_content`,
`_derive_assistant_prefix_by_render`, `_fix_chat_template` Case 2,
and `_VariantTokenizerProxy`. No behavior change; same intent,
fewer lines. All 21 follow-up tests and the 51-cell Phase 1 matrix
still pass.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Sandbox probe, fix is_sharegpt validator mismatch, reject negated gates

Three real bugs from the 10-agent Opus review:

1. Probe now uses `jinja2.sandbox.SandboxedEnvironment` instead of bare
   `jinja2.Environment`. The probe renders at model-load time (before
   the user calls `apply_chat_template`), so it was a new eager
   code-execution surface that the base HF tokenizer loading does not
   have. SandboxedEnvironment blocks attribute-chain exploits at
   negligible cost.

2. `_repair_string_template` now tries validation with both
   `is_sharegpt=False` and `is_sharegpt=True`. Previously, when
   `_fix_chat_template` internally fell back to the other schema via
   its dual-probe, the outer validation still used the caller's
   original `is_sharegpt` -- rendering with the wrong message keys and
   spuriously dropping a valid repair.

3. `_has_add_generation_prompt_block` now skips `If` nodes whose test
   is a `Not` expression. A negated gate like
   `{% if not add_generation_prompt %}{{ x }}{% endif %}` fires when
   agp=False, so its emitting body is not a generation block -- but the
   old code counted any Name reference regardless of polarity.

Cleanup: removed unused `self._label`, added `\r` escape in
generation-block literal, switched variant labels to `!r` formatting,
removed redundant `import os as _os`.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix jinja2.sandbox import and sandbox proxy fallback

Two critical findings from the 20-reviewer pass:

1. [20/20] The proxy read-only fallback used bare `jinja2.Environment`,
   not sandboxed. All 20 reviewers independently reproduced marker-file
   creation via `cycler.__init__.__globals__['os'].system(...)` during
   `fix_chat_template()`. Fixed: fallback now uses
   `from jinja2.sandbox import SandboxedEnvironment`.

2. [14/20] The render-diff probe did `import jinja2` then referenced
   `jinja2.sandbox.SandboxedEnvironment`. `jinja2.sandbox` is a
   submodule that is NOT auto-imported by `import jinja2` on Jinja 3.1.6.
   This caused `AttributeError` (swallowed by `except Exception`),
   making the entire Case 2 repair path silently return None in a clean
   process. The 6 reviewers who saw it work had `jinja2.sandbox`
   pre-imported by an earlier module in their process. Fixed: both the
   probe and the proxy fallback now use
   `from jinja2.sandbox import SandboxedEnvironment`.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
danielhanchen added a commit that referenced this pull request May 18, 2026
* studio: load cached GGUF models when fully offline

When huggingface.co is unreachable, GGUF model loads fail in three distinct
places even though the bits are already in ~/.cache/huggingface/hub. Each
failure has a different surface symptom:

1. list_gguf_variants() raises straight through HTTPException(500), so the
   variant dropdown shows 'Failed to list GGUF variants'.

2. detect_gguf_model_remote() silently returns None after retries fail. The
   caller then treats a GGUF-only repo as non-GGUF and routes it through the
   transformers/MLX path. On Apple Silicon this surfaces as 'Unsloth currently
   only works on NVIDIA, AMD and Intel GPUs.'

3. _download_gguf() loses list_repo_files() to the network and falls back to a
   filename heuristic ('{repo}-{variant}.gguf'). When the repo name does not
   echo the filenames (e.g. repo 'Qwen3.6-27B-MTP-GGUF' contains a file
   'Qwen3.6-27B-UD-Q4_K_XL.gguf' with no MTP), hf_hub_download cannot find
   that invented filename in the cache and aborts.

Fix in three layers:

- list_gguf_variants / detect_gguf_model_remote: honor HF_HUB_OFFLINE and
  fall back to scanning the local HF cache snapshot when the API throws.
  detect_gguf_model_remote still keeps its retry loop for transient flakes;
  the cache fallback only kicks in after every attempt fails.

- _download_gguf: when list_repo_files() fails, look up variant -> real
  filename inside the cached snapshot before resorting to the heuristic.

- llama_cpp.load_model / inference worker startup: when DNS for
  huggingface.co fails (2s probe), set HF_HUB_OFFLINE=1 for the process so
  every hf_hub_download call below resolves from cache instantly instead of
  spending ~25s on five exponential retries.

Online behavior is unchanged: the API is tried first and only used to fail
over. The cache scan is a strict subset of what list_local_gguf_variants
already does today for local paths.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* studio: tighten inline comments on offline GGUF fallback

* studio: address review feedback on offline GGUF fallback

Fixes from the review pass on unslothai#5505:

* ruff F823 (lint CI red): the late `import os` at the bottom of
  LlamaCppBackend.load_model made `os` a function-local name, so my
  new `os.environ` reference at the top of the same method was a
  use-before-bind. Surfaces at runtime as
  'cannot access local variable os where it is not associated with a value'
  and is why the Mac/Windows Studio API jobs were failing too. The
  env-var mutation has been moved into a module-level contextmanager,
  so load_model no longer touches `os` directly.

* Codex P1: cache variant match now uses the relative path, not the
  basename. Layouts like `BF16/foo.gguf` (variant token only in
  parent dir) were silently skipped, falling through to the bogus
  `{repo}-{variant}.gguf` heuristic and failing offline loads of
  models stored under quant-named subdirs.

* Codex P1: HF_HUB_OFFLINE no longer persists past one model load.
  llama_cpp.load_model now uses a contextmanager that probes DNS,
  sets HF_HUB_OFFLINE/TRANSFORMERS_OFFLINE only when DNS is dead,
  and pops them in finally (preserving any prior user setting of
  TRANSFORMERS_OFFLINE). Pre-existing user-set HF_HUB_OFFLINE is
  respected as a no-op. worker.py keeps the startup probe because the
  orchestrator spawns a fresh worker per load -- comment updated to
  make that lifecycle explicit, and a warning is now logged.

* Gemini: cache-dir lookup centralized in `_iter_hf_cache_snapshots`.
  Three near-identical copies (in list/detect helpers and the
  llama_cpp offline scan) now go through one helper.

* Gemini: `huggingface_hub.utils.is_offline_mode` does not exist in
  1.x (verified locally); `huggingface_hub.constants.HF_HUB_OFFLINE`
  is snapshot-at-import-time and does not reflect runtime mutations.
  Manual env-var parsing kept.

* socket probe now saves and restores the prior default timeout
  instead of unconditionally setting None on exit, so it composes
  with caller code that already configured a timeout.

* worker.py probe now logs a warning when offline mode is auto-enabled
  so debugging the case isn't blind.

* studio: regression tests for offline GGUF cache fallback

Lock in the offline fallback path from unslothai#5505 so future refactors can't
silently regress either bug. 26 tests, 0.55 s, no network/GPU/subprocess.

Covers:

* _iter_hf_cache_snapshots: missing cache, missing repo, missing
  snapshots/, newest-mtime ordering, case-insensitive repo match.
* _list_gguf_variants_from_hf_cache and the list_gguf_variants
  online/offline-env/API-exception/reraise paths.
* _detect_gguf_from_hf_cache and detect_gguf_model_remote 3x-fail
  fallback. Pre-existing RepositoryNotFoundError early-return preserved.
* Codex P1 #1 regression: BF16/foo.gguf (quant only in subdir name)
  must resolve via _detect_gguf_from_hf_cache, which now matches the
  snapshot-relative path rather than the basename.
* _probe_dns_dead: returns True/False, restores prior socket timeout.
* Codex P1 #2 regression: _hf_offline_if_dns_dead sets env only inside
  the block, restores on exit (including on exception), re-probes DNS
  on the next call so a transient hiccup cannot lock the long-lived
  LlamaCppBackend singleton offline. Honors a user-set HF_HUB_OFFLINE
  as a no-op. Preserves a user-set TRANSFORMERS_OFFLINE across exit.

Follows the existing studio backend test stub pattern (loggers /
structlog / httpx stubs + backend dir on sys.path).

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* studio: extend offline cache fallback to _download_mmproj and quant label

Two follow-up fixes from the review pass on unslothai#5505:

* _download_mmproj() now mirrors _download_gguf()'s offline path:
  when list_repo_files() fails, scan the local HF cache snapshot for
  any GGUF whose basename starts with mmproj-. Without this, offline
  vision GGUF loads succeed at the main weight (the existing PR fix)
  but the mmproj returns None and llama-server starts without vision
  support. Same _iter_hf_cache_snapshots helper, F16 preference and
  fallback to the first match are preserved.

* _extract_quant_label() now considers parent directory segments when
  the basename has no quant token. Layouts like BF16/foo.gguf are
  already documented in this file and are returned by the new
  snapshot-relative-path filter in _download_gguf; before this fix
  their variant label collapsed to "foo" (the last hyphen segment of
  the basename). Regex is the same; the search just walks parent
  segments innermost-first if the basename misses.

Tests (studio/backend/tests/test_offline_gguf_cache_fallback.py):

* TestExtractQuantLabelSubdir: basename quant unchanged, quant-only-
  in-parent, UD- prefix in parent, deeper nesting picks the
  innermost matching segment.
* TestDownloadMmprojOfflineCacheFallback: cache fallback returns the
  mmproj when list_repo_files fails, F16 preference holds when both
  variants are in cache, no-mmproj cache returns None.
* httpx stub now prefers the real package when installed (the CI
  install list already includes it) and falls back to the stub only
  when httpx is genuinely missing. Newer huggingface_hub imports
  HTTPError/Response/Request at module load, so the previous
  fixed-set stub broke when those names were added upstream.

26 existing cases plus 7 new = 33 pass in 0.74s.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix/adjust offline cache + DNS probe per PR unslothai#5505 review

Four review findings tightened, with regression tests:

- list_local_gguf_variants subdir collapse (P1 codex 10:08): pass the
  snapshot-relative path to _extract_quant_label so BF16/foo.gguf and
  Q4_K_M/foo.gguf produce distinct labels instead of folding to the same
  basename pseudo-quant.
- list_gguf_variants cache fallback (P2 codex 12:10): surface
  RepositoryNotFoundError / GatedRepoError / RevisionNotFoundError /
  EntryNotFoundError to the caller instead of masking with stale cache,
  matching detect_gguf_model_remote.
- _detect_gguf_from_hf_cache mmproj (P2 codex 12:10): exclude mmproj
  files from the candidate list so a partial cache with only a vision
  projector cannot route the projector as the main model.
- _probe_dns_dead global timeout (P2 codex 13:06): run the gethostbyname
  on a daemon thread with join timeout so concurrent sockets in the same
  interpreter never inherit a process-wide socket.setdefaulttimeout
  mutation. Same shape applied in worker.py's startup probe.

* Make llama-server health check tolerant of warmup races

Two layered fixes for the Windows GGUF smoke CI Tool calling Tests
flake that exit-22'd on a single httpx.ReadError during llama-server
warmup. The 'windows-latest -> windows-2025-vs2026' image rollout is
hitting main with the identical symptom.

A. _wait_for_health: catch httpx.ReadError, RemoteProtocolError,
   WriteError alongside ConnectError and TimeoutException. A TCP RST
   mid-read while llama-server is still binding the port (WinError
   10054) is a 'still warming up' signal, not fatal. The existing
   _process.poll() check still wins for real crashes.

B. _drain_stdout + spawn: tee llama-server stdout/stderr to a
   per-launch log file at ~/.unsloth/studio/logs/llama-server/
   <port>.log. Any future subprocess crash leaves a forensic trace
   on disk even when Studio's traceback only captures the symptom
   (ReadError) and not the cause. Best-effort: a logging-side OSError
   never blocks the load.

Regression coverage: TestWaitForHealthRetriesOnReadError pins the
retry behaviour for the three new exception types and verifies that a
real process exit still short-circuits the loop.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* ci(windows): retry inference/load + collect llama-server logs

Composite fix for the Tool calling Tests flake that exit-22'd on a
single httpx.ReadError during llama-server warm-up. The
windows-latest -> windows-2025-vs2026 runner image rollout has been
hitting main with the identical symptom.

- All three jobs (openai-anthropic, tool-calling, json-images) now
  retry POST /api/inference/load up to 3 times with 10s backoff and
  preserve the response body for post-mortem. One transient 500 no
  longer fails the whole job.
- A new "Collect llama-server logs" step copies the per-launch
  llama-server stdout teed by Studio under ~/.unsloth/studio/logs/
  llama-server/ into the workspace, and the upload-artifact step
  now includes logs/llama-server/*.log so any future subprocess
  crash leaves a forensic trace.

---------

Co-authored-by: shimmyshimmer <shimmyshimmer@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Daniel Han <danielhanchen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants