Skip to content

Commit 23dcf01

Browse files
committed
Refactor model management and API integration for improved consistency
- Removed the `useHuggingFaceModels` hook and updated related components to directly use the new API endpoint for fetching HuggingFace models. - Refactored model-related components to utilize the unified model structure, enhancing data handling and consistency across the application. - Updated the ModelDownloadList and ModelListItem components to streamline model display and download logic. - Cleaned up unused imports and hooks, improving code clarity and maintainability. - Adjusted the ModelListHeader to include a slider for filtering models by size, enhancing user experience.
1 parent cb699a0 commit 23dcf01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+516
-1090
lines changed

AGENTS.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ The project includes many specialized hooks organized by functionality:
174174

175175
#### Model Management Hooks
176176

177-
- **`useHuggingFaceModels`**: Fetches and caches HuggingFace models with TanStack Query
178177
- **`useLoraModels`**: Manages LoRA (Low-Rank Adaptation) model data
179178
- **`useModelBasePaths`**: Provides base cache directories for HuggingFace Hub and Ollama models
180179
- **`useModelsWithSize`**: Fetches model data with size information for storage planning

build.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def pack(self) -> None:
340340
"install",
341341
"-p",
342342
str(self.ENV_DIR),
343-
"ffmpeg",
343+
"ffmpeg>=6,<7",
344344
"cairo",
345345
"git",
346346
"x264",
@@ -410,9 +410,7 @@ def __init__(
410410
self.python_version = python_version
411411
self.env_name = env_name or self.DEFAULT_ENV_NAME
412412
self.env_prefix = (
413-
Path(env_prefix).expanduser().resolve()
414-
if env_prefix is not None
415-
else None
413+
Path(env_prefix).expanduser().resolve() if env_prefix is not None else None
416414
)
417415
combined_channels = list(self.DEFAULT_CHANNELS)
418416
if channels:
@@ -502,7 +500,9 @@ def create(
502500
) -> None:
503501
if self.env_exists():
504502
if not force:
505-
logger.info("Conda environment already exists; use --force to recreate it.")
503+
logger.info(
504+
"Conda environment already exists; use --force to recreate it."
505+
)
506506
return
507507
logger.info("Removing existing conda environment before recreation.")
508508
self.remove(skip_confirmation=True)
@@ -633,7 +633,9 @@ def handle_env_info(args: argparse.Namespace) -> None:
633633
manager.info()
634634

635635

636-
def handle_env_list(args: argparse.Namespace) -> None: # noqa: ARG001 - matches signature
636+
def handle_env_list(
637+
args: argparse.Namespace,
638+
) -> None: # noqa: ARG001 - matches signature
637639
manager = CondaEnvironmentManager()
638640
manager.list()
639641

@@ -682,7 +684,9 @@ def build_parser() -> argparse.ArgumentParser:
682684
)
683685
build_parser.set_defaults(func=handle_build_command)
684686

685-
env_parser = subparsers.add_parser("env", help="Manage the Nodetool conda environment")
687+
env_parser = subparsers.add_parser(
688+
"env", help="Manage the Nodetool conda environment"
689+
)
686690
env_subparsers = env_parser.add_subparsers(dest="env_command", required=True)
687691

688692
target_parent = argparse.ArgumentParser(add_help=False)

web/src/__tests__/components/chat/composer/NodeToolsSelector.test.tsx

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,65 @@ jest.mock("@mui/icons-material", () => ({
6161
Close: () => <svg data-testid="CloseIcon" />
6262
}));
6363

64-
// Use the real store; we'll set its state in tests
64+
// Test fixtures and shared mocks need to be defined before jest.mock() that use them
65+
const mockOnChange = jest.fn();
66+
const mockSetSearchTerm = jest.fn();
67+
const mockSetHoveredNode = jest.fn();
6568

66-
// Do not mock the store itself; we will stub the selector hook instead
69+
const mockNodeMetadata: Record<string, any> = {
70+
"tool.node1": {
71+
node_type: "tool.node1",
72+
title: "Tool Node 1",
73+
namespace: "tool",
74+
properties: [],
75+
outputs: [],
76+
expose_as_tool: true
77+
},
78+
"tool.node2": {
79+
node_type: "tool.node2",
80+
title: "Tool Node 2",
81+
namespace: "tool",
82+
properties: [],
83+
outputs: [],
84+
expose_as_tool: true
85+
},
86+
"regular.node": {
87+
node_type: "regular.node",
88+
title: "Regular Node",
89+
namespace: "regular",
90+
properties: [],
91+
outputs: [],
92+
expose_as_tool: false
93+
}
94+
};
95+
96+
const mockSearchResults = [
97+
mockNodeMetadata["tool.node1"],
98+
mockNodeMetadata["tool.node2"]
99+
];
100+
101+
// Mock the NodeMenuStore hook directly so we can control searchTerm and results
102+
jest.mock("../../../../stores/NodeMenuStore", () => {
103+
let currentStore: any = {
104+
searchTerm: "",
105+
setSearchTerm: (_term: string) => {},
106+
searchResults: [],
107+
isLoading: false,
108+
selectedPath: [],
109+
hoveredNode: null,
110+
setHoveredNode: (_node: any) => {}
111+
};
112+
const useNodeToolsMenuStore = (selector?: any) =>
113+
selector ? selector(currentStore) : currentStore;
114+
const __setNodeToolsMenuStore = (newStore: any) => {
115+
currentStore = newStore;
116+
};
117+
return {
118+
__esModule: true,
119+
useNodeToolsMenuStore,
120+
__setNodeToolsMenuStore
121+
};
122+
});
67123

68124
// Mock the SearchInput component
69125
jest.mock("../../../../components/search/SearchInput", () => ({
@@ -150,6 +206,7 @@ jest.mock("lodash", () => ({
150206
}));
151207

152208
import useMetadataStore from "../../../../stores/MetadataStore";
209+
import { __setNodeToolsMenuStore } from "../../../../stores/NodeMenuStore";
153210
import { useStoreWithEqualityFn } from "zustand/traditional";
154211

155212
// Mock the useStoreWithEqualityFn hook to return from our mock store
@@ -163,48 +220,11 @@ jest.mock("react", () => ({
163220
useRef: jest.fn(() => ({ current: null }))
164221
}));
165222

166-
// Test fixtures
167-
const mockNodeMetadata: Record<string, any> = {
168-
"tool.node1": {
169-
node_type: "tool.node1",
170-
title: "Tool Node 1",
171-
namespace: "tool",
172-
properties: [],
173-
outputs: [],
174-
expose_as_tool: true
175-
},
176-
"tool.node2": {
177-
node_type: "tool.node2",
178-
title: "Tool Node 2",
179-
namespace: "tool",
180-
properties: [],
181-
outputs: [],
182-
expose_as_tool: true
183-
},
184-
"regular.node": {
185-
node_type: "regular.node",
186-
title: "Regular Node",
187-
namespace: "regular",
188-
properties: [],
189-
outputs: [],
190-
expose_as_tool: false
191-
}
192-
};
193-
194-
const mockSearchResults = [
195-
mockNodeMetadata["tool.node1"],
196-
mockNodeMetadata["tool.node2"]
197-
];
198-
199223
const renderComponent = (props: any) => {
200224
return render(<NodeToolsSelector {...props} />);
201225
};
202226

203227
describe("NodeToolsSelector", () => {
204-
const mockOnChange = jest.fn();
205-
const mockSetSearchTerm = jest.fn();
206-
const mockSetHoveredNode = jest.fn();
207-
208228
const baseProps = {
209229
value: [],
210230
onChange: mockOnChange
@@ -214,30 +234,21 @@ describe("NodeToolsSelector", () => {
214234
metadata: mockNodeMetadata
215235
};
216236

217-
const mockNodeMenuStore = {
218-
searchTerm: "",
219-
setSearchTerm: mockSetSearchTerm,
220-
searchResults: mockSearchResults,
221-
isLoading: false,
222-
selectedPath: [],
223-
hoveredNode: null,
224-
setHoveredNode: mockSetHoveredNode,
225-
// Add missing properties that might be used
226-
availableNodes: mockSearchResults,
227-
filteredNodes: mockSearchResults
228-
};
229-
230237
beforeEach(() => {
231238
jest.clearAllMocks();
232239

233240
// Initialize real store state
234241
useMetadataStore.setState({ metadata: mockNodeMetadata });
235242

236-
(useStoreWithEqualityFn as jest.Mock).mockImplementation(
237-
(_store, selector) => {
238-
return selector ? selector(mockNodeMenuStore) : mockNodeMenuStore;
239-
}
240-
);
243+
__setNodeToolsMenuStore({
244+
searchTerm: "",
245+
setSearchTerm: (term: string) => mockSetSearchTerm(term),
246+
searchResults: mockSearchResults,
247+
isLoading: false,
248+
selectedPath: [],
249+
hoveredNode: null,
250+
setHoveredNode: (node: any) => mockSetHoveredNode(node)
251+
});
241252
});
242253

243254
describe("Basic Rendering", () => {

0 commit comments

Comments
 (0)